/*
 * mountd	This program handles RPC "NFS" mount requests.
 *
 * Usage:	[rpc.]mountd [-dpnv] [-f authfile]
 *
 * Version:	@(#)mountd.c	1.5	04/04/93
 *
 * Authors:	Mark A. Shand, May 1988
 *		Rick Sladkey, <jrs@world.std.com>
 *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
 *		Copyright 1988 Mark A. Shand
 *		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 "nfsd.h"


#define OLD_RPCGEN			/* why?  Dunno... -FvK		*/


#ifndef OLD_RPCGEN
#   define mountproc_null_1		mountproc_null_1_svc
#   define mountproc_mnt_1		mountproc_mnt_1_svc
#   define mountproc_dump_1		mountproc_dump_1_svc
#   define mountproc_umnt_1		mountproc_umnt_1_svc
#   define mountproc_umntall_1		mountproc_umntall_1_svc
#   define mountproc_export_1		mountproc_export_1_svc
#   define mountproc_exportall_1	mountproc_exportall_1_svc
#endif


static char *Version = "@(#) mountd 1.5 (04/04/93)";


char argbuf[512];
char *auth_file = NULL;
#ifdef OLD_RPCGEN
int _rpcpmstart = 0;
#endif


static _PRO( void usage, (void)						);


/* In mount_svc.c: */
extern _PRO( void mount_run, (void)					);


/* The NULL request handler. */
void *mountproc_null_1(argp, rqstp)
void *argp;
struct svc_req *rqstp;
{
  static char res;

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


fhstatus *mountproc_mnt_1(argp, rqstp)
dirpath *argp;
struct svc_req *rqstp;
{
  static fhstatus res;
  struct stat stbuf;
  clnt_param *cp;

  bzero(&res, sizeof(res));
  sprintf(argbuf, "%s", *argp);
  log_call(rqstp, "mountproc_mnt_1", argbuf);
  if (((cp = auth_clnt(rqstp, argbuf)) == NULL))
			res.fhs_status = NFSERR_ACCES;
    else if (stat(*argp, &stbuf) < 0)
			res.fhs_status = nfs_errno();
    else if ((stbuf.st_mode & S_IFMT) != S_IFDIR)
			res.fhs_status = NFSERR_NOTDIR;
    else {
	res.fhs_status = fh_create((nfs_fh *)
		&(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));
  log_call(rqstp, "mountproc_dump_1", "");
  return(&res);
}


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

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


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

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


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

  bzero(&res, sizeof(res));
  log_call(rqstp, "mountproc_export_1", "");
  res = export_list;
  return(&res);
}


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


static void usage()
{
  dprintf(0, "Usage: mountd [-dpnv] [-f authfile]\n");
  (void) closelog();
  exit(-1);
}


void main(argc, argv)
int argc;
char **argv;
{
  int c, fd;
  extern int getopt(), optind, opterr;
  extern char *optarg;

  /* Parse the command line options and arguments. */
  opterr = 0;
  while ((c = getopt(argc, argv, "df:pv")) != EOF) switch(c) {
	case 'd':
	case 'v':
		toggle_logging(0);
		break;
	case 'f':
		auth_file = optarg;
		break;
	case 'n':
		allow_non_root = 1;
		break;
	case 'p':
		promiscuous = 1;
		break;
	case '?':
	default:
		usage();
  }

  /* No more arguments allowed. */
  if (optind != argc) usage();

  /* We first fork off a child. */
  if ((c = fork()) > 0) exit(0);
  if (c < 0) {
	fprintf(stderr, "mountd: cannot fork: %s\n", strerror(errno));
	exit(-1);
  }

  /* Now we remove ourselves from the foreground. */
  (void) close(0);
  (void) close(1);
  (void) close(2);
  if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
	(void) ioctl(fd, TIOCNOTTY, (char *)NULL);
	(void) close(fd);
  }

  /* Initialize logging. */
  log_open("mountd");

  /* Initialize the FH module. */
  fh_init();

  /* Initialize the AUTH module. */
  auth_init(auth_file);

  /* Enable the LOG toggle with a signal. */
  (void) signal(SIGUSR1, toggle_logging);

  /* Run the MOUNT server. */
  mount_run();

  dprintf(0, "Oh no Mr. Bill... mount_run() returned!\n");
  exit(1);
}
