]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
dhcpcd: dump all variables and optionally all interfaces
authorRoy Marples <roy@marples.name>
Tue, 31 Mar 2020 10:51:24 +0000 (11:51 +0100)
committerRoy Marples <roy@marples.name>
Tue, 31 Mar 2020 10:51:24 +0000 (11:51 +0100)
This allows someone to view pretty much the whole state.

src/dhcpcd.c

index 9208f37c152af749d6bac4c2fcf8998a4654d552..2ffea5bdb01ee77bc2c44809d32ba477444c4486 100644 (file)
@@ -1552,26 +1552,39 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx, struct fd_list *fd,
                ctx->options |= DHCPCD_DUMPLEASE;
                size_t nifaces = 0;
 
-               for (oi = optind; oi < argc; oi++) {
-                       if ((ifp = if_find(ctx->ifaces, argv[oi])) == NULL)
-                               continue;
+               TAILQ_FOREACH(ifp, ctx->ifaces, next) {
                        if (!ifp->active)
                                continue;
-                       opt = send_interface(NULL, ifp, af);
-                       if (opt != -1)
+                       for (oi = optind; oi < argc; oi++) {
+                               if (strcmp(ifp->name, argv[oi]) == 0)
+                                       break;
+                       }
+                       if (optind == argc || oi < argc) {
+                               opt = send_interface(NULL, ifp, af);
+                               if (opt == -1)
+                                       goto dumperr;
                                nifaces += (size_t)opt;
+                       }
                }
                if (write(fd->fd, &nifaces, sizeof(nifaces)) != sizeof(nifaces))
-                       return -1;
-               for (oi = optind; oi < argc; oi++) {
-                       if ((ifp = if_find(ctx->ifaces, argv[oi])) == NULL)
-                               continue;
+                       goto dumperr;
+               TAILQ_FOREACH(ifp, ctx->ifaces, next) {
                        if (!ifp->active)
                                continue;
-                       send_interface(fd, ifp, af);
+                       for (oi = optind; oi < argc; oi++) {
+                               if (strcmp(ifp->name, argv[oi]) == 0)
+                                       break;
+                       }
+                       if (optind == argc || oi < argc) {
+                               if (send_interface(fd, ifp, af) == -1)
+                                       goto dumperr;
+                       }
                }
                ctx->options &= ~DHCPCD_DUMPLEASE;
                return 0;
+dumperr:
+               ctx->options &= ~DHCPCD_DUMPLEASE;
+               return -1;
        }
 
        /* Only privileged users can control dhcpcd via the socket. */
@@ -1618,14 +1631,20 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx, struct fd_list *fd,
        return 0;
 }
 
+static const char *dumpskip[] = {
+       "PATH=",
+       "pid=",
+       "chroot=",
+};
+
 static int
 dhcpcd_readdump(struct dhcpcd_ctx *ctx)
 {
        int error = 0;
-       size_t nifaces, buflen = 0, dlen;
+       size_t nifaces, buflen = 0, dlen, i;
        ssize_t len;
        char *buf = NULL, *dp, *de;
-       bool print;
+       const char *skip;
 
 again1:
        len = read(ctx->control_fd, &nifaces, sizeof(nifaces));
@@ -1660,6 +1679,11 @@ again2:
                        buf = nbuf;
                        buflen = dlen;
                }
+               if (dlen == 0) {
+                       errno = EINVAL;
+                       error = -1;
+                       goto out;
+               }
 again3:
                if (read(ctx->control_fd, buf, dlen) != (ssize_t)dlen) {
                        if (errno == EAGAIN)
@@ -1669,28 +1693,23 @@ again3:
                }
                dp = buf;
                de = dp + dlen;
+               if (*(dp - 1) != '\0') {
+                       errno = EINVAL;
+                       error = -1;
+                       goto out;
+               }
                while (dp < de) {
-                       if (dp + 6 >= de) /* _new and = something */
-                               break;
-                       if (dp[0] == 'n' && dp[3] == '_') {
-                               if (dp[1] == 'e' && dp[2] == 'w') {
-                                       print = true;
+                       for (i = 0; i < __arraycount(dumpskip); i++) {
+                               skip = dumpskip[i];
+                               if (strncmp(dp, skip, strlen(skip)) == 0)
+                                       break;
+                       }
+                       if (i == __arraycount(dumpskip)) {
+                               if (strncmp(dp, "new_", 4) == 0)
                                        dp += 4;
-                               } else if (dp[1] == 'd' &&
-                                   isdigit((unsigned char)dp[2]))
-                                       print = true;
-                               else
-                                       print = false;
-                       } else
-                               print = false;
-                       while (dp < de && *dp != '\0') {
-                               if (print)
-                                       putchar(*dp);
-                               dp++;
+                               printf("%s\n", dp);
                        }
-                       if (print)
-                               putchar('\n');
-                       dp++;
+                       dp += strlen(dp) + 1;
                }
                fflush(stdout);
                if (nifaces != 1)