NFSv2/usr/src/etc/newfs.c

Compare this file to the similar file:
Show the results in this format:

#ifndef lint
static	char *sccsid = "@(#)newfs.c 1.1 85/05/30 SMI"; /* from UCB 4.9 7/6/83 */
#endif

/*
 * newfs: friendly front end to mkfs
 */
#include <sys/param.h>
#include <sys/stat.h>
#include <ufs/fs.h>
#include <sys/dir.h>

#include <stdio.h>
#include <disktab.h>

#ifdef sun
#include <sys/ioctl.h>
#include <sun/dklabel.h>
#include <sun/dkio.h>

struct disktab *getdiskbydev();

#endif sun

#define	BOOTDIR	"/usr/mdec"	/* directory for boot blocks */

int	verbose;		/* show mkfs line before exec */
int	noboot;			/* do not fill boot blocks */
int	fssize;			/* file system size */
int	fsize;			/* fragment size */
int	bsize;			/* block size */
int	ntracks;		/* # tracks/cylinder */
int	nsectors;		/* # sectors/track */
int	cpg;			/* cylinders/cylinder group */
int	minfree = -1;		/* free space threshold */
int	rpm;			/* revolutions/minute of drive */

char	device[MAXPATHLEN];
char	cmd[BUFSIZ];

char	*index();
char	*rindex();
char	*sprintf();

main(argc, argv)
	char *argv[];
{
	char *cp, *special;
	register struct disktab *dp;
	register struct partition *pp;
	struct stat st;
	register int i;
	int status;

	argc--, argv++;
	while (argc > 0 && argv[0][0] == '-') {
		for (cp = &argv[0][1]; *cp; cp++)
			switch (*cp) {

			case 'v':
				verbose++;
				break;

			case 'n':
				noboot++;
				break;

			case 's':
				if (argc < 1)
					fatal("-s: missing file system size");
				argc--, argv++;
				fssize = atoi(*argv);
				if (fssize < 0)
					fatal("%s: bad file system size",
						*argv);
				goto next;

			case 't':
				if (argc < 1)
					fatal("-t: missing track total");
				argc--, argv++;
				ntracks = atoi(*argv);
				if (ntracks < 0)
					fatal("%s: bad total tracks", *argv);
				goto next;

			case 'b':
				if (argc < 1)
					fatal("-b: missing block size");
				argc--, argv++;
				bsize = atoi(*argv);
				if (bsize < 0 || bsize < MINBSIZE)
					fatal("%s: bad block size", *argv);
				goto next;

			case 'f':
				if (argc < 1)
					fatal("-f: missing frag size");
				argc--, argv++;
				fsize = atoi(*argv);
				if (fsize < 0)
					fatal("%s: bad frag size", *argv);
				goto next;

			case 'c':
				if (argc < 1)
					fatal("-c: missing cylinders/group");
				argc--, argv++;
				cpg = atoi(*argv);
				if (cpg < 0)
					fatal("%s: bad cylinders/group", *argv);
				goto next;

			case 'm':
				if (argc < 1)
					fatal("-m: missing free space %%\n");
				argc--, argv++;
				minfree = atoi(*argv);
				if (minfree < 0 || minfree > 99)
					fatal("%s: bad free space %%\n",
						*argv);
				goto next;

			case 'r':
				if (argc < 1)
					fatal("-r: missing revs/minute\n");
				argc--, argv++;
				rpm = atoi(*argv);
				if (rpm < 0)
					fatal("%s: bad revs/minute\n", *argv);
				goto next;

			default:
				fatal("-%c: unknown flag", cp);
			}
next:
		argc--, argv++;
	}
#ifdef vax
	if (argc < 2) {
		fprintf(stderr, "usage: newfs [ -v ] [ mkfs-options ] %s\n",
			"special-device device-type");
#endif vax
#ifdef sun
	if (argc < 1) {
		fprintf(stderr, "usage: newfs [ -v ] [ mkfs-options ] %s\n",
			"raw-special-device");
#endif sun
		fprintf(stderr, "where mkfs-options are:\n");
		fprintf(stderr, "\t-s file system size (sectors)\n");
		fprintf(stderr, "\t-b block size\n");
		fprintf(stderr, "\t-f frag size\n");
		fprintf(stderr, "\t-t tracks/cylinder\n");
		fprintf(stderr, "\t-c cylinders/group\n");
		fprintf(stderr, "\t-m minimum free space %%\n");
		fprintf(stderr, "\t-r revolutions/minute\n");
		exit(1);
	}
	special = argv[0];
again:
	if (stat(special, &st) < 0) {
		if (*special != '/') {
			if (*special == 'r')
				special++;
			special = sprintf(device, "/dev/r%s", special);
			goto again;
		}
		fprintf(stderr, "newfs: "); perror(special);
		exit(2);
	}
#ifndef sun
	if ((st.st_mode & S_IFMT) != S_IFBLK &&
	    (st.st_mode & S_IFMT) != S_IFCHR)
		fatal("%s: not a block or character device", special);
	dp = getdiskbyname(argv[1]);
#else sun
	if ((st.st_mode & S_IFMT) != S_IFCHR)
		fatal("%s: not a raw disk device", special);
	dp = getdiskbydev(special);
#endif sun
	if (dp == 0)
#ifndef sun
		fatal("%s: unknown disk type", argv[1]);
#else sun
		fatal("%s: unknown disk information", argv[1]);
#endif sun
	cp = index(argv[0], '\0') - 1;
	if (cp == 0 || *cp < 'a' || *cp > 'h')
		fatal("%s: can't figure out file system partition", argv[0]);
	pp = &dp->d_partitions[*cp - 'a'];
	if (fssize == 0) {
		fssize = pp->p_size;
		if (fssize < 0)
			fatal("%s: no default size for `%c' partition",
				argv[1], *cp);
	}
	if (nsectors == 0) {
		nsectors = dp->d_nsectors;
		if (nsectors < 0)
			fatal("%s: no default #sectors/track", argv[1]);
	}
	if (ntracks == 0) {
		ntracks = dp->d_ntracks;
		if (ntracks < 0)
			fatal("%s: no default #tracks", argv[1]);
	}
	if (bsize == 0) {
		bsize = pp->p_bsize;
		if (bsize < 0)
			fatal("%s: no default block size for `%c' partition",
				argv[1], *cp);
	}
	if (fsize == 0) {
		fsize = pp->p_fsize;
		if (fsize < 0)
			fatal("%s: no default frag size for `%c' partition",
				argv[1], *cp);
	}
	if (rpm == 0) {
		rpm = dp->d_rpm;
		if (rpm < 0)
			fatal("%s: no default revolutions/minute value",
				argv[1]);
	}
	if (minfree < 0)
		minfree = 10;
	if (cpg == 0)
		cpg = 16;
	sprintf(cmd, "mkfs %s %d %d %d %d %d %d %d %d", special,
		fssize, nsectors, ntracks, bsize, fsize, cpg, minfree, rpm/60);
	if (verbose)
		printf("%s\n", cmd);
	if (status = system(cmd))
		exit(status);
	sprintf(cmd, "/etc/fsirand %s", special);
	if (status = system(cmd))
		printf("%s: failed, status = %d\n", cmd, status);
	if (*cp == 'a' && !noboot) {
		char type[3];
		struct stat sb;

		cp = rindex(special, '/');
		if (cp == NULL)
			fatal("%s: can't figure out disk type from name",
				special);
		if (stat(special, &sb) >= 0 && (sb.st_mode & S_IFMT) == S_IFCHR)
			cp++;
		type[0] = *++cp;
		type[1] = *++cp;
		type[2] = '\0';
		installboot(special, type);
	}
	exit(0);
}

installboot(dev, type)
	char *dev, *type;
{
	int fd;
#ifdef vax
	char bootblock[MAXPATHLEN];
	char boot0image[DEV_BSIZE];
#endif vax
	char standalonecode[MAXPATHLEN];
	char boot1image[BBSIZE - DEV_BSIZE];

#ifdef vax
	sprintf(bootblock, "%s/%sboot", BOOTDIR, type);
#endif vax
	sprintf(standalonecode, "%s/boot%s", BOOTDIR, type);
	if (verbose) {
		printf("installing boot code\n");
#ifdef vax
		printf("sector 0 boot = %s\n", bootblock);
#endif vax
		printf("1st level boot = %s\n", standalonecode);
	}
#ifdef vax
	fd = open(bootblock, 0);
	if (fd < 0) {
		fprintf(stderr, "newfs: "); perror(bootblock);
		exit(1);
	}
	if (read(fd, boot0image, sizeof boot0image) < 0) {
		fprintf(stderr, "newfs: "); perror(bootblock);
		exit(2);
	}
	close(fd);
#endif vax
	fd = open(standalonecode, 0);
	if (fd < 0) {
		fprintf(stderr, "newfs: "); perror(standalonecode);
		exit(1);
	}
	if (read(fd, boot1image, sizeof boot1image) < 0) {
		fprintf(stderr, "newfs: "); perror(standalonecode);
		exit(2);
	}
	close(fd);
	fd = open(dev, 1);
	if (fd < 0) {
		fprintf(stderr, "newfs: "); perror(dev);
		exit(1);
	}
#ifdef vax
	if (write(fd, boot0image, sizeof boot0image) != sizeof boot0image) {
		fprintf(stderr, "newfs: "); perror(dev);
		exit(2);
	}
#endif vax
	lseek(fd, (long)DEV_BSIZE, 0);
	if (write(fd, boot1image, sizeof boot1image) != sizeof boot1image) {
		fprintf(stderr, "newfs: "); perror(dev);
		exit(2);
	}
	close(fd);
}

/*VARARGS*/
fatal(fmt, arg1, arg2)
	char *fmt;
{

	fprintf(stderr, "newfs: ");
	fprintf(stderr, fmt, arg1, arg2);
	putc('\n', stderr);
	exit(10);
}

#ifdef sun
struct disktab *
getdiskbydev(disk)
	char *disk;
{
	static struct disktab d;
	struct dk_geom g;
	struct dk_map m;
	int fd, part;

	part = disk[strlen(disk)-1] - 'a';
	if ((fd = open(disk, 0)) < 0) {
		perror(disk);
		exit(1);
	}
	if (ioctl(fd, DKIOCGGEOM, &g) < 0) {
		perror("geom ioctl");
		exit(1);
	}
	d.d_secsize = 512;
	d.d_ntracks = g.dkg_nhead;
	d.d_nsectors = g.dkg_nsect;
	d.d_ncylinders = g.dkg_ncyl;
	d.d_rpm = 3600;
	if (ioctl(fd, DKIOCGPART, &m) < 0) {
		perror("part ioctl");
		exit(1);
	}
	close(fd);
	d.d_partitions[part].p_size = m.dkl_nblk;
	d.d_partitions[part].p_bsize = 4096;
	d.d_partitions[part].p_fsize = 1024;
	return (&d);
}
#endif sun