/*
 * Mini mount implementation for busybox
 *
 * Copyright (C) 1999 by Erik Andersen <andersee@debian.org>
 *
 * 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 will 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
 *
 * 3/21/1999	Charles P. Wright <cpwright@cpwright.com>
 *		searches through fstab when -a is passed
 *		will try mounting stuff with all fses when passed -t auto
 *
 * 1999-04-17	Dave Cinege...Rewrote -t auto. Fixed ro mtab.
 * 1999-10-07	Erik Andersen.  Rewrote of a lot of code. Removed mtab 
 *              usage, major adjustments, and some serious dieting all around.
*/

#include "internal.h"
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <mntent.h>
#include <sys/mount.h>
#include <ctype.h>
#include <fstab.h>

const char mount_usage[] = "Usage:\tmount [flags]\n"
    "\tmount [flags] device directory [-o options,more-options]\n"
    "\n"
    "Flags:\n"
    "\t-a:\tMount all file systems in fstab.\n"
    "\t-o option:\tOne of many filesystem options, listed below.\n"
    "\t-r:\tMount the filesystem read-only.\n"
    "\t-t filesystem-type:\tSpecify the filesystem type.\n"
    "\t-w:\tMount for reading and writing (default).\n"
    "\n"
    "Options for use with the \"-o\" flag:\n"
    "\tasync / sync:\tWrites are asynchronous / synchronous.\n"
    "\tdev / nodev:\tAllow use of special device files / disallow them.\n"
    "\texec / noexec:\tAllow use of executable files / disallow them.\n"
    "\tsuid / nosuid:\tAllow set-user-id-root programs / disallow them.\n"
    "\tremount: Re-mount a currently-mounted filesystem, changing its flags.\n"
    "\tro / rw: Mount for read-only / read-write.\n"
    "\t"
    "There are EVEN MORE flags that are specific to each filesystem.\n"
    "You'll have to see the written documentation for those.\n";

struct mount_options {
    const char *name;
    unsigned long and;
    unsigned long or;
};

static const struct mount_options mount_options[] = {
    {"async", ~MS_SYNCHRONOUS, 0},
    {"defaults", ~0, 0},
    {"dev", ~MS_NODEV, 0},
    {"exec", ~MS_NOEXEC, 0},
    {"nodev", ~0, MS_NODEV},
    {"noexec", ~0, MS_NOEXEC},
    {"nosuid", ~0, MS_NOSUID},
    {"remount", ~0, MS_REMOUNT},
    {"ro", ~0, MS_RDONLY},
    {"rw", ~MS_RDONLY, 0},
    {"suid", ~MS_NOSUID, 0},
    {"sync", ~0, MS_SYNCHRONOUS},
    {0, 0, 0}
};


/* Seperate standard mount options from the nonstandard string options */
static void
parse_mount_options ( char *options, unsigned long *flags, char *strflags)
{
    while (options) {
	int gotone=FALSE;
	char *comma = strchr (options, ',');
	const struct mount_options* f = mount_options;
	if (comma)
	    *comma = '\0';

	while (f->name != 0) {
	    if (strcasecmp (f->name, options) == 0) {
		*flags &= f->and;
		*flags |= f->or;
		gotone=TRUE;
		break;
	    }
	    f++;
	}
	if (*strflags && strflags!= '\0' && gotone==FALSE) {
	    char *temp=strflags;
	    temp += strlen (strflags);
	    *temp++ = ',';
	    *temp++ = '\0';
	}
	if (gotone==FALSE) {
	    strcat (strflags, options);
	    gotone=FALSE;
	}
	if (comma) {
	    *comma = ',';
	    options = ++comma;
	} else {
	    break;
	}
    }
}

int
mount_one (
	   char *blockDevice, char *directory, char *filesystemType,
	   unsigned long flags, char *string_flags)
{
    int status = 0;

    char buf[255];

    if (strcmp(filesystemType, "auto") == 0) {
	FILE *f = fopen ("/proc/filesystems", "r");

	if (f == NULL)
	    return( FALSE);

	while (fgets (buf, sizeof (buf), f) != NULL) {
	    filesystemType = buf;
	    if (*filesystemType == '\t') {	// Not a nodev filesystem

		// Add NULL termination to each line
		while (*filesystemType && *filesystemType != '\n')
		    filesystemType++;
		*filesystemType = '\0';

		filesystemType = buf;
		filesystemType++;	// hop past tab

		status = mount (blockDevice, directory, filesystemType,
				flags | MS_MGC_VAL, string_flags);
		if (status == 0)
		    break;
	    }
	}
	fclose (f);
    } else {
	status = mount (blockDevice, directory, filesystemType,
			flags | MS_MGC_VAL, string_flags);
    }

    if (status) {
	fprintf (stderr, "Mounting %s on %s failed: %s\n",
		 blockDevice, directory, strerror(errno));
	return (FALSE);
    }
    return (TRUE);
}

extern int mount_main (int argc, char **argv)
{
    char string_flags[1024]="";
    unsigned long flags = 0;
    char *filesystemType = "auto";
    char *device = NULL;
    char *directory = NULL;
    struct stat statBuf;
    int all = 0;
    int i;

    if (stat("/etc/fstab", &statBuf) < 0) 
	fprintf(stderr, "/etc/fstab file missing -- Please install one.\n\n");

    if (argc == 1) {
	FILE *mountTable;
	if ((mountTable = setmntent ("/proc/mounts", "r"))) {
	    struct mntent *m;
	    while ((m = getmntent (mountTable)) != 0) {
		struct fstab* fstabItem;
		char *blockDevice = m->mnt_fsname;
		/* Note that if /etc/fstab is missing, libc can't fix up /dev/root for us */
		if (strcmp (blockDevice, "/dev/root") == 0) {
		    fstabItem = getfsfile ("/");
		    if (fstabItem != NULL)
			blockDevice = fstabItem->fs_spec;
		}
		printf ("%s on %s type %s (%s)\n", blockDevice, m->mnt_dir,
			m->mnt_type, m->mnt_opts);
	    }
	    endmntent (mountTable);
	}
	exit( TRUE);
    }


    /* Parse options */
    i = --argc;
    argv++;
    while (i > 0 && **argv) {
	if (**argv == '-') {
	    while (i>0 && *++(*argv)) switch (**argv) {
	    case 'o':
		if (--i == 0) {
		    fprintf (stderr, "%s\n", mount_usage);
		    exit( FALSE);
		}
		parse_mount_options (*(++argv), &flags, string_flags);
		--i;
		++argv;
		break;
	    case 'r':
		flags |= MS_RDONLY;
		break;
	    case 't':
		if (--i == 0) {
		    fprintf (stderr, "%s\n", mount_usage);
		    exit( FALSE);
		}
		filesystemType = *(++argv);
		--i;
		++argv;
		break;
	    case 'w':
		flags &= ~MS_RDONLY;
		break;
	    case 'a':
		all = 1;
		break;
	    case 'v':
	    case 'h':
	    case '-':
		fprintf (stderr, "%s\n", mount_usage);
		exit( TRUE);
		break;
	    }
	} else {
	    if (device == NULL)
		device=*argv;
	    else if (directory == NULL)
		directory=*argv;
	    else {
		fprintf (stderr, "%s\n", mount_usage);
		exit( TRUE);
	    }
	}
	i--;
	argv++;
    }

    if (all == 1) {
	struct mntent *m;
	FILE *f = setmntent ("/etc/fstab", "r");

	if (f == NULL) {
	    perror("/etc/fstab");
	    exit( FALSE); 
	}
	while ((m = getmntent (f)) != NULL) {
	    // If the file system isn't noauto, and isn't mounted on /, mount 
	    // it
	    if ((!strstr (m->mnt_opts, "noauto"))
		&& (m->mnt_dir[1] != '\0') && !((m->mnt_type[0] == 's')
						&& (m->mnt_type[1] == 'w'))
		&& !((m->mnt_type[0] == 'n') && (m->mnt_type[1] == 'f'))) {
		mount_one (m->mnt_fsname, m->mnt_dir, m->mnt_type, flags,
			   m->mnt_opts);
	    }
	}
	endmntent (f);
    } else {
	if (device && directory) {
	    exit (mount_one (device, directory, filesystemType, 
			flags, string_flags));
	} else {
	    fprintf (stderr, "%s\n", mount_usage);
	    exit( FALSE);
	}
    }
    exit( TRUE);
}
