/* 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];
	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, "/proc/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;
}

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