/* vi: set sw=4 ts=4: */
/*
 * Utility routines.
 *
 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
 *
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 */

#include "libbb.h"

/* #define DEBUGGING 1 */

#ifdef DEBUGGING
#define debug(...) do { printf(__VA_ARGS__); } while (0)
#else
#define debug(...) ((void)0)
#endif


/* Find block device /dev/XXX which contains specified file
 * We handle /dev/dir/dir/dir too, at a cost of ~80 more bytes code */

/* Do not reallocate all this stuff on each recursion */
enum { DEVNAME_MAX = 256 };
struct arena {
	struct stat st;
	dev_t dev;
	/* Was PATH_MAX, but we recurse _/dev_. We can assume
	 * people are not crazy enough to have mega-deep tree there */
	char devpath[DEVNAME_MAX];
};

static char *find_block_device_in_dir(struct arena *ap)
{
	DIR *dir;
	struct dirent *entry;
	char *retpath = NULL;
	int len, rem;

	len = strlen(ap->devpath);
	rem = DEVNAME_MAX-2 - len;
	if (rem <= 0)
		return NULL;

	dir = opendir(ap->devpath);
	if (!dir)
		return NULL;

	ap->devpath[len++] = '/';

	while ((entry = readdir(dir)) != NULL) {
		safe_strncpy(ap->devpath + len, entry->d_name, rem);
		/* lstat: do not follow links */
		if (lstat(ap->devpath, &ap->st) != 0)
			continue;
		if (S_ISBLK(ap->st.st_mode) && ap->st.st_rdev == ap->dev) {
			retpath = xstrdup(ap->devpath);
			break;
		}
		if (S_ISDIR(ap->st.st_mode)) {
			/* Do not recurse for '.' and '..' */
			if (DOT_OR_DOTDOT(entry->d_name))
				continue;
			retpath = find_block_device_in_dir(ap);
			if (retpath)
				break;
		}
	}
	closedir(dir);

	return retpath;
}

#define PROC_MOUNTINFO  "/proc/self/mountinfo"
/* A major of zero indicates a non-device mount. Use the kernel's show_mountinfo(),
 * exposed through /proc/self/mountinfo to lookup the device reference. */
static char *find_device_in_mountinfo(struct arena *ap)
{
	char line[1024];
	char *linePtr;
	char *retpath = NULL;

	FILE *fp = fopen_for_read(PROC_MOUNTINFO);
	if (!fp)
		return NULL;

	debug("Looking for device %u:%u\n", major(ap->dev), minor(ap->dev));
	while (fgets(line, sizeof(line), fp)) {
			int mnt_id, parent_mnt_id;
			unsigned int major, minor;
			char mnt_typename[1024], mnt_devname[1024];

			linePtr = line;
			if (sscanf(linePtr, "%i %i %u:%u", &mnt_id, &parent_mnt_id, &major, &minor) != 4) {
				debug("Couldn't parse line: '%s'\n", line);
			} else if ((linePtr = strstr(linePtr, " - ")) == NULL) {
				debug("Couldn't find ' - ': '%s'\n", line);
			} else if (sscanf(linePtr, " - %s %s ", mnt_typename, mnt_devname) != 2) {
				debug("Couldn't parse line: '%s'\n", line);
			} else if ((major(ap->dev) != major) || (minor(ap->dev) != minor)) {
				debug("Non-matching device %u:%u --> %s\n", major, minor, mnt_devname);
			} else {
				debug("Found a match %u:%u --> %s\n", major, minor, mnt_devname);
				retpath = xstrdup(mnt_devname);
				break;
			}
	}

	fclose(fp);

	return retpath;
}

char* FAST_FUNC find_block_device(const char *path)
{
	struct arena a;

	if (stat(path, &a.st) != 0)
		return NULL;
	a.dev = S_ISBLK(a.st.st_mode) ? a.st.st_rdev : a.st.st_dev;
	if (major(a.dev) != 0) {
		strcpy(a.devpath, "/dev");
		return find_block_device_in_dir(&a);
	} else {
		return find_device_in_mountinfo(&a);
	}
}
