/* makedevs.c - Make ranges of device files.
 *
 * Copyright 2014 Bilal Qureshi <bilal.jmi@gmail.com>
 * Copyright 2014 Kyungwan Han <asura321@gmail.com>
 *
 * No Standard
 
USE_MAKEDEVS(NEWTOY(makedevs, "<1>1d:", TOYFLAG_USR|TOYFLAG_BIN))

config MAKEDEVS
  bool "makedevs"
  default y
  help
    usage: makedevs [-d device_table] rootdir

    Create a range of special files as specified in a device table.

    -d	File containing device table (default reads from stdin)

    Each line of the device table has the fields:
    <name> <type> <mode> <uid> <gid> <major> <minor> <start> <increment> <count>
    Where name is the file name, and type is one of the following:

    b	Block device
    c	Character device
    d	Directory
    f	Regular file
    p	Named pipe (fifo)

    Other fields specify permissions, user and group id owning the file,
    and additional fields for device special files. Use '-' for blank entries,
    unspecified fields are treated as '-'.
*/

#define FOR_makedevs
#include "toys.h"

GLOBALS(
  char *d;
)

void makedevs_main()
{
  int fd = 0, line_no, i;
  char *line = NULL;

  // Open file and chdir, verbosely
  xprintf("rootdir = %s\n", *toys.optargs);
  if ((toys.optflags & FLAG_d) && strcmp(TT.d, "-")) {
    fd = xopenro(TT.d);
    xprintf("table = %s\n", TT.d);
  } else xprintf("table = <stdin>\n");
  xchdir(*toys.optargs);

  for (line_no = 0; (line = get_line(fd)); free(line)) {
    char type=0, user[64], group[64], *node, *ptr = line;
    unsigned int mode = 0755, major = 0, minor = 0, cnt = 0, incr = 0, 
                 st_val = 0;
    uid_t uid;
    gid_t gid;
    struct stat st;

    line_no++;
    while (isspace(*ptr)) ptr++;
    if (!*ptr || *ptr == '#') continue;
    node = ptr;

    while (*ptr && !isspace(*ptr)) ptr++;
    if (*ptr) *(ptr++) = 0;
    *user = *group = 0;
    sscanf(ptr, "%c %o %63s %63s %u %u %u %u %u", &type, &mode,
           user, group, &major, &minor, &st_val, &incr, &cnt);

    // type order here needs to line up with actions[] order.
    i = stridx("pcbdf", type);
    if (i == -1) {
      error_msg("line %d: bad type %c", line_no, type);
      continue;
    } else mode |= (mode_t[]){S_IFIFO, S_IFCHR, S_IFBLK, 0, 0}[i];

    uid = *user ? xgetuid(user) : getuid();
    gid = *group ? xgetgid(group) : getgid();

    while (*node == '/') node++; // using relative path

    for (i = 0; (!cnt && !i) || i < cnt; i++) {
      if (cnt>1) {
        snprintf(toybuf, sizeof(toybuf), "%.999s%u", node, st_val + i);
        ptr = toybuf;
      } else ptr = node;

      if (type == 'd') {
        if (mkpathat(AT_FDCWD, ptr, mode, MKPATHAT_MKLAST | MKPATHAT_MAKE))  {
          perror_msg("can't create directory '%s'", ptr);
          continue;
        }
      } else if (type == 'f') {
        if (stat(ptr, &st) || !S_ISREG(st.st_mode)) {
          perror_msg("line %d: file '%s' does not exist", line_no, ptr);
          continue;
        }
      } else if (mknod(ptr, mode, dev_makedev(major, minor + i*incr))) {
        perror_msg("line %d: can't create node '%s'", line_no, ptr);
        continue;
      }

      if (chown(ptr, uid, gid) || chmod(ptr, mode)) 
        perror_msg("line %d: can't chown/chmod '%s'", line_no, ptr);
    }
  }
  xclose(fd);
}
