{.name = "numeric", .has_arg = 0, .val = 'n'},
{.name = "out-interface", .has_arg = 1, .val = 'o'},
{.name = "verbose", .has_arg = 0, .val = 'v'},
- {.name = "wait", .has_arg = 0, .val = 'w'},
+ {.name = "wait", .has_arg = 2, .val = 'w'},
{.name = "exact", .has_arg = 0, .val = 'x'},
{.name = "version", .has_arg = 0, .val = 'V'},
{.name = "help", .has_arg = 2, .val = 'h'},
" network interface name ([+] for wildcard)\n"
" --table -t table table to manipulate (default: `filter')\n"
" --verbose -v verbose mode\n"
-" --wait -w wait for the xtables lock\n"
+" --wait -w [seconds] wait for the xtables lock\n"
" --line-numbers print line numbers when listing\n"
" --exact -x expand numbers (display exact values)\n"
/*"[!] --fragment -f match second or further fragments only\n"*/
struct in6_addr *smasks = NULL, *dmasks = NULL;
int verbose = 0;
- bool wait = false;
+ int wait = 0;
const char *chain = NULL;
const char *shostnetworkmask = NULL, *dhostnetworkmask = NULL;
const char *policy = NULL, *newname = NULL;
opts = xt_params->orig_opts;
while ((cs.c = getopt_long(argc, argv,
- "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:bvwnt:m:xc:g:46",
+ "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:bvw::nt:m:xc:g:46",
opts, NULL)) != -1) {
switch (cs.c) {
/*
"You cannot use `-w' from "
"ip6tables-restore");
}
- wait = true;
+ wait = -1;
+ if (optarg) {
+ if (sscanf(optarg, "%i", &wait) != 1)
+ xtables_error(PARAMETER_PROBLEM,
+ "wait seconds not numeric");
+ } else if (optind < argc && argv[optind][0] != '-'
+ && argv[optind][0] != '!')
+ if (sscanf(argv[optind++], "%i", &wait) != 1)
+ xtables_error(PARAMETER_PROBLEM,
+ "wait seconds not numeric");
break;
case 'm':
/* Attempt to acquire the xtables lock */
if (!restore && !xtables_lock(wait)) {
- fprintf(stderr, "Another app is currently holding the xtables lock. "
- "Perhaps you want to use the -w option?\n");
+ fprintf(stderr, "Another app is currently holding the xtables lock. ");
+ if (wait == 0)
+ fprintf(stderr, "Perhaps you want to use the -w option?\n");
+ else
+ fprintf(stderr, "Stopped waiting after %ds.\n", wait);
xtables_free_opts(1);
exit(RESOURCE_PROBLEM);
}
detailed information on the rule or rules to be printed. \fB\-v\fP may be
specified multiple times to possibly emit more detailed debug statements.
.TP
-\fB\-w\fP, \fB\-\-wait\fP
+\fB\-w\fP, \fB\-\-wait\fP [\fIseconds\fP]
Wait for the xtables lock.
To prevent multiple instances of the program from running concurrently,
an attempt will be made to obtain an exclusive lock at launch. By default,
the program will exit if the lock cannot be obtained. This option will
-make the program wait until the exclusive lock can be obtained.
+make the program wait (indefinitely or for optional \fIseconds\fP) until
+the exclusive lock can be obtained.
.TP
\fB\-n\fP, \fB\-\-numeric\fP
Numeric output.
{.name = "numeric", .has_arg = 0, .val = 'n'},
{.name = "out-interface", .has_arg = 1, .val = 'o'},
{.name = "verbose", .has_arg = 0, .val = 'v'},
- {.name = "wait", .has_arg = 0, .val = 'w'},
+ {.name = "wait", .has_arg = 2, .val = 'w'},
{.name = "exact", .has_arg = 0, .val = 'x'},
{.name = "fragments", .has_arg = 0, .val = 'f'},
{.name = "version", .has_arg = 0, .val = 'V'},
" network interface name ([+] for wildcard)\n"
" --table -t table table to manipulate (default: `filter')\n"
" --verbose -v verbose mode\n"
-" --wait -w wait for the xtables lock\n"
+" --wait -w [seconds] wait for the xtables lock\n"
" --line-numbers print line numbers when listing\n"
" --exact -x expand numbers (display exact values)\n"
"[!] --fragment -f match second or further fragments only\n"
struct in_addr *daddrs = NULL, *dmasks = NULL;
int verbose = 0;
- bool wait = false;
+ int wait = 0;
const char *chain = NULL;
const char *shostnetworkmask = NULL, *dhostnetworkmask = NULL;
const char *policy = NULL, *newname = NULL;
/* Suppress error messages: we may add new options if we
demand-load a protocol. */
opterr = 0;
-
opts = xt_params->orig_opts;
while ((cs.c = getopt_long(argc, argv,
- "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvwnt:m:xc:g:46",
+ "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvw::nt:m:xc:g:46",
opts, NULL)) != -1) {
switch (cs.c) {
/*
"You cannot use `-w' from "
"iptables-restore");
}
- wait = true;
+ wait = -1;
+ if (optarg) {
+ if (sscanf(optarg, "%i", &wait) != 1)
+ xtables_error(PARAMETER_PROBLEM,
+ "wait seconds not numeric");
+ } else if (optind < argc && argv[optind][0] != '-'
+ && argv[optind][0] != '!')
+ if (sscanf(argv[optind++], "%i", &wait) != 1)
+ xtables_error(PARAMETER_PROBLEM,
+ "wait seconds not numeric");
break;
case 'm':
/* Attempt to acquire the xtables lock */
if (!restore && !xtables_lock(wait)) {
- fprintf(stderr, "Another app is currently holding the xtables lock. "
- "Perhaps you want to use the -w option?\n");
+ fprintf(stderr, "Another app is currently holding the xtables lock. ");
+ if (wait == 0)
+ fprintf(stderr, "Perhaps you want to use the -w option?\n");
+ else
+ fprintf(stderr, "Stopped waiting after %ds.\n", wait);
xtables_free_opts(1);
exit(RESOURCE_PROBLEM);
}
match->init(match->m);
}
-bool xtables_lock(bool wait)
+bool xtables_lock(int wait)
{
int i = 0, ret, xt_socket;
struct sockaddr_un xt_addr;
+ int waited = 0;
memset(&xt_addr, 0, sizeof(xt_addr));
xt_addr.sun_family = AF_UNIX;
offsetof(struct sockaddr_un, sun_path)+XT_SOCKET_LEN);
if (ret == 0)
return true;
- else if (wait == false)
+ else if (wait >= 0 && waited >= wait)
return false;
if (++i % 2 == 0)
fprintf(stderr, "Another app is currently holding the xtables lock; "
- "waiting for it to exit...\n");
+ "waiting (%ds) for it to exit...\n", waited);
+ waited++;
sleep(1);
}
}
extern int subcmd_main(int, char **, const struct subcommand *);
extern void xs_init_target(struct xtables_target *);
extern void xs_init_match(struct xtables_match *);
-extern bool xtables_lock(bool wait);
+extern bool xtables_lock(int wait);
extern const struct xtables_afinfo *afinfo;
{.name = "numeric", .has_arg = 0, .val = 'n'},
{.name = "out-interface", .has_arg = 1, .val = 'o'},
{.name = "verbose", .has_arg = 0, .val = 'v'},
+ {.name = "wait", .has_arg = 2, .val = 'w'},
{.name = "exact", .has_arg = 0, .val = 'x'},
{.name = "fragments", .has_arg = 0, .val = 'f'},
{.name = "version", .has_arg = 0, .val = 'V'},
{
struct iptables_command_state cs;
int verbose = 0;
+ int wait = 0;
const char *chain = NULL;
const char *policy = NULL, *newname = NULL;
unsigned int rulenum = 0, command = 0;
opts = xt_params->orig_opts;
while ((cs.c = getopt_long(argc, argv,
- "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvnt:m:xc:g:46",
+ "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvw::nt:m:xc:g:46",
opts, NULL)) != -1) {
switch (cs.c) {
/*
"You cannot use `-w' from "
"iptables-restore");
}
+ if (optarg) {
+ if (sscanf(optarg, "%i", &wait) != 1)
+ xtables_error(PARAMETER_PROBLEM,
+ "wait seconds not numeric");
+ } else if (optind < argc && argv[optind][0] != '-'
+ && argv[optind][0] != '!')
+ if (sscanf(argv[optind++], "%i", &wait) != 1)
+ xtables_error(PARAMETER_PROBLEM,
+ "wait seconds not numeric");
break;
case '0':