xref: /original-bsd/old/arff/arff.c (revision f0fd5f8a)
1 static	char *sccsid = "@(#)arff.c	4.11 (Berkeley) 82/06/27";
2 
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <time.h>
6 #include <signal.h>
7 #include <stdio.h>
8 
9 #define dbprintf printf
10 
11 struct rt_dat {
12 	u_short	rt_yr:5;	/* year-1972 */
13 	u_short	rt_dy:5;	/* day */
14 	u_short	rt_mo:5;	/* month */
15 };
16 
17 struct	rt_axent {
18 	char	rt_sent[14];
19 };
20 
21 struct rt_ent {
22 	char	rt_pad;		/* unusued */
23 	char	rt_stat;	/* type of entry, or end of seg */
24 	u_short	rt_name[3];	/* name, 3 words in rad50 form */
25 	u_short	rt_len;		/* length of file */
26 	char	rt_chan;	/* only used in temporary files */
27 	char	rt_job;		/* only used in temporary files */
28 	struct rt_dat rt_date;	/* creation date */
29 };
30 
31 #define RT_TEMP		1
32 #define RT_NULL		2
33 #define RT_FILE		4
34 #define RT_ESEG		8
35 
36 #define RT_BLOCK	512	/* block size */
37 #define RT_DIRSIZE	31	/* max # of directory segments */
38 
39 struct rt_head {
40 	short	rt_numseg;	/* # of segments available */
41 	short	rt_nxtseg;	/* # of next logical segment */
42 	short	rt_lstseg;	/* highest seg currently open */
43 	u_short	rt_entpad;	/* extra words/directory entry */
44 	short	rt_stfile;	/* block # where files begin */
45 };
46 
47 struct	rt_dir {
48 	struct rt_head	rt_axhead;
49 	struct rt_ent	rt_ents[72];
50 	char		_dirpad[6];
51 };
52 
53 extern struct rt_dir	rt_dir[RT_DIRSIZE];
54 extern int		rt_entsiz;
55 extern int		floppydes;
56 extern char		*rt_last;
57 
58 typedef struct fldope {
59 	int	startad;
60 	int	count;
61 struct	rt_ent	*rtdope;
62 } FLDOPE;
63 
64 FLDOPE *lookup();
65 
66 #define rt(p) ((struct rt_ent *) p )
67 #define Ain1 03100
68 #define Ain2 050
69 #define flag(c) (flg[('c') - 'a'])
70 
71 char *man = "rxtd";
72 char zeroes[512];
73 
74 extern char *val;
75 extern char table[256];
76 struct rt_dir rt_dir[RT_DIRSIZE] = {
77 	{4, 0, 1, 0, 14},
78 	{ {0, RT_NULL, {0, 0, 0}, 494, 0}, {0, RT_ESEG} }
79 };
80 
81 int	rt_entsiz;
82 int	rt_nleft;
83 struct rt_ent *rt_curend[RT_DIRSIZE];
84 int	floppydes;
85 int	dirdirty;
86 char	*rt_last;
87 char	*defdev = "/dev/floppy";
88 
89 char *opt = "vf";
90 
91 int	signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};
92 extern long lseek();
93 int	rcmd(), dcmd(), xcmd(), tcmd();
94 
95 int	(*comfun)();
96 char	flg[26];
97 char	**namv;
98 int	namc;
99 int	file;
100 
101 main(argc, argv)
102 	char *argv[];
103 {
104 	register char *cp;
105 
106 	if (argc < 2)
107 		usage();
108 	cp = argv[1];
109 	for (cp = argv[1]; *cp; cp++)
110 		switch (*cp) {
111 
112 		case 'm':
113 		case 'v':
114 		case 'u':
115 		case 'w':
116 			flg[*cp-'a']++;
117 			continue;
118 		case 'c':
119 			{
120 #define SURE	"Last chance before clobbering floppy?"
121 				int tty;
122 				char response[128];
123 
124 				tty = open("/dev/tty", 2);
125 				write(tty, SURE, sizeof(SURE));
126 				read(tty, response, sizeof(response));
127 				if (*response != 'y')
128 					exit(50);
129 				flag(c)++;
130 				close(tty);
131 			}
132 			dirdirty++;
133 			continue;
134 
135 		case 'r':
136 			setcom(rcmd);
137 			flag(r)++;
138 			continue;
139 
140 		case 'd':
141 			setcom(dcmd);
142 			flag(d)++;
143 			continue;
144 
145 		case 'x':
146 			setcom(xcmd);
147 			continue;
148 
149 		case 't':
150 			setcom(tcmd);
151 			continue;
152 
153 		case 'f':
154 			defdev = argv[2];
155 			argv++;
156 			argc--;
157 			continue;
158 
159 		default:
160 			fprintf(stderr, "arff: bad option `%c'\n", *cp);
161 			exit(1);
162 		}
163 
164 	namv = argv+2;
165 	namc = argc-2;
166 	if (comfun == 0) {
167 		if (flag(u) == 0) {
168 			fprintf(stderr, "arff: one of [%s] must be specified\n",
169 				man);
170 			exit(1);
171 		}
172 		setcom(rcmd);
173 	}
174 	(*comfun)();
175 	exit(notfound());
176 }
177 
178 setcom(fun)
179 	int (*fun)();
180 {
181 	if (comfun != 0) {
182 		fprintf(stderr, "arff: only one of [%s] allowed\n", man);
183 		exit(1);
184 	}
185 	comfun = fun;
186 }
187 
188 usage()
189 {
190 	fprintf(stderr, "usage: ar [%s][%s] archive files ...\n", opt, man);
191 	exit(1);
192 }
193 
194 notfound()
195 {
196 	register i, n = 0;
197 
198 	for (i = 0; i < namc; i++)
199 		if (namv[i]) {
200 			fprintf(stderr, "arff: %s not found\n", namv[i]);
201 			n++;
202 		}
203 	return(n);
204 }
205 
206 mesg(c)
207 {
208 	if (flag(v))
209 		if (c != 'c' || flag(v) > 1)
210 			printf("%c - %s\n", c, file);
211 }
212 
213 tcmd()
214 {
215 	register char *de, *last;
216 	FLDOPE *lookup(), *dope;
217 	int segnum, nleft;
218 	register i;
219 	register struct rt_ent *rde;
220 
221 	rt_init();
222 	if (namc == 0)
223 		for (segnum = 0; segnum != -1;
224 		     segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1)
225 		{
226 			last = rt_last + segnum*2*RT_BLOCK;
227 			for (de = ((char *)&rt_dir[segnum])+10; de <= last;
228 			    de += rt_entsiz)
229 				if (rtls(rt(de))) {
230 					nleft = (last-de)/rt_entsiz;
231 #define ENTRIES "\n%d entries remaining in directory segment %d.\n"
232 					printf(ENTRIES, nleft, segnum+1);
233 					break;
234 				}
235 		}
236 	else
237 		for (i = 0; i < namc; i++)
238 			if (dope = lookup(namv[i])) {
239 				rde = dope->rtdope;
240 				rtls(rde);
241 				namv[i] = 0;
242 			}
243 }
244 
245 rtls(de)
246 	register struct rt_ent *de;
247 {
248 	int month, day, year;
249 	char name[12], ext[4];
250 
251 	switch (de->rt_stat) {
252 
253 	case RT_TEMP:
254 		if (flag(v))
255 			printf("Tempfile:\n");
256 		/* fall thru...*/
257 
258 	case RT_FILE:
259 		if (!flag(v)) {
260 			sunrad50(name, de->rt_name);
261 			printf("%s\n", name);
262 			break;
263 		}
264 		unrad50(2, de->rt_name, name);
265 		unrad50(1, &(de->rt_name[2]), ext);
266 		day = de->rt_date.rt_dy;
267 		year = de->rt_date.rt_yr+72;
268 		month = de->rt_date.rt_mo;
269 		printf("%6.6s  %3.3s	%02d/%02d/%02d	%d\n",name,
270 			ext, month, day, year, de->rt_len);
271 		break;
272 
273 	case RT_NULL:
274 		printf("%-25.9s	%d\n","<UNUSED>", de->rt_len);
275 		break;
276 
277 	case RT_ESEG:
278 		return(1);
279 	}
280 	return(0);
281 }
282 
283 xcmd()
284 {
285 	register char *de, *last;
286 	int segnum;
287 	char name[12];
288 	register int i;
289 
290 	rt_init();
291 	if (namc == 0) {
292 		for (segnum = 0; segnum != -1;
293 		     segnum = rt_dir[segnum].rt_axhead.rt_nxtseg-1)
294 			for (last = rt_last+(segnum*2*RT_BLOCK),
295 			     de = ((char *)&rt_dir[segnum])+10; de <= last;
296 			     de += rt_entsiz)
297 				switch (rt(de)->rt_stat) {
298 				case RT_ESEG:
299 					return;
300 				case RT_TEMP:
301 				case RT_FILE:
302 					sunrad50(name,rt(de)->rt_name);
303 					rtx(name);
304 				case RT_NULL:
305 				;
306 				}
307 	} else
308 		for (i = 0; i < namc; i++)
309 			if (rtx(namv[i]) == 0)
310 				namv[i] = 0;
311 }
312 
313 rtx(name)
314 	char *name;
315 {
316 	register FLDOPE *dope;
317 	FLDOPE *lookup();
318 	register startad, count;
319 	int file;
320 	char buff[512];
321 
322 
323 	if (dope = lookup(name)) {
324 		if (flag(v))
325 			rtls(dope->rtdope);
326 		else
327 			printf("x - %s\n",name);
328 
329 		if ((file = creat(name, 0666)) < 0)
330 			return(1);
331 		count = dope->count;
332 		startad = dope->startad;
333 		for( ; count > 0 ; count -= 512) {
334 			lread(startad, 512, buff);
335 			write(file, buff, 512);
336 			startad += 512;
337 		}
338 		close(file);
339 		return(0);
340 	}
341 	return(1);
342 }
343 
344 rt_init()
345 {
346 	static initized = 0;
347 	register char *de, *last;
348 	register i;
349 	int dirnum;
350 	char *mode;
351 	FILE *temp_floppydes;
352 
353 	if (initized)
354 		return;
355 	initized = 1;
356 	if (flag(c) || flag(d) || flag(r))
357 		mode = "r+";
358 	else
359 		mode = "r";
360 	if ((temp_floppydes = fopen(defdev, mode)) == NULL) {
361 		perror(defdev);
362 		exit(1);
363 	} else
364 		floppydes = fileno(temp_floppydes);
365 	if (!flag(c)) {
366 		lread(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]);
367 		dirnum = rt_dir[0].rt_axhead.rt_numseg;
368 		if (dirnum > RT_DIRSIZE) {
369 			fprintf(stderr,"arff: too many directory segments\n");
370 			exit(1);
371 		}
372 		for (i = 1; i < dirnum; i++)
373 			lread((6+2*i)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[i]);
374 	} else
375 		dirnum = 1;
376 
377 	rt_entsiz = 2*rt_dir[0].rt_axhead.rt_entpad + 14;
378 	rt_entsiz = 14;			/* assume rt_entpad = 0 ??? */
379 	rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz;
380 	rt_nleft = 0;
381 
382 	for (i = 0; i < dirnum; i++) {
383 		last = rt_last + i*2*RT_BLOCK;
384 		for (de = ((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz)
385 			if (rt(de)->rt_stat == RT_ESEG)
386 				break;
387 		rt_curend[i] = rt(de);
388 		rt_nleft += (last-de)/rt_entsiz;
389 	}
390 }
391 
392 static FLDOPE result;
393 
394 FLDOPE *
395 lookup(name)
396 	char *name;
397 {
398 	unsigned short rname[3];
399 	register char *de, *last;
400 	int segnum;
401 	register index;
402 
403 	srad50(name,rname);
404 
405 	/*
406 	 *  Search for name, accumulate blocks in index
407 	 */
408 	rt_init();
409 	for (segnum = 0; segnum != -1;
410 	     segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1)
411 	{
412 		index = 0;
413 		last = rt_last + segnum*2*RT_BLOCK;
414 		for (de=((char *)&rt_dir[segnum])+10;
415 		     rt(de)->rt_stat != RT_ESEG; de += rt_entsiz)
416 			switch(rt(de)->rt_stat) {
417 
418 			case RT_FILE:
419 			case RT_TEMP:
420 				if(samename(rname,rt(de)->rt_name)) {
421 					result.count = rt(de)->rt_len * 512;
422 					result.startad = 512*
423 						(rt_dir[segnum].rt_axhead.rt_stfile + index);
424 					result.rtdope = (struct rt_ent *) de;
425 					return(&result);
426 				}
427 
428 			case RT_NULL:
429 				index += rt(de)->rt_len;
430 			}
431         }
432 	return((FLDOPE *) 0);
433 
434 }
435 
436 static
437 samename(a, b)
438 	u_short a[], b[];
439 {
440 	return(*a == *b && a[1] == b[1] && a[2] == b[2] );
441 }
442 
443 rad50(cp, out)
444 	register u_char *cp;
445 	u_short *out;
446 {
447 	register index, temp;
448 
449 	for (index = 0; *cp; index++) {
450 		temp = Ain1 * table[*cp++];
451 		if (*cp!=0) {
452 			temp += Ain2 * table[*cp++];
453 			if(*cp!=0)
454 				temp += table[*cp++];
455 		}
456 		out[index] = temp;
457 	}
458 }
459 
460 #define reduce(x, p, q) (x = v[p/q], p %= q);
461 
462 unrad50(count, in, cp)
463 	u_short *in;
464 	register char *cp;
465 {
466 	register i, temp;
467 	register u_char *v = (u_char *) val;
468 
469 	for (i = 0; i < count; i++) {
470 		temp = in[i];
471 		reduce(*cp++, temp, Ain1);
472 		reduce(*cp++, temp, Ain2);
473 		reduce(*cp++, temp, 1);
474 	}
475 	*cp=0;
476 }
477 
478 srad50(name, rname)
479 	register char *name;
480 	register u_short *rname;
481 {
482 	register index;
483 	register char *cp;
484 	char file[7], ext[4];
485 
486 	/*
487 	 * Find end of pathname
488 	 */
489 	for (cp = name; *cp++; )
490 		;
491 	while (cp >= name && *--cp != '/')
492 		;
493 	cp++;
494 	/*
495 	 * Change to rad50
496 	 */
497 	for (index = 0; *cp; ) {
498 		file[index++] = *cp++;
499 		if (*cp == '.') {
500 			cp++;
501 			break;
502 		}
503 		if (index >= 6) {
504 			break;
505 		}
506 	}
507 	file[index] = 0;
508 	for (index = 0; *cp; ) {
509 		ext[index++] = *cp++;
510 		if (*cp == '.' || index >= 3)
511 			break;
512 	}
513 	ext[index]=0;
514 	rname[0] = rname[1] = rname[2] = 0;
515 	rad50((u_char *)file, rname);
516 	rad50((u_char *)ext, rname+2);
517 }
518 
519 sunrad50(name, rname)
520 	u_short rname[];
521 	register char *name;
522 {
523 	register char *cp, *cp2;
524 	char ext[4];
525 
526 	unrad50(2, rname, name);
527 	unrad50(1, rname + 2, ext);
528 	/*
529 	 * Jam name and extension together with a dot
530 	 * deleting white space
531 	 */
532 	for (cp = name; *cp++;)
533 		;
534 	--cp;
535 	while (*--cp == ' ' && cp >= name)
536 		;
537 	*++cp = '.';
538 	cp++;
539 	for (cp2 = ext; *cp2 != ' ' && cp2 < ext+3;)
540 		*cp++ = *cp2++;
541 	*cp=0;
542 	if (cp[-1] == '.')
543 		cp[-1] = 0;
544 }
545 
546 static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789";
547 static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789";
548 
549 static char table[256] = {
550 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
551 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
552 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
553 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
554 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
555 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
556 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
557 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
558 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
559 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
560 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
561 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
562 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
563 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
564 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
565 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 };
566 
567 /*
568  * Logical to physical adress translation
569  */
570 long
571 trans(logical)
572 	register int logical;
573 {
574 	register int sector, bytes, track;
575 
576 	logical += 26*128;
577 	bytes = (logical&127);
578 	logical >>= 7;
579 	sector = logical%26;
580 	if(sector >= 13)
581 		sector = sector*2+1;
582 	else
583 		sector *= 2;
584 	sector += 26 + ((track = (logical/26))-1)*6;
585 	sector %= 26;
586 	return((((track*26)+sector) << 7) + bytes);
587 }
588 
589 lread(startad, count, obuff)
590 	register startad, count;
591 	register char *obuff;
592 {
593 	long trans();
594 	extern floppydes;
595 	register int size = flag(m) ? 512 : 128;
596 
597 	rt_init();
598 	while ((count -= size) >= 0) {
599 		lseek(floppydes, flag(m) ?
600 			(long)startad : trans(startad), 0);
601 		if (read(floppydes, obuff, size) != size)
602 			fprintf(stderr, "arff: read error block %d\n",
603 				startad/size);
604 		obuff += size;
605 		startad += size;
606 	}
607 }
608 
609 lwrite(startad, count, obuff)
610 	register startad, count;
611 	register char *obuff;
612 {
613 	long trans();
614 	extern floppydes;
615 	register int size = flag(m) ? 512 : 128;
616 
617 	rt_init();
618 	while ((count -= size) >= 0) {
619 		lseek(floppydes, flag(m) ?
620 			(long)startad : trans(startad), 0);
621 		if (write(floppydes, obuff, size) != size)
622 			fprintf(stderr, "arff: write error block %d\n",
623 				startad/size);
624 		obuff += size;
625 		startad += size;
626 	}
627 }
628 
629 rcmd()
630 {
631 	register int i;
632 
633 	rt_init();
634 	if (namc > 0)
635 		for (i = 0; i < namc; i++)
636 			if (rtr(namv[i]) == 0)
637 				namv[i] = 0;
638 }
639 
640 rtr(name)
641 	char *name;
642 {
643 	register FLDOPE *dope;
644 	register struct rt_ent *de;
645 	struct stat buf;
646 	register struct stat *bufp = &buf;
647 	int segnum;
648 	register char *last;
649 
650 	if (stat(name, bufp) < 0) {
651 		perror(name);
652 		return(-1);
653 	}
654 	if (dope = lookup(name)) {
655 		/* can replace, no problem */
656 		de = dope->rtdope;
657 		if (bufp->st_size <= (de->rt_len * 512))
658 			printf("r - %s\n",name),
659 			toflop(name, bufp->st_size, dope);
660 		else {
661 			fprintf(stderr, "%s will not fit in currently used file on floppy\n",name);
662 			return(-1);
663 		}
664 	} else {
665 		/* Search for vacant spot */
666 		for (segnum = 0; segnum != -1;
667 		     segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1)
668 		{
669 			last = rt_last + segnum*2*RT_BLOCK;
670 			for (de = rt_dir[segnum].rt_ents;
671 			    rt(de)->rt_stat != RT_ESEG; de++)
672 				if ((de)->rt_stat == RT_NULL) {
673 					if (bufp->st_size <= (de->rt_len*512)) {
674 						printf("a - %s\n",name),
675 						mkent(de, segnum, bufp,name);
676 						goto found;
677 					}
678 					continue;
679 				}
680 	    }
681 	    printf("%s: no slot for file\n", name);
682 	    return (-1);
683 	}
684 
685 found:
686 	if (dope = lookup(name)) {
687 		toflop(name, bufp->st_size, dope);
688 		return (0);
689 	}
690 	printf("%s: internal error, added then not found\n", name);
691 	return (-1);
692 }
693 
694 mkent(de, segnum, bufp, name)
695 	register struct rt_ent *de;
696 	int segnum;
697 	register struct stat *bufp;
698 	char *name;
699 {
700 	struct tm *localtime();
701 	register struct tm *timp;
702 	register struct rt_ent *workp;
703 	int count;
704 
705 	count = (((bufp->st_size -1) >>9) + 1);
706 	/* make sure there is room */
707 	if (de->rt_len == count)
708 		goto overwrite;
709 	if ((char *)rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) {
710 		/* no entries left on segment */
711 		if (flag(o))
712 			goto overwrite;
713 		fprintf(stderr,"Directory segment #%d full on  %s\n",segnum+1,
714 			defdev);
715 		exit(1);
716 	}
717 	/* copy directory entries up */
718 	for (workp = rt_curend[segnum]+1; workp > de; workp--)
719 		*workp = workp[-1];
720 	de[1].rt_len -= count;
721 	de->rt_len = count;
722 	rt_curend[segnum]++;
723 	rt_nleft--;
724 
725 overwrite:
726 	srad50(name,de->rt_name);
727 	timp = localtime(&bufp->st_mtime);
728 	de->rt_date.rt_dy = timp->tm_mday;
729 	de->rt_date.rt_mo = timp->tm_mon + 1;
730 	de->rt_date.rt_yr = timp->tm_year - 72;
731 	de->rt_stat = RT_FILE;
732 	de->rt_pad = 0;
733 	de->rt_chan = 0;
734 	de->rt_job = 0;
735 	lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[segnum]);
736 }
737 
738 toflop(name, ocount, dope)
739 	char *name;
740 	register FLDOPE *dope;
741 	long ocount;
742 {
743 	register file, n, startad = dope->startad, count = ocount;
744 	char buff[512];
745 
746 	file = open(name, 0);
747 	if (file < 0) {
748 		fprintf(stderr, "arff: couldn't open %s\n",name);
749 		exit(1);
750 	}
751 	for( ; count >= 512; count -= 512) {
752 		read(file, buff, 512);
753 		lwrite(startad, 512, buff);
754 		startad += 512;
755 	}
756 	read(file, buff, count);
757 	close(file);
758 	if (count <= 0)
759 		return;
760 	for (n = count; n < 512; n ++)
761 		buff[n] = 0;
762 	lwrite(startad, 512, buff);
763 	count = (dope->rtdope->rt_len*512-ocount)/512 ;
764 	if (count <= 0)
765 		return;
766 	for ( ; count > 0 ; count--) {
767 		startad += 512;
768 		lwrite(startad, 512, zeroes);
769 	}
770 }
771 
772 dcmd()
773 {
774 	register int i;
775 
776 	rt_init();
777 	if (namc)
778 		for (i = 0; i < namc; i++)
779 			if (rtk(namv[i])==0)
780 				namv[i]=0;
781 	if (dirdirty)
782 		scrunch();
783 }
784 
785 rtk(name)
786 	char *name;
787 {
788 	register FLDOPE *dope;
789 	register struct rt_ent *de;
790 	FLDOPE *lookup();
791 
792 	if (dope = lookup(name)) {
793 		printf("d - %s\n",name);
794 		de = dope->rtdope;
795 		de->rt_stat = RT_NULL;
796 		de->rt_name[0] = 0;
797 		de->rt_name[1] = 0;
798 		de->rt_name[2] = 0;
799 		* ((u_short *)&(de->rt_date)) = 0;
800 		dirdirty = 1;
801 		return(0);
802 	}
803 	return(1);
804 }
805 
806 scrunch()
807 {
808 	register struct rt_ent *de , *workp;
809 	register segnum;
810 
811 	for (segnum = 0; segnum != -1;
812 	     segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) {
813 		dirdirty = 0;
814 		for (de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++)
815 			if (de->rt_stat == RT_NULL && de[1].rt_stat == RT_NULL) {
816 				(de+1)->rt_len += de->rt_len;
817 				for (workp = de; workp < rt_curend[segnum]; workp++)
818 					*workp = workp[1];
819 				de--;
820 				rt_curend[segnum]--;
821 				rt_nleft++;
822 				dirdirty = 1;
823 			}
824 		if (dirdirty)
825 			lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK,
826 				(char *)&rt_dir[segnum]);
827 	}
828 }
829