xref: /csrg-svn/old/arff/arff.c (revision 3799)
1*3799Shickman static	char *sccsid = "@(#)arff.c	4.6 (Berkeley) 81/05/18";
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
653489Sroot    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;
346*3799Shickman 	int dirnum;
347*3799Shickman 	char *mode;
3483346Swnj 	register char *last;
349*3799Shickman 	FILE *temp_floppydes;
350954Sbill 
351954Sbill 	if(initized) return;
352954Sbill 	initized = 1;
353954Sbill 	if(flag('c') || flag('d') || flag('r'))
354*3799Shickman 		mode = "r+";
355954Sbill 	else
356*3799Shickman 		mode = "r";
357*3799Shickman 	if((temp_floppydes = fopen(defdev, mode)) == NULL) {
358*3799Shickman 		perror(defdev);
3593356Swnj 		exit(1);
360*3799Shickman 	} else
361*3799Shickman 		floppydes = fileno(temp_floppydes);
3623346Swnj 	if(flag('c')==0) {
3633346Swnj 		lread(6*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[0]);
3643346Swnj 		dirnum = rt_dir[0].rt_axhead.rt_numseg;
3653346Swnj 		if (dirnum > RT_DIRSIZE) {
3663346Swnj 		   fprintf(stderr,"arff: too many directory segments\n");
3673346Swnj 		   exit(1);
3683346Swnj 		}
3693346Swnj 		for (i=1; i<dirnum; i++)
3703346Swnj 		   lread((6+2*i)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[i]);
3713489Sroot 	} else
3723489Sroot 		dirnum = 1;
373954Sbill 
3743346Swnj 	rt_entsiz = 2*rt_dir[0].rt_axhead.rt_entpad + 14;
3753346Swnj 	rt_entsiz = 14;			/* assume rt_entpad = 0 ??? */
3763346Swnj 	rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz;
3773346Swnj 	rt_nleft = 0;
3783346Swnj 
3793346Swnj 	for (i=0; i<dirnum; i++) {
3803346Swnj   	    last = rt_last + i*2*RT_BLOCK;
3813346Swnj 	    for(de=((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) {
382954Sbill 		if(rt(de)->rt_stat==RT_ESEG) break;
3833346Swnj 	    }
3843346Swnj 	    rt_curend[i] = rt(de);
3853346Swnj 	    rt_nleft += (last - de) / rt_entsiz;
386954Sbill 	}
387954Sbill }
388954Sbill 
389954Sbill static FLDOPE result;
390954Sbill FLDOPE *
391954Sbill lookup(name)
392954Sbill char * name;
393954Sbill {
394954Sbill 	unsigned short rname[3];
395954Sbill 	register char *de;
3963346Swnj 	int segnum;
3973346Swnj 	register char *last;
398954Sbill 	register index;
399954Sbill 
400954Sbill 	srad50(name,rname);
401954Sbill 
4023356Swnj 	/*
403954Sbill 	 *  Search for name, accumulate blocks in index
404954Sbill 	 */
405954Sbill 	rt_init();
4063346Swnj 	for (segnum=0; segnum != -1;    /* for all dir. segments */
4073346Swnj              segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) {
4083346Swnj 	    index = 0;
4093346Swnj 	    last = rt_last + segnum*2*RT_BLOCK;
4103346Swnj 	    for(de=((char *)&rt_dir[segnum])+10;
4113346Swnj 		rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) {
412954Sbill 		switch(rt(de)->rt_stat) {
413954Sbill 		case RT_FILE:
414954Sbill 		case RT_TEMP:
415954Sbill 		if(samename(rname,rt(de)->rt_name))
416954Sbill 			goto found;
417954Sbill 		case RT_NULL:
418954Sbill 			index += rt(de)->rt_len;
419954Sbill 		}
4203346Swnj 	    }
4213346Swnj         }
422954Sbill 	return((FLDOPE *) 0);
423954Sbill found:	result.count = rt(de)->rt_len * 512;
4243346Swnj 	result.startad = 512 * (rt_dir[segnum].rt_axhead.rt_stfile + index);
425954Sbill 	result.rtdope = (struct rt_ent *) de;
426954Sbill 	return(&result);
427954Sbill }
428954Sbill static
429954Sbill samename(a,b)
430954Sbill unsigned short a[3],b[3];
431954Sbill {
432954Sbill 	return( a[0]==b[0] && a[1]==b[1] && a[2]==b[2] );
433954Sbill }
434954Sbill 
435954Sbill 
436954Sbill rad50(cp,out)
437954Sbill register unsigned char *cp;
438954Sbill unsigned short *out;
439954Sbill {
440954Sbill 	register index;
441954Sbill 	register temp;
442954Sbill 
443954Sbill 	for(index = 0;*cp; index++) {
444954Sbill 
445954Sbill 		temp = Ain1 * table[*cp++];
446954Sbill 		if(*cp!=0) {
447954Sbill 			temp += Ain2 * table[*cp++];
448954Sbill 
449954Sbill 			if(*cp!=0)
450954Sbill 				temp += table[*cp++];
451954Sbill 		}
452954Sbill 
453954Sbill 		out[index] = temp;
454954Sbill 	}
455954Sbill }
456954Sbill #define reduce(x,p,q) \
457954Sbill 	(x = v[p/q], p %= q);
458954Sbill 
459954Sbill unrad50(count,in,cp)
460954Sbill unsigned short *in;
461954Sbill register char *cp;
462954Sbill {
463954Sbill 	register i, temp; register unsigned char *v = (unsigned char *) val;
464954Sbill 
465954Sbill 	for(i = 0; i < count; i++) {
466954Sbill 		temp = in[i];
467954Sbill 
468954Sbill 		reduce (*cp++,temp,Ain1);
469954Sbill 		reduce (*cp++,temp,Ain2);
470954Sbill 		reduce (*cp++,temp,1);
471954Sbill 	}
472954Sbill 	*cp=0;
473954Sbill }
474954Sbill 
475954Sbill srad50(name,rname)
476954Sbill register char * name;
477954Sbill register unsigned short *rname;
478954Sbill {
479954Sbill 	register index; register char *cp;
480954Sbill 	char file[7],ext[4];
4813356Swnj 	/*
482954Sbill 	 * Find end of pathname
483954Sbill 	 */
484954Sbill 	for(cp = name; *cp++; );
485954Sbill 	while(cp >= name && *--cp != '/');
486954Sbill 	cp++;
4873356Swnj 	/*
488954Sbill 	 * Change to rad50
489954Sbill 	 *
490954Sbill 	 */
491954Sbill 	for(index = 0; *cp; ){
492954Sbill 		file[index++] = *cp++;
493954Sbill 		if(*cp=='.') {
494954Sbill 			cp++;
495954Sbill 			break;
496954Sbill 		}
497954Sbill 		if(index>=6) {
498954Sbill 			break;
499954Sbill 		}
500954Sbill 	}
501954Sbill 	file[index] = 0;
502954Sbill 	for(index = 0; *cp; ){
503954Sbill 		ext[index++] = *cp++;
504954Sbill 		if(*cp=='.' || index>=3) {
505954Sbill 			break;
506954Sbill 		}
507954Sbill 	}
508954Sbill 	ext[index]=0;
509954Sbill 	rname[0] = 0;
510954Sbill 	rname[1] = 0;
511954Sbill 	rname[2] = 0;
512954Sbill 	rad50((unsigned char *)file,rname);
513954Sbill 	rad50((unsigned char *)ext,rname+2);
514954Sbill }
515954Sbill sunrad50(name,rname)
516954Sbill unsigned short rname[3];
517954Sbill register char *name;
518954Sbill {
519954Sbill 	register char *cp, *cp2;
520954Sbill 	char ext[4];
521954Sbill 
522954Sbill 	unrad50(2,rname,name);
523954Sbill 	unrad50(1,rname + 2,ext);
524954Sbill 	/* Jam name and extension together with a dot
525954Sbill 	   deleting white space */
526954Sbill 	for(cp = name; *cp++;);--cp;  while(*--cp==' ' && cp>=name);
527954Sbill 	*++cp = '.';cp++;
528954Sbill 	for(cp2=ext; *cp2!=' ' && cp2 < ext + 3;) {
529954Sbill 		*cp++ = *cp2++;
530954Sbill 	}
531954Sbill 	*cp=0;
532954Sbill 	if(cp[-1]=='.') cp[-1] = 0;
533954Sbill }
534954Sbill 
535954Sbill static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789";
536954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789";
537954Sbill static char table[256] = {
538954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
539954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
540954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
541954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
542954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
543954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
544954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
545954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
546954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
547954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
548954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
549954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
550954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
551954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
552954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
553954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 };
554954Sbill 
555954Sbill long trans(logical)
556954Sbill register int logical;
557954Sbill {
558954Sbill 	/*  Logical to physical adress translation */
559954Sbill 	register int sector, bytes, track;
560954Sbill 
561954Sbill 	logical += 26 * 128;
562954Sbill 	bytes = (logical & 127);
563954Sbill 	logical >>= 7;
564954Sbill 	sector = logical % 26;
565954Sbill 	if(sector >= 13)
566954Sbill 		sector = sector *2 +1;
567954Sbill 	else
568954Sbill 		sector *= 2;
569954Sbill 	sector += 26 + ((track = (logical / 26)) - 1) * 6;
570954Sbill 	sector %= 26;
571954Sbill 	return( (((track *26) + sector) << 7) + bytes);
572954Sbill }
573954Sbill lread(startad,count,obuff)
574954Sbill register startad, count;
575954Sbill register char * obuff;
576954Sbill {
577954Sbill 	long trans();
578954Sbill 	extern floppydes;
579*3799Shickman 	int temp;
580954Sbill 	rt_init();
581954Sbill 	if(flg['m'-'a']==0)
582954Sbill 		while( (count -= 128) >= 0) {
583954Sbill 			lseek(floppydes, trans(startad), 0);
584*3799Shickman 			 if ((temp = read(floppydes,obuff,128)) != 128)
585*3799Shickman 				fprintf(stderr, "arff: read error block %d %d\n",startad/128, temp);
586954Sbill 			obuff += 128;
587954Sbill 			startad += 128;
588954Sbill 		}
589954Sbill 	else
590954Sbill 		while( (count -= 512) >= 0) {
591954Sbill 			lseek(floppydes,(long) (startad), 0);
592*3799Shickman 			if ((temp = read(floppydes, obuff, 512)) != 512)
593*3799Shickman 				fprintf(stderr, "arff: read error block %d %d\n",startad/512, temp);
594954Sbill 			obuff += 512;
595954Sbill 			startad += 512;
596954Sbill 		}
597954Sbill }
598954Sbill lwrite(startad,count,obuff)
599954Sbill register startad, count;
600954Sbill register char * obuff;
601954Sbill {
602954Sbill 	long trans();
603954Sbill 	extern floppydes;
604954Sbill 	rt_init();
605954Sbill 	if(flg['m'-'a']==0)
606954Sbill 		while( (count -= 128) >= 0) {
607954Sbill 			lseek(floppydes, trans(startad), 0);
6083356Swnj 			if ( write(floppydes,obuff,128) != 128)
6093356Swnj 				fprintf(stderr, "arff: write error block %d\n",startad/128);
610954Sbill 			obuff += 128;
611954Sbill 			startad += 128;
612954Sbill 		}
613954Sbill 	else
614954Sbill 		while( (count -= 512) >= 0) {
615954Sbill 			lseek(floppydes,(long) (startad), 0);
6163356Swnj 			if ( write(floppydes,obuff,512) != 512)
6173356Swnj 				fprintf(stderr, "arff: write error block %d\n",startad/512);
618954Sbill 			obuff += 512;
619954Sbill 			startad += 512;
620954Sbill 		}
621954Sbill }
622954Sbill 
623954Sbill rcmd()
624954Sbill {
625954Sbill 	register int i;
626954Sbill 
627954Sbill 	rt_init();
6283489Sroot 	if (namc>0)
629954Sbill 		for(i = 0; i < namc; i++)
6303356Swnj 			if(rtr(namv[i])==0) namv[i]=0;
631954Sbill }
632954Sbill 
633954Sbill rtr(name)
634954Sbill char *name;
635954Sbill {
636954Sbill 	register FLDOPE *dope; register struct rt_ent *de;
637954Sbill 	struct stat buf; register struct stat *bufp = &buf;
6383346Swnj 	int segnum;
6393346Swnj 	register char *last;
640954Sbill 
6413489Sroot 	if(stat(name,bufp)<0) {
6423489Sroot 		perror(name);
6433489Sroot 		return(-1);
6443489Sroot 	}
645954Sbill 	if(dope = lookup(name)) {
646954Sbill 		/* can replace, no problem */
647954Sbill 		de = dope->rtdope;
648954Sbill 		if(bufp->st_size <= (de->rt_len * 512))
649954Sbill 			printf("r - %s\n",name),
650954Sbill 			toflop(name,bufp->st_size,dope);
651954Sbill 		else {
6523356Swnj 			fprintf(stderr, "%s will not fit in currently used file on floppy\n",name);
6533489Sroot 			return(-1);
654954Sbill 		}
655954Sbill 	} else {
6563346Swnj 	    /* Search for vacant spot */
6573346Swnj 	    for (segnum=0; segnum != -1;    /* for all dir. segments */
6583346Swnj 		 segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) {
6593346Swnj 		last = rt_last + segnum*2*RT_BLOCK;
6603346Swnj 		for(de = rt_dir[segnum].rt_ents;
6613346Swnj 		    rt(de)->rt_stat != RT_ESEG; de++) {
662954Sbill 			switch((de)->rt_stat) {
663954Sbill 			case RT_NULL:
664954Sbill 				if(bufp->st_size <= (de->rt_len * 512)) {
665954Sbill 					printf("a - %s\n",name),
6663346Swnj 					mkent(de,segnum,bufp,name);
667954Sbill 					goto found;
668954Sbill 				}
669954Sbill 				continue;
670954Sbill 			}
671954Sbill 		}
6723346Swnj 	    }
6733489Sroot 	    printf("%s: no slot for file\n", name);
6743489Sroot 	    return (-1);
675954Sbill 	}
676954Sbill found:	if(dope=lookup(name)) {
677954Sbill 		toflop(name,bufp->st_size,dope);
6783489Sroot 		return (0);
679954Sbill 	}
6803489Sroot 	printf("%s: internal error, added then not found\n", name);
6813489Sroot 	return (-1);
682954Sbill 
683954Sbill }
6843346Swnj mkent(de,segnum,bufp,name)
685954Sbill register struct rt_ent *de;
6863346Swnj int segnum;
687954Sbill register struct stat *bufp;
688954Sbill char *name;
689954Sbill {
690954Sbill 	struct tm *localtime(); register struct tm *timp;
691954Sbill 	register struct rt_ent *workp; int count;
692954Sbill 
693954Sbill 	count = (((bufp->st_size -1) >>9) + 1);
694954Sbill 						/* Make sure there is room */
695954Sbill 	if(de->rt_len==count)
696954Sbill 		goto overwrite;
6973346Swnj 	if(rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) {
6983346Swnj 						/* no entries left on segment */
699954Sbill 		if(flg['o'-'a'])
700954Sbill 			goto overwrite;
7013346Swnj 		fprintf(stderr,"Directory segment #%d full on  %s\n",segnum+1,
7023346Swnj                     defdev);
703954Sbill 		exit(1);
704954Sbill 	}
705954Sbill 					/* copy directory entries up */
7063346Swnj 	for(workp = rt_curend[segnum]+1; workp > de; workp--)
707954Sbill 		*workp = workp[-1];
708954Sbill 	de[1].rt_len -= count;
709954Sbill 	de->rt_len = count;
7103346Swnj 	rt_curend[segnum]++;
711954Sbill 	rt_nleft--;
712954Sbill overwrite:
713954Sbill 	srad50(name,de->rt_name);
714954Sbill 	timp = localtime(&bufp->st_mtime);
715954Sbill 	de->rt_date.rt_dy = timp->tm_mday + 1;
716954Sbill 	de->rt_date.rt_mo = timp->tm_mon + 1;
717954Sbill 	de->rt_date.rt_yr = timp->tm_year - 72;
718954Sbill 	de->rt_stat = RT_FILE;
719954Sbill 	de->rt_pad = 0;
720954Sbill 	de->rt_chan = 0;
721954Sbill 	de->rt_job = 0;
7223346Swnj 	lwrite((6+segnum*2)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[segnum]);
723954Sbill }
724954Sbill 
725954Sbill toflop(name,ocount,dope)
726954Sbill char *name;
727954Sbill register FLDOPE *dope;
728954Sbill long ocount;
729954Sbill {
730954Sbill 	register file, n, startad = dope->startad, count = ocount;
731954Sbill 	char buff[512];
732954Sbill 
733954Sbill 	file = open(name,0);
734954Sbill 	if(file < 0) {
7353356Swnj 		fprintf(stderr, "arff: couldn't open %s\n",name);exit(1);}
736954Sbill 	for( ; count >= 512; count -= 512) {
737954Sbill 		read(file,buff,512);
738954Sbill 		lwrite(startad,512,buff);
739954Sbill 		startad += 512;
740954Sbill 	}
741954Sbill 	read(file,buff,count);
742954Sbill 	close(file);
743954Sbill 	if(count <= 0) return;
744954Sbill 	for(n = count; n < 512; n ++) buff[n] = 0;
745954Sbill 	lwrite(startad,512,buff);
746954Sbill 	count = (dope->rtdope->rt_len * 512 - ocount) / 512 ;
747954Sbill 	if(count <= 0) return;
748954Sbill 	for( ; count > 0 ; count--) {
749954Sbill 		startad += 512;
750954Sbill 		lwrite(startad,512,zeroes);
751954Sbill 	}
752954Sbill 
753954Sbill }
754954Sbill dcmd()
755954Sbill {
756954Sbill 	register int i;
757954Sbill 
758954Sbill 	rt_init();
759954Sbill 	if(namc)
760954Sbill 		for(i = 0; i < namc; i++)
761954Sbill 			if(rtk(namv[i])==0) namv[i]=0;
762954Sbill 	if(dirdirty)
763954Sbill 		scrunch();
764954Sbill 
765954Sbill }
766954Sbill rtk(name)
767954Sbill char *name;
768954Sbill {
769954Sbill 	register FLDOPE *dope;
770954Sbill 	register struct rt_ent *de;
771954Sbill 	FLDOPE *lookup();
772954Sbill 
773954Sbill 	if(dope = lookup(name)) {
774954Sbill 		printf("d - %s\n",name);
775954Sbill 		de = dope->rtdope;
776954Sbill 		de->rt_stat = RT_NULL;
777954Sbill 		de->rt_name[0] = 0;
778954Sbill 		de->rt_name[1] = 0;
779954Sbill 		de->rt_name[2] = 0;
780954Sbill 		* ((unsigned short *) & (de->rt_date)) = 0;
781954Sbill 		dirdirty = 1;
782954Sbill 		return(0);
783954Sbill 	}
784954Sbill 	return(1);
785954Sbill }
786954Sbill scrunch() {
7873346Swnj 	register struct rt_ent *de , *workp;
7883346Swnj 	register segnum;
7893346Swnj 	for (segnum=0; segnum != -1;    /* for all dir. segments */
7903346Swnj 	     segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) {
7913346Swnj 	    dirdirty = 0;
7923346Swnj 	    for(de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) {
793954Sbill 		if(de->rt_stat==RT_NULL && de[1].rt_stat==RT_NULL) {
794954Sbill 			(de+1)->rt_len += de->rt_len;
7953346Swnj 			for(workp = de; workp < rt_curend[segnum]; workp++)
796954Sbill 				*workp = workp[1];
797954Sbill 			de--;
7983346Swnj 			rt_curend[segnum]--;
799954Sbill 			rt_nleft++;
8003346Swnj 			dirdirty = 1;
801954Sbill 		}
8023346Swnj 	    }
8033346Swnj 	    if (dirdirty)
8043346Swnj 	    lwrite((6+segnum*2)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[segnum]);
805954Sbill 	}
806954Sbill }
807