xref: /csrg-svn/old/arff/arff.c (revision 3489)
1*3489Sroot static	char *sccsid = "@(#)arff.c	4.5 (Berkeley) 81/04/08";
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 {
93356Swnj unsigned short	int	rt_yr:5;	/* Year - 1972			 */
103356Swnj unsigned short	int	rt_dy:5;	/* day				 */
113356Swnj unsigned short	int	rt_mo:5;	/* month				 */
12954Sbill };
13954Sbill struct	rt_axent {
14954Sbill 	char	rt_sent[14];
15954Sbill };
16954Sbill 
17954Sbill struct rt_ent {
183356Swnj 	char  rt_pad;			/* unusued		     */
193356Swnj 	char  rt_stat;			/* Type of entry, or end of seg */
203356Swnj 	unsigned short rt_name[3];	/* Name, 3 words in rad50 form */
213356Swnj 	short rt_len;			/* Length of file	      */
223356Swnj 	char  rt_chan;			/* Only used in temporary files */
233356Swnj 	char  rt_job;			/* Only used in temporary files */
243356Swnj 	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 {
333356Swnj 	short	rt_numseg;		/* number of segments available */
343356Swnj 	short	rt_nxtseg;		/* segment no of next log. seg */
353356Swnj 	short	rt_lstseg;		/* highest seg currenltly open */
363356Swnj 	unsigned short	rt_entpad;	/* extra words/dir. entry      */
373356Swnj 	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
65*3489Sroot    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 
943356Swnj 	/* register i;
95954Sbill 	for(i=0; signum[i]; i++)
96954Sbill 		if(signal(signum[i], SIG_IGN) != SIG_IGN)
973356Swnj 			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));
1163356Swnj 			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 {
1803356Swnj 
1813356Swnj 	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;
3553356Swnj 	if((floppydes = open(defdev,mode)) < 0) {
356954Sbill 		dbprintf("Floppy open failed\n");
3573356Swnj 		exit(1);
3583356Swnj 	}
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]);
368*3489Sroot 	} else
369*3489Sroot 		dirnum = 1;
370954Sbill 
3713346Swnj 	rt_entsiz = 2*rt_dir[0].rt_axhead.rt_entpad + 14;
3723346Swnj 	rt_entsiz = 14;			/* assume rt_entpad = 0 ??? */
3733346Swnj 	rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz;
3743346Swnj 	rt_nleft = 0;
3753346Swnj 
3763346Swnj 	for (i=0; i<dirnum; i++) {
3773346Swnj   	    last = rt_last + i*2*RT_BLOCK;
3783346Swnj 	    for(de=((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) {
379954Sbill 		if(rt(de)->rt_stat==RT_ESEG) break;
3803346Swnj 	    }
3813346Swnj 	    rt_curend[i] = rt(de);
3823346Swnj 	    rt_nleft += (last - de) / rt_entsiz;
383954Sbill 	}
384954Sbill }
385954Sbill 
386954Sbill static FLDOPE result;
387954Sbill FLDOPE *
388954Sbill lookup(name)
389954Sbill char * name;
390954Sbill {
391954Sbill 	unsigned short rname[3];
392954Sbill 	register char *de;
3933346Swnj 	int segnum;
3943346Swnj 	register char *last;
395954Sbill 	register index;
396954Sbill 
397954Sbill 	srad50(name,rname);
398954Sbill 
3993356Swnj 	/*
400954Sbill 	 *  Search for name, accumulate blocks in index
401954Sbill 	 */
402954Sbill 	rt_init();
4033346Swnj 	for (segnum=0; segnum != -1;    /* for all dir. segments */
4043346Swnj              segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) {
4053346Swnj 	    index = 0;
4063346Swnj 	    last = rt_last + segnum*2*RT_BLOCK;
4073346Swnj 	    for(de=((char *)&rt_dir[segnum])+10;
4083346Swnj 		rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) {
409954Sbill 		switch(rt(de)->rt_stat) {
410954Sbill 		case RT_FILE:
411954Sbill 		case RT_TEMP:
412954Sbill 		if(samename(rname,rt(de)->rt_name))
413954Sbill 			goto found;
414954Sbill 		case RT_NULL:
415954Sbill 			index += rt(de)->rt_len;
416954Sbill 		}
4173346Swnj 	    }
4183346Swnj         }
419954Sbill 	return((FLDOPE *) 0);
420954Sbill found:	result.count = rt(de)->rt_len * 512;
4213346Swnj 	result.startad = 512 * (rt_dir[segnum].rt_axhead.rt_stfile + index);
422954Sbill 	result.rtdope = (struct rt_ent *) de;
423954Sbill 	return(&result);
424954Sbill }
425954Sbill static
426954Sbill samename(a,b)
427954Sbill unsigned short a[3],b[3];
428954Sbill {
429954Sbill 	return( a[0]==b[0] && a[1]==b[1] && a[2]==b[2] );
430954Sbill }
431954Sbill 
432954Sbill 
433954Sbill rad50(cp,out)
434954Sbill register unsigned char *cp;
435954Sbill unsigned short *out;
436954Sbill {
437954Sbill 	register index;
438954Sbill 	register temp;
439954Sbill 
440954Sbill 	for(index = 0;*cp; index++) {
441954Sbill 
442954Sbill 		temp = Ain1 * table[*cp++];
443954Sbill 		if(*cp!=0) {
444954Sbill 			temp += Ain2 * table[*cp++];
445954Sbill 
446954Sbill 			if(*cp!=0)
447954Sbill 				temp += table[*cp++];
448954Sbill 		}
449954Sbill 
450954Sbill 		out[index] = temp;
451954Sbill 	}
452954Sbill }
453954Sbill #define reduce(x,p,q) \
454954Sbill 	(x = v[p/q], p %= q);
455954Sbill 
456954Sbill unrad50(count,in,cp)
457954Sbill unsigned short *in;
458954Sbill register char *cp;
459954Sbill {
460954Sbill 	register i, temp; register unsigned char *v = (unsigned char *) val;
461954Sbill 
462954Sbill 	for(i = 0; i < count; i++) {
463954Sbill 		temp = in[i];
464954Sbill 
465954Sbill 		reduce (*cp++,temp,Ain1);
466954Sbill 		reduce (*cp++,temp,Ain2);
467954Sbill 		reduce (*cp++,temp,1);
468954Sbill 	}
469954Sbill 	*cp=0;
470954Sbill }
471954Sbill 
472954Sbill srad50(name,rname)
473954Sbill register char * name;
474954Sbill register unsigned short *rname;
475954Sbill {
476954Sbill 	register index; register char *cp;
477954Sbill 	char file[7],ext[4];
4783356Swnj 	/*
479954Sbill 	 * Find end of pathname
480954Sbill 	 */
481954Sbill 	for(cp = name; *cp++; );
482954Sbill 	while(cp >= name && *--cp != '/');
483954Sbill 	cp++;
4843356Swnj 	/*
485954Sbill 	 * Change to rad50
486954Sbill 	 *
487954Sbill 	 */
488954Sbill 	for(index = 0; *cp; ){
489954Sbill 		file[index++] = *cp++;
490954Sbill 		if(*cp=='.') {
491954Sbill 			cp++;
492954Sbill 			break;
493954Sbill 		}
494954Sbill 		if(index>=6) {
495954Sbill 			break;
496954Sbill 		}
497954Sbill 	}
498954Sbill 	file[index] = 0;
499954Sbill 	for(index = 0; *cp; ){
500954Sbill 		ext[index++] = *cp++;
501954Sbill 		if(*cp=='.' || index>=3) {
502954Sbill 			break;
503954Sbill 		}
504954Sbill 	}
505954Sbill 	ext[index]=0;
506954Sbill 	rname[0] = 0;
507954Sbill 	rname[1] = 0;
508954Sbill 	rname[2] = 0;
509954Sbill 	rad50((unsigned char *)file,rname);
510954Sbill 	rad50((unsigned char *)ext,rname+2);
511954Sbill }
512954Sbill sunrad50(name,rname)
513954Sbill unsigned short rname[3];
514954Sbill register char *name;
515954Sbill {
516954Sbill 	register char *cp, *cp2;
517954Sbill 	char ext[4];
518954Sbill 
519954Sbill 	unrad50(2,rname,name);
520954Sbill 	unrad50(1,rname + 2,ext);
521954Sbill 	/* Jam name and extension together with a dot
522954Sbill 	   deleting white space */
523954Sbill 	for(cp = name; *cp++;);--cp;  while(*--cp==' ' && cp>=name);
524954Sbill 	*++cp = '.';cp++;
525954Sbill 	for(cp2=ext; *cp2!=' ' && cp2 < ext + 3;) {
526954Sbill 		*cp++ = *cp2++;
527954Sbill 	}
528954Sbill 	*cp=0;
529954Sbill 	if(cp[-1]=='.') cp[-1] = 0;
530954Sbill }
531954Sbill 
532954Sbill static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789";
533954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789";
534954Sbill static char table[256] = {
535954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
536954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
537954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
538954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
539954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
540954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
541954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
542954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
543954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
544954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
545954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
546954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
547954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
548954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
549954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
550954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 };
551954Sbill 
552954Sbill long trans(logical)
553954Sbill register int logical;
554954Sbill {
555954Sbill 	/*  Logical to physical adress translation */
556954Sbill 	register int sector, bytes, track;
557954Sbill 
558954Sbill 	logical += 26 * 128;
559954Sbill 	bytes = (logical & 127);
560954Sbill 	logical >>= 7;
561954Sbill 	sector = logical % 26;
562954Sbill 	if(sector >= 13)
563954Sbill 		sector = sector *2 +1;
564954Sbill 	else
565954Sbill 		sector *= 2;
566954Sbill 	sector += 26 + ((track = (logical / 26)) - 1) * 6;
567954Sbill 	sector %= 26;
568954Sbill 	return( (((track *26) + sector) << 7) + bytes);
569954Sbill }
570954Sbill lread(startad,count,obuff)
571954Sbill register startad, count;
572954Sbill register char * obuff;
573954Sbill {
574954Sbill 	long trans();
575954Sbill 	extern floppydes;
576954Sbill 	rt_init();
577954Sbill 	if(flg['m'-'a']==0)
578954Sbill 		while( (count -= 128) >= 0) {
579954Sbill 			lseek(floppydes, trans(startad), 0);
5803356Swnj 			 if (read(floppydes,obuff,128) != 128)
5813356Swnj 				fprintf(stderr, "arff: read error block %d\n",startad/128);
582954Sbill 			obuff += 128;
583954Sbill 			startad += 128;
584954Sbill 		}
585954Sbill 	else
586954Sbill 		while( (count -= 512) >= 0) {
587954Sbill 			lseek(floppydes,(long) (startad), 0);
5883356Swnj 				fprintf(stderr, "arff: read error block %d\n",startad/512);
589954Sbill 			obuff += 512;
590954Sbill 			startad += 512;
591954Sbill 		}
592954Sbill }
593954Sbill lwrite(startad,count,obuff)
594954Sbill register startad, count;
595954Sbill register char * obuff;
596954Sbill {
597954Sbill 	long trans();
598954Sbill 	extern floppydes;
599954Sbill 	rt_init();
600954Sbill 	if(flg['m'-'a']==0)
601954Sbill 		while( (count -= 128) >= 0) {
602954Sbill 			lseek(floppydes, trans(startad), 0);
6033356Swnj 			if ( write(floppydes,obuff,128) != 128)
6043356Swnj 				fprintf(stderr, "arff: write error block %d\n",startad/128);
605954Sbill 			obuff += 128;
606954Sbill 			startad += 128;
607954Sbill 		}
608954Sbill 	else
609954Sbill 		while( (count -= 512) >= 0) {
610954Sbill 			lseek(floppydes,(long) (startad), 0);
6113356Swnj 			if ( write(floppydes,obuff,512) != 512)
6123356Swnj 				fprintf(stderr, "arff: write error block %d\n",startad/512);
613954Sbill 			obuff += 512;
614954Sbill 			startad += 512;
615954Sbill 		}
616954Sbill }
617954Sbill 
618954Sbill rcmd()
619954Sbill {
620954Sbill 	register int i;
621954Sbill 
622954Sbill 	rt_init();
623*3489Sroot 	if (namc>0)
624954Sbill 		for(i = 0; i < namc; i++)
6253356Swnj 			if(rtr(namv[i])==0) namv[i]=0;
626954Sbill }
627954Sbill 
628954Sbill rtr(name)
629954Sbill char *name;
630954Sbill {
631954Sbill 	register FLDOPE *dope; register struct rt_ent *de;
632954Sbill 	struct stat buf; register struct stat *bufp = &buf;
6333346Swnj 	int segnum;
6343346Swnj 	register char *last;
635954Sbill 
636*3489Sroot 	if(stat(name,bufp)<0) {
637*3489Sroot 		perror(name);
638*3489Sroot 		return(-1);
639*3489Sroot 	}
640954Sbill 	if(dope = lookup(name)) {
641954Sbill 		/* can replace, no problem */
642954Sbill 		de = dope->rtdope;
643954Sbill 		if(bufp->st_size <= (de->rt_len * 512))
644954Sbill 			printf("r - %s\n",name),
645954Sbill 			toflop(name,bufp->st_size,dope);
646954Sbill 		else {
6473356Swnj 			fprintf(stderr, "%s will not fit in currently used file on floppy\n",name);
648*3489Sroot 			return(-1);
649954Sbill 		}
650954Sbill 	} else {
6513346Swnj 	    /* Search for vacant spot */
6523346Swnj 	    for (segnum=0; segnum != -1;    /* for all dir. segments */
6533346Swnj 		 segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) {
6543346Swnj 		last = rt_last + segnum*2*RT_BLOCK;
6553346Swnj 		for(de = rt_dir[segnum].rt_ents;
6563346Swnj 		    rt(de)->rt_stat != RT_ESEG; de++) {
657954Sbill 			switch((de)->rt_stat) {
658954Sbill 			case RT_NULL:
659954Sbill 				if(bufp->st_size <= (de->rt_len * 512)) {
660954Sbill 					printf("a - %s\n",name),
6613346Swnj 					mkent(de,segnum,bufp,name);
662954Sbill 					goto found;
663954Sbill 				}
664954Sbill 				continue;
665954Sbill 			}
666954Sbill 		}
6673346Swnj 	    }
668*3489Sroot 	    printf("%s: no slot for file\n", name);
669*3489Sroot 	    return (-1);
670954Sbill 	}
671954Sbill found:	if(dope=lookup(name)) {
672954Sbill 		toflop(name,bufp->st_size,dope);
673*3489Sroot 		return (0);
674954Sbill 	}
675*3489Sroot 	printf("%s: internal error, added then not found\n", name);
676*3489Sroot 	return (-1);
677954Sbill 
678954Sbill }
6793346Swnj mkent(de,segnum,bufp,name)
680954Sbill register struct rt_ent *de;
6813346Swnj int segnum;
682954Sbill register struct stat *bufp;
683954Sbill char *name;
684954Sbill {
685954Sbill 	struct tm *localtime(); register struct tm *timp;
686954Sbill 	register struct rt_ent *workp; int count;
687954Sbill 
688954Sbill 	count = (((bufp->st_size -1) >>9) + 1);
689954Sbill 						/* Make sure there is room */
690954Sbill 	if(de->rt_len==count)
691954Sbill 		goto overwrite;
6923346Swnj 	if(rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) {
6933346Swnj 						/* no entries left on segment */
694954Sbill 		if(flg['o'-'a'])
695954Sbill 			goto overwrite;
6963346Swnj 		fprintf(stderr,"Directory segment #%d full on  %s\n",segnum+1,
6973346Swnj                     defdev);
698954Sbill 		exit(1);
699954Sbill 	}
700954Sbill 					/* copy directory entries up */
7013346Swnj 	for(workp = rt_curend[segnum]+1; workp > de; workp--)
702954Sbill 		*workp = workp[-1];
703954Sbill 	de[1].rt_len -= count;
704954Sbill 	de->rt_len = count;
7053346Swnj 	rt_curend[segnum]++;
706954Sbill 	rt_nleft--;
707954Sbill overwrite:
708954Sbill 	srad50(name,de->rt_name);
709954Sbill 	timp = localtime(&bufp->st_mtime);
710954Sbill 	de->rt_date.rt_dy = timp->tm_mday + 1;
711954Sbill 	de->rt_date.rt_mo = timp->tm_mon + 1;
712954Sbill 	de->rt_date.rt_yr = timp->tm_year - 72;
713954Sbill 	de->rt_stat = RT_FILE;
714954Sbill 	de->rt_pad = 0;
715954Sbill 	de->rt_chan = 0;
716954Sbill 	de->rt_job = 0;
7173346Swnj 	lwrite((6+segnum*2)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[segnum]);
718954Sbill }
719954Sbill 
720954Sbill toflop(name,ocount,dope)
721954Sbill char *name;
722954Sbill register FLDOPE *dope;
723954Sbill long ocount;
724954Sbill {
725954Sbill 	register file, n, startad = dope->startad, count = ocount;
726954Sbill 	char buff[512];
727954Sbill 
728954Sbill 	file = open(name,0);
729954Sbill 	if(file < 0) {
7303356Swnj 		fprintf(stderr, "arff: couldn't open %s\n",name);exit(1);}
731954Sbill 	for( ; count >= 512; count -= 512) {
732954Sbill 		read(file,buff,512);
733954Sbill 		lwrite(startad,512,buff);
734954Sbill 		startad += 512;
735954Sbill 	}
736954Sbill 	read(file,buff,count);
737954Sbill 	close(file);
738954Sbill 	if(count <= 0) return;
739954Sbill 	for(n = count; n < 512; n ++) buff[n] = 0;
740954Sbill 	lwrite(startad,512,buff);
741954Sbill 	count = (dope->rtdope->rt_len * 512 - ocount) / 512 ;
742954Sbill 	if(count <= 0) return;
743954Sbill 	for( ; count > 0 ; count--) {
744954Sbill 		startad += 512;
745954Sbill 		lwrite(startad,512,zeroes);
746954Sbill 	}
747954Sbill 
748954Sbill }
749954Sbill dcmd()
750954Sbill {
751954Sbill 	register int i;
752954Sbill 
753954Sbill 	rt_init();
754954Sbill 	if(namc)
755954Sbill 		for(i = 0; i < namc; i++)
756954Sbill 			if(rtk(namv[i])==0) namv[i]=0;
757954Sbill 	if(dirdirty)
758954Sbill 		scrunch();
759954Sbill 
760954Sbill }
761954Sbill rtk(name)
762954Sbill char *name;
763954Sbill {
764954Sbill 	register FLDOPE *dope;
765954Sbill 	register struct rt_ent *de;
766954Sbill 	FLDOPE *lookup();
767954Sbill 
768954Sbill 	if(dope = lookup(name)) {
769954Sbill 		printf("d - %s\n",name);
770954Sbill 		de = dope->rtdope;
771954Sbill 		de->rt_stat = RT_NULL;
772954Sbill 		de->rt_name[0] = 0;
773954Sbill 		de->rt_name[1] = 0;
774954Sbill 		de->rt_name[2] = 0;
775954Sbill 		* ((unsigned short *) & (de->rt_date)) = 0;
776954Sbill 		dirdirty = 1;
777954Sbill 		return(0);
778954Sbill 	}
779954Sbill 	return(1);
780954Sbill }
781954Sbill scrunch() {
7823346Swnj 	register struct rt_ent *de , *workp;
7833346Swnj 	register segnum;
7843346Swnj 	for (segnum=0; segnum != -1;    /* for all dir. segments */
7853346Swnj 	     segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) {
7863346Swnj 	    dirdirty = 0;
7873346Swnj 	    for(de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) {
788954Sbill 		if(de->rt_stat==RT_NULL && de[1].rt_stat==RT_NULL) {
789954Sbill 			(de+1)->rt_len += de->rt_len;
7903346Swnj 			for(workp = de; workp < rt_curend[segnum]; workp++)
791954Sbill 				*workp = workp[1];
792954Sbill 			de--;
7933346Swnj 			rt_curend[segnum]--;
794954Sbill 			rt_nleft++;
7953346Swnj 			dirdirty = 1;
796954Sbill 		}
7973346Swnj 	    }
7983346Swnj 	    if (dirdirty)
7993346Swnj 	    lwrite((6+segnum*2)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[segnum]);
800954Sbill 	}
801954Sbill }
802