/* $Header: /cvsroot/watchdog/watchdog/src/mntent.c,v 1.2 2006/07/31 09:39:23 meskes Exp $ */

/* Private version of the libc *mntent() routines. */
/* Note slightly different prototypes. */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <string.h>		/* for strchr */
#include <ctype.h>		/* for isdigit */
#include "wd_mntent.h"
#include "sundries.h"		/* for xmalloc */

/* Unfortunately the classical Unix /etc/mtab and /etc/fstab
   do not handle directory names containing spaces.
   Here we mangle them, replacing a space by \040.
   What do other Unices do? */

static char need_escaping[] = { ' ', '\t', '\n', '\\' };

static char *
mangle(const char *s) {
	char *ss, *sp;
	int n;

	n = (int) strlen(s);
	ss = sp = xmalloc(4*n+1);
	while(1) {
		for (n = 0; n < sizeof(need_escaping); n++) {
			if (*s == need_escaping[n]) {
				*sp++ = '\\';
				*sp++ = '0' + ((*s & 0300) >> 6);
				*sp++ = '0' + ((*s & 070) >> 3);
				*sp++ = '0' + (*s & 07);
				goto next;
			}
		}
		*sp++ = *s;
		if (*s == 0)
			break;
	next:
		s++;
	}
	return ss;
}

static int
is_space_or_tab (char c) {
	return (c == ' ' || c == '\t');
}

static char *
skip_spaces(char *s) {
	while (is_space_or_tab(*s))
		s++;
	return s;
}

static char *
skip_nonspaces(char *s) {
	while (*s && !is_space_or_tab(*s))
		s++;
	return s;
}

#define isoctal(a) (((a) & ~7) == '0')

/* returns malloced pointer - no more strdup required */
static char *
unmangle(char *s) {
	char *ret, *ss, *sp;

	ss = skip_nonspaces(s);
	ret = sp = xmalloc(ss-s+1);
	while(s != ss) {
		if (*s == '\\' && isoctal(s[1]) && isoctal(s[2]) && isoctal(s[3])) {
			*sp++ = 64*(s[1] & 7) + 8*(s[2] & 7) + (s[3] & 7);
			s += 4;
		} else
			*sp++ = *s++;
	}
	*sp = 0;
	return ret;
}

/*
 * fstat'ing the file and allocating a buffer holding all of it
 * may be a bad idea: if the file is /proc/mounttab, the stat
 * returns 0.
 * (On the other hand, mangling and unmangling is meaningless
 *  for /proc/mounttab.)
 */

mntFILE *
my_setmntent (const char *file, char *mode) {
	mntFILE *mfp = xmalloc(sizeof(*mfp));

	mfp->mntent_fp = fopen (file, mode);
	mfp->mntent_file = xstrdup(file);
	mfp->mntent_errs = (mfp->mntent_fp == NULL);
	mfp->mntent_softerrs = 0;
	mfp->mntent_lineno = 0;
	return mfp;
}

void
my_endmntent (mntFILE *mfp) {
	if (mfp) {
		if (mfp->mntent_fp)
			fclose(mfp->mntent_fp);
		if (mfp->mntent_file)
			free(mfp->mntent_file);
		free(mfp);
	}
}


int
my_addmntent (mntFILE *mfp, struct mntent *mnt) {
	char *m1, *m2, *m3, *m4;
	int res;

	if (fseek (mfp->mntent_fp, 0, SEEK_END))
		return 1;			/* failure */

	m1 = mangle(mnt->mnt_fsname);
	m2 = mangle(mnt->mnt_dir);
	m3 = mangle(mnt->mnt_type);
	m4 = mangle(mnt->mnt_opts);

	res = ((fprintf (mfp->mntent_fp, "%s %s %s %s %d %d\n",
			 m1, m2, m3, m4, mnt->mnt_freq, mnt->mnt_passno)
		< 0) ? 1 : 0);

	free(m1);
	free(m2);
	free(m3);
	free(m4);
	return res;
}

/* Read the next entry from the file fp. Stop reading at an incorrect entry. */
struct mntent *
my_getmntent (mntFILE *mfp) {
	static char buf[4096];
	static struct mntent me;
	char *s;

 again:
	if (mfp->mntent_errs || mfp->mntent_softerrs >= ERR_MAX)
		return NULL;

	/* read the next non-blank non-comment line */
	do {
		if (fgets (buf, sizeof(buf), mfp->mntent_fp) == NULL)
			return NULL;

		s = strchr (buf, '\n');
		if (s == NULL) {
			/* extremely long line - assume file was corrupted */
			mfp->mntent_errs = 1;
			goto err;
		}
		*s = 0;
		s = skip_spaces(buf);
	} while (*s == '\0' || *s == '#');

	me.mnt_fsname = unmangle(s);
	s = skip_nonspaces(s);
	s = skip_spaces(s);
	me.mnt_dir = unmangle(s);
	s = skip_nonspaces(s);
	s = skip_spaces(s);
	me.mnt_type = unmangle(s);
	s = skip_nonspaces(s);
	s = skip_spaces(s);
	me.mnt_opts = unmangle(s);
	s = skip_nonspaces(s);
	s = skip_spaces(s);

	if(isdigit(*s)) {
		me.mnt_freq = atoi(s);
		while(isdigit(*s)) s++;
	} else
		me.mnt_freq = 0;
	if(*s && !is_space_or_tab(*s))
		goto err;

	s = skip_spaces(s);
	if(isdigit(*s)) {
		me.mnt_passno = atoi(s);
		while(isdigit(*s)) s++;
	} else
		me.mnt_passno = 0;
	if(*s && !is_space_or_tab(*s))
		goto err;

	/* allow more stuff, e.g. comments, on this line */

	return &me;

err:
	mfp->mntent_softerrs++;
	fprintf(stderr, "[mntent]: line %d in %s is bad%s\n",
		mfp->mntent_lineno, mfp->mntent_file,
		(mfp->mntent_errs || mfp->mntent_softerrs >= ERR_MAX) ?
		"; rest of file ignored" : "");
	goto again;
}
