umount: getopt return value is int, not char
[minix.git] / commands / mount / mount.c
blobf4e463cad0a5346004286a10684ada9bdf143497
1 /* mount - mount a file system Author: Andy Tanenbaum */
3 #include <errno.h>
4 #include <sys/types.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <sys/mount.h>
8 #include <unistd.h>
9 #include <minix/minlib.h>
10 #include <stdio.h>
11 #include <fstab.h>
13 #define MINIX_FS_TYPE "mfs"
15 int main(int argc, char **argv);
16 void list(void);
17 void usage(void);
18 void update_mtab(char *dev, char *mountpoint, char *fstype, int mountflags);
19 int mount_all(void);
21 static int write_mtab = 1;
23 int main(argc, argv)
24 int argc;
25 char *argv[];
27 int all = 0, i, v = 0, mountflags;
28 char **ap, *opt, *err, *type, *args, *device;
30 if (argc == 1) list(); /* just list /etc/mtab */
31 mountflags = 0;
32 type = NULL;
33 args = NULL;
34 ap = argv+1;
35 for (i = 1; i < argc; i++) {
36 if (argv[i][0] == '-') {
37 opt = argv[i]+1;
38 while (*opt != 0) switch (*opt++) {
39 case 'r': mountflags |= MS_RDONLY; break;
40 case 't': if (++i == argc) usage();
41 type = argv[i];
42 break;
43 case 'i': mountflags |= MS_REUSE; break;
44 case 'e': mountflags |= MS_EXISTING; break;
45 case 'n': write_mtab = 0; break;
46 case 'o': if (++i == argc) usage();
47 args = argv[i];
48 break;
49 case 'a': all = 1; break;
50 default: usage();
52 } else {
53 *ap++ = argv[i];
56 *ap = NULL;
57 argc = (ap - argv);
59 if (!all && (argc != 3 || *argv[1] == 0)) usage();
60 if (all == 1) {
61 return mount_all();
64 device = argv[1];
65 if (!strcmp(device, "none")) device = NULL;
67 if ((type == NULL || !strcmp(type, MINIX_FS_TYPE)) && device != NULL) {
68 /* auto-detect type and/or version */
69 v = fsversion(device, "mount");
70 switch (v) {
71 case FSVERSION_MFS1:
72 case FSVERSION_MFS2:
73 case FSVERSION_MFS3: type = MINIX_FS_TYPE; break;
74 case FSVERSION_EXT2: type = "ext2"; break;
78 if (mount(device, argv[2], mountflags, type, args) < 0) {
79 err = strerror(errno);
80 fprintf(stderr, "mount: Can't mount %s on %s: %s\n",
81 argv[1], argv[2], err);
82 return(EXIT_FAILURE);
85 printf("%s is mounted on %s\n", argv[1], argv[2]);
86 return(EXIT_SUCCESS);
89 void list()
91 int n;
92 char dev[PATH_MAX], mountpoint[PATH_MAX], type[MNTNAMELEN], flags[MNTFLAGLEN];
94 /* Read and print /etc/mtab. */
95 n = load_mtab("mount");
96 if (n < 0) exit(1);
98 while (1) {
99 n = get_mtab_entry(dev, mountpoint, type, flags);
100 if (n < 0) break;
101 printf("%s on %s type %s (%s)\n", dev, mountpoint, type, flags);
103 exit(0);
107 has_opt(char *mntopts, char *option)
109 char *optbuf, *opt;
110 int found = 0;
112 optbuf = strdup(mntopts);
113 for (opt = optbuf; (opt = strtok(opt, ",")) != NULL; opt = NULL) {
114 if (!strcmp(opt, option)) found = 1;
116 free (optbuf);
117 return(found);
122 mount_all()
124 struct fstab *fs;
125 int ro, mountflags;
126 char mountpoint[PATH_MAX];
127 char *device, *err;
129 while ((fs = getfsent()) != NULL) {
130 ro = 0;
131 mountflags = 0;
132 device = NULL;
133 if (realpath(fs->fs_file, mountpoint) == NULL) {
134 fprintf(stderr, "Can't mount on %s\n", fs->fs_file);
135 return(EXIT_FAILURE);
137 if (has_opt(fs->fs_mntops, "noauto"))
138 continue;
139 if (!strcmp(mountpoint, "/"))
140 continue; /* Not remounting root */
141 if (has_opt(fs->fs_mntops, "ro"))
142 ro = 1;
143 if (ro) {
144 mountflags |= MS_RDONLY;
147 device = fs->fs_spec;
148 /* passing a null string for block special device means don't
149 * use a device at all and this is what we need to do for
150 * entries starting with "none"
152 if (!strcmp(device, "none"))
153 device = NULL;
155 if (mount(device, mountpoint, mountflags, fs->fs_vfstype,
156 fs->fs_mntops) != 0) {
157 err = strerror(errno);
158 fprintf(stderr, "mount: Can't mount %s on %s: %s\n",
159 fs->fs_spec, fs->fs_file, err);
160 return(EXIT_FAILURE);
163 return(EXIT_SUCCESS);
166 void usage()
168 std_err("Usage: mount [-a] [-r] [-e] [-t type] [-o options] special name\n");
169 exit(1);