/* pgrep.c - pgrep and pkill implementation
 *
 * Copyright 2012 Madhur Verma <mad.flexi@gmail.com>
 * Copyright 2013 Kyungwan Han <asura321@gmail.com>
 *

USE_PGREP(NEWTOY(pgrep, "?P# s# xvonlf[!sP]", TOYFLAG_USR|TOYFLAG_BIN))
USE_PGREP(OLDTOY(pkill, pgrep, OPTSTR_pgrep, TOYFLAG_USR|TOYFLAG_BIN))

config PGREP
  bool "pgrep"
  default n
  help
    usage: pgrep [-flnovx] [-s SID|-P PPID|PATTERN]
           pkill [-l|-SIGNAL] [-fnovx] [-s SID|-P PPID|PATTERN]

    -l  Show command name too / List all signals
    -f  Match against entire command line
    -n  Show/Signal the newest process only
    -o  Show/Signal the oldest process only
    -v  Negate the match
    -x  Match whole name (not substring)
    -s  Match session ID (0 for current)
    -P  Match parent process ID
*/

#define FOR_pgrep
#include "toys.h"
#include <regex.h>

#define flag_get(f,v,d)   ((toys.optflags & f) ? v : d)
#define flag_chk(f)       ((toys.optflags & f) ? 1 : 0)

GLOBALS(
  long sid;       //-s
  long ppid;      //-P
  char *signame;
)

static int exec_action(unsigned pid, char *name, int signal)
{
  if (toys.which->name[1] == 'g') {
    printf("%d", pid);
    if (flag_chk(FLAG_l)) printf(" %s", name);
    printf("\n");
  } else {
    kill(pid, signal);
  }
  return 0;
}

static int regex_match(regex_t *rp, char *tar, char *patt)
{
  regmatch_t rm[1];
  int len = strlen(tar);
  if (regexec(rp, tar, 1, rm, 0) == 0) {
    if (flag_chk(FLAG_x)) {
      if ((rm[0].rm_so == 0) && ((rm[0].rm_eo - rm[0].rm_so) == len)) return 1;
    } else return 1;
  }
  return 0;
}

void pgrep_main(void)
{
  int signum=0, eval=0, ret=1;
  DIR *dp=NULL;
  struct dirent *entry=NULL;
  regex_t rp;
  unsigned  pid=0, ppid=0, sid=0, latest_pid=0;
  char *cmdline=NULL, *latest_cmdline = NULL;
  pid_t self = getpid();

  if (!(dp = opendir("/proc"))) perror_exit("OPENDIR: failed to open /proc");
  setlinebuf(stdout);

  if (toys.which->name[1] == 'k') {
    if (flag_chk(FLAG_l)) {
      sig_to_num(NULL);
      return;
    }
    if (!TT.signame && *toys.optargs && **toys.optargs == '-') {
      TT.signame = *(toys.optargs++) + 1;
    }
    if (TT.signame) {
      char *arg;
      int i = strtol(TT.signame, &arg, 10);
      if (!*arg) arg = num_to_sig(i);
      else arg = TT.signame;
      if (!arg || (signum = sig_to_num(arg)) == -1)
        error_exit("Unknown signal '%s'", arg);
    } else signum = SIGTERM;
  }
  if (!(flag_chk(FLAG_s) || flag_chk(FLAG_P)) && !*toys.optargs) {
    toys.exithelp++;
    error_exit("missing argument");
  }
  if (*(toys.optargs+1) && !(flag_chk(FLAG_s) || flag_chk(FLAG_P))) {
    toys.exithelp++;
    error_exit("max argument > 1");
  }
  if (*toys.optargs) { /* compile regular expression(PATTERN) */
    if ((eval = regcomp(&rp, *toys.optargs, REG_EXTENDED | REG_NOSUB)) != 0) {
      char errbuf[256];
      (void) regerror(eval, &rp, errbuf, sizeof(errbuf));
      error_exit("%s", errbuf);
    }
  }
  if (flag_chk(FLAG_s)&&(TT.sid==0)) TT.sid = getsid(0);
  while ((entry = readdir(dp))) {
    int fd = -1, n = 0;
    if (!isdigit(*entry->d_name)) continue;

    pid = strtol(entry->d_name, NULL, 10);
    if (pid == self) continue;

    snprintf(toybuf, sizeof(toybuf), "/proc/%s/cmdline", entry->d_name);
    if ((fd = open(toybuf, O_RDONLY)) == -1) goto cmdline_fail;
    n = read(fd, toybuf, sizeof(toybuf));
    close(fd);
    toybuf[n--] = '\0';
    if (n < 0) {
cmdline_fail:
      snprintf(toybuf, sizeof(toybuf), "/proc/%s/comm", entry->d_name);
      if ((fd = open(toybuf, O_RDONLY)) == -1) continue;
      n = read(fd, toybuf, sizeof(toybuf));
      close(fd);
      toybuf[--n] = '\0';
      if (n < 1) continue;
    }
    if (flag_chk(FLAG_f)) {
      while (--n)
        if (toybuf[n] < ' ') toybuf[n] = ' ';
    }
    if (cmdline) free(cmdline);
    cmdline = xstrdup(toybuf);
    if (flag_chk(FLAG_s) || flag_chk(FLAG_P)) {
      snprintf(toybuf, sizeof(toybuf), "/proc/%s/stat", entry->d_name);
      if ((fd = open(toybuf, O_RDONLY)) == -1) continue;
      n = read(fd, toybuf, sizeof(toybuf));
      close(fd);
      if (n<1) continue;
      n = sscanf(toybuf, "%*u %*s %*c %u %*u %u", &ppid, &sid);
      if (flag_chk(FLAG_s)) if (sid != TT.sid) continue;
      if (flag_chk(FLAG_P)) if (ppid != TT.ppid) continue;
    }
    if (!*toys.optargs || (regex_match(&rp, cmdline, *toys.optargs)^flag_chk(FLAG_v))) {
      if (flag_chk(FLAG_n)) {
        if (latest_cmdline) free(latest_cmdline);
        latest_cmdline = xstrdup(cmdline);
        latest_pid = pid;
      } else exec_action(pid, cmdline, signum);
      ret = 0;
      if (flag_chk(FLAG_o)) break;
    }
  }
  if (cmdline) free(cmdline);
  if (latest_cmdline) {
    exec_action(latest_pid, latest_cmdline, signum);
    free(latest_cmdline);
  }
  if (*toys.optargs) regfree(&rp);
  closedir(dp);
  toys.exitval = ret;
}
