/*
 * Copyright 1993, 1994 by Ulrich Khn. All rights reserved.
 *
 * THIS PROGRAM COMES WITH ABSOLUTELY NO WARRANTY, NOT
 * EVEN THE IMPLIED WARRANTIES OF MERCHANTIBILITY OR
 * FITNESS FOR A PARTICULAR PURPOSE. USE AT YOUR OWN
 * RISK.
 */

/*
 * File : mntent.c
 *        access files containing file system information
 *
 */


#include <stdio.h>
#include <stdlib.h>
#include <support.h>
#include <ctype.h>
#include <file.h>
#include <errno.h>
#include "mntent.h"



#define MAX_LINE_LEN 80


static struct mntent the_mntent;
static char the_mntbuf[MAX_LINE_LEN+2];


FILE *
setmntent(char *name, char *type)
{
	FILE *fp;
	int i;

	/* open the file */
	fp = fopen(name, type);
	if (!fp)
		return NULL;

	/* set up some static buffers etc. */
	the_mntent.mnt_fsname = NULL;
	the_mntent.mnt_dir = NULL;
	the_mntent.mnt_type = NULL;
	the_mntent.mnt_opts = NULL;
	the_mntent.mnt_freq = 0;
	the_mntent.mnt_passno = 0;
	for (i = 0;  i < MAX_LINE_LEN+2;  i++)
		the_mntbuf[i] = '\0';

	return fp;
}


int
endmntent(FILE *fp)
{
	fclose(fp);
	return 1;   /* for compatibility */
}



struct mntent *
getmntent(FILE *fp)
{
	char *p;

read_again:
	p = fgets(the_mntbuf, MAX_LINE_LEN, fp);
	if (p == NULL)
		return NULL;

	/* strip off tailing line separator */
	p = the_mntbuf;
	while (*p && (*p != '\r') && (*p != '\n'))
		p++;
	*p = '\0';

	/* check for comments */
	if (the_mntbuf[0] == '#')   /* if that line is a comment, do it again */
	{
		goto read_again;
	}

	/* now scan the line and set the mntent struct accordingly */
	p = the_mntbuf;
	while (*p && iswhite(*p))   /* skip leading white spaces */
		p++;
	the_mntent.mnt_fsname = p;
	while (*p && !iswhite(*p))
		p++;
	if (*p)
		*p++ = '\0';

	while (*p && iswhite(*p))
		p++;
	the_mntent.mnt_dir = p;
	while (*p && !iswhite(*p))
		p++;
	if (*p)
		*p++ = '\0';

	while (*p && iswhite(*p))
		p++;
	the_mntent.mnt_type = p;
	while (*p && !iswhite(*p))
		p++;
	if (*p)
		*p++ = '\0';

	while (*p && iswhite(*p))
		p++;
	the_mntent.mnt_opts = p;
	while (*p && !iswhite(*p))
		p++;
	if (*p)
		*p++ = '\0';

	while (*p && iswhite(*p))
		p++;
	the_mntent.mnt_freq = (int)strtol(p, &p, 10);
	if (*p)
		p++;

	while (*p && iswhite(*p))
		p++;
	the_mntent.mnt_passno = (int)strtol(p, &p, 10);

	return &the_mntent;
}


int
addmntent(FILE *fp, struct mntent *mnt)
{
	char line[MAX_LINE_LEN+3], numbuf[8];
	char *p, *s;
	long n, r;

	/* wait for a lock on that file */
	do {
		r = flock(fileno(fp), LOCK_EX|LOCK_NB);
	} while ((r < 0) && (errno == ELOCKED));

	if (r != 0)
		return 1;

	fseek(fp, 0, SEEK_END);   /* go to end of file */
	n = 0;
	p = line;
	if (mnt->mnt_fsname)
	{
		for (s = mnt->mnt_fsname;  (n < MAX_LINE_LEN-1) && *s;  n++)
			*p++ = *s++;
		*p++ = ' ';
		n++;
	}

	if (mnt->mnt_dir)
	{
		for (s = mnt->mnt_dir;  (n < MAX_LINE_LEN-1) && *s;  n++)
			*p++ = *s++;
		*p++ = ' ';
		n++;
	}

	if (mnt->mnt_type)
	{
		for (s = mnt->mnt_type;  (n < MAX_LINE_LEN-1) && *s;  n++)
			*p++ = *s++;
		*p++ = ' ';
		n++;
	}

	if (mnt->mnt_opts)
	{
		for (s = mnt->mnt_opts;  (n < MAX_LINE_LEN-1) && *s;  n++)
			*p++ = *s++;
		*p++ = ' ';
		n++;
	}

	s = _itoa(mnt->mnt_freq, numbuf, 10);
	for ( ; (n < MAX_LINE_LEN-1) && *s;  n++)
		*p++ = *s++;
	*p++ = ' ';
	n++;

	s = _itoa(mnt->mnt_passno, numbuf, 10);
	for ( ; (n < MAX_LINE_LEN-1) && *s;  n++)
		*p++ = *s++;
	*p++ = '\r';
	*p++ = '\n';
	*p = '\0';

	r = fwrite(line, 1, n+2, fp);

	flock(fileno(fp), LOCK_UN);   /* unlock file */

	if (r == n+2)
		return 0;
	else
		return 1;
}


char *
hasmntopt(struct mntent *mnt, char *opt)
{
	return NULL;
}
