1 /* 2 * Copyright (c) 1980 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 */ 6 7 #ifndef lint 8 char copyright[] = 9 "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 10 All rights reserved.\n"; 11 #endif not lint 12 13 #ifndef lint 14 static char sccsid[] = "@(#)mount.c 5.8 (Berkeley) 06/28/89"; 15 #endif not lint 16 17 #include <sys/param.h> 18 #include <sys/file.h> 19 #include <sys/mount.h> 20 #include <fstab.h> 21 #include <mtab.h> 22 #include <errno.h> 23 #include <stdio.h> 24 25 #define BADTYPE(type) \ 26 (strcmp(type, FSTAB_RO) && strcmp(type, FSTAB_RW) && \ 27 strcmp(type, FSTAB_RQ)) 28 #define SETTYPE(type) \ 29 (!strcmp(type, FSTAB_RW) || !strcmp(type, FSTAB_RQ)) 30 31 #define MTAB "/etc/mtab" 32 33 static struct mtab mtab[NMOUNT]; 34 static int fake, verbose; 35 36 main(argc, argv) 37 int argc; 38 char **argv; 39 { 40 extern char *optarg; 41 extern int optind; 42 register struct mtab *mp; 43 register struct fstab *fs; 44 register int cnt; 45 int all, ch, fd, rval, sfake; 46 char *type; 47 48 all = 0; 49 type = NULL; 50 while ((ch = getopt(argc, argv, "afrwv")) != EOF) 51 switch((char)ch) { 52 case 'a': 53 all = 1; 54 break; 55 case 'f': 56 fake = 1; 57 break; 58 case 'r': 59 type = FSTAB_RO; 60 break; 61 case 'v': 62 verbose = 1; 63 break; 64 case 'w': 65 type = FSTAB_RW; 66 break; 67 case '?': 68 default: 69 usage(); 70 } 71 argc -= optind; 72 argv += optind; 73 74 /* NOSTRICT */ 75 if ((fd = open(MTAB, O_RDONLY, 0)) >= 0) { 76 if (read(fd, (char *)mtab, NMOUNT * sizeof(struct mtab)) < 0) 77 mtaberr(); 78 (void)close(fd); 79 } 80 81 if (all) { 82 rval = 0; 83 for (sfake = fake; fs = getfsent(); fake = sfake) { 84 if (BADTYPE(fs->fs_type)) 85 continue; 86 /* `/' is special, it's always mounted */ 87 if (!strcmp(fs->fs_file, "/")) 88 fake = 1; 89 rval |= mountfs(fs->fs_spec, fs->fs_file, 90 type ? type : fs->fs_type); 91 } 92 exit(rval); 93 } 94 95 if (argc == 0) { 96 if (verbose || fake || type) 97 usage(); 98 for (mp = mtab, cnt = NMOUNT; cnt--; ++mp) 99 if (*mp->m_path) 100 prmtab(mp); 101 exit(0); 102 } 103 104 if (all) 105 usage(); 106 107 if (argc == 1) { 108 if (!(fs = getfsfile(*argv)) && !(fs = getfsspec(*argv))) { 109 fprintf(stderr, 110 "mount: unknown special file or file system %s.\n", 111 *argv); 112 exit(1); 113 } 114 if (BADTYPE(fs->fs_type)) { 115 fprintf(stderr, 116 "mount: %s has unknown file system type.\n", *argv); 117 exit(1); 118 } 119 exit(mountfs(fs->fs_spec, fs->fs_file, 120 type ? type : fs->fs_type)); 121 } 122 123 if (argc != 2) 124 usage(); 125 126 exit(mountfs(argv[0], argv[1], type ? type : "rw")); 127 } 128 129 static 130 mountfs(spec, name, type) 131 char *spec, *name, *type; 132 { 133 extern int errno; 134 register struct mtab *mp, *space; 135 register int cnt; 136 register char *p; 137 int fd, flags; 138 struct ufs_args args; 139 char *index(), *rindex(), *strcpy(); 140 141 if (!fake) { 142 flags = 0; 143 if (!strcmp(type, FSTAB_RO)) 144 flags |= M_RDONLY; 145 args.fspec = spec; 146 if (mount(MOUNT_UFS, name, flags, &args)) { 147 fprintf(stderr, "%s on %s: ", spec, name); 148 switch (errno) { 149 case EMFILE: 150 fprintf(stderr, "Mount table full\n"); 151 break; 152 case EINVAL: 153 fprintf(stderr, "Bogus super block\n"); 154 break; 155 default: 156 perror((char *)NULL); 157 break; 158 } 159 return(1); 160 } 161 162 /* we don't do quotas.... */ 163 if (strcmp(type, FSTAB_RQ) == 0) 164 type = FSTAB_RW; 165 } 166 167 /* trim trailing /'s and find last component of name */ 168 for (p = index(spec, '\0'); *--p == '/';); 169 *++p = '\0'; 170 if (p = rindex(spec, '/')) { 171 *p = '\0'; 172 spec = p + 1; 173 } 174 175 for (mp = mtab, cnt = NMOUNT, space = NULL; cnt--; ++mp) { 176 if (!strcmp(mp->m_dname, spec)) 177 break; 178 if (!space && !*mp->m_path) 179 space = mp; 180 } 181 if (cnt == -1) { 182 if (!space) { 183 fprintf(stderr, "mount: no more room in %s.\n", MTAB); 184 exit(1); 185 } 186 mp = space; 187 } 188 189 #define DNMAX (sizeof(mtab[0].m_dname) - 1) 190 #define PNMAX (sizeof(mtab[0].m_path) - 1) 191 192 (void)strncpy(mp->m_dname, spec, DNMAX); 193 mp->m_dname[DNMAX] = '\0'; 194 (void)strncpy(mp->m_path, name, PNMAX); 195 mp->m_path[PNMAX] = '\0'; 196 (void)strcpy(mp->m_type, type); 197 198 if (verbose) 199 prmtab(mp); 200 201 for (mp = mtab + NMOUNT - 1; mp > mtab && !*mp->m_path; --mp); 202 if ((fd = open(MTAB, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) 203 mtaberr(); 204 cnt = (mp - mtab + 1) * sizeof(struct mtab); 205 /* NOSTRICT */ 206 if (write(fd, (char *)mtab, cnt) != cnt) 207 mtaberr(); 208 (void)close(fd); 209 return(0); 210 } 211 212 static 213 prmtab(mp) 214 register struct mtab *mp; 215 { 216 printf("%s on %s", mp->m_dname, mp->m_path); 217 if (!strcmp(mp->m_type, FSTAB_RO)) 218 printf("\t(read-only)"); 219 else if (!strcmp(mp->m_type, FSTAB_RQ)) 220 printf("\t(with quotas)"); 221 printf("\n"); 222 } 223 224 static 225 mtaberr() 226 { 227 fprintf(stderr, "mount: %s: ", MTAB); 228 perror((char *)NULL); 229 exit(1); 230 } 231 232 static 233 usage() 234 { 235 fprintf(stderr, "usage: mount [-afrw]\nor mount [-frw] special | node\nor mount [-frw] special node\n"); 236 exit(1); 237 } 238