/* 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[20], tproto[5];

	if (sscanf(arg, "%u/%4s", port, tproto) != 2)
		return NULL;
	sprintf(path, "/proc/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[20], line[MAX_LINE + 1];
	ino_t tmp_inode;
	dev_t tmp_dev;
	long long uint64_inode;
	unsigned tmp_port;
	FILE *f;

	tmp_dev = find_socket_dev();

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

	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) {
				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_for_read(fname);
	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;
}

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

	xchdir("/proc");
	d = opendir("/proc");
	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 UNUSED_PARAM, 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;

	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); /* changes dir to "/proc" */

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