|
|
1.1 ! root 1: /* ! 2: * Mount a filesystem ! 3: */ ! 4: ! 5: char helpmessage[] = "\ ! 6: \ ! 7: mount -- mount file system\n\ ! 8: Usage: /etc/mount [ special directory [-fru] ]\n\ ! 9: Options:\n\ ! 10: -r Mount is read only\n\ ! 11: -u No mount, just update '/etc/mnttab' and/or '/etc/mtab'\n\ ! 12: The file system residing on the block special file 'special' becomes\n\ ! 13: accessible through the pathname 'directory'.\n\ ! 14: With no arguments, lists the currently mount file systems.\n\ ! 15: If /etc/mtab appears out of date, due to reboot, the fact is noted.\n\ ! 16: If /etc/mnttab is present, then the dates of mounting will be reported.\n\ ! 17: \ ! 18: "; ! 19: ! 20: #include <stdio.h> ! 21: #include <mtab.h> ! 22: #include <mnttab.h> ! 23: #include <sys/mount.h> ! 24: #include <errno.h> ! 25: #include <sys/filsys.h> ! 26: #include <canon.h> ! 27: #include <sys/stat.h> ! 28: #include <sys/timeb.h> ! 29: ! 30: int uflag; /* Update mount table only */ ! 31: int rflag; /* Read-only mount */ ! 32: int qmtab; /* Mtab is out of date */ ! 33: char mtabf[] = "/etc/mtab"; ! 34: char mnttabf[] = "/etc/mnttab"; /* System 5 style */ ! 35: struct mtab mtab; ! 36: struct mnttab mnttab; ! 37: struct stat sbuf; ! 38: char mspec[MNAMSIZ]; ! 39: extern FILE *getmtab(); ! 40: extern FILE *getmnttab(); ! 41: char *ctime(); ! 42: ! 43: main(argc, argv) ! 44: char *argv[]; ! 45: { ! 46: if (argc == 1) ! 47: mlist(); ! 48: else { ! 49: if (argc==4 && *argv[3]=='-') { ! 50: getflags(argv[3]+1); ! 51: argc -= 1; ! 52: } ! 53: if (argc==3) { ! 54: domount(argv[1], argv[2], rflag); ! 55: } else ! 56: usage(); ! 57: } ! 58: return (0); ! 59: } ! 60: ! 61: getflags(ap) ! 62: register char *ap; ! 63: { ! 64: register int c; ! 65: ! 66: while ((c = *ap++) != '\0') ! 67: switch (c) { ! 68: case 'r': ! 69: rflag = MFRON; ! 70: continue; ! 71: ! 72: case 'u': ! 73: uflag++; ! 74: continue; ! 75: ! 76: default: ! 77: usage(); ! 78: } ! 79: } ! 80: ! 81: usage() ! 82: { ! 83: fprintf(stderr, helpmessage); ! 84: exit(1); ! 85: } ! 86: ! 87: merror(f) ! 88: char *f; ! 89: { ! 90: register int err; ! 91: ! 92: err = errno; ! 93: fprintf(stderr, "mount: %r", &f); ! 94: if (err == EBUSY) ! 95: fprintf(stderr, ": mount device or directory busy\n"); ! 96: else if (err > 0 && err < sys_nerr) ! 97: fprintf(stderr, ": %s\n", sys_errlist[err]); ! 98: else ! 99: fprintf(stderr, ": unrecognized error\n"); ! 100: exit(1); ! 101: } ! 102: ! 103: domount(special, name, flag) ! 104: char *special; ! 105: char *name; ! 106: int flag; ! 107: { ! 108: register FILE *fp; ! 109: register int openerr; ! 110: extern time_t time(); ! 111: ! 112: chkname(name); ! 113: if (!uflag) { ! 114: chkspec(special); ! 115: if (mount(special, name, flag) != 0) ! 116: merror("%s on %s", special, name); ! 117: } ! 118: if ((fp = getmnttab()) == NULL) { ! 119: openerr |= 1; ! 120: } else { ! 121: mcopy(special, mspec); ! 122: while (fread(&mnttab, sizeof(mnttab), 1, fp) == 1) { ! 123: if (mnttab.mt_dev[0] == '\0' ! 124: || strncmp(mnttab.mt_filsys, mspec, MNTNSIZ) == 0) { ! 125: fseek(fp, (long)(-sizeof(mnttab)), 1); ! 126: break; ! 127: } ! 128: } ! 129: strncpy(mnttab.mt_dev, name, MNTNSIZ); ! 130: strncpy(mnttab.mt_filsys, mspec, MNTNSIZ); ! 131: mnttab.mt_ro_flg = flag; ! 132: mnttab.mt_time = time(NULL); ! 133: if (fwrite(&mnttab, sizeof(mnttab), 1, fp) != 1) ! 134: merror("writing %s", mnttabf); ! 135: fclose(fp); ! 136: } ! 137: if ((fp = getmtab()) == NULL) { ! 138: openerr |= 2; ! 139: } else { ! 140: mcopy(special, mspec); ! 141: while (fread(&mtab, sizeof(mtab), 1, fp) == 1) { ! 142: if (mtab.mt_name[0] == '\0' ! 143: || strncmp(mtab.mt_special, mspec, MNAMSIZ) == 0) { ! 144: fseek(fp, (long)(-sizeof(mtab)), 1); ! 145: break; ! 146: } ! 147: } ! 148: strncpy(mtab.mt_name, name, MNAMSIZ); ! 149: strncpy(mtab.mt_special, mspec, MNAMSIZ); ! 150: mtab.mt_flags = flag; ! 151: if (fwrite(&mtab, sizeof(mtab), 1, fp) != 1) ! 152: merror("writing %s", mtabf); ! 153: fclose(fp); ! 154: } ! 155: if (openerr == 3 && uflag) ! 156: merror("could not open %s or %s", mnttabf, mtabf); ! 157: } ! 158: ! 159: mlist() ! 160: { ! 161: register FILE *fp; ! 162: ! 163: if ((fp = getmnttab()) != NULL) { ! 164: while (fread(&mnttab, sizeof(mnttab), 1, fp) == 1) ! 165: if (*mnttab.mt_dev != '\0') { ! 166: printf("/dev/%.*s on %.*s", MNTNSIZ, ! 167: mnttab.mt_filsys, MNTNSIZ, mnttab.mt_dev); ! 168: if (mnttab.mt_ro_flg & MFRON) ! 169: printf(" (read only)"); ! 170: else ! 171: printf(" (writeable)"); ! 172: printf(" since %s", ctime(&mnttab.mt_time)); ! 173: } ! 174: return; ! 175: } ! 176: if ((fp = getmtab()) != NULL) { ! 177: if (qmtab) ! 178: fprintf(stderr, ! 179: "mount: /etc/mtab older than /etc/boottime\n"); ! 180: while (fread(&mtab, sizeof(mtab), 1, fp) == 1) ! 181: if (*mtab.mt_name != '\0') { ! 182: printf("/dev/%.*s on %.*s", MNAMSIZ, ! 183: mtab.mt_special, MNAMSIZ, mtab.mt_name); ! 184: if (mtab.mt_flags & MFRON) ! 185: printf(" (read only)"); ! 186: printf("\n"); ! 187: } ! 188: } ! 189: } ! 190: ! 191: FILE * ! 192: getmnttab() ! 193: { ! 194: return (fopen(mnttabf, "r+w")); ! 195: } ! 196: ! 197: FILE * ! 198: getmtab() ! 199: { ! 200: time_t boottime; ! 201: ! 202: if (stat("/etc/boottime", &sbuf) != 0) ! 203: boottime = (time_t)0; ! 204: else ! 205: boottime = sbuf.st_mtime; ! 206: if (stat(mtabf, &sbuf) != 0) ! 207: return (NULL); ! 208: if (sbuf.st_mtime < boottime) ! 209: qmtab = 1; ! 210: return (fopen(mtabf, "r+w")); ! 211: } ! 212: ! 213: chkname(name) ! 214: char *name; ! 215: { ! 216: if (stat(name, &sbuf) < 0) ! 217: merror("%s", name); ! 218: if ((sbuf.st_mode&S_IFMT) != S_IFDIR) { ! 219: errno = ENOTDIR; ! 220: merror("%s", name); ! 221: } ! 222: } ! 223: ! 224: chkspec(special) ! 225: char *special; ! 226: { ! 227: register FILE *fp; ! 228: struct filsys f; ! 229: ! 230: if (stat(special, &sbuf) < 0) ! 231: merror("%s", special); ! 232: if ((sbuf.st_mode&S_IFMT) != S_IFBLK) { ! 233: errno = ENOTBLK; ! 234: merror("%s", special); ! 235: } ! 236: if ((fp = fopen(special, "r")) == NULL) ! 237: merror("opening %s", special); ! 238: fseek(fp, (long)SUPERI*BSIZE, 0); ! 239: if (fread(&f, sizeof(f), 1, fp) != 1) ! 240: merror("%s", special); ! 241: canf(&f); ! 242: if ( ! tstf(&f)) { ! 243: fprintf(stderr, ! 244: "mount: %s: badly formed file system\n", special); ! 245: exit(1); ! 246: } ! 247: } ! 248: ! 249: canf(fp) ! 250: register struct filsys *fp; ! 251: { ! 252: register daddr_t *dp; ! 253: register ino_t *ip; ! 254: ! 255: canshort(fp->s_isize); ! 256: candaddr(fp->s_fsize); ! 257: canshort(fp->s_nfree); ! 258: for (dp = &fp->s_free[0]; dp < &fp->s_free[NICFREE]; dp += 1) ! 259: candaddr(*dp); ! 260: canshort(fp->s_ninode); ! 261: for (ip = &fp->s_inode[0]; ip < &fp->s_inode[NICINOD]; ip += 1) ! 262: canino(*ip); ! 263: candaddr(fp->s_tfree); ! 264: canino(fp->s_tinode); ! 265: } ! 266: ! 267: tstf(fp) ! 268: register struct filsys *fp; ! 269: { ! 270: register daddr_t *dp; ! 271: register ino_t *ip; ! 272: register ino_t maxinode; ! 273: ! 274: maxinode = (fp->s_isize - INODEI) * INOPB + 1; ! 275: if (fp->s_isize >= fp->s_fsize) ! 276: return (0); ! 277: if (fp->s_tfree < fp->s_nfree ! 278: || fp->s_tfree >= fp->s_fsize - fp->s_isize + 1) ! 279: return (0); ! 280: if (fp->s_tinode < fp->s_ninode ! 281: || fp->s_tinode >= maxinode-1) ! 282: return (0); ! 283: for (dp = &fp->s_free[0]; dp < &fp->s_free[fp->s_nfree]; dp += 1) ! 284: if (*dp < fp->s_isize || *dp >= fp->s_fsize) ! 285: return (0); ! 286: for (ip = &fp->s_inode[0]; ip < &fp->s_inode[fp->s_ninode]; ip += 1) ! 287: if (*ip < 1 || *ip > maxinode) ! 288: return (0); ! 289: return (1); ! 290: } ! 291: ! 292: /* ! 293: * Copy special pathname (stripped of ! 294: * leading directories) into a fixed ! 295: * size buffer. ! 296: */ ! 297: mcopy(ms, buf) ! 298: char *ms, *buf; ! 299: { ! 300: register char *p1, *p2; ! 301: ! 302: for (p1=p2=ms; *p1 != '\0'; ) ! 303: if (*p1++ == '/') ! 304: p2 = p1; ! 305: p1 = buf; ! 306: while (*p1++ = *p2++) ! 307: ; ! 308: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.