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

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

#include <sys/nfs_defines.h>

/*
 * Copyright (c) 1980 Regents of the University of California.
 * All rights reserved.  The Berkeley software License Agreement
 * specifies the terms and conditions for redistribution.
 */

#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)fstab.c	5.2 (Berkeley) 3/9/86";
#endif LIBC_SCCS and not lint

#ifdef VFS
/* @(#)fstab.c	1.2 87/07/06 3.2/4.3NFSSRC */
#endif VFS

#include <fstab.h>
#include <stdio.h>
#include <ctype.h>
#ifdef VFS
#include <mntent.h>
#endif VFS

static	struct fstab fs;
static	char line[BUFSIZ+1];
static	FILE *fs_file = 0;

#ifndef VFS
static char *
fsskip(p)
	register char *p;
{

	while (*p && *p != ':')
		++p;
	if (*p)
		*p++ = 0;
	return (p);
}

static char *
fsdigit(backp, string, end)
	int *backp;
	char *string, end;
{
	register int value = 0;
	register char *cp;

	for (cp = string; *cp && isdigit(*cp); cp++) {
		value *= 10;
		value += *cp - '0';
	}
	if (*cp == '\0')
		return ((char *)0);
	*backp = value;
	while (*cp && *cp != end)
		cp++;
	if (*cp == '\0')
		return ((char *)0);
	return (cp+1);
}

#endif !VFS
static
fstabscan(fs)
	struct fstab *fs;
{
#ifndef VFS
	register char *cp;
#else !VFS
	struct mntent *mnt;
#endif !VFS

#ifndef VFS
	cp = fgets(line, 256, fs_file);
	if (cp == NULL)
#else !VFS
	while (((mnt = getmntent(fs_file)) != NULL)
	    && ((strcmp(mnt->mnt_type, MNTTYPE_NFS) == 0) ||
                (strcmp(mnt->mnt_type, MNTTYPE_AFS) == 0) ||
		(strcmp(mnt->mnt_type, MNTTYPE_DFS) == 0)));
	if (mnt == NULL)
#endif !VFS
		return (EOF);
#ifndef VFS
	fs->fs_spec = cp;
	cp = fsskip(cp);
	fs->fs_file = cp;
	cp = fsskip(cp);
	fs->fs_type = cp;
	cp = fsskip(cp);
	cp = fsdigit(&fs->fs_freq, cp, ':');
	if (cp == 0)
		return (3);
	cp = fsdigit(&fs->fs_passno, cp, '\n');
	if (cp == 0)
		return (4);
#else !VFS
	fs->fs_spec = mnt->mnt_fsname;
	fs->fs_file = mnt->mnt_dir;
	if (strcmp(mnt->mnt_type, MNTTYPE_IGNORE) == 0) {
		strcpy(mnt->mnt_opts, FSTAB_XX);
	} else if (strcmp(mnt->mnt_type, MNTTYPE_SWAP) == 0) {
		strcpy(mnt->mnt_opts, FSTAB_SW);
	} else if (hasmntopt(mnt, MNTOPT_RO)) {
		strcpy(mnt->mnt_opts, FSTAB_RO);
	} else if (hasmntopt(mnt, MNTOPT_QUOTA)) {
		strcpy(mnt->mnt_opts, FSTAB_RQ);
	} else {
		strcpy(mnt->mnt_opts, FSTAB_RW);
	}
	fs->fs_type = mnt->mnt_opts;
	fs->fs_freq = mnt->mnt_freq;
	fs->fs_passno = mnt->mnt_passno;
#endif !VFS
	return (5);
}
	
setfsent()
{

	if (fs_file)
		endfsent();
#ifndef VFS
	if ((fs_file = fopen(FSTAB, "r")) == NULL) {
#else !VFS
	if ((fs_file = setmntent(FSTAB, "r")) == NULL) {
#endif !VFS
		fs_file = 0;
		return (0);
	}
	return (1);
}

endfsent()
{

	if (fs_file) {
#ifndef VFS
		fclose(fs_file);
#else !VFS
		endmntent(fs_file);
#endif !VFS
		fs_file = 0;
	}
	return (1);
}

struct fstab *
getfsent()
{
	int nfields;

	if ((fs_file == 0) && (setfsent() == 0))
		return ((struct fstab *)0);
	nfields = fstabscan(&fs);
	if (nfields == EOF || nfields != 5)
		return ((struct fstab *)0);
	return (&fs);
}

struct fstab *
getfsspec(name)
	char *name;
{
	register struct fstab *fsp;

	if (setfsent() == 0)	/* start from the beginning */
		return ((struct fstab *)0);
	while((fsp = getfsent()) != 0)
		if (strcmp(fsp->fs_spec, name) == 0)
			return (fsp);
	return ((struct fstab *)0);
}

struct fstab *
getfsfile(name)
	char *name;
{
	register struct fstab *fsp;

	if (setfsent() == 0)	/* start from the beginning */
		return ((struct fstab *)0);
	while ((fsp = getfsent()) != 0)
		if (strcmp(fsp->fs_file, name) == 0)
			return (fsp);
	return ((struct fstab *)0);
}

struct fstab *
getfstype(type)
	char *type;
{
	register struct fstab *fs;

	if (setfsent() == 0)
		return ((struct fstab *)0);
	while ((fs = getfsent()) != 0)
		if (strcmp(fs->fs_type, type) == 0)
			return (fs);
	return ((struct fstab *)0);
}
