/*
 * support/export/xtab.c
 *
 * Interface to the xtab file.
 *
 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <sys/fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "xmalloc.h"
#include "nfslib.h"
#include "exportfs.h"
#include "xio.h"
#include "xlog.h"
#include "v4root.h"

int v4root_needed;
static void cond_rename(char *newfile, char *oldfile);

static int
xtab_read(char *xtab, char *lockfn, int is_export)
{
    /* is_export == 0  => reading /proc/fs/nfs/exports - we know these things are exported to kernel
     * is_export == 1  => reading /var/lib/nfs/etab - these things are allowed to be exported
     * is_export == 2  => reading /var/lib/nfs/xtab - these things might be known to kernel
     */
	struct exportent	*xp;
	nfs_export		*exp;
	int			lockid;

	if ((lockid = xflock(lockfn, "r")) < 0)
		return 0;
	setexportent(xtab, "r");
	if (is_export == 1)
		v4root_needed = 1;
	while ((xp = getexportent(is_export==0, 0)) != NULL) {
		if (!(exp = export_lookup(xp->e_hostname, xp->e_path, is_export != 1)) &&
		    !(exp = export_create(xp, is_export!=1))) {
			continue;
		}
		switch (is_export) {
		case 0:
			exp->m_exported = 1;
			break;
		case 1:
			exp->m_xtabent = 1;
			exp->m_mayexport = 1;
			if ((xp->e_flags & NFSEXP_FSID) && xp->e_fsid == 0)
				v4root_needed = 0;
			break;
		case 2:
			exp->m_exported = -1;/* may be exported */
			break;
		}
	}
	endexportent();
	xfunlock(lockid);

	return 0;
}

int
xtab_mount_read(void)
{
	int fd;
	if ((fd=open(_PATH_PROC_EXPORTS, O_RDONLY))>=0) {
		close(fd);
		return xtab_read(_PATH_PROC_EXPORTS,
				 _PATH_PROC_EXPORTS, 0);
	} else if ((fd=open(_PATH_PROC_EXPORTS_ALT, O_RDONLY) >= 0)) {
		close(fd);
		return xtab_read(_PATH_PROC_EXPORTS_ALT,
				 _PATH_PROC_EXPORTS_ALT, 0);
	} else
		return xtab_read(_PATH_XTAB, _PATH_XTABLCK, 2);
}

int
xtab_export_read(void)
{
	return xtab_read(_PATH_ETAB, _PATH_ETABLCK, 1);
}

/*
 * mountd now keeps an open fd for the etab at all times to make sure that the
 * inode number changes when the xtab_export_write is done. If you change the
 * routine below such that the files are edited in place, then you'll need to
 * fix the auth_reload logic as well...
 */
static int
xtab_write(char *xtab, char *xtabtmp, char *lockfn, int is_export)
{
	struct exportent	xe;
	nfs_export		*exp;
	int			lockid, i;

	if ((lockid = xflock(lockfn, "w")) < 0) {
		xlog(L_ERROR, "can't lock %s for writing", xtab);
		return 0;
	}
	setexportent(xtabtmp, "w");

	for (i = 0; i < MCL_MAXTYPES; i++) {
		for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
			if (is_export && !exp->m_xtabent)
				continue;
			if (!is_export && ! exp->m_exported)
				continue;

			/* write out the export entry using the FQDN */
			xe = exp->m_export;
			xe.e_hostname = exp->m_client->m_hostname;
			putexportent(&xe);
		}
	}
	endexportent();

	cond_rename(xtabtmp, xtab);

	xfunlock(lockid);

	return 1;
}

int
xtab_export_write()
{
	return xtab_write(_PATH_ETAB, _PATH_ETABTMP, _PATH_ETABLCK, 1);
}

int
xtab_mount_write()
{
	return xtab_write(_PATH_XTAB, _PATH_XTABTMP, _PATH_XTABLCK, 0);
}

void
xtab_append(nfs_export *exp)
{
	struct exportent xe;
	int		lockid;

	if ((lockid = xflock(_PATH_XTABLCK, "w")) < 0)
		return;
	setexportent(_PATH_XTAB, "a");
	xe = exp->m_export;
	xe.e_hostname = exp->m_client->m_hostname;
	putexportent(&xe);
	endexportent();
	xfunlock(lockid);
	exp->m_xtabent = 1;
}

/*
 * rename newfile onto oldfile unless
 * they are identical
 */
static void cond_rename(char *newfile, char *oldfile)
{
	int nfd, ofd;
	char nbuf[4096], obuf[4096];
	int ncnt, ocnt;

	nfd = open(newfile, 0);
	if (nfd < 0)
		return;
	ofd = open(oldfile, 0);
	if (ofd < 0) {
		close(nfd);
		rename(newfile, oldfile);
		return;
	}

	do {
		ncnt = read(nfd, nbuf, sizeof(nbuf));
		if (ncnt < 0)
			break;
		ocnt = read(ofd, obuf, sizeof(obuf));
		if (ocnt < 0)
			break;
		if (ncnt != ocnt)
			break;
		if (ncnt == 0) {
			close(nfd);
			close(ofd);
			unlink(newfile);
			return;
		}
	} while (memcmp(obuf, nbuf, ncnt) == 0);

	/* some mis-match */
	close(nfd);
	close(ofd);
	rename(newfile, oldfile);
	return;
}
