1433d6423SLionel Sambuc /* mount - mount a file system Author: Andy Tanenbaum */
2433d6423SLionel Sambuc
3433d6423SLionel Sambuc #include <errno.h>
4433d6423SLionel Sambuc #include <sys/types.h>
5433d6423SLionel Sambuc #include <stdlib.h>
6433d6423SLionel Sambuc #include <string.h>
7433d6423SLionel Sambuc #include <sys/mount.h>
8433d6423SLionel Sambuc #include <unistd.h>
9433d6423SLionel Sambuc #include <minix/minlib.h>
10433d6423SLionel Sambuc #include <stdio.h>
11433d6423SLionel Sambuc #include <fstab.h>
12433d6423SLionel Sambuc
13433d6423SLionel Sambuc #define MINIX_FS_TYPE "mfs"
14433d6423SLionel Sambuc
15433d6423SLionel Sambuc int main(int argc, char **argv);
16433d6423SLionel Sambuc void list(void);
17433d6423SLionel Sambuc void usage(void);
18433d6423SLionel Sambuc void update_mtab(char *dev, char *mountpoint, char *fstype, int mountflags);
19433d6423SLionel Sambuc int mount_all(void);
20433d6423SLionel Sambuc
21433d6423SLionel Sambuc static int write_mtab = 1;
22433d6423SLionel Sambuc
main(argc,argv)23433d6423SLionel Sambuc int main(argc, argv)
24433d6423SLionel Sambuc int argc;
25433d6423SLionel Sambuc char *argv[];
26433d6423SLionel Sambuc {
27433d6423SLionel Sambuc int all = 0, i, v = 0, mountflags, srvflags;
28433d6423SLionel Sambuc char **ap, *opt, *err, *type, *args, *device;
29433d6423SLionel Sambuc
30433d6423SLionel Sambuc if (argc == 1) list(); /* just list /etc/mtab */
31433d6423SLionel Sambuc mountflags = 0;
32433d6423SLionel Sambuc srvflags = 0;
33433d6423SLionel Sambuc type = NULL;
34433d6423SLionel Sambuc args = NULL;
35433d6423SLionel Sambuc ap = argv+1;
36433d6423SLionel Sambuc for (i = 1; i < argc; i++) {
37433d6423SLionel Sambuc if (argv[i][0] == '-') {
38433d6423SLionel Sambuc opt = argv[i]+1;
39433d6423SLionel Sambuc while (*opt != 0) switch (*opt++) {
40433d6423SLionel Sambuc case 'r': mountflags |= MNT_RDONLY; break;
41433d6423SLionel Sambuc case 't': if (++i == argc) usage();
42433d6423SLionel Sambuc type = argv[i];
43433d6423SLionel Sambuc break;
44433d6423SLionel Sambuc case 'i': srvflags |= MS_REUSE; break;
45433d6423SLionel Sambuc case 'e': srvflags |= MS_EXISTING; break;
46433d6423SLionel Sambuc case 'n': write_mtab = 0; break;
47433d6423SLionel Sambuc case 'o': if (++i == argc) usage();
48433d6423SLionel Sambuc args = argv[i];
49433d6423SLionel Sambuc break;
50433d6423SLionel Sambuc case 'a': all = 1; break;
51433d6423SLionel Sambuc default: usage();
52433d6423SLionel Sambuc }
53433d6423SLionel Sambuc } else {
54433d6423SLionel Sambuc *ap++ = argv[i];
55433d6423SLionel Sambuc }
56433d6423SLionel Sambuc }
57433d6423SLionel Sambuc *ap = NULL;
58433d6423SLionel Sambuc argc = (ap - argv);
59433d6423SLionel Sambuc
60433d6423SLionel Sambuc if (!all && (argc != 3 || *argv[1] == 0)) usage();
61433d6423SLionel Sambuc if (all == 1) {
62433d6423SLionel Sambuc return mount_all();
63433d6423SLionel Sambuc }
64433d6423SLionel Sambuc
65433d6423SLionel Sambuc device = argv[1];
66433d6423SLionel Sambuc if (!strcmp(device, "none")) device = NULL;
67433d6423SLionel Sambuc
68433d6423SLionel Sambuc if ((type == NULL || !strcmp(type, MINIX_FS_TYPE)) && device != NULL) {
69433d6423SLionel Sambuc /* auto-detect type and/or version */
70433d6423SLionel Sambuc v = fsversion(device, "mount");
71433d6423SLionel Sambuc switch (v) {
72433d6423SLionel Sambuc case FSVERSION_MFS1:
73433d6423SLionel Sambuc case FSVERSION_MFS2:
74433d6423SLionel Sambuc case FSVERSION_MFS3: type = MINIX_FS_TYPE; break;
75433d6423SLionel Sambuc case FSVERSION_EXT2: type = "ext2"; break;
76*69eead77SJean-Baptiste Boric case FSVERSION_ISO9660: type = "isofs"; break;
77433d6423SLionel Sambuc }
78433d6423SLionel Sambuc }
79433d6423SLionel Sambuc
80433d6423SLionel Sambuc if (minix_mount(device, argv[2], mountflags, srvflags, type, args) < 0) {
81433d6423SLionel Sambuc err = strerror(errno);
82433d6423SLionel Sambuc fprintf(stderr, "mount: Can't mount %s on %s: %s\n",
83433d6423SLionel Sambuc argv[1], argv[2], err);
84433d6423SLionel Sambuc return(EXIT_FAILURE);
85433d6423SLionel Sambuc }
86433d6423SLionel Sambuc
87433d6423SLionel Sambuc printf("%s is mounted on %s\n", argv[1], argv[2]);
88433d6423SLionel Sambuc return(EXIT_SUCCESS);
89433d6423SLionel Sambuc }
90433d6423SLionel Sambuc
list()91433d6423SLionel Sambuc void list()
92433d6423SLionel Sambuc {
93433d6423SLionel Sambuc int n;
94433d6423SLionel Sambuc char dev[PATH_MAX], mountpoint[PATH_MAX], type[MNTNAMELEN], flags[MNTFLAGLEN];
95433d6423SLionel Sambuc
96433d6423SLionel Sambuc /* Read and print /etc/mtab. */
97433d6423SLionel Sambuc n = load_mtab("mount");
98433d6423SLionel Sambuc if (n < 0) exit(1);
99433d6423SLionel Sambuc
100433d6423SLionel Sambuc while (1) {
101433d6423SLionel Sambuc n = get_mtab_entry(dev, mountpoint, type, flags);
102433d6423SLionel Sambuc if (n < 0) break;
103433d6423SLionel Sambuc printf("%s on %s type %s (%s)\n", dev, mountpoint, type, flags);
104433d6423SLionel Sambuc }
105433d6423SLionel Sambuc exit(0);
106433d6423SLionel Sambuc }
107433d6423SLionel Sambuc
108433d6423SLionel Sambuc int
has_opt(char * mntopts,char * option)109433d6423SLionel Sambuc has_opt(char *mntopts, char *option)
110433d6423SLionel Sambuc {
111433d6423SLionel Sambuc char *optbuf, *opt;
112433d6423SLionel Sambuc int found = 0;
113433d6423SLionel Sambuc
114433d6423SLionel Sambuc optbuf = strdup(mntopts);
115433d6423SLionel Sambuc for (opt = optbuf; (opt = strtok(opt, ",")) != NULL; opt = NULL) {
116433d6423SLionel Sambuc if (!strcmp(opt, option)) found = 1;
117433d6423SLionel Sambuc }
118433d6423SLionel Sambuc free (optbuf);
119433d6423SLionel Sambuc return(found);
120433d6423SLionel Sambuc }
121433d6423SLionel Sambuc
122433d6423SLionel Sambuc
123433d6423SLionel Sambuc int
mount_all()124433d6423SLionel Sambuc mount_all()
125433d6423SLionel Sambuc {
126433d6423SLionel Sambuc struct fstab *fs;
127433d6423SLionel Sambuc int ro, mountflags;
128433d6423SLionel Sambuc char mountpoint[PATH_MAX];
129433d6423SLionel Sambuc char *device, *err;
130433d6423SLionel Sambuc
131433d6423SLionel Sambuc while ((fs = getfsent()) != NULL) {
132433d6423SLionel Sambuc ro = 0;
133433d6423SLionel Sambuc mountflags = 0;
134433d6423SLionel Sambuc device = NULL;
135433d6423SLionel Sambuc if (realpath(fs->fs_file, mountpoint) == NULL) {
136433d6423SLionel Sambuc fprintf(stderr, "Can't mount on %s\n", fs->fs_file);
137433d6423SLionel Sambuc return(EXIT_FAILURE);
138433d6423SLionel Sambuc }
139433d6423SLionel Sambuc if (has_opt(fs->fs_mntops, "noauto"))
140433d6423SLionel Sambuc continue;
141433d6423SLionel Sambuc if (!strcmp(mountpoint, "/"))
142433d6423SLionel Sambuc continue; /* Not remounting root */
143433d6423SLionel Sambuc if (has_opt(fs->fs_mntops, "ro"))
144433d6423SLionel Sambuc ro = 1;
145433d6423SLionel Sambuc if (ro) {
146433d6423SLionel Sambuc mountflags |= MNT_RDONLY;
147433d6423SLionel Sambuc }
148433d6423SLionel Sambuc
149433d6423SLionel Sambuc device = fs->fs_spec;
150433d6423SLionel Sambuc /* passing a null string for block special device means don't
151433d6423SLionel Sambuc * use a device at all and this is what we need to do for
152433d6423SLionel Sambuc * entries starting with "none"
153433d6423SLionel Sambuc */
154433d6423SLionel Sambuc if (!strcmp(device, "none"))
155433d6423SLionel Sambuc device = NULL;
156433d6423SLionel Sambuc
157433d6423SLionel Sambuc if (minix_mount(device, mountpoint, mountflags, 0, fs->fs_vfstype,
158433d6423SLionel Sambuc fs->fs_mntops) != 0) {
159433d6423SLionel Sambuc err = strerror(errno);
160433d6423SLionel Sambuc fprintf(stderr, "mount: Can't mount %s on %s: %s\n",
161433d6423SLionel Sambuc fs->fs_spec, fs->fs_file, err);
162433d6423SLionel Sambuc return(EXIT_FAILURE);
163433d6423SLionel Sambuc }
164433d6423SLionel Sambuc }
165433d6423SLionel Sambuc return(EXIT_SUCCESS);
166433d6423SLionel Sambuc }
167433d6423SLionel Sambuc
usage()168433d6423SLionel Sambuc void usage()
169433d6423SLionel Sambuc {
170433d6423SLionel Sambuc std_err("Usage: mount [-a] [-r] [-e] [-t type] [-o options] special name\n");
171433d6423SLionel Sambuc exit(1);
172433d6423SLionel Sambuc }
173