197c2c1eba507d10005e305098c3fc21b1472c97eRob Landley/* sysctl.c - A utility to read and manipulate the sysctl parameters. 297c2c1eba507d10005e305098c3fc21b1472c97eRob Landley * 397c2c1eba507d10005e305098c3fc21b1472c97eRob Landley * Copyright 2014 Bilal Qureshi <bilal.jmi@gmail.com> 497c2c1eba507d10005e305098c3fc21b1472c97eRob Landley * Copyright 2014 Kyungwan Han <asura321@gmail.com> 597c2c1eba507d10005e305098c3fc21b1472c97eRob Landley * 697c2c1eba507d10005e305098c3fc21b1472c97eRob Landley * No Standard 797c2c1eba507d10005e305098c3fc21b1472c97eRob Landley 81dd3704c5ffea926f61a96bb7de7d9dbee52fa44Paul BarkerUSE_SYSCTL(NEWTOY(sysctl, "^neNqwpaA[!ap][!aq][!aw][+aA]", TOYFLAG_SBIN)) 997c2c1eba507d10005e305098c3fc21b1472c97eRob Landley 1097c2c1eba507d10005e305098c3fc21b1472c97eRob Landleyconfig SYSCTL 1197c2c1eba507d10005e305098c3fc21b1472c97eRob Landley bool "sysctl" 1297641f459a3e74045305b4ef9b80bb00bc56a29fRob Landley default y 1397c2c1eba507d10005e305098c3fc21b1472c97eRob Landley help 14e973d23094883ad66ec24247cb95dbe65db1324eRob Landley usage: sysctl [-aAeNnqw] [-p [FILE] | KEY[=VALUE]...] 1597c2c1eba507d10005e305098c3fc21b1472c97eRob Landley 16e973d23094883ad66ec24247cb95dbe65db1324eRob Landley Read/write system control data (under /proc/sys). 17f272df9e821e00afb962a62556318cecfcd694aeRob Landley 18e973d23094883ad66ec24247cb95dbe65db1324eRob Landley -a,A Show all values 19e973d23094883ad66ec24247cb95dbe65db1324eRob Landley -e Don't warn about unknown keys 20e973d23094883ad66ec24247cb95dbe65db1324eRob Landley -N Don't print key values 21e973d23094883ad66ec24247cb95dbe65db1324eRob Landley -n Don't print key names 228941e5fef58025591b7441372d486cf5de46dd39Rob Landley -p Read values from FILE (default /etc/sysctl.conf) 23e973d23094883ad66ec24247cb95dbe65db1324eRob Landley -q Don't show value after write 24e973d23094883ad66ec24247cb95dbe65db1324eRob Landley -w Only write values (object to reading) 2597c2c1eba507d10005e305098c3fc21b1472c97eRob Landley*/ 2697c2c1eba507d10005e305098c3fc21b1472c97eRob Landley#define FOR_sysctl 2797c2c1eba507d10005e305098c3fc21b1472c97eRob Landley#include "toys.h" 2897c2c1eba507d10005e305098c3fc21b1472c97eRob Landley 29e973d23094883ad66ec24247cb95dbe65db1324eRob Landley// Null terminate at =, return value 30e973d23094883ad66ec24247cb95dbe65db1324eRob Landleystatic char *split_key(char *key) 3197c2c1eba507d10005e305098c3fc21b1472c97eRob Landley{ 32e973d23094883ad66ec24247cb95dbe65db1324eRob Landley char *value = strchr(key, '='); 33e973d23094883ad66ec24247cb95dbe65db1324eRob Landley 34e973d23094883ad66ec24247cb95dbe65db1324eRob Landley if (value) *(value++)=0; 35e973d23094883ad66ec24247cb95dbe65db1324eRob Landley 36e973d23094883ad66ec24247cb95dbe65db1324eRob Landley return value; 3797c2c1eba507d10005e305098c3fc21b1472c97eRob Landley} 3897c2c1eba507d10005e305098c3fc21b1472c97eRob Landley 3997c2c1eba507d10005e305098c3fc21b1472c97eRob Landleystatic void replace_char(char *str, char old, char new) 4097c2c1eba507d10005e305098c3fc21b1472c97eRob Landley{ 41f272df9e821e00afb962a62556318cecfcd694aeRob Landley for (; *str; str++) if (*str == old) *str = new; 4297c2c1eba507d10005e305098c3fc21b1472c97eRob Landley} 4397c2c1eba507d10005e305098c3fc21b1472c97eRob Landley 44e973d23094883ad66ec24247cb95dbe65db1324eRob Landleystatic void key_error(char *key) 4597c2c1eba507d10005e305098c3fc21b1472c97eRob Landley{ 4608f2d7d333f1a52ad48bcdc1c2ec1387b9053784Rob Landley if (errno == ENOENT) { 4708f2d7d333f1a52ad48bcdc1c2ec1387b9053784Rob Landley if (!(toys.optflags & FLAG_e)) error_msg("unknown key '%s'", key); 4808f2d7d333f1a52ad48bcdc1c2ec1387b9053784Rob Landley } else perror_msg("key '%s'", key); 4997c2c1eba507d10005e305098c3fc21b1472c97eRob Landley} 5097c2c1eba507d10005e305098c3fc21b1472c97eRob Landley 51e973d23094883ad66ec24247cb95dbe65db1324eRob Landleystatic int write_key(char *path, char *key, char *value) 5297c2c1eba507d10005e305098c3fc21b1472c97eRob Landley{ 53e973d23094883ad66ec24247cb95dbe65db1324eRob Landley int fd = open(path, O_WRONLY);; 5497c2c1eba507d10005e305098c3fc21b1472c97eRob Landley 55e973d23094883ad66ec24247cb95dbe65db1324eRob Landley if (fd < 0) { 56e973d23094883ad66ec24247cb95dbe65db1324eRob Landley key_error(key); 57e973d23094883ad66ec24247cb95dbe65db1324eRob Landley 58e973d23094883ad66ec24247cb95dbe65db1324eRob Landley return 0; 5997c2c1eba507d10005e305098c3fc21b1472c97eRob Landley } 60e973d23094883ad66ec24247cb95dbe65db1324eRob Landley xwrite(fd, value, strlen(value)); 6197c2c1eba507d10005e305098c3fc21b1472c97eRob Landley xclose(fd); 6297c2c1eba507d10005e305098c3fc21b1472c97eRob Landley 63e973d23094883ad66ec24247cb95dbe65db1324eRob Landley return 1; 6497c2c1eba507d10005e305098c3fc21b1472c97eRob Landley} 6597c2c1eba507d10005e305098c3fc21b1472c97eRob Landley 66e973d23094883ad66ec24247cb95dbe65db1324eRob Landley// Display all keys under a path 67e973d23094883ad66ec24247cb95dbe65db1324eRob Landleystatic int do_show_keys(struct dirtree *dt) 6897c2c1eba507d10005e305098c3fc21b1472c97eRob Landley{ 69e973d23094883ad66ec24247cb95dbe65db1324eRob Landley char *path, *data, *key; 7097c2c1eba507d10005e305098c3fc21b1472c97eRob Landley 71e973d23094883ad66ec24247cb95dbe65db1324eRob Landley if (!dirtree_notdotdot(dt)) return 0; // Skip . and .. 72e973d23094883ad66ec24247cb95dbe65db1324eRob Landley if (S_ISDIR(dt->st.st_mode)) return DIRTREE_RECURSE; 73e973d23094883ad66ec24247cb95dbe65db1324eRob Landley 74e973d23094883ad66ec24247cb95dbe65db1324eRob Landley path = dirtree_path(dt, 0); 75e973d23094883ad66ec24247cb95dbe65db1324eRob Landley data = readfile(path, 0, 0); 76e973d23094883ad66ec24247cb95dbe65db1324eRob Landley replace_char(key = path + 10, '/', '.'); // skip "/proc/sys/" 77e973d23094883ad66ec24247cb95dbe65db1324eRob Landley if (!data) key_error(key); 78e973d23094883ad66ec24247cb95dbe65db1324eRob Landley else { 79e973d23094883ad66ec24247cb95dbe65db1324eRob Landley // Print the parts that aren't switched off by flags. 80e973d23094883ad66ec24247cb95dbe65db1324eRob Landley if (!(toys.optflags & FLAG_n)) xprintf("%s", key); 81e973d23094883ad66ec24247cb95dbe65db1324eRob Landley if (!(toys.optflags & (FLAG_N|FLAG_n))) xprintf(" = "); 82e973d23094883ad66ec24247cb95dbe65db1324eRob Landley for (key = data+strlen(data); key > data && isspace(*--key); *key = 0); 83e973d23094883ad66ec24247cb95dbe65db1324eRob Landley if (!(toys.optflags & FLAG_N)) xprintf("%s", data); 84e973d23094883ad66ec24247cb95dbe65db1324eRob Landley if ((toys.optflags & (FLAG_N|FLAG_n)) != (FLAG_N|FLAG_n)) xputc('\n'); 8597c2c1eba507d10005e305098c3fc21b1472c97eRob Landley } 8697c2c1eba507d10005e305098c3fc21b1472c97eRob Landley 87e973d23094883ad66ec24247cb95dbe65db1324eRob Landley free(data); 88e973d23094883ad66ec24247cb95dbe65db1324eRob Landley free(path); 89e973d23094883ad66ec24247cb95dbe65db1324eRob Landley 90e973d23094883ad66ec24247cb95dbe65db1324eRob Landley return 0; 91f272df9e821e00afb962a62556318cecfcd694aeRob Landley} 92f272df9e821e00afb962a62556318cecfcd694aeRob Landley 9308f2d7d333f1a52ad48bcdc1c2ec1387b9053784Rob Landley// Read/write entries under a key. Accepts "key=value" in key if !value 94e973d23094883ad66ec24247cb95dbe65db1324eRob Landleystatic void process_key(char *key, char *value) 9597c2c1eba507d10005e305098c3fc21b1472c97eRob Landley{ 9608f2d7d333f1a52ad48bcdc1c2ec1387b9053784Rob Landley char *path; 9797c2c1eba507d10005e305098c3fc21b1472c97eRob Landley 9808f2d7d333f1a52ad48bcdc1c2ec1387b9053784Rob Landley if (!value) value = split_key(key); 9908f2d7d333f1a52ad48bcdc1c2ec1387b9053784Rob Landley if ((toys.optflags & FLAG_w) && !value) { 10070a84a356b1c56743618362867b9300007d11998Rob Landley error_msg("'%s' not key=value", key); 101e973d23094883ad66ec24247cb95dbe65db1324eRob Landley 102e973d23094883ad66ec24247cb95dbe65db1324eRob Landley return; 10397c2c1eba507d10005e305098c3fc21b1472c97eRob Landley } 104f272df9e821e00afb962a62556318cecfcd694aeRob Landley 10508f2d7d333f1a52ad48bcdc1c2ec1387b9053784Rob Landley path = xmprintf("/proc/sys/%s", key); 106e973d23094883ad66ec24247cb95dbe65db1324eRob Landley replace_char(path, '.', '/'); 107e973d23094883ad66ec24247cb95dbe65db1324eRob Landley // Note: failure to assign to a non-leaf node suppresses the display. 10808f2d7d333f1a52ad48bcdc1c2ec1387b9053784Rob Landley if (!(value && (!write_key(path, key, value) || (toys.optflags & FLAG_q)))) { 10908f2d7d333f1a52ad48bcdc1c2ec1387b9053784Rob Landley if (!access(path, R_OK)) dirtree_read(path, do_show_keys); 11008f2d7d333f1a52ad48bcdc1c2ec1387b9053784Rob Landley else key_error(key); 11108f2d7d333f1a52ad48bcdc1c2ec1387b9053784Rob Landley } 112e973d23094883ad66ec24247cb95dbe65db1324eRob Landley free(path); 11397c2c1eba507d10005e305098c3fc21b1472c97eRob Landley} 11497c2c1eba507d10005e305098c3fc21b1472c97eRob Landley 11597c2c1eba507d10005e305098c3fc21b1472c97eRob Landleyvoid sysctl_main() 11697c2c1eba507d10005e305098c3fc21b1472c97eRob Landley{ 117e973d23094883ad66ec24247cb95dbe65db1324eRob Landley char **args = 0; 118e973d23094883ad66ec24247cb95dbe65db1324eRob Landley 119e973d23094883ad66ec24247cb95dbe65db1324eRob Landley // Display all keys 120e973d23094883ad66ec24247cb95dbe65db1324eRob Landley if (toys.optflags & FLAG_a) dirtree_read("/proc/sys", do_show_keys); 121e973d23094883ad66ec24247cb95dbe65db1324eRob Landley 122e973d23094883ad66ec24247cb95dbe65db1324eRob Landley // read file 123e973d23094883ad66ec24247cb95dbe65db1324eRob Landley else if (toys.optflags & FLAG_p) { 124e973d23094883ad66ec24247cb95dbe65db1324eRob Landley FILE *fp = xfopen(*toys.optargs ? *toys.optargs : "/etc/sysctl.conf", "r"); 125e973d23094883ad66ec24247cb95dbe65db1324eRob Landley size_t len; 126e973d23094883ad66ec24247cb95dbe65db1324eRob Landley 12708f2d7d333f1a52ad48bcdc1c2ec1387b9053784Rob Landley for (;;) { 12808f2d7d333f1a52ad48bcdc1c2ec1387b9053784Rob Landley char *line = 0, *key, *val; 129e973d23094883ad66ec24247cb95dbe65db1324eRob Landley 13008f2d7d333f1a52ad48bcdc1c2ec1387b9053784Rob Landley if (-1 == (len = getline(&line, &len, fp))) break; 13108f2d7d333f1a52ad48bcdc1c2ec1387b9053784Rob Landley key = line; 132e973d23094883ad66ec24247cb95dbe65db1324eRob Landley while (isspace(*key)) key++; 133e973d23094883ad66ec24247cb95dbe65db1324eRob Landley if (*key == '#' || *key == ';' || !*key) continue; 13408f2d7d333f1a52ad48bcdc1c2ec1387b9053784Rob Landley while (len && isspace(line[len-1])) line[--len] = 0; 135e973d23094883ad66ec24247cb95dbe65db1324eRob Landley if (!(val = split_key(line))) { 13608f2d7d333f1a52ad48bcdc1c2ec1387b9053784Rob Landley error_msg("'%s' not key=value", line); 137e973d23094883ad66ec24247cb95dbe65db1324eRob Landley continue; 138e973d23094883ad66ec24247cb95dbe65db1324eRob Landley } 139e973d23094883ad66ec24247cb95dbe65db1324eRob Landley 14008f2d7d333f1a52ad48bcdc1c2ec1387b9053784Rob Landley // Trim whitespace around = 141e973d23094883ad66ec24247cb95dbe65db1324eRob Landley len = (val-line)-1; 142e973d23094883ad66ec24247cb95dbe65db1324eRob Landley while (len && isspace(line[len-1])) line[--len] = 0; 143e973d23094883ad66ec24247cb95dbe65db1324eRob Landley while (isspace(*val)) val++;; 144e973d23094883ad66ec24247cb95dbe65db1324eRob Landley 145e973d23094883ad66ec24247cb95dbe65db1324eRob Landley process_key(key, val); 14608f2d7d333f1a52ad48bcdc1c2ec1387b9053784Rob Landley free(line); 14797c2c1eba507d10005e305098c3fc21b1472c97eRob Landley } 148e973d23094883ad66ec24247cb95dbe65db1324eRob Landley fclose(fp); 149e973d23094883ad66ec24247cb95dbe65db1324eRob Landley 150e973d23094883ad66ec24247cb95dbe65db1324eRob Landley // Loop through arguments, displaying or assigning as appropriate 1518941e5fef58025591b7441372d486cf5de46dd39Rob Landley } else { 1528941e5fef58025591b7441372d486cf5de46dd39Rob Landley if (!*toys.optargs) help_exit(0); 1538941e5fef58025591b7441372d486cf5de46dd39Rob Landley for (args = toys.optargs; *args; args++) process_key(*args, 0); 1548941e5fef58025591b7441372d486cf5de46dd39Rob Landley } 15597c2c1eba507d10005e305098c3fc21b1472c97eRob Landley} 156