Better optional argument handling.

Some options can take an optional argument. However, in this case GNU getopt
requires that the optional argument is right next to the option without
whitespace inbetween. If there is whitespace, getopt will treat it as a
non-option argument, but tincd ignored those without a warning. Now tincd will
allow optional arguments with whitespace inbetween, and will give an error when
it encounters any other non-option arguments.

The tinc binary now requires that all options for itself are given before the
command.
This commit is contained in:
Guus Sliepen 2013-05-30 16:53:16 +02:00
parent ced4c1a327
commit 6bf3595a91
2 changed files with 16 additions and 14 deletions

View file

@ -79,19 +79,11 @@ static struct WSAData wsa_state;
static struct option const long_options[] = {
{"config", required_argument, NULL, 'c'},
{"debug", optional_argument, NULL, 0},
{"no-detach", no_argument, NULL, 0},
{"mlock", no_argument, NULL, 0},
{"net", required_argument, NULL, 'n'},
{"help", no_argument, NULL, 1},
{"version", no_argument, NULL, 2},
{"pidfile", required_argument, NULL, 5},
{"logfile", required_argument, NULL, 0},
{"bypass-security", no_argument, NULL, 0},
{"chroot", no_argument, NULL, 0},
{"user", required_argument, NULL, 0},
{"option", required_argument, NULL, 0},
{"force", no_argument, NULL, 6},
{"pidfile", required_argument, NULL, 3},
{"force", no_argument, NULL, 4},
{NULL, 0, NULL, 0}
};
@ -163,7 +155,7 @@ static bool parse_options(int argc, char **argv) {
int r;
int option_index = 0;
while((r = getopt_long(argc, argv, "c:n:Dd::Lo:RU:", long_options, &option_index)) != EOF) {
while((r = getopt_long(argc, argv, "+c:n:", long_options, &option_index)) != EOF) {
switch (r) {
case 0: /* long option */
break;
@ -185,11 +177,11 @@ static bool parse_options(int argc, char **argv) {
show_version = true;
break;
case 5: /* open control socket here */
case 3: /* open control socket here */
pidfilename = xstrdup(optarg);
break;
case 6: /* force */
case 4: /* force */
force = true;
break;

View file

@ -167,7 +167,9 @@ static bool parse_options(int argc, char **argv) {
break;
#endif
case 'd': /* inc debug level */
case 'd': /* increase debug level */
if(!optarg && optind < argc && *argv[optind] != '-')
optarg = argv[optind++];
if(optarg)
debug_level = atoi(optarg);
else
@ -214,6 +216,8 @@ static bool parse_options(int argc, char **argv) {
case 4: /* write log entries to a file */
use_logfile = true;
if(!optarg && optind < argc && *argv[optind] != '-')
optarg = argv[optind++];
if(optarg)
logfilename = xstrdup(optarg);
break;
@ -231,6 +235,12 @@ static bool parse_options(int argc, char **argv) {
}
}
if(optind < argc) {
fprintf(stderr, "%s: unrecognized argument '%s'\n", argv[0], argv[optind]);
usage(true);
return false;
}
if(!netname && (netname = getenv("NETNAME")))
netname = xstrdup(netname);