--------------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);
}