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:
parent
ced4c1a327
commit
6bf3595a91
2 changed files with 16 additions and 14 deletions
|
@ -79,19 +79,11 @@ static struct WSAData wsa_state;
|
||||||
|
|
||||||
static struct option const long_options[] = {
|
static struct option const long_options[] = {
|
||||||
{"config", required_argument, NULL, 'c'},
|
{"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'},
|
{"net", required_argument, NULL, 'n'},
|
||||||
{"help", no_argument, NULL, 1},
|
{"help", no_argument, NULL, 1},
|
||||||
{"version", no_argument, NULL, 2},
|
{"version", no_argument, NULL, 2},
|
||||||
{"pidfile", required_argument, NULL, 5},
|
{"pidfile", required_argument, NULL, 3},
|
||||||
{"logfile", required_argument, NULL, 0},
|
{"force", no_argument, NULL, 4},
|
||||||
{"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},
|
|
||||||
{NULL, 0, NULL, 0}
|
{NULL, 0, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -163,7 +155,7 @@ static bool parse_options(int argc, char **argv) {
|
||||||
int r;
|
int r;
|
||||||
int option_index = 0;
|
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) {
|
switch (r) {
|
||||||
case 0: /* long option */
|
case 0: /* long option */
|
||||||
break;
|
break;
|
||||||
|
@ -185,11 +177,11 @@ static bool parse_options(int argc, char **argv) {
|
||||||
show_version = true;
|
show_version = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5: /* open control socket here */
|
case 3: /* open control socket here */
|
||||||
pidfilename = xstrdup(optarg);
|
pidfilename = xstrdup(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6: /* force */
|
case 4: /* force */
|
||||||
force = true;
|
force = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
12
src/tincd.c
12
src/tincd.c
|
@ -167,7 +167,9 @@ static bool parse_options(int argc, char **argv) {
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case 'd': /* inc debug level */
|
case 'd': /* increase debug level */
|
||||||
|
if(!optarg && optind < argc && *argv[optind] != '-')
|
||||||
|
optarg = argv[optind++];
|
||||||
if(optarg)
|
if(optarg)
|
||||||
debug_level = atoi(optarg);
|
debug_level = atoi(optarg);
|
||||||
else
|
else
|
||||||
|
@ -214,6 +216,8 @@ static bool parse_options(int argc, char **argv) {
|
||||||
|
|
||||||
case 4: /* write log entries to a file */
|
case 4: /* write log entries to a file */
|
||||||
use_logfile = true;
|
use_logfile = true;
|
||||||
|
if(!optarg && optind < argc && *argv[optind] != '-')
|
||||||
|
optarg = argv[optind++];
|
||||||
if(optarg)
|
if(optarg)
|
||||||
logfilename = xstrdup(optarg);
|
logfilename = xstrdup(optarg);
|
||||||
break;
|
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")))
|
if(!netname && (netname = getenv("NETNAME")))
|
||||||
netname = xstrdup(netname);
|
netname = xstrdup(netname);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue