Browse Source

Use libnotch's xdg module.

Use the xdg module from my auxiliary library to get the path to the
configuration directory.
master
Damien Goutte-Gattat 4 months ago
parent
commit
dbbaed4b44
  1. 3
      lib/Makefile.am
  2. 6
      lib/xdg-vars.h
  3. 152
      lib/xdg.c
  4. 45
      lib/xdg.h
  5. 27
      src/gfsec-split.c
  6. 21
      src/gfsec-use.c

3
lib/Makefile.am

@ -1,5 +1,6 @@
noinst_LIBRARIES = libgfsecret.a
libgfsecret_a_SOURCES = err.compat.h compat.h splitstr.c splitstr.h xmem.c xmem.h
libgfsecret_a_SOURCES = err.compat.h compat.h splitstr.c splitstr.h xmem.c xmem.h \
xdg.c xdg.h xdg-vars.h
libgfsecret_a_LIBADD = $(LIBOBJS)

6
lib/xdg-vars.h

@ -0,0 +1,6 @@
XDG_VAR(XDG_DATA_HOME, data_home, "~/.local/share")
XDG_VAR(XDG_CONFIG_HOME, config_home, "~/.config")
XDG_VAR(XDG_DATA_DIRS, data_dirs, "/usr/local/share:/usr/share")
XDG_VAR(XDG_CONFIG_DIRS, config_dirs, "/etc/xdg")
XDG_VAR(XDG_CACHE_HOME, cache_home, "~/.cache")
XDG_VAR(XDG_RUNTIME_DIR, runtime_dir, ".")

152
lib/xdg.c

@ -0,0 +1,152 @@
/*
* xdg - Incenp.org Notch Library: XDG Base Directory implementation
* Copyright (C) 2011 Damien Goutte-Gattat
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <xdg.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <err.h>
#include <sys/types.h>
#include <unistd.h>
#include <pwd.h>
enum {
#define XDG_VAR(variable_name, member_name, default_value) \
variable_name,
#include "xdg-vars.h"
#undef XDG_VAR
XDG_MAX_VARS
};
typedef struct {
char *var_name;
char *def_value;
char *value;
size_t len;
size_t offset;
} xdg_var_t;
xdg_t *
xdg_init(void)
{
xdg_t *xdg;
char *home_dir;
size_t home_len, needed;
int offset, i;
xdg_var_t vars[XDG_MAX_VARS + 1] = {
#define XDG_VAR(variable_name, member_name, default_value) \
{ #variable_name, default_value, NULL, 0, offsetof(xdg_t, member_name) },
#include "xdg-vars.h"
#undef XDG_VAR
{ NULL, NULL, NULL, 0, 0 }
};
needed = offset = sizeof(*xdg);
/* Retrieve home directory (needed for some default values). */
if ( ! (home_dir = getenv("HOME")) ) {
struct passwd *pw;
do {
errno = 0;
if ( (pw = getpwuid(getuid())) )
home_dir = pw->pw_dir;
} while ( ! pw && errno == EINTR );
}
home_len = home_dir ? strlen(home_dir) : 0;
/* Retrieve XDG variables and compute the amount of memory
* needed to store everything. */
for ( i = 0; i < XDG_MAX_VARS; i++ ) {
vars[i].value = getenv(vars[i].var_name);
if ( ! vars[i].value || ! vars[i].value[0] ) {
if ( i == XDG_RUNTIME_DIR )
/* XDG Base Directory specification mandates this warning. */
warnx("XDG_RUNTIME_DIR is not set");
vars[i].value = vars[i].def_value;
}
vars[i].len = strlen(vars[i].value);
needed += vars[i].len + 1;
if ( vars[i].value[0] == '~' ) {
if ( ! home_dir ) {
/* We need the home directory, but were unable to get it. */
errno = ENOENT;
return NULL;
}
needed += home_len;
}
}
if ( ! (xdg = malloc(needed)) )
return NULL;
/* Store everything into the xdg_t structure. */
for ( i = 0; i < XDG_MAX_VARS; i++ ) {
/* Left value is the offset of the member in the xdg_t
* structure; right value is the offset of the
* corresponding data in the area after the structure. */
*((char **)((char *)xdg + vars[i].offset)) = (char *)xdg + offset;
/* Replace '~' by home directory. */
if ( vars[i].value[0] == '~' ) {
vars[i].value = &(vars[i].value[1]);
strcpy((char *)xdg + offset, home_dir);
offset += home_len;
}
strcpy((char *)xdg + offset, vars[i].value);
offset += vars[i].len + 1;
}
return xdg;
}
xdg_t *xdg = NULL;
static void
xdg_free(void)
{
if ( xdg )
free(xdg);
}
xdg_t *
xdg_get(int fatal)
{
if ( ! xdg ) {
if ( ! (xdg = xdg_init()) ) {
if ( fatal )
err(EXIT_FAILURE, "Cannot get XDG variables");
return NULL;
}
atexit(xdg_free);
}
return xdg;
}

45
lib/xdg.h

@ -0,0 +1,45 @@
/*
* xdg - Incenp.org Notch Library: XDG Base Directory implementation
* Copyright (C) 2011 Damien Goutte-Gattat
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ICP20110203_XDG_H
#define ICP20110203_XDG_H
typedef struct {
#define XDG_VAR(variable_name, member_name, default_value) \
char *member_name;
#include "xdg-vars.h"
#undef XDG_VAR
} xdg_t;
xdg_t *xdg;
#ifdef __cplusplus
extern "C" {
#endif
xdg_t *
xdg_init(void);
xdg_t *
xdg_get(int);
#ifdef __cplusplus
}
#endif
#endif /* !ICP20110203_XDG_H */

27
src/gfsec-split.c

@ -34,6 +34,7 @@
#include <gcrypt.h>
#include <xmem.h>
#include <xdg.h>
#include "util.h"
#include "secretcfg.h"
@ -225,33 +226,17 @@ transform_config_pathname(char *cfg, size_t len, const char *secret)
base = xstrdup(cfg);
if ( base ) {
const char *env_info;
char config_dir[255];
if ( (env_info = getenv("XDG_CONFIG_HOME")) && *env_info)
rc = snprintf(config_dir, sizeof(config_dir), "%s/gfsecret", env_info);
else if ( (env_info = getenv("HOME")) && *env_info)
rc = snprintf(config_dir, sizeof(config_dir), "%s/.config/gfsecret", env_info);
else {
rc = -1;
errno = ENOENT;
}
if ( rc != -1 && (unsigned)rc >= sizeof(config_dir) ) {
rc = snprintf(cfg, len, "%s/gfsecret", xdg->config_home);
if ( (unsigned)rc >= len - 6 - strlen(base) ) {
rc = -1;
errno = ENAMETOOLONG;
}
if ( rc != -1 )
rc = makedir(config_dir, 0700);
rc = makedir(cfg, 0700);
if ( rc != -1 )
rc = snprintf(cfg, len, "%s/%s.conf", config_dir, base);
if ( rc != -1 && (unsigned)rc >= len ) {
rc = -1;
errno = ENAMETOOLONG;
}
snprintf(cfg, len, "%s/gfsecret/%s.conf", xdg->config_home, base);
free(base);
}
@ -311,6 +296,8 @@ main(int argc, char **argv)
srandom(time(NULL));
(void) xdg_get(1);
cfg = gfsec_secret_new();
while ( (c = getopt_long(argc, argv, "hvn:s:ic:ko:r:d:l",

21
src/gfsec-use.c

@ -35,6 +35,8 @@
#include <gcrypt.h>
#include <xdg.h>
#include "util.h"
#include "secret.h"
#include "secretcfg.h"
@ -90,24 +92,13 @@ See the COPYING file or <http://www.gnu.org/licenses/gpl.html>.\n\
static int
get_config_file_in_dir(const char *filename, char *buffer, size_t len)
{
int rc;
const char *env_info;
if ( (env_info = getenv("XDG_CONFIG_HOME")) && *env_info )
rc = snprintf(buffer, len, "%s/gfsecret/%s.conf", env_info, filename);
else if ( (env_info = getenv("HOME")) && *env_info )
rc = snprintf(buffer, len, "%s/.config/gfsecret/%s.conf", env_info, filename);
else {
rc = -1;
errno = ENOENT;
}
int rc = 0;
if ( rc >= 0 && (unsigned)rc >= len ) {
rc = snprintf(buffer, len, "%s/gfsecret/%s.conf", xdg->config_home, filename);
if ( (unsigned)rc >= len ) {
rc = -1;
errno = ENAMETOOLONG;
}
else
rc = 0;
return rc;
}
@ -202,6 +193,8 @@ main(int argc, char **argv)
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
(void) xdg_get(1);
while ( (c = getopt_long(argc, argv, "hvc:ko:r:d:",
options, NULL)) != -1 ) {
switch ( c ) {

Loading…
Cancel
Save