/*
 * lslocks(8) - list local system locks
 *
 * Copyright (C) 2012 Davidlohr Bueso <dave@gnu.org>
 *
 * Very generally based on lslk(8) by Victor A. Abell <abe@purdue.edu>
 * Since it stopped being maintained over a decade ago, this
 * program should be considered its replacement.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <stdio.h>
#include <string.h>
#include <getopt.h>
#include <stdlib.h>
#include <assert.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <libmount.h>
#include <libsmartcols.h>

#include "pathnames.h"
#include "canonicalize.h"
#include "nls.h"
#include "xalloc.h"
#include "strutils.h"
#include "c.h"
#include "list.h"
#include "closestream.h"
#include "optutils.h"
#include "procutils.h"

/* column IDs */
enum {
	COL_SRC = 0,
	COL_PID,
	COL_TYPE,
	COL_SIZE,
	COL_MODE,
	COL_M,
	COL_START,
	COL_END,
	COL_PATH,
	COL_BLOCKER
};

/* column names */
struct colinfo {
	const char *name; /* header */
	double	   whint; /* width hint (N < 1 is in percent of termwidth) */
	int	   flags; /* SCOLS_FL_* */
	const char *help;
};

/* columns descriptions */
static struct colinfo infos[] = {
	[COL_SRC]  = { "COMMAND",15, 0, N_("command of the process holding the lock") },
	[COL_PID]  = { "PID",     5, SCOLS_FL_RIGHT, N_("PID of the process holding the lock") },
	[COL_TYPE] = { "TYPE",    5, SCOLS_FL_RIGHT, N_("kind of lock") },
	[COL_SIZE] = { "SIZE",    4, SCOLS_FL_RIGHT, N_("size of the lock") },
	[COL_MODE] = { "MODE",    5, 0, N_("lock access mode") },
	[COL_M]    = { "M",       1, 0, N_("mandatory state of the lock: 0 (none), 1 (set)")},
	[COL_START] = { "START", 10, SCOLS_FL_RIGHT, N_("relative byte offset of the lock")},
	[COL_END]  = { "END",    10, SCOLS_FL_RIGHT, N_("ending offset of the lock")},
	[COL_PATH] = { "PATH",    0, SCOLS_FL_TRUNC, N_("path of the locked file")},
	[COL_BLOCKER] = { "BLOCKER", 0, SCOLS_FL_RIGHT, N_("PID of the process blocking the lock") }
};

static int columns[ARRAY_SIZE(infos) * 2];
static size_t ncolumns;

static pid_t pid = 0;

static struct libmnt_table *tab;		/* /proc/self/mountinfo */

/* basic output flags */
static int no_headings;
static int no_inaccessible;
static int raw;
static int json;
static int bytes;

struct lock {
	struct list_head locks;

	char *cmdname;
	pid_t pid;
	char *path;
	char *type;
	char *mode;
	off_t start;
	off_t end;
	unsigned int mandatory :1,
		     blocked   :1;
	uint64_t size;
	int id;
};

static void rem_lock(struct lock *lock)
{
	if (!lock)
		return;

	free(lock->path);
	free(lock->mode);
	free(lock->cmdname);
	free(lock->type);
	list_del(&lock->locks);
	free(lock);
}

static void disable_columns_truncate(void)
{
	size_t i;

	for (i = 0; i < ARRAY_SIZE(infos); i++)
		infos[i].flags &= ~SCOLS_FL_TRUNC;
}

/*
 * Associate the device's mountpoint for a filename
 */
static char *get_fallback_filename(dev_t dev)
{
	struct libmnt_fs *fs;
	char *res = NULL;

	if (!tab) {
		tab = mnt_new_table_from_file(_PATH_PROC_MOUNTINFO);
		if (!tab)
			return NULL;
	}

	fs = mnt_table_find_devno(tab, dev, MNT_ITER_BACKWARD);
	if (!fs)
		return NULL;

	xasprintf(&res, "%s...", mnt_fs_get_target(fs));
	return res;
}

/*
 * Return the absolute path of a file from
 * a given inode number (and its size)
 */
static char *get_filename_sz(ino_t inode, pid_t lock_pid, size_t *size)
{
	struct stat sb;
	struct dirent *dp;
	DIR *dirp;
	size_t len;
	int fd;
	char path[PATH_MAX], sym[PATH_MAX], *ret = NULL;

	*size = 0;
	memset(path, 0, sizeof(path));
	memset(sym, 0, sizeof(sym));

	/*
	 * We know the pid so we don't have to
	 * iterate the *entire* filesystem searching
	 * for the damn file.
	 */
	sprintf(path, "/proc/%d/fd/", lock_pid);
	if (!(dirp = opendir(path)))
		return NULL;

	if ((len = strlen(path)) >= (sizeof(path) - 2))
		goto out;

	if ((fd = dirfd(dirp)) < 0 )
		goto out;

	while ((dp = readdir(dirp))) {
		if (!strcmp(dp->d_name, ".") ||
		    !strcmp(dp->d_name, ".."))
			continue;

		/* care only for numerical descriptors */
		if (!strtol(dp->d_name, (char **) NULL, 10))
			continue;

		if (!fstatat(fd, dp->d_name, &sb, 0)
		    && inode != sb.st_ino)
			continue;

		if ((len = readlinkat(fd, dp->d_name, sym, sizeof(sym) - 1)) < 1)
			goto out;

		*size = sb.st_size;
		sym[len] = '\0';

		ret = xstrdup(sym);
		break;
	}
out:
	closedir(dirp);
	return ret;
}

/*
 * Return the inode number from a string
 */
static ino_t get_dev_inode(char *str, dev_t *dev)
{
	unsigned int maj = 0, min = 0;
	ino_t inum = 0;

	sscanf(str, "%02x:%02x:%ju", &maj, &min, &inum);

	*dev = (dev_t) makedev(maj, min);
	return inum;
}

static int get_local_locks(struct list_head *locks)
{
	int i;
	ino_t inode = 0;
	FILE *fp;
	char buf[PATH_MAX], *tok = NULL;
	size_t sz;
	struct lock *l;
	dev_t dev = 0;

	if (!(fp = fopen(_PATH_PROC_LOCKS, "r")))
		return -1;

	while (fgets(buf, sizeof(buf), fp)) {

		l = xcalloc(1, sizeof(*l));
		INIT_LIST_HEAD(&l->locks);

		for (tok = strtok(buf, " "), i = 0; tok;
		     tok = strtok(NULL, " "), i++) {

			/*
			 * /proc/locks has *exactly* 8 "blocks" of text
			 * separated by ' ' - check <kernel>/fs/locks.c
			 */
			switch (i) {
			case 0: /* ID: */
				tok[strlen(tok) - 1] = '\0';
				l->id = strtos32_or_err(tok, _("failed to parse ID"));
				break;
			case 1: /* posix, flock, etc */
				if (strcmp(tok, "->") == 0) {	/* optional field */
					l->blocked = 1;
					i--;
				} else
					l->type = xstrdup(tok);
				break;

			case 2: /* is this a mandatory lock? other values are advisory or noinode */
				l->mandatory = *tok == 'M' ? 1 : 0;
				break;
			case 3: /* lock mode */
				l->mode = xstrdup(tok);
				break;

			case 4: /* PID */
				/*
				 * If user passed a pid we filter it later when adding
				 * to the list, no need to worry now. OFD locks use -1 PID.
				 */
				l->pid = strtos32_or_err(tok, _("failed to parse pid"));
				if (l->pid > 0) {
					l->cmdname = proc_get_command_name(l->pid);
					if (!l->cmdname)
						l->cmdname = xstrdup(_("(unknown)"));
				} else
					l->cmdname = xstrdup(_("(undefined)"));
				break;

			case 5: /* device major:minor and inode number */
				inode = get_dev_inode(tok, &dev);
				break;

			case 6: /* start */
				l->start = !strcmp(tok, "EOF") ? 0 :
					   strtou64_or_err(tok, _("failed to parse start"));
				break;

			case 7: /* end */
				/* replace '\n' character */
				tok[strlen(tok)-1] = '\0';
				l->end = !strcmp(tok, "EOF") ? 0 :
					 strtou64_or_err(tok, _("failed to parse end"));
				break;
			default:
				break;
			}
		}

		l->path = get_filename_sz(inode, l->pid, &sz);

		/* no permissions -- ignore */
		if (!l->path && no_inaccessible) {
			rem_lock(l);
			continue;
		}

		if (!l->path) {
			/* probably no permission to peek into l->pid's path */
			l->path = get_fallback_filename(dev);
			l->size = 0;
		} else
			l->size = sz;

		list_add(&l->locks, locks);
	}

	fclose(fp);
	return 0;
}

static int column_name_to_id(const char *name, size_t namesz)
{
	size_t i;

	assert(name);

	for (i = 0; i < ARRAY_SIZE(infos); i++) {
		const char *cn = infos[i].name;

		if (!strncasecmp(name, cn, namesz) && !*(cn + namesz))
			return i;
	}
	warnx(_("unknown column: %s"), name);
	return -1;
}

static inline int get_column_id(int num)
{
	assert(num >= 0);
	assert((size_t) num < ncolumns);
	assert(columns[num] < (int) ARRAY_SIZE(infos));

	return columns[num];
}


static inline struct colinfo *get_column_info(unsigned num)
{
	return &infos[ get_column_id(num) ];
}

static pid_t get_blocker(int id, struct list_head *locks)
{
	struct list_head *p;

	list_for_each(p, locks) {
		struct lock *l = list_entry(p, struct lock, locks);

		if (l->id == id && !l->blocked)
			return l->pid;
	}

	return 0;
}

static void add_scols_line(struct libscols_table *table, struct lock *l, struct list_head *locks)
{
	size_t i;
	struct libscols_line *line;
	/*
	 * Whenever cmdname or filename is NULL it is most
	 * likely  because there's no read permissions
	 * for the specified process.
	 */
	const char *notfnd = "";

	assert(l);
	assert(table);

	line = scols_table_new_line(table, NULL);
	if (!line)
		err(EXIT_FAILURE, _("failed to allocate output line"));

	for (i = 0; i < ncolumns; i++) {
		char *str = NULL;

		switch (get_column_id(i)) {
		case COL_SRC:
			xasprintf(&str, "%s", l->cmdname ? l->cmdname : notfnd);
			break;
		case COL_PID:
			xasprintf(&str, "%d", l->pid);
			break;
		case COL_TYPE:
			xasprintf(&str, "%s", l->type);
			break;
		case COL_SIZE:
			if (!l->size)
				break;
			if (bytes)
				xasprintf(&str, "%ju", l->size);
			else
				str = size_to_human_string(SIZE_SUFFIX_1LETTER, l->size);
			break;
		case COL_MODE:
			xasprintf(&str, "%s%s", l->mode, l->blocked ? "*" : "");
			break;
		case COL_M:
			xasprintf(&str, "%d", l->mandatory ? 1 : 0);
			break;
		case COL_START:
			xasprintf(&str, "%jd", l->start);
			break;
		case COL_END:
			xasprintf(&str, "%jd", l->end);
			break;
		case COL_PATH:
			xasprintf(&str, "%s", l->path ? l->path : notfnd);
			break;
		case COL_BLOCKER:
		{
			pid_t bl = l->blocked && l->id ?
						get_blocker(l->id, locks) : 0;
			if (bl)
				xasprintf(&str, "%d", (int) bl);
		}
		default:
			break;
		}

		if (str && scols_line_refer_data(line, i, str))
			err(EXIT_FAILURE, _("failed to add output data"));
	}
}

static int show_locks(struct list_head *locks)
{
	int rc = 0;
	size_t i;
	struct list_head *p, *pnext;
	struct libscols_table *table;

	table = scols_new_table();
	if (!table)
		err(EXIT_FAILURE, _("failed to allocate output table"));

	scols_table_enable_raw(table, raw);
	scols_table_enable_json(table, json);
	scols_table_enable_noheadings(table, no_headings);

	if (json)
		scols_table_set_name(table, "locks");

	for (i = 0; i < ncolumns; i++) {
		struct libscols_column *cl;
		struct colinfo *col = get_column_info(i);

		cl = scols_table_new_column(table, col->name, col->whint, col->flags);
		if (!cl)
			err(EXIT_FAILURE, _("failed to allocate output column"));

		if (json) {
			int id = get_column_id(i);

			switch (id) {
			case COL_SIZE:
				if (!bytes)
					break;
				/* fallthrough */
			case COL_PID:
			case COL_START:
			case COL_END:
			case COL_BLOCKER:
				scols_column_set_json_type(cl, SCOLS_JSON_NUMBER);
				break;
			case COL_M:
				scols_column_set_json_type(cl, SCOLS_JSON_BOOLEAN);
				break;
			default:
				scols_column_set_json_type(cl, SCOLS_JSON_STRING);
				break;
			}
		}

	}

	/* prepare data for output */
	list_for_each(p, locks) {
		struct lock *l = list_entry(p, struct lock, locks);

		if (pid && pid != l->pid)
			continue;

		add_scols_line(table, l, locks);
	}

	/* destroy the list */
	list_for_each_safe(p, pnext, locks) {
		struct lock *l = list_entry(p, struct lock, locks);
		rem_lock(l);
	}

	scols_print_table(table);
	scols_unref_table(table);
	return rc;
}


static void __attribute__((__noreturn__)) usage(void)
{
	FILE *out = stdout;
	size_t i;

	fputs(USAGE_HEADER, out);

	fprintf(out,
		_(" %s [options]\n"), program_invocation_short_name);

	fputs(USAGE_SEPARATOR, out);
	fputs(_("List local system locks.\n"), out);

	fputs(USAGE_OPTIONS, out);
	fputs(_(" -b, --bytes            print SIZE in bytes rather than in human readable format\n"), out);
	fputs(_(" -J, --json             use JSON output format\n"), out);
	fputs(_(" -i, --noinaccessible   ignore locks without read permissions\n"), out);
	fputs(_(" -n, --noheadings       don't print headings\n"), out);
	fputs(_(" -o, --output <list>    define which output columns to use\n"), out);
	fputs(_("     --output-all       output all columns\n"), out);
	fputs(_(" -p, --pid <pid>        display only locks held by this process\n"), out);
	fputs(_(" -r, --raw              use the raw output format\n"), out);
	fputs(_(" -u, --notruncate       don't truncate text in columns\n"), out);

	fputs(USAGE_SEPARATOR, out);
	printf(USAGE_HELP_OPTIONS(24));

	fputs(USAGE_COLUMNS, out);

	for (i = 0; i < ARRAY_SIZE(infos); i++)
		fprintf(out, " %11s  %s\n", infos[i].name, _(infos[i].help));

	printf(USAGE_MAN_TAIL("lslocks(8)"));

	exit(EXIT_SUCCESS);
}

int main(int argc, char *argv[])
{
	int c, rc = 0;
	struct list_head locks;
	char *outarg = NULL;
	enum {
		OPT_OUTPUT_ALL = CHAR_MAX + 1
	};
	static const struct option long_opts[] = {
		{ "bytes",      no_argument,       NULL, 'b' },
		{ "json",       no_argument,       NULL, 'J' },
		{ "pid",	required_argument, NULL, 'p' },
		{ "help",	no_argument,       NULL, 'h' },
		{ "output",     required_argument, NULL, 'o' },
		{ "output-all",	no_argument,       NULL, OPT_OUTPUT_ALL },
		{ "notruncate", no_argument,       NULL, 'u' },
		{ "version",    no_argument,       NULL, 'V' },
		{ "noheadings", no_argument,       NULL, 'n' },
		{ "raw",        no_argument,       NULL, 'r' },
		{ "noinaccessible", no_argument, NULL, 'i' },
		{ NULL, 0, NULL, 0 }
	};

	static const ul_excl_t excl[] = {	/* rows and cols in ASCII order */
		{ 'J','r' },
		{ 0 }
	};
	int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;
	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	while ((c = getopt_long(argc, argv,
				"biJp:o:nruhV", long_opts, NULL)) != -1) {

		err_exclusive_options(c, long_opts, excl, excl_st);

		switch(c) {
		case 'b':
			bytes = 1;
			break;
		case 'i':
			no_inaccessible = 1;
			break;
		case 'J':
			json = 1;
			break;
		case 'p':
			pid = strtos32_or_err(optarg, _("invalid PID argument"));
			break;
		case 'o':
			outarg = optarg;
			break;
		case OPT_OUTPUT_ALL:
			for (ncolumns = 0; ncolumns < ARRAY_SIZE(infos); ncolumns++)
				columns[ncolumns] = ncolumns;
			break;
		case 'V':
			printf(UTIL_LINUX_VERSION);
			return EXIT_SUCCESS;
		case 'h':
			usage();
		case 'n':
			no_headings = 1;
			break;
		case 'r':
			raw = 1;
			break;
		case 'u':
			disable_columns_truncate();
			break;
		default:
			errtryhelp(EXIT_FAILURE);
		}
	}

	INIT_LIST_HEAD(&locks);

	if (!ncolumns) {
		/* default columns */
		columns[ncolumns++] = COL_SRC;
		columns[ncolumns++] = COL_PID;
		columns[ncolumns++] = COL_TYPE;
		columns[ncolumns++] = COL_SIZE;
		columns[ncolumns++] = COL_MODE;
		columns[ncolumns++] = COL_M;
		columns[ncolumns++] = COL_START;
		columns[ncolumns++] = COL_END;
		columns[ncolumns++] = COL_PATH;
	}

	if (outarg && string_add_to_idarray(outarg, columns, ARRAY_SIZE(columns),
					 &ncolumns, column_name_to_id) < 0)
		return EXIT_FAILURE;

	scols_init_debug(0);

	rc = get_local_locks(&locks);

	if (!rc && !list_empty(&locks))
		rc = show_locks(&locks);

	mnt_unref_table(tab);
	return rc;
}
