/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 1990 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <ctype.h>
#include <mntent.h>
#include <sys/file.h>
#include <malloc.h>
static int mntprtent(FILE *, struct mntent *);
static struct mntent *mntp;
struct mntent *
_mnt(void)
{
if (mntp == 0)
mntp = (struct mntent *)calloc(1, sizeof (struct mntent));
return (mntp);
}
static char *
mntstr(char **p)
{
unsigned char *cp = (unsigned char *) *p;
unsigned char *retstr;
while (*cp && isspace(*cp))
cp++;
retstr = cp;
while (*cp && !isspace(*cp))
cp++;
if (*cp) {
*cp = '\0';
cp++;
}
*p = (char *) cp;
return ((char *)retstr);
}
static int
mntdigit(char **p)
{
int value = 0;
unsigned char *cp = (unsigned char *) *p;
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 = (char *) cp;
return (value);
}
static int
mnttabscan(FILE *mnttabp, struct mntent *mnt)
{
static char *line = NULL;
char *cp;
if (line == NULL)
line = (char *)malloc(BUFSIZ+1);
do {
cp = fgets(line, BUFSIZ, mnttabp);
if (cp == NULL) {
return (EOF);
}
} while (*cp == '#');
mnt->mnt_fsname = mntstr(&cp);
if (*cp == '\0')
return (1);
mnt->mnt_dir = mntstr(&cp);
if (*cp == '\0')
return (2);
mnt->mnt_type = mntstr(&cp);
if (*cp == '\0')
return (3);
mnt->mnt_opts = mntstr(&cp);
if (*cp == '\0')
return (4);
mnt->mnt_freq = mntdigit(&cp);
if (*cp == '\0')
return (5);
mnt->mnt_passno = mntdigit(&cp);
return (6);
}
FILE *
setmntent(char *fname, char *flag)
{
FILE *mnttabp;
if ((mnttabp = fopen(fname, flag)) == NULL) {
return (NULL);
}
for (; *flag ; flag++) {
if (*flag == 'w' || *flag == 'a' || *flag == '+') {
if (flock(fileno(mnttabp), LOCK_EX) < 0) {
fclose(mnttabp);
return (NULL);
}
break;
}
}
return (mnttabp);
}
int
endmntent(FILE *mnttabp)
{
if (mnttabp) {
fclose(mnttabp);
}
return (1);
}
struct mntent *
getmntent(FILE *mnttabp)
{
int nfields;
if (mnttabp == 0)
return ((struct mntent *)0);
if (_mnt() == 0)
return ((struct mntent *)0);
nfields = mnttabscan(mnttabp, mntp);
if (nfields == EOF || nfields != 6)
return ((struct mntent *)0);
return (mntp);
}
int
addmntent(FILE *mnttabp, struct mntent *mnt)
{
if (fseek(mnttabp, 0L, 2) < 0)
return (1);
if (mnt == (struct mntent *)0)
return (1);
if (mnt->mnt_fsname == NULL || mnt->mnt_dir == NULL ||
mnt->mnt_type == NULL || mnt->mnt_opts == NULL)
return (1);
mntprtent(mnttabp, mnt);
return (0);
}
static char *
mntopt(char **p)
{
unsigned char *cp = (unsigned char *) *p;
unsigned char *retstr;
while (*cp && isspace(*cp))
cp++;
retstr = cp;
while (*cp && *cp != ',')
cp++;
if (*cp) {
*cp = '\0';
cp++;
}
*p = (char *) cp;
return ((char *)retstr);
}
char *
hasmntopt(struct mntent *mnt, char *opt)
{
char *f, *opts;
static char *tmpopts;
if (tmpopts == 0) {
tmpopts = (char *)calloc(256, sizeof (char));
if (tmpopts == 0)
return (0);
}
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 int
mntprtent(FILE *mnttabp, 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);
}