/*
 * pstree.c - display process tree
 *
 * Copyright (C) 1993-2002 Werner Almesberger
 * Copyright (C) 2002-2009 Craig Small
 * Copyright (C) 2010 Lauri Kasanen
 *
 * Based on pstree (PSmisc) 22.13.
 *
 * Licensed under GPLv2, see file LICENSE in this source tree.
 */

//config:config PSTREE
//config:	bool "pstree"
//config:	default y
//config:	help
//config:	  Display a tree of processes.

//applet:IF_PSTREE(APPLET(pstree, _BB_DIR_USR_BIN, _BB_SUID_DROP))

//kbuild:lib-$(CONFIG_PSTREE) += pstree.o

//usage:#define pstree_trivial_usage
//usage:	"[-p] [PID|USER]"
//usage:#define pstree_full_usage "\n\n"
//usage:       "Display process tree, optionally start from USER or PID\n"
//usage:     "\nOptions:"
//usage:     "\n	-p	Show pids"

#include "libbb.h"

#define PROC_BASE "/proc"

#define OPT_PID  (1 << 0)

struct child;

typedef struct proc {
	char comm[COMM_LEN + 1];
//	char flags; - unused, delete?
	pid_t pid;
	uid_t uid;
	struct child *children;
	struct proc *parent;
	struct proc *next;
} PROC;

/* For flags above */
//#define PFLAG_THREAD  0x01

typedef struct child {
	PROC *child;
	struct child *next;
} CHILD;

#define empty_2  "  "
#define branch_2 "|-"
#define vert_2   "| "
#define last_2   "`-"
#define single_3 "---"
#define first_3  "-+-"

struct globals {
	/* 0-based. IOW: the number of chars we printed on current line */
	unsigned cur_x;
	unsigned output_width;

	/* The buffers will be dynamically increased in size as needed */
	unsigned capacity;
	unsigned *width;
	uint8_t *more;

	PROC *list;

	smallint dumped; /* used by dump_by_user */
};
#define G (*ptr_to_globals)
#define INIT_G() do { \
        SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
} while (0)


/*
 * Allocates additional buffer space for width and more as needed.
 * The first call will allocate the first buffer.
 *
 * bufindex  the index that will be used after the call to this function.
 */
static void ensure_buffer_capacity(int bufindex)
{
	if (bufindex >= G.capacity) {
		G.capacity += 0x100;
		G.width = xrealloc(G.width, G.capacity * sizeof(G.width[0]));
		G.more = xrealloc(G.more, G.capacity * sizeof(G.more[0]));
	}
}

/* NB: this function is never called with "bad" chars
 * (control chars or chars >= 0x7f)
 */
static void out_char(char c)
{
	G.cur_x++;
	if (G.cur_x > G.output_width)
		return;
	if (G.cur_x == G.output_width)
		c = '+';
	putchar(c);
}

/* NB: this function is never called with "bad" chars
 * (control chars or chars >= 0x7f)
 */
static void out_string(const char *str)
{
	while (*str)
		out_char(*str++);
}

static void out_newline(void)
{
	putchar('\n');
	G.cur_x = 0;
}

static PROC *find_proc(pid_t pid)
{
	PROC *walk;

	for (walk = G.list; walk; walk = walk->next)
		if (walk->pid == pid)
			break;

	return walk;
}

static PROC *new_proc(const char *comm, pid_t pid, uid_t uid)
{
	PROC *new = xzalloc(sizeof(*new));

	strcpy(new->comm, comm);
	new->pid = pid;
	new->uid = uid;
	new->next = G.list;

	G.list = new;
	return G.list;
}

static void add_child(PROC *parent, PROC *child)
{
	CHILD *new, **walk;
	int cmp;

	new = xmalloc(sizeof(*new));

	new->child = child;
	for (walk = &parent->children; *walk; walk = &(*walk)->next) {
		cmp = strcmp((*walk)->child->comm, child->comm);
		if (cmp > 0)
			break;
		if (cmp == 0 && (*walk)->child->uid > child->uid)
			break;
	}
	new->next = *walk;
	*walk = new;
}

static void add_proc(const char *comm, pid_t pid, pid_t ppid,
			uid_t uid /*, char isthread*/)
{
	PROC *this, *parent;

	this = find_proc(pid);
	if (!this)
		this = new_proc(comm, pid, uid);
	else {
		strcpy(this->comm, comm);
		this->uid = uid;
	}

	if (pid == ppid)
		ppid = 0;
//	if (isthread)
//		this->flags |= PFLAG_THREAD;

	parent = find_proc(ppid);
	if (!parent)
		parent = new_proc("?", ppid, 0);

	add_child(parent, this);
	this->parent = parent;
}

static int tree_equal(const PROC *a, const PROC *b)
{
	const CHILD *walk_a, *walk_b;

	if (strcmp(a->comm, b->comm) != 0)
		return 0;
	if ((option_mask32 /*& OPT_PID*/) && a->pid != b->pid)
		return 0;

	for (walk_a = a->children, walk_b = b->children;
	  walk_a && walk_b;
	  walk_a = walk_a->next, walk_b = walk_b->next
	) {
		if (!tree_equal(walk_a->child, walk_b->child))
			return 0;
	}

	return !(walk_a || walk_b);
}

static int out_args(const char *mystr)
{
	const char *here;
	int strcount = 0;
	char tmpstr[5];

	for (here = mystr; *here; here++) {
		if (*here == '\\') {
			out_string("\\\\");
			strcount += 2;
		} else if (*here >= ' ' && *here < 0x7f) {
			out_char(*here);
			strcount++;
		} else {
			sprintf(tmpstr, "\\%03o", (unsigned char) *here);
			out_string(tmpstr);
			strcount += 4;
		}
	}

	return strcount;
}

static void
dump_tree(PROC *current, int level, int rep, int leaf, int last, int closing)
{
	CHILD *walk, *next, **scan;
	int lvl, i, add, offset, count, comm_len, first;
	char tmp[sizeof(int)*3 + 4];

	if (!current)
		return;

	if (!leaf) {
		for (lvl = 0; lvl < level; lvl++) {
			i = G.width[lvl] + 1;
			while (--i >= 0)
				out_char(' ');

			if (lvl == level - 1) {
				if (last) {
					out_string(last_2);
				} else {
					out_string(branch_2);
				}
			} else {
				if (G.more[lvl + 1]) {
					out_string(vert_2);
				} else {
					out_string(empty_2);
				}
			}
		}
	}

	add = 0;
	if (rep > 1) {
		add += sprintf(tmp, "%d*[", rep);
		out_string(tmp);
	}
	comm_len = out_args(current->comm);
	if (option_mask32 /*& OPT_PID*/) {
		comm_len += sprintf(tmp, "(%d)", (int)current->pid);
		out_string(tmp);
	}
	offset = G.cur_x;

	if (!current->children)	{
		while (closing--)
			out_char(']');
		out_newline();
	}
	ensure_buffer_capacity(level);
	G.more[level] = !last;

	G.width[level] = comm_len + G.cur_x - offset + add;
	if (G.cur_x >= G.output_width) {
		//out_string(first_3); - why? it won't print anything
		//out_char('+');
		out_newline();
		return;
	}

	first = 1;
	for (walk = current->children; walk; walk = next) {
		count = 0;
		next = walk->next;
		scan = &walk->next;
		while (*scan) {
			if (!tree_equal(walk->child, (*scan)->child))
				scan = &(*scan)->next;
			else {
				if (next == *scan)
					next = (*scan)->next;
				count++;
				*scan = (*scan)->next;
			}
		}
		if (first) {
			out_string(next ? first_3 : single_3);
			first = 0;
		}

		dump_tree(walk->child, level + 1, count + 1,
				walk == current->children, !next,
				closing + (count ? 1 : 0));
	}
}

static void dump_by_user(PROC *current, uid_t uid)
{
	const CHILD *walk;

	if (!current)
		return;

	if (current->uid == uid) {
		if (G.dumped)
			putchar('\n');
		dump_tree(current, 0, 1, 1, 1, 0);
		G.dumped = 1;
		return;
	}
	for (walk = current->children; walk; walk = walk->next)
		dump_by_user(walk->child, uid);
}

static void handle_thread(const char *comm, pid_t pid, pid_t ppid, uid_t uid)
{
	char threadname[COMM_LEN + 2];
	sprintf(threadname, "{%.*s}", COMM_LEN - 2, comm);
	add_proc(threadname, pid, ppid, uid/*, 1*/);
}

static void mread_proc(void)
{
	procps_status_t *p = NULL;
	pid_t parent = 0;
	int flags = PSSCAN_COMM | PSSCAN_PID | PSSCAN_PPID | PSSCAN_UIDGID | PSSCAN_TASKS;

	while ((p = procps_scan(p, flags)) != NULL) {
#if ENABLE_FEATURE_SHOW_THREADS
		if (p->pid != p->main_thread_pid)
			handle_thread(p->comm, p->pid, parent, p->uid);
		else
#endif
		{
			add_proc(p->comm, p->pid, p->ppid, p->uid/*, 0*/);
			parent = p->pid;
		}
	}
}

int pstree_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int pstree_main(int argc UNUSED_PARAM, char **argv)
{
	pid_t pid = 1;
	long uid = 0;

	INIT_G();

	get_terminal_width_height(0, &G.output_width, NULL);

	opt_complementary = "?1";
	getopt32(argv, "p");
	argv += optind;

	if (argv[0]) {
		if (argv[0][0] >= '0' && argv[0][0] <= '9') {
			pid = xatoi(argv[0]);
		} else {
			uid = xuname2uid(argv[0]);
		}
	}

	mread_proc();

	if (!uid)
		dump_tree(find_proc(pid), 0, 1, 1, 1, 0);
	else {
		dump_by_user(find_proc(1), uid);
		if (!G.dumped) {
			bb_error_msg_and_die("no processes found");
		}
	}

	if (ENABLE_FEATURE_CLEAN_UP) {
		free(G.width);
		free(G.more);
	}
	return 0;
}
