xref: /csrg-svn/usr.sbin/mkproto/mkproto.c (revision 61855)
148347Sbostic /*-
2*61855Sbostic  * Copyright (c) 1983, 1993
3*61855Sbostic  *	The Regents of the University of California.  All rights reserved.
448347Sbostic  *
548347Sbostic  * %sccs.include.proprietary.c%
621155Sdist  */
721155Sdist 
814556Ssam #ifndef lint
9*61855Sbostic static char copyright[] =
10*61855Sbostic "@(#) Copyright (c) 1983, 1993\n\
11*61855Sbostic 	The Regents of the University of California.  All rights reserved.\n";
1248347Sbostic #endif /* not lint */
138142Smckusick 
1421155Sdist #ifndef lint
15*61855Sbostic static char sccsid[] = "@(#)mkproto.c	8.1 (Berkeley) 06/06/93";
1648347Sbostic #endif /* not lint */
1721155Sdist 
188142Smckusick /*
198142Smckusick  * Make a file system prototype.
208142Smckusick  * usage: mkproto filsys proto
218142Smckusick  */
228142Smckusick #include <sys/param.h>
2354059Sbostic #include <sys/time.h>
248142Smckusick #include <sys/dir.h>
2552871Sbostic #include <ufs/ufs/dinode.h>
2652871Sbostic #include <ufs/ffs/fs.h>
2738517Sbostic #include <stdio.h>
288142Smckusick 
298142Smckusick union {
308142Smckusick 	struct	fs fs;
318142Smckusick 	char	fsx[SBSIZE];
328142Smckusick } ufs;
338142Smckusick #define sblock	ufs.fs
348142Smckusick union {
358142Smckusick 	struct	cg cg;
368142Smckusick 	char	cgx[MAXBSIZE];
378142Smckusick } ucg;
388142Smckusick #define	acg	ucg.cg
398142Smckusick struct	fs *fs;
408142Smckusick struct	csum *fscs;
418142Smckusick int	fso, fsi;
428142Smckusick FILE	*proto;
438142Smckusick char	token[BUFSIZ];
448142Smckusick int	errs;
4530558Smckusick long	dev_bsize = 1;
468142Smckusick int	ino = 10;
478142Smckusick long	getnum();
488142Smckusick char	*strcpy();
4939474Smckusick ino_t	ialloc();
508142Smckusick 
518142Smckusick main(argc, argv)
528142Smckusick 	int argc;
538142Smckusick 	char *argv[];
548142Smckusick {
558142Smckusick 	int i;
5633139Sbostic 	char *calloc();
578142Smckusick 
588142Smckusick 	if (argc != 3) {
598142Smckusick 		fprintf(stderr, "usage: mkproto filsys proto\n");
608142Smckusick 		exit(1);
618142Smckusick 	}
628142Smckusick 	fso = open(argv[1], 1);
638142Smckusick 	fsi = open(argv[1], 0);
648142Smckusick 	if (fso < 0 || fsi < 0) {
658142Smckusick 		perror(argv[1]);
668142Smckusick 		exit(1);
678142Smckusick 	}
688142Smckusick 	fs = &sblock;
6930558Smckusick 	rdfs(SBOFF, SBSIZE, (char *)fs);
7030558Smckusick 	dev_bsize = fs->fs_fsize / fsbtodb(fs, 1);
7133139Sbostic 	fscs = (struct csum *)calloc(1, (u_int)fs->fs_cssize);
728142Smckusick 	for (i = 0; i < fs->fs_cssize; i += fs->fs_bsize)
738142Smckusick 		rdfs(fsbtodb(fs, fs->fs_csaddr + numfrags(fs, i)),
748142Smckusick 			(int)(fs->fs_cssize - i < fs->fs_bsize ?
758142Smckusick 			    fs->fs_cssize - i : fs->fs_bsize),
768142Smckusick 			((char *)fscs) + i);
778142Smckusick 	proto = fopen(argv[2], "r");
7839474Smckusick 	descend((struct dinode *)0, ROOTINO);
7930558Smckusick 	wtfs(SBOFF / dev_bsize, SBSIZE, (char *)fs);
808142Smckusick 	for (i = 0; i < fs->fs_cssize; i += fs->fs_bsize)
818142Smckusick 		wtfs(fsbtodb(&sblock, fs->fs_csaddr + numfrags(&sblock, i)),
828142Smckusick 			(int)(fs->fs_cssize - i < fs->fs_bsize ?
838142Smckusick 			    fs->fs_cssize - i : fs->fs_bsize),
848142Smckusick 			((char *)fscs) + i);
858142Smckusick 	exit(errs);
868142Smckusick }
878142Smckusick 
8839474Smckusick descend(par, parinum)
8939474Smckusick 	struct dinode *par;
9039474Smckusick 	ino_t parinum;
918142Smckusick {
9239474Smckusick 	struct dinode in;
9339474Smckusick 	ino_t inum;
948142Smckusick 	int ibc = 0;
958142Smckusick 	int i, f, c;
968142Smckusick 	struct dinode *dip, inos[MAXBSIZE / sizeof (struct dinode)];
978142Smckusick 	daddr_t ib[MAXBSIZE / sizeof (daddr_t)];
988142Smckusick 	char buf[MAXBSIZE];
998142Smckusick 
1008142Smckusick 	getstr();
10139474Smckusick 	in.di_mode = gmode(token[0], "-bcd", IFREG, IFBLK, IFCHR, IFDIR);
10239474Smckusick 	in.di_mode |= gmode(token[1], "-u", 0, ISUID, 0, 0);
10339474Smckusick 	in.di_mode |= gmode(token[2], "-g", 0, ISGID, 0, 0);
1048142Smckusick 	for (i = 3; i < 6; i++) {
1058142Smckusick 		c = token[i];
1068142Smckusick 		if (c < '0' || c > '7') {
1078142Smckusick 			printf("%c/%s: bad octal mode digit\n", c, token);
1088142Smckusick 			errs++;
1098142Smckusick 			c = 0;
1108142Smckusick 		}
11139474Smckusick 		in.di_mode |= (c-'0')<<(15-3*i);
1128142Smckusick 	}
11339474Smckusick 	in.di_uid = getnum(); in.di_gid = getnum();
1148142Smckusick 	for (i = 0; i < fs->fs_bsize; i++)
1158142Smckusick 		buf[i] = 0;
1168142Smckusick 	for (i = 0; i < NINDIR(fs); i++)
1178142Smckusick 		ib[i] = (daddr_t)0;
11839474Smckusick 	in.di_nlink = 1;
11939474Smckusick 	in.di_size = 0;
1208142Smckusick 	for (i = 0; i < NDADDR; i++)
12139474Smckusick 		in.di_db[i] = (daddr_t)0;
1228142Smckusick 	for (i = 0; i < NIADDR; i++)
12339474Smckusick 		in.di_ib[i] = (daddr_t)0;
12439474Smckusick 	if (par != (struct dinode *)0) {
12539474Smckusick 		inum = ialloc(&in);
1268142Smckusick 	} else {
1278142Smckusick 		par = &in;
1288142Smckusick 		i = itod(fs, ROOTINO);
1298142Smckusick 		rdfs(fsbtodb(fs, i), fs->fs_bsize, (char *)inos);
1308142Smckusick 		dip = &inos[ROOTINO % INOPB(fs)];
13139474Smckusick 		inum = ROOTINO;
13239474Smckusick 		in.di_nlink = dip->di_nlink;
13339474Smckusick 		in.di_size = dip->di_size;
13439474Smckusick 		in.di_db[0] = dip->di_db[0];
13539474Smckusick 		rdfs(fsbtodb(fs, in.di_db[0]), fs->fs_bsize, buf);
1368142Smckusick 	}
1378142Smckusick 
13839474Smckusick 	switch (in.di_mode&IFMT) {
1398142Smckusick 
1408142Smckusick 	case IFREG:
1418142Smckusick 		getstr();
1428142Smckusick 		f = open(token, 0);
1438142Smckusick 		if (f < 0) {
1448142Smckusick 			printf("%s: cannot open\n", token);
1458142Smckusick 			errs++;
1468142Smckusick 			break;
1478142Smckusick 		}
1488142Smckusick 		while ((i = read(f, buf, (int)fs->fs_bsize)) > 0) {
14939474Smckusick 			in.di_size += i;
15039474Smckusick 			newblk(buf, &ibc, ib, (int)dblksize(fs, &in, ibc));
1518142Smckusick 		}
1528142Smckusick 		close(f);
1538142Smckusick 		break;
1548142Smckusick 
1558142Smckusick 	case IFBLK:
1568142Smckusick 	case IFCHR:
1578142Smckusick 		/*
1588142Smckusick 		 * special file
1598142Smckusick 		 * content is maj/min types
1608142Smckusick 		 */
1618142Smckusick 
1628142Smckusick 		i = getnum() & 0377;
1638142Smckusick 		f = getnum() & 0377;
16439474Smckusick 		in.di_rdev = (i << 8) | f;
1658142Smckusick 		break;
1668142Smckusick 
1678142Smckusick 	case IFDIR:
1688142Smckusick 		/*
1698142Smckusick 		 * directory
1708142Smckusick 		 * put in extra links
1718142Smckusick 		 * call recursively until
1728142Smckusick 		 * name of "$" found
1738142Smckusick 		 */
1748142Smckusick 
17539474Smckusick 		if (inum != ROOTINO) {
17639474Smckusick 			par->di_nlink++;
17739474Smckusick 			in.di_nlink++;
17839474Smckusick 			entry(&in, inum, ".", buf);
17939474Smckusick 			entry(&in, parinum, "..", buf);
1808142Smckusick 		}
1818142Smckusick 		for (;;) {
1828142Smckusick 			getstr();
1838142Smckusick 			if (token[0]=='$' && token[1]=='\0')
1848142Smckusick 				break;
1858142Smckusick 			entry(&in, (ino_t)(ino+1), token, buf);
18639474Smckusick 			descend(&in, inum);
1878142Smckusick 		}
18839474Smckusick 		if (inum != ROOTINO)
18939474Smckusick 			newblk(buf, &ibc, ib, (int)dblksize(fs, &in, 0));
1908142Smckusick 		else
19139474Smckusick 			wtfs(fsbtodb(fs, in.di_db[0]), (int)fs->fs_bsize, buf);
1928142Smckusick 		break;
1938142Smckusick 	}
19439474Smckusick 	iput(&in, &ibc, ib, inum);
1958142Smckusick }
1968142Smckusick 
1978142Smckusick /*ARGSUSED*/
1988142Smckusick gmode(c, s, m0, m1, m2, m3)
1998142Smckusick 	char c, *s;
2008142Smckusick {
2018142Smckusick 	int i;
2028142Smckusick 
2038142Smckusick 	for (i = 0; s[i]; i++)
2048142Smckusick 		if (c == s[i])
2058142Smckusick 			return((&m0)[i]);
2068142Smckusick 	printf("%c/%s: bad mode\n", c, token);
2078142Smckusick 	errs++;
2088142Smckusick 	return(0);
2098142Smckusick }
2108142Smckusick 
2118142Smckusick long
2128142Smckusick getnum()
2138142Smckusick {
2148142Smckusick 	int i, c;
2158142Smckusick 	long n;
2168142Smckusick 
2178142Smckusick 	getstr();
2188142Smckusick 	n = 0;
2198142Smckusick 	i = 0;
2208142Smckusick 	for (i = 0; c=token[i]; i++) {
2218142Smckusick 		if (c<'0' || c>'9') {
2228142Smckusick 			printf("%s: bad number\n", token);
2238142Smckusick 			errs++;
2248142Smckusick 			return((long)0);
2258142Smckusick 		}
2268142Smckusick 		n = n*10 + (c-'0');
2278142Smckusick 	}
2288142Smckusick 	return(n);
2298142Smckusick }
2308142Smckusick 
2318142Smckusick getstr()
2328142Smckusick {
2338142Smckusick 	int i, c;
2348142Smckusick 
2358142Smckusick loop:
2368142Smckusick 	switch (c = getc(proto)) {
2378142Smckusick 
2388142Smckusick 	case ' ':
2398142Smckusick 	case '\t':
2408142Smckusick 	case '\n':
2418142Smckusick 		goto loop;
2428142Smckusick 
2438142Smckusick 	case EOF:
2448142Smckusick 		printf("Unexpected EOF\n");
2458142Smckusick 		exit(1);
2468142Smckusick 
2478142Smckusick 	case ':':
2488142Smckusick 		while (getc(proto) != '\n')
2498142Smckusick 			;
2508142Smckusick 		goto loop;
2518142Smckusick 
2528142Smckusick 	}
2538142Smckusick 	i = 0;
2548142Smckusick 	do {
2558142Smckusick 		token[i++] = c;
2568142Smckusick 		c = getc(proto);
2578142Smckusick 	} while (c != ' ' && c != '\t' && c != '\n' && c != '\0');
2588142Smckusick 	token[i] = 0;
2598142Smckusick }
2608142Smckusick 
2618142Smckusick entry(ip, inum, str, buf)
26239474Smckusick 	struct dinode *ip;
2638142Smckusick 	ino_t inum;
2648142Smckusick 	char *str;
2658142Smckusick 	char *buf;
2668142Smckusick {
2678142Smckusick 	register struct direct *dp, *odp;
26812214Ssam 	int oldsize, newsize, spacefree;
2698142Smckusick 
2708142Smckusick 	odp = dp = (struct direct *)buf;
27139474Smckusick 	while ((int)dp - (int)buf < ip->di_size) {
2728142Smckusick 		odp = dp;
2738142Smckusick 		dp = (struct direct *)((int)dp + dp->d_reclen);
2748142Smckusick 	}
2758142Smckusick 	if (odp != dp)
2768142Smckusick 		oldsize = DIRSIZ(odp);
2778142Smckusick 	else
2788142Smckusick 		oldsize = 0;
27912214Ssam 	spacefree = odp->d_reclen - oldsize;
2808142Smckusick 	dp = (struct direct *)((int)odp + oldsize);
2818142Smckusick 	dp->d_ino = inum;
2828142Smckusick 	dp->d_namlen = strlen(str);
2838142Smckusick 	newsize = DIRSIZ(dp);
28412214Ssam 	if (spacefree >= newsize) {
2858142Smckusick 		odp->d_reclen = oldsize;
28612214Ssam 		dp->d_reclen = spacefree;
2878142Smckusick 	} else {
2888142Smckusick 		dp = (struct direct *)((int)odp + odp->d_reclen);
2898142Smckusick 		if ((int)dp - (int)buf >= fs->fs_bsize) {
2908142Smckusick 			printf("directory too large\n");
2918142Smckusick 			exit(1);
2928142Smckusick 		}
2938142Smckusick 		dp->d_ino = inum;
2948142Smckusick 		dp->d_namlen = strlen(str);
2958142Smckusick 		dp->d_reclen = DIRBLKSIZ;
2968142Smckusick 	}
2978142Smckusick 	strcpy(dp->d_name, str);
29839474Smckusick 	ip->di_size = (int)dp - (int)buf + newsize;
2998142Smckusick }
3008142Smckusick 
3018142Smckusick newblk(buf, aibc, ib, size)
3028142Smckusick 	int *aibc;
3038142Smckusick 	char *buf;
3048142Smckusick 	daddr_t *ib;
3058142Smckusick 	int size;
3068142Smckusick {
3078142Smckusick 	int i;
30833139Sbostic 	daddr_t bno, alloc();
3098142Smckusick 
3108142Smckusick 	bno = alloc(size);
3118142Smckusick 	wtfs(fsbtodb(fs, bno), (int)fs->fs_bsize, buf);
3128142Smckusick 	for (i = 0; i < fs->fs_bsize; i++)
3138142Smckusick 		buf[i] = 0;
3148142Smckusick 	ib[(*aibc)++] = bno;
3158142Smckusick 	if (*aibc >= NINDIR(fs)) {
3168142Smckusick 		printf("indirect block full\n");
3178142Smckusick 		errs++;
3188142Smckusick 		*aibc = 0;
3198142Smckusick 	}
3208142Smckusick }
3218142Smckusick 
32239474Smckusick iput(ip, aibc, ib, inum)
32339474Smckusick 	struct dinode *ip;
3248142Smckusick 	int *aibc;
3258142Smckusick 	daddr_t *ib;
32639474Smckusick 	ino_t inum;
3278142Smckusick {
32854065Sbostic 	struct dinode buf[MAXBSIZE / sizeof (struct dinode)];
32933139Sbostic 	daddr_t d, alloc();
3308142Smckusick 	int i;
33154065Sbostic 	struct timeval t;
3328142Smckusick 
33354065Sbostic 	(void)gettimeofday(&t, NULL);
33454065Sbostic 	ip->di_atime.ts_sec = t.tv_sec;
33554065Sbostic 	ip->di_atime.ts_nsec = 0;
33654059Sbostic 	ip->di_mtime = ip->di_ctime = ip->di_atime;
33739474Smckusick 	switch (ip->di_mode&IFMT) {
3388142Smckusick 
3398142Smckusick 	case IFDIR:
3408142Smckusick 	case IFREG:
3418142Smckusick 		for (i = 0; i < *aibc; i++) {
3428142Smckusick 			if (i >= NDADDR)
3438142Smckusick 				break;
34439474Smckusick 			ip->di_db[i] = ib[i];
3458142Smckusick 		}
3468142Smckusick 		if (*aibc > NDADDR) {
34739474Smckusick 			ip->di_ib[0] = alloc((int)fs->fs_bsize);
3488142Smckusick 			for (i = 0; i < NINDIR(fs) - NDADDR; i++) {
3498142Smckusick 				ib[i] = ib[i+NDADDR];
3508142Smckusick 				ib[i+NDADDR] = (daddr_t)0;
3518142Smckusick 			}
35239474Smckusick 			wtfs(fsbtodb(fs, ip->di_ib[0]),
3538142Smckusick 			    (int)fs->fs_bsize, (char *)ib);
3548142Smckusick 		}
3558142Smckusick 		break;
3568142Smckusick 
3578142Smckusick 	case IFBLK:
3588142Smckusick 	case IFCHR:
3598142Smckusick 		break;
3608142Smckusick 
3618142Smckusick 	default:
36239474Smckusick 		printf("bad mode %o\n", ip->di_mode);
3638142Smckusick 		exit(1);
3648142Smckusick 	}
36539474Smckusick 	d = fsbtodb(fs, itod(fs, inum));
3668142Smckusick 	rdfs(d, (int)fs->fs_bsize, (char *)buf);
36739474Smckusick 	buf[itoo(fs, inum)] = *ip;
3688142Smckusick 	wtfs(d, (int)fs->fs_bsize, (char *)buf);
3698142Smckusick }
3708142Smckusick 
3718142Smckusick daddr_t
3728142Smckusick alloc(size)
3738142Smckusick 	int size;
3748142Smckusick {
3758142Smckusick 	int i, frag;
3768142Smckusick 	daddr_t d;
3778142Smckusick 	static int cg = 0;
3788142Smckusick 
3798142Smckusick again:
3808142Smckusick 	rdfs(fsbtodb(&sblock, cgtod(&sblock, cg)), (int)sblock.fs_cgsize,
3818142Smckusick 	    (char *)&acg);
38234575Smckusick 	if (!cg_chkmagic(&acg)) {
3838142Smckusick 		printf("cg %d: bad magic number\n", cg);
3848142Smckusick 		return (0);
3858142Smckusick 	}
3868142Smckusick 	if (acg.cg_cs.cs_nbfree == 0) {
3878142Smckusick 		cg++;
3888142Smckusick 		if (cg >= fs->fs_ncg) {
3898142Smckusick 			printf("ran out of space\n");
3908142Smckusick 			return (0);
3918142Smckusick 		}
3928142Smckusick 		goto again;
3938142Smckusick 	}
3948142Smckusick 	for (d = 0; d < acg.cg_ndblk; d += sblock.fs_frag)
39534575Smckusick 		if (isblock(&sblock, (u_char *)cg_blksfree(&acg),
39634575Smckusick 		    d / sblock.fs_frag))
3978142Smckusick 			goto goth;
3988142Smckusick 	printf("internal error: can't find block in cyl %d\n", cg);
3998142Smckusick 	return (0);
4008142Smckusick goth:
40134575Smckusick 	clrblock(&sblock, (u_char *)cg_blksfree(&acg), d / sblock.fs_frag);
4028142Smckusick 	acg.cg_cs.cs_nbfree--;
4038142Smckusick 	sblock.fs_cstotal.cs_nbfree--;
4048142Smckusick 	fscs[cg].cs_nbfree--;
40534575Smckusick 	cg_blktot(&acg)[cbtocylno(&sblock, d)]--;
40634575Smckusick 	cg_blks(&sblock, &acg, cbtocylno(&sblock, d))[cbtorpos(&sblock, d)]--;
4078142Smckusick 	if (size != sblock.fs_bsize) {
4088142Smckusick 		frag = howmany(size, sblock.fs_fsize);
4098142Smckusick 		fscs[cg].cs_nffree += sblock.fs_frag - frag;
4108142Smckusick 		sblock.fs_cstotal.cs_nffree += sblock.fs_frag - frag;
4118142Smckusick 		acg.cg_cs.cs_nffree += sblock.fs_frag - frag;
4128142Smckusick 		acg.cg_frsum[sblock.fs_frag - frag]++;
4138142Smckusick 		for (i = frag; i < sblock.fs_frag; i++)
41434575Smckusick 			setbit(cg_blksfree(&acg), d + i);
4158142Smckusick 	}
4168142Smckusick 	wtfs(fsbtodb(&sblock, cgtod(&sblock, cg)), (int)sblock.fs_cgsize,
4178142Smckusick 	    (char *)&acg);
4188142Smckusick 	return (acg.cg_cgx * fs->fs_fpg + d);
4198142Smckusick }
4208142Smckusick 
4218142Smckusick /*
4228142Smckusick  * Allocate an inode on the disk
4238142Smckusick  */
42439474Smckusick ino_t
4258142Smckusick ialloc(ip)
42639474Smckusick 	register struct dinode *ip;
4278142Smckusick {
42839474Smckusick 	ino_t inum;
4298142Smckusick 	int c;
4308142Smckusick 
43139474Smckusick 	inum = ++ino;
43239474Smckusick 	c = itog(&sblock, inum);
4338142Smckusick 	rdfs(fsbtodb(&sblock, cgtod(&sblock, c)), (int)sblock.fs_cgsize,
4348142Smckusick 	    (char *)&acg);
43534575Smckusick 	if (!cg_chkmagic(&acg)) {
4368142Smckusick 		printf("cg %d: bad magic number\n", c);
4378142Smckusick 		exit(1);
4388142Smckusick 	}
43939474Smckusick 	if (ip->di_mode & IFDIR) {
4408142Smckusick 		acg.cg_cs.cs_ndir++;
4418142Smckusick 		sblock.fs_cstotal.cs_ndir++;
4428142Smckusick 		fscs[c].cs_ndir++;
4438142Smckusick 	}
4448142Smckusick 	acg.cg_cs.cs_nifree--;
44539474Smckusick 	setbit(cg_inosused(&acg), inum);
4468142Smckusick 	wtfs(fsbtodb(&sblock, cgtod(&sblock, c)), (int)sblock.fs_cgsize,
4478142Smckusick 	    (char *)&acg);
4488142Smckusick 	sblock.fs_cstotal.cs_nifree--;
4498142Smckusick 	fscs[c].cs_nifree--;
45039474Smckusick 	if(inum >= sblock.fs_ipg * sblock.fs_ncg) {
45139474Smckusick 		printf("fsinit: inode value out of range (%lu).\n", inum);
4528142Smckusick 		exit(1);
4538142Smckusick 	}
45439474Smckusick 	return (inum);
4558142Smckusick }
4568142Smckusick 
4578142Smckusick /*
4588142Smckusick  * read a block from the file system
4598142Smckusick  */
4608142Smckusick rdfs(bno, size, bf)
4618142Smckusick 	int bno, size;
4628142Smckusick 	char *bf;
4638142Smckusick {
4648142Smckusick 	int n;
46533139Sbostic 	off_t lseek();
4668142Smckusick 
46730558Smckusick 	if (lseek(fsi, bno * dev_bsize, 0) < 0) {
46833139Sbostic 		printf("seek error: %d\n", bno);
4698142Smckusick 		perror("rdfs");
4708142Smckusick 		exit(1);
4718142Smckusick 	}
4728142Smckusick 	n = read(fsi, bf, size);
4738142Smckusick 	if(n != size) {
47433139Sbostic 		printf("read error: %d\n", bno);
4758142Smckusick 		perror("rdfs");
4768142Smckusick 		exit(1);
4778142Smckusick 	}
4788142Smckusick }
4798142Smckusick 
4808142Smckusick /*
4818142Smckusick  * write a block to the file system
4828142Smckusick  */
4838142Smckusick wtfs(bno, size, bf)
4848142Smckusick 	int bno, size;
4858142Smckusick 	char *bf;
4868142Smckusick {
4878142Smckusick 	int n;
48833139Sbostic 	off_t lseek();
4898142Smckusick 
49030558Smckusick 	if (lseek(fso, bno * dev_bsize, 0) < 0) {
49133139Sbostic 		printf("seek error: %d\n", bno);
4928142Smckusick 		perror("wtfs");
4938142Smckusick 		exit(1);
4948142Smckusick 	}
4958142Smckusick 	n = write(fso, bf, size);
4968142Smckusick 	if(n != size) {
49733139Sbostic 		printf("write error: %d\n", bno);
4988142Smckusick 		perror("wtfs");
4998142Smckusick 		exit(1);
5008142Smckusick 	}
5018142Smckusick }
5028142Smckusick /*
5038142Smckusick  * check if a block is available
5048142Smckusick  */
5058142Smckusick isblock(fs, cp, h)
5068142Smckusick 	struct fs *fs;
5078142Smckusick 	unsigned char *cp;
5088142Smckusick 	int h;
5098142Smckusick {
5108142Smckusick 	unsigned char mask;
5118142Smckusick 
5128142Smckusick 	switch (fs->fs_frag) {
5138142Smckusick 	case 8:
5148142Smckusick 		return (cp[h] == 0xff);
5158142Smckusick 	case 4:
5168142Smckusick 		mask = 0x0f << ((h & 0x1) << 2);
5178142Smckusick 		return ((cp[h >> 1] & mask) == mask);
5188142Smckusick 	case 2:
5198142Smckusick 		mask = 0x03 << ((h & 0x3) << 1);
5208142Smckusick 		return ((cp[h >> 2] & mask) == mask);
5218142Smckusick 	case 1:
5228142Smckusick 		mask = 0x01 << (h & 0x7);
5238142Smckusick 		return ((cp[h >> 3] & mask) == mask);
5248142Smckusick 	default:
52533139Sbostic 		fprintf(stderr, "isblock bad fs_frag %ld\n", fs->fs_frag);
5268142Smckusick 		return (0);
5278142Smckusick 	}
5288142Smckusick 	/*NOTREACHED*/
5298142Smckusick }
5308142Smckusick 
5318142Smckusick /*
5328142Smckusick  * take a block out of the map
5338142Smckusick  */
5348142Smckusick clrblock(fs, cp, h)
5358142Smckusick 	struct fs *fs;
5368142Smckusick 	unsigned char *cp;
5378142Smckusick 	int h;
5388142Smckusick {
5398142Smckusick 	switch ((fs)->fs_frag) {
5408142Smckusick 	case 8:
5418142Smckusick 		cp[h] = 0;
5428142Smckusick 		return;
5438142Smckusick 	case 4:
5448142Smckusick 		cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
5458142Smckusick 		return;
5468142Smckusick 	case 2:
5478142Smckusick 		cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
5488142Smckusick 		return;
5498142Smckusick 	case 1:
5508142Smckusick 		cp[h >> 3] &= ~(0x01 << (h & 0x7));
5518142Smckusick 		return;
5528142Smckusick 	default:
55333139Sbostic 		fprintf(stderr, "clrblock bad fs_frag %ld\n", fs->fs_frag);
5548142Smckusick 		return;
5558142Smckusick 	}
5568142Smckusick }
5578142Smckusick 
558