/* sysctl.c - A utility to read and manipulate the sysctl parameters.
 *
 * Copyright 2014 Bilal Qureshi <bilal.jmi@gmail.com>
 * Copyright 2014 Kyungwan Han <asura321@gmail.com>
 *
 * No Standard
 
USE_SYSCTL(NEWTOY(sysctl, "^neNqwpaA[!ap][!aq][!aw][+aA]", TOYFLAG_SBIN))

config SYSCTL
  bool "sysctl"
  default y
  help
    usage: sysctl [-aAeNnqw] [-p [FILE] | KEY[=VALUE]...]

    Read/write system control data (under /proc/sys).

    -a,A	Show all values
    -e	Don't warn about unknown keys
    -N	Don't print key values
    -n	Don't print key names
    -p	Read values from FILE (default /etc/sysctl.conf)
    -q	Don't show value after write
    -w	Only write values (object to reading)
*/
#define FOR_sysctl
#include "toys.h"

// Null terminate at =, return value
static char *split_key(char *key)
{
  char *value = strchr(key, '=');

  if (value) *(value++)=0;

  return value;
}

static void replace_char(char *str, char old, char new)
{
  for (; *str; str++) if (*str == old) *str = new;
}

static void key_error(char *key)
{
  if (errno == ENOENT) {
    if (!(toys.optflags & FLAG_e)) error_msg("unknown key '%s'", key);
  } else perror_msg("key '%s'", key);
}

static int write_key(char *path, char *key, char *value)
{
  int fd = open(path, O_WRONLY);;

  if (fd < 0) {
    key_error(key);

    return 0;
  }
  xwrite(fd, value, strlen(value));
  xclose(fd);

  return 1;
}

// Display all keys under a path
static int do_show_keys(struct dirtree *dt)
{
  char *path, *data, *key;

  if (!dirtree_notdotdot(dt)) return 0; // Skip . and ..
  if (S_ISDIR(dt->st.st_mode)) return DIRTREE_RECURSE;

  path = dirtree_path(dt, 0);
  data = readfile(path, 0, 0);
  replace_char(key = path + 10, '/', '.'); // skip "/proc/sys/"
  if (!data) key_error(key);
  else {
    // Print the parts that aren't switched off by flags.
    if (!(toys.optflags & FLAG_n)) xprintf("%s", key);
    if (!(toys.optflags & (FLAG_N|FLAG_n))) xprintf(" = ");
    for (key = data+strlen(data); key > data && isspace(*--key); *key = 0);
    if (!(toys.optflags & FLAG_N)) xprintf("%s", data);
    if ((toys.optflags & (FLAG_N|FLAG_n)) != (FLAG_N|FLAG_n)) xputc('\n');
  }

  free(data);
  free(path);

  return 0;
}

// Read/write entries under a key. Accepts "key=value" in key if !value
static void process_key(char *key, char *value)
{
  char *path;

  if (!value) value = split_key(key);
  if ((toys.optflags & FLAG_w) && !value) {
    error_msg("'%s' not key=value", key);

    return;
  }

  path = xmprintf("/proc/sys/%s", key);
  replace_char(path, '.', '/');
  // Note: failure to assign to a non-leaf node suppresses the display.
  if (!(value && (!write_key(path, key, value) || (toys.optflags & FLAG_q)))) {
    if (!access(path, R_OK)) dirtree_read(path, do_show_keys);
    else key_error(key);
  }
  free(path);
}

void sysctl_main()
{
  char **args = 0;

  // Display all keys
  if (toys.optflags & FLAG_a) dirtree_read("/proc/sys", do_show_keys);

  // read file
  else if (toys.optflags & FLAG_p) {
    FILE *fp = xfopen(*toys.optargs ? *toys.optargs : "/etc/sysctl.conf", "r");
    size_t len;

    for (;;) {
      char *line = 0, *key, *val;

      if (-1 == (len = getline(&line, &len, fp))) break;
      key = line;
      while (isspace(*key)) key++;
      if (*key == '#' || *key == ';' || !*key) continue;
      while (len && isspace(line[len-1])) line[--len] = 0;
      if (!(val = split_key(line))) {
        error_msg("'%s' not key=value", line);
        continue;
      }

      // Trim whitespace around =
      len = (val-line)-1;
      while (len && isspace(line[len-1])) line[--len] = 0;
      while (isspace(*val)) val++;;

      process_key(key, val);
      free(line);
    }
    fclose(fp);

  // Loop through arguments, displaying or assigning as appropriate
  } else {
    if (!*toys.optargs) help_exit(0);
    for (args = toys.optargs; *args; args++) process_key(*args, 0);
  }
}
