/*
 * mount.c, by rmk
 */

#include <sys/mount.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <linux/loop.h>

#define ARRAY_SIZE(x)	(sizeof(x) / sizeof(x[0]))

#define DEFAULT_LOOP_DEVICE "/dev/block/loop0"
#define LOOPDEV_MAXLEN 64

struct mount_opts {
	const char str[16];
	unsigned long rwmask;
	unsigned long rwset;
	unsigned long rwnoset;
};

struct extra_opts {
	char *str;
	char *end;
	int used_size;
	int alloc_size;
};

/*
 * These options define the function of "mount(2)".
 */
#define MS_TYPE	(MS_REMOUNT|MS_BIND|MS_MOVE)


static const struct mount_opts options[] = {
	/* name		mask		set		noset		*/
	{ "async",	MS_SYNCHRONOUS,	0,		MS_SYNCHRONOUS	},
	{ "atime",	MS_NOATIME,	0,		MS_NOATIME	},
	{ "bind",	MS_TYPE,	MS_BIND,	0,		},
	{ "dev",	MS_NODEV,	0,		MS_NODEV	},
	{ "diratime",	MS_NODIRATIME,	0,		MS_NODIRATIME	},
	{ "dirsync",	MS_DIRSYNC,	MS_DIRSYNC,	0		},
	{ "exec",	MS_NOEXEC,	0,		MS_NOEXEC	},
	{ "move",	MS_TYPE,	MS_MOVE,	0		},
	{ "recurse",	MS_REC,		MS_REC,		0		},
	{ "rec",	MS_REC,		MS_REC,		0		},
	{ "remount",	MS_TYPE,	MS_REMOUNT,	0		},
	{ "ro",		MS_RDONLY,	MS_RDONLY,	0		},
	{ "rw",		MS_RDONLY,	0,		MS_RDONLY	},
	{ "suid",	MS_NOSUID,	0,		MS_NOSUID	},
	{ "sync",	MS_SYNCHRONOUS,	MS_SYNCHRONOUS,	0		},
	{ "verbose",	MS_VERBOSE,	MS_VERBOSE,	0		},
	{ "unbindable",	MS_UNBINDABLE,	MS_UNBINDABLE,	0		},
	{ "private",	MS_PRIVATE,	MS_PRIVATE,	0		},
	{ "slave",	MS_SLAVE,	MS_SLAVE,	0		},
	{ "shared",	MS_SHARED,	MS_SHARED,	0		},
};

static void add_extra_option(struct extra_opts *extra, char *s)
{
	int len = strlen(s);
	int newlen;

	if (extra->str)
	       len++;			/* +1 for ',' */
	newlen = extra->used_size + len;

	if (newlen >= extra->alloc_size) {
		char *new;

		new = realloc(extra->str, newlen + 1);	/* +1 for NUL */
		if (!new)
			return;

		extra->str = new;
		extra->end = extra->str + extra->used_size;
		extra->alloc_size = newlen + 1;
	}

	if (extra->used_size) {
		*extra->end = ',';
		extra->end++;
	}
	strcpy(extra->end, s);
	extra->used_size += len;

}

static unsigned long
parse_mount_options(char *arg, unsigned long rwflag, struct extra_opts *extra, int* loop, char *loopdev)
{
	char *s;
    
    *loop = 0;
	while ((s = strsep(&arg, ",")) != NULL) {
		char *opt = s;
		unsigned int i;
		int res, no = s[0] == 'n' && s[1] == 'o';

		if (no)
			s += 2;

        if (strncmp(s, "loop=", 5) == 0) {
            *loop = 1;
            strlcpy(loopdev, s + 5, LOOPDEV_MAXLEN);
            continue;
        }

        if (strcmp(s, "loop") == 0) {
            *loop = 1;
            strlcpy(loopdev, DEFAULT_LOOP_DEVICE, LOOPDEV_MAXLEN);
            continue;
        }
		for (i = 0, res = 1; i < ARRAY_SIZE(options); i++) {
			res = strcmp(s, options[i].str);

			if (res == 0) {
				rwflag &= ~options[i].rwmask;
				if (no)
					rwflag |= options[i].rwnoset;
				else
					rwflag |= options[i].rwset;
			}
			if (res <= 0)
				break;
		}

		if (res != 0 && s[0])
			add_extra_option(extra, opt);
	}

	return rwflag;
}

/*
 * Mark the given block device as read-write, using the BLKROSET ioctl.
 */
static void fs_set_blk_rw(const char *blockdev)
{
    int fd;
    int OFF = 0;

    fd = open(blockdev, O_RDONLY);
    if (fd < 0) {
        // should never happen
        return;
    }

    ioctl(fd, BLKROSET, &OFF);
    close(fd);
}

static char *progname;

static struct extra_opts extra;
static unsigned long rwflag;

static int
do_mount(char *dev, char *dir, char *type, unsigned long rwflag, void *data, int loop,
         char *loopdev)
{
	char *s;
	int error = 0;

    if (loop) {
        int file_fd, device_fd;
        int flags;

        flags = (rwflag & MS_RDONLY) ? O_RDONLY : O_RDWR;
        
        file_fd = open(dev, flags);
        if (file_fd < 0) {
            perror("open backing file failed");
            return 1;
        }
        device_fd = open(loopdev, flags);
        if (device_fd < 0) {
            perror("open loop device failed");
            close(file_fd);
            return 1;
        }
        if (ioctl(device_fd, LOOP_SET_FD, file_fd) < 0) {
            perror("ioctl LOOP_SET_FD failed");
            close(file_fd);
            close(device_fd);
            return 1;
        }

        close(file_fd);
        close(device_fd);
        dev = loopdev;
    }

    if ((rwflag & MS_RDONLY) == 0) {
        fs_set_blk_rw(dev);
    }

	while ((s = strsep(&type, ",")) != NULL) {
retry:
		if (mount(dev, dir, s, rwflag, data) == -1) {
			error = errno;
			/*
			 * If the filesystem is not found, or the
			 * superblock is invalid, try the next.
			 */
			if (error == ENODEV || error == EINVAL)
				continue;

			/*
			 * If we get EACCESS, and we're trying to
			 * mount readwrite and this isn't a remount,
			 * try read only.
			 */
			if (error == EACCES &&
			    (rwflag & (MS_REMOUNT|MS_RDONLY)) == 0) {
				rwflag |= MS_RDONLY;
				goto retry;
			}
			break;
		}
	}

	if (error) {
		errno = error;
		perror("mount");
		return 255;
	}

	return 0;
}

static int print_mounts()
{
    FILE* f;
    int length;
    char buffer[100];
    
    f = fopen("/proc/mounts", "r");
    if (!f) {
        fprintf(stdout, "could not open /proc/mounts\n");
        return -1;
    }

    do {
        length = fread(buffer, 1, 100, f);
        if (length > 0)
            fwrite(buffer, 1, length, stdout);
    } while (length > 0);

    fclose(f);
    return 0;
}

static int get_mounts_dev_dir(const char *arg, char **dev, char **dir)
{
	FILE *f;
	char mount_dev[256];
	char mount_dir[256];
	char mount_type[256];
	char mount_opts[256];
	int mount_freq;
	int mount_passno;
	int match;

	f = fopen("/proc/mounts", "r");
	if (!f) {
		fprintf(stdout, "could not open /proc/mounts\n");
		return -1;
	}

	do {
		match = fscanf(f, "%255s %255s %255s %255s %d %d\n",
					   mount_dev, mount_dir, mount_type,
					   mount_opts, &mount_freq, &mount_passno);
		mount_dev[255] = 0;
		mount_dir[255] = 0;
		mount_type[255] = 0;
		mount_opts[255] = 0;
		if (match == 6 &&
			(strcmp(arg, mount_dev) == 0 ||
			 strcmp(arg, mount_dir) == 0)) {
			*dev = strdup(mount_dev);
			*dir = strdup(mount_dir);
			fclose(f);
			return 0;
		}
	} while (match != EOF);

	fclose(f);
	return -1;
}

int mount_main(int argc, char *argv[])
{
	char *type = NULL;
	char *dev = NULL;
	char *dir = NULL;
	int c;
	int loop = 0;
	char loopdev[LOOPDEV_MAXLEN];

	progname = argv[0];
	rwflag = MS_VERBOSE;
	
	// mount with no arguments is equivalent to "cat /proc/mounts"
	if (argc == 1) return print_mounts();

	do {
		c = getopt(argc, argv, "o:rt:w");
		if (c == EOF)
			break;
		switch (c) {
		case 'o':
			rwflag = parse_mount_options(optarg, rwflag, &extra, &loop, loopdev);
			break;
		case 'r':
			rwflag |= MS_RDONLY;
			break;
		case 't':
			type = optarg;
			break;
		case 'w':
			rwflag &= ~MS_RDONLY;
			break;
		case '?':
			fprintf(stderr, "%s: invalid option -%c\n",
				progname, optopt);
			exit(1);
		}
	} while (1);

	/*
	 * If remount, bind or move was specified, then we don't
	 * have a "type" as such.  Use the dummy "none" type.
	 */
	if (rwflag & MS_TYPE)
		type = "none";

	if (optind + 2 == argc) {
		dev = argv[optind];
		dir = argv[optind + 1];
	} else if (optind + 1 == argc && rwflag & MS_REMOUNT) {
		get_mounts_dev_dir(argv[optind], &dev, &dir);
	}

	if (dev == NULL || dir == NULL || type == NULL) {
		fprintf(stderr, "Usage: %s [-r] [-w] [-o options] [-t type] "
			"device directory\n", progname);
		exit(1);
	}

	return do_mount(dev, dir, type, rwflag, extra.str, loop, loopdev);
	/* We leak dev and dir in some cases, but we're about to exit */
}
