xref: /csrg-svn/sbin/newfs/newfs.c (revision 14884)
110762Ssam #ifndef lint
2*14884Smckusick static char sccsid[] = "@(#)newfs.c	4.12 08/28/83";
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 
1810762Ssam int	verbose;		/* show mkfs line before exec */
1912334Shelge int	noboot;			/* do not fill boot blocks */
2010762Ssam int	fssize;			/* file system size */
2110762Ssam int	fsize;			/* fragment size */
2210762Ssam int	bsize;			/* block size */
2310762Ssam int	ntracks;		/* # tracks/cylinder */
2410762Ssam int	nsectors;		/* # sectors/track */
2510762Ssam int	sectorsize;		/* bytes/sector */
2610762Ssam int	cpg;			/* cylinders/cylinder group */
2712334Shelge int	minfree = -1;		/* free space threshold */
2811069Ssam int	rpm;			/* revolutions/minute of drive */
29*14884Smckusick int	density;		/* number of bytes per inode */
3010762Ssam 
3110762Ssam char	*av[20];		/* argv array and buffers for exec */
3210762Ssam char	a2[20];
3310762Ssam char	a3[20];
3410762Ssam char	a4[20];
3510762Ssam char	a5[20];
3610762Ssam char	a6[20];
3710762Ssam char	a7[20];
3811069Ssam char	a8[20];
3911069Ssam char	a9[20];
40*14884Smckusick char	a10[20];
4110762Ssam char	device[MAXPATHLEN];
4210762Ssam char	cmd[BUFSIZ];
4310762Ssam 
4410762Ssam char	*index();
4510762Ssam char	*rindex();
4610762Ssam char	*sprintf();
4710762Ssam 
4810762Ssam main(argc, argv)
4914064Smckusick 	int argc;
5010762Ssam 	char *argv[];
5110762Ssam {
5210762Ssam 	char *cp, *special;
5310762Ssam 	register struct disktab *dp;
5410762Ssam 	register struct partition *pp;
5510762Ssam 	struct stat st;
5610762Ssam 	register int i;
5710762Ssam 	int status;
5810762Ssam 
5910762Ssam 	argc--, argv++;
6010762Ssam 	while (argc > 0 && argv[0][0] == '-') {
6110762Ssam 		for (cp = &argv[0][1]; *cp; cp++)
6210762Ssam 			switch (*cp) {
6310762Ssam 
6410762Ssam 			case 'v':
6510762Ssam 				verbose++;
6610762Ssam 				break;
6710762Ssam 
6812334Shelge 			case 'n':
6912334Shelge 				noboot++;
7012334Shelge 				break;
7112334Shelge 
7210762Ssam 			case 's':
7310762Ssam 				if (argc < 1)
7410762Ssam 					fatal("-s: missing file system size");
7510762Ssam 				argc--, argv++;
7610762Ssam 				fssize = atoi(*argv);
7710762Ssam 				if (fssize < 0)
7810762Ssam 					fatal("%s: bad file system size",
7910762Ssam 						*argv);
8010762Ssam 				goto next;
8110762Ssam 
8210762Ssam 			case 't':
8310762Ssam 				if (argc < 1)
8410762Ssam 					fatal("-t: missing track total");
8510762Ssam 				argc--, argv++;
8610762Ssam 				ntracks = atoi(*argv);
8710762Ssam 				if (ntracks < 0)
8810762Ssam 					fatal("%s: bad total tracks", *argv);
8910762Ssam 				goto next;
9010762Ssam 
9110762Ssam 			case 'b':
9210762Ssam 				if (argc < 1)
9310762Ssam 					fatal("-b: missing block size");
9410762Ssam 				argc--, argv++;
9510762Ssam 				bsize = atoi(*argv);
9610762Ssam 				if (bsize < 0 || bsize < MINBSIZE)
9710762Ssam 					fatal("%s: bad block size", *argv);
9810762Ssam 				goto next;
9910762Ssam 
10010762Ssam 			case 'f':
10110762Ssam 				if (argc < 1)
10210762Ssam 					fatal("-f: missing frag size");
10310762Ssam 				argc--, argv++;
10410762Ssam 				fsize = atoi(*argv);
10510762Ssam 				if (fsize < 0)
10610762Ssam 					fatal("%s: bad frag size", *argv);
10710762Ssam 				goto next;
10810762Ssam 
10910762Ssam 			case 'S':
11010762Ssam 				if (argc < 1)
11110762Ssam 					fatal("-S: missing sector size");
11210762Ssam 				argc--, argv++;
11310762Ssam 				sectorsize = atoi(*argv);
11410762Ssam 				if (sectorsize < 0)
11510762Ssam 					fatal("%s: bad sector size", *argv);
11610762Ssam 				goto next;
11710762Ssam 
11810762Ssam 			case 'c':
11910762Ssam 				if (argc < 1)
12010762Ssam 					fatal("-c: missing cylinders/group");
12110762Ssam 				argc--, argv++;
12210762Ssam 				cpg = atoi(*argv);
12310762Ssam 				if (cpg < 0)
12410762Ssam 					fatal("%s: bad cylinders/group", *argv);
12510762Ssam 				goto next;
12610762Ssam 
12711069Ssam 			case 'm':
12811069Ssam 				if (argc < 1)
12911069Ssam 					fatal("-m: missing free space %%\n");
13011069Ssam 				argc--, argv++;
13111069Ssam 				minfree = atoi(*argv);
13211069Ssam 				if (minfree < 0 || minfree > 99)
13311069Ssam 					fatal("%s: bad free space %%\n",
13411069Ssam 						*argv);
13511069Ssam 				goto next;
13611069Ssam 
13711069Ssam 			case 'r':
13811069Ssam 				if (argc < 1)
13911069Ssam 					fatal("-r: missing revs/minute\n");
14011069Ssam 				argc--, argv++;
14111069Ssam 				rpm = atoi(*argv);
14211069Ssam 				if (rpm < 0)
14311069Ssam 					fatal("%s: bad revs/minute\n", *argv);
14411069Ssam 				goto next;
14511069Ssam 
146*14884Smckusick 			case 'i':
147*14884Smckusick 				if (argc < 1)
148*14884Smckusick 					fatal("-i: missing bytes per inode\n");
149*14884Smckusick 				argc--, argv++;
150*14884Smckusick 				density = atoi(*argv);
151*14884Smckusick 				if (density < 0)
152*14884Smckusick 					fatal("%s: bad bytes per inode\n",
153*14884Smckusick 						*argv);
154*14884Smckusick 				goto next;
155*14884Smckusick 
15610762Ssam 			default:
15710762Ssam 				fatal("-%c: unknown flag", cp);
15810762Ssam 			}
15910762Ssam next:
16010762Ssam 		argc--, argv++;
16110762Ssam 	}
16210762Ssam 	if (argc < 2) {
16311069Ssam 		fprintf(stderr, "usage: newfs [ -v ] [ mkfs-options ] %s\n",
16410762Ssam 			"special-device device-type");
16510762Ssam 		fprintf(stderr, "where mkfs-options are:\n");
16611057Ssam 		fprintf(stderr, "\t-s file system size (sectors)\n");
16711057Ssam 		fprintf(stderr, "\t-b block size\n");
16811057Ssam 		fprintf(stderr, "\t-f frag size\n");
16910873Ssam 		fprintf(stderr, "\t-t tracks/cylinder\n");
17010873Ssam 		fprintf(stderr, "\t-c cylinders/group\n");
17111069Ssam 		fprintf(stderr, "\t-m minimum free space %%\n");
17211069Ssam 		fprintf(stderr, "\t-r revolutions/minute\n");
17311057Ssam 		fprintf(stderr, "\t-S sector size\n");
174*14884Smckusick 		fprintf(stderr, "\t-i number of bytes per inode\n");
17510762Ssam 		exit(1);
17610762Ssam 	}
17710762Ssam 	special = argv[0];
17814064Smckusick 	cp = rindex(special, '/');
17914064Smckusick 	if (cp != 0)
18014064Smckusick 		special = cp + 1;
18114321Ssam 	if (*special == 'r' && special[1] != 'a' && special[1] != 'b')
18214064Smckusick 		special++;
18314064Smckusick 	special = sprintf(device, "/dev/r%s", special);
18410762Ssam 	if (stat(special, &st) < 0) {
18511069Ssam 		fprintf(stderr, "newfs: "); perror(special);
18610762Ssam 		exit(2);
18710762Ssam 	}
18814064Smckusick 	if ((st.st_mode & S_IFMT) != S_IFCHR)
18914064Smckusick 		fatal("%s: not a character device", special);
19010762Ssam 	dp = getdiskbyname(argv[1]);
19110762Ssam 	if (dp == 0)
19210762Ssam 		fatal("%s: unknown disk type", argv[1]);
19310762Ssam 	cp = index(argv[0], '\0') - 1;
19410762Ssam 	if (cp == 0 || *cp < 'a' || *cp > 'h')
19510762Ssam 		fatal("%s: can't figure out file system partition", argv[0]);
19610762Ssam 	pp = &dp->d_partitions[*cp - 'a'];
19710762Ssam 	if (fssize == 0) {
19810762Ssam 		fssize = pp->p_size;
19910762Ssam 		if (fssize < 0)
20010762Ssam 			fatal("%s: no default size for `%c' partition",
20110762Ssam 				argv[1], *cp);
20210762Ssam 	}
20310762Ssam 	if (nsectors == 0) {
20410762Ssam 		nsectors = dp->d_nsectors;
20510762Ssam 		if (nsectors < 0)
20610762Ssam 			fatal("%s: no default #sectors/track", argv[1]);
20710762Ssam 	}
20810762Ssam 	if (ntracks == 0) {
20910762Ssam 		ntracks = dp->d_ntracks;
21010762Ssam 		if (ntracks < 0)
21110762Ssam 			fatal("%s: no default #tracks", argv[1]);
21210762Ssam 	}
21310762Ssam 	if (sectorsize == 0) {
21410762Ssam 		sectorsize = dp->d_secsize;
21510762Ssam 		if (sectorsize < 0)
21610762Ssam 			fatal("%s: no default sector size", argv[1]);
21710762Ssam 	}
21810762Ssam 	if (bsize == 0) {
21910762Ssam 		bsize = pp->p_bsize;
22010762Ssam 		if (bsize < 0)
22110762Ssam 			fatal("%s: no default block size for `%c' partition",
22210762Ssam 				argv[1], *cp);
22310762Ssam 	}
22410762Ssam 	if (fsize == 0) {
22510762Ssam 		fsize = pp->p_fsize;
22610762Ssam 		if (fsize < 0)
22710762Ssam 			fatal("%s: no default frag size for `%c' partition",
22810762Ssam 				argv[1], *cp);
22910762Ssam 	}
23011069Ssam 	if (rpm == 0) {
23111069Ssam 		rpm = dp->d_rpm;
23211069Ssam 		if (rpm < 0)
23311069Ssam 			fatal("%s: no default revolutions/minute value",
23411069Ssam 				argv[1]);
23511069Ssam 	}
236*14884Smckusick 	if (density <= 0)
237*14884Smckusick 		density = 2048;
23812334Shelge 	if (minfree < 0)
23911069Ssam 		minfree = 10;
24011069Ssam 	if (cpg == 0)
24111069Ssam 		cpg = 16;
24210762Ssam 	i = 0;
24310762Ssam 	av[i++] = sprintf(a2, "%d", fssize);
24410762Ssam 	av[i++] = sprintf(a3, "%d", nsectors);
24510762Ssam 	av[i++] = sprintf(a4, "%d", ntracks);
24610762Ssam 	av[i++] = sprintf(a5, "%d", bsize);
24710762Ssam 	av[i++] = sprintf(a6, "%d", fsize);
24811069Ssam 	av[i++] = sprintf(a7, "%d", cpg);
24911069Ssam 	av[i++] = sprintf(a8, "%d", minfree);
25011069Ssam 	av[i++] = sprintf(a9, "%d", rpm / 60);
251*14884Smckusick 	av[i++] = sprintf(a10, "%d", density);
25210762Ssam 	av[i++] = 0;
25310762Ssam 	sprintf(cmd, "/etc/mkfs %s", special);
25410762Ssam 	for (i = 0; av[i] != 0; i++) {
25510762Ssam 		strcat(cmd, " ");
25610762Ssam 		strcat(cmd, av[i]);
25710762Ssam 	}
25810762Ssam 	if (verbose)
25910762Ssam 		printf("%s\n", cmd);
26010762Ssam 	if (status = system(cmd))
26110762Ssam 		exit(status);
26212334Shelge 	if (*cp == 'a' && !noboot) {
26310762Ssam 		char type[3];
26413819Ssam 		struct stat sb;
26510762Ssam 
26610762Ssam 		cp = rindex(special, '/');
26710762Ssam 		if (cp == NULL)
26810762Ssam 			fatal("%s: can't figure out disk type from name",
26910762Ssam 				special);
27013819Ssam 		if (stat(special, &sb) >= 0 && (sb.st_mode & S_IFMT) == S_IFCHR)
27110873Ssam 			cp++;
27210762Ssam 		type[0] = *++cp;
27310762Ssam 		type[1] = *++cp;
27410762Ssam 		type[2] = '\0';
27510762Ssam 		installboot(special, type);
27610762Ssam 	}
27710762Ssam 	exit(0);
27810762Ssam }
27910762Ssam 
28010762Ssam installboot(dev, type)
28110762Ssam 	char *dev, *type;
28210762Ssam {
28310762Ssam 	int fd;
28410762Ssam 	char bootblock[MAXPATHLEN], standalonecode[MAXPATHLEN];
28510762Ssam 	char bootimage[BBSIZE];
28610762Ssam 
28711183Ssam 	sprintf(bootblock, "%s/%sboot", BOOTDIR, type);
28811183Ssam 	sprintf(standalonecode, "%s/boot%s", BOOTDIR, type);
28910762Ssam 	if (verbose) {
29010762Ssam 		printf("installing boot code\n");
29110762Ssam 		printf("sector 0 boot = %s\n", bootblock);
29210762Ssam 		printf("1st level boot = %s\n", standalonecode);
29310762Ssam 	}
29410762Ssam 	fd = open(bootblock, 0);
29510762Ssam 	if (fd < 0) {
29611069Ssam 		fprintf(stderr, "newfs: "); perror(bootblock);
29710762Ssam 		exit(1);
29810762Ssam 	}
29910762Ssam 	if (read(fd, bootimage, DEV_BSIZE) < 0) {
30011069Ssam 		fprintf(stderr, "newfs: "); perror(bootblock);
30110762Ssam 		exit(2);
30210762Ssam 	}
30310762Ssam 	close(fd);
30410762Ssam 	fd = open(standalonecode, 0);
30510762Ssam 	if (fd < 0) {
30611069Ssam 		fprintf(stderr, "newfs: "); perror(standalonecode);
30710762Ssam 		exit(1);
30810762Ssam 	}
30910762Ssam 	if (read(fd, &bootimage[DEV_BSIZE], BBSIZE - DEV_BSIZE) < 0) {
31011069Ssam 		fprintf(stderr, "newfs: "); perror(standalonecode);
31110762Ssam 		exit(2);
31210762Ssam 	}
31310762Ssam 	close(fd);
31410763Ssam 	fd = open(dev, 1);
31510762Ssam 	if (fd < 0) {
31611069Ssam 		fprintf(stderr, "newfs: "); perror(dev);
31710762Ssam 		exit(1);
31810762Ssam 	}
31910762Ssam 	if (write(fd, bootimage, BBSIZE) != BBSIZE) {
32011069Ssam 		fprintf(stderr, "newfs: "); perror(dev);
32110762Ssam 		exit(2);
32210762Ssam 	}
32310762Ssam 	close(fd);
32410762Ssam }
32510762Ssam 
32610762Ssam /*VARARGS*/
32710762Ssam fatal(fmt, arg1, arg2)
32810762Ssam 	char *fmt;
32910762Ssam {
33010762Ssam 
33111069Ssam 	fprintf(stderr, "newfs: ");
33210762Ssam 	fprintf(stderr, fmt, arg1, arg2);
33310762Ssam 	putc('\n', stderr);
33410762Ssam 	exit(10);
33510762Ssam }
336