/*
 * 5799-WZQ (C) COPYRIGHT = NONE
 * LICENSED MATERIALS - PROPERTY OF IBM
 */
/* $Header:mntent.c 12.0$ */
/* $ACIS:mntent.c 12.0$ */
/* $Source: /ibm/acis/usr/src/lib/libc/gen/RCS/mntent.c,v $ */

#ifndef lint
static char *rcsid = "$Header:mntent.c 12.0$";
#endif

#include <sys/nfs_defines.h>

#ifndef lint
static	char sccsid[] = "@(#)mntent.c 1.1 86/02/03 SMI";
/* @(#)mntent.c	2.1 86/04/11 NFSSRC */
/* @(#)mntent.c 1.1 86/09/24 SMI */
/* @(#)mntent.c 1.2 86/11/14 NFSSRC */
/* @(#)mntent.c 1.1 87/07/06 3.2/4.3 NFSSRC */
#endif

#ifdef VFS
#include <stdio.h>
#include <ctype.h>
#include <mntent.h>
#include <sys/file.h>

static	struct mntent mnt;
static	char line[BUFSIZ+1];

static char *
mntstr(p)
	register char **p;
{
	char *cp = *p;
	char *retstr;

	while (*cp && isspace(*cp))
		cp++;
	retstr = cp;
	while (*cp && !isspace(*cp))
		cp++;
	if (*cp) {
		*cp = '\0';
		cp++;
	}
	*p = cp;
	return (retstr);
}

static int
mntdigit(p)
	register char **p;
{
	register int value = 0;
	char *cp = *p;
	char *retstr;

	while (*cp && isspace(*cp))
		cp++;
	for (; *cp && isdigit(*cp); cp++) {
		value *= 10;
		value += *cp - '0';
	}
	while (*cp && !isspace(*cp))
		cp++;
	if (*cp) {
		*cp = '\0';
		cp++;
	}
	*p = cp;
	return (value);
}

static
mnttabscan(mnttabp, mnt)
	FILE *mnttabp;
	struct mntent *mnt;
{
	char *cp;
	char *errorstring;

	do {
		cp = fgets(line, 256, mnttabp);
		if (cp == NULL) {
			return (EOF);
		}
	} while (*cp == '#');
	errorstring = cp; 
	mnt->mnt_fsname = mntstr(&cp);
	if (*cp == '\0') {
		fprintf(stderr,
		"getmntent: 5 fields are missing from the fstab line:%s\n",
		errorstring);
		return (1);
	}
	mnt->mnt_dir = mntstr(&cp);
	if (*cp == '\0') {
		fprintf(stderr,
		"getmntent: 4 fields are missing from the fstab line:%s\n",
		errorstring);
		return (2);
	}
	mnt->mnt_type = mntstr(&cp);
	if (*cp == '\0') {
		fprintf(stderr,
		"getmntent: 3 fields are missing from the fstab line:%s\n",
		errorstring);
		return (3);
	}
	mnt->mnt_opts = mntstr(&cp);
	if (*cp == '\0') {
		fprintf(stderr,
		"getmntent: 4 fields are missing from the fstab line:%s\n",
		errorstring);
		return (4);
	}
	mnt->mnt_freq = mntdigit(&cp);
	if (*cp == '\0') {
		fprintf(stderr,
		"getmntent: 1 field is missing from the fstab line:%s\n",
		errorstring);
		return (5);
	}
	mnt->mnt_passno = mntdigit(&cp);
	if (*cp == '\0') {
		/* this is the correct number to return */
		return (6);
	} 
	else
	{
		fprintf(stderr,
		"getmntent: Too many fields on the fstab line:%s\n",
		errorstring);
		return(7);
	}
}
	
FILE *
setmntent(fname, flag)
	char *fname;
	char *flag;
{
	FILE *mnttabp;
	int lock;

	if ((mnttabp = fopen(fname, flag)) == NULL) {
		return (NULL);
	}
	lock = LOCK_SH;
	while (*flag) {
		if (*flag == 'w' || *flag == 'a' || *flag == '+') {
			lock = LOCK_EX;
		}
		flag++;
	}
	if (flock(fileno(mnttabp), lock) < 0) {
		fclose(mnttabp);
		return (NULL);
	}
	return (mnttabp);
}

int
endmntent(mnttabp)
	FILE *mnttabp;
{

	if (mnttabp) {
		fclose(mnttabp);
	}
	return (1);
}

struct mntent *
getmntent(mnttabp)
	FILE *mnttabp;
{
	int nfields;

	if (mnttabp == 0)
		return ((struct mntent *)0);
	do {
		nfields = mnttabscan(mnttabp, &mnt);
		if (nfields == EOF)
			return ((struct mntent *)0);
	} while (nfields != 6);
	return (&mnt);
}

addmntent(mnttabp, mnt)
	FILE *mnttabp;
	register struct mntent *mnt;
{
	if (fseek(mnttabp, 0, 2) < 0) {
		return (1);
	}
	mntprtent(mnttabp, mnt);
	return (0);
}

static char tmpopts[256];

static char *
mntopt(p)
	char **p;
{
	char *cp = *p;
	char *retstr;

	while (*cp && isspace(*cp))
		cp++;
	retstr = cp;
	while (*cp && *cp != ',')
		cp++;
	if (*cp) {
		*cp = '\0';
		cp++;
	}
	*p = cp;
	return (retstr);
}

char *
hasmntopt(mnt, opt)
	register struct mntent *mnt;
	register char *opt;
{
	char *f, *opts;

	strcpy(tmpopts, mnt->mnt_opts);
	opts = tmpopts;
	f = mntopt(&opts);
	for (; *f; f = mntopt(&opts)) {
		if (strncmp(opt, f, strlen(opt)) == 0)
			return (f - tmpopts + mnt->mnt_opts);
	} 
	return (NULL);
}

static
mntprtent(mnttabp, mnt)
	FILE *mnttabp;
	register struct mntent *mnt;
{
	fprintf(mnttabp, "%s %s %s %s %d %d\n",
	    mnt->mnt_fsname,
	    mnt->mnt_dir,
	    mnt->mnt_type,
	    mnt->mnt_opts,
	    mnt->mnt_freq,
	    mnt->mnt_passno);
	return(0);
}
#endif VFS
