Add guards when closing connections so that we can call the cb
authorRoy Marples <roy@marples.name>
Tue, 2 Sep 2014 21:14:49 +0000 (21:14 +0000)
committerRoy Marples <roy@marples.name>
Tue, 2 Sep 2014 21:14:49 +0000 (21:14 +0000)
with the fd still there so the application can stop watching it.
Link against libintl when needed.
Numerous fixes when dhcpcd is started/stopped/started.

Makefile
configure
src/Makefile
src/dhcpcd-gtk/main.c
src/dhcpcd-qt/dhcpcd-qt.cpp
src/dhcpcd-qt/dhcpcd-qt.h
src/dhcpcd-qt/dhcpcd-qt.pro
src/libdhcpcd/dhcpcd.c
src/libdhcpcd/dhcpcd.h
src/libdhcpcd/wpa.c

index 8c1928f6fbc7c67bf1292cb0095cb19f069ac5b5..7a4ed6be4d016ba465f988a53bd7021ff5de1d7f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,14 +1,14 @@
 PROG=          dhcpcd-ui
 VERSION=       0.7.0
 
-.PHONY:                icons
-
-SUBDIR=                src icons
-
 TOPDIR=                .
 include ${TOPDIR}/iconfig.mk
 include ${MKDIR}/subdir.mk
 
+.PHONY:                icons
+
+SUBDIR=                src ${ICONS}
+
 GITREF?=       HEAD
 DISTPREFIX?=   ${PROG}-${VERSION}
 DISTFILE?=     ${DISTPREFIX}.tar.bz2
index 8da4f077ed7ae320f9a21c7057e742566d5afd3e..867263c5b618357c05f10e9ad7f8740f86463067 100755 (executable)
--- a/configure
+++ b/configure
@@ -254,6 +254,7 @@ EOF
        elif $XCC _gettext.c -o _gettext -lintl 2>/dev/null; then
                GETTEXT="yes (-lintl)"
                LIB_INTL=-lintl
+               QMAKE_CONFIG="CONFIG+=has_libintl"
        else
                GETTEXT=no
        fi
@@ -364,11 +365,10 @@ elif [ -n "$WITH_QT" -a "$WITH_QT" != no ]; then
        fi
 fi
 
-if [ -z "$UI" ]; then
-       echo "$0: no UI is available, not building." >&2
-       exit 1
+if [ -n "$UI" ]; then
+       echo "ICONS=            icons" >>$CONFIG_MK
 fi
-echo "UI=              $UI" >>config.mk
+echo "UI=              $UI" >>$CONFIG_MK
 
 echo
 echo "   SYSCONFDIR =          $SYSCONFDIR"
@@ -382,7 +382,7 @@ echo
 echo "MKDIR=           \${TOPDIR}/mk" >>$CONFIG_MK
 
 if $DHCPCD_QT; then
-       if ! (cd src/dhcpcd-qt; qmake dhcpcd-qt.pro); then
+       if ! (cd src/dhcpcd-qt; qmake $QMAKE_CONFIG dhcpcd-qt.pro); then
                echo "$0: failed to configure dhcpcd-qt" >&2
                exit 1
        fi
index cf96e6292ee2238685eb469e5a226a7d49f035ba..c51eac1d590ea86e4d7fd9c668470ed01fc20120 100644 (file)
@@ -1,6 +1,6 @@
 TOPDIR=                ..
 include ${TOPDIR}/iconfig.mk
 
-SUBDIR=                libdhcpcd ${UI}
+SUBDIR=                libdhcpcd dhcpcd-online ${UI}
 
 include ${MKDIR}/subdir.mk
index 79749978fef6c2089cf7c3d9ae1559d60f8f7c51..fb6575713126b3914fcce9c091e4d312b3ab521f 100644 (file)
@@ -233,48 +233,6 @@ notify(const char *title, const char *msg, const char *icon)
 #  define notify(a, b, c)
 #endif
 
-static void
-dhcpcd_status_cb(DHCPCD_CONNECTION *con, const char *status, _unused void *data)
-{
-       static char *last = NULL;
-       const char *msg;
-       bool refresh;
-       WI_SCAN *w;
-
-       g_message("Status changed to %s", status);
-       if (g_strcmp0(status, "down") == 0) {
-               msg = N_(last ?
-                   "Connection to dhcpcd lost" : "dhcpcd not running");
-               if (ani_timer != 0) {
-                       g_source_remove(ani_timer);
-                       ani_timer = 0;
-                       ani_counter = 0;
-               }
-               gtk_status_icon_set_from_icon_name(status_icon,
-                   "network-offline");
-               gtk_status_icon_set_tooltip_text(status_icon, msg);
-               notify(_("No network"), msg, "network-offline");
-               dhcpcd_prefs_abort();
-               while (wi_scans) {
-                       w = wi_scans->next;
-                       dhcpcd_wi_scans_free(wi_scans->scans);
-                       g_free(wi_scans);
-                       wi_scans = w;
-               }
-       } else {
-               if ((last == NULL || g_strcmp0(last, "down") == 0)) {
-                       g_message(_("Connected to %s-%s"), "dhcpcd",
-                           dhcpcd_version(con));
-                       refresh = true;
-               } else
-                       refresh = false;
-               update_online(con, refresh);
-       }
-
-       g_free(last);
-       last = g_strdup(status);
-}
-
 static struct watch *
 dhcpcd_findwatch(int fd, gpointer data, struct watch **last)
 {
@@ -360,6 +318,50 @@ dhcpcd_watch(int fd,
        return TRUE;
 }
 
+static void
+dhcpcd_status_cb(DHCPCD_CONNECTION *con, const char *status, _unused void *data)
+{
+       static char *last = NULL;
+       const char *msg;
+       bool refresh;
+       WI_SCAN *w;
+
+       g_message("Status changed to %s", status);
+       if (g_strcmp0(status, "down") == 0) {
+               msg = N_(last ?
+                   "Connection to dhcpcd lost" : "dhcpcd not running");
+               if (ani_timer != 0) {
+                       g_source_remove(ani_timer);
+                       ani_timer = 0;
+                       ani_counter = 0;
+               }
+               gtk_status_icon_set_from_icon_name(status_icon,
+                   "network-offline");
+               gtk_status_icon_set_tooltip_text(status_icon, msg);
+               notify(_("No network"), msg, "network-offline");
+               dhcpcd_prefs_abort();
+               while (wi_scans) {
+                       w = wi_scans->next;
+                       dhcpcd_wi_scans_free(wi_scans->scans);
+                       g_free(wi_scans);
+                       wi_scans = w;
+               }
+               dhcpcd_unwatch(-1, con);
+               g_timeout_add(DHCPCD_RETRYOPEN, dhcpcd_try_open, con);
+       } else {
+               if ((last == NULL || g_strcmp0(last, "down") == 0)) {
+                       g_message(_("Connected to %s-%s"), "dhcpcd",
+                           dhcpcd_version(con));
+                       refresh = true;
+               } else
+                       refresh = false;
+               update_online(con, refresh);
+       }
+
+       g_free(last);
+       last = g_strdup(status);
+}
+
 static gboolean
 dhcpcd_cb(_unused GIOChannel *gio, _unused GIOCondition c, gpointer data)
 {
index c77ec41c196eab733d708077174af509db01f896..5d08f9f73a7cacbb57feca45de507f41e0defe56 100644 (file)
@@ -49,6 +49,7 @@ DhcpcdQt::DhcpcdQt()
        lastStatus = NULL;
        aniTimer = new QTimer(this);
        connect(aniTimer, SIGNAL(timeout()), this, SLOT(animate()));
+       notifier = NULL;
        retryOpenTimer = NULL;
 
        about = NULL;
@@ -169,14 +170,14 @@ void DhcpcdQt::statusCallback(const char *status)
 
        qDebug("Status changed to %s", status);
        if (strcmp(status, "down") == 0) {
-               QString msg;
-               if (lastStatus)
-                       msg = tr("Connection to dhcpcd lost");
-               else
-                       msg = tr("dhcpcd not running");
                aniTimer->stop();
                aniCounter = 0;
                setIcon("status", "network-offline");
+               if (notifier) {
+                       delete notifier;
+                       notifier = NULL;
+               }
+               trayIcon->setToolTip(tr("Not connected to dhcpcd"));
        } else {
                bool refresh;
 
@@ -190,6 +191,15 @@ void DhcpcdQt::statusCallback(const char *status)
 
        free(lastStatus);
        lastStatus = strdup(status);
+
+       if (strcmp(status, "down") == 0) {
+               if (retryOpenTimer == NULL) {
+                       retryOpenTimer = new QTimer(this);
+                       connect(retryOpenTimer, SIGNAL(timeout()),
+                           this, SLOT(tryOpen()));
+                       retryOpenTimer->start(DHCPCD_RETRYOPEN);
+               }
+       }
 }
 
 void DhcpcdQt::dhcpcd_status_cb(_unused DHCPCD_CONNECTION *con,
@@ -302,7 +312,7 @@ void DhcpcdQt::dhcpcd_wpa_scan_cb(DHCPCD_WPA *wpa, void *d)
        dhcpcdQt->scanCallback(wpa);
 }
 
-bool DhcpcdQt::tryOpen() {
+void DhcpcdQt::tryOpen() {
        int fd = dhcpcd_open(con);
        static int last_error;
 
@@ -317,7 +327,7 @@ bool DhcpcdQt::tryOpen() {
                            this, SLOT(tryOpen()));
                        retryOpenTimer->start(DHCPCD_RETRYOPEN);
                }
-               return false;
+               return;
        }
 
        if (retryOpenTimer) {
@@ -327,8 +337,6 @@ bool DhcpcdQt::tryOpen() {
 
        notifier = new QSocketNotifier(fd, QSocketNotifier::Read);
        connect(notifier, SIGNAL(activated(int)), this, SLOT(dispatch()));
-
-       return true;
 }
 
 void DhcpcdQt::dispatch() {
index fd4952a7e16b6dd253deeeb60d6c21d87ffebdba..6ea55bcc21306f9895a65ac9f5799663f7879d13 100644 (file)
@@ -74,6 +74,7 @@ protected:
        void closeEvent(QCloseEvent *event);
 
 private slots:
+       void tryOpen();
        void animate();
        void dispatch();
        void showAbout();
@@ -84,7 +85,6 @@ private slots:
 
 private:
        DHCPCD_CONNECTION *con;
-       bool tryOpen();
        QSocketNotifier *notifier;
        QTimer *retryOpenTimer;
        QList<DhcpcdWi *> *wis;
index d5c06ae64afda770007e27c586b7f8ab341870b0..536cb19ee9395e3087c5ffb2ec1825416aeeda8c 100644 (file)
@@ -11,4 +11,8 @@ INCLUDEPATH+=         ../libdhcpcd/
 
 LIBS+=                 -L../libdhcpcd ../libdhcpcd/libdhcpcd.a
 
+has_libintl {
+       LIBS +=         -lintl
+}
+
 QMAKE_CLEAN+=          ${TARGET}
index 491961a6f09cdd81be783cd1ccf785bcc1011595..e6c74261bd524902d08ef39cf174f6ba6fb3c23e 100644 (file)
@@ -225,7 +225,8 @@ dhcpcd_get_prefix_value(const DHCPCD_IF *i, const char *prefix, const char *var)
        return dhcpcd_get_value(i, pvar);
 }
 
-static bool strtobool(const char *var)
+static bool
+strtobool(const char *var)
 {
 
        if (var == NULL)
@@ -260,12 +261,12 @@ get_status(DHCPCD_CONNECTION *con)
 }
 
 static void
-update_status(DHCPCD_CONNECTION *con)
+update_status(DHCPCD_CONNECTION *con, const char *nstatus)
 {
-       const char *nstatus;
 
        assert(con);
-       nstatus = get_status(con);
+       if (nstatus == NULL)
+               nstatus = get_status(con);
        if (con->status == NULL || strcmp(nstatus, con->status)) {
                con->status = nstatus;
                if (con->status_cb)
@@ -521,7 +522,7 @@ dhcpcd_dispatch(DHCPCD_CONNECTION *con)
 
        /* Have to call update_status last as it could
         * cause the interface to be destroyed. */
-       update_status(con);
+       update_status(con, NULL);
 }
 
 DHCPCD_CONNECTION *
@@ -531,6 +532,7 @@ dhcpcd_new(void)
 
        con = calloc(1, sizeof(*con));
        con->command_fd = con->listen_fd = -1;
+       con->open = false;
        return con;
 }
 
@@ -568,52 +570,51 @@ dhcpcd_open(DHCPCD_CONNECTION *con)
        DHCPCD_IF *i;
 
        assert(con);
-       if (con->listen_fd != -1)
+       if (con->listen_fd != -1) {
+               if (!con->open) {
+                       errno = EISCONN;
+                       return -1;
+               }
                return con->listen_fd;
-       con->command_fd = dhcpcd_connect();
-       if (con->command_fd == -1) {
-               update_status(con);
-               return -1;
        }
+       con->command_fd = dhcpcd_connect();
+       if (con->command_fd == -1)
+               goto err_exit;
 
        con->terminate_commands = false;
        if (dhcpcd_command(con, "--version", &con->version) <= 0)
-               return -1;
+               goto err_exit;
        con->terminate_commands =
            strverscmp(con->version, "6.4.1") >= 0 ? true : false;
 
        if (dhcpcd_command(con, "--getconfigfile", &con->cffile) <= 0)
-               return -1;
+               goto err_exit;
 
        con->listen_fd = dhcpcd_connect();
-       if (con->listen_fd == -1) {
-               close(con->command_fd);
-               con->command_fd = -1;
-               update_status(con);
-               return -1;
-       }
+       if (con->listen_fd == -1)
+               goto err_exit;
        dhcpcd_command_fd(con, con->listen_fd, "--listen", NULL);
 
        dhcpcd_command_fd(con, con->command_fd, "--getinterfaces", NULL);
        bytes = read(con->command_fd, cmd, sizeof(nifs));
-       if (bytes != sizeof(nifs)) {
-               close(con->command_fd);
-               con->command_fd = -1;
-               close(con->listen_fd);
-               con->listen_fd = -1;
-       } else {
-               memcpy(&nifs, cmd, sizeof(nifs));
-               /* We don't dispatch each interface here as that
-                * causes too much notification spam when the GUI starts */
-               for (n = 0; n < nifs; n++) {
-                       i = dhcpcd_read_if(con, con->command_fd);
-                       if (i)
-                               dhcpcd_wpa_if_event(i);
-               }
+       if (bytes != sizeof(nifs))
+               goto err_exit;
+
+       memcpy(&nifs, cmd, sizeof(nifs));
+       /* We don't dispatch each interface here as that
+        * causes too much notification spam when the GUI starts */
+       for (n = 0; n < nifs; n++) {
+               i = dhcpcd_read_if(con, con->command_fd);
+               if (i)
+                       dhcpcd_wpa_if_event(i);
        }
-       update_status(con);
-
+       update_status(con, NULL);
+       con->open = true;
        return con->listen_fd;
+
+err_exit:
+       dhcpcd_close(con);
+       return -1;
 }
 
 int
@@ -675,17 +676,26 @@ dhcpcd_close(DHCPCD_CONNECTION *con)
 
        assert(con);
 
+       con->open = false;
+
        /* Shut down WPA listeners as they aren't much good without dhcpcd.
         * They'll be restarted anyway when dhcpcd comes back up. */
        for (wpa = con->wpa; wpa; wpa = wpa->next)
                dhcpcd_wpa_close(con->wpa);
 
-       if (con->command_fd != -1) {
+       if (con->command_fd != -1)
                shutdown(con->command_fd, SHUT_RDWR);
+       if (con->listen_fd != -1)
+               shutdown(con->listen_fd, SHUT_RDWR);
+
+       update_status(con, "down");
+
+       if (con->command_fd != -1) {
+               close(con->command_fd);
                con->command_fd = -1;
        }
        if (con->listen_fd != -1) {
-               shutdown(con->listen_fd, SHUT_RDWR);
+               close(con->listen_fd);
                con->listen_fd = -1;
        }
 
index b8c13669f3828a2c898a8009046035ffed8ac222..f05e6dc2a236896141ef69ef981afa8dac851ba4 100644 (file)
@@ -44,7 +44,7 @@ extern "C" {
 #define WPA_CTRL_DIR           "/var/run/wpa_supplicant"
 #endif
 
-#define DHCPCD_RETRYOPEN       1       /* seconds */
+#define DHCPCD_RETRYOPEN       100     /* milliseconds */
 #define DHCPCD_WI_HIST_MAX     10      /* Recall 10 scans for averages */
 
 #define IF_SSIDSIZE            33
@@ -121,16 +121,18 @@ typedef struct dhcpcd_wi_hist {
 typedef struct dhcpcd_wpa {
        struct dhcpcd_wpa *next;
        char ifname[IF_NAMESIZE];
+       bool open;
        int command_fd;
        char *command_path;
        int listen_fd;
        char *listen_path;
-       int attached;
+       bool attached;
        struct dhcpcd_connection *con;
 } DHCPCD_WPA;
 
 typedef struct dhcpcd_connection {
        struct dhcpcd_connection *next;
+       bool open;
        int command_fd;
        int listen_fd;
 
index 42a1f9acd4ebe00cdb852993d06e0d84b328563c..d47632170d5500a016f8edea6f54925b1e784d24 100644 (file)
@@ -140,7 +140,7 @@ dhcpcd_wpa_command_arg(DHCPCD_WPA *wpa, const char *cmd, const char *arg)
 }
 
 static bool
-dhcpcd_attach_detach(DHCPCD_WPA *wpa, int attach)
+dhcpcd_attach_detach(DHCPCD_WPA *wpa, bool attach)
 {
        char buf[10];
        ssize_t bytes;
@@ -459,13 +459,23 @@ void
 dhcpcd_wpa_close(DHCPCD_WPA *wpa)
 {
 
-       if (wpa->command_fd == -1)
+       assert(wpa);
+
+       if (wpa->command_fd == -1 || !wpa->open)
                return;
 
-       dhcpcd_attach_detach(wpa, -1);
+       wpa->open = false;
+       dhcpcd_attach_detach(wpa, false);
        shutdown(wpa->command_fd, SHUT_RDWR);
-       wpa->command_fd = -1;
        shutdown(wpa->listen_fd, SHUT_RDWR);
+
+       if (wpa->con->wpa_status_cb)
+               wpa->con->wpa_status_cb(wpa, "down",
+                   wpa->con->wpa_status_context);
+
+       close(wpa->command_fd);
+       wpa->command_fd = -1;
+       close(wpa->listen_fd);
        wpa->listen_fd = -1;
        unlink(wpa->command_path);
        free(wpa->command_path);
@@ -473,11 +483,6 @@ dhcpcd_wpa_close(DHCPCD_WPA *wpa)
        unlink(wpa->listen_path);
        free(wpa->listen_path);
        wpa->listen_path = NULL;
-
-       if (wpa->con->wpa_status_cb)
-               wpa->con->wpa_status_cb(wpa, "down",
-                   wpa->con->wpa_status_context);
-
 }
 
 DHCPCD_WPA *
@@ -518,6 +523,7 @@ DHCPCD_CONNECTION *
 dhcpcd_wpa_connection(DHCPCD_WPA *wpa)
 {
 
+       assert(wpa);
        return wpa->con;
 }
 
@@ -534,8 +540,13 @@ dhcpcd_wpa_open(DHCPCD_WPA *wpa)
        int cmd_fd, list_fd = -1;
        char *cmd_path = NULL, *list_path = NULL;
 
-       if (wpa->listen_fd != -1)
+       if (wpa->listen_fd != -1) {
+               if (!wpa->open) {
+                       errno = EISCONN;
+                       return -1;
+               }
                return wpa->listen_fd;
+       }
 
        cmd_fd = wpa_open(wpa->ifname, &cmd_path);
        if (cmd_fd == -1)
@@ -545,12 +556,13 @@ dhcpcd_wpa_open(DHCPCD_WPA *wpa)
        if (list_fd == -1)
                goto fail;
 
-       wpa->attached = 0;
+       wpa->open = true;
+       wpa->attached = false;
        wpa->command_fd = cmd_fd;
        wpa->command_path = cmd_path;
        wpa->listen_fd = list_fd;
        wpa->listen_path = list_path;
-       if (!dhcpcd_attach_detach(wpa, 1)) {
+       if (!dhcpcd_attach_detach(wpa, true)) {
                dhcpcd_wpa_close(wpa);
                return -1;
        }
@@ -578,7 +590,8 @@ int
 dhcpcd_wpa_get_fd(DHCPCD_WPA *wpa)
 {
 
-       return wpa->listen_fd;
+       assert(wpa);
+       return wpa->open ? wpa->listen_fd : -1;
 }
 
 void
@@ -586,6 +599,7 @@ dhcpcd_wpa_set_scan_callback(DHCPCD_CONNECTION *con,
     void (*cb)(DHCPCD_WPA *, void *), void *context)
 {
 
+       assert(con);
        con->wi_scanresults_cb = cb;
        con->wi_scanresults_context = context;
 }
@@ -596,6 +610,7 @@ dhcpcd_wpa_dispatch(DHCPCD_WPA *wpa)
        char buffer[256], *p;
        size_t bytes;
 
+       assert(wpa);
        bytes = (size_t)read(wpa->listen_fd, buffer, sizeof(buffer));
        if ((ssize_t)bytes == -1 || bytes == 0) {
                dhcpcd_wpa_close(wpa);