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