/* 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);
  }
}
