summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2003-11-05 23:31:31 +0000
committerLennart Poettering <lennart@poettering.net>2003-11-05 23:31:31 +0000
commit21c20545874b31e6cf3b2dd87c678f9ca1cde365 (patch)
tree401d5c8e230c69b8626e124c5e7754f3e605bc75
parentb5313e96dae1e63557ef5c47eb68734de3812bd9 (diff)
isuspend feature
git-svn-id: file:///home/lennart/svn/public/waproamd/trunk@33 022f378f-78c4-0310-b860-d162c87e6274
-rw-r--r--src/nlapi.c2
-rw-r--r--src/waproamd.c172
2 files changed, 119 insertions, 55 deletions
diff --git a/src/nlapi.c b/src/nlapi.c
index 318199f..1738325 100644
--- a/src/nlapi.c
+++ b/src/nlapi.c
@@ -86,7 +86,7 @@ int nlapi_work(int block) {
daemon_log(LOG_ERR, "NLAPI: Packet too small or truncated!\n");
return -1;
}
-
+
for (c = callbacks; c; c = c->next)
if (c->callback(p, c->userdata) < 0)
return -1;
diff --git a/src/waproamd.c b/src/waproamd.c
index 96bc0bd..4a6b3c3 100644
--- a/src/waproamd.c
+++ b/src/waproamd.c
@@ -55,6 +55,9 @@ int use_assocwatch = 1,
use_ifmonitor = 0,
daemonize = 1,
wait_on_fork = 0,
+#ifdef DAEMON_PID_FILE_KILL_WAIT_AVAILABLE
+ wait_on_kill = 0,
+#endif
use_syslog = 1;
int poll_interval = 5,
@@ -212,6 +215,8 @@ int go(struct interface *i) {
int scanning = 0;
int send_retval = 1;
int r = -1, sigfd;
+ int paused = 0;
+ int force_assoc_check = 0;
fd_set fds;
daemon_log(LOG_INFO, "waproamd "VERSION" initializing%s%s.", use_ifmonitor ? ", using NETLINK device monitoring" : "", use_assocwatch ? ", using wireless event notifications" : "");
@@ -221,7 +226,7 @@ int go(struct interface *i) {
goto finish;
}
- if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, SIGCHLD, -1) < 0) {
+ if (daemon_signal_init(SIGINT, SIGTERM, SIGQUIT, SIGHUP, SIGCHLD, SIGUSR1, SIGUSR2, -1) < 0) {
daemon_log(LOG_ERR, "Could not register signal handler: %s", strerror(errno));
goto finish;
}
@@ -274,7 +279,7 @@ int go(struct interface *i) {
for (;;) {
fd_set qfds;
- struct timeval tv, *ptv;
+ struct timeval tv, *ptv = NULL;
time_t now = time(NULL);
int a, d;
@@ -287,9 +292,7 @@ int go(struct interface *i) {
next_scan = (time_t) -1;
}
-
- ptv = NULL;
-
+
if (scanning) {
tv.tv_sec = 0;
tv.tv_usec = 100000;
@@ -330,7 +333,7 @@ int go(struct interface *i) {
if (nlapi_work(0) < 0)
goto finish;
- if (!disabled && !use_assocwatch) {
+ if (force_assoc_check || (!disabled && !use_assocwatch && !paused)) {
if ((associated = interface_is_assoc(i, &associated_ap)) < 0) {
if (!use_ifmonitor)
goto finish;
@@ -339,56 +342,67 @@ int go(struct interface *i) {
}
}
- /* Changed: enabled -> disabled */
- if (!d && disabled) {
- daemon_log(LOG_INFO, "Interface disabled\n");
+ force_assoc_check = 0;
- if (associated)
- if (set_current_ap(NULL) < 0)
- goto finish;
-
- associated = scanning = 0;
- }
+ if (paused) {
- /* Changed: disabled -> enabled */
- if (d && !disabled) {
- daemon_log(LOG_INFO, "Interface enabled\n");
- associated = scanning = 0;
- }
-
- /* Changed: associated -> not associated */
- if (a && !associated) {
- daemon_log(LOG_INFO, "No longer associated.\n");
- scanning = 0;
- }
-
- /* Changed: not associated -> associated */
- if (!a && associated) {
- if (set_current_ap(&associated_ap) < 0)
- goto finish;
-
- daemon_log(LOG_INFO, "Associated.\n");
- scanning = 0;
- }
-
- if (scanning) {
- int r;
- struct ap_info *ai = NULL;
+ /* If paused ignore new data */
+ associated = a;
+ disabled = d;
+
+ } else {
+
+ /* Changed: enabled -> disabled */
+ if (!d && disabled) {
+ daemon_log(LOG_INFO, "Interface disabled\n");
- if ((r = read_scan(i, &ai)) < 0) {
- if (!use_ifmonitor)
- goto finish;
+ if (associated)
+ if (set_current_ap(NULL) < 0)
+ goto finish;
+ associated = scanning = 0;
+ }
+
+ /* Changed: disabled -> enabled */
+ if (d && !disabled) {
+ daemon_log(LOG_INFO, "Interface enabled\n");
+ associated = scanning = 0;
+ }
+
+ /* Changed: associated -> not associated */
+ if (a && !associated) {
+ daemon_log(LOG_INFO, "No longer associated.\n");
scanning = 0;
+ }
+
+ /* Changed: not associated -> associated */
+ if (!a && associated) {
+ if (set_current_ap(&associated_ap) < 0)
+ goto finish;
- } else if (!r) {
-
+ daemon_log(LOG_INFO, "Associated.\n");
scanning = 0;
+ }
+
+ if (scanning) {
+ int r;
+ struct ap_info *ai = NULL;
- if (!associated) {
-
- if (set_current_ap(ai ? &ai->ap : NULL) < 0)
+ if ((r = read_scan(i, &ai)) < 0) {
+ if (!use_ifmonitor)
goto finish;
+
+ scanning = 0;
+
+ } else if (!r) {
+
+ scanning = 0;
+
+ if (!associated) {
+
+ if (set_current_ap(ai ? &ai->ap : NULL) < 0)
+ goto finish;
+ }
}
}
}
@@ -416,6 +430,18 @@ int go(struct interface *i) {
case SIGCHLD:
break;
+
+ case SIGUSR1:
+ daemon_log(LOG_INFO, "SIGUSR1: Daemon suspended (#%i)", ++paused);
+ break;
+
+ case SIGUSR2:
+ if (paused > 0) {
+ daemon_log(LOG_INFO, "SIGUSR2: Daemon resumed (#%i)", paused);
+ force_assoc_check = ! --paused;
+ }
+
+ break;
default:
daemon_log(LOG_INFO, "Ignoring unknown signal %s", strsignal(sig));
@@ -425,10 +451,10 @@ int go(struct interface *i) {
}
if (next_scan == (time_t) -1 && !scanning)
- if (!disabled && !associated)
+ if (!disabled && !associated && !paused)
next_scan = time(NULL) + scan_interval;
- if (disabled || associated) {
+ if (disabled || associated || paused) {
scanning = 0;
next_scan = (time_t) -1;
}
@@ -464,6 +490,9 @@ void usage(char *p) {
" -s --no-syslog Do not use syslog, use stderr instead (for debugging) (%s)\n"
" -i --iface=IFACE Specify network interface (%s)\n"
" -w --wait-on-fork Wait until daemon fork finished (%s)\n"
+#ifdef DAEMON_PID_FILE_KILL_WAIT_AVAILABLE
+ " -W --wait-on-kill When run with -k, wait until the daemon died (%s)\n"
+#endif
" -M --monitor Use interface monitoring (%s)\n"
" -e --no-event Don't use wireless event API (%s)\n"
" -t --scan-interval=SECS Specify scan interval (%i)\n"
@@ -471,12 +500,18 @@ void usage(char *p) {
" -h --help Show this help\n"
" -k --kill Kill a running daemon\n"
" -c --check-running Check if a daemon is currently running\n"
- " -v --version Show version\n",
+ " -v --version Show version\n"
+ " -S --suspend Suspend running daemon\n"
+ " -R --resume Resume running daemon\n"
+ " -r --issue-scan Tell running daemon to issue a new scan immediately\n",
p, p,
!daemonize ? "on" : "off",
!use_syslog ? "on" : "off",
interface_name,
wait_on_fork ? "on" : "off",
+#ifdef DAEMON_PID_FILE_KILL_WAIT_AVAILABLE
+ wait_on_kill ? "on" : "off",
+#endif
use_ifmonitor ? "on" : "off",
use_assocwatch ? "off" : "on",
scan_interval,
@@ -489,6 +524,9 @@ void parse_args(int argc, char *argv[]) {
{"no-syslog", no_argument, 0, 's'},
{"iface", required_argument, 0, 'i'},
{"wait-on-fork", no_argument, 0, 'w'},
+#ifdef DAEMON_PID_FILE_KILL_WAIT_AVAILABLE
+ {"wait-on-kill", no_argument, 0, 'W'},
+#endif
{"monitor", no_argument, 0, 'M'},
{"no-event", no_argument, 0, 'e'},
{"scan-interval", required_argument, 0, 't'},
@@ -497,15 +535,18 @@ void parse_args(int argc, char *argv[]) {
{"kill", no_argument, 0, 'k'},
{"check-running", no_argument, 0, 'c'},
{"version", no_argument, 0, 'v'},
+ {"suspend", no_argument, 0, 'S'},
+ {"resume", no_argument, 0, 'R'},
+ {"issue-scan", no_argument, 0, 'r'},
{0, 0, 0, 0}
};
int option_index = 0;
- int _help = 0, _kill = 0, _check = 0, _version = 0;
+ int _help = 0, _kill = 0, _check = 0, _version = 0, _suspend = 0, _resume = 0, _issuescan = 0;
for (;;) {
int c;
- if ((c = getopt_long(argc, argv, "nsi:whkcvMet:p:", long_options, &option_index)) < 0)
+ if ((c = getopt_long(argc, argv, "nsi:whkcvMet:p:SRr", long_options, &option_index)) < 0)
break;
switch (c) {
@@ -527,6 +568,20 @@ void parse_args(int argc, char *argv[]) {
wait_on_fork = !wait_on_fork;
break;
+#ifdef DAEMON_PID_FILE_KILL_WAIT_AVAILABLE
+ case 'W':
+ wait_on_kill = !wait_on_kill;
+ break;
+#endif
+ case 'S':
+ _suspend = 1;
+ break;
+ case 'R':
+ _resume = 1;
+ break;
+ case 'z':
+ _issuescan = 1;
+ break;
case 'M':
use_ifmonitor = !use_ifmonitor;
break;
@@ -583,8 +638,17 @@ void parse_args(int argc, char *argv[]) {
exit(0);
}
- if (_kill) {
- if (daemon_pid_file_kill(SIGINT) < 0) {
+ if (_kill || _resume || _suspend || _issuescan) {
+ int rv;
+
+#ifdef DAEMON_PID_FILE_KILL_WAIT_AVAILABLE
+ if (_kill && wait_on_kill)
+ rv = daemon_pid_file_kill_wait(SIGINT, 5);
+ else
+#endif
+ rv = daemon_pid_file_kill(_kill ? SIGINT : (_resume ? SIGUSR2 : (_issuescan ? SIGHUP : SIGUSR1)));
+
+ if (rv < 0) {
daemon_log(LOG_ERR, "Failed to kill daemon. (%s)", strerror(errno));
exit(6);
}