summaryrefslogtreecommitdiffstats
path: root/src/waproamd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/waproamd.c')
-rw-r--r--src/waproamd.c180
1 files changed, 102 insertions, 78 deletions
diff --git a/src/waproamd.c b/src/waproamd.c
index 0e2c719..23884bf 100644
--- a/src/waproamd.c
+++ b/src/waproamd.c
@@ -50,10 +50,13 @@ char *interface_name = NULL;
int interface_index = -1;
int disabled = 0,
- associated = 0;
+ associated = 0,
+ do_status_check = 0;
-struct hw_addr associated_ap;
-struct hw_addr current_ap;
+struct ap_info associated_ap;
+
+struct ap_info current_ap;
+int current_ap_valid = 0;
int use_assocwatch = 1,
use_ifmonitor = 0,
@@ -85,51 +88,70 @@ int issue_scan(struct interface *i) {
return 0;
}
-void get_script_path(char *path, int l, struct hw_addr *ap, int uc) {
+int get_script_path(char *path, int l, struct ap_info *ai) {
assert(path && l);
- if (!ap) {
+ if (!ai) {
snprintf(path, l, "%s/default", SCRIPTDIR);
- return;
+ return 0;
}
- snprintf(path, l, uc ? "%s/%02X:%02X:%02X:%02X:%02X:%02X": "%s/%02x:%02x:%02x:%02x:%02x:%02x",
+ snprintf(path, l, "%s/%02X:%02X:%02X:%02X:%02X:%02X",
+ SCRIPTDIR,
+ ai->ap.addr[0], ai->ap.addr[1], ai->ap.addr[2],
+ ai->ap.addr[3], ai->ap.addr[4], ai->ap.addr[5]);
+
+ if (!access(path, X_OK))
+ return 0;
+
+ snprintf(path, l, "%s/%02x:%02x:%02x:%02x:%02x:%02x",
SCRIPTDIR,
- ap->addr[0], ap->addr[1], ap->addr[2],
- ap->addr[3], ap->addr[4], ap->addr[5]);
+ ai->ap.addr[0], ai->ap.addr[1], ai->ap.addr[2],
+ ai->ap.addr[3], ai->ap.addr[4], ai->ap.addr[5]);
+
+ if (!access(path, X_OK))
+ return 0;
+
+ if (ai->essid[0]) {
+ snprintf(path, l, "%s/essid:%s",
+ SCRIPTDIR,
+ escape_essid(ai->essid));
+
+ if (!access(path, X_OK))
+ return 0;
+ }
+
+ return -1;
}
-struct ap_info selected_ap;
-int selected_ap_has_script;
-int selected_ap_valid;
+struct ap_info scan_ap;
+int scan_ap_has_script;
+int scan_ap_valid;
-static int scan_result_cb(struct ap_info*ap) {
- int b;
+static int scan_result_cb(struct ap_info*ai) {
+ int f;
char path[PATH_MAX];
- assert(ap);
- get_script_path(path, sizeof(path), &ap->ap, 0);
- if (!(b = !access(path, X_OK))) {
- get_script_path(path, sizeof(path), &ap->ap, 1);
- b = !access(path, X_OK);
- }
-
- if (selected_ap_valid) {
+ assert(ai);
- if (!b || selected_ap_has_script)
- return 0;
- }
-
- memcpy(&selected_ap, ap, sizeof(struct ap_info));
- selected_ap_valid = 1;
- selected_ap_has_script = 1;
+ /* Found something suitable earlier */
+ if (scan_ap_valid && scan_ap_has_script)
+ return 0;
+
+ f = get_script_path(path, sizeof(path), ai);
+ if (scan_ap_valid && !f)
+ return 0;
+
+ memcpy(&scan_ap, ai, sizeof(struct ap_info));
+ scan_ap_valid = 1;
+ scan_ap_has_script = !f;
return 0;
}
int read_scan(struct interface *i, struct ap_info **ap) {
int r;
- selected_ap_valid = 0;
- selected_ap_has_script = 0;
+ scan_ap_valid = 0;
+ scan_ap_has_script = 0;
if ((r = iw_scan_result(i, scan_result_cb)) < 0)
return -1;
@@ -137,48 +159,55 @@ int read_scan(struct interface *i, struct ap_info **ap) {
if (r == 1)
return 1;
- *ap = selected_ap_valid ? &selected_ap : NULL;
+ *ap = scan_ap_valid ? &scan_ap : NULL;
return 0;
}
-int run_script(struct hw_addr *ap, const char *arg) {
+int run_script(struct ap_info *ai, const char *arg) {
+ char t[32];
char path[PATH_MAX];
- get_script_path(path, sizeof(path), ap, 0);
-
- if (access(path, X_OK) < 0) {
- get_script_path(path, sizeof(path), ap, 1);
-
- if (access(path, X_OK) < 0)
- get_script_path(path, sizeof(path), NULL, 0);
- }
+ if (get_script_path(path, sizeof(path), ai) < 0)
+ get_script_path(path, sizeof(path), NULL);
+ setenv("IFACE", interface_name, 1);
+ if (!ai->adhoc) {
+ snprint_hw_addr(t, sizeof(t), &ai->ap);
+ setenv("AP", t, 1);
+ } else
+ setenv("AP", "n.a.", 1);
+
+ setenv("ESSID", ai->essid, 1);
+ setenv("ESSID_ESCAPED", escape_essid(ai->essid), 1);
+ setenv("ADHOC", ai->adhoc ? "YES" : "NO", 1);
+
return log_exec(SCRIPTDIR, path, arg);
};
-int set_current_ap(struct hw_addr *a) {
- char t[32];
+int set_current_ap(struct ap_info *a) {
- if (!a)
- a = &null_ap;
-
- if (!hw_addr_equal(a, &current_ap)) {
+ if ((a && current_ap_valid && !iw_ap_info_equal(a, &current_ap)) ||
+ (!!a != !!current_ap_valid)) {
- if (!hw_addr_equal(&current_ap, &null_ap)) {
+ if (current_ap_valid) {
if (run_script(&current_ap, "stop") < 0)
return -1;
}
-
- memcpy(&current_ap, a, sizeof(struct hw_addr));
- snprint_hw_addr(t, sizeof(t), &current_ap);
- setenv("AP", t, 1);
- setenv("IFACE", interface_name, 1);
+ if ((current_ap_valid = !!a))
+ memcpy(&current_ap, a, sizeof(struct ap_info));
- if (!hw_addr_equal(&current_ap, &null_ap)) {
- daemon_log(LOG_INFO, "Selected new AP %s", t);
+ if (current_ap_valid) {
+
+ if (current_ap.adhoc)
+ daemon_log(LOG_INFO, "Selected new ad hoc network with ESSID '%s'", escape_essid(a->essid));
+ else {
+ char t[20];
+ snprint_hw_addr(t, sizeof(t), &current_ap.ap);
+ daemon_log(LOG_INFO, "Selected new AP %s with ESSID", t, escape_essid(a->essid));
+ }
if (run_script(&current_ap, "start") < 0)
return -1;
@@ -205,13 +234,11 @@ int assocwatch_cb(int index, struct hw_addr *a) {
if (get_ifname(index, name, sizeof(name)) < 0)
return -1;
- if (!strcmp(name, interface_name)) {
- interface_index = index;
- disabled = 0;
- if ((associated = !!a))
- memcpy(&associated_ap, a, sizeof(struct hw_addr));
- }
+ if (strcmp(name, interface_name))
+ return 0;
+ do_status_check = 1;
+
return 0;
}
@@ -221,7 +248,6 @@ int go(struct interface *i) {
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" : "");
@@ -250,8 +276,9 @@ int go(struct interface *i) {
disabled = 0;
memset(&current_ap, 0, sizeof(current_ap));
+ current_ap_valid = 0;
- if ((associated = interface_is_assoc(i, &associated_ap)) < 0) {
+ if ((associated = iw_assoc(i, &associated_ap)) < 0) {
if (!use_ifmonitor)
goto finish;
@@ -270,7 +297,7 @@ int go(struct interface *i) {
daemon_log(LOG_INFO, "Initialization complete.");
- set_current_ap(&associated_ap);
+ set_current_ap(associated ? &associated_ap : NULL);
next_scan = associated || disabled ? (time_t) -1 : 0;
if (daemonize && wait_on_fork) {
@@ -298,7 +325,7 @@ int go(struct interface *i) {
next_scan = (time_t) -1;
}
- if (force_assoc_check) {
+ if (do_status_check) {
tv.tv_sec = 0;
tv.tv_usec = 0;
ptv = &tv;
@@ -342,19 +369,20 @@ int go(struct interface *i) {
if (nlapi_work(0) < 0)
goto finish;
- if (force_assoc_check || (!disabled && !use_assocwatch && !paused)) {
+ if (do_status_check || (!use_assocwatch && !disabled && !paused)) {
daemon_log(LOG_INFO, "Querying association status");
- if ((associated = interface_is_assoc(i, &associated_ap)) < 0) {
+ if ((associated = iw_assoc(i, &associated_ap)) < 0) {
if (!use_ifmonitor)
goto finish;
associated = 0;
}
+
}
- force_assoc_check = 0;
+ do_status_check = 0;
if (paused) {
@@ -413,16 +441,11 @@ int go(struct interface *i) {
if (!associated) {
- if (ai) {
- if (iw_tune(i, ai) < 0)
- goto finish;
+ if (ai && iw_tune(i, ai) < 0)
+ goto finish;
- if (set_current_ap(&ai->ap) < 0)
- goto finish;
- } else {
- if (set_current_ap(NULL) < 0)
- goto finish;
- }
+ if (set_current_ap(ai) < 0)
+ goto finish;
}
}
}
@@ -465,7 +488,8 @@ int go(struct interface *i) {
case SIGUSR2:
if (paused > 0) {
daemon_log(LOG_INFO, "SIGUSR2: Daemon resumed (#%i)", paused--);
- force_assoc_check = !paused;
+ if (!paused)
+ do_status_check = 1;
}
break;