/*
 * $Header: /usr/local/devel/postgres/src/bin/unfsmntd/RCS/unfsmntd.c,v 1.4 1993/06/24 03:51:45 aoki Exp $
 */

/* UNFSD - copyright Mark A Shand, May 1988.
 * This software maybe be used for any purpose provided
 * the above copyright notice is retained.  It is supplied
 * as is, with no warranty expressed or implied.
 */

#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <rpc/rpc.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#undef TRUE
#undef FALSE
#include "mount.h"
#include "tmp/libpq.h"
#include "tmp/libpq-fs.h"

extern char *PQhost;
extern char *PQport;

static struct timeval TIMEOUT = { 25, 0 };

#ifdef DEBUG
#include <ctype.h>
#include <stdio.h>
static FILE *debuglog = NULL;
static char *pname = "umountd";
static char argbuf[512];

logcall(namex, arg, rqstp)
char	*namex;
char	*arg;
struct svc_req	*rqstp;
{
	int	i;

	if (debuglog == NULL)
	{
		unsigned long tloc;
		if ((debuglog = fopen("/tmp/umountd.log", "a+")) == NULL)
			return;
		time(&tloc);
		fprintf(debuglog, "\n\nstarting %s at %s\n", pname, ctime(&tloc));
	}
	fprintf(debuglog, "%s [ %d %d ",
		namex,
		rqstp->rq_cred.oa_flavor,
		rqstp->rq_cred.oa_length);
	if (rqstp->rq_cred.oa_flavor == AUTH_UNIX)
	{
		struct authunix_parms *unix_cred;
		unix_cred = (struct authunix_parms *) rqstp->rq_clntcred;
		fprintf(debuglog, "%.24s %s %d.%d ",
			ctime(&unix_cred->aup_time),
			unix_cred->aup_machname,
			unix_cred->aup_uid,
			unix_cred->aup_gid);
		if (unix_cred->aup_len > 0)
		{
			for (i = 0; i < unix_cred->aup_len; i++)
				fprintf(debuglog, "%c%d", (i==0?'(':','),
					unix_cred->aup_gids[i]);
			fprintf(debuglog, ") ");
		}
	}
	fprintf(debuglog, "]\n\t%s\n", arg);
	fflush(debuglog);
	return 0;
}
#else
#define logcall(namex, arg, client)
#endif /* DEBUG */

char *dbname = NULL;

int
unfsmntd_init(argc,argv)
     int argc;
     char *argv[];
{
    extern char *optarg;
    int c,errflg = 0;
    
#ifndef DEBUG
	int fd;

	if (fork())
		exit(0);
	close(0);
	close(1);
	close(2);
#ifndef PORTNAME_hpux
	if ((fd = open("/dev/tty", 2)) >= 0)
	{
		ioctl(fd, TIOCNOTTY, (char *)0);
		(void) close(fd);
	}
#endif /* PORTNAME_hpux */
#endif /* DEBUG */
    while((c = getopt(argc,argv,"D:H:P:")) != -1) {
	switch(c) {
	  case 'D':
	    dbname = optarg;
	    break;
	  case 'H':
	    PQhost = optarg;
	    break;
	  case 'P':
	    PQport = optarg;
	    break;
	  case '?':
	    errflg++;
	}
    }
    if (!dbname) errflg++;
    if (errflg) {
	fprintf(stderr,"usage: unfsmntd -D databasename [-H postmaster host] [-P postmaster port]\n");
	exit(1);
    }
    {
	extern int p_attr_caching;
	p_attr_caching = 1;
    }
    PQsetdb(dbname);
    {
	char *res;
	res = (char *)PQexec("begin");
	if (*res == 'E') {
	    fprintf(stderr,"unfsd: begin xact failed: %s\n",*++res);
	    fflush(stderr);
	    exit(2);
	}
    }
    
	fh_init();
}

void *
mountproc_null_1(argp, rqstp)
	void *argp;
	struct svc_req *rqstp;
{
	static char res;

	bzero(&res, sizeof(res));
	logcall("mountproc_null_1", "", rqstp);
	return ((void *)&res);
}


fhstatus *
mountproc_mnt_1(argp, rqstp)
	dirpath *argp;
	struct svc_req *rqstp;
{
	static fhstatus res;
	struct pgstat stbuf;
	extern int errno;

	bzero(&res, sizeof(res));
	logcall("mountproc_mnt_1", sprintf(argbuf, "%s", *argp), rqstp);
	if (p_stat(*argp, &stbuf) < 0)
		res.fhs_status = errno;
	else if ((stbuf.st_mode & S_IFMT) != S_IFDIR)
		res.fhs_status = ENOTDIR;
	else
	{
		res.fhs_status = 0;
		res.fhs_status = fh_create(&(res.fhstatus_u.fhs_fhandle),*argp);
	}
	return (&res);
}


mountlist *
mountproc_dump_1(argp, rqstp)
	void *argp;
	struct svc_req *rqstp;
{
	static mountlist res;

	bzero(&res, sizeof(res));
	logcall("mountproc_dump_1", "", rqstp);
	return (&res);
}


void *
mountproc_umnt_1(argp, rqstp)
	dirpath *argp;
	struct svc_req *rqstp;
{
	static char res;

	bzero(&res, sizeof(res));
	logcall("mountproc_umnt_1", sprintf(argbuf, "%s", *argp), rqstp);
	return ((void *)&res);
}


void *
mountproc_umntall_1(argp, rqstp)
	void *argp;
	struct svc_req *rqstp;
{
	static char res;

	bzero(&res, sizeof(res));
	logcall("mountproc_umntall_1", "", rqstp);
	return ((void *)&res);
}


exports *
mountproc_export_1(argp, rqstp)
	void *argp;
	struct svc_req *rqstp;
{
	static exports res;
	static groupnode resgr;

	bzero(&res, sizeof(res));
	logcall("mountproc_export_1", "", rqstp);
	res.ex_dir = "/";
	res.ex_groups = &resgr;
	bzero(&resgr, sizeof(resgr));
	resgr.gr_name = "mollusca";
	resgr.gr_next = (groups *) 0;
	res.ex_next = (exports *) 0;
	return (&res);
}


exports *
mountproc_exportall_1(argp, rqstp)
	void *argp;
	struct svc_req *rqstp;
{
	logcall("mountproc_exportall_1", "", rqstp);
	return (mountproc_export_1(argp, rqstp));
}
