/* vi: set sw=4 ts=4: */
/*
 * tiny fuser implementation
 *
 * Copyright 2004 Tony J. White
 *
 * Licensed under GPLv2, see file LICENSE in this source tree.
 */

#include "libbb.h"

#define MAX_LINE 255

#define OPTION_STRING "mks64"
enum {
	OPT_MOUNT  = (1 << 0),
	OPT_KILL   = (1 << 1),
	OPT_SILENT = (1 << 2),
	OPT_IP6    = (1 << 3),
	OPT_IP4    = (1 << 4),
};

typedef struct inode_list {
	struct inode_list *next;
	ino_t inode;
	dev_t dev;
} inode_list;

typedef struct pid_list {
	struct pid_list *next;
	pid_t pid;
} pid_list;


struct globals {
	pid_list *pid_list_head;
	inode_list *inode_list_head;
} FIX_ALIASING;
#define G (*(struct globals*)&bb_common_bufsiz1)
#define INIT_G() do { } while (0)


static void add_pid(const pid_t pid)
{
	pid_list **curr = &G.pid_list_head;

	while (*curr) {
		if ((*curr)->pid == pid)
			return;
		curr = &(*curr)->next;
	}

	*curr = xzalloc(sizeof(pid_list));
	(*curr)->pid = pid;
}

static void add_inode(const struct stat *st)
{
	inode_list **curr = &G.inode_list_head;

	while (*curr) {
		if ((*curr)->dev == st->st_dev
		 && (*curr)->inode == st->st_ino
		) {
			return;
		}
		curr = &(*curr)->next;
	}

	*curr = xzalloc(sizeof(inode_list));
	(*curr)->dev = st->st_dev;
	(*curr)->inode = st->st_ino;
}

static void scan_proc_net(const char *path, unsigned port)
{
	char line[MAX_LINE + 1];
	long long uint64_inode;
	unsigned tmp_port;
	FILE *f;
	struct stat st;
	int fd;

	/* find socket dev */
	st.st_dev = 0;
	fd = socket(AF_INET, SOCK_DGRAM, 0);
	if (fd >= 0) {
		fstat(fd, &st);
		close(fd);
	}

	f = fopen_for_read(path);
	if (!f)
		return;

	while (fgets(line, MAX_LINE, f)) {
		char addr[68];
		if (sscanf(line, "%*d: %64[0-9A-Fa-f]:%x %*x:%*x %*x %*x:%*x "
				"%*x:%*x %*x %*d %*d %llu",
				addr, &tmp_port, &uint64_inode) == 3
		) {
			int len = strlen(addr);
			if (len == 8 && (option_mask32 & OPT_IP6))
				continue;
			if (len > 8 && (option_mask32 & OPT_IP4))
				continue;
			if (tmp_port == port) {
				st.st_ino = uint64_inode;
				add_inode(&st);
			}
		}
	}
	fclose(f);
}

static int search_dev_inode(const struct stat *st)
{
	inode_list *ilist = G.inode_list_head;

	while (ilist) {
		if (ilist->dev == st->st_dev) {
			if (option_mask32 & OPT_MOUNT)
				return 1;
			if (ilist->inode == st->st_ino)
				return 1;
		}
		ilist = ilist->next;
	}
	return 0;
}

static void scan_pid_maps(const char *fname, pid_t pid)
{
	FILE *file;
	char line[MAX_LINE + 1];
	int major, minor;
	long long uint64_inode;
	struct stat st;

	file = fopen_for_read(fname);
	if (!file)
		return;

	while (fgets(line, MAX_LINE, file)) {
		if (sscanf(line, "%*s %*s %*s %x:%x %llu", &major, &minor, &uint64_inode) != 3)
			continue;
		st.st_ino = uint64_inode;
		if (major == 0 && minor == 0 && st.st_ino == 0)
			continue;
		st.st_dev = makedev(major, minor);
		if (search_dev_inode(&st))
			add_pid(pid);
	}
	fclose(file);
}

static void scan_link(const char *lname, pid_t pid)
{
	struct stat st;

	if (stat(lname, &st) >= 0) {
		if (search_dev_inode(&st))
			add_pid(pid);
	}
}

static void scan_dir_links(const char *dname, pid_t pid)
{
	DIR *d;
	struct dirent *de;
	char *lname;

	d = opendir(dname);
	if (!d)
		return;

	while ((de = readdir(d)) != NULL) {
		lname = concat_subpath_file(dname, de->d_name);
		if (lname == NULL)
			continue;
		scan_link(lname, pid);
		free(lname);
	}
	closedir(d);
}

/* NB: does chdir internally */
static void scan_proc_pids(void)
{
	DIR *d;
	struct dirent *de;
	pid_t pid;

	xchdir("/proc");
	d = opendir("/proc");
	if (!d)
		return;

	while ((de = readdir(d)) != NULL) {
		pid = (pid_t)bb_strtou(de->d_name, NULL, 10);
		if (errno)
			continue;
		if (chdir(de->d_name) < 0)
			continue;
		scan_link("cwd", pid);
		scan_link("exe", pid);
		scan_link("root", pid);

		scan_dir_links("fd", pid);
		scan_dir_links("lib", pid);
		scan_dir_links("mmap", pid);

		scan_pid_maps("maps", pid);
		xchdir("/proc");
	}
	closedir(d);
}

int fuser_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int fuser_main(int argc UNUSED_PARAM, char **argv)
{
	pid_list *plist;
	pid_t mypid;
	char **pp;
	struct stat st;
	unsigned port;
	int opt;
	int exitcode;
	int killsig;
/*
fuser [OPTIONS] FILE or PORT/PROTO
Find processes which use FILEs or PORTs
        -m      Find processes which use same fs as FILEs
        -4      Search only IPv4 space
        -6      Search only IPv6 space
        -s      Don't display PIDs
        -k      Kill found processes
        -SIGNAL Signal to send (default: KILL)
*/
	/* Handle -SIGNAL. Oh my... */
	killsig = SIGKILL; /* yes, the default is not SIGTERM */
	pp = argv;
	while (*++pp) {
		char *arg = *pp;
		if (arg[0] != '-')
			continue;
		if (arg[1] == '-' && arg[2] == '\0') /* "--" */
			break;
		if ((arg[1] == '4' || arg[1] == '6') && arg[2] == '\0')
			continue; /* it's "-4" or "-6" */
		opt = get_signum(&arg[1]);
		if (opt < 0)
			continue;
		/* "-SIGNAL" option found. Remove it and bail out */
		killsig = opt;
		do {
			pp[0] = arg = pp[1];
			pp++;
		} while (arg);
		break;
	}

	opt_complementary = "-1"; /* at least one param */
	opt = getopt32(argv, OPTION_STRING);
	argv += optind;

	pp = argv;
	while (*pp) {
		/* parse net arg */
		char path[20], tproto[5];
		if (sscanf(*pp, "%u/%4s", &port, tproto) != 2)
			goto file;
		sprintf(path, "/proc/net/%s", tproto);
		if (access(path, R_OK) != 0) { /* PORT/PROTO */
			scan_proc_net(path, port);
		} else { /* FILE */
 file:
			xstat(*pp, &st);
			add_inode(&st);
		}
		pp++;
	}

	scan_proc_pids(); /* changes dir to "/proc" */

	mypid = getpid();
	plist = G.pid_list_head;
	while (1) {
		if (!plist)
			return EXIT_FAILURE;
		if (plist->pid != mypid)
			break;
		plist = plist->next;
	}

	exitcode = EXIT_SUCCESS;
	do {
		if (plist->pid != mypid) {
			if (opt & OPT_KILL) {
				if (kill(plist->pid, killsig) != 0) {
					bb_perror_msg("kill pid %u", (unsigned)plist->pid);
					exitcode = EXIT_FAILURE;
				}
			}
			if (!(opt & OPT_SILENT)) {
				printf("%u ", (unsigned)plist->pid);
			}
		}
		plist = plist->next;
	} while (plist);

	if (!(opt & (OPT_SILENT))) {
		bb_putchar('\n');
	}

	return exitcode;
}
