Close WPA listeners when we lose the connection.
[dhcpcd-ui] / src / dhcpcd-qt / dhcpcd-qt.cpp
index 57c278e5cbfd4326ffe6c4b559da12981b148347..6cb9d9a9acad2a9a1acdd137edddaa34b30ec8f2 100644 (file)
@@ -66,24 +66,39 @@ DhcpcdQt::DhcpcdQt()
                exit(EXIT_FAILURE);
                return;
        }
+       dhcpcd_set_progname(con, "dhcpcd-qt");
        dhcpcd_set_status_callback(con, dhcpcd_status_cb, this);
        dhcpcd_set_if_callback(con, dhcpcd_if_cb, this);
        dhcpcd_wpa_set_scan_callback(con, dhcpcd_wpa_scan_cb, this);
+       dhcpcd_wpa_set_status_callback(con, dhcpcd_wpa_status_cb, this);
        tryOpen();
 }
 
 DhcpcdQt::~DhcpcdQt()
 {
 
-       qDeleteAll(*wis);
-       delete wis;
-
        if (con != NULL) {
                dhcpcd_close(con);
                dhcpcd_free(con);
        }
 
        free(lastStatus);
+
+       qDeleteAll(*wis);
+       delete wis;
+
+}
+
+DHCPCD_CONNECTION *DhcpcdQt::getConnection()
+{
+
+       return con;
+}
+
+QList<DhcpcdWi *> *DhcpcdQt::getWis()
+{
+
+       return wis;
 }
 
 void DhcpcdQt::animate()
@@ -173,12 +188,23 @@ void DhcpcdQt::statusCallback(const char *status)
        if (strcmp(status, "down") == 0) {
                aniTimer->stop();
                aniCounter = 0;
+               onLine = carrier = false;
                setIcon("status", "network-offline");
+               trayIcon->setToolTip(tr("Not connected to dhcpcd"));
+               /* Close down everything */
                if (notifier) {
                        delete notifier;
                        notifier = NULL;
                }
-               trayIcon->setToolTip(tr("Not connected to dhcpcd"));
+               if (ssidMenu) {
+                       delete ssidMenu;
+                       ssidMenu = NULL;
+               }
+               if (preferences) {
+                       delete preferences;
+                       preferences = NULL;
+               }
+               preferencesAction->setEnabled(false);
        } else {
                bool refresh;
 
@@ -317,14 +343,44 @@ void DhcpcdQt::dhcpcd_wpa_scan_cb(DHCPCD_WPA *wpa, void *d)
        dhcpcdQt->scanCallback(wpa);
 }
 
+void DhcpcdQt::wpaStatusCallback(DHCPCD_WPA *wpa, const char *status)
+{
+       DHCPCD_IF *i;
+
+       i = dhcpcd_wpa_if(wpa);
+       qDebug("%s: WPA status %s", i->ifname, status);
+       if (strcmp(status, "down") == 0) {
+               DhcpcdWi *wi = findWi(wpa);
+               if (wi) {
+                       wis->removeOne(wi);
+                       delete wi;
+               }
+       }
+}
+
+void DhcpcdQt::dhcpcd_wpa_status_cb(DHCPCD_WPA *wpa, const char *status,
+    void *d)
+{
+       DhcpcdQt *dhcpcdQt = (DhcpcdQt *)d;
+
+       dhcpcdQt->wpaStatusCallback(wpa, status);
+}
+
 void DhcpcdQt::tryOpen() {
-       int fd = dhcpcd_open(con);
+       int fd = dhcpcd_open(con, true);
        static int last_error;
 
        if (fd == -1) {
+               if (errno == EACCES || errno == EPERM) {
+                       if ((fd = dhcpcd_open(con, false)) != -1)
+                               goto unprived;
+               }
                if (errno != last_error) {
                        last_error = errno;
-                       qCritical("dhcpcd_open: %s", strerror(errno));
+                       const char *errt = strerror(errno);
+                       qCritical("dhcpcd_open: %s", errt);
+                       trayIcon->setToolTip(
+                           tr("Error connecting to dhcpcd: %1").arg(errt));
                }
                if (retryOpenTimer == NULL) {
                        retryOpenTimer = new QTimer(this);
@@ -335,6 +391,7 @@ void DhcpcdQt::tryOpen() {
                return;
        }
 
+unprived:
        /* Start listening to WPA events */
        dhcpcd_wpa_start(con);
 
@@ -345,6 +402,8 @@ void DhcpcdQt::tryOpen() {
 
        notifier = new QSocketNotifier(fd, QSocketNotifier::Read);
        connect(notifier, SIGNAL(activated(int)), this, SLOT(dispatch()));
+
+       preferencesAction->setEnabled(dhcpcd_privileged(con));
 }
 
 void DhcpcdQt::dispatch() {
@@ -461,6 +520,7 @@ void DhcpcdQt::createActions()
 
        preferencesAction = new QAction(tr("&Preferences"), this);
        preferencesAction->setIcon(QIcon::fromTheme("preferences-system-network"));
+       preferencesAction->setEnabled(false);
        connect(preferencesAction, SIGNAL(triggered()),
            this, SLOT(showPreferences()));