1: /* 2: * Copyright (c) 1983 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) 1983 Regents of the University of California.\n\ 10: All rights reserved.\n"; 11: #endif not lint 12: 13: #ifndef lint 14: static char sccsid[] = "@(#)newfs.c 5.2 (Berkeley) 9/11/85"; 15: #endif not lint 16: 17: /* 18: * newfs: friendly front end to mkfs 19: */ 20: #include <sys/param.h> 21: #include <sys/stat.h> 22: #include <sys/fs.h> 23: #include <sys/dir.h> 24: 25: #include <stdio.h> 26: #include <disktab.h> 27: 28: #define BOOTDIR "/usr/mdec" /* directory for boot blocks */ 29: 30: int Nflag; /* run mkfs without writing file system */ 31: int verbose; /* show mkfs line before exec */ 32: int noboot; /* do not fill boot blocks */ 33: int fssize; /* file system size */ 34: int fsize; /* fragment size */ 35: int bsize; /* block size */ 36: int ntracks; /* # tracks/cylinder */ 37: int nsectors; /* # sectors/track */ 38: int sectorsize; /* bytes/sector */ 39: int cpg; /* cylinders/cylinder group */ 40: int minfree = -1; /* free space threshold */ 41: int opt; /* optimization preference (space or time) */ 42: int rpm; /* revolutions/minute of drive */ 43: int density; /* number of bytes per inode */ 44: 45: char *av[20]; /* argv array and buffers for exec */ 46: char a2[20]; 47: char a3[20]; 48: char a4[20]; 49: char a5[20]; 50: char a6[20]; 51: char a7[20]; 52: char a8[20]; 53: char a9[20]; 54: char a10[20]; 55: char device[MAXPATHLEN]; 56: char cmd[BUFSIZ]; 57: 58: char *index(); 59: char *rindex(); 60: char *sprintf(); 61: 62: main(argc, argv) 63: int argc; 64: char *argv[]; 65: { 66: char *cp, *special; 67: register struct disktab *dp; 68: register struct partition *pp; 69: struct stat st; 70: register int i; 71: int status; 72: 73: argc--, argv++; 74: while (argc > 0 && argv[0][0] == '-') { 75: for (cp = &argv[0][1]; *cp; cp++) 76: switch (*cp) { 77: 78: case 'v': 79: verbose++; 80: break; 81: 82: case 'N': 83: Nflag++; 84: /* fall through to */ 85: 86: case 'n': 87: noboot++; 88: break; 89: 90: case 's': 91: if (argc < 1) 92: fatal("-s: missing file system size"); 93: argc--, argv++; 94: fssize = atoi(*argv); 95: if (fssize < 0) 96: fatal("%s: bad file system size", 97: *argv); 98: goto next; 99: 100: case 't': 101: if (argc < 1) 102: fatal("-t: missing track total"); 103: argc--, argv++; 104: ntracks = atoi(*argv); 105: if (ntracks < 0) 106: fatal("%s: bad total tracks", *argv); 107: goto next; 108: 109: case 'o': 110: if (argc < 1) 111: fatal("-o: missing optimization preference"); 112: argc--, argv++; 113: if (strcmp(*argv, "space") == 0) 114: opt = FS_OPTSPACE; 115: else if (strcmp(*argv, "time") == 0) 116: opt = FS_OPTTIME; 117: else 118: fatal("%s: bad optimization preference %s", 119: *argv, 120: "(options are `space' or `time')"); 121: goto next; 122: 123: case 'b': 124: if (argc < 1) 125: fatal("-b: missing block size"); 126: argc--, argv++; 127: bsize = atoi(*argv); 128: if (bsize < 0 || bsize < MINBSIZE) 129: fatal("%s: bad block size", *argv); 130: goto next; 131: 132: case 'f': 133: if (argc < 1) 134: fatal("-f: missing frag size"); 135: argc--, argv++; 136: fsize = atoi(*argv); 137: if (fsize < 0) 138: fatal("%s: bad frag size", *argv); 139: goto next; 140: 141: case 'S': 142: if (argc < 1) 143: fatal("-S: missing sector size"); 144: argc--, argv++; 145: sectorsize = atoi(*argv); 146: if (sectorsize < 0) 147: fatal("%s: bad sector size", *argv); 148: goto next; 149: 150: case 'c': 151: if (argc < 1) 152: fatal("-c: missing cylinders/group"); 153: argc--, argv++; 154: cpg = atoi(*argv); 155: if (cpg < 0) 156: fatal("%s: bad cylinders/group", *argv); 157: goto next; 158: 159: case 'm': 160: if (argc < 1) 161: fatal("-m: missing free space %%\n"); 162: argc--, argv++; 163: minfree = atoi(*argv); 164: if (minfree < 0 || minfree > 99) 165: fatal("%s: bad free space %%\n", 166: *argv); 167: goto next; 168: 169: case 'r': 170: if (argc < 1) 171: fatal("-r: missing revs/minute\n"); 172: argc--, argv++; 173: rpm = atoi(*argv); 174: if (rpm < 0) 175: fatal("%s: bad revs/minute\n", *argv); 176: goto next; 177: 178: case 'i': 179: if (argc < 1) 180: fatal("-i: missing bytes per inode\n"); 181: argc--, argv++; 182: density = atoi(*argv); 183: if (density < 0) 184: fatal("%s: bad bytes per inode\n", 185: *argv); 186: goto next; 187: 188: default: 189: fatal("-%c: unknown flag", cp); 190: } 191: next: 192: argc--, argv++; 193: } 194: if (argc < 2) { 195: fprintf(stderr, "usage: newfs [ -v ] [ mkfs-options ] %s\n", 196: "special-device device-type"); 197: fprintf(stderr, "where mkfs-options are:\n"); 198: fprintf(stderr, "\t-N do not create file system, %s\n", 199: "just print out parameters"); 200: fprintf(stderr, "\t-s file system size (sectors)\n"); 201: fprintf(stderr, "\t-b block size\n"); 202: fprintf(stderr, "\t-f frag size\n"); 203: fprintf(stderr, "\t-t tracks/cylinder\n"); 204: fprintf(stderr, "\t-c cylinders/group\n"); 205: fprintf(stderr, "\t-m minimum free space %%\n"); 206: fprintf(stderr, "\t-o optimization preference %s\n", 207: "(`space' or `time')"); 208: fprintf(stderr, "\t-r revolutions/minute\n"); 209: fprintf(stderr, "\t-S sector size\n"); 210: fprintf(stderr, "\t-i number of bytes per inode\n"); 211: exit(1); 212: } 213: special = argv[0]; 214: cp = rindex(special, '/'); 215: if (cp != 0) 216: special = cp + 1; 217: if (*special == 'r' && special[1] != 'a' && special[1] != 'b') 218: special++; 219: special = sprintf(device, "/dev/r%s", special); 220: if (stat(special, &st) < 0) { 221: fprintf(stderr, "newfs: "); perror(special); 222: exit(2); 223: } 224: if ((st.st_mode & S_IFMT) != S_IFCHR) 225: fatal("%s: not a character device", special); 226: dp = getdiskbyname(argv[1]); 227: if (dp == 0) 228: fatal("%s: unknown disk type", argv[1]); 229: cp = index(argv[0], '\0') - 1; 230: if (cp == 0 || *cp < 'a' || *cp > 'h') 231: fatal("%s: can't figure out file system partition", argv[0]); 232: pp = &dp->d_partitions[*cp - 'a']; 233: if (fssize == 0) { 234: fssize = pp->p_size; 235: if (fssize < 0) 236: fatal("%s: no default size for `%c' partition", 237: argv[1], *cp); 238: } 239: if (nsectors == 0) { 240: nsectors = dp->d_nsectors; 241: if (nsectors < 0) 242: fatal("%s: no default #sectors/track", argv[1]); 243: } 244: if (ntracks == 0) { 245: ntracks = dp->d_ntracks; 246: if (ntracks < 0) 247: fatal("%s: no default #tracks", argv[1]); 248: } 249: if (sectorsize == 0) { 250: sectorsize = dp->d_secsize; 251: if (sectorsize < 0) 252: fatal("%s: no default sector size", argv[1]); 253: } 254: if (bsize == 0) { 255: bsize = pp->p_bsize; 256: if (bsize < 0) 257: fatal("%s: no default block size for `%c' partition", 258: argv[1], *cp); 259: } 260: if (fsize == 0) { 261: fsize = pp->p_fsize; 262: if (fsize < 0) 263: fatal("%s: no default frag size for `%c' partition", 264: argv[1], *cp); 265: } 266: if (rpm == 0) { 267: rpm = dp->d_rpm; 268: if (rpm < 0) 269: fatal("%s: no default revolutions/minute value", 270: argv[1]); 271: } 272: if (density <= 0) 273: density = 2048; 274: if (minfree < 0) 275: minfree = 10; 276: if (minfree < 10 && opt != FS_OPTSPACE) { 277: fprintf(stderr, "setting optimization for space "); 278: fprintf(stderr, "with minfree less than 10%\n"); 279: opt = FS_OPTSPACE; 280: } 281: if (cpg == 0) 282: cpg = 16; 283: i = 0; 284: if (Nflag) 285: av[i++] = "-N"; 286: av[i++] = special; 287: av[i++] = sprintf(a2, "%d", fssize); 288: av[i++] = sprintf(a3, "%d", nsectors); 289: av[i++] = sprintf(a4, "%d", ntracks); 290: av[i++] = sprintf(a5, "%d", bsize); 291: av[i++] = sprintf(a6, "%d", fsize); 292: av[i++] = sprintf(a7, "%d", cpg); 293: av[i++] = sprintf(a8, "%d", minfree); 294: av[i++] = sprintf(a9, "%d", rpm / 60); 295: av[i++] = sprintf(a10, "%d", density); 296: av[i++] = opt == FS_OPTSPACE ? "s" : "t"; 297: av[i++] = 0; 298: strcpy(cmd, "/etc/mkfs"); 299: for (i = 0; av[i] != 0; i++) { 300: strcat(cmd, " "); 301: strcat(cmd, av[i]); 302: } 303: if (verbose) 304: printf("%s\n", cmd); 305: if (status = system(cmd)) 306: exit(status >> 8); 307: if (*cp == 'a' && !noboot) { 308: char type[3]; 309: struct stat sb; 310: 311: cp = rindex(special, '/'); 312: if (cp == NULL) 313: fatal("%s: can't figure out disk type from name", 314: special); 315: if (stat(special, &sb) >= 0 && (sb.st_mode & S_IFMT) == S_IFCHR) 316: cp++; 317: type[0] = *++cp; 318: type[1] = *++cp; 319: type[2] = '\0'; 320: installboot(special, type); 321: } 322: exit(0); 323: } 324: 325: installboot(dev, type) 326: char *dev, *type; 327: { 328: int fd; 329: char bootblock[MAXPATHLEN], standalonecode[MAXPATHLEN]; 330: char bootimage[BBSIZE]; 331: 332: sprintf(bootblock, "%s/%sboot", BOOTDIR, type); 333: sprintf(standalonecode, "%s/boot%s", BOOTDIR, type); 334: if (verbose) { 335: printf("installing boot code\n"); 336: printf("sector 0 boot = %s\n", bootblock); 337: printf("1st level boot = %s\n", standalonecode); 338: } 339: fd = open(bootblock, 0); 340: if (fd < 0) { 341: fprintf(stderr, "newfs: "); perror(bootblock); 342: exit(1); 343: } 344: if (read(fd, bootimage, DEV_BSIZE) < 0) { 345: fprintf(stderr, "newfs: "); perror(bootblock); 346: exit(2); 347: } 348: close(fd); 349: fd = open(standalonecode, 0); 350: if (fd < 0) { 351: fprintf(stderr, "newfs: "); perror(standalonecode); 352: exit(1); 353: } 354: if (read(fd, &bootimage[DEV_BSIZE], BBSIZE - DEV_BSIZE) < 0) { 355: fprintf(stderr, "newfs: "); perror(standalonecode); 356: exit(2); 357: } 358: close(fd); 359: fd = open(dev, 1); 360: if (fd < 0) { 361: fprintf(stderr, "newfs: "); perror(dev); 362: exit(1); 363: } 364: if (write(fd, bootimage, BBSIZE) != BBSIZE) { 365: fprintf(stderr, "newfs: "); perror(dev); 366: exit(2); 367: } 368: close(fd); 369: } 370: 371: /*VARARGS*/ 372: fatal(fmt, arg1, arg2) 373: char *fmt; 374: { 375: 376: fprintf(stderr, "newfs: "); 377: fprintf(stderr, fmt, arg1, arg2); 378: putc('\n', stderr); 379: exit(10); 380: }