sysctl.c - ubase - suckless linux base utils
 (HTM) git clone git://git.suckless.org/ubase
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       sysctl.c (3285B)
       ---
            1 /* See LICENSE file for copyright and license details. */
            2 #include <fcntl.h>
            3 #include <limits.h>
            4 #include <stdio.h>
            5 #include <stdlib.h>
            6 #include <string.h>
            7 #include <unistd.h>
            8 
            9 #include "text.h"
           10 #include "util.h"
           11 
           12 static void
           13 replacestr(char *s, int a, int b)
           14 {
           15         for (; *s; s++)
           16                 if (*s == a)
           17                         *s = b;
           18 }
           19 
           20 static int
           21 getsysctl(char *variable, char **value)
           22 {
           23         char path[PATH_MAX];
           24         char *p;
           25         char *buf, *tmp, c;
           26         int fd;
           27         ssize_t n;
           28         size_t sz, i;
           29 
           30         replacestr(variable, '.', '/');
           31 
           32         strlcpy(path, "/proc/sys/", sizeof(path));
           33         if (strlcat(path, variable, sizeof(path)) >= sizeof(path)) {
           34                 replacestr(variable, '/', '.');
           35                 return -1;
           36         }
           37 
           38         replacestr(variable, '/', '.');
           39 
           40         fd = open(path, O_RDONLY);
           41         if (fd < 0)
           42                 return -1;
           43 
           44         i = 0;
           45         sz = 1;
           46         buf = NULL;
           47         while (1) {
           48                 n = read(fd, &c, 1);
           49                 if (n < 0) {
           50                         close(fd);
           51                         free(buf);
           52                         return -1;
           53                 }
           54                 if (n == 0)
           55                         break;
           56                 if (i == sz - 1) {
           57                         sz *= 2;
           58                         tmp = realloc(buf, sz);
           59                         if (!tmp) {
           60                                 close(fd);
           61                                 free(buf);
           62                                 return -1;
           63                         }
           64                         buf = tmp;
           65                 }
           66                 buf[i++] = c;
           67         }
           68         buf[i] = '\0';
           69 
           70         p = strrchr(buf, '\n');
           71         if (p)
           72                 *p = '\0';
           73 
           74         *value = buf;
           75 
           76         close(fd);
           77 
           78         return 0;
           79 }
           80 
           81 static int
           82 setsysctl(char *variable, char *value)
           83 {
           84         char path[PATH_MAX];
           85         int fd;
           86         ssize_t n;
           87 
           88         replacestr(variable, '.', '/');
           89 
           90         strlcpy(path, "/proc/sys/", sizeof(path));
           91         if (strlcat(path, variable, sizeof(path)) >= sizeof(path)) {
           92                 replacestr(variable, '/', '.');
           93                 return -1;
           94         }
           95 
           96         replacestr(variable, '/', '.');
           97 
           98         fd = open(path, O_WRONLY);
           99         if (fd < 0)
          100                 return -1;
          101 
          102         n = write(fd, value, strlen(value));
          103         if ((size_t)n != strlen(value)) {
          104                 close(fd);
          105                 return -1;
          106         }
          107 
          108         close(fd);
          109 
          110         return 0;
          111 }
          112 
          113 static int
          114 parsepair(char *pair)
          115 {
          116         char *p;
          117         char *variable;
          118         char *value;
          119 
          120         for (p = pair; *p; p++) {
          121                 if (p[0] == '.' && p[1] == '.') {
          122                         weprintf("malformed input: %s\n", pair);
          123                         return -1;
          124                 }
          125         }
          126         p = strchr(pair, '=');
          127         if (p) {
          128                 if (p[1] == '\0') {
          129                         weprintf("malformed input: %s\n", pair);
          130                         return -1;
          131                 }
          132                 *p = '\0';
          133                 value = &p[1];
          134         } else {
          135                 value = NULL;
          136         }
          137         variable = pair;
          138         if (value) {
          139                 if (setsysctl(variable, value) < 0) {
          140                         weprintf("failed to set sysctl for %s\n", variable);
          141                         return -1;
          142                 }
          143         } else {
          144                 if (getsysctl(variable, &value) < 0) {
          145                         weprintf("failed to get sysctl for %s\n", variable);
          146                         return -1;
          147                 }
          148                 printf("%s = %s\n", variable, value);
          149                 free(value);
          150         }
          151 
          152         return 0;
          153 }
          154 
          155 static void
          156 usage(void)
          157 {
          158         eprintf("usage: %s [-p file] variable[=value]...\n", argv0);
          159 }
          160 
          161 int
          162 main(int argc, char *argv[])
          163 {
          164         FILE *fp;
          165         char *buf = NULL, *p;
          166         char *file = NULL;
          167         size_t size = 0;
          168         int i;
          169         int r = 0;
          170 
          171         ARGBEGIN {
          172         case 'p':
          173                 file = EARGF(usage());
          174                 break;
          175         default:
          176                 usage();
          177         } ARGEND;
          178 
          179         if (!file && argc < 1)
          180                 usage();
          181 
          182         if (!file) {
          183                 for (i = 0; i < argc; i++)
          184                         if (parsepair(argv[i]) < 0)
          185                                 r = 1;
          186         } else {
          187                 fp = fopen(file, "r");
          188                 if (!fp)
          189                         eprintf("fopen %s:", file);
          190                 while (agetline(&buf, &size, fp) != -1) {
          191                         p = buf;
          192                         for (p = buf; *p == ' ' || *p == '\t'; p++)
          193                                 ;
          194                         if (*p == '#' || *p == '\n')
          195                                 continue;
          196                         for (p = buf; *p; p++) {
          197                                 if (*p == '\n') {
          198                                         *p = '\0';
          199                                         break;
          200                                 }
          201                         }
          202                         p = buf;
          203                         if (parsepair(p) < 0)
          204                                 r = 1;
          205                 }
          206                 if (ferror(fp))
          207                         eprintf("%s: read error:", file);
          208                 free(buf);
          209                 fclose(fp);
          210         }
          211 
          212         return r;
          213 }