/* vi: set sw=4 ts=4: */
/*
 * Mini pgrep/pkill implementation for busybox
 *
 * Copyright (C) 2007 Loic Grenie <loic.grenie@gmail.com>
 *
 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
 */

#include <getopt.h>

#include "libbb.h"
#include "xregex.h"

/* Idea taken from kill.c */
#define pgrep (ENABLE_PGREP && applet_name[1] == 'g')
#define pkill (ENABLE_PKILL && applet_name[1] == 'k')

enum {
	/* "vlfxon" */
	PGREPOPTBIT_V = 0, /* must be first, we need OPT_INVERT = 0/1 */
	PGREPOPTBIT_L,
	PGREPOPTBIT_F,
	PGREPOPTBIT_X,
	PGREPOPTBIT_O,
	PGREPOPTBIT_N,
};

#define OPT_INVERT	(opt & (1 << PGREPOPTBIT_V))
#define OPT_LIST	(opt & (1 << PGREPOPTBIT_L))
#define OPT_FULL	(opt & (1 << PGREPOPTBIT_F))
#define OPT_ANCHOR	(opt & (1 << PGREPOPTBIT_X))
#define OPT_FIRST	(opt & (1 << PGREPOPTBIT_O))
#define OPT_LAST	(opt & (1 << PGREPOPTBIT_N))

static void act(unsigned pid, char *cmd, int signo, unsigned opt)
{
	if (pgrep) {
		if (OPT_LIST)
			printf("%d %s\n", pid, cmd);
		else
			printf("%d\n", pid);
	} else
		kill(pid, signo);
}

int pgrep_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int pgrep_main(int argc, char **argv)
{
	unsigned pid = getpid();
	int signo = SIGTERM;
	unsigned opt;
	int scan_mask = PSSCAN_COMM;
	char *first_arg;
	int first_arg_idx;
	int matched_pid;
	char *cmd_last;
	procps_status_t *proc;
	/* These are initialized to 0 */
	struct {
		regex_t re_buffer;
		regmatch_t re_match[1];
	} Z;
#define re_buffer (Z.re_buffer)
#define re_match  (Z.re_match )

	memset(&Z, 0, sizeof(Z));

	/* We must avoid interpreting -NUM (signal num) as an option */
	first_arg_idx = 1;
	while (1) {
		first_arg = argv[first_arg_idx];
		if (!first_arg)
			break;
		if (first_arg[0] != '-' || first_arg[1] < 'a' || first_arg[1] > 'z') {
			argv[first_arg_idx] = NULL;
			break;
		}
		first_arg_idx++;
	}
	opt = getopt32(argv, "vlfxon");
	argv[first_arg_idx] = first_arg;

	argv += optind;
	//argc -= optind; - unused anyway
	if (OPT_FULL)
		scan_mask |= PSSCAN_ARGVN;

	if (pkill) {
		if (OPT_LIST) { /* -l: print the whole signal list */
			print_signames();
			return 0;
		}
		if (first_arg && first_arg[0] == '-') {
			signo = get_signum(&first_arg[1]);
			if (signo < 0) /* || signo > MAX_SIGNUM ? */
				bb_error_msg_and_die("bad signal name '%s'", &first_arg[1]);
			argv++;
		}
	}

	/* One pattern is required */
	if (!argv[0] || argv[1])
		bb_show_usage();

	xregcomp(&re_buffer, argv[0], 0);
	matched_pid = 0;
	cmd_last = NULL;
	proc = NULL;
	while ((proc = procps_scan(proc, scan_mask)) != NULL) {
		char *cmd;
		if (proc->pid == pid)
			continue;
		cmd = proc->argv0;
		if (!cmd)
			cmd = proc->comm;
		/* NB: OPT_INVERT is always 0 or 1 */
		if ((regexec(&re_buffer, cmd, 1, re_match, 0) == 0 /* match found */
                     && (!OPT_ANCHOR || (re_match[0].rm_so == 0 && re_match[0].rm_eo == strlen(cmd)))) ^ OPT_INVERT
		) {
			matched_pid = proc->pid;
			if (OPT_LAST) {
				free(cmd_last);
				cmd_last = xstrdup(cmd);
				continue;
			}
			act(proc->pid, cmd, signo, opt);
			if (OPT_FIRST)
				break;
		}
	}
	if (cmd_last) {
		act(matched_pid, cmd_last, signo, opt);
		if (ENABLE_FEATURE_CLEAN_UP)
			free(cmd_last);
	}
	return matched_pid == 0; /* return 1 if no processes listed/signaled */
}
