/*
 * Implementation of the getmntent. You can supply a filedescriptor to
 * getmntent the one you got returned from setmntent but this is a FILE
 * pointer. Because we use the same static memory on a call to the function
 * the old value is overwritten. So to keep the info make a copy of it.
 * 
 * Version: $Id: mntent.c,v 1.2 1993/05/30 13:29:25 mvw Exp mvw $
 */

#include <stdio.h>
#include <mntent.h>
#include <fcntl.h>
#include <string.h>

static struct mntent _mnt_ent;
static char     _mntstr[MNTMAXSTR];

char *_kill_spaces(char *str)
{
   char *_s;

   _s = strchr(str, ' ');
   if (_s == (char *) 0)
      _s = strchr(str, '\t');
   if (_s == (char *) 0)
      return (str);
   *_s++ = '\0';

   while (*_s == ' ' || *_s == '\t')
      _s++;

   return (_s);
}

struct mntent  *getmntent(FILE * fp)
{
   char *_s = _mntstr, *_t;

   do {
      if (fgets(_mntstr, MNTMAXSTR, fp) == NULL)
         return ((struct mntent *) NULL);
      _mntstr[strlen(_mntstr) - 1] = '\0';
      while (*_s == ' ' || *_s == '\t')
         _s++;
   } while (*_s == '#' || !strlen(_mntstr));

   _mnt_ent.mnt_fsname = _s;
   _s = _kill_spaces(_s);
   _mnt_ent.mnt_dir = _s;
   _s = _kill_spaces(_s);
   _mnt_ent.mnt_type = _s;
   _s = _kill_spaces(_s);
   if (*_s < '0' || *_s > '9') {   /* Are there mntopts */
      _mnt_ent.mnt_opts = _s;
      _s = _kill_spaces(_s);
   } else
      _mnt_ent.mnt_opts = (char *) 0;
   _t = _s;
   _s = _kill_spaces(_s);
   _mnt_ent.mnt_freq = atoi(_t);
   _t = _s;
   _s = _kill_spaces(_s);
   _mnt_ent.mnt_passno = atoi(_t);

   return (&_mnt_ent);
}

/*
 * Test to see if an option is in the mntent.mnt_opts field and return an
 * pointer to the option when found otherwise return 0.
 */
char *hasmntopt(const struct mntent * mnt, const char *opt)
{
   char *_s, *_cutstr;

   _cutstr = (char *) malloc(MNTMAXSTR);
   strcpy(_cutstr, mnt->mnt_opts);
   while (_cutstr) {
      _s = strchr(_cutstr, ',');
      if (_s)
         *_s = '\0';
      if (!strncmp(opt, _cutstr, strlen(opt)))
         return (_cutstr);
      _cutstr = (_s) ? _s + 1 : (char *) NULL;
   }
   return ((char *) NULL);
}

/*
 * Add an mntent struct to the end of an file. For this the file must be
 * opened for writing.
 */
int addmntent(FILE * fp, const struct mntent * mnt)
{
   fseek(fp, (long) 0, SEEK_END);   /* Seek to end of file */

   fprintf(fp, "%s\t%s\t%s\t", mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type);
   fprintf(fp, "%s\t%d\t%d\n", mnt->mnt_opts, mnt->mnt_freq, mnt->mnt_passno);
   return (0);
}

/*
 * Fname is a name of a file containing lines in the format specified in
 * fstab(4). Flags are the same used for fopen.
 */
FILE *setmntent(const char *filename, const char *flags)
{
   FILE *_fp;

   if ((_fp = fopen(filename, flags)) == (FILE *) NULL)
      return ((FILE *) NULL);
   else
      return (_fp);
}

int endmntent(FILE * fp)
{
   return (fclose(fp) ? 1 : 0);
}
