Set a progname to send with our command.
[dhcpcd-ui] / src / libdhcpcd / dhcpcd.c
index 9efc95041b116ecede20edf45c09ec422c38ade4..508137ce51b6c904505082b6a251590a5dbe92cd 100644 (file)
@@ -65,9 +65,9 @@ static const char * const dhcpcd_types[] =
 
 static ssize_t
 dhcpcd_command_fd(DHCPCD_CONNECTION *con,
-    int fd, const char *cmd, char **buffer)
+    int fd, bool progname, const char *cmd, char **buffer)
 {
-       size_t len;
+       size_t pl, cl, len;
        ssize_t bytes;
        char buf[1024], *p;
        char *nbuf;
@@ -76,15 +76,28 @@ dhcpcd_command_fd(DHCPCD_CONNECTION *con,
         * Each argument is NULL seperated.
         * We may need to send a space one day, so the API
         * in this function may need to be improved */
-       len = strlen(cmd) + 1;
+       cl = strlen(cmd);
+       if (progname) {
+               pl = strlen(con->progname);
+               len = pl + 1 + cl + 1;
+       } else {
+               pl = 0;
+               len = cl + 1;
+       }
        if (con->terminate_commands)
                len++;
        if (len > sizeof(buf)) {
                errno = ENOBUFS;
                return -1;
        }
-       strlcpy(buf, cmd, sizeof(buf));
        p = buf;
+       if (progname) {
+               memcpy(buf, con->progname, pl);
+               buf[pl] = '\0';
+               p = buf + pl + 1;
+       }
+       memcpy(p, cmd, cl);
+       p[cl] = '\0';
        while ((p = strchr(p, ' ')) != NULL)
                *p++ = '\0';
        if (con->terminate_commands) {
@@ -115,7 +128,14 @@ ssize_t
 dhcpcd_command(DHCPCD_CONNECTION *con, const char *cmd, char **buffer)
 {
 
-       return dhcpcd_command_fd(con, con->command_fd, cmd, buffer);
+       return dhcpcd_command_fd(con, con->command_fd, true, cmd, buffer);
+}
+
+static ssize_t
+dhcpcd_ctrl_command(DHCPCD_CONNECTION *con, const char *cmd, char **buffer)
+{
+
+       return dhcpcd_command_fd(con, con->command_fd, false, cmd, buffer);
 }
 
 bool
@@ -141,19 +161,24 @@ dhcpcd_command_arg(DHCPCD_CONNECTION *con, const char *cmd, const char *arg,
        size_t cmdlen, len;
 
        cmdlen = strlen(cmd);
-       len = cmdlen + strlen(arg) + 2;
+       if (arg)
+               len = cmdlen + strlen(arg) + 2;
+       else
+               len = cmdlen + 1;
        if (!dhcpcd_realloc(con, len))
                return -1;
        strlcpy(con->buf, cmd, con->buflen);
-       con->buf[cmdlen] = ' ';
-       strlcpy(con->buf + cmdlen + 1, arg, con->buflen - 1 - cmdlen);
+       if (arg) {
+               con->buf[cmdlen] = ' ';
+               strlcpy(con->buf + cmdlen + 1, arg, con->buflen - 1 - cmdlen);
+       }
 
-       return dhcpcd_command_fd(con, con->command_fd, con->buf, buffer);
+       return dhcpcd_command_fd(con, con->command_fd, true, con->buf, buffer);
 }
 
 
 static int
-dhcpcd_connect(int opts)
+dhcpcd_connect(const char *path, int opts)
 {
        int fd;
        socklen_t len;
@@ -165,7 +190,7 @@ dhcpcd_connect(int opts)
 
        memset(&sun, 0, sizeof(sun));
        sun.sun_family = AF_UNIX;
-       strlcpy(sun.sun_path, DHCPCD_SOCKET, sizeof(sun.sun_path));
+       strlcpy(sun.sun_path, path, sizeof(sun.sun_path));
        len = (socklen_t)SUN_LEN(&sun);
        if (connect(fd, (struct sockaddr *)&sun, len) == 0)
                return fd;
@@ -375,7 +400,7 @@ dhcpcd_new_if(DHCPCD_CONNECTION *con, char *data, size_t len)
         } else if (strcmp(type, "link")) {
                /* If link is down, ignore it */
                e = dhcpcd_get_if(con, ifname, "link");
-               if (e && strcmp(e->reason, "NOCARRIER") == 0)
+               if (e && !e->up)
                        return NULL;
        }
 
@@ -543,9 +568,26 @@ dhcpcd_new(void)
        con = calloc(1, sizeof(*con));
        con->command_fd = con->listen_fd = -1;
        con->open = false;
+       con->progname = "libdhcpcd";
        return con;
 }
 
+void
+dhcpcd_set_progname(DHCPCD_CONNECTION *con, const char *progname)
+{
+
+       assert(con);
+       con->progname = progname;
+}
+
+const char *
+dhcpcd_get_progname(const DHCPCD_CONNECTION *con)
+{
+
+       assert(con);
+       return con->progname;
+}
+
 #ifndef __GLIBC__
 /* Good enough for our needs */
 static int
@@ -572,8 +614,9 @@ strverscmp(const char *s1, const char *s2)
 #endif
 
 int
-dhcpcd_open(DHCPCD_CONNECTION *con)
+dhcpcd_open(DHCPCD_CONNECTION *con, bool privileged)
 {
+       const char *path = privileged ? DHCPCD_SOCKET : DHCPCD_UNPRIV_SOCKET;
        char cmd[128];
        ssize_t bytes;
        size_t nifs, n;
@@ -586,28 +629,29 @@ dhcpcd_open(DHCPCD_CONNECTION *con)
                return -1;
        }
        /* We need to block the command fd */
-       con->command_fd = dhcpcd_connect(0);
+       con->command_fd = dhcpcd_connect(path, 0);
        if (con->command_fd == -1)
                goto err_exit;
 
        con->terminate_commands = false;
-       if (dhcpcd_command(con, "--version", &con->version) <= 0)
+       if (dhcpcd_ctrl_command(con, "--version", &con->version) <= 0)
                goto err_exit;
        con->terminate_commands =
            strverscmp(con->version, "6.4.1") >= 0 ? true : false;
 
-       if (dhcpcd_command(con, "--getconfigfile", &con->cffile) <= 0)
+       if (dhcpcd_ctrl_command(con, "--getconfigfile", &con->cffile) <= 0)
                goto err_exit;
 
        con->open = true;
+       con->privileged = privileged;
        update_status(con, NULL);
 
-       con->listen_fd = dhcpcd_connect(SOCK_NONBLOCK);
+       con->listen_fd = dhcpcd_connect(path, SOCK_NONBLOCK);
        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);
+       dhcpcd_command_fd(con, con->listen_fd, false, "--listen", NULL);
+       dhcpcd_command_fd(con, con->command_fd, false, "--getinterfaces", NULL);
        bytes = read(con->command_fd, cmd, sizeof(nifs));
        if (bytes != sizeof(nifs))
                goto err_exit;
@@ -634,6 +678,14 @@ dhcpcd_get_fd(DHCPCD_CONNECTION *con)
        return con->listen_fd;
 }
 
+bool
+dhcpcd_privileged(DHCPCD_CONNECTION *con)
+{
+
+       assert(con);
+       return con->privileged;
+}
+
 const char *
 dhcpcd_status(DHCPCD_CONNECTION *con)
 {
@@ -681,7 +733,9 @@ dhcpcd_set_status_callback(DHCPCD_CONNECTION *con,
 void
 dhcpcd_close(DHCPCD_CONNECTION *con)
 {
-       DHCPCD_WPA *wpa;
+       DHCPCD_IF *nif;
+       DHCPCD_WPA *nwpa;
+       DHCPCD_WI_HIST *nh;
 
        assert(con);
 
@@ -689,8 +743,24 @@ dhcpcd_close(DHCPCD_CONNECTION *con)
 
        /* 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)
+       while (con->wpa) {
+               nwpa = con->wpa->next;
                dhcpcd_wpa_close(con->wpa);
+               free(con->wpa);
+               con->wpa = nwpa;
+       }
+       while (con->wi_history) {
+               nh = con->wi_history->next;
+               free(con->wi_history);
+               con->wi_history = nh;
+       }
+       while (con->interfaces) {
+               nif = con->interfaces->next;
+               free(con->interfaces->data);
+               free(con->interfaces->last_message);
+               free(con->interfaces);
+               con->interfaces = nif;
+       }
 
        if (con->command_fd != -1)
                shutdown(con->command_fd, SHUT_RDWR);
@@ -723,6 +793,14 @@ dhcpcd_close(DHCPCD_CONNECTION *con)
        }
 }
 
+void
+dhcpcd_free(DHCPCD_CONNECTION *con)
+{
+
+       assert(con);
+       free(con);
+}
+
 DHCPCD_CONNECTION *
 dhcpcd_if_connection(DHCPCD_IF *i)
 {
@@ -764,7 +842,9 @@ dhcpcd_if_message(DHCPCD_IF *i, bool *new_msg)
                                reason = _("Not associated");
                } else
                        reason = _("Cable unplugged");
-       } else if (strcmp(i->reason, "UNKNOWN") == 0)
+       } else if (strcmp(i->reason, "DEPARTED") == 0)
+               reason = _("Departed");
+       else if (strcmp(i->reason, "UNKNOWN") == 0)
                reason = _("Unknown link state");
        else if (strcmp(i->reason, "FAIL") == 0)
                reason = _("Automatic configuration not possible");
@@ -822,32 +902,3 @@ dhcpcd_if_message(DHCPCD_IF *i, bool *new_msg)
 
        return msg;
 }
-
-void
-dhcpcd_free(DHCPCD_CONNECTION *con)
-{
-       DHCPCD_IF *nif;
-       DHCPCD_WPA *nwpa;
-       DHCPCD_WI_HIST *nh;
-
-       assert(con);
-       while (con->interfaces) {
-               nif = con->interfaces->next;
-               free(con->interfaces->data);
-               free(con->interfaces->last_message);
-               free(con->interfaces);
-               con->interfaces = nif;
-       }
-       while (con->wpa) {
-               nwpa = con->wpa->next;
-               dhcpcd_wpa_close(con->wpa);
-               free(con->wpa);
-               con->wpa = nwpa;
-       }
-       while (con->wi_history) {
-               nh = con->wi_history->next;
-               free(con->wi_history);
-               con->wi_history = nh;
-       }
-       free(con);
-}