/* 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;
};
#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;
}
