From 21c20545874b31e6cf3b2dd87c678f9ca1cde365 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 5 Nov 2003 23:31:31 +0000 Subject: isuspend feature git-svn-id: file:///home/lennart/svn/public/waproamd/trunk@33 022f378f-78c4-0310-b860-d162c87e6274 --- src/nlapi.c | 2 +- src/waproamd.c | 172 +++++++++++++++++++++++++++++++++++++++------------------ 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); } -- cgit