/* fsck.c -  check and repair a Linux filesystem
 *
 * Copyright 2013 Sandeep Sharma <sandeep.jack2756@gmail.com>
 * Copyright 2013 Kyungwan Han <asura321@gmail.com>

USE_FSCK(NEWTOY(fsck, "?t:ANPRTVsC#", TOYFLAG_USR|TOYFLAG_BIN))

config FSCK
  bool "fsck"
  default n
  help
    usage: fsck [-ANPRTV] [-C FD] [-t FSTYPE] [FS_OPTS] [BLOCKDEV]... 
    
    Check and repair filesystems

    -A      Walk /etc/fstab and check all filesystems
    -N      Don't execute, just show what would be done
    -P      With -A, check filesystems in parallel
    -R      With -A, skip the root filesystem
    -T      Don't show title on startup
    -V      Verbose
    -C n    Write status information to specified filedescriptor
    -t TYPE List of filesystem types to check

*/

#define FOR_fsck
#include "toys.h"
#include <mntent.h>

#define FLAG_WITHOUT_NO_PRFX 1
#define FLAG_WITH_NO_PRFX 2
#define FLAG_DONE 1

GLOBALS(
  int fd_num;
  char *t_list;

  struct double_list *devices;
  int *arr_flag;
  char **arr_type;
  int negate;
  int sum_status;
  int nr_run;
  int sig_num;
  long max_nr_run;
)

struct f_sys_info {
  char *device, *mountpt, *type, *opts;
  int passno, flag;
  struct f_sys_info *next;
};

struct child_list {
  struct child_list *next;
  pid_t pid;
  char *prog_name, *dev_name;
};

static struct f_sys_info *filesys_info = NULL; //fstab entry list
static struct child_list *c_list = NULL; //fsck.type child list.

static void kill_all(void) 
{
  struct child_list *child;

  for (child = c_list; child; child = child->next) 
    kill(child->pid, SIGTERM);
  _exit(0);
}

static long strtol_range(char *str, int min, int max)
{
  char *endptr = NULL;
  errno = 0;
  long ret_value = strtol(str, &endptr, 10);

  if(errno) perror_exit("Invalid num %s", str);
  else if(endptr && (*endptr != '\0' || endptr == str))
    perror_exit("Not a valid num %s", str);
  if(ret_value >= min && ret_value <= max) return ret_value;
  else perror_exit("Number %s is not in valid [%d-%d] Range", str, min, max);
}

//create fstab entries list.
static struct f_sys_info* create_db(struct mntent *f_info)
{
  struct f_sys_info *temp = filesys_info;
  if (temp) {
    while (temp->next) temp = temp->next;
    temp->next = xzalloc(sizeof(struct f_sys_info));
    temp = temp->next;
  } else filesys_info = temp = xzalloc(sizeof(struct f_sys_info));

  temp->device = xstrdup(f_info->mnt_fsname);
  temp->mountpt = xstrdup(f_info->mnt_dir);
  if (strchr(f_info->mnt_type, ',')) temp->type = xstrdup("auto");
  else  temp->type = xstrdup(f_info->mnt_type);
  temp->opts = xstrdup(f_info->mnt_opts);
  temp->passno = f_info->mnt_passno;
  return temp;
}

//is we have 'no' or ! before type.
static int is_no_prefix(char **p)
{
  int no = 0;

  if ((*p[0] == 'n' && *(*p + 1) == 'o')) no = 2; 
  else if (*p[0] == '!') no = 1;
  *p += no;
  return ((no) ? 1 :0);
}

static void fix_tlist(void)
{
  char *p, *s = TT.t_list;
  int n = 1, no;

  while ((s = strchr(s, ','))) {
    s++;
    n++;
  }

  TT.arr_flag = xzalloc((n + 1) * sizeof(char));
  TT.arr_type = xzalloc((n + 1) * sizeof(char *));
  s = TT.t_list;
  n = 0;
  while ((p = strsep(&s, ","))) {
    no = is_no_prefix(&p);
    if (!strcmp(p, "loop")) TT.arr_flag[n] = no ? FLAG_WITH_NO_PRFX :FLAG_WITHOUT_NO_PRFX; 
    else if (!strncmp(p, "opts=", 5)) {
      p+=5;
      TT.arr_flag[n] = is_no_prefix(&p) ?FLAG_WITH_NO_PRFX :FLAG_WITHOUT_NO_PRFX;
    }
    else {
      if (!n) TT.negate = no;
      if (n && TT.negate != no) error_exit("either all or none of the filesystem"
          " types passed to -t must be prefixed with 'no' or '!'");
    }
    TT.arr_type[n++] = p;
  }
}

//ignore these types...
static int ignore_type(char *type)
{
  int i = 0;
  char *str;
  char *ignored_types[] = {
    "ignore","iso9660", "nfs","proc",
    "sw","swap", "tmpfs","devpts",NULL
  };
  while ((str = ignored_types[i++])) {
    if (!strcmp(str, type)) return 1;
  }
  return 0;
}

// return true if has to ignore the filesystem.
static int to_be_ignored(struct f_sys_info *finfo) 
{
  int i, ret = 0, type_present = 0;

  if (!finfo->passno) return 1; //Ignore with pass num = 0
  if (TT.arr_type) {
    for (i = 0; TT.arr_type[i]; i++) {
      if (!TT.arr_flag[i]) { //it is type of filesys.
        type_present = 2;
        if (!strcmp(TT.arr_type[i], finfo->type)) ret = 0;
        else ret = 1;
      } else if (TT.arr_flag[i] == FLAG_WITH_NO_PRFX) { //it is option of filesys
        if (hasmntopt((const struct mntent *)finfo, TT.arr_type[i])) return 1;
      } else { //FLAG_WITHOUT_NO_PRFX
        if (!hasmntopt((const struct mntent *)finfo, TT.arr_type[i])) return 1;
      }
    }
  }
  if (ignore_type(finfo->type)) return 1;
  if (TT.arr_type && type_present != 2) return 0;
  return ((TT.negate) ? !ret : ret);
}

// find type and execute corresponding fsck.type prog.
static void do_fsck(struct f_sys_info *finfo) 
{
  struct child_list *child;
  char **args;
  char *type;
  pid_t pid;
  int i = 1, j = 0;

  if (strcmp(finfo->type, "auto")) type = finfo->type;
  else if (TT.t_list && (TT.t_list[0] != 'n' || TT.t_list[1] != 'o' || TT.t_list[0] != '!')
      && strncmp(TT.t_list, "opts=", 5) && strncmp(TT.t_list , "loop", 4)
      && !TT.arr_type[1]) type = TT.t_list; //one file sys at cmdline
  else type = "auto";

  args = xzalloc((toys.optc + 2 + 1 + 1) * sizeof(char*)); //+1, for NULL, +1 if -C
  args[0] = xmprintf("fsck.%s", type);
  
  if(toys.optflags & FLAG_C) args[i++] = xmprintf("%s %d","-C", TT.fd_num);
  while(toys.optargs[j]) {
    if(*toys.optargs[j]) args[i++] = xstrdup(toys.optargs[j]);
    j++;
  }
  args[i] = finfo->device;

  TT.nr_run++;
  if ((toys.optflags & FLAG_V) || (toys.optflags & FLAG_N)) {
    printf("[%s (%d) -- %s]", args[0], TT.nr_run,
        finfo->mountpt ? finfo->mountpt : finfo->device);
    for (i = 0; args[i]; i++) xprintf(" %s", args[i]);
    xputc('\n');
  }

  if (toys.optflags & FLAG_N) return;
  else { 
    if ((pid = fork()) < 0) {
      perror_msg(args[0]);
      return; 
    }
    if (!pid) xexec(args); //child, executes fsck.type
  } 

  child = xzalloc(sizeof(struct child_list)); //Parent, add to child list.
  child->dev_name = xstrdup(finfo->device);
  child->prog_name = args[0];
  child->pid = pid;

  if (c_list) {
    child->next = c_list;
    c_list = child;
  } else {
    c_list = child;
    child->next =NULL;
  }
}

// for_all = 1; wait for all child to exit
// for_all = 0; wait for any one to exit
static int wait_for(int for_all)
{
  pid_t pid;
  int status = 0, child_exited;
  struct child_list *prev, *temp = c_list;
  prev = temp;

  errno = 0;
  if (!c_list) return 0;
  while ((pid = wait(&status))) {
    if (TT.sig_num) kill_all();
    child_exited = 0;
    if (pid < 0) {
      if (errno == EINTR) continue;
      else if (errno == ECHILD) break; //No child to wait, break and return status.
      else perror_exit("option arg Invalid\n"); //paranoid.
    }
    while (temp) {
      if (temp->pid == pid) {
        child_exited = 1;
        break;
      }
      prev = temp;
      temp = temp->next;
    }
    if (child_exited) {
      if (WIFEXITED(status)) TT.sum_status |= WEXITSTATUS(status);
      else if (WIFSIGNALED(status)) { 
        TT.sum_status |= 4; //Uncorrected.
        if (WTERMSIG(status) != SIGINT)
          perror_msg("child Term. by sig: %d\n",(WTERMSIG(status)));
        TT.sum_status |= 8; //Operatinal error
      } else { 
        TT.sum_status |= 4; //Uncorrected.
        perror_msg("%s %s: status is %x, should never happen\n", 
            temp->prog_name, temp->dev_name, status);
      }
      TT.nr_run--;
      if (prev == temp) c_list = c_list->next; //first node 
      else prev->next = temp->next;
      free(temp->prog_name);
      free(temp->dev_name);
      free(temp);
      if (!for_all) break;
    }
  }
  return TT.sum_status;
}

//scan all the fstab entries or -t matches with fstab.
static int scan_all(void)
{
  struct f_sys_info *finfo = filesys_info;
  int ret = 0, passno;

  if (toys.optflags & FLAG_V) xprintf("Checking all filesystem\n");
  while (finfo) {
    if (to_be_ignored(finfo)) finfo->flag |= FLAG_DONE;
    finfo = finfo->next;
  }
  finfo = filesys_info;

  if (!(toys.optflags & FLAG_P)) {
    while (finfo) {
      if (!strcmp(finfo->mountpt, "/")) { // man says: check / in parallel with others if -P is absent.
        if ((toys.optflags & FLAG_R) || to_be_ignored(finfo)) {
          finfo->flag |= FLAG_DONE;
          break;
        } else {
          do_fsck(finfo);
          finfo->flag |= FLAG_DONE;
          if (TT.sig_num) kill_all();
          if ((ret |= wait_for(1)) > 4) return ret; //destruction in filesys.
          break;
        }
      }
      finfo = finfo->next;
    }
  }
  if (toys.optflags & FLAG_R) { // with -PR we choose to skip root.
    for (finfo = filesys_info; finfo; finfo = finfo->next) {
      if(!strcmp(finfo->mountpt, "/")) finfo->flag |= FLAG_DONE;
    }
  }
  passno = 1;
  while (1) {
    for (finfo = filesys_info; finfo; finfo = finfo->next) 
      if (!finfo->flag) break;
    if (!finfo) break;

    for (finfo = filesys_info; finfo; finfo = finfo->next) {
      if (finfo->flag) continue;
      if (finfo->passno == passno) {
        do_fsck(finfo);
        finfo->flag |= FLAG_DONE;
        if ((toys.optflags & FLAG_s) || (TT.nr_run 
              && (TT.nr_run >= TT.max_nr_run))) ret |= wait_for(0);
      }
    }
    if (TT.sig_num) kill_all();
    ret |= wait_for(1);
    passno++;
  }
  return ret;
}

void record_sig_num(int sig) 
{
  TT.sig_num = sig;
}

static void list_free(void *node) //for satisfying Valgrind
{
  free(((struct double_list*)node)->data);
  free(node);
}

static void free_all(void) 
{
  struct f_sys_info *finfo, *temp;

  llist_traverse(TT.devices, list_free);
  free(TT.arr_type);
  free(TT.arr_flag);
  for (finfo = filesys_info; finfo;) {
    temp = finfo->next;
    free(finfo->device);
    free(finfo->mountpt);
    free(finfo->type);
    free(finfo->opts);
    free(finfo);
    finfo = temp;
  }
}

void fsck_main(void)
{
  struct mntent mt;
  struct double_list *dev;
  struct f_sys_info *finfo;
  FILE *fp;
  char *tmp, **arg = toys.optargs;

  sigatexit(record_sig_num);
  while (*arg) {
    if ((**arg == '/') || strchr(*arg, '=')) {
      dlist_add(&TT.devices, xstrdup(*arg));
      **arg = '\0';
    }
    arg++;
  }
  if (toys.optflags & FLAG_t) fix_tlist();
  if (!(tmp = getenv("FSTAB_FILE"))) tmp = "/etc/fstab";
  if (!(fp = setmntent(tmp, "r"))) perror_exit("setmntent failed:");
  while (getmntent_r(fp, &mt, toybuf, 4096)) create_db(&mt);
  endmntent(fp);

  if (!(toys.optflags & FLAG_T)) xprintf("fsck ----- (Toybox)\n");

  if ((tmp = getenv("FSCK_MAX_INST"))) TT.max_nr_run = strtol_range(tmp, 0, INT_MAX);
  if (!TT.devices || (toys.optflags & FLAG_A)) {
    toys.exitval = scan_all();
    if (CFG_TOYBOX_FREE) free_all();
    return;
  }

  dev = TT.devices;
  dev->prev->next = NULL; //break double list to traverse.
  for (; dev; dev = dev->next) {
    for (finfo = filesys_info; finfo; finfo = finfo->next)
      if (!strcmp(finfo->device, dev->data) 
          || !strcmp(finfo->mountpt, dev->data)) break;
    if (!finfo) { //if not present, fill def values.
      mt.mnt_fsname = dev->data;
      mt.mnt_dir = "";
      mt.mnt_type = "auto";
      mt.mnt_opts = "";
      mt.mnt_passno = -1;
      finfo = create_db(&mt);
    }
    do_fsck(finfo);
    finfo->flag |= FLAG_DONE;
    if ((toys.optflags & FLAG_s) || (TT.nr_run && (TT.nr_run >= TT.max_nr_run))) 
      toys.exitval |= wait_for(0);
  }
  if (TT.sig_num) kill_all();
  toys.exitval |= wait_for(1);
  finfo = filesys_info;
  if (CFG_TOYBOX_FREE) free_all();
}
