1*21159Sdist /* 2*21159Sdist * Copyright (c) 1983 Regents of the University of California. 3*21159Sdist * All rights reserved. The Berkeley software License Agreement 4*21159Sdist * specifies the terms and conditions for redistribution. 5*21159Sdist */ 6*21159Sdist 710762Ssam #ifndef lint 8*21159Sdist char copyright[] = 9*21159Sdist "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 10*21159Sdist All rights reserved.\n"; 11*21159Sdist #endif not lint 1210762Ssam 13*21159Sdist #ifndef lint 14*21159Sdist static char sccsid[] = "@(#)newfs.c 5.1 (Berkeley) 05/28/85"; 15*21159Sdist #endif not lint 16*21159Sdist 1710762Ssam /* 1811069Ssam * newfs: friendly front end to mkfs 1910762Ssam */ 2010762Ssam #include <sys/param.h> 2110762Ssam #include <sys/stat.h> 2210762Ssam #include <sys/fs.h> 2313603Ssam #include <sys/dir.h> 2410762Ssam 2510762Ssam #include <stdio.h> 2610762Ssam #include <disktab.h> 2710762Ssam 2811183Ssam #define BOOTDIR "/usr/mdec" /* directory for boot blocks */ 2911183Ssam 3016945Smckusick int Nflag; /* run mkfs without writing file system */ 3110762Ssam int verbose; /* show mkfs line before exec */ 3212334Shelge int noboot; /* do not fill boot blocks */ 3310762Ssam int fssize; /* file system size */ 3410762Ssam int fsize; /* fragment size */ 3510762Ssam int bsize; /* block size */ 3610762Ssam int ntracks; /* # tracks/cylinder */ 3710762Ssam int nsectors; /* # sectors/track */ 3810762Ssam int sectorsize; /* bytes/sector */ 3910762Ssam int cpg; /* cylinders/cylinder group */ 4012334Shelge int minfree = -1; /* free space threshold */ 4111069Ssam int rpm; /* revolutions/minute of drive */ 4214884Smckusick int density; /* number of bytes per inode */ 4310762Ssam 4410762Ssam char *av[20]; /* argv array and buffers for exec */ 4510762Ssam char a2[20]; 4610762Ssam char a3[20]; 4710762Ssam char a4[20]; 4810762Ssam char a5[20]; 4910762Ssam char a6[20]; 5010762Ssam char a7[20]; 5111069Ssam char a8[20]; 5211069Ssam char a9[20]; 5314884Smckusick char a10[20]; 5410762Ssam char device[MAXPATHLEN]; 5510762Ssam char cmd[BUFSIZ]; 5610762Ssam 5710762Ssam char *index(); 5810762Ssam char *rindex(); 5910762Ssam char *sprintf(); 6010762Ssam 6110762Ssam main(argc, argv) 6214064Smckusick int argc; 6310762Ssam char *argv[]; 6410762Ssam { 6510762Ssam char *cp, *special; 6610762Ssam register struct disktab *dp; 6710762Ssam register struct partition *pp; 6810762Ssam struct stat st; 6910762Ssam register int i; 7010762Ssam int status; 7110762Ssam 7210762Ssam argc--, argv++; 7310762Ssam while (argc > 0 && argv[0][0] == '-') { 7410762Ssam for (cp = &argv[0][1]; *cp; cp++) 7510762Ssam switch (*cp) { 7610762Ssam 7710762Ssam case 'v': 7810762Ssam verbose++; 7910762Ssam break; 8010762Ssam 8116945Smckusick case 'N': 8216945Smckusick Nflag++; 8316945Smckusick /* fall through to */ 8416945Smckusick 8512334Shelge case 'n': 8612334Shelge noboot++; 8712334Shelge break; 8812334Shelge 8910762Ssam case 's': 9010762Ssam if (argc < 1) 9110762Ssam fatal("-s: missing file system size"); 9210762Ssam argc--, argv++; 9310762Ssam fssize = atoi(*argv); 9410762Ssam if (fssize < 0) 9510762Ssam fatal("%s: bad file system size", 9610762Ssam *argv); 9710762Ssam goto next; 9810762Ssam 9910762Ssam case 't': 10010762Ssam if (argc < 1) 10110762Ssam fatal("-t: missing track total"); 10210762Ssam argc--, argv++; 10310762Ssam ntracks = atoi(*argv); 10410762Ssam if (ntracks < 0) 10510762Ssam fatal("%s: bad total tracks", *argv); 10610762Ssam goto next; 10710762Ssam 10810762Ssam case 'b': 10910762Ssam if (argc < 1) 11010762Ssam fatal("-b: missing block size"); 11110762Ssam argc--, argv++; 11210762Ssam bsize = atoi(*argv); 11310762Ssam if (bsize < 0 || bsize < MINBSIZE) 11410762Ssam fatal("%s: bad block size", *argv); 11510762Ssam goto next; 11610762Ssam 11710762Ssam case 'f': 11810762Ssam if (argc < 1) 11910762Ssam fatal("-f: missing frag size"); 12010762Ssam argc--, argv++; 12110762Ssam fsize = atoi(*argv); 12210762Ssam if (fsize < 0) 12310762Ssam fatal("%s: bad frag size", *argv); 12410762Ssam goto next; 12510762Ssam 12610762Ssam case 'S': 12710762Ssam if (argc < 1) 12810762Ssam fatal("-S: missing sector size"); 12910762Ssam argc--, argv++; 13010762Ssam sectorsize = atoi(*argv); 13110762Ssam if (sectorsize < 0) 13210762Ssam fatal("%s: bad sector size", *argv); 13310762Ssam goto next; 13410762Ssam 13510762Ssam case 'c': 13610762Ssam if (argc < 1) 13710762Ssam fatal("-c: missing cylinders/group"); 13810762Ssam argc--, argv++; 13910762Ssam cpg = atoi(*argv); 14010762Ssam if (cpg < 0) 14110762Ssam fatal("%s: bad cylinders/group", *argv); 14210762Ssam goto next; 14310762Ssam 14411069Ssam case 'm': 14511069Ssam if (argc < 1) 14611069Ssam fatal("-m: missing free space %%\n"); 14711069Ssam argc--, argv++; 14811069Ssam minfree = atoi(*argv); 14911069Ssam if (minfree < 0 || minfree > 99) 15011069Ssam fatal("%s: bad free space %%\n", 15111069Ssam *argv); 15211069Ssam goto next; 15311069Ssam 15411069Ssam case 'r': 15511069Ssam if (argc < 1) 15611069Ssam fatal("-r: missing revs/minute\n"); 15711069Ssam argc--, argv++; 15811069Ssam rpm = atoi(*argv); 15911069Ssam if (rpm < 0) 16011069Ssam fatal("%s: bad revs/minute\n", *argv); 16111069Ssam goto next; 16211069Ssam 16314884Smckusick case 'i': 16414884Smckusick if (argc < 1) 16514884Smckusick fatal("-i: missing bytes per inode\n"); 16614884Smckusick argc--, argv++; 16714884Smckusick density = atoi(*argv); 16814884Smckusick if (density < 0) 16914884Smckusick fatal("%s: bad bytes per inode\n", 17014884Smckusick *argv); 17114884Smckusick goto next; 17214884Smckusick 17310762Ssam default: 17410762Ssam fatal("-%c: unknown flag", cp); 17510762Ssam } 17610762Ssam next: 17710762Ssam argc--, argv++; 17810762Ssam } 17910762Ssam if (argc < 2) { 18011069Ssam fprintf(stderr, "usage: newfs [ -v ] [ mkfs-options ] %s\n", 18110762Ssam "special-device device-type"); 18210762Ssam fprintf(stderr, "where mkfs-options are:\n"); 18316945Smckusick fprintf(stderr, "\t-N do not create file system, %s\n", 18416945Smckusick "just print out parameters"); 18511057Ssam fprintf(stderr, "\t-s file system size (sectors)\n"); 18611057Ssam fprintf(stderr, "\t-b block size\n"); 18711057Ssam fprintf(stderr, "\t-f frag size\n"); 18810873Ssam fprintf(stderr, "\t-t tracks/cylinder\n"); 18910873Ssam fprintf(stderr, "\t-c cylinders/group\n"); 19011069Ssam fprintf(stderr, "\t-m minimum free space %%\n"); 19111069Ssam fprintf(stderr, "\t-r revolutions/minute\n"); 19211057Ssam fprintf(stderr, "\t-S sector size\n"); 19314884Smckusick fprintf(stderr, "\t-i number of bytes per inode\n"); 19410762Ssam exit(1); 19510762Ssam } 19610762Ssam special = argv[0]; 19714064Smckusick cp = rindex(special, '/'); 19814064Smckusick if (cp != 0) 19914064Smckusick special = cp + 1; 20014321Ssam if (*special == 'r' && special[1] != 'a' && special[1] != 'b') 20114064Smckusick special++; 20214064Smckusick special = sprintf(device, "/dev/r%s", special); 20310762Ssam if (stat(special, &st) < 0) { 20411069Ssam fprintf(stderr, "newfs: "); perror(special); 20510762Ssam exit(2); 20610762Ssam } 20714064Smckusick if ((st.st_mode & S_IFMT) != S_IFCHR) 20814064Smckusick fatal("%s: not a character device", special); 20910762Ssam dp = getdiskbyname(argv[1]); 21010762Ssam if (dp == 0) 21110762Ssam fatal("%s: unknown disk type", argv[1]); 21210762Ssam cp = index(argv[0], '\0') - 1; 21310762Ssam if (cp == 0 || *cp < 'a' || *cp > 'h') 21410762Ssam fatal("%s: can't figure out file system partition", argv[0]); 21510762Ssam pp = &dp->d_partitions[*cp - 'a']; 21610762Ssam if (fssize == 0) { 21710762Ssam fssize = pp->p_size; 21810762Ssam if (fssize < 0) 21910762Ssam fatal("%s: no default size for `%c' partition", 22010762Ssam argv[1], *cp); 22110762Ssam } 22210762Ssam if (nsectors == 0) { 22310762Ssam nsectors = dp->d_nsectors; 22410762Ssam if (nsectors < 0) 22510762Ssam fatal("%s: no default #sectors/track", argv[1]); 22610762Ssam } 22710762Ssam if (ntracks == 0) { 22810762Ssam ntracks = dp->d_ntracks; 22910762Ssam if (ntracks < 0) 23010762Ssam fatal("%s: no default #tracks", argv[1]); 23110762Ssam } 23210762Ssam if (sectorsize == 0) { 23310762Ssam sectorsize = dp->d_secsize; 23410762Ssam if (sectorsize < 0) 23510762Ssam fatal("%s: no default sector size", argv[1]); 23610762Ssam } 23710762Ssam if (bsize == 0) { 23810762Ssam bsize = pp->p_bsize; 23910762Ssam if (bsize < 0) 24010762Ssam fatal("%s: no default block size for `%c' partition", 24110762Ssam argv[1], *cp); 24210762Ssam } 24310762Ssam if (fsize == 0) { 24410762Ssam fsize = pp->p_fsize; 24510762Ssam if (fsize < 0) 24610762Ssam fatal("%s: no default frag size for `%c' partition", 24710762Ssam argv[1], *cp); 24810762Ssam } 24911069Ssam if (rpm == 0) { 25011069Ssam rpm = dp->d_rpm; 25111069Ssam if (rpm < 0) 25211069Ssam fatal("%s: no default revolutions/minute value", 25311069Ssam argv[1]); 25411069Ssam } 25514884Smckusick if (density <= 0) 25614884Smckusick density = 2048; 25712334Shelge if (minfree < 0) 25811069Ssam minfree = 10; 25911069Ssam if (cpg == 0) 26011069Ssam cpg = 16; 26110762Ssam i = 0; 26216945Smckusick if (Nflag) 26316945Smckusick av[i++] = "-N"; 26416945Smckusick av[i++] = special; 26510762Ssam av[i++] = sprintf(a2, "%d", fssize); 26610762Ssam av[i++] = sprintf(a3, "%d", nsectors); 26710762Ssam av[i++] = sprintf(a4, "%d", ntracks); 26810762Ssam av[i++] = sprintf(a5, "%d", bsize); 26910762Ssam av[i++] = sprintf(a6, "%d", fsize); 27011069Ssam av[i++] = sprintf(a7, "%d", cpg); 27111069Ssam av[i++] = sprintf(a8, "%d", minfree); 27211069Ssam av[i++] = sprintf(a9, "%d", rpm / 60); 27314884Smckusick av[i++] = sprintf(a10, "%d", density); 27410762Ssam av[i++] = 0; 27516945Smckusick strcpy(cmd, "/etc/mkfs"); 27610762Ssam for (i = 0; av[i] != 0; i++) { 27710762Ssam strcat(cmd, " "); 27810762Ssam strcat(cmd, av[i]); 27910762Ssam } 28010762Ssam if (verbose) 28110762Ssam printf("%s\n", cmd); 28210762Ssam if (status = system(cmd)) 28316407Sralph exit(status >> 8); 28412334Shelge if (*cp == 'a' && !noboot) { 28510762Ssam char type[3]; 28613819Ssam struct stat sb; 28710762Ssam 28810762Ssam cp = rindex(special, '/'); 28910762Ssam if (cp == NULL) 29010762Ssam fatal("%s: can't figure out disk type from name", 29110762Ssam special); 29213819Ssam if (stat(special, &sb) >= 0 && (sb.st_mode & S_IFMT) == S_IFCHR) 29310873Ssam cp++; 29410762Ssam type[0] = *++cp; 29510762Ssam type[1] = *++cp; 29610762Ssam type[2] = '\0'; 29710762Ssam installboot(special, type); 29810762Ssam } 29910762Ssam exit(0); 30010762Ssam } 30110762Ssam 30210762Ssam installboot(dev, type) 30310762Ssam char *dev, *type; 30410762Ssam { 30510762Ssam int fd; 30610762Ssam char bootblock[MAXPATHLEN], standalonecode[MAXPATHLEN]; 30710762Ssam char bootimage[BBSIZE]; 30810762Ssam 30911183Ssam sprintf(bootblock, "%s/%sboot", BOOTDIR, type); 31011183Ssam sprintf(standalonecode, "%s/boot%s", BOOTDIR, type); 31110762Ssam if (verbose) { 31210762Ssam printf("installing boot code\n"); 31310762Ssam printf("sector 0 boot = %s\n", bootblock); 31410762Ssam printf("1st level boot = %s\n", standalonecode); 31510762Ssam } 31610762Ssam fd = open(bootblock, 0); 31710762Ssam if (fd < 0) { 31811069Ssam fprintf(stderr, "newfs: "); perror(bootblock); 31910762Ssam exit(1); 32010762Ssam } 32110762Ssam if (read(fd, bootimage, DEV_BSIZE) < 0) { 32211069Ssam fprintf(stderr, "newfs: "); perror(bootblock); 32310762Ssam exit(2); 32410762Ssam } 32510762Ssam close(fd); 32610762Ssam fd = open(standalonecode, 0); 32710762Ssam if (fd < 0) { 32811069Ssam fprintf(stderr, "newfs: "); perror(standalonecode); 32910762Ssam exit(1); 33010762Ssam } 33110762Ssam if (read(fd, &bootimage[DEV_BSIZE], BBSIZE - DEV_BSIZE) < 0) { 33211069Ssam fprintf(stderr, "newfs: "); perror(standalonecode); 33310762Ssam exit(2); 33410762Ssam } 33510762Ssam close(fd); 33610763Ssam fd = open(dev, 1); 33710762Ssam if (fd < 0) { 33811069Ssam fprintf(stderr, "newfs: "); perror(dev); 33910762Ssam exit(1); 34010762Ssam } 34110762Ssam if (write(fd, bootimage, BBSIZE) != BBSIZE) { 34211069Ssam fprintf(stderr, "newfs: "); perror(dev); 34310762Ssam exit(2); 34410762Ssam } 34510762Ssam close(fd); 34610762Ssam } 34710762Ssam 34810762Ssam /*VARARGS*/ 34910762Ssam fatal(fmt, arg1, arg2) 35010762Ssam char *fmt; 35110762Ssam { 35210762Ssam 35311069Ssam fprintf(stderr, "newfs: "); 35410762Ssam fprintf(stderr, fmt, arg1, arg2); 35510762Ssam putc('\n', stderr); 35610762Ssam exit(10); 35710762Ssam } 358