xref: /original-bsd/old/arff/arff.c (revision 2e5d0128)
12e57d5edSdist /*
22e57d5edSdist  * Copyright (c) 1980 Regents of the University of California.
32e57d5edSdist  * All rights reserved.  The Berkeley software License Agreement
42e57d5edSdist  * specifies the terms and conditions for redistribution.
52e57d5edSdist  */
62e57d5edSdist 
7b74381a6Ssam #ifndef lint
82e57d5edSdist char copyright[] =
92e57d5edSdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\
102e57d5edSdist  All rights reserved.\n";
112e57d5edSdist #endif not lint
122e57d5edSdist 
132e57d5edSdist #ifndef lint
14*2e5d0128Sbloom static char sccsid[] = "@(#)arff.c	5.2 (Berkeley) 02/11/86";
152e57d5edSdist #endif not lint
16c09a6a34Ssam 
171437cf11Sbill #include <sys/types.h>
181437cf11Sbill #include <sys/stat.h>
191bbff716Ssam #include <sys/time.h>
201437cf11Sbill #include <signal.h>
211437cf11Sbill #include <stdio.h>
2219251218Ssam #include <sys/file.h>
23c09a6a34Ssam 
241437cf11Sbill #define dbprintf printf
25c09a6a34Ssam 
261437cf11Sbill struct rt_dat {
27c09a6a34Ssam 	u_short	rt_yr:5;	/* year-1972 */
28c09a6a34Ssam 	u_short	rt_dy:5;	/* day */
29c09a6a34Ssam 	u_short	rt_mo:5;	/* month */
301437cf11Sbill };
31c09a6a34Ssam 
321437cf11Sbill struct	rt_axent {
331437cf11Sbill 	char	rt_sent[14];
341437cf11Sbill };
351437cf11Sbill 
361437cf11Sbill struct rt_ent {
371437cf11Sbill 	char	rt_pad;		/* unusued */
38c09a6a34Ssam 	char	rt_stat;	/* type of entry, or end of seg */
39c09a6a34Ssam 	u_short	rt_name[3];	/* name, 3 words in rad50 form */
402ef99505Swnj 	u_short	rt_len;		/* length of file */
41c09a6a34Ssam 	char	rt_chan;	/* only used in temporary files */
42c09a6a34Ssam 	char	rt_job;		/* only used in temporary files */
43c09a6a34Ssam 	struct	rt_dat rt_date;	/* creation date */
441437cf11Sbill };
45c09a6a34Ssam 
461437cf11Sbill #define RT_TEMP		1
471437cf11Sbill #define RT_NULL		2
481437cf11Sbill #define RT_FILE		4
491437cf11Sbill #define RT_ESEG		8
50c09a6a34Ssam 
51c09a6a34Ssam #define RT_BLOCK	512	/* block size */
52d0b9e33eSwnj #define RT_DIRSIZE	31	/* max # of directory segments */
53c09a6a34Ssam 
541437cf11Sbill struct rt_head {
55c09a6a34Ssam 	short	rt_numseg;	/* # of segments available */
56c09a6a34Ssam 	short	rt_nxtseg;	/* # of next logical segment */
57c09a6a34Ssam 	short	rt_lstseg;	/* highest seg currently open */
58c09a6a34Ssam 	u_short	rt_entpad;	/* extra words/directory entry */
59c09a6a34Ssam 	short	rt_stfile;	/* block # where files begin */
601437cf11Sbill };
61c09a6a34Ssam 
621437cf11Sbill struct	rt_dir {
631437cf11Sbill 	struct rt_head	rt_axhead;
641437cf11Sbill 	struct rt_ent	rt_ents[72];
651437cf11Sbill 	char		_dirpad[6];
661437cf11Sbill };
67c09a6a34Ssam 
68*2e5d0128Sbloom #define rd_numseg rt_axhead.rt_numseg
69*2e5d0128Sbloom #define rd_nxtseg rt_axhead.rt_nxtseg
70*2e5d0128Sbloom #define rd_lstseg rt_axhead.rt_lstseg
71*2e5d0128Sbloom #define rd_entpad rt_axhead.rt_entpad
72*2e5d0128Sbloom #define rd_stfile rt_axhead.rt_stfile
73*2e5d0128Sbloom 
741437cf11Sbill typedef struct fldope {
751437cf11Sbill 	int	startad;
761437cf11Sbill 	int	count;
771437cf11Sbill struct	rt_ent	*rtdope;
781437cf11Sbill } FLDOPE;
79c09a6a34Ssam 
801437cf11Sbill FLDOPE *lookup();
81c09a6a34Ssam 
821437cf11Sbill #define	rt(p)	((struct rt_ent *) p )
831437cf11Sbill #define	Ain1	03100
841437cf11Sbill #define	Ain2	050
85c09a6a34Ssam #define	flag(c)	(flg[('c') - 'a'])
861437cf11Sbill 
87c09a6a34Ssam char	*man = "rxtd";
881437cf11Sbill char	zeroes[512];
89c09a6a34Ssam 
901437cf11Sbill extern char *val;
911437cf11Sbill extern char table[256];
92c09a6a34Ssam struct rt_dir rt_dir[RT_DIRSIZE] = {
93c09a6a34Ssam 	{ 4, 0, 1, 0, 14 },
94*2e5d0128Sbloom 	{ { 0, RT_NULL, { 0, 0, 0 }, 486, 0 },
95*2e5d0128Sbloom 	  { 0, RT_ESEG } }
96*2e5d0128Sbloom };
97*2e5d0128Sbloom 
98*2e5d0128Sbloom struct rt_dir rt_nulldir = {
99*2e5d0128Sbloom 	{ 0, 0, 0, 0, 0 },
100*2e5d0128Sbloom 	{ { 0, RT_NULL, { 0, 0, 0 }, 0, 0 },
101b74381a6Ssam 	  { 0, RT_ESEG } }
102c09a6a34Ssam };
103c09a6a34Ssam 
1041437cf11Sbill int	rt_entsiz;
1051437cf11Sbill int	rt_nleft;
106d0b9e33eSwnj struct rt_ent *rt_curend[RT_DIRSIZE];
1071437cf11Sbill int	floppydes;
1081437cf11Sbill int	dirdirty;
1091437cf11Sbill char	*rt_last;
1101437cf11Sbill char	*defdev = "/dev/floppy";
1111437cf11Sbill 
112*2e5d0128Sbloom char *opt = "vfbcm";
1131437cf11Sbill 
114c09a6a34Ssam extern long lseek();
115c09a6a34Ssam int	rcmd(), dcmd(), xcmd(), tcmd();
116c09a6a34Ssam 
1171437cf11Sbill int	(*comfun)();
1181437cf11Sbill char	flg[26];
1191437cf11Sbill char	**namv;
1201437cf11Sbill int	namc;
1211437cf11Sbill 
1221437cf11Sbill main(argc, argv)
1231437cf11Sbill 	char *argv[];
1241437cf11Sbill {
1251437cf11Sbill 	register char *cp;
1261437cf11Sbill 
1271437cf11Sbill 	if (argc < 2)
1281437cf11Sbill 		usage();
1291437cf11Sbill 	for (cp = argv[1]; *cp; cp++)
1301437cf11Sbill 		switch (*cp) {
131c09a6a34Ssam 
1321437cf11Sbill 		case 'm':
1331437cf11Sbill 		case 'v':
1341437cf11Sbill 		case 'u':
1351437cf11Sbill 		case 'w':
136*2e5d0128Sbloom 		case 'b':
1371437cf11Sbill 			flg[*cp-'a']++;
1381437cf11Sbill 			continue;
1391437cf11Sbill 		case 'c':
140c09a6a34Ssam 			flag(c)++;
1411437cf11Sbill 			dirdirty++;
1421437cf11Sbill 			continue;
1431437cf11Sbill 
1441437cf11Sbill 		case 'r':
1451437cf11Sbill 			setcom(rcmd);
146c09a6a34Ssam 			flag(r)++;
1471437cf11Sbill 			continue;
1481437cf11Sbill 
1491437cf11Sbill 		case 'd':
1501437cf11Sbill 			setcom(dcmd);
151c09a6a34Ssam 			flag(d)++;
1521437cf11Sbill 			continue;
1531437cf11Sbill 
1541437cf11Sbill 		case 'x':
1551437cf11Sbill 			setcom(xcmd);
1561437cf11Sbill 			continue;
1571437cf11Sbill 
1581437cf11Sbill 		case 't':
1591437cf11Sbill 			setcom(tcmd);
1601437cf11Sbill 			continue;
1611437cf11Sbill 
1621437cf11Sbill 		case 'f':
1631437cf11Sbill 			defdev = argv[2];
1641437cf11Sbill 			argv++;
1651437cf11Sbill 			argc--;
1661437cf11Sbill 			continue;
1671437cf11Sbill 
1681437cf11Sbill 		default:
1691437cf11Sbill 			fprintf(stderr, "arff: bad option `%c'\n", *cp);
1701437cf11Sbill 			exit(1);
1711437cf11Sbill 		}
172c09a6a34Ssam 
1731437cf11Sbill 	namv = argv+2;
1741437cf11Sbill 	namc = argc-2;
1751437cf11Sbill 	if (comfun == 0) {
176c09a6a34Ssam 		if (flag(u) == 0) {
177c09a6a34Ssam 			fprintf(stderr, "arff: one of [%s] must be specified\n",
178c09a6a34Ssam 				man);
1791437cf11Sbill 			exit(1);
1801437cf11Sbill 		}
1811437cf11Sbill 		setcom(rcmd);
1821437cf11Sbill 	}
1831437cf11Sbill 	(*comfun)();
1841437cf11Sbill 	exit(notfound());
1851437cf11Sbill }
1861437cf11Sbill 
1871437cf11Sbill setcom(fun)
1881437cf11Sbill 	int (*fun)();
1891437cf11Sbill {
1901437cf11Sbill 	if (comfun != 0) {
1911437cf11Sbill 		fprintf(stderr, "arff: only one of [%s] allowed\n", man);
1921437cf11Sbill 		exit(1);
1931437cf11Sbill 	}
1941437cf11Sbill 	comfun = fun;
1951437cf11Sbill }
1961437cf11Sbill 
1971437cf11Sbill usage()
1981437cf11Sbill {
199296c7c8aSwnj 	fprintf(stderr, "usage: ar [%s][%s] archive files ...\n", opt, man);
2001437cf11Sbill 	exit(1);
2011437cf11Sbill }
2021437cf11Sbill 
2031437cf11Sbill notfound()
2041437cf11Sbill {
205c09a6a34Ssam 	register i, n = 0;
2061437cf11Sbill 
2071437cf11Sbill 	for (i = 0; i < namc; i++)
2081437cf11Sbill 		if (namv[i]) {
2091437cf11Sbill 			fprintf(stderr, "arff: %s not found\n", namv[i]);
2101437cf11Sbill 			n++;
2111437cf11Sbill 		}
2121437cf11Sbill 	return (n);
2131437cf11Sbill }
2141437cf11Sbill 
2151437cf11Sbill tcmd()
2161437cf11Sbill {
217c09a6a34Ssam 	register char *de, *last;
2181437cf11Sbill 	FLDOPE *lookup(), *dope;
219c09a6a34Ssam 	int segnum, nleft;
220c09a6a34Ssam 	register i;
2211437cf11Sbill 	register struct rt_ent *rde;
2221437cf11Sbill 
2231437cf11Sbill 	rt_init();
224b74381a6Ssam 	if (namc != 0) {
225b74381a6Ssam 		for (i = 0; i < namc; i++)
226b74381a6Ssam 			if (dope = lookup(namv[i])) {
227b74381a6Ssam 				rde = dope->rtdope;
228*2e5d0128Sbloom 				(void) rtls(rde);
229b74381a6Ssam 				namv[i] = 0;
230b74381a6Ssam 			}
231b74381a6Ssam 		return;
232b74381a6Ssam 	}
233c09a6a34Ssam 	for (segnum = 0; segnum != -1;
234*2e5d0128Sbloom 	  segnum = rt_dir[segnum].rd_nxtseg - 1) {
235d0b9e33eSwnj 		last = rt_last + segnum*2*RT_BLOCK;
236d0b9e33eSwnj 		for (de = ((char *)&rt_dir[segnum])+10; de <= last;
237c09a6a34Ssam 		    de += rt_entsiz)
2381437cf11Sbill 			if (rtls(rt(de))) {
239d0b9e33eSwnj 				nleft = (last-de)/rt_entsiz;
240c09a6a34Ssam #define ENTRIES "\n%d entries remaining in directory segment %d.\n"
241c09a6a34Ssam 				printf(ENTRIES, nleft, segnum+1);
2421437cf11Sbill 				break;
2431437cf11Sbill 			}
2441437cf11Sbill 	}
2451437cf11Sbill }
246c09a6a34Ssam 
2471437cf11Sbill rtls(de)
2481437cf11Sbill 	register struct rt_ent *de;
2491437cf11Sbill {
2501437cf11Sbill 	int month, day, year;
2511437cf11Sbill 	char name[12], ext[4];
2521437cf11Sbill 
2531437cf11Sbill 	switch (de->rt_stat) {
254c09a6a34Ssam 
2551437cf11Sbill 	case RT_TEMP:
256c09a6a34Ssam 		if (flag(v))
2571437cf11Sbill 			printf("Tempfile:\n");
258c09a6a34Ssam 		/* fall thru...*/
259c09a6a34Ssam 
2601437cf11Sbill 	case RT_FILE:
261c09a6a34Ssam 		if (!flag(v)) {
262c09a6a34Ssam 			sunrad50(name, de->rt_name);
263c09a6a34Ssam 			printf("%s\n", name);
264c09a6a34Ssam 			break;
265c09a6a34Ssam 		}
2661437cf11Sbill 		unrad50(2, de->rt_name, name);
2671437cf11Sbill 		unrad50(1, &(de->rt_name[2]), ext);
2681437cf11Sbill 		day = de->rt_date.rt_dy;
2691437cf11Sbill 		year = de->rt_date.rt_yr+72;
2701437cf11Sbill 		month = de->rt_date.rt_mo;
2711437cf11Sbill 		printf("%6.6s  %3.3s	%02d/%02d/%02d	%d\n",name,
2721437cf11Sbill 			ext, month, day, year, de->rt_len);
2731437cf11Sbill 		break;
2741437cf11Sbill 
2751437cf11Sbill 	case RT_NULL:
2761437cf11Sbill 		printf("%-25.9s	%d\n","<UNUSED>", de->rt_len);
2771437cf11Sbill 		break;
2781437cf11Sbill 
2791437cf11Sbill 	case RT_ESEG:
2801437cf11Sbill 		return (1);
2811437cf11Sbill 	}
2821437cf11Sbill 	return (0);
2831437cf11Sbill }
284c09a6a34Ssam 
2851437cf11Sbill xcmd()
2861437cf11Sbill {
287c09a6a34Ssam 	register char *de, *last;
288d0b9e33eSwnj 	int segnum;
2891437cf11Sbill 	char name[12];
2901437cf11Sbill 	register int i;
2911437cf11Sbill 
2921437cf11Sbill 	rt_init();
293b74381a6Ssam 	if (namc != 0) {
294b74381a6Ssam 		for (i = 0; i < namc; i++)
295b74381a6Ssam 			if (rtx(namv[i]) == 0)
296b74381a6Ssam 				namv[i] = 0;
297b74381a6Ssam 		return;
298b74381a6Ssam 	}
299c09a6a34Ssam 	for (segnum = 0; segnum != -1;
300*2e5d0128Sbloom 	     segnum = rt_dir[segnum].rd_nxtseg-1)
301c09a6a34Ssam 		for (last = rt_last+(segnum*2*RT_BLOCK),
302c09a6a34Ssam 		     de = ((char *)&rt_dir[segnum])+10; de <= last;
30367f39843Sralph 		     de += rt_entsiz) {
3040200ad53Swnj 			switch (rt(de)->rt_stat) {
305b74381a6Ssam 
3060200ad53Swnj 			case RT_ESEG:
30767f39843Sralph 				break;	/* exit loop and try next segment */
308b74381a6Ssam 
3090200ad53Swnj 			case RT_TEMP:
3100200ad53Swnj 			case RT_FILE:
3110200ad53Swnj 				sunrad50(name,rt(de)->rt_name);
312*2e5d0128Sbloom 				(void) rtx(name);
313b74381a6Ssam 
3140200ad53Swnj 			case RT_NULL:
31567f39843Sralph 			default:
31667f39843Sralph 				continue;
31767f39843Sralph 			}
318b74381a6Ssam 			break;
3190200ad53Swnj 		}
3201437cf11Sbill }
321c09a6a34Ssam 
3221437cf11Sbill rtx(name)
3231437cf11Sbill 	char *name;
3241437cf11Sbill {
3251437cf11Sbill 	register FLDOPE *dope;
3261437cf11Sbill 	FLDOPE *lookup();
3271437cf11Sbill 	register startad, count;
328c09a6a34Ssam 	int file;
329c09a6a34Ssam 	char buff[512];
3301437cf11Sbill 
3311437cf11Sbill 
3321437cf11Sbill 	if (dope = lookup(name)) {
333c09a6a34Ssam 		if (flag(v))
334*2e5d0128Sbloom 			(void) rtls(dope->rtdope);
3351437cf11Sbill 		else
3361437cf11Sbill 			printf("x - %s\n",name);
3371437cf11Sbill 
338c09a6a34Ssam 		if ((file = creat(name, 0666)) < 0)
339c09a6a34Ssam 			return (1);
3401437cf11Sbill 		count = dope->count;
3411437cf11Sbill 		startad = dope->startad;
3421437cf11Sbill 		for( ; count > 0 ; count -= 512) {
3431437cf11Sbill 			lread(startad, 512, buff);
344*2e5d0128Sbloom 			(void) write(file, buff, 512);
3451437cf11Sbill 			startad += 512;
3461437cf11Sbill 		}
347*2e5d0128Sbloom 		(void) close(file);
3481437cf11Sbill 		return (0);
3491437cf11Sbill 	}
3501437cf11Sbill 	return (1);
3511437cf11Sbill }
352c09a6a34Ssam 
3531437cf11Sbill rt_init()
3541437cf11Sbill {
3551437cf11Sbill 	static initized = 0;
356c09a6a34Ssam 	register char *de, *last;
357d0b9e33eSwnj 	register i;
358a11ea3b6Shickman 	int dirnum;
359a11ea3b6Shickman 	char *mode;
360a11ea3b6Shickman 	FILE *temp_floppydes;
3611437cf11Sbill 
362c09a6a34Ssam 	if (initized)
363c09a6a34Ssam 		return;
3641437cf11Sbill 	initized = 1;
36519251218Ssam 	if (flag(c)) {
36619251218Ssam 		struct stat sb;
36719251218Ssam 		char response[128];
36819251218Ssam 		int tty;
36919251218Ssam 
37019251218Ssam 		if (stat(defdev, &sb) >= 0 && (sb.st_mode & S_IFMT) == S_IFREG)
37119251218Ssam 			goto ignore;
37219251218Ssam 		tty = open("/dev/tty", O_RDWR);
37319251218Ssam #define SURE	"Are you sure you want to clobber the floppy? "
374*2e5d0128Sbloom 		(void) write(tty, SURE, sizeof (SURE));
375*2e5d0128Sbloom 		(void) read(tty, response, sizeof (response));
37619251218Ssam 		if (*response != 'y')
37719251218Ssam 			exit(50);
378*2e5d0128Sbloom 		(void) close(tty);
37919251218Ssam ignore:
38019251218Ssam 		;
38119251218Ssam 	}
382c09a6a34Ssam 	if (flag(c) || flag(d) || flag(r))
383a11ea3b6Shickman 		mode = "r+";
3841437cf11Sbill 	else
385a11ea3b6Shickman 		mode = "r";
386a11ea3b6Shickman 	if ((temp_floppydes = fopen(defdev, mode)) == NULL) {
387a11ea3b6Shickman 		perror(defdev);
388296c7c8aSwnj 		exit(1);
389a11ea3b6Shickman 	} else
390a11ea3b6Shickman 		floppydes = fileno(temp_floppydes);
391c09a6a34Ssam 	if (!flag(c)) {
392d0b9e33eSwnj 		lread(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]);
393*2e5d0128Sbloom 		dirnum = rt_dir[0].rd_numseg;
394254d8466Shelge 		/* check for blank/uninitialized diskette */
395254d8466Shelge 		if (dirnum <= 0) {
396254d8466Shelge 			fprintf(stderr,"arff: bad directory format\n");
397254d8466Shelge 			exit(1);
398254d8466Shelge 		}
399d0b9e33eSwnj 		if (dirnum > RT_DIRSIZE) {
400d0b9e33eSwnj 			fprintf(stderr,"arff: too many directory segments\n");
401d0b9e33eSwnj 			exit(1);
402d0b9e33eSwnj 		}
403d0b9e33eSwnj 		for (i = 1; i < dirnum; i++)
404d0b9e33eSwnj 			lread((6+2*i)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[i]);
405*2e5d0128Sbloom 	} else {
40619ec2be6Sroot 		dirnum = 1;
407*2e5d0128Sbloom 		if (flag(b)) {
408*2e5d0128Sbloom 			rt_dir[0].rd_numseg = 31;
409*2e5d0128Sbloom 			rt_dir[0].rd_stfile = 68;
410*2e5d0128Sbloom 			rt_dir[0].rt_ents[0].rt_len = 20480 - 68;
411*2e5d0128Sbloom 		}
412*2e5d0128Sbloom 	}
4131437cf11Sbill 
414*2e5d0128Sbloom 	rt_entsiz = 2*rt_dir[0].rd_entpad + 14;
415*2e5d0128Sbloom 	/*
416*2e5d0128Sbloom 	 * We assume that the directory entries have no padding.  This
417*2e5d0128Sbloom 	 * may not be a valid assumption, but there are numerous point
418*2e5d0128Sbloom 	 * in the code where it assumes it is an rt_ent structure and
419*2e5d0128Sbloom 	 * not an rt_entsiz sized structure.
420*2e5d0128Sbloom 	 */
421*2e5d0128Sbloom 	rt_entsiz = 14;
422d0b9e33eSwnj 	rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz;
423d0b9e33eSwnj 	rt_nleft = 0;
424d0b9e33eSwnj 
425d0b9e33eSwnj 	for (i = 0; i < dirnum; i++) {
426d0b9e33eSwnj 		last = rt_last + i*2*RT_BLOCK;
427c09a6a34Ssam 		for (de = ((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz)
428c09a6a34Ssam 			if (rt(de)->rt_stat == RT_ESEG)
429c09a6a34Ssam 				break;
430d0b9e33eSwnj 		rt_curend[i] = rt(de);
431d0b9e33eSwnj 		rt_nleft += (last-de)/rt_entsiz;
432d0b9e33eSwnj 	}
4331437cf11Sbill }
4341437cf11Sbill 
4351437cf11Sbill static FLDOPE result;
436c09a6a34Ssam 
4371437cf11Sbill FLDOPE *
4381437cf11Sbill lookup(name)
4391437cf11Sbill 	char *name;
4401437cf11Sbill {
4411437cf11Sbill 	unsigned short rname[3];
442*2e5d0128Sbloom 	register char *de;
443d0b9e33eSwnj 	int segnum;
4441437cf11Sbill 	register index;
4451437cf11Sbill 
4461437cf11Sbill 	srad50(name,rname);
4471437cf11Sbill 
4481437cf11Sbill 	/*
4491437cf11Sbill 	 *  Search for name, accumulate blocks in index
4501437cf11Sbill 	 */
4511437cf11Sbill 	rt_init();
452c09a6a34Ssam 	for (segnum = 0; segnum != -1;
453*2e5d0128Sbloom 	     segnum = rt_dir[segnum].rd_nxtseg - 1)
454c09a6a34Ssam 	{
4551437cf11Sbill 		index = 0;
456d0b9e33eSwnj 		for (de=((char *)&rt_dir[segnum])+10;
457c09a6a34Ssam 		     rt(de)->rt_stat != RT_ESEG; de += rt_entsiz)
4581437cf11Sbill 			switch(rt(de)->rt_stat) {
459c09a6a34Ssam 
4601437cf11Sbill 			case RT_FILE:
4611437cf11Sbill 			case RT_TEMP:
462c09a6a34Ssam 				if(samename(rname,rt(de)->rt_name)) {
463c09a6a34Ssam 					result.count = rt(de)->rt_len * 512;
464c09a6a34Ssam 					result.startad = 512*
465*2e5d0128Sbloom 					    (rt_dir[segnum].rd_stfile + index);
466c09a6a34Ssam 					result.rtdope = (struct rt_ent *) de;
467c09a6a34Ssam 					return (&result);
468c09a6a34Ssam 				}
469c09a6a34Ssam 
4701437cf11Sbill 			case RT_NULL:
4711437cf11Sbill 				index += rt(de)->rt_len;
4721437cf11Sbill 			}
4731437cf11Sbill         }
4741437cf11Sbill 	return ((FLDOPE *) 0);
475c09a6a34Ssam 
4761437cf11Sbill }
477c09a6a34Ssam 
4781437cf11Sbill static
4791437cf11Sbill samename(a, b)
480c09a6a34Ssam 	u_short a[], b[];
4811437cf11Sbill {
482c09a6a34Ssam 	return (*a == *b && a[1] == b[1] && a[2] == b[2] );
4831437cf11Sbill }
4841437cf11Sbill 
4851437cf11Sbill rad50(cp, out)
486c09a6a34Ssam 	register u_char *cp;
487c09a6a34Ssam 	u_short *out;
4881437cf11Sbill {
489c09a6a34Ssam 	register index, temp;
4901437cf11Sbill 
4911437cf11Sbill 	for (index = 0; *cp; index++) {
4921437cf11Sbill 		temp = Ain1 * table[*cp++];
4931437cf11Sbill 		if (*cp!=0) {
4941437cf11Sbill 			temp += Ain2 * table[*cp++];
4951437cf11Sbill 			if(*cp!=0)
4961437cf11Sbill 				temp += table[*cp++];
4971437cf11Sbill 		}
4981437cf11Sbill 		out[index] = temp;
4991437cf11Sbill 	}
5001437cf11Sbill }
501c09a6a34Ssam 
502c09a6a34Ssam #define reduce(x, p, q) (x = v[p/q], p %= q);
5031437cf11Sbill 
5041437cf11Sbill unrad50(count, in, cp)
505c09a6a34Ssam 	u_short *in;
5061437cf11Sbill 	register char *cp;
5071437cf11Sbill {
508c09a6a34Ssam 	register i, temp;
509c09a6a34Ssam 	register u_char *v = (u_char *) val;
5101437cf11Sbill 
5111437cf11Sbill 	for (i = 0; i < count; i++) {
5121437cf11Sbill 		temp = in[i];
5131437cf11Sbill 		reduce(*cp++, temp, Ain1);
5141437cf11Sbill 		reduce(*cp++, temp, Ain2);
5151437cf11Sbill 		reduce(*cp++, temp, 1);
5161437cf11Sbill 	}
5171437cf11Sbill 	*cp=0;
5181437cf11Sbill }
5191437cf11Sbill 
5201437cf11Sbill srad50(name, rname)
5211437cf11Sbill 	register char *name;
522c09a6a34Ssam 	register u_short *rname;
5231437cf11Sbill {
524c09a6a34Ssam 	register index;
525c09a6a34Ssam 	register char *cp;
5261437cf11Sbill 	char file[7], ext[4];
527c09a6a34Ssam 
5281437cf11Sbill 	/*
5291437cf11Sbill 	 * Find end of pathname
5301437cf11Sbill 	 */
531c09a6a34Ssam 	for (cp = name; *cp++; )
532c09a6a34Ssam 		;
533c09a6a34Ssam 	while (cp >= name && *--cp != '/')
534c09a6a34Ssam 		;
5351437cf11Sbill 	cp++;
5361437cf11Sbill 	/*
5371437cf11Sbill 	 * Change to rad50
5381437cf11Sbill 	 */
5391437cf11Sbill 	for (index = 0; *cp; ) {
5401437cf11Sbill 		file[index++] = *cp++;
5411437cf11Sbill 		if (*cp == '.') {
5421437cf11Sbill 			cp++;
5431437cf11Sbill 			break;
5441437cf11Sbill 		}
5451437cf11Sbill 		if (index >= 6) {
5461437cf11Sbill 			break;
5471437cf11Sbill 		}
5481437cf11Sbill 	}
5491437cf11Sbill 	file[index] = 0;
5501437cf11Sbill 	for (index = 0; *cp; ) {
5511437cf11Sbill 		ext[index++] = *cp++;
552c09a6a34Ssam 		if (*cp == '.' || index >= 3)
5531437cf11Sbill 			break;
5541437cf11Sbill 	}
5551437cf11Sbill 	ext[index]=0;
556c09a6a34Ssam 	rname[0] = rname[1] = rname[2] = 0;
557c09a6a34Ssam 	rad50((u_char *)file, rname);
558c09a6a34Ssam 	rad50((u_char *)ext, rname+2);
5591437cf11Sbill }
560c09a6a34Ssam 
5611437cf11Sbill sunrad50(name, rname)
562c09a6a34Ssam 	u_short rname[];
5631437cf11Sbill 	register char *name;
5641437cf11Sbill {
5651437cf11Sbill 	register char *cp, *cp2;
5661437cf11Sbill 	char ext[4];
5671437cf11Sbill 
5681437cf11Sbill 	unrad50(2, rname, name);
5691437cf11Sbill 	unrad50(1, rname + 2, ext);
570c09a6a34Ssam 	/*
571c09a6a34Ssam 	 * Jam name and extension together with a dot
572c09a6a34Ssam 	 * deleting white space
573c09a6a34Ssam 	 */
574c09a6a34Ssam 	for (cp = name; *cp++;)
575c09a6a34Ssam 		;
576c09a6a34Ssam 	--cp;
577c09a6a34Ssam 	while (*--cp == ' ' && cp >= name)
578c09a6a34Ssam 		;
579c09a6a34Ssam 	*++cp = '.';
580c09a6a34Ssam 	cp++;
581c09a6a34Ssam 	for (cp2 = ext; *cp2 != ' ' && cp2 < ext+3;)
5821437cf11Sbill 		*cp++ = *cp2++;
5831437cf11Sbill 	*cp=0;
584c09a6a34Ssam 	if (cp[-1] == '.')
585c09a6a34Ssam 		cp[-1] = 0;
5861437cf11Sbill }
5871437cf11Sbill 
5881437cf11Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789";
589c09a6a34Ssam 
5901437cf11Sbill static char table[256] = {
5911437cf11Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
5921437cf11Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
5931437cf11Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
5941437cf11Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
5951437cf11Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
5961437cf11Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
5971437cf11Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
5981437cf11Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
5991437cf11Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
6001437cf11Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
6011437cf11Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
6021437cf11Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
6031437cf11Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
6041437cf11Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
6051437cf11Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
6061437cf11Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 };
6071437cf11Sbill 
608c09a6a34Ssam /*
609c09a6a34Ssam  * Logical to physical adress translation
610c09a6a34Ssam  */
611c09a6a34Ssam long
612c09a6a34Ssam trans(logical)
6131437cf11Sbill 	register int logical;
6141437cf11Sbill {
6151437cf11Sbill 	register int sector, bytes, track;
6161437cf11Sbill 
6171437cf11Sbill 	logical += 26*128;
6181437cf11Sbill 	bytes = (logical&127);
6191437cf11Sbill 	logical >>= 7;
6201437cf11Sbill 	sector = logical%26;
6211437cf11Sbill 	if(sector >= 13)
6221437cf11Sbill 		sector = sector*2+1;
6231437cf11Sbill 	else
6241437cf11Sbill 		sector *= 2;
6251437cf11Sbill 	sector += 26 + ((track = (logical/26))-1)*6;
6261437cf11Sbill 	sector %= 26;
6271437cf11Sbill 	return ((((track*26)+sector) << 7) + bytes);
6281437cf11Sbill }
629c09a6a34Ssam 
6301437cf11Sbill lread(startad, count, obuff)
6311437cf11Sbill 	register startad, count;
6321437cf11Sbill 	register char *obuff;
6331437cf11Sbill {
6341437cf11Sbill 	long trans();
6351437cf11Sbill 	extern floppydes;
636c09a6a34Ssam 	register int size = flag(m) ? 512 : 128;
637c09a6a34Ssam 
6381437cf11Sbill 	rt_init();
639c09a6a34Ssam 	while ((count -= size) >= 0) {
640*2e5d0128Sbloom 		(void) lseek(floppydes, flag(m) ?
641c09a6a34Ssam 			(long)startad : trans(startad), 0);
642c09a6a34Ssam 		if (read(floppydes, obuff, size) != size)
643c09a6a34Ssam 			fprintf(stderr, "arff: read error block %d\n",
644c09a6a34Ssam 				startad/size);
645c09a6a34Ssam 		obuff += size;
646c09a6a34Ssam 		startad += size;
6471437cf11Sbill 	}
6481437cf11Sbill }
649c09a6a34Ssam 
6501437cf11Sbill lwrite(startad, count, obuff)
6511437cf11Sbill 	register startad, count;
6521437cf11Sbill 	register char *obuff;
6531437cf11Sbill {
6541437cf11Sbill 	long trans();
6551437cf11Sbill 	extern floppydes;
656c09a6a34Ssam 	register int size = flag(m) ? 512 : 128;
657c09a6a34Ssam 
6581437cf11Sbill 	rt_init();
659c09a6a34Ssam 	while ((count -= size) >= 0) {
660*2e5d0128Sbloom 		(void) lseek(floppydes, flag(m) ?
661c09a6a34Ssam 			(long)startad : trans(startad), 0);
662c09a6a34Ssam 		if (write(floppydes, obuff, size) != size)
663c09a6a34Ssam 			fprintf(stderr, "arff: write error block %d\n",
664c09a6a34Ssam 				startad/size);
665c09a6a34Ssam 		obuff += size;
666c09a6a34Ssam 		startad += size;
6671437cf11Sbill 	}
6681437cf11Sbill }
6691437cf11Sbill 
6701437cf11Sbill rcmd()
6711437cf11Sbill {
6721437cf11Sbill 	register int i;
6731437cf11Sbill 
6741437cf11Sbill 	rt_init();
6751437cf11Sbill 	if (namc > 0)
6761437cf11Sbill 		for (i = 0; i < namc; i++)
677c09a6a34Ssam 			if (rtr(namv[i]) == 0)
678c09a6a34Ssam 				namv[i] = 0;
6791437cf11Sbill }
6801437cf11Sbill 
6811437cf11Sbill rtr(name)
6821437cf11Sbill 	char *name;
6831437cf11Sbill {
684c09a6a34Ssam 	register FLDOPE *dope;
685c09a6a34Ssam 	register struct rt_ent *de;
686c09a6a34Ssam 	struct stat buf;
687c09a6a34Ssam 	register struct stat *bufp = &buf;
688d0b9e33eSwnj 	int segnum;
689*2e5d0128Sbloom 	char type;
6901437cf11Sbill 
69119ec2be6Sroot 	if (stat(name, bufp) < 0) {
69219ec2be6Sroot 		perror(name);
69319ec2be6Sroot 		return (-1);
69419ec2be6Sroot 	}
695*2e5d0128Sbloom 	type = 'a';
6961437cf11Sbill 	if (dope = lookup(name)) {
6971437cf11Sbill 		/* can replace, no problem */
6981437cf11Sbill 		de = dope->rtdope;
699*2e5d0128Sbloom 		if (bufp->st_size <= (de->rt_len * 512)) {
700*2e5d0128Sbloom 			printf("r - %s\n",name);
7011437cf11Sbill 			toflop(name, bufp->st_size, dope);
702b74381a6Ssam 			goto found;
703*2e5d0128Sbloom 		} else {
704*2e5d0128Sbloom 			de = dope->rtdope;
705*2e5d0128Sbloom 			type = 'r';
706*2e5d0128Sbloom 			de->rt_stat = RT_NULL;
707*2e5d0128Sbloom 			de->rt_name[0] = 0;
708*2e5d0128Sbloom 			de->rt_name[1] = 0;
709*2e5d0128Sbloom 			de->rt_name[2] = 0;
710*2e5d0128Sbloom 			*((u_short *)&(de->rt_date)) = 0;
711*2e5d0128Sbloom 			scrunch();
712*2e5d0128Sbloom 		}
713b74381a6Ssam 	}
714b74381a6Ssam 	/*
715b74381a6Ssam 	 * Search for vacant spot
716b74381a6Ssam 	 */
717c09a6a34Ssam 	for (segnum = 0; segnum != -1;
718*2e5d0128Sbloom 	     segnum = rt_dir[segnum].rd_nxtseg - 1)
719c09a6a34Ssam 	{
720d0b9e33eSwnj 		for (de = rt_dir[segnum].rt_ents;
721c09a6a34Ssam 		    rt(de)->rt_stat != RT_ESEG; de++)
722c09a6a34Ssam 			if ((de)->rt_stat == RT_NULL) {
7231437cf11Sbill 				if (bufp->st_size <= (de->rt_len*512)) {
724*2e5d0128Sbloom 					printf("%c - %s\n", type, name),
725d0b9e33eSwnj 					mkent(de, segnum, bufp,name);
7261437cf11Sbill 					goto found;
7271437cf11Sbill 				}
7281437cf11Sbill 				continue;
729d0b9e33eSwnj 			}
730d0b9e33eSwnj 	}
731*2e5d0128Sbloom 	if (type = 'r')
732*2e5d0128Sbloom 		printf("%s: no slot for file, file deleted\n",name);
733*2e5d0128Sbloom 	else
73419ec2be6Sroot 		printf("%s: no slot for file\n", name);
73519ec2be6Sroot 	return (-1);
736c09a6a34Ssam 
737c09a6a34Ssam found:
738c09a6a34Ssam 	if (dope = lookup(name)) {
7391437cf11Sbill 		toflop(name, bufp->st_size, dope);
7401437cf11Sbill 		return (0);
7411437cf11Sbill 	}
74219ec2be6Sroot 	printf("%s: internal error, added then not found\n", name);
74319ec2be6Sroot 	return (-1);
7441437cf11Sbill }
745c09a6a34Ssam 
746d0b9e33eSwnj mkent(de, segnum, bufp, name)
7471437cf11Sbill 	register struct rt_ent *de;
748d0b9e33eSwnj 	int segnum;
7491437cf11Sbill 	register struct stat *bufp;
7501437cf11Sbill 	char *name;
7511437cf11Sbill {
752c09a6a34Ssam 	struct tm *localtime();
753c09a6a34Ssam 	register struct tm *timp;
754c09a6a34Ssam 	register struct rt_ent *workp;
755c09a6a34Ssam 	int count;
7561437cf11Sbill 
7571437cf11Sbill 	count = (((bufp->st_size -1) >>9) + 1);
758c09a6a34Ssam 	/* make sure there is room */
7591437cf11Sbill 	if (de->rt_len == count)
7601437cf11Sbill 		goto overwrite;
761c09a6a34Ssam 	if ((char *)rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) {
762*2e5d0128Sbloom 		/* no entries left on segment, trying adding new segment */
763*2e5d0128Sbloom 		if (rt_dir[0].rd_numseg > rt_dir[0].rd_lstseg) {
764*2e5d0128Sbloom 			short newseg;
765*2e5d0128Sbloom 			register int i;
766*2e5d0128Sbloom 			int maxseg;
767*2e5d0128Sbloom 			short size;
768*2e5d0128Sbloom 
769*2e5d0128Sbloom 			newseg = rt_dir[0].rd_lstseg++;
770*2e5d0128Sbloom 			rt_dir[newseg] = rt_nulldir;
771*2e5d0128Sbloom 			rt_dir[newseg].rd_nxtseg = rt_dir[segnum].rd_nxtseg;
772*2e5d0128Sbloom 			rt_dir[segnum].rd_nxtseg = newseg + 1;
773*2e5d0128Sbloom 			rt_dir[newseg].rd_entpad = rt_dir[0].rd_entpad;
774*2e5d0128Sbloom 			rt_dir[newseg].rd_numseg = rt_dir[0].rd_numseg;
775*2e5d0128Sbloom 			size = 0;
776*2e5d0128Sbloom 			maxseg = 0;
777*2e5d0128Sbloom 			for(i = newseg - 1; i >= 0; i--) {
778*2e5d0128Sbloom 				workp = rt_curend[i] - 1;
779*2e5d0128Sbloom 				if (workp->rt_stat != RT_NULL)
780*2e5d0128Sbloom 					continue;
781*2e5d0128Sbloom 				if (workp->rt_len < size)
782*2e5d0128Sbloom 					continue;
783*2e5d0128Sbloom 				size = workp->rt_len;
784*2e5d0128Sbloom 				maxseg = i;
785*2e5d0128Sbloom 			}
786*2e5d0128Sbloom 			size = 0;
787*2e5d0128Sbloom 			for (workp = &rt_dir[maxseg].rt_ents[0];
788*2e5d0128Sbloom 			    workp->rt_stat != RT_ESEG; workp++) {
789*2e5d0128Sbloom 				size += workp->rt_len;
790*2e5d0128Sbloom 			}
791*2e5d0128Sbloom 			workp--;
792*2e5d0128Sbloom 			rt_dir[newseg].rt_ents[0].rt_len = workp->rt_len;
793*2e5d0128Sbloom 			rt_dir[newseg].rd_stfile =
794*2e5d0128Sbloom 			    rt_dir[maxseg].rd_stfile + size - workp->rt_len;
795*2e5d0128Sbloom 			workp->rt_len = 0;
796*2e5d0128Sbloom 			rt_curend[newseg] = &rt_dir[newseg].rt_ents[1];
797*2e5d0128Sbloom 			lwrite(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]);
798*2e5d0128Sbloom 			if (segnum != 0)
799*2e5d0128Sbloom 				lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK,
800*2e5d0128Sbloom 				    (char *)&rt_dir[segnum]);
801*2e5d0128Sbloom 			lwrite((6+newseg*2)*RT_BLOCK, 2*RT_BLOCK,
802*2e5d0128Sbloom 			    (char *)&rt_dir[newseg]);
803*2e5d0128Sbloom 			segnum = newseg;
804*2e5d0128Sbloom 			de = &rt_dir[newseg].rt_ents[0];
805*2e5d0128Sbloom 		} else {
806*2e5d0128Sbloom 			fprintf(stderr, "All directory segments full on  %s\n",
807*2e5d0128Sbloom 				defdev);
8081437cf11Sbill 			exit(1);
8091437cf11Sbill 		}
810*2e5d0128Sbloom 	}
8111437cf11Sbill 	/* copy directory entries up */
812d0b9e33eSwnj 	for (workp = rt_curend[segnum]+1; workp > de; workp--)
8131437cf11Sbill 		*workp = workp[-1];
8141437cf11Sbill 	de[1].rt_len -= count;
8151437cf11Sbill 	de->rt_len = count;
816d0b9e33eSwnj 	rt_curend[segnum]++;
8171437cf11Sbill 	rt_nleft--;
818c09a6a34Ssam 
8191437cf11Sbill overwrite:
8201437cf11Sbill 	srad50(name,de->rt_name);
8211437cf11Sbill 	timp = localtime(&bufp->st_mtime);
822b566105aSwnj 	de->rt_date.rt_dy = timp->tm_mday;
8231437cf11Sbill 	de->rt_date.rt_mo = timp->tm_mon + 1;
8241437cf11Sbill 	de->rt_date.rt_yr = timp->tm_year - 72;
8251437cf11Sbill 	de->rt_stat = RT_FILE;
8261437cf11Sbill 	de->rt_pad = 0;
8271437cf11Sbill 	de->rt_chan = 0;
8281437cf11Sbill 	de->rt_job = 0;
829d0b9e33eSwnj 	lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[segnum]);
8301437cf11Sbill }
8311437cf11Sbill 
8321437cf11Sbill toflop(name, ocount, dope)
8331437cf11Sbill 	char *name;
8341437cf11Sbill 	register FLDOPE *dope;
8351437cf11Sbill 	long ocount;
8361437cf11Sbill {
8371437cf11Sbill 	register file, n, startad = dope->startad, count = ocount;
8381437cf11Sbill 	char buff[512];
8391437cf11Sbill 
8401437cf11Sbill 	file = open(name, 0);
8411437cf11Sbill 	if (file < 0) {
842c09a6a34Ssam 		fprintf(stderr, "arff: couldn't open %s\n",name);
843c09a6a34Ssam 		exit(1);
844c09a6a34Ssam 	}
8451437cf11Sbill 	for( ; count >= 512; count -= 512) {
846*2e5d0128Sbloom 		(void) read(file, buff, 512);
8471437cf11Sbill 		lwrite(startad, 512, buff);
8481437cf11Sbill 		startad += 512;
8491437cf11Sbill 	}
850*2e5d0128Sbloom 	(void) read(file, buff, count);
851*2e5d0128Sbloom 	(void) close(file);
852c09a6a34Ssam 	if (count <= 0)
853c09a6a34Ssam 		return;
854c09a6a34Ssam 	for (n = count; n < 512; n ++)
855c09a6a34Ssam 		buff[n] = 0;
8561437cf11Sbill 	lwrite(startad, 512, buff);
8571437cf11Sbill 	count = (dope->rtdope->rt_len*512-ocount)/512 ;
858c09a6a34Ssam 	if (count <= 0)
859c09a6a34Ssam 		return;
8601437cf11Sbill 	for ( ; count > 0 ; count--) {
8611437cf11Sbill 		startad += 512;
8621437cf11Sbill 		lwrite(startad, 512, zeroes);
8631437cf11Sbill 	}
8641437cf11Sbill }
865c09a6a34Ssam 
8661437cf11Sbill dcmd()
8671437cf11Sbill {
8681437cf11Sbill 	register int i;
8691437cf11Sbill 
8701437cf11Sbill 	rt_init();
8711437cf11Sbill 	if (namc)
8721437cf11Sbill 		for (i = 0; i < namc; i++)
873c09a6a34Ssam 			if (rtk(namv[i])==0)
874c09a6a34Ssam 				namv[i]=0;
8751437cf11Sbill 	if (dirdirty)
8761437cf11Sbill 		scrunch();
8771437cf11Sbill }
878c09a6a34Ssam 
8791437cf11Sbill rtk(name)
8801437cf11Sbill 	char *name;
8811437cf11Sbill {
8821437cf11Sbill 	register FLDOPE *dope;
8831437cf11Sbill 	register struct rt_ent *de;
8841437cf11Sbill 	FLDOPE *lookup();
8851437cf11Sbill 
8861437cf11Sbill 	if (dope = lookup(name)) {
8871437cf11Sbill 		printf("d - %s\n",name);
8881437cf11Sbill 		de = dope->rtdope;
8891437cf11Sbill 		de->rt_stat = RT_NULL;
8901437cf11Sbill 		de->rt_name[0] = 0;
8911437cf11Sbill 		de->rt_name[1] = 0;
8921437cf11Sbill 		de->rt_name[2] = 0;
893c09a6a34Ssam 		*((u_short *)&(de->rt_date)) = 0;
8941437cf11Sbill 		dirdirty = 1;
8951437cf11Sbill 		return (0);
8961437cf11Sbill 	}
8971437cf11Sbill 	return (1);
8981437cf11Sbill }
899c09a6a34Ssam 
900c09a6a34Ssam scrunch()
901c09a6a34Ssam {
902d0b9e33eSwnj 	register struct rt_ent *de , *workp;
903d0b9e33eSwnj 	register segnum;
904c09a6a34Ssam 
905c09a6a34Ssam 	for (segnum = 0; segnum != -1;
906*2e5d0128Sbloom 	     segnum = rt_dir[segnum].rd_nxtseg - 1) {
907c09a6a34Ssam 		for (de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++)
908b74381a6Ssam 			if (de->rt_stat == RT_NULL &&
909254d8466Shelge 			    (de+1)->rt_stat == RT_NULL) {
9101437cf11Sbill 				(de+1)->rt_len += de->rt_len;
911d0b9e33eSwnj 				for (workp=de; workp<rt_curend[segnum]; workp++)
9121437cf11Sbill 					*workp = workp[1];
9131437cf11Sbill 				de--;
914d0b9e33eSwnj 				rt_curend[segnum]--;
9151437cf11Sbill 				rt_nleft++;
9161437cf11Sbill 			}
917c09a6a34Ssam 		lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK,
918c09a6a34Ssam 			(char *)&rt_dir[segnum]);
919d0b9e33eSwnj 	}
920254d8466Shelge 	dirdirty = 0;
9211437cf11Sbill }
922