/* vi: set sw=4 ts=4: */
/*
 * tiny fuser implementation
 *
 * Copyright 2004 Tony J. White
 *
 * May be distributed under the conditions of the
 * GNU Library General Public License
 */

#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;

static dev_t find_socket_dev(void)
{
	int fd = socket(AF_INET, SOCK_DGRAM, 0);
	if (fd >= 0) {
		struct stat buf;
		int r = fstat(fd, &buf);
		close(fd);
		if (r == 0)
			return buf.st_dev;
	}
	return 0;
}

static int file_to_dev_inode(const char *filename, dev_t *dev, ino_t *inode)
{
	struct stat f_stat;
	if (stat(filename, &f_stat))
		return 0;
	*inode = f_stat.st_ino;
	*dev = f_stat.st_dev;
	return 1;
}

static char *parse_net_arg(const char *arg, unsigned *port)
{
	char path[12], tproto[5];

	if (sscanf(arg, "%u/%4s", port, tproto) != 2)
		return NULL;
	sprintf(path, "net/%s", tproto);
	if (access(path, R_OK) != 0)
		return NULL;
	return xstrdup(tproto);
}

static pid_list *add_pid(pid_list *plist, pid_t pid)
{
	pid_list *curr = plist;
	while (curr != NULL) {
		if (curr->pid == pid)
			return plist;
		curr = curr->next;
	}
	curr = xmalloc(sizeof(pid_list));
	curr->pid = pid;
	curr->next = plist;
	return curr;
}

static inode_list *add_inode(inode_list *ilist, dev_t dev, ino_t inode)
{
	inode_list *curr = ilist;
	while (curr != NULL) {
		if (curr->inode == inode && curr->dev == dev)
			return ilist;
		curr = curr->next;
	}
	curr = xmalloc(sizeof(inode_list));
	curr->dev = dev;
	curr->inode = inode;
	curr->next = ilist;
	return curr;
}

static inode_list *scan_proc_net(const char *proto,
				unsigned port, inode_list *ilist)
{
	char path[12], line[MAX_LINE + 1];
	char addr[128];
	ino_t tmp_inode;
	dev_t tmp_dev;
	long long uint64_inode;
	unsigned tmp_port;
	FILE *f;

	tmp_dev = find_socket_dev();

	sprintf(path, "net/%s", proto);
	f = fopen(path, "r");
	if (!f)
		return ilist;

	while (fgets(line, MAX_LINE, f)) {
		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
		) {
			if (strlen(addr) == 8 && (option_mask32 & OPT_IP6))
				continue;
			if (strlen(addr) > 8 && (option_mask32 & OPT_IP4))
				continue;
			if (tmp_port == port) {
				tmp_inode = uint64_inode;
				ilist = add_inode(ilist, tmp_dev, tmp_inode);
			}
		}
	}
	fclose(f);
	return ilist;
}

static int search_dev_inode(inode_list *ilist, dev_t dev, ino_t inode)
{
	while (ilist) {
		if (ilist->dev == dev) {
			if (option_mask32 & OPT_MOUNT)
				return 1;
			if (ilist->inode == inode)
				return 1;
		}
		ilist = ilist->next;
	}
	return 0;
}

static pid_list *scan_pid_maps(const char *fname, pid_t pid,
				inode_list *ilist, pid_list *plist)
{
	FILE *file;
	char line[MAX_LINE + 1];
	int major, minor;
	ino_t inode;
	long long uint64_inode;
	dev_t dev;

	file = fopen(fname, "r");
	if (!file)
		return plist;
	while (fgets(line, MAX_LINE, file)) {
		if (sscanf(line, "%*s %*s %*s %x:%x %llu", &major, &minor, &uint64_inode) != 3)
			continue;
		inode = uint64_inode;
		if (major == 0 && minor == 0 && inode == 0)
			continue;
		dev = makedev(major, minor);
		if (search_dev_inode(ilist, dev, inode))
			plist = add_pid(plist, pid);
	}
	fclose(file);
	return plist;
}

static pid_list *scan_link(const char *lname, pid_t pid,
				inode_list *ilist, pid_list *plist)
{
	ino_t inode;
	dev_t dev;

	if (!file_to_dev_inode(lname, &dev, &inode))
		return plist;
	if (search_dev_inode(ilist, dev, inode))
		plist = add_pid(plist, pid);
	return plist;
}

static pid_list *scan_dir_links(const char *dname, pid_t pid,
				inode_list *ilist, pid_list *plist)
{
	DIR *d;
	struct dirent *de;
	char *lname;

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

static pid_list *scan_proc_pids(inode_list *ilist)
{
	DIR *d;
	struct dirent *de;
	pid_t pid;
	pid_list *plist;

	d = opendir(".");
	if (!d)
		return NULL;

	plist = NULL;
	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;
		plist = scan_link("cwd", pid, ilist, plist);
		plist = scan_link("exe", pid, ilist, plist);
		plist = scan_link("root", pid, ilist, plist);
		plist = scan_dir_links("fd", pid, ilist, plist);
		plist = scan_dir_links("lib", pid, ilist, plist);
		plist = scan_dir_links("mmap", pid, ilist, plist);
		plist = scan_pid_maps("maps", pid, ilist, plist);
		xchdir("/proc");
	}
	closedir(d);
	return plist;
}

static int print_pid_list(pid_list *plist)
{
	while (plist != NULL) {
		printf("%u ", (unsigned)plist->pid);
		plist = plist->next;
	}
	bb_putchar('\n');
	return 1;
}

static int kill_pid_list(pid_list *plist, int sig)
{
	pid_t mypid = getpid();
	int success = 1;

	while (plist != NULL) {
		if (plist->pid != mypid) {
			if (kill(plist->pid, sig) != 0) {
				bb_perror_msg("kill pid %u", (unsigned)plist->pid);
				success = 0;
			}
		}
		plist = plist->next;
	}
	return success;
}

int fuser_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int fuser_main(int argc, char **argv)
{
	pid_list *plist;
	inode_list *ilist;
	char **pp;
	dev_t dev;
	ino_t inode;
	unsigned port;
	int opt;
	int success;
	int killsig;
/*
fuser [options] FILEs or PORT/PROTOs
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      Silent: just exit with 0 if any processes are found
        -k      Kill found processes (otherwise display PIDs)
        -SIGNAL Signal to send (default: TERM)
*/
	/* Handle -SIGNAL. Oh my... */
	killsig = 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 = getopt32(argv, OPTION_STRING);
	argv += optind;

	xchdir("/proc");

	ilist = NULL;
	pp = argv;
	while (*pp) {
		char *proto = parse_net_arg(*pp, &port);
		if (proto) { /* PORT/PROTO */
			ilist = scan_proc_net(proto, port, ilist);
			free(proto);
		} else { /* FILE */
			if (!file_to_dev_inode(*pp, &dev, &inode))
				bb_perror_msg_and_die("can't open %s", *pp);
			ilist = add_inode(ilist, dev, inode);
		}
		pp++;
	}

	plist = scan_proc_pids(ilist);

	if (!plist)
		return EXIT_FAILURE;
	success = 1;
	if (opt & OPT_KILL) {
		success = kill_pid_list(plist, killsig);
	} else if (!(opt & OPT_SILENT)) {
		success = print_pid_list(plist);
	}
	return (success != 1); /* 0 == success */
}
