xref: /csrg-svn/old/arff/arff.c (revision 3356)
1*3356Swnj static	char *sccsid = "@(#)arff.c	4.4 (Berkeley) 81/03/22";
2954Sbill #include <sys/types.h>
3954Sbill #include <sys/stat.h>
4954Sbill #include <time.h>
5954Sbill #include <signal.h>
6954Sbill #include <stdio.h>
7954Sbill #define dbprintf printf
8954Sbill struct rt_dat {
9*3356Swnj unsigned short	int	rt_yr:5;	/* Year - 1972			 */
10*3356Swnj unsigned short	int	rt_dy:5;	/* day				 */
11*3356Swnj unsigned short	int	rt_mo:5;	/* month				 */
12954Sbill };
13954Sbill struct	rt_axent {
14954Sbill 	char	rt_sent[14];
15954Sbill };
16954Sbill 
17954Sbill struct rt_ent {
18*3356Swnj 	char  rt_pad;			/* unusued		     */
19*3356Swnj 	char  rt_stat;			/* Type of entry, or end of seg */
20*3356Swnj 	unsigned short rt_name[3];	/* Name, 3 words in rad50 form */
21*3356Swnj 	short rt_len;			/* Length of file	      */
22*3356Swnj 	char  rt_chan;			/* Only used in temporary files */
23*3356Swnj 	char  rt_job;			/* Only used in temporary files */
24*3356Swnj 	struct rt_dat rt_date;		/* Creation Date			 */
25954Sbill };
26954Sbill #define RT_TEMP 1
27954Sbill #define RT_NULL 2
28954Sbill #define RT_FILE 4
29954Sbill #define RT_ESEG 8
30954Sbill #define RT_BLOCK 512
313346Swnj #define RT_DIRSIZE 31			/* max # of directory segments */
32954Sbill struct rt_head {
33*3356Swnj 	short	rt_numseg;		/* number of segments available */
34*3356Swnj 	short	rt_nxtseg;		/* segment no of next log. seg */
35*3356Swnj 	short	rt_lstseg;		/* highest seg currenltly open */
36*3356Swnj 	unsigned short	rt_entpad;	/* extra words/dir. entry      */
37*3356Swnj 	short	rt_stfile;		/* block no where files begin  */
38954Sbill };
39954Sbill struct	rt_dir {
40954Sbill 	struct rt_head	rt_axhead;
41954Sbill 	struct rt_ent	rt_ents[72];
42954Sbill 	char	_dirpad[6];
43954Sbill };
443346Swnj extern struct rt_dir	rt_dir[RT_DIRSIZE];
45954Sbill extern int		rt_entsiz;
46954Sbill extern int		floppydes;
47954Sbill extern char		*rt_last;
48954Sbill typedef struct fldope {
49954Sbill 	int	startad;
50954Sbill 	int	count;
51954Sbill struct	rt_ent	*rtdope;
52954Sbill } FLDOPE;
53954Sbill FLDOPE *lookup();
54954Sbill #define rt(p) ((struct rt_ent *) p )
55954Sbill #define Ain1 03100
56954Sbill #define Ain2 050
57954Sbill #define flag(c) (flg[(c) - 'a'])
58954Sbill 
59954Sbill char	*man	=	{ "rxtd" };
60954Sbill 
61954Sbill char zeroes[512];
62954Sbill extern char *val;
63954Sbill extern char table[256];
643346Swnj struct rt_dir
653346Swnj    rt_dir[RT_DIRSIZE] = {{4,0,1,0,14},{0,RT_NULL,{0,0,0},494,0}, {0,RT_ESEG}};
66954Sbill int		rt_entsiz;
67954Sbill int		rt_nleft;
683346Swnj struct rt_ent	*rt_curend[RT_DIRSIZE];
69954Sbill int		floppydes;
70954Sbill int		dirdirty;
71954Sbill char		*rt_last;
72954Sbill char		*defdev = "/dev/floppy";
73954Sbill 
74954Sbill char	*opt	=	{ "vf" };
75954Sbill 
76954Sbill int	signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};
77954Sbill long	lseek();
78954Sbill int	rcmd();
79954Sbill int	dcmd();
80954Sbill int	xcmd();
81954Sbill int	tcmd();
82954Sbill int	(*comfun)();
83954Sbill char	flg[26];
84954Sbill char	**namv;
85954Sbill int	namc;
86954Sbill int	file;
87954Sbill 
88954Sbill 
89954Sbill main(argc, argv)
90954Sbill char *argv[];
91954Sbill {
92954Sbill 	register char *cp;
93954Sbill 
94*3356Swnj 	/* register i;
95954Sbill 	for(i=0; signum[i]; i++)
96954Sbill 		if(signal(signum[i], SIG_IGN) != SIG_IGN)
97*3356Swnj 			signal(signum[i], sigdone); */
98954Sbill 	if(argc < 2)
99954Sbill 		usage();
100954Sbill 	cp = argv[1];
101954Sbill 	for(cp = argv[1]; *cp; cp++)
102954Sbill 	switch(*cp) {
103954Sbill 	case 'm':
104954Sbill 	case 'v':
105954Sbill 	case 'u':
106954Sbill 	case 'w':
107954Sbill 		flg[*cp - 'a']++;
108954Sbill 		continue;
109954Sbill 	case 'c':
110954Sbill 		{
111954Sbill #define SURE	"Are you sure you want to clobber the floppy?\n"
112954Sbill 			int tty;
1131735Sbill 			char response[128];
114954Sbill 			tty = open("/dev/tty",2);
115954Sbill 			write(tty,SURE,sizeof(SURE));
116*3356Swnj 			read(tty,response,sizeof(response));
117954Sbill 			if(*response!='y')
118954Sbill 				exit(50);
119954Sbill 			flag('c')++;
120954Sbill 			close(tty);
121954Sbill 		}
122954Sbill 		dirdirty++;
123954Sbill 		continue;
124954Sbill 
125954Sbill 	case 'r':
126954Sbill 		setcom(rcmd);
127954Sbill 		flag('r')++;
128954Sbill 		continue;
129954Sbill 
130954Sbill 	case 'd':
131954Sbill 		setcom(dcmd);
132954Sbill 		flag('d')++;
133954Sbill 		continue;
134954Sbill 
135954Sbill 	case 'x':
136954Sbill 		setcom(xcmd);
137954Sbill 		continue;
138954Sbill 
139954Sbill 	case 't':
140954Sbill 		setcom(tcmd);
141954Sbill 		continue;
142954Sbill 
143954Sbill 	case 'f':
144954Sbill 		defdev = argv[2];
145954Sbill 		argv++;
146954Sbill 		argc--;
147954Sbill 		continue;
148954Sbill 
149954Sbill 
150954Sbill 	default:
151954Sbill 		fprintf(stderr, "arff: bad option `%c'\n", *cp);
152954Sbill 		exit(1);
153954Sbill 	}
154954Sbill 	namv = argv+2;
155954Sbill 	namc = argc-2;
156954Sbill 	if(comfun == 0) {
157954Sbill 		if(flg['u'-'a'] == 0) {
158954Sbill 			fprintf(stderr, "arff: one of [%s] must be specified\n", man);
159954Sbill 			exit(1);
160954Sbill 		}
161954Sbill 		setcom(rcmd);
162954Sbill 	}
163954Sbill 	(*comfun)();
164954Sbill 	exit(notfound());
165954Sbill }
166954Sbill 
167954Sbill setcom(fun)
168954Sbill int (*fun)();
169954Sbill {
170954Sbill 
171954Sbill 	if(comfun != 0) {
172954Sbill 		fprintf(stderr, "arff: only one of [%s] allowed\n", man);
173954Sbill 		exit(1);
174954Sbill 	}
175954Sbill 	comfun = fun;
176954Sbill }
177954Sbill 
178954Sbill usage()
179954Sbill {
180*3356Swnj 
181*3356Swnj 	fprintf(stderr, "usage: ar [%s][%s] archive files ...\n", opt, man);
182954Sbill 	exit(1);
183954Sbill }
184954Sbill 
185954Sbill notfound()
186954Sbill {
187954Sbill 	register i, n;
188954Sbill 
189954Sbill 	n = 0;
190954Sbill 	for(i=0; i<namc; i++)
191954Sbill 		if(namv[i]) {
192954Sbill 			fprintf(stderr, "arff: %s not found\n", namv[i]);
193954Sbill 			n++;
194954Sbill 		}
195954Sbill 	return(n);
196954Sbill }
197954Sbill 
198954Sbill phserr()
199954Sbill {
200954Sbill 
201954Sbill 	fprintf(stderr, "arff: phase error on %s\n", file);
202954Sbill }
203954Sbill 
204954Sbill mesg(c)
205954Sbill {
206954Sbill 
207954Sbill 	if(flg['v'-'a'])
208954Sbill 		if(c != 'c' || flg['v'-'a'] > 1)
209954Sbill 			printf("%c - %s\n", c, file);
210954Sbill }
211954Sbill 
212954Sbill tcmd()
213954Sbill {
214954Sbill 	register char *de;
2153346Swnj 	int segnum;
2163346Swnj 	register char *last;
217954Sbill 	FLDOPE *lookup(), *dope;
218954Sbill 	int nleft; register i;
219954Sbill 	register struct rt_ent *rde;
220954Sbill 
221954Sbill 	rt_init();
222954Sbill 	if(namc==0)
2233346Swnj 	    for (segnum=0; segnum != -1;    /* for all dir. segments */
2243346Swnj 		 segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) {
2253346Swnj 		last = rt_last + segnum*2*RT_BLOCK;
2263346Swnj 		for(de=((char *)&rt_dir[segnum])+10; de <= last;
2273346Swnj 		    de += rt_entsiz) {
228954Sbill 			if(rtls(rt(de))) {
2293346Swnj 				nleft = (last - de) / rt_entsiz;
2303346Swnj 				printf("\n%d entries remaining",nleft);
2313346Swnj 				printf(" in directory segment %d.\n",segnum+1);
232954Sbill 				break;
233954Sbill 			}
234954Sbill 		}
2353346Swnj 	    }
236954Sbill 	else
237954Sbill 		for(i = 0; i < namc; i++) {
238954Sbill 			if(dope = lookup(namv[i])) {
239954Sbill 				rde = dope->rtdope;
240954Sbill 				rtls(rde);
241954Sbill 				namv[i] = 0;
242954Sbill 			}
243954Sbill 		}
244954Sbill }
245954Sbill rtls(de)
246954Sbill register struct rt_ent *de;
247954Sbill {
248954Sbill 	int month,day,year;
249954Sbill 	char name[12], ext[4];
250954Sbill 
251954Sbill 	if(flg['v'-'a'])
252954Sbill 		switch(de->rt_stat) {
253954Sbill 		case RT_TEMP:
254954Sbill 			printf("Tempfile:\n");
255954Sbill 		case RT_FILE:
256954Sbill 			unrad50(2,de->rt_name,name);
257954Sbill 			unrad50(1,&(de->rt_name[2]),ext);
258954Sbill 			day = de->rt_date.rt_dy;
259954Sbill 			year = de->rt_date.rt_yr + 72;
260954Sbill 			month = de->rt_date.rt_mo;
261954Sbill 			printf("%6.6s  %3.3s	%02d/%02d/%02d	%d\n",name,
262954Sbill 				ext,month,day,year,de->rt_len);
263954Sbill 			break;
264954Sbill 
265954Sbill 		case RT_NULL:
266954Sbill 			printf("%-25.9s	%d\n","<UNUSED>",de->rt_len);
267954Sbill 			break;
268954Sbill 
269954Sbill 		case RT_ESEG:
270954Sbill 			return(1);
271954Sbill 		}
272954Sbill 	else {
273954Sbill 		switch(de->rt_stat) {
274954Sbill 		case RT_TEMP:
275954Sbill 		case RT_FILE:
276954Sbill 			sunrad50(name,de->rt_name);
277954Sbill 			printf(name);putchar('\n');
278954Sbill 			break;
279954Sbill 
280954Sbill 		case RT_ESEG:
281954Sbill 			return(1);
282954Sbill 
283954Sbill 		case RT_NULL:
284954Sbill 			;
285954Sbill 		}
286954Sbill 	}
287954Sbill 	return(0);
288954Sbill }
289954Sbill xcmd()
290954Sbill {
291954Sbill 	register char *de;
2923346Swnj 	int segnum;
2933346Swnj 	register char *last;
294954Sbill 	char name[12];
295954Sbill 	register int i;
296954Sbill 
297954Sbill 	rt_init();
298954Sbill 	if(namc==0)
2993346Swnj 	    for (segnum=0; segnum != -1;    /* for all dir. segments */
3003346Swnj 		 segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) {
3013346Swnj 		last = rt_last + segnum*2*RT_BLOCK;
3023346Swnj 		for(de=((char *)&rt_dir[segnum])+10; de <= last;
3033346Swnj 		    de += rt_entsiz) {
304954Sbill 			sunrad50(name,rt(de)->rt_name);
305954Sbill 			rtx(name);
306954Sbill 		}
3073346Swnj 	    }
308954Sbill 	else
309954Sbill 		for(i = 0; i < namc; i++)
310954Sbill 		if(rtx(namv[i])==0) namv[i] = 0;
311954Sbill }
312954Sbill rtx(name)
313954Sbill char *name;
314954Sbill {
315954Sbill 	register FLDOPE *dope;
316954Sbill 	FLDOPE *lookup();
317954Sbill 	register startad, count;
318954Sbill 	int file; char buff[512];
319954Sbill 
320954Sbill 
321954Sbill 	if(dope = lookup(name)) {
322954Sbill 		if(flg['v' - 'a'])
323954Sbill 			rtls(dope->rtdope);
324954Sbill 		else
325954Sbill 			printf("x - %s\n",name);
326954Sbill 
327954Sbill 		file = creat(name, 0666);
328954Sbill 		if(file < 0) return(1);
329954Sbill 		count = dope->count;
330954Sbill 		startad = dope->startad;
331954Sbill 		for( ; count > 0 ; count -= 512) {
332954Sbill 			lread(startad,512,buff);
333954Sbill 			write(file,buff,512);
334954Sbill 			startad += 512;
335954Sbill 		}
336954Sbill 		close(file);
337954Sbill 		return(0);
338954Sbill 	}
339954Sbill 	return(1);
340954Sbill }
341954Sbill rt_init()
342954Sbill {
343954Sbill 	static initized = 0;
344954Sbill 	register char *de;
3453346Swnj 	register i;
3463346Swnj 	int mode, dirnum;
3473346Swnj 	register char *last;
348954Sbill 
349954Sbill 	if(initized) return;
350954Sbill 	initized = 1;
351954Sbill 	if(flag('c') || flag('d') || flag('r'))
352954Sbill 		mode = 2;
353954Sbill 	else
354954Sbill 		mode = 0;
355*3356Swnj 	if((floppydes = open(defdev,mode)) < 0) {
356954Sbill 		dbprintf("Floppy open failed\n");
357*3356Swnj 		exit(1);
358*3356Swnj 	}
3593346Swnj 	if(flag('c')==0) {
3603346Swnj 		lread(6*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[0]);
3613346Swnj 		dirnum = rt_dir[0].rt_axhead.rt_numseg;
3623346Swnj 		if (dirnum > RT_DIRSIZE) {
3633346Swnj 		   fprintf(stderr,"arff: too many directory segments\n");
3643346Swnj 		   exit(1);
3653346Swnj 		}
3663346Swnj 		for (i=1; i<dirnum; i++)
3673346Swnj 		   lread((6+2*i)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[i]);
3683346Swnj 	}
369954Sbill 
3703346Swnj 	rt_entsiz = 2*rt_dir[0].rt_axhead.rt_entpad + 14;
3713346Swnj 	rt_entsiz = 14;			/* assume rt_entpad = 0 ??? */
3723346Swnj 	rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz;
3733346Swnj 	rt_nleft = 0;
3743346Swnj 
3753346Swnj 	for (i=0; i<dirnum; i++) {
3763346Swnj   	    last = rt_last + i*2*RT_BLOCK;
3773346Swnj 	    for(de=((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) {
378954Sbill 		if(rt(de)->rt_stat==RT_ESEG) break;
3793346Swnj 	    }
3803346Swnj 	    rt_curend[i] = rt(de);
3813346Swnj 	    rt_nleft += (last - de) / rt_entsiz;
382954Sbill 	}
383954Sbill }
384954Sbill 
385954Sbill static FLDOPE result;
386954Sbill FLDOPE *
387954Sbill lookup(name)
388954Sbill char * name;
389954Sbill {
390954Sbill 	unsigned short rname[3];
391954Sbill 	register char *de;
3923346Swnj 	int segnum;
3933346Swnj 	register char *last;
394954Sbill 	register index;
395954Sbill 
396954Sbill 	srad50(name,rname);
397954Sbill 
398*3356Swnj 	/*
399954Sbill 	 *  Search for name, accumulate blocks in index
400954Sbill 	 */
401954Sbill 	rt_init();
4023346Swnj 	for (segnum=0; segnum != -1;    /* for all dir. segments */
4033346Swnj              segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) {
4043346Swnj 	    index = 0;
4053346Swnj 	    last = rt_last + segnum*2*RT_BLOCK;
4063346Swnj 	    for(de=((char *)&rt_dir[segnum])+10;
4073346Swnj 		rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) {
408954Sbill 		switch(rt(de)->rt_stat) {
409954Sbill 		case RT_FILE:
410954Sbill 		case RT_TEMP:
411954Sbill 		if(samename(rname,rt(de)->rt_name))
412954Sbill 			goto found;
413954Sbill 		case RT_NULL:
414954Sbill 			index += rt(de)->rt_len;
415954Sbill 		}
4163346Swnj 	    }
4173346Swnj         }
418954Sbill 	return((FLDOPE *) 0);
419954Sbill found:	result.count = rt(de)->rt_len * 512;
4203346Swnj 	result.startad = 512 * (rt_dir[segnum].rt_axhead.rt_stfile + index);
421954Sbill 	result.rtdope = (struct rt_ent *) de;
422954Sbill 	return(&result);
423954Sbill }
424954Sbill static
425954Sbill samename(a,b)
426954Sbill unsigned short a[3],b[3];
427954Sbill {
428954Sbill 	return( a[0]==b[0] && a[1]==b[1] && a[2]==b[2] );
429954Sbill }
430954Sbill 
431954Sbill 
432954Sbill rad50(cp,out)
433954Sbill register unsigned char *cp;
434954Sbill unsigned short *out;
435954Sbill {
436954Sbill 	register index;
437954Sbill 	register temp;
438954Sbill 
439954Sbill 	for(index = 0;*cp; index++) {
440954Sbill 
441954Sbill 		temp = Ain1 * table[*cp++];
442954Sbill 		if(*cp!=0) {
443954Sbill 			temp += Ain2 * table[*cp++];
444954Sbill 
445954Sbill 			if(*cp!=0)
446954Sbill 				temp += table[*cp++];
447954Sbill 		}
448954Sbill 
449954Sbill 		out[index] = temp;
450954Sbill 	}
451954Sbill }
452954Sbill #define reduce(x,p,q) \
453954Sbill 	(x = v[p/q], p %= q);
454954Sbill 
455954Sbill unrad50(count,in,cp)
456954Sbill unsigned short *in;
457954Sbill register char *cp;
458954Sbill {
459954Sbill 	register i, temp; register unsigned char *v = (unsigned char *) val;
460954Sbill 
461954Sbill 	for(i = 0; i < count; i++) {
462954Sbill 		temp = in[i];
463954Sbill 
464954Sbill 		reduce (*cp++,temp,Ain1);
465954Sbill 		reduce (*cp++,temp,Ain2);
466954Sbill 		reduce (*cp++,temp,1);
467954Sbill 	}
468954Sbill 	*cp=0;
469954Sbill }
470954Sbill 
471954Sbill srad50(name,rname)
472954Sbill register char * name;
473954Sbill register unsigned short *rname;
474954Sbill {
475954Sbill 	register index; register char *cp;
476954Sbill 	char file[7],ext[4];
477*3356Swnj 	/*
478954Sbill 	 * Find end of pathname
479954Sbill 	 */
480954Sbill 	for(cp = name; *cp++; );
481954Sbill 	while(cp >= name && *--cp != '/');
482954Sbill 	cp++;
483*3356Swnj 	/*
484954Sbill 	 * Change to rad50
485954Sbill 	 *
486954Sbill 	 */
487954Sbill 	for(index = 0; *cp; ){
488954Sbill 		file[index++] = *cp++;
489954Sbill 		if(*cp=='.') {
490954Sbill 			cp++;
491954Sbill 			break;
492954Sbill 		}
493954Sbill 		if(index>=6) {
494954Sbill 			break;
495954Sbill 		}
496954Sbill 	}
497954Sbill 	file[index] = 0;
498954Sbill 	for(index = 0; *cp; ){
499954Sbill 		ext[index++] = *cp++;
500954Sbill 		if(*cp=='.' || index>=3) {
501954Sbill 			break;
502954Sbill 		}
503954Sbill 	}
504954Sbill 	ext[index]=0;
505954Sbill 	rname[0] = 0;
506954Sbill 	rname[1] = 0;
507954Sbill 	rname[2] = 0;
508954Sbill 	rad50((unsigned char *)file,rname);
509954Sbill 	rad50((unsigned char *)ext,rname+2);
510954Sbill }
511954Sbill sunrad50(name,rname)
512954Sbill unsigned short rname[3];
513954Sbill register char *name;
514954Sbill {
515954Sbill 	register char *cp, *cp2;
516954Sbill 	char ext[4];
517954Sbill 
518954Sbill 	unrad50(2,rname,name);
519954Sbill 	unrad50(1,rname + 2,ext);
520954Sbill 	/* Jam name and extension together with a dot
521954Sbill 	   deleting white space */
522954Sbill 	for(cp = name; *cp++;);--cp;  while(*--cp==' ' && cp>=name);
523954Sbill 	*++cp = '.';cp++;
524954Sbill 	for(cp2=ext; *cp2!=' ' && cp2 < ext + 3;) {
525954Sbill 		*cp++ = *cp2++;
526954Sbill 	}
527954Sbill 	*cp=0;
528954Sbill 	if(cp[-1]=='.') cp[-1] = 0;
529954Sbill }
530954Sbill 
531954Sbill static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789";
532954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789";
533954Sbill static char table[256] = {
534954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
535954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
536954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
537954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
538954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
539954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
540954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
541954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
542954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
543954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
544954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
545954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
546954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
547954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
548954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
549954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 };
550954Sbill 
551954Sbill long trans(logical)
552954Sbill register int logical;
553954Sbill {
554954Sbill 	/*  Logical to physical adress translation */
555954Sbill 	register int sector, bytes, track;
556954Sbill 
557954Sbill 	logical += 26 * 128;
558954Sbill 	bytes = (logical & 127);
559954Sbill 	logical >>= 7;
560954Sbill 	sector = logical % 26;
561954Sbill 	if(sector >= 13)
562954Sbill 		sector = sector *2 +1;
563954Sbill 	else
564954Sbill 		sector *= 2;
565954Sbill 	sector += 26 + ((track = (logical / 26)) - 1) * 6;
566954Sbill 	sector %= 26;
567954Sbill 	return( (((track *26) + sector) << 7) + bytes);
568954Sbill }
569954Sbill lread(startad,count,obuff)
570954Sbill register startad, count;
571954Sbill register char * obuff;
572954Sbill {
573954Sbill 	long trans();
574954Sbill 	extern floppydes;
575954Sbill 	rt_init();
576954Sbill 	if(flg['m'-'a']==0)
577954Sbill 		while( (count -= 128) >= 0) {
578954Sbill 			lseek(floppydes, trans(startad), 0);
579*3356Swnj 			 if (read(floppydes,obuff,128) != 128)
580*3356Swnj 				fprintf(stderr, "arff: read error block %d\n",startad/128);
581954Sbill 			obuff += 128;
582954Sbill 			startad += 128;
583954Sbill 		}
584954Sbill 	else
585954Sbill 		while( (count -= 512) >= 0) {
586954Sbill 			lseek(floppydes,(long) (startad), 0);
587*3356Swnj 				fprintf(stderr, "arff: read error block %d\n",startad/512);
588954Sbill 			obuff += 512;
589954Sbill 			startad += 512;
590954Sbill 		}
591954Sbill }
592954Sbill lwrite(startad,count,obuff)
593954Sbill register startad, count;
594954Sbill register char * obuff;
595954Sbill {
596954Sbill 	long trans();
597954Sbill 	extern floppydes;
598954Sbill 	rt_init();
599954Sbill 	if(flg['m'-'a']==0)
600954Sbill 		while( (count -= 128) >= 0) {
601954Sbill 			lseek(floppydes, trans(startad), 0);
602*3356Swnj 			if ( write(floppydes,obuff,128) != 128)
603*3356Swnj 				fprintf(stderr, "arff: write error block %d\n",startad/128);
604954Sbill 			obuff += 128;
605954Sbill 			startad += 128;
606954Sbill 		}
607954Sbill 	else
608954Sbill 		while( (count -= 512) >= 0) {
609954Sbill 			lseek(floppydes,(long) (startad), 0);
610*3356Swnj 			if ( write(floppydes,obuff,512) != 512)
611*3356Swnj 				fprintf(stderr, "arff: write error block %d\n",startad/512);
612954Sbill 			obuff += 512;
613954Sbill 			startad += 512;
614954Sbill 		}
615954Sbill }
616954Sbill 
617954Sbill rcmd()
618954Sbill {
619954Sbill 	register int i;
620954Sbill 
621954Sbill 	rt_init();
622954Sbill 	if(namc>0)
623954Sbill 		for(i = 0; i < namc; i++)
624*3356Swnj 			if(rtr(namv[i])==0) namv[i]=0;
625954Sbill 
626954Sbill 
627954Sbill }
628954Sbill 
629954Sbill rtr(name)
630954Sbill char *name;
631954Sbill {
632954Sbill 	register FLDOPE *dope; register struct rt_ent *de;
633954Sbill 	struct stat buf; register struct stat *bufp = &buf;
6343346Swnj 	int segnum;
6353346Swnj 	register char *last;
636954Sbill 
637954Sbill 	if(stat(name,bufp)<0) return(1);
638954Sbill 	if(dope = lookup(name)) {
639954Sbill 		/* can replace, no problem */
640954Sbill 		de = dope->rtdope;
641954Sbill 		if(bufp->st_size <= (de->rt_len * 512))
642954Sbill 			printf("r - %s\n",name),
643954Sbill 			toflop(name,bufp->st_size,dope);
644954Sbill 		else {
645*3356Swnj 			fprintf(stderr, "%s will not fit in currently used file on floppy\n",name);
646954Sbill 			return(1);
647954Sbill 		}
648954Sbill 	} else {
6493346Swnj 	    /* Search for vacant spot */
6503346Swnj 	    for (segnum=0; segnum != -1;    /* for all dir. segments */
6513346Swnj 		 segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) {
6523346Swnj 		last = rt_last + segnum*2*RT_BLOCK;
6533346Swnj 		for(de = rt_dir[segnum].rt_ents;
6543346Swnj 		    rt(de)->rt_stat != RT_ESEG; de++) {
655954Sbill 			switch((de)->rt_stat) {
656954Sbill 			case RT_NULL:
657954Sbill 				if(bufp->st_size <= (de->rt_len * 512)) {
658954Sbill 					printf("a - %s\n",name),
6593346Swnj 					mkent(de,segnum,bufp,name);
660954Sbill 					goto found;
661954Sbill 				}
662954Sbill 				continue;
663954Sbill 			}
664954Sbill 		}
6653346Swnj 	    }
6663346Swnj 	    return(3);
667954Sbill 	}
668954Sbill found:	if(dope=lookup(name)) {
669954Sbill 		toflop(name,bufp->st_size,dope);
670954Sbill 		return(0);
671954Sbill 	}
672954Sbill 	return(7);
673954Sbill 
674954Sbill }
6753346Swnj mkent(de,segnum,bufp,name)
676954Sbill register struct rt_ent *de;
6773346Swnj int segnum;
678954Sbill register struct stat *bufp;
679954Sbill char *name;
680954Sbill {
681954Sbill 	struct tm *localtime(); register struct tm *timp;
682954Sbill 	register struct rt_ent *workp; int count;
683954Sbill 
684954Sbill 	count = (((bufp->st_size -1) >>9) + 1);
685954Sbill 						/* Make sure there is room */
686954Sbill 	if(de->rt_len==count)
687954Sbill 		goto overwrite;
6883346Swnj 	if(rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) {
6893346Swnj 						/* no entries left on segment */
690954Sbill 		if(flg['o'-'a'])
691954Sbill 			goto overwrite;
6923346Swnj 		fprintf(stderr,"Directory segment #%d full on  %s\n",segnum+1,
6933346Swnj                     defdev);
694954Sbill 		exit(1);
695954Sbill 	}
696954Sbill 					/* copy directory entries up */
6973346Swnj 	for(workp = rt_curend[segnum]+1; workp > de; workp--)
698954Sbill 		*workp = workp[-1];
699954Sbill 	de[1].rt_len -= count;
700954Sbill 	de->rt_len = count;
7013346Swnj 	rt_curend[segnum]++;
702954Sbill 	rt_nleft--;
703954Sbill overwrite:
704954Sbill 	srad50(name,de->rt_name);
705954Sbill 	timp = localtime(&bufp->st_mtime);
706954Sbill 	de->rt_date.rt_dy = timp->tm_mday + 1;
707954Sbill 	de->rt_date.rt_mo = timp->tm_mon + 1;
708954Sbill 	de->rt_date.rt_yr = timp->tm_year - 72;
709954Sbill 	de->rt_stat = RT_FILE;
710954Sbill 	de->rt_pad = 0;
711954Sbill 	de->rt_chan = 0;
712954Sbill 	de->rt_job = 0;
7133346Swnj 	lwrite((6+segnum*2)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[segnum]);
714954Sbill }
715954Sbill 
716954Sbill toflop(name,ocount,dope)
717954Sbill char *name;
718954Sbill register FLDOPE *dope;
719954Sbill long ocount;
720954Sbill {
721954Sbill 	register file, n, startad = dope->startad, count = ocount;
722954Sbill 	char buff[512];
723954Sbill 
724954Sbill 	file = open(name,0);
725954Sbill 	if(file < 0) {
726*3356Swnj 		fprintf(stderr, "arff: couldn't open %s\n",name);exit(1);}
727954Sbill 	for( ; count >= 512; count -= 512) {
728954Sbill 		read(file,buff,512);
729954Sbill 		lwrite(startad,512,buff);
730954Sbill 		startad += 512;
731954Sbill 	}
732954Sbill 	read(file,buff,count);
733954Sbill 	close(file);
734954Sbill 	if(count <= 0) return;
735954Sbill 	for(n = count; n < 512; n ++) buff[n] = 0;
736954Sbill 	lwrite(startad,512,buff);
737954Sbill 	count = (dope->rtdope->rt_len * 512 - ocount) / 512 ;
738954Sbill 	if(count <= 0) return;
739954Sbill 	for( ; count > 0 ; count--) {
740954Sbill 		startad += 512;
741954Sbill 		lwrite(startad,512,zeroes);
742954Sbill 	}
743954Sbill 
744954Sbill }
745954Sbill dcmd()
746954Sbill {
747954Sbill 	register int i;
748954Sbill 
749954Sbill 	rt_init();
750954Sbill 	if(namc)
751954Sbill 		for(i = 0; i < namc; i++)
752954Sbill 			if(rtk(namv[i])==0) namv[i]=0;
753954Sbill 	if(dirdirty)
754954Sbill 		scrunch();
755954Sbill 
756954Sbill }
757954Sbill rtk(name)
758954Sbill char *name;
759954Sbill {
760954Sbill 	register FLDOPE *dope;
761954Sbill 	register struct rt_ent *de;
762954Sbill 	FLDOPE *lookup();
763954Sbill 
764954Sbill 	if(dope = lookup(name)) {
765954Sbill 		printf("d - %s\n",name);
766954Sbill 		de = dope->rtdope;
767954Sbill 		de->rt_stat = RT_NULL;
768954Sbill 		de->rt_name[0] = 0;
769954Sbill 		de->rt_name[1] = 0;
770954Sbill 		de->rt_name[2] = 0;
771954Sbill 		* ((unsigned short *) & (de->rt_date)) = 0;
772954Sbill 		dirdirty = 1;
773954Sbill 		return(0);
774954Sbill 	}
775954Sbill 	return(1);
776954Sbill }
777954Sbill scrunch() {
7783346Swnj 	register struct rt_ent *de , *workp;
7793346Swnj 	register segnum;
7803346Swnj 	for (segnum=0; segnum != -1;    /* for all dir. segments */
7813346Swnj 	     segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) {
7823346Swnj 	    dirdirty = 0;
7833346Swnj 	    for(de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) {
784954Sbill 		if(de->rt_stat==RT_NULL && de[1].rt_stat==RT_NULL) {
785954Sbill 			(de+1)->rt_len += de->rt_len;
7863346Swnj 			for(workp = de; workp < rt_curend[segnum]; workp++)
787954Sbill 				*workp = workp[1];
788954Sbill 			de--;
7893346Swnj 			rt_curend[segnum]--;
790954Sbill 			rt_nleft++;
7913346Swnj 			dirdirty = 1;
792954Sbill 		}
7933346Swnj 	    }
7943346Swnj 	    if (dirdirty)
7953346Swnj 	    lwrite((6+segnum*2)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[segnum]);
796954Sbill 	}
797954Sbill }
798