110762Ssam #ifndef lint 2*16945Smckusick static char sccsid[] = "@(#)newfs.c 4.14 08/16/84"; 310762Ssam #endif 410762Ssam 510762Ssam /* 611069Ssam * newfs: friendly front end to mkfs 710762Ssam */ 810762Ssam #include <sys/param.h> 910762Ssam #include <sys/stat.h> 1010762Ssam #include <sys/fs.h> 1113603Ssam #include <sys/dir.h> 1210762Ssam 1310762Ssam #include <stdio.h> 1410762Ssam #include <disktab.h> 1510762Ssam 1611183Ssam #define BOOTDIR "/usr/mdec" /* directory for boot blocks */ 1711183Ssam 18*16945Smckusick int Nflag; /* run mkfs without writing file system */ 1910762Ssam int verbose; /* show mkfs line before exec */ 2012334Shelge int noboot; /* do not fill boot blocks */ 2110762Ssam int fssize; /* file system size */ 2210762Ssam int fsize; /* fragment size */ 2310762Ssam int bsize; /* block size */ 2410762Ssam int ntracks; /* # tracks/cylinder */ 2510762Ssam int nsectors; /* # sectors/track */ 2610762Ssam int sectorsize; /* bytes/sector */ 2710762Ssam int cpg; /* cylinders/cylinder group */ 2812334Shelge int minfree = -1; /* free space threshold */ 2911069Ssam int rpm; /* revolutions/minute of drive */ 3014884Smckusick int density; /* number of bytes per inode */ 3110762Ssam 3210762Ssam char *av[20]; /* argv array and buffers for exec */ 3310762Ssam char a2[20]; 3410762Ssam char a3[20]; 3510762Ssam char a4[20]; 3610762Ssam char a5[20]; 3710762Ssam char a6[20]; 3810762Ssam char a7[20]; 3911069Ssam char a8[20]; 4011069Ssam char a9[20]; 4114884Smckusick char a10[20]; 4210762Ssam char device[MAXPATHLEN]; 4310762Ssam char cmd[BUFSIZ]; 4410762Ssam 4510762Ssam char *index(); 4610762Ssam char *rindex(); 4710762Ssam char *sprintf(); 4810762Ssam 4910762Ssam main(argc, argv) 5014064Smckusick int argc; 5110762Ssam char *argv[]; 5210762Ssam { 5310762Ssam char *cp, *special; 5410762Ssam register struct disktab *dp; 5510762Ssam register struct partition *pp; 5610762Ssam struct stat st; 5710762Ssam register int i; 5810762Ssam int status; 5910762Ssam 6010762Ssam argc--, argv++; 6110762Ssam while (argc > 0 && argv[0][0] == '-') { 6210762Ssam for (cp = &argv[0][1]; *cp; cp++) 6310762Ssam switch (*cp) { 6410762Ssam 6510762Ssam case 'v': 6610762Ssam verbose++; 6710762Ssam break; 6810762Ssam 69*16945Smckusick case 'N': 70*16945Smckusick Nflag++; 71*16945Smckusick /* fall through to */ 72*16945Smckusick 7312334Shelge case 'n': 7412334Shelge noboot++; 7512334Shelge break; 7612334Shelge 7710762Ssam case 's': 7810762Ssam if (argc < 1) 7910762Ssam fatal("-s: missing file system size"); 8010762Ssam argc--, argv++; 8110762Ssam fssize = atoi(*argv); 8210762Ssam if (fssize < 0) 8310762Ssam fatal("%s: bad file system size", 8410762Ssam *argv); 8510762Ssam goto next; 8610762Ssam 8710762Ssam case 't': 8810762Ssam if (argc < 1) 8910762Ssam fatal("-t: missing track total"); 9010762Ssam argc--, argv++; 9110762Ssam ntracks = atoi(*argv); 9210762Ssam if (ntracks < 0) 9310762Ssam fatal("%s: bad total tracks", *argv); 9410762Ssam goto next; 9510762Ssam 9610762Ssam case 'b': 9710762Ssam if (argc < 1) 9810762Ssam fatal("-b: missing block size"); 9910762Ssam argc--, argv++; 10010762Ssam bsize = atoi(*argv); 10110762Ssam if (bsize < 0 || bsize < MINBSIZE) 10210762Ssam fatal("%s: bad block size", *argv); 10310762Ssam goto next; 10410762Ssam 10510762Ssam case 'f': 10610762Ssam if (argc < 1) 10710762Ssam fatal("-f: missing frag size"); 10810762Ssam argc--, argv++; 10910762Ssam fsize = atoi(*argv); 11010762Ssam if (fsize < 0) 11110762Ssam fatal("%s: bad frag size", *argv); 11210762Ssam goto next; 11310762Ssam 11410762Ssam case 'S': 11510762Ssam if (argc < 1) 11610762Ssam fatal("-S: missing sector size"); 11710762Ssam argc--, argv++; 11810762Ssam sectorsize = atoi(*argv); 11910762Ssam if (sectorsize < 0) 12010762Ssam fatal("%s: bad sector size", *argv); 12110762Ssam goto next; 12210762Ssam 12310762Ssam case 'c': 12410762Ssam if (argc < 1) 12510762Ssam fatal("-c: missing cylinders/group"); 12610762Ssam argc--, argv++; 12710762Ssam cpg = atoi(*argv); 12810762Ssam if (cpg < 0) 12910762Ssam fatal("%s: bad cylinders/group", *argv); 13010762Ssam goto next; 13110762Ssam 13211069Ssam case 'm': 13311069Ssam if (argc < 1) 13411069Ssam fatal("-m: missing free space %%\n"); 13511069Ssam argc--, argv++; 13611069Ssam minfree = atoi(*argv); 13711069Ssam if (minfree < 0 || minfree > 99) 13811069Ssam fatal("%s: bad free space %%\n", 13911069Ssam *argv); 14011069Ssam goto next; 14111069Ssam 14211069Ssam case 'r': 14311069Ssam if (argc < 1) 14411069Ssam fatal("-r: missing revs/minute\n"); 14511069Ssam argc--, argv++; 14611069Ssam rpm = atoi(*argv); 14711069Ssam if (rpm < 0) 14811069Ssam fatal("%s: bad revs/minute\n", *argv); 14911069Ssam goto next; 15011069Ssam 15114884Smckusick case 'i': 15214884Smckusick if (argc < 1) 15314884Smckusick fatal("-i: missing bytes per inode\n"); 15414884Smckusick argc--, argv++; 15514884Smckusick density = atoi(*argv); 15614884Smckusick if (density < 0) 15714884Smckusick fatal("%s: bad bytes per inode\n", 15814884Smckusick *argv); 15914884Smckusick goto next; 16014884Smckusick 16110762Ssam default: 16210762Ssam fatal("-%c: unknown flag", cp); 16310762Ssam } 16410762Ssam next: 16510762Ssam argc--, argv++; 16610762Ssam } 16710762Ssam if (argc < 2) { 16811069Ssam fprintf(stderr, "usage: newfs [ -v ] [ mkfs-options ] %s\n", 16910762Ssam "special-device device-type"); 17010762Ssam fprintf(stderr, "where mkfs-options are:\n"); 171*16945Smckusick fprintf(stderr, "\t-N do not create file system, %s\n", 172*16945Smckusick "just print out parameters"); 17311057Ssam fprintf(stderr, "\t-s file system size (sectors)\n"); 17411057Ssam fprintf(stderr, "\t-b block size\n"); 17511057Ssam fprintf(stderr, "\t-f frag size\n"); 17610873Ssam fprintf(stderr, "\t-t tracks/cylinder\n"); 17710873Ssam fprintf(stderr, "\t-c cylinders/group\n"); 17811069Ssam fprintf(stderr, "\t-m minimum free space %%\n"); 17911069Ssam fprintf(stderr, "\t-r revolutions/minute\n"); 18011057Ssam fprintf(stderr, "\t-S sector size\n"); 18114884Smckusick fprintf(stderr, "\t-i number of bytes per inode\n"); 18210762Ssam exit(1); 18310762Ssam } 18410762Ssam special = argv[0]; 18514064Smckusick cp = rindex(special, '/'); 18614064Smckusick if (cp != 0) 18714064Smckusick special = cp + 1; 18814321Ssam if (*special == 'r' && special[1] != 'a' && special[1] != 'b') 18914064Smckusick special++; 19014064Smckusick special = sprintf(device, "/dev/r%s", special); 19110762Ssam if (stat(special, &st) < 0) { 19211069Ssam fprintf(stderr, "newfs: "); perror(special); 19310762Ssam exit(2); 19410762Ssam } 19514064Smckusick if ((st.st_mode & S_IFMT) != S_IFCHR) 19614064Smckusick fatal("%s: not a character device", special); 19710762Ssam dp = getdiskbyname(argv[1]); 19810762Ssam if (dp == 0) 19910762Ssam fatal("%s: unknown disk type", argv[1]); 20010762Ssam cp = index(argv[0], '\0') - 1; 20110762Ssam if (cp == 0 || *cp < 'a' || *cp > 'h') 20210762Ssam fatal("%s: can't figure out file system partition", argv[0]); 20310762Ssam pp = &dp->d_partitions[*cp - 'a']; 20410762Ssam if (fssize == 0) { 20510762Ssam fssize = pp->p_size; 20610762Ssam if (fssize < 0) 20710762Ssam fatal("%s: no default size for `%c' partition", 20810762Ssam argv[1], *cp); 20910762Ssam } 21010762Ssam if (nsectors == 0) { 21110762Ssam nsectors = dp->d_nsectors; 21210762Ssam if (nsectors < 0) 21310762Ssam fatal("%s: no default #sectors/track", argv[1]); 21410762Ssam } 21510762Ssam if (ntracks == 0) { 21610762Ssam ntracks = dp->d_ntracks; 21710762Ssam if (ntracks < 0) 21810762Ssam fatal("%s: no default #tracks", argv[1]); 21910762Ssam } 22010762Ssam if (sectorsize == 0) { 22110762Ssam sectorsize = dp->d_secsize; 22210762Ssam if (sectorsize < 0) 22310762Ssam fatal("%s: no default sector size", argv[1]); 22410762Ssam } 22510762Ssam if (bsize == 0) { 22610762Ssam bsize = pp->p_bsize; 22710762Ssam if (bsize < 0) 22810762Ssam fatal("%s: no default block size for `%c' partition", 22910762Ssam argv[1], *cp); 23010762Ssam } 23110762Ssam if (fsize == 0) { 23210762Ssam fsize = pp->p_fsize; 23310762Ssam if (fsize < 0) 23410762Ssam fatal("%s: no default frag size for `%c' partition", 23510762Ssam argv[1], *cp); 23610762Ssam } 23711069Ssam if (rpm == 0) { 23811069Ssam rpm = dp->d_rpm; 23911069Ssam if (rpm < 0) 24011069Ssam fatal("%s: no default revolutions/minute value", 24111069Ssam argv[1]); 24211069Ssam } 24314884Smckusick if (density <= 0) 24414884Smckusick density = 2048; 24512334Shelge if (minfree < 0) 24611069Ssam minfree = 10; 24711069Ssam if (cpg == 0) 24811069Ssam cpg = 16; 24910762Ssam i = 0; 250*16945Smckusick if (Nflag) 251*16945Smckusick av[i++] = "-N"; 252*16945Smckusick av[i++] = special; 25310762Ssam av[i++] = sprintf(a2, "%d", fssize); 25410762Ssam av[i++] = sprintf(a3, "%d", nsectors); 25510762Ssam av[i++] = sprintf(a4, "%d", ntracks); 25610762Ssam av[i++] = sprintf(a5, "%d", bsize); 25710762Ssam av[i++] = sprintf(a6, "%d", fsize); 25811069Ssam av[i++] = sprintf(a7, "%d", cpg); 25911069Ssam av[i++] = sprintf(a8, "%d", minfree); 26011069Ssam av[i++] = sprintf(a9, "%d", rpm / 60); 26114884Smckusick av[i++] = sprintf(a10, "%d", density); 26210762Ssam av[i++] = 0; 263*16945Smckusick strcpy(cmd, "/etc/mkfs"); 26410762Ssam for (i = 0; av[i] != 0; i++) { 26510762Ssam strcat(cmd, " "); 26610762Ssam strcat(cmd, av[i]); 26710762Ssam } 26810762Ssam if (verbose) 26910762Ssam printf("%s\n", cmd); 27010762Ssam if (status = system(cmd)) 27116407Sralph exit(status >> 8); 27212334Shelge if (*cp == 'a' && !noboot) { 27310762Ssam char type[3]; 27413819Ssam struct stat sb; 27510762Ssam 27610762Ssam cp = rindex(special, '/'); 27710762Ssam if (cp == NULL) 27810762Ssam fatal("%s: can't figure out disk type from name", 27910762Ssam special); 28013819Ssam if (stat(special, &sb) >= 0 && (sb.st_mode & S_IFMT) == S_IFCHR) 28110873Ssam cp++; 28210762Ssam type[0] = *++cp; 28310762Ssam type[1] = *++cp; 28410762Ssam type[2] = '\0'; 28510762Ssam installboot(special, type); 28610762Ssam } 28710762Ssam exit(0); 28810762Ssam } 28910762Ssam 29010762Ssam installboot(dev, type) 29110762Ssam char *dev, *type; 29210762Ssam { 29310762Ssam int fd; 29410762Ssam char bootblock[MAXPATHLEN], standalonecode[MAXPATHLEN]; 29510762Ssam char bootimage[BBSIZE]; 29610762Ssam 29711183Ssam sprintf(bootblock, "%s/%sboot", BOOTDIR, type); 29811183Ssam sprintf(standalonecode, "%s/boot%s", BOOTDIR, type); 29910762Ssam if (verbose) { 30010762Ssam printf("installing boot code\n"); 30110762Ssam printf("sector 0 boot = %s\n", bootblock); 30210762Ssam printf("1st level boot = %s\n", standalonecode); 30310762Ssam } 30410762Ssam fd = open(bootblock, 0); 30510762Ssam if (fd < 0) { 30611069Ssam fprintf(stderr, "newfs: "); perror(bootblock); 30710762Ssam exit(1); 30810762Ssam } 30910762Ssam if (read(fd, bootimage, DEV_BSIZE) < 0) { 31011069Ssam fprintf(stderr, "newfs: "); perror(bootblock); 31110762Ssam exit(2); 31210762Ssam } 31310762Ssam close(fd); 31410762Ssam fd = open(standalonecode, 0); 31510762Ssam if (fd < 0) { 31611069Ssam fprintf(stderr, "newfs: "); perror(standalonecode); 31710762Ssam exit(1); 31810762Ssam } 31910762Ssam if (read(fd, &bootimage[DEV_BSIZE], BBSIZE - DEV_BSIZE) < 0) { 32011069Ssam fprintf(stderr, "newfs: "); perror(standalonecode); 32110762Ssam exit(2); 32210762Ssam } 32310762Ssam close(fd); 32410763Ssam fd = open(dev, 1); 32510762Ssam if (fd < 0) { 32611069Ssam fprintf(stderr, "newfs: "); perror(dev); 32710762Ssam exit(1); 32810762Ssam } 32910762Ssam if (write(fd, bootimage, BBSIZE) != BBSIZE) { 33011069Ssam fprintf(stderr, "newfs: "); perror(dev); 33110762Ssam exit(2); 33210762Ssam } 33310762Ssam close(fd); 33410762Ssam } 33510762Ssam 33610762Ssam /*VARARGS*/ 33710762Ssam fatal(fmt, arg1, arg2) 33810762Ssam char *fmt; 33910762Ssam { 34010762Ssam 34111069Ssam fprintf(stderr, "newfs: "); 34210762Ssam fprintf(stderr, fmt, arg1, arg2); 34310762Ssam putc('\n', stderr); 34410762Ssam exit(10); 34510762Ssam } 346