xref: /original-bsd/old/arff/arff.c (revision 73af9334)
1*73af9334Sbostic /*-
2*73af9334Sbostic  * Copyright (c) 1980 The Regents of the University of California.
3*73af9334Sbostic  * All rights reserved.
4*73af9334Sbostic  *
5*73af9334Sbostic  * %sccs.include.proprietary.c%
62e57d5edSdist  */
72e57d5edSdist 
8b74381a6Ssam #ifndef lint
92e57d5edSdist char copyright[] =
10*73af9334Sbostic "@(#) Copyright (c) 1980 The Regents of the University of California.\n\
112e57d5edSdist  All rights reserved.\n";
12*73af9334Sbostic #endif /* not lint */
132e57d5edSdist 
142e57d5edSdist #ifndef lint
15*73af9334Sbostic static char sccsid[] = "@(#)arff.c	5.8 (Berkeley) 04/18/91";
16*73af9334Sbostic #endif /* not lint */
17c09a6a34Ssam 
181437cf11Sbill #include <sys/types.h>
191437cf11Sbill #include <sys/stat.h>
201bbff716Ssam #include <sys/time.h>
21e01a7c91Sbostic #include <sys/signal.h>
2219251218Ssam #include <sys/file.h>
23e01a7c91Sbostic #include <stdio.h>
24e01a7c91Sbostic #include "pathnames.h"
25c09a6a34Ssam 
261437cf11Sbill #define dbprintf printf
27c09a6a34Ssam 
281437cf11Sbill struct rt_dat {
29c09a6a34Ssam 	u_short	rt_yr:5;	/* year-1972 */
30c09a6a34Ssam 	u_short	rt_dy:5;	/* day */
31c09a6a34Ssam 	u_short	rt_mo:5;	/* month */
321437cf11Sbill };
33c09a6a34Ssam 
341437cf11Sbill struct	rt_axent {
351437cf11Sbill 	char	rt_sent[14];
361437cf11Sbill };
371437cf11Sbill 
381437cf11Sbill struct rt_ent {
391437cf11Sbill 	char	rt_pad;		/* unusued */
400a8e9d21Sbostic 	u_char	rt_stat;	/* type of entry, or end of seg */
41c09a6a34Ssam 	u_short	rt_name[3];	/* name, 3 words in rad50 form */
422ef99505Swnj 	u_short	rt_len;		/* length of file */
430a8e9d21Sbostic 	u_char	rt_chan;	/* only used in temporary files */
44c09a6a34Ssam 	char	rt_job;		/* only used in temporary files */
45c09a6a34Ssam 	struct	rt_dat rt_date;	/* creation date */
461437cf11Sbill };
47c09a6a34Ssam 
481437cf11Sbill #define RT_TEMP		1
491437cf11Sbill #define RT_NULL		2
501437cf11Sbill #define RT_FILE		4
510a8e9d21Sbostic #define RT_PFILE	(0200|RT_FILE)	/* protected file */
521437cf11Sbill #define RT_ESEG		8
53c09a6a34Ssam 
54c09a6a34Ssam #define RT_BLOCK	512	/* block size */
55d0b9e33eSwnj #define RT_DIRSIZE	31	/* max # of directory segments */
56c09a6a34Ssam 
571437cf11Sbill struct rt_head {
58c09a6a34Ssam 	short	rt_numseg;	/* # of segments available */
59c09a6a34Ssam 	short	rt_nxtseg;	/* # of next logical segment */
60c09a6a34Ssam 	short	rt_lstseg;	/* highest seg currently open */
61c09a6a34Ssam 	u_short	rt_entpad;	/* extra words/directory entry */
62c09a6a34Ssam 	short	rt_stfile;	/* block # where files begin */
631437cf11Sbill };
64c09a6a34Ssam 
651437cf11Sbill struct	rt_dir {
661437cf11Sbill 	struct rt_head	rt_axhead;
671437cf11Sbill 	struct rt_ent	rt_ents[72];
681437cf11Sbill 	char		_dirpad[6];
691437cf11Sbill };
70c09a6a34Ssam 
712e5d0128Sbloom #define rd_numseg rt_axhead.rt_numseg
722e5d0128Sbloom #define rd_nxtseg rt_axhead.rt_nxtseg
732e5d0128Sbloom #define rd_lstseg rt_axhead.rt_lstseg
742e5d0128Sbloom #define rd_entpad rt_axhead.rt_entpad
752e5d0128Sbloom #define rd_stfile rt_axhead.rt_stfile
762e5d0128Sbloom 
771437cf11Sbill typedef struct fldope {
781437cf11Sbill 	int	startad;
791437cf11Sbill 	int	count;
801437cf11Sbill struct	rt_ent	*rtdope;
811437cf11Sbill } FLDOPE;
82c09a6a34Ssam 
831437cf11Sbill FLDOPE *lookup();
84c09a6a34Ssam 
851437cf11Sbill #define	rt(p)	((struct rt_ent *) p )
861437cf11Sbill #define	Ain1	03100
871437cf11Sbill #define	Ain2	050
88c09a6a34Ssam #define	flag(c)	(flg[('c') - 'a'])
891437cf11Sbill 
90c09a6a34Ssam char	*man = "rxtd";
911437cf11Sbill char	zeroes[512];
92c09a6a34Ssam 
931437cf11Sbill extern char *val;
941437cf11Sbill extern char table[256];
95c09a6a34Ssam struct rt_dir rt_dir[RT_DIRSIZE] = {
96b5239b99Sbostic 	{
97c09a6a34Ssam 	{ 4, 0, 1, 0, 14 },
982e5d0128Sbloom 	{ { 0, RT_NULL, { 0, 0, 0 }, 486, 0 },
992e5d0128Sbloom 	  { 0, RT_ESEG } }
100b5239b99Sbostic 	}
1012e5d0128Sbloom };
1022e5d0128Sbloom 
1032e5d0128Sbloom struct rt_dir rt_nulldir = {
1042e5d0128Sbloom 	{ 0, 0, 0, 0, 0 },
1052e5d0128Sbloom 	{ { 0, RT_NULL, { 0, 0, 0 }, 0, 0 },
106b74381a6Ssam 	  { 0, RT_ESEG } }
107c09a6a34Ssam };
108c09a6a34Ssam 
1091437cf11Sbill int	rt_entsiz;
1101437cf11Sbill int	rt_nleft;
111d0b9e33eSwnj struct rt_ent *rt_curend[RT_DIRSIZE];
1121437cf11Sbill int	floppydes;
1131437cf11Sbill int	dirdirty;
1141437cf11Sbill char	*rt_last;
115e01a7c91Sbostic char	*defdev = _PATH_FLOPPY;
1161437cf11Sbill 
1172e5d0128Sbloom char *opt = "vfbcm";
1181437cf11Sbill 
119c09a6a34Ssam extern long lseek();
120c09a6a34Ssam int	rcmd(), dcmd(), xcmd(), tcmd();
121c09a6a34Ssam 
1221437cf11Sbill int	(*comfun)();
1231437cf11Sbill char	flg[26];
1241437cf11Sbill char	**namv;
1251437cf11Sbill int	namc;
1261437cf11Sbill 
main(argc,argv)1271437cf11Sbill main(argc, argv)
1281437cf11Sbill 	char *argv[];
1291437cf11Sbill {
1301437cf11Sbill 	register char *cp;
1311437cf11Sbill 
1321437cf11Sbill 	if (argc < 2)
1331437cf11Sbill 		usage();
1341437cf11Sbill 	for (cp = argv[1]; *cp; cp++)
1351437cf11Sbill 		switch (*cp) {
136c09a6a34Ssam 
1371437cf11Sbill 		case 'm':
1381437cf11Sbill 		case 'v':
1391437cf11Sbill 		case 'u':
1401437cf11Sbill 		case 'w':
1412e5d0128Sbloom 		case 'b':
1421437cf11Sbill 			flg[*cp-'a']++;
1431437cf11Sbill 			continue;
1441437cf11Sbill 		case 'c':
145c09a6a34Ssam 			flag(c)++;
1461437cf11Sbill 			dirdirty++;
1471437cf11Sbill 			continue;
1481437cf11Sbill 
1491437cf11Sbill 		case 'r':
1501437cf11Sbill 			setcom(rcmd);
151c09a6a34Ssam 			flag(r)++;
1521437cf11Sbill 			continue;
1531437cf11Sbill 
1541437cf11Sbill 		case 'd':
1551437cf11Sbill 			setcom(dcmd);
156c09a6a34Ssam 			flag(d)++;
1571437cf11Sbill 			continue;
1581437cf11Sbill 
1591437cf11Sbill 		case 'x':
1601437cf11Sbill 			setcom(xcmd);
1611437cf11Sbill 			continue;
1621437cf11Sbill 
1631437cf11Sbill 		case 't':
1641437cf11Sbill 			setcom(tcmd);
1651437cf11Sbill 			continue;
1661437cf11Sbill 
1671437cf11Sbill 		case 'f':
1681437cf11Sbill 			defdev = argv[2];
1691437cf11Sbill 			argv++;
1701437cf11Sbill 			argc--;
1711437cf11Sbill 			continue;
1721437cf11Sbill 
1731437cf11Sbill 		default:
1741437cf11Sbill 			fprintf(stderr, "arff: bad option `%c'\n", *cp);
1751437cf11Sbill 			exit(1);
1761437cf11Sbill 		}
177c09a6a34Ssam 
1781437cf11Sbill 	namv = argv+2;
1791437cf11Sbill 	namc = argc-2;
1801437cf11Sbill 	if (comfun == 0) {
181c09a6a34Ssam 		if (flag(u) == 0) {
182c09a6a34Ssam 			fprintf(stderr, "arff: one of [%s] must be specified\n",
183c09a6a34Ssam 				man);
1841437cf11Sbill 			exit(1);
1851437cf11Sbill 		}
1861437cf11Sbill 		setcom(rcmd);
1871437cf11Sbill 	}
1881437cf11Sbill 	(*comfun)();
1891437cf11Sbill 	exit(notfound());
1901437cf11Sbill }
1911437cf11Sbill 
1921437cf11Sbill setcom(fun)
1931437cf11Sbill 	int (*fun)();
1941437cf11Sbill {
1951437cf11Sbill 	if (comfun != 0) {
1961437cf11Sbill 		fprintf(stderr, "arff: only one of [%s] allowed\n", man);
1971437cf11Sbill 		exit(1);
1981437cf11Sbill 	}
1991437cf11Sbill 	comfun = fun;
2001437cf11Sbill }
2011437cf11Sbill 
usage()2021437cf11Sbill usage()
2031437cf11Sbill {
204296c7c8aSwnj 	fprintf(stderr, "usage: ar [%s][%s] archive files ...\n", opt, man);
2051437cf11Sbill 	exit(1);
2061437cf11Sbill }
2071437cf11Sbill 
notfound()2081437cf11Sbill notfound()
2091437cf11Sbill {
210c09a6a34Ssam 	register i, n = 0;
2111437cf11Sbill 
2121437cf11Sbill 	for (i = 0; i < namc; i++)
2131437cf11Sbill 		if (namv[i]) {
2141437cf11Sbill 			fprintf(stderr, "arff: %s not found\n", namv[i]);
2151437cf11Sbill 			n++;
2161437cf11Sbill 		}
2171437cf11Sbill 	return (n);
2181437cf11Sbill }
2191437cf11Sbill 
tcmd()2201437cf11Sbill tcmd()
2211437cf11Sbill {
222c09a6a34Ssam 	register char *de, *last;
2231437cf11Sbill 	FLDOPE *lookup(), *dope;
224c09a6a34Ssam 	int segnum, nleft;
225c09a6a34Ssam 	register i;
2261437cf11Sbill 	register struct rt_ent *rde;
2271437cf11Sbill 
2281437cf11Sbill 	rt_init();
229b74381a6Ssam 	if (namc != 0) {
230b74381a6Ssam 		for (i = 0; i < namc; i++)
231b74381a6Ssam 			if (dope = lookup(namv[i])) {
232b74381a6Ssam 				rde = dope->rtdope;
2332e5d0128Sbloom 				(void) rtls(rde);
234b74381a6Ssam 				namv[i] = 0;
235b74381a6Ssam 			}
236b74381a6Ssam 		return;
237b74381a6Ssam 	}
238c09a6a34Ssam 	for (segnum = 0; segnum != -1;
2392e5d0128Sbloom 	  segnum = rt_dir[segnum].rd_nxtseg - 1) {
240d0b9e33eSwnj 		last = rt_last + segnum*2*RT_BLOCK;
241d0b9e33eSwnj 		for (de = ((char *)&rt_dir[segnum])+10; de <= last;
242c09a6a34Ssam 		    de += rt_entsiz)
2431437cf11Sbill 			if (rtls(rt(de))) {
244d0b9e33eSwnj 				nleft = (last-de)/rt_entsiz;
245c09a6a34Ssam #define ENTRIES "\n%d entries remaining in directory segment %d.\n"
246c09a6a34Ssam 				printf(ENTRIES, nleft, segnum+1);
2471437cf11Sbill 				break;
2481437cf11Sbill 			}
2491437cf11Sbill 	}
2501437cf11Sbill }
251c09a6a34Ssam 
rtls(de)2521437cf11Sbill rtls(de)
2531437cf11Sbill 	register struct rt_ent *de;
2541437cf11Sbill {
2551437cf11Sbill 	int month, day, year;
2561437cf11Sbill 	char name[12], ext[4];
2571437cf11Sbill 
2581437cf11Sbill 	switch (de->rt_stat) {
259c09a6a34Ssam 
2601437cf11Sbill 	case RT_TEMP:
261c09a6a34Ssam 		if (flag(v))
2621437cf11Sbill 			printf("Tempfile:\n");
263c09a6a34Ssam 		/* fall thru...*/
264c09a6a34Ssam 
2651437cf11Sbill 	case RT_FILE:
2660a8e9d21Sbostic 	case RT_PFILE:
267c09a6a34Ssam 		if (!flag(v)) {
268c09a6a34Ssam 			sunrad50(name, de->rt_name);
269c09a6a34Ssam 			printf("%s\n", name);
270c09a6a34Ssam 			break;
271c09a6a34Ssam 		}
2721437cf11Sbill 		unrad50(2, de->rt_name, name);
2731437cf11Sbill 		unrad50(1, &(de->rt_name[2]), ext);
2741437cf11Sbill 		day = de->rt_date.rt_dy;
2751437cf11Sbill 		year = de->rt_date.rt_yr+72;
2761437cf11Sbill 		month = de->rt_date.rt_mo;
2771437cf11Sbill 		printf("%6.6s  %3.3s	%02d/%02d/%02d	%d\n",name,
2781437cf11Sbill 			ext, month, day, year, de->rt_len);
2791437cf11Sbill 		break;
2801437cf11Sbill 
2811437cf11Sbill 	case RT_NULL:
2821437cf11Sbill 		printf("%-25.9s	%d\n","<UNUSED>", de->rt_len);
2831437cf11Sbill 		break;
2841437cf11Sbill 
2851437cf11Sbill 	case RT_ESEG:
2861437cf11Sbill 		return (1);
2871437cf11Sbill 	}
2881437cf11Sbill 	return (0);
2891437cf11Sbill }
290c09a6a34Ssam 
xcmd()2911437cf11Sbill xcmd()
2921437cf11Sbill {
293c09a6a34Ssam 	register char *de, *last;
294d0b9e33eSwnj 	int segnum;
2951437cf11Sbill 	char name[12];
2961437cf11Sbill 	register int i;
2971437cf11Sbill 
2981437cf11Sbill 	rt_init();
299b74381a6Ssam 	if (namc != 0) {
300b74381a6Ssam 		for (i = 0; i < namc; i++)
301b74381a6Ssam 			if (rtx(namv[i]) == 0)
302b74381a6Ssam 				namv[i] = 0;
303b74381a6Ssam 		return;
304b74381a6Ssam 	}
305c09a6a34Ssam 	for (segnum = 0; segnum != -1;
3062e5d0128Sbloom 	     segnum = rt_dir[segnum].rd_nxtseg-1)
307c09a6a34Ssam 		for (last = rt_last+(segnum*2*RT_BLOCK),
308c09a6a34Ssam 		     de = ((char *)&rt_dir[segnum])+10; de <= last;
30967f39843Sralph 		     de += rt_entsiz) {
3100200ad53Swnj 			switch (rt(de)->rt_stat) {
311b74381a6Ssam 
3120200ad53Swnj 			case RT_ESEG:
31367f39843Sralph 				break;	/* exit loop and try next segment */
314b74381a6Ssam 
3150200ad53Swnj 			case RT_TEMP:
3160200ad53Swnj 			case RT_FILE:
3170a8e9d21Sbostic 			case RT_PFILE:
3180200ad53Swnj 				sunrad50(name,rt(de)->rt_name);
3192e5d0128Sbloom 				(void) rtx(name);
320b74381a6Ssam 
3210200ad53Swnj 			case RT_NULL:
32267f39843Sralph 			default:
32367f39843Sralph 				continue;
32467f39843Sralph 			}
325b74381a6Ssam 			break;
3260200ad53Swnj 		}
3271437cf11Sbill }
328c09a6a34Ssam 
rtx(name)3291437cf11Sbill rtx(name)
3301437cf11Sbill 	char *name;
3311437cf11Sbill {
3321437cf11Sbill 	register FLDOPE *dope;
3331437cf11Sbill 	FLDOPE *lookup();
3341437cf11Sbill 	register startad, count;
335c09a6a34Ssam 	int file;
336c09a6a34Ssam 	char buff[512];
3371437cf11Sbill 
3381437cf11Sbill 
3391437cf11Sbill 	if (dope = lookup(name)) {
340c09a6a34Ssam 		if (flag(v))
3412e5d0128Sbloom 			(void) rtls(dope->rtdope);
3421437cf11Sbill 		else
3431437cf11Sbill 			printf("x - %s\n",name);
3441437cf11Sbill 
345c09a6a34Ssam 		if ((file = creat(name, 0666)) < 0)
346c09a6a34Ssam 			return (1);
3471437cf11Sbill 		count = dope->count;
3481437cf11Sbill 		startad = dope->startad;
3491437cf11Sbill 		for( ; count > 0 ; count -= 512) {
350b1b6657eSkarels 			(void) lread(startad, 512, buff);
3512e5d0128Sbloom 			(void) write(file, buff, 512);
3521437cf11Sbill 			startad += 512;
3531437cf11Sbill 		}
3542e5d0128Sbloom 		(void) close(file);
3551437cf11Sbill 		return (0);
3561437cf11Sbill 	}
3571437cf11Sbill 	return (1);
3581437cf11Sbill }
359c09a6a34Ssam 
rt_init()3601437cf11Sbill rt_init()
3611437cf11Sbill {
3621437cf11Sbill 	static initized = 0;
363c09a6a34Ssam 	register char *de, *last;
364d0b9e33eSwnj 	register i;
365a11ea3b6Shickman 	int dirnum;
366a11ea3b6Shickman 	char *mode;
367a11ea3b6Shickman 	FILE *temp_floppydes;
3681437cf11Sbill 
369c09a6a34Ssam 	if (initized)
370c09a6a34Ssam 		return;
3711437cf11Sbill 	initized = 1;
37219251218Ssam 	if (flag(c)) {
37319251218Ssam 		struct stat sb;
37419251218Ssam 		char response[128];
37519251218Ssam 		int tty;
37619251218Ssam 
37719251218Ssam 		if (stat(defdev, &sb) >= 0 && (sb.st_mode & S_IFMT) == S_IFREG)
37819251218Ssam 			goto ignore;
379e01a7c91Sbostic 		tty = open(_PATH_TTY, O_RDWR);
38019251218Ssam #define SURE	"Are you sure you want to clobber the floppy? "
3812e5d0128Sbloom 		(void) write(tty, SURE, sizeof (SURE));
3822e5d0128Sbloom 		(void) read(tty, response, sizeof (response));
38319251218Ssam 		if (*response != 'y')
38419251218Ssam 			exit(50);
3852e5d0128Sbloom 		(void) close(tty);
38619251218Ssam ignore:
38719251218Ssam 		;
38819251218Ssam 	}
389c09a6a34Ssam 	if (flag(c) || flag(d) || flag(r))
390a11ea3b6Shickman 		mode = "r+";
3911437cf11Sbill 	else
392a11ea3b6Shickman 		mode = "r";
393a11ea3b6Shickman 	if ((temp_floppydes = fopen(defdev, mode)) == NULL) {
394a11ea3b6Shickman 		perror(defdev);
395296c7c8aSwnj 		exit(1);
396a11ea3b6Shickman 	} else
397a11ea3b6Shickman 		floppydes = fileno(temp_floppydes);
398c09a6a34Ssam 	if (!flag(c)) {
399b1b6657eSkarels 		if (lread(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]))
400b1b6657eSkarels 			exit(2);
4012e5d0128Sbloom 		dirnum = rt_dir[0].rd_numseg;
402254d8466Shelge 		/* check for blank/uninitialized diskette */
403254d8466Shelge 		if (dirnum <= 0) {
404254d8466Shelge 			fprintf(stderr,"arff: bad directory format\n");
405254d8466Shelge 			exit(1);
406254d8466Shelge 		}
407d0b9e33eSwnj 		if (dirnum > RT_DIRSIZE) {
408d0b9e33eSwnj 			fprintf(stderr,"arff: too many directory segments\n");
409d0b9e33eSwnj 			exit(1);
410d0b9e33eSwnj 		}
411d0b9e33eSwnj 		for (i = 1; i < dirnum; i++)
412b1b6657eSkarels 		    if (lread((6+2*i)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[i]))
413b1b6657eSkarels 			exit(1);
4142e5d0128Sbloom 	} else {
41519ec2be6Sroot 		dirnum = 1;
4162e5d0128Sbloom 		if (flag(b)) {
4172e5d0128Sbloom 			rt_dir[0].rd_numseg = 31;
4182e5d0128Sbloom 			rt_dir[0].rd_stfile = 68;
4192e5d0128Sbloom 			rt_dir[0].rt_ents[0].rt_len = 20480 - 68;
4202e5d0128Sbloom 		}
4212e5d0128Sbloom 	}
4221437cf11Sbill 
4232e5d0128Sbloom 	rt_entsiz = 2*rt_dir[0].rd_entpad + 14;
4242e5d0128Sbloom 	/*
4252e5d0128Sbloom 	 * We assume that the directory entries have no padding.  This
4262e5d0128Sbloom 	 * may not be a valid assumption, but there are numerous point
4272e5d0128Sbloom 	 * in the code where it assumes it is an rt_ent structure and
4282e5d0128Sbloom 	 * not an rt_entsiz sized structure.
4292e5d0128Sbloom 	 */
4302e5d0128Sbloom 	rt_entsiz = 14;
431d0b9e33eSwnj 	rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz;
432d0b9e33eSwnj 	rt_nleft = 0;
433d0b9e33eSwnj 
434d0b9e33eSwnj 	for (i = 0; i < dirnum; i++) {
435d0b9e33eSwnj 		last = rt_last + i*2*RT_BLOCK;
436c09a6a34Ssam 		for (de = ((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz)
437c09a6a34Ssam 			if (rt(de)->rt_stat == RT_ESEG)
438c09a6a34Ssam 				break;
439d0b9e33eSwnj 		rt_curend[i] = rt(de);
440d0b9e33eSwnj 		rt_nleft += (last-de)/rt_entsiz;
441d0b9e33eSwnj 	}
4421437cf11Sbill }
4431437cf11Sbill 
4441437cf11Sbill static FLDOPE result;
445c09a6a34Ssam 
4461437cf11Sbill FLDOPE *
lookup(name)4471437cf11Sbill lookup(name)
4481437cf11Sbill 	char *name;
4491437cf11Sbill {
4501437cf11Sbill 	unsigned short rname[3];
4512e5d0128Sbloom 	register char *de;
452d0b9e33eSwnj 	int segnum;
4531437cf11Sbill 	register index;
4541437cf11Sbill 
4551437cf11Sbill 	srad50(name,rname);
4561437cf11Sbill 
4571437cf11Sbill 	/*
4581437cf11Sbill 	 *  Search for name, accumulate blocks in index
4591437cf11Sbill 	 */
4601437cf11Sbill 	rt_init();
461c09a6a34Ssam 	for (segnum = 0; segnum != -1;
4622e5d0128Sbloom 	     segnum = rt_dir[segnum].rd_nxtseg - 1)
463c09a6a34Ssam 	{
4641437cf11Sbill 		index = 0;
465d0b9e33eSwnj 		for (de=((char *)&rt_dir[segnum])+10;
466c09a6a34Ssam 		     rt(de)->rt_stat != RT_ESEG; de += rt_entsiz)
4671437cf11Sbill 			switch(rt(de)->rt_stat) {
468c09a6a34Ssam 
4691437cf11Sbill 			case RT_FILE:
4700a8e9d21Sbostic 			case RT_PFILE:
4711437cf11Sbill 			case RT_TEMP:
472c09a6a34Ssam 				if(samename(rname,rt(de)->rt_name)) {
473c09a6a34Ssam 					result.count = rt(de)->rt_len * 512;
474c09a6a34Ssam 					result.startad = 512*
4752e5d0128Sbloom 					    (rt_dir[segnum].rd_stfile + index);
476c09a6a34Ssam 					result.rtdope = (struct rt_ent *) de;
477c09a6a34Ssam 					return (&result);
478c09a6a34Ssam 				}
479c09a6a34Ssam 
4801437cf11Sbill 			case RT_NULL:
4811437cf11Sbill 				index += rt(de)->rt_len;
4821437cf11Sbill 			}
4831437cf11Sbill         }
4841437cf11Sbill 	return ((FLDOPE *) 0);
485c09a6a34Ssam 
4861437cf11Sbill }
487c09a6a34Ssam 
4881437cf11Sbill static
samename(a,b)4891437cf11Sbill samename(a, b)
490c09a6a34Ssam 	u_short a[], b[];
4911437cf11Sbill {
492c09a6a34Ssam 	return (*a == *b && a[1] == b[1] && a[2] == b[2] );
4931437cf11Sbill }
4941437cf11Sbill 
rad50(cp,out)4951437cf11Sbill rad50(cp, out)
496c09a6a34Ssam 	register u_char *cp;
497c09a6a34Ssam 	u_short *out;
4981437cf11Sbill {
499c09a6a34Ssam 	register index, temp;
5001437cf11Sbill 
5011437cf11Sbill 	for (index = 0; *cp; index++) {
5021437cf11Sbill 		temp = Ain1 * table[*cp++];
5031437cf11Sbill 		if (*cp!=0) {
5041437cf11Sbill 			temp += Ain2 * table[*cp++];
5051437cf11Sbill 			if(*cp!=0)
5061437cf11Sbill 				temp += table[*cp++];
5071437cf11Sbill 		}
5081437cf11Sbill 		out[index] = temp;
5091437cf11Sbill 	}
5101437cf11Sbill }
511c09a6a34Ssam 
512c09a6a34Ssam #define reduce(x, p, q) (x = v[p/q], p %= q);
5131437cf11Sbill 
unrad50(count,in,cp)5141437cf11Sbill unrad50(count, in, cp)
515c09a6a34Ssam 	u_short *in;
5161437cf11Sbill 	register char *cp;
5171437cf11Sbill {
518c09a6a34Ssam 	register i, temp;
519c09a6a34Ssam 	register u_char *v = (u_char *) val;
5201437cf11Sbill 
5211437cf11Sbill 	for (i = 0; i < count; i++) {
5221437cf11Sbill 		temp = in[i];
5231437cf11Sbill 		reduce(*cp++, temp, Ain1);
5241437cf11Sbill 		reduce(*cp++, temp, Ain2);
5251437cf11Sbill 		reduce(*cp++, temp, 1);
5261437cf11Sbill 	}
5271437cf11Sbill 	*cp=0;
5281437cf11Sbill }
5291437cf11Sbill 
srad50(name,rname)5301437cf11Sbill srad50(name, rname)
5311437cf11Sbill 	register char *name;
532c09a6a34Ssam 	register u_short *rname;
5331437cf11Sbill {
534c09a6a34Ssam 	register index;
535c09a6a34Ssam 	register char *cp;
5361437cf11Sbill 	char file[7], ext[4];
537c09a6a34Ssam 
5381437cf11Sbill 	/*
5391437cf11Sbill 	 * Find end of pathname
5401437cf11Sbill 	 */
541c09a6a34Ssam 	for (cp = name; *cp++; )
542c09a6a34Ssam 		;
543c09a6a34Ssam 	while (cp >= name && *--cp != '/')
544c09a6a34Ssam 		;
5451437cf11Sbill 	cp++;
5461437cf11Sbill 	/*
5471437cf11Sbill 	 * Change to rad50
5481437cf11Sbill 	 */
5491437cf11Sbill 	for (index = 0; *cp; ) {
5501437cf11Sbill 		file[index++] = *cp++;
5511437cf11Sbill 		if (*cp == '.') {
5521437cf11Sbill 			cp++;
5531437cf11Sbill 			break;
5541437cf11Sbill 		}
5551437cf11Sbill 		if (index >= 6) {
5561437cf11Sbill 			break;
5571437cf11Sbill 		}
5581437cf11Sbill 	}
5591437cf11Sbill 	file[index] = 0;
5601437cf11Sbill 	for (index = 0; *cp; ) {
5611437cf11Sbill 		ext[index++] = *cp++;
562c09a6a34Ssam 		if (*cp == '.' || index >= 3)
5631437cf11Sbill 			break;
5641437cf11Sbill 	}
5651437cf11Sbill 	ext[index]=0;
566c09a6a34Ssam 	rname[0] = rname[1] = rname[2] = 0;
567c09a6a34Ssam 	rad50((u_char *)file, rname);
568c09a6a34Ssam 	rad50((u_char *)ext, rname+2);
5691437cf11Sbill }
570c09a6a34Ssam 
sunrad50(name,rname)5711437cf11Sbill sunrad50(name, rname)
572c09a6a34Ssam 	u_short rname[];
5731437cf11Sbill 	register char *name;
5741437cf11Sbill {
5751437cf11Sbill 	register char *cp, *cp2;
5761437cf11Sbill 	char ext[4];
5771437cf11Sbill 
5781437cf11Sbill 	unrad50(2, rname, name);
5791437cf11Sbill 	unrad50(1, rname + 2, ext);
580c09a6a34Ssam 	/*
581c09a6a34Ssam 	 * Jam name and extension together with a dot
582c09a6a34Ssam 	 * deleting white space
583c09a6a34Ssam 	 */
584c09a6a34Ssam 	for (cp = name; *cp++;)
585c09a6a34Ssam 		;
586c09a6a34Ssam 	--cp;
587c09a6a34Ssam 	while (*--cp == ' ' && cp >= name)
588c09a6a34Ssam 		;
589c09a6a34Ssam 	*++cp = '.';
590c09a6a34Ssam 	cp++;
591c09a6a34Ssam 	for (cp2 = ext; *cp2 != ' ' && cp2 < ext+3;)
5921437cf11Sbill 		*cp++ = *cp2++;
5931437cf11Sbill 	*cp=0;
594c09a6a34Ssam 	if (cp[-1] == '.')
595c09a6a34Ssam 		cp[-1] = 0;
5961437cf11Sbill }
5971437cf11Sbill 
5981437cf11Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789";
599c09a6a34Ssam 
6001437cf11Sbill static char table[256] = {
6011437cf11Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
6021437cf11Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
6031437cf11Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
6041437cf11Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 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, 29,
6071437cf11Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
6081437cf11Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
6091437cf11Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
6101437cf11Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
6111437cf11Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
6121437cf11Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
6131437cf11Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
6141437cf11Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
6151437cf11Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
6161437cf11Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 };
6171437cf11Sbill 
618c09a6a34Ssam /*
619c09a6a34Ssam  * Logical to physical adress translation
620c09a6a34Ssam  */
621c09a6a34Ssam long
trans(logical)622c09a6a34Ssam trans(logical)
6231437cf11Sbill 	register int logical;
6241437cf11Sbill {
6251437cf11Sbill 	register int sector, bytes, track;
6261437cf11Sbill 
6271437cf11Sbill 	logical += 26*128;
6281437cf11Sbill 	bytes = (logical&127);
6291437cf11Sbill 	logical >>= 7;
6301437cf11Sbill 	sector = logical%26;
6311437cf11Sbill 	if(sector >= 13)
6321437cf11Sbill 		sector = sector*2+1;
6331437cf11Sbill 	else
6341437cf11Sbill 		sector *= 2;
6351437cf11Sbill 	sector += 26 + ((track = (logical/26))-1)*6;
6361437cf11Sbill 	sector %= 26;
6371437cf11Sbill 	return ((((track*26)+sector) << 7) + bytes);
6381437cf11Sbill }
639c09a6a34Ssam 
lread(startad,count,obuff)6401437cf11Sbill lread(startad, count, obuff)
6411437cf11Sbill 	register startad, count;
6421437cf11Sbill 	register char *obuff;
6431437cf11Sbill {
6441437cf11Sbill 	long trans();
6451437cf11Sbill 	extern floppydes;
646c09a6a34Ssam 	register int size = flag(m) ? 512 : 128;
647b1b6657eSkarels 	int error = 0;
648b1b6657eSkarels 	extern int errno;
649c09a6a34Ssam 
6501437cf11Sbill 	rt_init();
651c09a6a34Ssam 	while ((count -= size) >= 0) {
6522e5d0128Sbloom 		(void) lseek(floppydes, flag(m) ?
653c09a6a34Ssam 			(long)startad : trans(startad), 0);
654b1b6657eSkarels 		if (read(floppydes, obuff, size) != size) {
655b1b6657eSkarels 			error = errno;
656b1b6657eSkarels 			fprintf(stderr, "arff: read error block %d: ",
657c09a6a34Ssam 				startad/size);
658b1b6657eSkarels 			errno = error;
659b1b6657eSkarels 			perror("");
660b1b6657eSkarels 		}
661c09a6a34Ssam 		obuff += size;
662c09a6a34Ssam 		startad += size;
6631437cf11Sbill 	}
664b1b6657eSkarels 	return (error);
6651437cf11Sbill }
666c09a6a34Ssam 
lwrite(startad,count,obuff)6671437cf11Sbill lwrite(startad, count, obuff)
6681437cf11Sbill 	register startad, count;
6691437cf11Sbill 	register char *obuff;
6701437cf11Sbill {
6711437cf11Sbill 	long trans();
6721437cf11Sbill 	extern floppydes;
673c09a6a34Ssam 	register int size = flag(m) ? 512 : 128;
674c09a6a34Ssam 
6751437cf11Sbill 	rt_init();
676c09a6a34Ssam 	while ((count -= size) >= 0) {
6772e5d0128Sbloom 		(void) lseek(floppydes, flag(m) ?
678c09a6a34Ssam 			(long)startad : trans(startad), 0);
679c09a6a34Ssam 		if (write(floppydes, obuff, size) != size)
680c09a6a34Ssam 			fprintf(stderr, "arff: write error block %d\n",
681c09a6a34Ssam 				startad/size);
682c09a6a34Ssam 		obuff += size;
683c09a6a34Ssam 		startad += size;
6841437cf11Sbill 	}
6851437cf11Sbill }
6861437cf11Sbill 
rcmd()6871437cf11Sbill rcmd()
6881437cf11Sbill {
6891437cf11Sbill 	register int i;
6901437cf11Sbill 
6911437cf11Sbill 	rt_init();
6921437cf11Sbill 	if (namc > 0)
6931437cf11Sbill 		for (i = 0; i < namc; i++)
694c09a6a34Ssam 			if (rtr(namv[i]) == 0)
695c09a6a34Ssam 				namv[i] = 0;
6961437cf11Sbill }
6971437cf11Sbill 
rtr(name)6981437cf11Sbill rtr(name)
6991437cf11Sbill 	char *name;
7001437cf11Sbill {
701c09a6a34Ssam 	register FLDOPE *dope;
702c09a6a34Ssam 	register struct rt_ent *de;
703c09a6a34Ssam 	struct stat buf;
704c09a6a34Ssam 	register struct stat *bufp = &buf;
705d0b9e33eSwnj 	int segnum;
7062e5d0128Sbloom 	char type;
7071437cf11Sbill 
70819ec2be6Sroot 	if (stat(name, bufp) < 0) {
70919ec2be6Sroot 		perror(name);
71019ec2be6Sroot 		return (-1);
71119ec2be6Sroot 	}
7122e5d0128Sbloom 	type = 'a';
7131437cf11Sbill 	if (dope = lookup(name)) {
7141437cf11Sbill 		/* can replace, no problem */
7151437cf11Sbill 		de = dope->rtdope;
7162e5d0128Sbloom 		if (bufp->st_size <= (de->rt_len * 512)) {
7172e5d0128Sbloom 			printf("r - %s\n",name);
7181437cf11Sbill 			toflop(name, bufp->st_size, dope);
719b74381a6Ssam 			goto found;
7202e5d0128Sbloom 		} else {
7212e5d0128Sbloom 			de = dope->rtdope;
7222e5d0128Sbloom 			type = 'r';
7232e5d0128Sbloom 			de->rt_stat = RT_NULL;
7242e5d0128Sbloom 			de->rt_name[0] = 0;
7252e5d0128Sbloom 			de->rt_name[1] = 0;
7262e5d0128Sbloom 			de->rt_name[2] = 0;
7272e5d0128Sbloom 			*((u_short *)&(de->rt_date)) = 0;
7282e5d0128Sbloom 			scrunch();
7292e5d0128Sbloom 		}
730b74381a6Ssam 	}
731b74381a6Ssam 	/*
732b74381a6Ssam 	 * Search for vacant spot
733b74381a6Ssam 	 */
734c09a6a34Ssam 	for (segnum = 0; segnum != -1;
7352e5d0128Sbloom 	     segnum = rt_dir[segnum].rd_nxtseg - 1)
736c09a6a34Ssam 	{
737d0b9e33eSwnj 		for (de = rt_dir[segnum].rt_ents;
738c09a6a34Ssam 		    rt(de)->rt_stat != RT_ESEG; de++)
739c09a6a34Ssam 			if ((de)->rt_stat == RT_NULL) {
7401437cf11Sbill 				if (bufp->st_size <= (de->rt_len*512)) {
7412e5d0128Sbloom 					printf("%c - %s\n", type, name),
742d0b9e33eSwnj 					mkent(de, segnum, bufp,name);
7431437cf11Sbill 					goto found;
7441437cf11Sbill 				}
7451437cf11Sbill 				continue;
746d0b9e33eSwnj 			}
747d0b9e33eSwnj 	}
748852ee85bSbostic 	if (type == 'r')
7492e5d0128Sbloom 		printf("%s: no slot for file, file deleted\n",name);
7502e5d0128Sbloom 	else
75119ec2be6Sroot 		printf("%s: no slot for file\n", name);
75219ec2be6Sroot 	return (-1);
753c09a6a34Ssam 
754c09a6a34Ssam found:
755c09a6a34Ssam 	if (dope = lookup(name)) {
7561437cf11Sbill 		toflop(name, bufp->st_size, dope);
7571437cf11Sbill 		return (0);
7581437cf11Sbill 	}
75919ec2be6Sroot 	printf("%s: internal error, added then not found\n", name);
76019ec2be6Sroot 	return (-1);
7611437cf11Sbill }
762c09a6a34Ssam 
mkent(de,segnum,bufp,name)763d0b9e33eSwnj mkent(de, segnum, bufp, name)
7641437cf11Sbill 	register struct rt_ent *de;
765d0b9e33eSwnj 	int segnum;
7661437cf11Sbill 	register struct stat *bufp;
7671437cf11Sbill 	char *name;
7681437cf11Sbill {
769c09a6a34Ssam 	struct tm *localtime();
770c09a6a34Ssam 	register struct tm *timp;
771c09a6a34Ssam 	register struct rt_ent *workp;
772c09a6a34Ssam 	int count;
7731437cf11Sbill 
7741437cf11Sbill 	count = (((bufp->st_size -1) >>9) + 1);
775c09a6a34Ssam 	/* make sure there is room */
7761437cf11Sbill 	if (de->rt_len == count)
7771437cf11Sbill 		goto overwrite;
778c09a6a34Ssam 	if ((char *)rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) {
7792e5d0128Sbloom 		/* no entries left on segment, trying adding new segment */
7802e5d0128Sbloom 		if (rt_dir[0].rd_numseg > rt_dir[0].rd_lstseg) {
7812e5d0128Sbloom 			short newseg;
7822e5d0128Sbloom 			register int i;
7832e5d0128Sbloom 			int maxseg;
7842e5d0128Sbloom 			short size;
7852e5d0128Sbloom 
7862e5d0128Sbloom 			newseg = rt_dir[0].rd_lstseg++;
7872e5d0128Sbloom 			rt_dir[newseg] = rt_nulldir;
7882e5d0128Sbloom 			rt_dir[newseg].rd_nxtseg = rt_dir[segnum].rd_nxtseg;
7892e5d0128Sbloom 			rt_dir[segnum].rd_nxtseg = newseg + 1;
7902e5d0128Sbloom 			rt_dir[newseg].rd_entpad = rt_dir[0].rd_entpad;
7912e5d0128Sbloom 			rt_dir[newseg].rd_numseg = rt_dir[0].rd_numseg;
7922e5d0128Sbloom 			size = 0;
7932e5d0128Sbloom 			maxseg = 0;
7942e5d0128Sbloom 			for(i = newseg - 1; i >= 0; i--) {
7952e5d0128Sbloom 				workp = rt_curend[i] - 1;
7962e5d0128Sbloom 				if (workp->rt_stat != RT_NULL)
7972e5d0128Sbloom 					continue;
7982e5d0128Sbloom 				if (workp->rt_len < size)
7992e5d0128Sbloom 					continue;
8002e5d0128Sbloom 				size = workp->rt_len;
8012e5d0128Sbloom 				maxseg = i;
8022e5d0128Sbloom 			}
8032e5d0128Sbloom 			size = 0;
8042e5d0128Sbloom 			for (workp = &rt_dir[maxseg].rt_ents[0];
8052e5d0128Sbloom 			    workp->rt_stat != RT_ESEG; workp++) {
8062e5d0128Sbloom 				size += workp->rt_len;
8072e5d0128Sbloom 			}
8082e5d0128Sbloom 			workp--;
8092e5d0128Sbloom 			rt_dir[newseg].rt_ents[0].rt_len = workp->rt_len;
8102e5d0128Sbloom 			rt_dir[newseg].rd_stfile =
8112e5d0128Sbloom 			    rt_dir[maxseg].rd_stfile + size - workp->rt_len;
8122e5d0128Sbloom 			workp->rt_len = 0;
8132e5d0128Sbloom 			rt_curend[newseg] = &rt_dir[newseg].rt_ents[1];
8142e5d0128Sbloom 			lwrite(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]);
8152e5d0128Sbloom 			if (segnum != 0)
8162e5d0128Sbloom 				lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK,
8172e5d0128Sbloom 				    (char *)&rt_dir[segnum]);
8182e5d0128Sbloom 			lwrite((6+newseg*2)*RT_BLOCK, 2*RT_BLOCK,
8192e5d0128Sbloom 			    (char *)&rt_dir[newseg]);
8202e5d0128Sbloom 			segnum = newseg;
8212e5d0128Sbloom 			de = &rt_dir[newseg].rt_ents[0];
8222e5d0128Sbloom 		} else {
8232e5d0128Sbloom 			fprintf(stderr, "All directory segments full on  %s\n",
8242e5d0128Sbloom 				defdev);
8251437cf11Sbill 			exit(1);
8261437cf11Sbill 		}
8272e5d0128Sbloom 	}
8281437cf11Sbill 	/* copy directory entries up */
829d0b9e33eSwnj 	for (workp = rt_curend[segnum]+1; workp > de; workp--)
8301437cf11Sbill 		*workp = workp[-1];
8311437cf11Sbill 	de[1].rt_len -= count;
8321437cf11Sbill 	de->rt_len = count;
833d0b9e33eSwnj 	rt_curend[segnum]++;
8341437cf11Sbill 	rt_nleft--;
835c09a6a34Ssam 
8361437cf11Sbill overwrite:
8371437cf11Sbill 	srad50(name,de->rt_name);
8381437cf11Sbill 	timp = localtime(&bufp->st_mtime);
839b566105aSwnj 	de->rt_date.rt_dy = timp->tm_mday;
8401437cf11Sbill 	de->rt_date.rt_mo = timp->tm_mon + 1;
8411437cf11Sbill 	de->rt_date.rt_yr = timp->tm_year - 72;
8421437cf11Sbill 	de->rt_stat = RT_FILE;
8431437cf11Sbill 	de->rt_pad = 0;
8441437cf11Sbill 	de->rt_chan = 0;
8451437cf11Sbill 	de->rt_job = 0;
846d0b9e33eSwnj 	lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[segnum]);
8471437cf11Sbill }
8481437cf11Sbill 
toflop(name,ocount,dope)8491437cf11Sbill toflop(name, ocount, dope)
8501437cf11Sbill 	char *name;
8511437cf11Sbill 	register FLDOPE *dope;
8521437cf11Sbill 	long ocount;
8531437cf11Sbill {
8541437cf11Sbill 	register file, n, startad = dope->startad, count = ocount;
8551437cf11Sbill 	char buff[512];
8561437cf11Sbill 
8571437cf11Sbill 	file = open(name, 0);
8581437cf11Sbill 	if (file < 0) {
859c09a6a34Ssam 		fprintf(stderr, "arff: couldn't open %s\n",name);
860c09a6a34Ssam 		exit(1);
861c09a6a34Ssam 	}
8621437cf11Sbill 	for( ; count >= 512; count -= 512) {
8632e5d0128Sbloom 		(void) read(file, buff, 512);
8641437cf11Sbill 		lwrite(startad, 512, buff);
8651437cf11Sbill 		startad += 512;
8661437cf11Sbill 	}
8672e5d0128Sbloom 	(void) read(file, buff, count);
8682e5d0128Sbloom 	(void) close(file);
869c09a6a34Ssam 	if (count <= 0)
870c09a6a34Ssam 		return;
871c09a6a34Ssam 	for (n = count; n < 512; n ++)
872c09a6a34Ssam 		buff[n] = 0;
8731437cf11Sbill 	lwrite(startad, 512, buff);
8741437cf11Sbill 	count = (dope->rtdope->rt_len*512-ocount)/512 ;
875c09a6a34Ssam 	if (count <= 0)
876c09a6a34Ssam 		return;
8771437cf11Sbill 	for ( ; count > 0 ; count--) {
8781437cf11Sbill 		startad += 512;
8791437cf11Sbill 		lwrite(startad, 512, zeroes);
8801437cf11Sbill 	}
8811437cf11Sbill }
882c09a6a34Ssam 
dcmd()8831437cf11Sbill dcmd()
8841437cf11Sbill {
8851437cf11Sbill 	register int i;
8861437cf11Sbill 
8871437cf11Sbill 	rt_init();
8881437cf11Sbill 	if (namc)
8891437cf11Sbill 		for (i = 0; i < namc; i++)
890c09a6a34Ssam 			if (rtk(namv[i])==0)
891c09a6a34Ssam 				namv[i]=0;
8921437cf11Sbill 	if (dirdirty)
8931437cf11Sbill 		scrunch();
8941437cf11Sbill }
895c09a6a34Ssam 
rtk(name)8961437cf11Sbill rtk(name)
8971437cf11Sbill 	char *name;
8981437cf11Sbill {
8991437cf11Sbill 	register FLDOPE *dope;
9001437cf11Sbill 	register struct rt_ent *de;
9011437cf11Sbill 	FLDOPE *lookup();
9021437cf11Sbill 
9031437cf11Sbill 	if (dope = lookup(name)) {
9041437cf11Sbill 		printf("d - %s\n",name);
9051437cf11Sbill 		de = dope->rtdope;
9061437cf11Sbill 		de->rt_stat = RT_NULL;
9071437cf11Sbill 		de->rt_name[0] = 0;
9081437cf11Sbill 		de->rt_name[1] = 0;
9091437cf11Sbill 		de->rt_name[2] = 0;
910c09a6a34Ssam 		*((u_short *)&(de->rt_date)) = 0;
9111437cf11Sbill 		dirdirty = 1;
9121437cf11Sbill 		return (0);
9131437cf11Sbill 	}
9141437cf11Sbill 	return (1);
9151437cf11Sbill }
916c09a6a34Ssam 
scrunch()917c09a6a34Ssam scrunch()
918c09a6a34Ssam {
919d0b9e33eSwnj 	register struct rt_ent *de , *workp;
920d0b9e33eSwnj 	register segnum;
921c09a6a34Ssam 
922c09a6a34Ssam 	for (segnum = 0; segnum != -1;
9232e5d0128Sbloom 	     segnum = rt_dir[segnum].rd_nxtseg - 1) {
924c09a6a34Ssam 		for (de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++)
925b74381a6Ssam 			if (de->rt_stat == RT_NULL &&
926254d8466Shelge 			    (de+1)->rt_stat == RT_NULL) {
9271437cf11Sbill 				(de+1)->rt_len += de->rt_len;
928d0b9e33eSwnj 				for (workp=de; workp<rt_curend[segnum]; workp++)
9291437cf11Sbill 					*workp = workp[1];
9301437cf11Sbill 				de--;
931d0b9e33eSwnj 				rt_curend[segnum]--;
9321437cf11Sbill 				rt_nleft++;
9331437cf11Sbill 			}
934c09a6a34Ssam 		lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK,
935c09a6a34Ssam 			(char *)&rt_dir[segnum]);
936d0b9e33eSwnj 	}
937254d8466Shelge 	dirdirty = 0;
9381437cf11Sbill }
939