/* modprobe.c - modprobe utility.
 *
 * Copyright 2012 Madhur Verma <mad.flexi@gmail.com>
 * Copyright 2013 Kyungwan Han <asura321@gmail.com>
 *
 * No Standard.

USE_MODPROBE(NEWTOY(modprobe, "alrqvsDbd*", TOYFLAG_SBIN))

config MODPROBE
  bool "modprobe"
  default n
  help
    usage: modprobe [-alrqvsDb] [-d DIR] MODULE [symbol=value][...]

    modprobe utility - inserts modules and dependencies.

    -a  Load multiple MODULEs
    -d  Load modules from DIR, option may be used multiple times
    -l  List (MODULE is a pattern)
    -r  Remove MODULE (stacks) or do autoclean
    -q  Quiet
    -v  Verbose
    -s  Log to syslog
    -D  Show dependencies
    -b  Apply blacklist to module names too
*/
#define FOR_modprobe
#include "toys.h"
#include <sys/syscall.h>

GLOBALS(
  struct arg_list *dirs;

  struct arg_list *probes;
  struct arg_list *dbase[256];
  char *cmdopts;
  int nudeps;
  uint8_t symreq;
)

/* Note: if "#define DBASE_SIZE" modified, 
 * Please update GLOBALS dbase[256] accordingly.
 */
#define DBASE_SIZE  256
#define MODNAME_LEN 256

// Modules flag definations
#define MOD_ALOADED   0x0001
#define MOD_BLACKLIST 0x0002
#define MOD_FNDDEPMOD 0x0004
#define MOD_NDDEPS    0x0008

// Current probing modules info
struct module_s {
  uint32_t flags;
  char *cmdname, *name, *depent, *opts;
  struct arg_list *rnames, *dep;
};

// Converts path name FILE to module name.
static char *path2mod(char *file, char *mod)
{
  int i;
  char *from;

  if (!file) return NULL;
  if (!mod) mod = xmalloc(MODNAME_LEN);
	
  from = getbasename(file);
  
  for (i = 0; i < (MODNAME_LEN-1) && from[i] && from[i] != '.'; i++)
    mod[i] = (from[i] == '-') ? '_' : from[i];
  mod[i] = '\0';
  return mod;
}

// Add options in opts from toadd.
static char *add_opts(char *opts, char *toadd)
{
  if (toadd) {
    int optlen = 0;

    if (opts) optlen = strlen(opts);
    opts = xrealloc(opts, optlen + strlen(toadd) + 2);
    sprintf(opts + optlen, " %s", toadd);
  }
  return opts;
}

// Remove first element from the list and return it.
static void *llist_popme(struct arg_list **head)
{
  char *data = NULL;
  struct arg_list *temp = *head;

  if (temp) {
    data = temp->arg;
    *head = temp->next;
    free(temp);
  }
  return data;
}

// Add new node at the beginning of the list.
static void llist_add(struct arg_list **old, void *data)
{
  struct arg_list *new = xmalloc(sizeof(struct arg_list));

  new->arg = (char*)data;
  new->next = *old;
  *old = new;
}

// Add new node at tail of list.
static void llist_add_tail(struct arg_list **head, void *data)
{
  while (*head) head = &(*head)->next;
  *head = xzalloc(sizeof(struct arg_list));
  (*head)->arg = (char*)data;
}

// Reverse list order.
static struct arg_list *llist_rev(struct arg_list *list)
{
  struct arg_list *rev = NULL;

  while (list) {
    struct arg_list *next = list->next;

    list->next = rev;
    rev = list;
    list = next;
  }
  return rev;
}

/*
 * Returns struct module_s from the data base if found, NULL otherwise.
 * if add - create module entry, add it to data base and return the same mod.
 */
static struct module_s *get_mod(char *mod, uint8_t add)
{
  char name[MODNAME_LEN];
  struct module_s *modentry;
  struct arg_list *temp;
  unsigned i, hash = 0;

  path2mod(mod, name);
  for (i = 0; name[i]; i++) hash = ((hash*31) + hash) + name[i];
  hash %= DBASE_SIZE;
  for (temp = TT.dbase[hash]; temp; temp = temp->next) {
    modentry = (struct module_s *) temp->arg;
    if (!strcmp(modentry->name, name)) return modentry;
  }
  if (!add) return NULL;
  modentry = xzalloc(sizeof(*modentry));
  modentry->name = xstrdup(name);
  llist_add(&TT.dbase[hash], modentry);
  return modentry;
}

/*
 * Read a line from file with \ continuation and escape commented line.
 * Return the line in allocated string (*li)
 */
static int read_line(FILE *fl, char **li)
{
  char *nxtline = NULL, *line;
  ssize_t len, nxtlen;
  size_t linelen, nxtlinelen;

  while (1) {
    line = NULL;
    linelen = nxtlinelen = 0;
    len = getline(&line, &linelen, fl);
    if (len <= 0) {
      free(line);
      return len;
    }
    // checking for commented lines.
    if (line[0] != '#') break;
    free(line);
  }
  for (;;) {
    if (line[len - 1] == '\n') len--;
    if (!len) { 
      free(line);
      return len;
    } else if (line[len - 1] != '\\') break;
    
    len--;
    nxtlen = getline(&nxtline, &nxtlinelen, fl);
    if (nxtlen <= 0) break;
    if (linelen < len + nxtlen + 1) {
      linelen = len + nxtlen + 1;
      line = xrealloc(line, linelen);
    }
    memcpy(&line[len], nxtline, nxtlen);
    len += nxtlen;
  }
  line[len] = '\0';
  *li = xstrdup(line);
  free(line);
  if (nxtline) free(nxtline);
  return len;
}

/*
 * Action to be taken on all config files in default directories
 * checks for aliases, options, install, remove and blacklist
 */
static int config_action(struct dirtree *node)
{
  FILE *fc;
  char *filename, *tokens[3], *line, *linecp;
  struct module_s *modent;
  int tcount = 0;

  if (!dirtree_notdotdot(node)) return 0;
  if (S_ISDIR(node->st.st_mode)) return DIRTREE_RECURSE;

  if (!S_ISREG(node->st.st_mode)) return 0; // process only regular file
  filename = dirtree_path(node, NULL);
  if (!(fc = fopen(filename, "r"))) {
    free(filename);
    return 0;
  }
  for (line = linecp = NULL; read_line(fc, &line) > 0; 
      free(line), free(linecp), line = linecp = NULL) {
    char *tk = NULL;

    if (!strlen(line)) continue; 
    linecp = xstrdup(line);
    for (tk = strtok(linecp, "# \t"), tcount = 0; tk;
        tk = strtok(NULL, "# \t"), tcount++) {
      tokens[tcount] = tk;
      if (tcount == 2) {
        tokens[2] = line + strlen(tokens[0]) + strlen(tokens[1]) + 2;
        break;
      }
    }
    if (!tk) continue; 
    // process the tokens[0] contains first word of config line.
    if (!strcmp(tokens[0], "alias")) {
      struct arg_list *temp;
      char aliase[MODNAME_LEN], *realname;

      if (!tokens[2]) continue;
      path2mod(tokens[1], aliase);
      for (temp = TT.probes; temp; temp = temp->next) {
        modent = (struct module_s *) temp->arg;
        if (fnmatch(aliase, modent->name, 0)) continue;
        realname = path2mod(tokens[2], NULL);
        llist_add(&modent->rnames, realname);
        if (modent->flags & MOD_NDDEPS) {
          modent->flags &= ~MOD_NDDEPS;
          TT.nudeps--;
        }
        modent = get_mod(realname, 1);
        if (!(modent->flags & MOD_NDDEPS)) {
          modent->flags |= MOD_NDDEPS;
          TT.nudeps++;
        }
      }
    } else if (!strcmp(tokens[0], "options")) {
      if (!tokens[2]) continue;
      modent = get_mod(tokens[1], 1);
      modent->opts = add_opts(modent->opts, tokens[2]);
    } else if (!strcmp(tokens[0], "include"))
      dirtree_read(tokens[1], config_action);
    else if (!strcmp(tokens[0], "blacklist"))
      get_mod(tokens[1], 1)->flags |= MOD_BLACKLIST;
    else if (!strcmp(tokens[0], "install")) continue;
    else if (!strcmp(tokens[0], "remove")) continue;
    else if (toys.optflags & FLAG_q)
      error_msg("Invalid option %s found in file %s", tokens[0], filename);
  }
  fclose(fc);
  free(filename);
  return 0;
}

// Show matched modules else return -1 on failure.
static int depmode_read_entry(char *cmdname)
{
  char *line;
  int ret = -1;
  FILE *fe = xfopen("modules.dep", "r");

  while (read_line(fe, &line) > 0) {
    char *tmp = strchr(line, ':');

    if (tmp) {
      *tmp = '\0';
     char *name = basename(line);

      tmp = strchr(name, '.');
      if (tmp) *tmp = '\0';
      if (!cmdname || !fnmatch(cmdname, name, 0)) {
        if (tmp) *tmp = '.';
        if (toys.optflags&FLAG_v) puts(line);
        ret = 0;
      }
    }
    free(line);
  }
  fclose(fe);
  return ret;
}

// Finds dependencies for modules from the modules.dep file.
static void find_dep(void)
{
  char *line = NULL;
  struct module_s *mod;
  FILE *fe = xfopen("modules.dep", "r");

  for (; read_line(fe, &line) > 0; free(line)) {
    char *tmp = strchr(line, ':');

    if (tmp) {
      *tmp = '\0';
      mod = get_mod(line, 0);
      if (!mod) continue;
      if ((mod->flags & MOD_ALOADED) &&
          !(toys.optflags & (FLAG_r | FLAG_D))) continue;
      
      mod->flags |= MOD_FNDDEPMOD;
      if ((mod->flags & MOD_NDDEPS) && (!mod->dep)) {
        TT.nudeps--;
        llist_add(&mod->dep, xstrdup(line));
        tmp++;
        if (*tmp) {
          char *tok;

          while ((tok = strsep(&tmp, " \t"))) {
            if (!*tok) continue;
            llist_add_tail(&mod->dep, xstrdup(tok));
          }
        }
      }
    }
  }
  fclose(fe);
}

// Remove a module from the Linux Kernel. if !modules does auto remove.
static int rm_mod(char *modules, uint32_t flags)
{
  if (modules) {
    int len = strlen(modules);

    if (len > 3 && !strcmp(modules+len-3, ".ko" )) modules[len-3] = 0;
  }

  errno = 0;
  syscall(__NR_delete_module, modules, flags ? flags : O_NONBLOCK|O_EXCL);

  return errno;
}

// Insert module same as insmod implementation.
static int ins_mod(char *modules, char *flags)
{
  char *buf = NULL;
  int len, res;
  int fd = xopenro(modules);

  while (flags && strlen(toybuf) + strlen(flags) + 2 < sizeof(toybuf)) {
    strcat(toybuf, flags);
    strcat(toybuf, " ");
  }

#ifdef __NR_finit_module
  res = syscall(__NR_finit_module, fd, toybuf, 0);
  if (!res || errno != ENOSYS) {
	  xclose(fd);
	  return res;
  }
#endif

  // TODO xreadfile()

  len = fdlength(fd);
  buf = xmalloc(len);
  xreadall(fd, buf, len);
  xclose(fd);

  res = syscall(__NR_init_module, buf, len, toybuf);
  if (CFG_TOYBOX_FREE && buf != toybuf) free(buf);
  return res;
}

// Add module in probes list, if not loaded.
static void add_mod(char *name)
{
  struct module_s *mod = get_mod(name, 1);

  if (!(toys.optflags & (FLAG_r | FLAG_D)) && (mod->flags & MOD_ALOADED)) {
    if (toys.optflags&FLAG_v) printf("skipping %s, already loaded\n", name);
    return;
  }
  if (toys.optflags&FLAG_v) printf("queuing %s\n", name);
  mod->cmdname = name;
  mod->flags |= MOD_NDDEPS;
  llist_add_tail(&TT.probes, mod);
  TT.nudeps++;
  if (!strncmp(mod->name, "symbol:", 7)) TT.symreq = 1;
}

// Parse cmdline options suplied for module.
static char *add_cmdopt(char **argv)
{
  char *opt = xzalloc(1);
  int lopt = 0;

  while (*++argv) {
    char *fmt, *var, *val;

    var = *argv;
    opt = xrealloc(opt, lopt + 2 + strlen(var) + 2);
    // check for key=val or key = val.
    fmt = "%.*s%s ";
    for (val = var; *val && *val != '='; val++);
    if (*val && strchr(++val, ' ')) fmt = "%.*s\"%s\" ";
    lopt += sprintf(opt + lopt, fmt, (int) (val - var), var, val);
  }
  return opt;
}

// Probes a single module and loads all its dependencies.
static int go_probe(struct module_s *m)
{
  int rc = 0, first = 1;

  if (!(m->flags & MOD_FNDDEPMOD)) {
    if (!(toys.optflags & FLAG_q))
      error_msg("module %s not found in modules.dep", m->name);
    return -ENOENT;
  }
  if (toys.optflags & FLAG_v) printf("go_prob'ing %s\n", m->name);
  if (!(toys.optflags & FLAG_r)) m->dep = llist_rev(m->dep);
  
  while (m->dep) {
    struct module_s *m2;
    char *fn, *options;

    rc = 0;
    fn = llist_popme(&m->dep);
    m2 = get_mod(fn, 1);
    // are we removing ?
    if (toys.optflags & FLAG_r) {
      if (m2->flags & MOD_ALOADED) {
        if ((rc = rm_mod(m2->name, O_EXCL))) {
          if (first) {
            perror_msg("can't unload module %s", m2->name);
            break;
          }
        } else m2->flags &= ~MOD_ALOADED;
      }
      first = 0;
      continue;
    }
    options = m2->opts;
    m2->opts = NULL;
    if (m == m2) options = add_opts(options, TT.cmdopts);

    // are we only checking dependencies ?
    if (toys.optflags & FLAG_D) {
      if (toys.optflags & FLAG_v)
        printf(options ? "insmod %s %s\n" : "insmod %s\n", fn, options);
      if (options) free(options);
      continue;
    }
    if (m2->flags & MOD_ALOADED) {
      if (toys.optflags&FLAG_v)
        printf("%s is already loaded, skipping\n", fn);
      if (options) free(options);
      continue;
    }
    // none of above is true insert the module.
    rc = ins_mod(fn, options);
    if (toys.optflags&FLAG_v)
      printf("loaded %s '%s', rc:%d\n", fn, options, rc);
    if (rc == EEXIST) rc = 0;
    if (options) free(options);
    if (rc) {
      perror_msg("can't load module %s (%s)", m2->name, fn);
      break;
    }
    m2->flags |= MOD_ALOADED;
  }
  return rc;
}

void modprobe_main(void)
{
  struct utsname uts;
  char **argv = toys.optargs, *procline = NULL;
  FILE *fs;
  struct module_s *module;
  unsigned flags = toys.optflags;
  struct arg_list *dirs;

  if ((toys.optc < 1) && (((flags & FLAG_r) && (flags & FLAG_l))
        ||(!((flags & FLAG_r)||(flags & FLAG_l)))))
  {
	  help_exit("bad syntax");
  }
  // Check for -r flag without arg if yes then do auto remove.
  if ((flags & FLAG_r) && !toys.optc) {
    if (rm_mod(NULL, O_NONBLOCK | O_EXCL)) perror_exit("rmmod");
    return;
  }

  if (!TT.dirs) {
    uname(&uts);
    TT.dirs = xzalloc(sizeof(struct arg_list));
    TT.dirs->arg = xmprintf("/lib/modules/%s", uts.release);
  }

  // modules.dep processing for dependency check.
  if (flags & FLAG_l) {
    for (dirs = TT.dirs; dirs; dirs = dirs->next) {
      xchdir(dirs->arg);
      if (!depmode_read_entry(toys.optargs[0]))
	      return;
    }
    error_exit("no module found.");
  }

  // Read /proc/modules to get loaded modules.
  fs = xfopen("/proc/modules", "r");
  
  while (read_line(fs, &procline) > 0) {
    *(strchr(procline, ' ')) = '\0';
    get_mod(procline, 1)->flags = MOD_ALOADED;
    free(procline);
    procline = NULL;
  }
  fclose(fs);
  if ((flags & FLAG_a) || (flags & FLAG_r)) {
    do {
      add_mod(*argv++);
    } while (*argv);
  } else {
    add_mod(argv[0]);
    TT.cmdopts = add_cmdopt(argv);
  }
  if (!TT.probes) {
    if (toys.optflags&FLAG_v) puts("All modules loaded");
    return;
  }
  dirtree_read("/etc/modprobe.conf", config_action);
  dirtree_read("/etc/modprobe.d", config_action);

  for (dirs = TT.dirs; dirs; dirs = dirs->next) {
    xchdir(dirs->arg);
    if (TT.symreq) dirtree_read("modules.symbols", config_action);
    if (TT.nudeps) dirtree_read("modules.alias", config_action);
  }

  for (dirs = TT.dirs; dirs; dirs = dirs->next) {
	  xchdir(dirs->arg);
	  find_dep();
  }

  while ((module = llist_popme(&TT.probes))) {
    if (!module->rnames) {
      if (toys.optflags&FLAG_v) puts("probing by module name");
      /* This is not an alias. Literal names are blacklisted
       * only if '-b' is given.
       */
      if (!(flags & FLAG_b) || !(module->flags & MOD_BLACKLIST))
        go_probe(module);
      continue;
    }
    do { // Probe all real names for the alias.
      char *real = ((struct arg_list*)llist_pop(&module->rnames))->arg;
      struct module_s *m2 = get_mod(real, 0);
      
      if (toys.optflags&FLAG_v)
        printf("probing alias %s by realname %s\n", module->name, real);
      if (!m2) continue;
      if (!(m2->flags & MOD_BLACKLIST) 
          && (!(m2->flags & MOD_ALOADED) || (flags & (FLAG_r | FLAG_D))))
        go_probe(m2);
      free(real);
    } while (module->rnames);
  }
}
