aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--src/argparse.c73
-rw-r--r--src/gpg-error.h.in3
-rw-r--r--tests/etc/t-argparse.conf42
-rw-r--r--tests/t-argparse.c5
-rw-r--r--tests/t-argparse.conf3
6 files changed, 113 insertions, 16 deletions
diff --git a/NEWS b/NEWS
index 1309dcf..d212f39 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,9 @@ Noteworthy changes in version 1.38 (unreleased) [C28/A28/R_]
ARGPARSE_CONFFILE NEW.
ARGPARSE_OPT_CONFFILE NEW.
ARGPARSE_PERMISSION_ERROR NEW.
+ ARGPARSE_INVALID_META NEW.
+ ARGPARSE_UNKNOWN_META NEW.
+ ARGPARSE_UNEXPECTED_META NEW.
ARGPARSE_conffile NEW.
ARGPARSE_noconffile NEW.
GPGRT_CONFDIR_USER NEW.
diff --git a/src/argparse.c b/src/argparse.c
index 6f6431d..765c96c 100644
--- a/src/argparse.c
+++ b/src/argparse.c
@@ -86,6 +86,7 @@ struct _gpgrt_argparse_internal_s
int idx; /* Note that this is saved and restored in _gpgrt_argparser. */
int inarg;
int stopped;
+ int insysconfig; /* Processing global config file. */
int explicit_confopt; /* A conffile option has been given. */
char *explicit_conffile; /* Malloced name of an explicit conffile. */
unsigned int opt_flags; /* Current option flags. */
@@ -278,6 +279,7 @@ initialize (gpgrt_argparse_t *arg, gpgrt_opt_t *opts, estream_t fp)
arg->internal->last = NULL;
arg->internal->inarg = 0;
arg->internal->stopped = 0;
+ arg->internal->insysconfig = 0;
arg->internal->explicit_confopt = 0;
arg->internal->explicit_conffile = NULL;
arg->internal->opt_flags = 0;
@@ -393,6 +395,12 @@ initialize (gpgrt_argparse_t *arg, gpgrt_opt_t *opts, estream_t fp)
s = _("out of core");
else if ( arg->r_opt == ARGPARSE_NO_CONFFILE )
s = NULL; /* Error has already been printed. */
+ else if ( arg->r_opt == ARGPARSE_INVALID_META )
+ s = _("invalid meta command");
+ else if ( arg->r_opt == ARGPARSE_UNKNOWN_META )
+ s = _("unknown meta command");
+ else if ( arg->r_opt == ARGPARSE_UNEXPECTED_META )
+ s = _("unexpected meta command");
else
s = _("invalid option");
if (s)
@@ -422,6 +430,12 @@ initialize (gpgrt_argparse_t *arg, gpgrt_opt_t *opts, estream_t fp)
_gpgrt_log_error ("%s\n", _("permission error"));
else if ( arg->r_opt == ARGPARSE_NO_CONFFILE)
; /* Error has already been printed. */
+ else if ( arg->r_opt == ARGPARSE_INVALID_META )
+ _gpgrt_log_error ("%s\n", _("invalid meta command"));
+ else if ( arg->r_opt == ARGPARSE_UNKNOWN_META )
+ _gpgrt_log_error ("%s\n", _("unknown meta command"));
+ else if ( arg->r_opt == ARGPARSE_UNEXPECTED_META )
+ _gpgrt_log_error ("%s\n",_("unexpected meta command"));
else
_gpgrt_log_error (_("invalid option \"%.50s\"\n"), s);
}
@@ -593,6 +607,10 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
Acopyarg, /* Copy the argument. */
Akeyword_eol, /* Got keyword at end of line. */
Akeyword_spc, /* Got keyword at space. */
+ Acopymetacmd, /* Copy a meta command. */
+ Askipmetacmd, /* Skip spaces after metacmd. */
+ Askipmetacmd2,/* Skip comment after metacmd. */
+ Ametacmd, /* Process the metacmd. */
Askipandleave /* Skip the rest of the line and then leave. */
} state;
gpgrt_opt_t **opts;
@@ -718,6 +736,24 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
goto leave;
}
} /* (end state Akeyword_eol/Akeyword_spc) */
+ else if (state == Ametacmd)
+ {
+ gpgrt_assert (*keyword == '[');
+ trim_spaces (keyword+1);
+ if (!keyword[1])
+ {
+ arg->r_opt = ARGPARSE_INVALID_META; /* Empty. */
+ goto leave;
+ }
+ if (!arg->internal->insysconfig)
+ {
+ arg->r_opt = ARGPARSE_UNEXPECTED_META;
+ goto leave;
+ }
+ /* _gpgrt_log_debug ("Got meta command '%s'\n", keyword+1); */
+ state = Ainit;
+ i = 0;
+ }
/* Get the next character from the line. */
if (unread_buf_count)
@@ -737,6 +773,16 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
state = Akeyword_eol;
goto nextstate;
}
+ else if (state == Acopymetacmd)
+ {
+ arg->r_opt = ARGPARSE_INVALID_META; /* "]" missing */
+ goto leave;
+ }
+ else if (state == Askipmetacmd || state == Askipmetacmd2)
+ {
+ state = Ametacmd;
+ goto nextstate;
+ }
else if (state == Awaitarg)
{
/* No argument found at the end of the line. */
@@ -833,14 +879,30 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
; /* Skip leading white space. */
else if (state == Ainit && c == '#' )
state = Acomment; /* Start of a comment. */
- else if (state == Acomment)
+ else if (state == Acomment || state == Askipmetacmd2)
; /* Skip comments. */
+ else if (state == Askipmetacmd)
+ {
+ if (c == '#')
+ state = Askipmetacmd2;
+ else if (!(isascii (c) && isspace(c)))
+ {
+ arg->r_opt = ARGPARSE_INVALID_META;
+ state = Askipandleave;
+ }
+ }
else if (state == Acopykeyword && isascii (c) && isspace(c))
{
keyword[i] = 0;
state = Akeyword_spc;
goto nextstate;
}
+ else if (state == Acopymetacmd && c == ']')
+ {
+ keyword[i] = 0;
+ state = Askipmetacmd;
+ goto nextstate;
+ }
else if (state == Awaitarg)
{
/* Skip leading spaces of the argument. */
@@ -902,10 +964,14 @@ _gpgrt_argparse (estream_t fp, gpgrt_argparse_t *arg, gpgrt_opt_t *opts_orig)
arg->r_opt = ARGPARSE_KEYWORD_TOO_LONG;
state = Askipandleave; /* Skip rest of line and leave. */
}
+ else if (!i)
+ {
+ state = c == '[' ? Acopymetacmd : Acopykeyword;
+ keyword[i++] = c;
+ }
else
{
keyword[i++] = c;
- state = Acopykeyword;
}
}
@@ -1173,6 +1239,7 @@ _gpgrt_argparser (gpgrt_argparse_t *arg, gpgrt_opt_t *opts,
_gpgrt_log_info (_("reading options from '%s'\n"),
arg->internal->confname);
arg->internal->state = STATE_read_sys;
+ arg->internal->insysconfig = 1;
arg->r.ret_str = xtrystrdup (arg->internal->confname);
if (!arg->r.ret_str)
arg->r_opt = ARGPARSE_OUT_OF_CORE;
@@ -1237,6 +1304,7 @@ _gpgrt_argparser (gpgrt_argparse_t *arg, gpgrt_opt_t *opts,
arg->internal->idx = 0;
arg->internal->stopped = 0;
arg->internal->inarg = 0;
+ arg->internal->insysconfig = 0;
_gpgrt_fclose (arg->internal->conffp);
arg->internal->conffp = _gpgrt_fopen (arg->internal->confname, "r");
if (!arg->internal->conffp)
@@ -1280,6 +1348,7 @@ _gpgrt_argparser (gpgrt_argparse_t *arg, gpgrt_opt_t *opts,
arg->internal->idx = 0;
arg->internal->stopped = 0;
arg->internal->inarg = 0;
+ arg->internal->insysconfig = 0;
if (!arg->argc || !arg->argv || !*arg->argv)
{
/* No or empty argument vector - don't bother to parse things. */
diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in
index e353700..165881b 100644
--- a/src/gpg-error.h.in
+++ b/src/gpg-error.h.in
@@ -1206,6 +1206,9 @@ typedef struct
#define ARGPARSE_PERMISSION_ERROR (-13)
#define ARGPARSE_NO_CONFFILE (-14)
#define ARGPARSE_CONFFILE (-15)
+#define ARGPARSE_INVALID_META (-16)
+#define ARGPARSE_UNKNOWN_META (-17)
+#define ARGPARSE_UNEXPECTED_META (-18)
/* Flags for the option descriptor (gpgrt_opt_t)->flags. Note that
* a TYPE constant may be or-ed with the OPT constants. */
diff --git a/tests/etc/t-argparse.conf b/tests/etc/t-argparse.conf
index 87bff72..0852e71 100644
--- a/tests/etc/t-argparse.conf
+++ b/tests/etc/t-argparse.conf
@@ -3,33 +3,51 @@
# Options applied to all user's config files
#verbose
-#[user :staff]
-# These option are applied to all users the group staff up until the
-# next [user statement]
+[group :staff]
+# These option are applied to all users of the group staff up until
+# the next [group] or [user] statement.
-#[+force]
+[+force]
+# All following option are forced and thus ignored when set in user
+# config files. Valid until the next [user] statement. Take care
+# that there are often "no-", "disable-", or "enable-" versions of
+# options; these should be explictly marked as ignored so that they
+# can't be used to override the force attribute.
-#[ignore]
+[ignore]
# The compliance is set immutable for these users
verbose
+# The next shall raise an error due to the garpage at the end.
+#<off>[+ignore] fooo
+
+
+#[+ignore-all]
+# All options are ignored.
+
+
+[-ignore] # Comment at line end
+# Options wich shall not be ignored. */
#no-verbose
-# (parsing does not stop for a group)
-#[user wk]
-# Options for user wk
+[user john ]
+# Options for user john
-# Change the immutable flag back to mutable.
-#[] compliance gnupg
+# Change the immutable attribute back to mutable.
+[-force]
+#compliance gnupg
-# Default key for wk
+# Default key for user john
my-option 42
# Parsing stops for user WK here.
-#[user *]
+[group * ]
+# Options for all group which have no specific group sections above
+
+[user *]
# Options for all users which have no specific user sections above
# The default algorithm for new keys is set to this.
diff --git a/tests/t-argparse.c b/tests/t-argparse.c
index b2b6e51..4719819 100644
--- a/tests/t-argparse.c
+++ b/tests/t-argparse.c
@@ -88,6 +88,7 @@ main (int argc, char **argv)
) };
int i;
const char *srcdir;
+ int any_warn = 0;
gpgrt_set_strusage (my_strusage);
srcdir = getenv ("srcdir");
@@ -120,7 +121,7 @@ main (int argc, char **argv)
case 'c': opt.crf = pargs.r_type? pargs.r.ret_str:"a.crf"; break;
case 'm': opt.myopt = pargs.r_type? pargs.r.ret_int : 1; break;
case 500: opt.a_long_one++; break;
- default : pargs.err = ARGPARSE_PRINT_ERROR; break;
+ default : pargs.err = ARGPARSE_PRINT_WARNING; any_warn = 1; break;
}
}
for (i=0; i < argc; i++ )
@@ -148,5 +149,5 @@ main (int argc, char **argv)
(void)fail;
(void)die;
- return 0;
+ return !!any_warn;
}
diff --git a/tests/t-argparse.conf b/tests/t-argparse.conf
index 0bbdd3e..e2c96e2 100644
--- a/tests/t-argparse.conf
+++ b/tests/t-argparse.conf
@@ -3,6 +3,9 @@
# Options applied to all user's config files
echo
+# The next should be flagged as unexpected meta command.
+#<off>[ignore]
+
my-option 4711
verbose