aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2020-04-03 19:27:05 +0000
committerWerner Koch <[email protected]>2020-04-03 19:27:05 +0000
commitd843d260f5502ba90a2a35dfe202439f32b0e9aa (patch)
treeb5d04f75886c8c883aaef63746e03bbbed69ced0
parentcore: Tweak the printing of headers in the --help output. (diff)
downloadlibgpg-error-d843d260f5502ba90a2a35dfe202439f32b0e9aa.tar.gz
libgpg-error-d843d260f5502ba90a2a35dfe202439f32b0e9aa.zip
core: Implement meta command [user] for the arg parser.
* src/sysutils.c (_gpgrt_getusername): New. * src/argparse.c (struct _gpgrt_argparse_internal_s): New flags user_* and store the current user. (initialize): Free new malloced field. Clear new flags. (handle_meta_user): Implement. (handle_metacmd): Implement user sections. Remove "group" meta command. (_gpgrt_argparse): Implement user sections. (finish_read_sys): Reset new vars. -- Implementing group would be somewhat complicated and it is doubtful whether this really makes sense and is manageable for the admin. Note that we have not yet implemented this for Windows. Signed-off-by: Werner Koch <[email protected]>
-rw-r--r--src/argparse.c106
-rw-r--r--src/gpgrt-int.h3
-rw-r--r--src/sysutils.c22
-rw-r--r--tests/etc/t-argparse.conf30
4 files changed, 125 insertions, 36 deletions
diff --git a/src/argparse.c b/src/argparse.c
index 6b3488a..0c5ec58 100644
--- a/src/argparse.c
+++ b/src/argparse.c
@@ -109,9 +109,14 @@ struct _gpgrt_argparse_internal_s
unsigned int explicit_ignore:1; /* Option has explicitly been set
* to ignore or unignore. */
unsigned int ignore_all_seen:1; /* [ignore-all] has been seen. */
+ unsigned int user_seen:1; /* A [user] has been seen. */
+ unsigned int user_wildcard:1; /* A [user *] has been seen. */
+ unsigned int user_any_active:1; /* Any user section was active. */
+ unsigned int user_active:1; /* User section active. */
unsigned int explicit_confopt:1; /* A conffile option has been given. */
char *explicit_conffile; /* Malloced name of an explicit
* conffile. */
+ char *username; /* Malloced current user name. */
unsigned int opt_flags; /* Current option flags. */
enum argparser_states state; /* State of the gpgrt_argparser. */
const char *last;
@@ -256,6 +261,7 @@ deinitialize (gpgrt_argparse_t *arg)
{
if (arg->internal)
{
+ xfree (arg->internal->username);
xfree (arg->internal->explicit_conffile);
xfree (arg->internal->opts);
xfree (arg->internal);
@@ -306,6 +312,10 @@ initialize (gpgrt_argparse_t *arg, gpgrt_opt_t *opts, estream_t fp)
arg->internal->inarg = 0;
arg->internal->stopped = 0;
arg->internal->in_sysconf = 0;
+ arg->internal->user_seen = 0;
+ arg->internal->user_wildcard = 0;
+ arg->internal->user_any_active = 0;
+ arg->internal->user_active = 0;
arg->internal->mark_forced = 0;
arg->internal->mark_ignore = 0;
arg->internal->explicit_ignore = 0;
@@ -652,19 +662,49 @@ ignore_invalid_option_clear (gpgrt_argparse_t *arg)
}
-/* Implementation of the "user" and "group" commands. ARG is the
- * context. A value of 0 for ALTERNATE requests the "user" command, a
- * value of "1" the "group" command. ARGS is a non-empty string which
- * this function is allowed to modify. */
+/* Implementation of the "user" command. ARG is the context. ARGS is
+ * a non-empty string which this function is allowed to modify. */
static int
handle_meta_user (gpgrt_argparse_t *arg, unsigned int alternate, char *args)
{
- (void)args;
+ (void)alternate;
+
+ if (!arg->internal->username)
+ {
+ arg->internal->username = _gpgrt_getusername ();
+ if (!arg->internal->username)
+ {
+ _gpgrt_log_error ("%s:%u: error getting current user's name: %s\n",
+ arg->internal->confname, arg->lineno,
+ _gpg_strerror (gpg_error_from_syserror ()));
+ /* Not necessary the correct error code but given that we
+ * either have a malloc error or some internal system error,
+ * it is the best we can do. */
+ return ARGPARSE_PERMISSION_ERROR;
+ }
+ }
- if (arg->internal->verbose)
- _gpgrt_log_info ("%s:%u: meta command %s is not yet supported\n",
- arg->internal->confname, arg->lineno,
- alternate? "group":"user");
+
+ arg->internal->user_seen = 1;
+ if (*args == '*' && !args[1])
+ {
+ arg->internal->user_wildcard = 1;
+ arg->internal->user_active = !arg->internal->user_any_active;
+ }
+ else if (arg->internal->user_wildcard)
+ {
+ /* All other user statements are ignored after a wildcard. */
+ arg->internal->user_active = 0;
+ }
+ else if (!strcasecmp (args, arg->internal->username))
+ {
+ arg->internal->user_any_active = 1;
+ arg->internal->user_active = 1;
+ }
+ else
+ {
+ arg->internal->user_active = 0;
+ }
return 0;
}
@@ -751,24 +791,26 @@ handle_metacmd (gpgrt_argparse_t *arg, char *keyword)
unsigned short alternate; /* Use alternate version of the command. */
unsigned short needarg:1; /* Command requires an argument. */
unsigned short always:1; /* Command allowed in all conf files. */
+ unsigned short noskip:1; /* Even done in non-active [user] mode. */
int (*func)(gpgrt_argparse_t *arg,
unsigned int alternate, char *args); /*handler*/
} cmds[] =
- {{ "user", 0, 1, 0, handle_meta_user },
- { "group", 1, 1, 0, handle_meta_user },
- { "force", 0, 0, 0, handle_meta_force },
- { "+force", 0, 0, 0, handle_meta_force },
- { "-force", 1, 0, 0, handle_meta_force },
- { "ignore", 0, 0, 0, handle_meta_ignore },
- { "+ignore", 0, 0, 0, handle_meta_ignore },
- { "-ignore", 1, 0, 0, handle_meta_ignore },
- { "ignore-all", 2, 0, 0, handle_meta_ignore },
- { "+ignore-all", 2, 0, 0, handle_meta_ignore },
- { "verbose", 0, 0, 1, handle_meta_verbose },
- { "+verbose", 0, 0, 1, handle_meta_verbose },
- { "-verbose", 1, 0, 1, handle_meta_verbose },
- { "echo", 0, 1, 1, handle_meta_echo },
- { "-echo", 1, 1, 1, handle_meta_echo }
+ {{ "user", 0, 1, 0, 1, handle_meta_user },
+ { "force", 0, 0, 0, 0, handle_meta_force },
+ { "+force", 0, 0, 0, 0, handle_meta_force },
+ { "-force", 1, 0, 0, 0, handle_meta_force },
+ { "ignore", 0, 0, 0, 0, handle_meta_ignore },
+ { "+ignore", 0, 0, 0, 0, handle_meta_ignore },
+ { "-ignore", 1, 0, 0, 0, handle_meta_ignore },
+ { "ignore-all", 2, 0, 0, 0, handle_meta_ignore },
+ { "+ignore-all", 2, 0, 0, 0, handle_meta_ignore },
+ { "verbose", 0, 0, 1, 1, handle_meta_verbose },
+ { "+verbose", 0, 0, 1, 1, handle_meta_verbose },
+ { "-verbose", 1, 0, 1, 1, handle_meta_verbose },
+ { "echo", 0, 1, 1, 1, handle_meta_echo },
+ { "-echo", 1, 1, 1, 1, handle_meta_echo },
+ { "info", 0, 1, 1, 0, handle_meta_echo },
+ { "-info", 1, 1, 1, 0, handle_meta_echo }
};
char *rest;
int i;
@@ -793,6 +835,12 @@ handle_metacmd (gpgrt_argparse_t *arg, char *keyword)
if (!arg->internal->in_sysconf && !cmds[i].always)
return ARGPARSE_UNEXPECTED_META;
+ if (!cmds[i].noskip
+ && arg->internal->in_sysconf
+ && arg->internal->user_seen
+ && !arg->internal->user_active)
+ return 0; /* Skip this meta command. */
+
return cmds[i].func (arg, cmds[i].alternate, rest);
}
@@ -944,6 +992,15 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
/* Known option but need to scan for args. */
state = Awaitarg;
}
+ else if (arg->internal->in_sysconf
+ && arg->internal->user_seen
+ && !arg->internal->user_active)
+ {
+ /* We are in a [user] meta command and it is not active.
+ * Skip the command. */
+ state = state == Akeyword_eol? Ainit : Acomment;
+ i = 0;
+ }
else if ((opts[idx].flags & ARGPARSE_OPT_IGNORE))
{
/* Known option is configured to be ignored. Start from
@@ -1384,6 +1441,7 @@ finish_read_sys (gpgrt_argparse_t *arg)
/* Reset all flags which pertain only to sysconf files. */
arg->internal->in_sysconf = 0;
+ arg->internal->user_active = 0;
arg->internal->mark_forced = 0;
arg->internal->mark_ignore = 0;
arg->internal->explicit_ignore = 0;
diff --git a/src/gpgrt-int.h b/src/gpgrt-int.h
index cc22004..629f527 100644
--- a/src/gpgrt-int.h
+++ b/src/gpgrt-int.h
@@ -795,6 +795,9 @@ char *_gpgrt_getcwd (void);
/* Return the home directory of user NAME. */
char *_gpgrt_getpwdir (const char *name);
+/* Return the account name of the current user. */
+char *_gpgrt_getusername (void);
+
/* Expand and concat file name parts. */
char *_gpgrt_vfnameconcat (int want_abs, const char *first_part,
va_list arg_ptr);
diff --git a/src/sysutils.c b/src/sysutils.c
index 6bdd76f..112c8b5 100644
--- a/src/sysutils.c
+++ b/src/sysutils.c
@@ -343,7 +343,7 @@ _gpgrt_getcwd (void)
/* Get the standard home directory for user NAME. If NAME is NULL the
- * directory for the current user is retruned. Caller must release
+ * directory for the current user is returned. Caller must release
* the returned string. */
char *
_gpgrt_getpwdir (const char *name)
@@ -376,3 +376,23 @@ _gpgrt_getpwdir (const char *name)
#endif /*HAVE_PWD_H*/
return result;
}
+
+
+/* Return a malloced copy of the current user's account name; this may
+ * return NULL on memory failure. */
+char *
+_gpgrt_getusername (void)
+{
+ char *result = NULL;
+#if defined(HAVE_PWD_H) && defined(HAVE_GETPWUID)
+ struct passwd *pwd;
+
+ pwd = getpwuid (getuid());
+ if (pwd)
+ {
+ result = _gpgrt_strdup (pwd->pw_name);
+ }
+
+#endif /*HAVE_PWD_H*/
+ return result;
+}
diff --git a/tests/etc/t-argparse.conf b/tests/etc/t-argparse.conf
index 90b9935..4562c7c 100644
--- a/tests/etc/t-argparse.conf
+++ b/tests/etc/t-argparse.conf
@@ -3,11 +3,21 @@
# Options applied to all user's config files
#verbose
+# The meta comman decho simply prints the argument. With a hash
+# prefix it does not prepend the file name and line number. For
+# future compatibility do not use doallar signs.
[-echo Begin global config]
[verbose]
-[group :staff]
-# These option are applied to all users of the group staff up until
-# the next [group] or [user] statement.
+
+[user joy]
+# All the following options are applied only if the current user's
+# account name is "joy" (case-insensitive). This ends with the next
+# user statement. This does not affect "echo" and "verbose".
+
+# info is an alias for echo but only executed if a user secion is active.
+# For future compatibility do not use percent or dollar signs.
+[-info In user Joy]
+
[-verbose]
[+force]
# All following option are forced and thus ignored when set in user
@@ -37,8 +47,9 @@ not-my-option
#no-verbose
-[user john ]
-# Options for user john
+# Options applied only for user joy end here.
+[user wk ]
+[-info Options applied only for user wk follow]
# Change the immutable attribute back to mutable.
[-force]
@@ -47,13 +58,10 @@ not-my-option
# Default key for user john
my-option 42
-# Parsing stops for user WK here.
-
-[group * ]
-# Options for all group which have no specific group sections above
-
+# Options applied only for user joy end here.
[user *]
-# Options for all users which have no specific user sections above
+[-info All the following options are applied only if the]
+[-info current user has no specific section above.]
# The default algorithm for new keys is set to this.
a-long-option