--------------mount.c---------------------
/*
 * Copyright (c) 1993 by David I. Bell
 * Permission is granted to use, distribute, or modify this source,
 * provided that this copyright notice remains intact.
 *
 * Most simple built-in commands are here.
 *
 * 2000-01-14: by Mario Frasca, added fstab-mtab usage and -a option
 * if compiled with -DMINIMALMOUNT then does nothing but call umount($1)


this mount command supports the options:
-h    Print a help message.
-t vfstype
      The argument following the -t is used to indicate
      the file system type.  The file system types which
      are currently supported are listed in
      elks/fs/filesystems.c: elksfs, minix, romfs
#ifndef MINIMALMOUNT
-a    Mount all filesystems (of the given types)
      mentioned in fstab.
-n     Mount without using /etc/mtab.  This is neces-
      sary for example when /etc is on a read-only file
      system.
#endif

the LINUX mount command supports the options:
-V     Output version.
-v     Verbose mode.
-F     (Used in conjunction with -a.) Fork off a new
      incarnation of mount for each device. This will do
      the mounts on different devices or different NFS
      servers in parallel. This has the advantage that
      it is faster; also NFS timeouts go in parallel. A
      disadvantage is that the mounts are done in unde-
      fined order. Thus, you cannot use this option if
      you want to mount both /usr and /usr/spool.
-f     Causes everything to be done except for the actual
      system call; if it's not obvious, this ``fakes''
      mounting the file system. This option is useful in
      conjunction with the -v flag to determine what the
      mount command is trying to do. It can also be used
      to add entries for devices that were mounted ear-
      lier with the -n option.
-s     Tolerate sloppy mount options rather than failing.
      This will ignore mount options not supported by a
      filesystem type. Not all filesystems support this
      option. This option exists for support of the Linux
      autofs-based automounter.

-r     Mount the file system read-only.
      A synonym is -o ro.

-w     Mount the file system read/write. This is the
      default. A synonym is -o rw.

-L label
      Mount the partition that has the specified label.

-U uuid
      Mount  the  partition  that has the specified uuid.
      These two options require the file /proc/partitions
      (present since Linux 2.1.116) to exist.

-t vfstype
       The argument following the -t is used to indicate
      the file system type. The file system types which
      are currently supported are listed in
      linux/fs/filesystems.c: minix, xiafs, ext, ext2,
      msdos, umsdos, vfat, proc, autofs, devpts, nfs,
      iso9660, smbfs, ncpfs, adfs, affs, coda, hfs, hpfs,
      ntfs, qnx4, romfs, ufs, sysv, xenix, coherent.
      Note that the last three are equivalent and that
      xenix and coherent will be removed at some point in
      the future -- use sysv instead. Since kernel
      version 2.1.21 the types ext and xiafs do not exist
      anymore.

-o     Options are specified with a -o flag followed by a
      comma separated string of options. Some of these
      options are only useful when they appear in the
      /etc/fstab file. The following options apply to
      any file system that is being mounted:

 */

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
#include <utime.h>
#include <errno.h>
#include <string.h>

#define BUFSIZE 128
#define ETCDIR "/etc/"

#ifndef MINIMALMOUNT
char mtabline[BUFSIZE];
char finddevice_out[BUFSIZE];
char * finddevice_in;
char * filtertype=NULL;
int usemtab;

void printline();
void finddeviceline();
void mountline();
void scanfile();
#endif

#ifndef MINIMALMOUNT
/*
 * Nonexistant files return FALSE.
 */
int
exists(name)
 char *name;
{
 struct stat statbuf;

 if (stat(name, &statbuf) < 0)
  return 0;

 return 1;
}
#endif

void usage()
{
  write(STDERR_FILENO, "mount: please read the docs\n", 28);
  exit(1);
}

void domount(device, dir, type, options)
char *device, *dir, *type;
int options;
{
#ifndef MINIMALMOUNT
  if (usemtab)
  {
    if(exists(ETCDIR"mtab"))
    {
      finddevice_in = device;
      *finddevice_out = 0;
      scanfile(ETCDIR"mtab", finddeviceline);
      if (*finddevice_out)
      {
        if(filtertype && !strstr(mtabline,filtertype))
          return;

        write(STDERR_FILENO, "mount: according to mtab, ", 26);
        write(STDERR_FILENO, device, strlen(device));
        write(STDERR_FILENO, " is already mounted\n", 20);
        return;
      }

      finddevice_in = dir;
      *finddevice_out = 0;
      scanfile(ETCDIR"mtab", finddeviceline);
      if (*finddevice_out)
      {
        if(filtertype && !strstr(mtabline,filtertype))
          return;

        write(STDERR_FILENO, "mount: according to mtab, ", 26);
        write(STDERR_FILENO, dir, strlen(dir));
        write(STDERR_FILENO, " is already in use\n", 19);
        return;
      }
    }

    if(filtertype)
      if(!strstr(mtabline, filtertype))
        return;
  }
#endif

  if (mount(device, dir, type, 0) < 0) {
    perror("mount failed");
    exit(1);
  }
#ifndef MINIMALMOUNT
  else if(usemtab)
  {
    int f = open(ETCDIR"mtab", O_RDWR|O_APPEND|O_CREAT,
S_IREAD|S_IWRITE);
    strcat(mtabline, "\n");
    write(f,mtabline, strlen(mtabline));
    close(f);
  }
#endif
}

#ifndef MINIMALMOUNT
void scanfile(filename, foo)
char * filename;
void foo();
{
  int f, left;
  char buf[BUFSIZE], *line, *next;

  f = open(filename, O_RDONLY);
  if(-1 == f)
  {
  write(STDERR_FILENO, "mount: can't open file\n", 23);
    exit(1);
  }

  left = read(f, buf, BUFSIZE);
  line = buf;
  next = strchr(line, '\n');
  if (next) *(next++)='\000';

  while (left>0)
  {
    if (!next)
    {
      if(line == buf)
        return;
      memmove(buf, line, left);
      left += read(f, buf+left, BUFSIZE-left);
      line = buf;
      next = strchr(line, '\n');
      if (next)
        *(next++)='\000';
    }
    else
    {
      foo(line);

      left -= next-line;
      line = next;
      next = strchr(line, '\n');
      if (next > line+left)
        next = 0;
      if (next)
        *(next++)='\000';
    }
  }
  close(f);
}

void printline(line)
char * line;
{
  write(STDOUT_FILENO, line, strlen(line));
  write(STDOUT_FILENO, "\n", 1);
}

void finddeviceline(line)
char * line;
{
  if (strstr(line, finddevice_in) && !*finddevice_out)
    strcpy(finddevice_out, line);
}
#endif

void mountline(line)
char * line;
{
  char *device, *dir, *type;

  if(strstr(line, "auto"))
  {
#ifndef MINIMALMOUNT
    strcpy(mtabline, line);
#endif
    device = strtok(line, " \t");
    dir    = strtok(NULL, " \t");
    type   = strtok(NULL, " \t");
   domount(device, dir, type, 0);
  }
}

void
main(argc, argv)
 char **argv;
{
 char *str, *device, *dir;
#ifndef MINIMALMOUNT
  char buf[BUFSIZE], *type;
  int allofthem = 0;
  usemtab = 1;
#else
  char *type = "minix";
#endif

 argc--;
 argv++;

 while ((argc > 0) && (**argv == '-')) {
  argc--;
  str = *argv++ ;

  while (*++str) switch (*str) {
   case 't':
    if ((argc <= 0) || (**argv == '-')) {
     write(STDERR_FILENO, "Missing file system type\n", 25);
     exit(1);
    }

#ifndef MINIMALMOUNT
    filtertype = *argv++;
#else
        type = *argv++;
#endif
    argc--;
    break;

      case 'h':
        usage();
        exit(0);
        break;

#ifndef MINIMALMOUNT
      case 'a':
        allofthem=1;
        break;

      case 'n':
        usemtab = 0;
        break;
#endif

   default:
    write(STDERR_FILENO, "Unknown option\n", 15);
    exit(1);
  }
 }

#ifndef MINIMALMOUNT
  if(allofthem)
  {
    scanfile(ETCDIR"fstab", mountline);
    exit(0);
  }

  *mtabline = 0;
#endif

  switch (argc)
  {
#ifndef MINIMALMOUNT
  case 0:
    {
      if(exists(ETCDIR"mtab"))
        scanfile(ETCDIR"mtab", printline);
      exit(0);
    }
    break;
  case 1:
    {
      finddevice_in = argv[0];
      *finddevice_out = 0;
      scanfile(ETCDIR"fstab", finddeviceline);
      if (!*finddevice_out)
      {
       write(STDERR_FILENO, "no entry in fstab\n", 18);
       exit(1);
      }
      strcpy(buf, finddevice_out);
      strcpy(mtabline, finddevice_out);
      device = strtok(buf, " \t");
      type = strtok(NULL, " \t");
      dir = argv[0];
    }
    break;
#endif
  case 2:
    {
      device = argv[0];
      dir = argv[1];
#ifndef MINIMALMOUNT
      type = filtertype;
      strcat(mtabline, device);
      strcat(mtabline, "\t");
      strcat(mtabline, dir);
      strcat(mtabline, "\t");
      strcat(mtabline, filtertype);
#endif
    }
    break;
  default:
  write(STDERR_FILENO, "Wrong number of arguments for mount\n", 36);
  exit(1);
  }

  /* device, dir (i.e.: mount point) and type are now correctly set */
  /* mtabline now contains the line to be added to mtab */

  domount(device, dir, type, 0);

 exit(0);
}
-------------umount.c---------------------
/*
 * Copyright (c) 1993 by David I. Bell
 * Permission is granted to use, distribute, or modify this source,
 * provided that this copyright notice remains intact.
 *
 * Most simple built-in commands are here.
 *
 * 2000-01-14: by Mario Frasca, added fstab-mtab usage and -a option
 *

this umount command supports the options:
-a    All of the file systems described in /etc/mtab are
      unmounted.
-n    Unmount without reading/writing in /etc/mtab.
-h    Print help message and exit.

the LINUX umount command supports the options:
-V    Print version and exit.
-v    Verbose mode.
-r    In case unmounting fails, try to remount read-only.

-t vfstype
      Indicate that the actions should only be taken on
      file systems of the specified type.  More than one
      type may be specified in a comma separated list.
      The list of file system types can be prefixed with
      no to specify the file system types on which no
      action should be taken.
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
#include <utime.h>
#include <errno.h>

#define BUFSIZE 128
#define ETCDIR "/etc/"

#ifndef MINIMALMOUNT
char finddevice_out[BUFSIZE];
char *finddevice_in;
int   filterwriteline_file;
char *filterwriteline_line;
int usemtab;
#endif

void usage()
{
  exit(1);
}

#ifndef MINIMALMOUNT
/*
 *  function scans the text file, identified by the first parameter.
 *  for each line in the file it invokes the function, passed
 *  as second parameter.
 *
 *  this function uses only low level reads.
 */
void scanfile(filename, foo)
char * filename;
void foo();
{
  int f, left;
  char buf[BUFSIZE], *line, *next;

  f = open(filename, O_RDONLY);
  if(-1 == f)
  {
      write(STDERR_FILENO, "mount: can't open file\n", 23);
    exit(1);
  }

  left = read(f, buf, BUFSIZE);
  line = buf;
  next = strchr(line, '\n');
  if (next) *(next++)='\000';

  while (left>0)
  {
    if (!next)
    {
      if(line == buf)
        return;
      memmove(buf, line, left);
      left += read(f, buf+left, BUFSIZE-left);
      line = buf;
      next = strchr(line, '\n');
      if (next)
        *(next++)='\000';
    }
    else
    {
      foo(line);

      left -= next-line;
      line = next;
      next = strchr(line, '\n');
      if (next > line+left)
        next = 0;
      if (next)
        *(next++)='\000';
    }
  }
  close(f);
}

void finddeviceline(line)
char * line;
{
  if (strstr(line, finddevice_in) && !*finddevice_out)
    strcpy(finddevice_out, line);
}

void filterwriteline(line)
char * line;
{
  if (strncmp(line, filterwriteline_line, strlen(filterwriteline_line)))

  {
    write(filterwriteline_file, line, strlen(line));
    write(filterwriteline_file, "\n", 1);
  }
}

/*
 * Nonexistant files return FALSE.
 */
int
exists(name)
   char   *name;
{
   struct   stat   statbuf;

   if (stat(name, &statbuf) < 0)
      return 0;

   return 1;
}
#endif

void umountline(line)
char *line;
{
  strtok(line, " \t");

   if (umount(line) < 0) {
      perror(line);
      exit(1);
   }
}

void
main(argc, argv)
   char   **argv;
{
  char *type, *str;
#ifndef MINIMALMOUNT
  int allofthem = 0;
  usemtab = 1;
#endif

   argc--;
   argv++;
   type = "minix";

   while ((argc > 0) && (**argv == '-')) {
      argc--;
      str = *argv++ ;

      while (*++str) switch (*str) {
         case 't':
            if ((argc <= 0) || (**argv == '-')) {
               write(STDERR_FILENO, "Missing file system type\n", 25);
               exit(1);
            }

            type = *argv++;
            argc--;
            break;

      case 'h':
        usage();
        exit(0);
            break;

#ifndef MINIMALMOUNT
      case 'a':
        allofthem=1;
        break;

      case 'n':
        usemtab = 0;
        break;
#endif

      default:
        write(STDERR_FILENO, "Unknown option\n", 15);
        exit(1);
      }
   }

#ifndef MINIMALMOUNT
  if(allofthem)
  {
    if(exists(ETCDIR"mtab"))
    {
      scanfile(ETCDIR"mtab", umountline);
      if(usemtab)
        unlink(ETCDIR"mtab");
    }
    exit(0);
  }
#endif

  if(0==argc)
    usage();

#ifndef MINIMALMOUNT
  if(!exists(ETCDIR"mtab") && usemtab)
  {
    write(STDERR_FILENO, "umount: according to mtab, nothing is
mounted\n", 46);
    exit(1);
  }
#endif

#ifdef MINIMALMOUNT
  /* assume that the first non-switch argument is the specialfile or
   * the dir that is to be unmounted
   */
  umountline(argv[0]);
#else

  if(usemtab)
  {
    /* if argv[0] is a mount point, then find corresponding device */
    if(strncmp(argv[0], "/dev/", 5))
    {
      finddevice_in = argv[0];
      *finddevice_out = 0;
      scanfile(ETCDIR"mtab", finddeviceline);
      if(!*finddevice_out)
      {
        write(STDERR_FILENO, "umount: according to mtab, mount point is
not mounted\n", 54);
        exit(1);
      }
    }
    else
    {
      /* see if mtab says that the device is mounted */
      finddevice_in = argv[0];
      *finddevice_out = 0;
      scanfile(ETCDIR"mtab", finddeviceline);
      if(!*finddevice_out)
      {
        write(STDERR_FILENO, "umount: according to mtab, device is not
mounted\n", 49);
        exit(1);
      }
    }
    /* /etc/mtab exists */

    /* finddevice_out contains a copy of the mounted line
     * that is to be unmounted.
     */

    umountline(finddevice_out);

    /* remove any backup of mtab */
    unlink(ETCDIR"mtab~");
    rename(ETCDIR"mtab", ETCDIR"mtab~");

    filterwriteline_file = open(ETCDIR"mtab", O_CREAT|O_WRONLY,
S_IREAD|S_IWRITE);
    filterwriteline_line = finddevice_out;
    /* this copies mtab~ to mtab except the device just unmounted. */
    scanfile(ETCDIR"mtab~", filterwriteline);
    close(filterwriteline_file);
    /* don't keep a backup of mtab */
    unlink(ETCDIR"mtab~");
  }
  else
    umountline(argv[0]);

#endif

   exit(0);
}


Reply via email to