xref: /minix3/minix/commands/mount/mount.c (revision 69eead77ff7b92014d108017d0765cfa7d3ddba7)
1 /* mount - mount a file system		Author: Andy Tanenbaum */
2 
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>
12 
13 #define MINIX_FS_TYPE "mfs"
14 
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);
20 
21 static int write_mtab = 1;
22 
main(argc,argv)23 int main(argc, argv)
24 int argc;
25 char *argv[];
26 {
27   int all = 0, i, v = 0, mountflags, srvflags;
28   char **ap, *opt, *err, *type, *args, *device;
29 
30   if (argc == 1) list();	/* just list /etc/mtab */
31   mountflags = 0;
32   srvflags = 0;
33   type = NULL;
34   args = NULL;
35   ap = argv+1;
36   for (i = 1; i < argc; i++) {
37 	if (argv[i][0] == '-') {
38 		opt = argv[i]+1;
39 		while (*opt != 0) switch (*opt++) {
40 		case 'r':	mountflags |= MNT_RDONLY;	break;
41 		case 't':	if (++i == argc) usage();
42 				type = argv[i];
43 				break;
44 		case 'i':	srvflags |= MS_REUSE;		break;
45 		case 'e':	srvflags |= MS_EXISTING;		break;
46 		case 'n':	write_mtab = 0;			break;
47 		case 'o':	if (++i == argc) usage();
48 				args = argv[i];
49 				break;
50 		case 'a':	all = 1; break;
51 		default:	usage();
52 		}
53 	} else {
54 		*ap++ = argv[i];
55 	}
56   }
57   *ap = NULL;
58   argc = (ap - argv);
59 
60   if (!all && (argc != 3 || *argv[1] == 0)) usage();
61   if (all == 1) {
62 	return mount_all();
63   }
64 
65   device = argv[1];
66   if (!strcmp(device, "none")) device = NULL;
67 
68   if ((type == NULL || !strcmp(type, MINIX_FS_TYPE)) && device != NULL) {
69 	/* auto-detect type and/or version */
70 	v = fsversion(device, "mount");
71 	switch (v) {
72 		case FSVERSION_MFS1:
73 		case FSVERSION_MFS2:
74 		case FSVERSION_MFS3: type = MINIX_FS_TYPE; break;
75 		case FSVERSION_EXT2: type = "ext2"; break;
76 		case FSVERSION_ISO9660: type = "isofs"; break;
77 	}
78   }
79 
80   if (minix_mount(device, argv[2], mountflags, srvflags, type, args) < 0) {
81 	err = strerror(errno);
82 	fprintf(stderr, "mount: Can't mount %s on %s: %s\n",
83 		argv[1], argv[2], err);
84 	return(EXIT_FAILURE);
85   }
86 
87   printf("%s is mounted on %s\n", argv[1], argv[2]);
88   return(EXIT_SUCCESS);
89 }
90 
list()91 void list()
92 {
93   int n;
94   char dev[PATH_MAX], mountpoint[PATH_MAX], type[MNTNAMELEN], flags[MNTFLAGLEN];
95 
96   /* Read and print /etc/mtab. */
97   n = load_mtab("mount");
98   if (n < 0) exit(1);
99 
100   while (1) {
101 	n = get_mtab_entry(dev, mountpoint, type, flags);
102 	if  (n < 0) break;
103 	printf("%s on %s type %s (%s)\n", dev, mountpoint, type, flags);
104   }
105   exit(0);
106 }
107 
108 int
has_opt(char * mntopts,char * option)109 has_opt(char *mntopts, char *option)
110 {
111 	char *optbuf, *opt;
112 	int found = 0;
113 
114 	optbuf = strdup(mntopts);
115 	for (opt = optbuf; (opt = strtok(opt, ",")) != NULL; opt = NULL) {
116 		if (!strcmp(opt, option)) found = 1;
117 	}
118 	free (optbuf);
119 	return(found);
120 }
121 
122 
123 int
mount_all()124 mount_all()
125 {
126 	struct fstab *fs;
127 	int ro, mountflags;
128 	char mountpoint[PATH_MAX];
129   	char *device, *err;
130 
131 	while ((fs = getfsent()) != NULL) {
132 		ro = 0;
133 		mountflags = 0;
134 		device = NULL;
135 		if (realpath(fs->fs_file, mountpoint) == NULL) {
136 			fprintf(stderr, "Can't mount on %s\n", fs->fs_file);
137 			return(EXIT_FAILURE);
138 		}
139 		if (has_opt(fs->fs_mntops, "noauto"))
140 			continue;
141 		if (!strcmp(mountpoint, "/"))
142 			continue; /* Not remounting root */
143 		if (has_opt(fs->fs_mntops, "ro"))
144 			ro = 1;
145 		if (ro) {
146 			mountflags |= MNT_RDONLY;
147 		}
148 
149 		device = fs->fs_spec;
150 		/* passing a null string for block special device means don't
151 		 * use a device at all and this is what we need to do for
152 		 * entries starting with "none"
153 		 */
154 		if (!strcmp(device, "none"))
155 			device = NULL;
156 
157 		if (minix_mount(device, mountpoint, mountflags, 0, fs->fs_vfstype,
158 		    fs->fs_mntops) != 0) {
159 			err = strerror(errno);
160 			fprintf(stderr, "mount: Can't mount %s on %s: %s\n",
161 				fs->fs_spec, fs->fs_file, err);
162 			return(EXIT_FAILURE);
163 		}
164 	}
165 	return(EXIT_SUCCESS);
166 }
167 
usage()168 void usage()
169 {
170   std_err("Usage: mount [-a] [-r] [-e] [-t type] [-o options] special name\n");
171   exit(1);
172 }
173