/* 1999-02-22 Arkadiusz Miskiewicz <misiek@pld.ORG.PL>
 * - added Native Language Support
 * Sun Mar 21 1999 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
 * - fixed strerr(errno) in gettext calls
 *
 * 2006-06-08 Amit Gud <agud@redhat.com>
 * - Moved code to nfs-utils/support/nfs from util-linux/mount.
 */

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

#include "fstab.h"
#include "xcommon.h"
#include "nfs_mntent.h"
#include "nfs_paths.h"
#include "nls.h"

#define LOCK_TIMEOUT	10
#define streq(s, t)	(strcmp ((s), (t)) == 0)
#define PROC_MOUNTS		"/proc/mounts"

extern char *progname;
extern int verbose;

/* Information about mtab. ------------------------------------*/
static int have_mtab_info = 0;
static int var_mtab_does_not_exist = 0;
static int var_mtab_is_a_symlink = 0;

static void
get_mtab_info(void) {
	struct stat mtab_stat;

	if (!have_mtab_info) {
		if (lstat(MOUNTED, &mtab_stat))
			var_mtab_does_not_exist = 1;
		else if (S_ISLNK(mtab_stat.st_mode))
			var_mtab_is_a_symlink = 1;
		have_mtab_info = 1;
	}
}

void
reset_mtab_info(void) {
        have_mtab_info = 0;
}

int
mtab_does_not_exist(void) {
	get_mtab_info();
	return var_mtab_does_not_exist;
}

static int
mtab_is_a_symlink(void) {
        get_mtab_info();
        return var_mtab_is_a_symlink;
}

int
mtab_is_writable() {
	int fd;

	/* Should we write to /etc/mtab upon an update?
	   Probably not if it is a symlink to /proc/mounts, since that
	   would create a file /proc/mounts in case the proc filesystem
	   is not mounted. */
	if (mtab_is_a_symlink())
		return 0;

	fd = open(MOUNTED, O_RDWR | O_CREAT, 0644);
	if (fd >= 0) {
		close(fd);
		return 1;
	} else
		return 0;
}

/* Contents of mtab and fstab ---------------------------------*/

struct mntentchn mounttable;
static int got_mtab = 0;
struct mntentchn procmounts;
static int got_procmounts = 0;
struct mntentchn fstab;
static int got_fstab = 0;

static void read_mounttable(void);
static void read_procmounts(void);
static void read_fstab(void);

static struct mntentchn *
mtab_head(void)
{
	if (!got_mtab)
		read_mounttable();
	return &mounttable;
}

static struct mntentchn *
procmounts_head(void)
{
	if (!got_procmounts)
		read_procmounts();
	return &procmounts;
}

static struct mntentchn *
fstab_head(void)
{
	if (!got_fstab)
		read_fstab();
	return &fstab;
}

#if 0
static void
my_free(const void *s) {
	if (s)
		free((void *) s);
}

static void
discard_mntentchn(struct mntentchn *mc0) {
	struct mntentchn *mc, *mc1;

	for (mc = mc0->nxt; mc && mc != mc0; mc = mc1) {
		mc1 = mc->nxt;
		my_free(mc->m.mnt_fsname);
		my_free(mc->m.mnt_dir);
		my_free(mc->m.mnt_type);
		my_free(mc->m.mnt_opts);
		free(mc);
	}
}
#endif

static void
read_mntentchn(mntFILE *mfp, const char *fnam, struct mntentchn *mc0) {
	struct mntentchn *mc = mc0;
	struct mntent *mnt;

	while ((mnt = nfs_getmntent(mfp)) != NULL) {
		if (!streq(mnt->mnt_type, MNTTYPE_IGNORE)) {
			mc->nxt = (struct mntentchn *) xmalloc(sizeof(*mc));
			mc->nxt->prev = mc;
			mc = mc->nxt;
			mc->m = *mnt;
			mc->nxt = mc0;
		}
	}
	mc0->prev = mc;
	if (ferror(mfp->mntent_fp)) {
		int errsv = errno;
		nfs_error(_("warning: error reading %s: %s"),
		      fnam, strerror (errsv));
		mc0->nxt = mc0->prev = NULL;
	}
	nfs_endmntent(mfp);
}

/*
 * Read /etc/mtab.  If that fails, try /proc/mounts.
 * This produces a linked list. The list head mounttable is a dummy.
 * Return 0 on success.
 */
static void
read_mounttable() {
        mntFILE *mfp;
        const char *fnam;
        struct mntentchn *mc = &mounttable;

        got_mtab = 1;
        mc->nxt = mc->prev = NULL;

        fnam = MOUNTED;
        mfp = nfs_setmntent (fnam, "r");
        if (mfp == NULL || mfp->mntent_fp == NULL) {
                int errsv = errno;
                fnam = PROC_MOUNTS;
                mfp = nfs_setmntent (fnam, "r");
                if (mfp == NULL || mfp->mntent_fp == NULL) {
                        nfs_error(_("warning: can't open %s: %s"),
                              MOUNTED, strerror (errsv));
                        return;
                }
                if (verbose)
                        printf(_("%s: could not open %s; using %s instead\n"),
				progname, MOUNTED, PROC_MOUNTS);
        }
        read_mntentchn(mfp, fnam, mc);
}

/*
 * Read /proc/mounts.
 * This produces a linked list. The list head procmounts is a dummy.
 * Return 0 on success.
 */
static void
read_procmounts() {
        mntFILE *mfp;
        const char *fnam;
        struct mntentchn *mc = &procmounts;

        got_procmounts = 1;
        mc->nxt = mc->prev = NULL;

        fnam = PROC_MOUNTS;
        mfp = nfs_setmntent(fnam, "r");
        if (mfp == NULL || mfp->mntent_fp == NULL) {
                nfs_error(_("warning: can't open %s: %s"),
                          PROC_MOUNTS, strerror (errno));
                return;
        }
        read_mntentchn(mfp, fnam, mc);
}

static void
read_fstab()
{
	mntFILE *mfp = NULL;
	const char *fnam;
	struct mntentchn *mc = &fstab;

	got_fstab = 1;
	mc->nxt = mc->prev = NULL;

	fnam = _PATH_FSTAB;
	mfp = nfs_setmntent (fnam, "r");
	if (mfp == NULL || mfp->mntent_fp == NULL) {
		int errsv = errno;
		nfs_error(_("warning: can't open %s: %s"),
			  _PATH_FSTAB, strerror (errsv));
		return;
	}
	read_mntentchn(mfp, fnam, mc);
}

/*
 * Given the directory name NAME, and the place MCPREV we found it last time,
 * try to find more occurrences.
 */ 
struct mntentchn *
getmntdirbackward (const char *name, struct mntentchn *mcprev) {
	struct mntentchn *mc, *mc0;

	mc0 = mtab_head();
	if (!mcprev)
		mcprev = mc0;
	for (mc = mcprev->prev; mc && mc != mc0; mc = mc->prev)
		if (streq(mc->m.mnt_dir, name))
			return mc;
	return NULL;
}

/*
 * Given the directory name NAME, and the place MCPREV we found it last time,
 * try to find more occurrences.
 */
struct mntentchn *
getprocmntdirbackward (const char *name, struct mntentchn *mcprev) {
	struct mntentchn *mc, *mc0;

	mc0 = procmounts_head();
	if (!mcprev)
		mcprev = mc0;
	for (mc = mcprev->prev; mc && mc != mc0; mc = mc->prev)
		if (streq(mc->m.mnt_dir, name))
			return mc;
	return NULL;
}

/*
 * Given the device name NAME, and the place MCPREV we found it last time,
 * try to find more occurrences.
 */ 
struct mntentchn *
getmntdevbackward (const char *name, struct mntentchn *mcprev) {
	struct mntentchn *mc, *mc0;

	mc0 = mtab_head();
	if (!mcprev)
		mcprev = mc0;
	for (mc = mcprev->prev; mc && mc != mc0; mc = mc->prev)
		if (streq(mc->m.mnt_fsname, name))
			return mc;
	return NULL;
}

/* Find the dir FILE in fstab.  */
struct mntentchn *
getfsfile (const char *file)
{
	struct mntentchn *mc, *mc0;

	mc0 = fstab_head();
	for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
		if (streq(mc->m.mnt_dir, file))
			return mc;
	return NULL;
}

/* Find the device SPEC in fstab.  */
struct mntentchn *
getfsspec (const char *spec)
{
	struct mntentchn *mc, *mc0;

	mc0 = fstab_head();
	for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
		if (streq(mc->m.mnt_fsname, spec))
			return mc;
	return NULL;
}

/* Updating mtab ----------------------------------------------*/

/* Flag for already existing lock file. */
static int we_created_lockfile = 0;
static int lockfile_fd = -1;

/* Flag to indicate that signals have been set up. */
static int signals_have_been_setup = 0;

/* Ensure that the lock is released if we are interrupted.  */
extern char *strsignal(int sig);	/* not always in <string.h> */

static void
handler (int sig) {
     die(EX_USER, "%s", strsignal(sig));
}

static void
setlkw_timeout (__attribute__((unused)) int sig) {
     /* nothing, fcntl will fail anyway */
}

/* Remove lock file.  */
void
unlock_mtab (void) {
	if (we_created_lockfile) {
		close(lockfile_fd);
		lockfile_fd = -1;
		unlink (MOUNTED_LOCK);
		we_created_lockfile = 0;
	}
}

/* Create the lock file.
   The lock file will be removed if we catch a signal or when we exit. */
/* The old code here used flock on a lock file /etc/mtab~ and deleted
   this lock file afterwards. However, as rgooch remarks, that has a
   race: a second mount may be waiting on the lock and proceed as
   soon as the lock file is deleted by the first mount, and immediately
   afterwards a third mount comes, creates a new /etc/mtab~, applies
   flock to that, and also proceeds, so that the second and third mount
   now both are scribbling in /etc/mtab.
   The new code uses a link() instead of a creat(), where we proceed
   only if it was us that created the lock, and hence we always have
   to delete the lock afterwards. Now the use of flock() is in principle
   superfluous, but avoids an arbitrary sleep(). */

/* Where does the link point to? Obvious choices are mtab and mtab~~.
   HJLu points out that the latter leads to races. Right now we use
   mtab~.<pid> instead. Use 20 as upper bound for the length of %d. */
#define MOUNTLOCK_LINKTARGET		MOUNTED_LOCK "%d"
#define MOUNTLOCK_LINKTARGET_LTH	(sizeof(MOUNTED_LOCK)+20)

void
lock_mtab (void) {
	int tries = 100000, i;
	char linktargetfile[MOUNTLOCK_LINKTARGET_LTH];

	at_die = unlock_mtab;

	if (!signals_have_been_setup) {
		int sig = 0;
		struct sigaction sa;

		sa.sa_flags = 0;
		sigfillset (&sa.sa_mask);
  
		while (sigismember (&sa.sa_mask, ++sig) != -1) {
			switch(sig) {
			case SIGCHLD:
			case SIGKILL:
			case SIGCONT:
			case SIGSTOP:
				/* The cannot be caught, or should not,
				 * so don't even try.
				 */
				continue;
			case SIGALRM:
				sa.sa_handler = setlkw_timeout;
				break;
			case SIGHUP:
			case SIGINT:
			case SIGQUIT:
			case SIGWINCH:
			case SIGTSTP:
			case SIGTTIN:
			case SIGTTOU:
			case SIGPIPE:
			case SIGXFSZ:
			case SIGXCPU:
				/* non-priv user can cause these to be
				 * generated, so ignore them.
				 */
				sa.sa_handler = SIG_IGN;
				break;
			default:
				/* The rest should not be possible, so just
				 * print a message and unlock mtab.
				 */
				sa.sa_handler = handler;
			}
			sigaction (sig, &sa, (struct sigaction *) 0);
		}
		signals_have_been_setup = 1;
	}

	sprintf(linktargetfile, MOUNTLOCK_LINKTARGET, getpid ());

	i = open (linktargetfile, O_WRONLY|O_CREAT, 0);
	if (i < 0) {
		int errsv = errno;
		/* linktargetfile does not exist (as a file)
		   and we cannot create it. Read-only filesystem?
		   Too many files open in the system?
		   Filesystem full? */
		die (EX_FILEIO, _("can't create lock file %s: %s "
						  "(use -n flag to override)"),
			 linktargetfile, strerror (errsv));
	}
	close(i);
	
	/* Repeat until it was us who made the link */
	while (!we_created_lockfile) {
		struct flock flock;
		int j;

		j = link(linktargetfile, MOUNTED_LOCK);

		{
			int errsv = errno;

			if (j == 0)
				we_created_lockfile = 1;

			if (j < 0 && errsv != EEXIST) {
				(void) unlink(linktargetfile);
				die (EX_FILEIO, _("can't link lock file %s: %s "
				     "(use -n flag to override)"),
				     MOUNTED_LOCK, strerror (errsv));
			}
		}

		lockfile_fd = open (MOUNTED_LOCK, O_WRONLY);

		if (lockfile_fd < 0) {
			int errsv = errno;
			/* Strange... Maybe the file was just deleted? */
			if (errno == ENOENT && tries-- > 0) {
				if (tries % 200 == 0)
					usleep(30);
				continue;
			}
			(void) unlink(linktargetfile);
			die (EX_FILEIO, _("can't open lock file %s: %s "
			     "(use -n flag to override)"),
			     MOUNTED_LOCK, strerror (errsv));
		}

		flock.l_type = F_WRLCK;
		flock.l_whence = SEEK_SET;
		flock.l_start = 0;
		flock.l_len = 0;

		if (j == 0) {
			/* We made the link. Now claim the lock. */
			if (fcntl (lockfile_fd, F_SETLK, &flock) == -1) {
				if (verbose) {
				    int errsv = errno;
				    nfs_error(_("%s: Can't lock lock file "
						"%s: %s"), progname,
					   	MOUNTED_LOCK,
						strerror (errsv));
				}
				/* proceed anyway */
			}
			(void) unlink(linktargetfile);
		} else {
			static int retries = 0;

			/* Someone else made the link. Wait. */
			alarm(LOCK_TIMEOUT);
			if (fcntl (lockfile_fd, F_SETLKW, &flock) == -1) {
				int errsv = errno;
				(void) unlink(linktargetfile);
				die (EX_FILEIO, _("can't lock lock file %s: %s"),
				     MOUNTED_LOCK, (errno == EINTR) ?
				     _("timed out") : strerror (errsv));
			}
			alarm(0);
			/* Limit the number of iterations - maybe there
			   still is some old /etc/mtab~ */
			++retries;
			if (retries % 200 == 0)
			   usleep(30);
			if (retries > 100000) {
				(void) unlink(linktargetfile);
				close(lockfile_fd);
				die (EX_FILEIO, _("Cannot create link %s\n"
						  "Perhaps there is a stale lock file?\n"),
					 MOUNTED_LOCK);
 			}
			close(lockfile_fd);
		}
	}
}

/*
 * Update the mtab.
 *  Used by umount with null INSTEAD: remove the last DIR entry.
 *  Used by mount upon a remount: update option part,
 *   and complain if a wrong device or type was given.
 *   [Note that often a remount will be a rw remount of /
 *    where there was no entry before, and we'll have to believe
 *    the values given in INSTEAD.]
 */

void
update_mtab (const char *dir, struct mntent *instead)
{
	mntFILE *mfp, *mftmp;
	const char *fnam = MOUNTED;
	struct mntentchn mtabhead;	/* dummy */
	struct mntentchn *mc, *mc0, *absent = NULL;

	if (mtab_does_not_exist() || !mtab_is_writable())
		return;

	lock_mtab();

	/* having locked mtab, read it again */
	mc0 = mc = &mtabhead;
	mc->nxt = mc->prev = NULL;

	mfp = nfs_setmntent(fnam, "r");
	if (mfp == NULL || mfp->mntent_fp == NULL) {
		int errsv = errno;
		nfs_error (_("cannot open %s (%s) - mtab not updated"),
		       fnam, strerror (errsv));
		goto leave;
	}

	read_mntentchn(mfp, fnam, mc);

	/* find last occurrence of dir */
	for (mc = mc0->prev; mc && mc != mc0; mc = mc->prev)
		if (streq(mc->m.mnt_dir, dir))
			break;
	if (mc && mc != mc0) {
		if (instead == NULL) {
			/* An umount - remove entry */
			if (mc && mc != mc0) {
				mc->prev->nxt = mc->nxt;
				mc->nxt->prev = mc->prev;
				free(mc);
			}
		} else {
			/* A remount */
			mc->m.mnt_opts = instead->mnt_opts;
		}
	} else if (instead) {
		/* not found, add a new entry */
		absent = xmalloc(sizeof(*absent));
		absent->m = *instead;
		absent->nxt = mc0;
		absent->prev = mc0->prev;
		mc0->prev = absent;
		if (mc0->nxt == NULL)
			mc0->nxt = absent;
	}

	/* write chain to mtemp */
	mftmp = nfs_setmntent (MOUNTED_TEMP, "w");
	if (mftmp == NULL || mftmp->mntent_fp == NULL) {
		int errsv = errno;
		nfs_error (_("cannot open %s (%s) - mtab not updated"),
		       MOUNTED_TEMP, strerror (errsv));
		goto leave;
	}

	for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt) {
		if (nfs_addmntent(mftmp, &(mc->m)) == 1) {
			int errsv = errno;
			die (EX_FILEIO, _("error writing %s: %s"),
			     MOUNTED_TEMP, strerror (errsv));
		}
	}

#if 0
	/* the chain might have strings copied from 'instead',
	 * so we cannot safely free it.
	 * And there is no need anyway because we are going to exit
	 * shortly.  So just don't call discard_mntentchn....
	 */
	discard_mntentchn(mc0);
#endif
	if (fchmod (fileno (mftmp->mntent_fp),
		    S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
		int errsv = errno;
		nfs_error(_("%s: error changing mode of %s: %s"),
				progname, MOUNTED_TEMP, strerror (errsv));
	}
	nfs_endmntent (mftmp);

	{ /*
	   * If mount is setuid and some non-root user mounts sth,
	   * then mtab.tmp might get the group of this user. Copy uid/gid
	   * from the present mtab before renaming.
	   */
	    struct stat sbuf;
	    if (stat (MOUNTED, &sbuf) == 0) {
			if (chown (MOUNTED_TEMP, sbuf.st_uid, sbuf.st_gid) < 0) {
				nfs_error(_("%s: error changing owner of %s: %s"),
					progname, MOUNTED_TEMP, strerror (errno));
			}
		}
	}

	/* rename mtemp to mtab */
	if (rename (MOUNTED_TEMP, MOUNTED) < 0) {
		int errsv = errno;
		nfs_error(_("%s: can't rename %s to %s: %s\n"),
				progname, MOUNTED_TEMP, MOUNTED,
				strerror(errsv));
	}

 leave:
	unlock_mtab();
}
