xref: /csrg-svn/old/arff/arff.c (revision 3346)
1*3346Swnj static	char *sccsid = "@(#)arff.c	4.3 (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 {
9954Sbill unsigned short	int	rt_yr:5;	/*Year - 1972			*/
10954Sbill unsigned short	int	rt_dy:5;	/*day				*/
11954Sbill unsigned short	int	rt_mo:5;	/*month				*/
12954Sbill };
13954Sbill struct	rt_axent {
14954Sbill 	char	rt_sent[14];
15954Sbill };
16954Sbill 
17954Sbill struct rt_ent {
18954Sbill 	char  rt_pad;			/*unusued		     */
19954Sbill 	char  rt_stat;			/*Type of entry, or end of seg*/
20954Sbill 	unsigned short rt_name[3];	/*Name, 3 words in rad50 form */
21954Sbill 	short rt_len;			/*Length of file	      */
22954Sbill 	char  rt_chan;			/*Only used in temporary files*/
23954Sbill 	char  rt_job;			/*Only used in temporary files*/
24954Sbill 	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
31*3346Swnj #define RT_DIRSIZE 31			/* max # of directory segments */
32954Sbill struct rt_head {
33954Sbill 	short	rt_numseg;		/*number of segments available*/
34954Sbill 	short	rt_nxtseg;		/*segment no of next log. seg */
35954Sbill 	short	rt_lstseg;		/*highest seg currenltly open */
36954Sbill 	unsigned short	rt_entpad;	/*extra words/dir. entry      */
37954Sbill 	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 };
44*3346Swnj 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];
64*3346Swnj struct rt_dir
65*3346Swnj    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;
68*3346Swnj 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 
94954Sbill 	/*register i;
95954Sbill 	for(i=0; signum[i]; i++)
96954Sbill 		if(signal(signum[i], SIG_IGN) != SIG_IGN)
97954Sbill 			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));
1161735Sbill 			read(tty,response,128);
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 
179954Sbill 
180954Sbill 
181954Sbill 
182954Sbill 
183954Sbill 
184954Sbill 
185954Sbill usage()
186954Sbill {
187954Sbill 	printf("usage: ar [%s][%s] archive files ...\n", opt, man);
188954Sbill 	exit(1);
189954Sbill }
190954Sbill 
191954Sbill 
192954Sbill 
193954Sbill notfound()
194954Sbill {
195954Sbill 	register i, n;
196954Sbill 
197954Sbill 	n = 0;
198954Sbill 	for(i=0; i<namc; i++)
199954Sbill 		if(namv[i]) {
200954Sbill 			fprintf(stderr, "arff: %s not found\n", namv[i]);
201954Sbill 			n++;
202954Sbill 		}
203954Sbill 	return(n);
204954Sbill }
205954Sbill 
206954Sbill 
207954Sbill 
208954Sbill phserr()
209954Sbill {
210954Sbill 
211954Sbill 	fprintf(stderr, "arff: phase error on %s\n", file);
212954Sbill }
213954Sbill 
214954Sbill mesg(c)
215954Sbill {
216954Sbill 
217954Sbill 	if(flg['v'-'a'])
218954Sbill 		if(c != 'c' || flg['v'-'a'] > 1)
219954Sbill 			printf("%c - %s\n", c, file);
220954Sbill }
221954Sbill 
222954Sbill tcmd()
223954Sbill {
224954Sbill 	register char *de;
225*3346Swnj 	int segnum;
226*3346Swnj 	register char *last;
227954Sbill 	FLDOPE *lookup(), *dope;
228954Sbill 	int nleft; register i;
229954Sbill 	register struct rt_ent *rde;
230954Sbill 
231954Sbill 	rt_init();
232954Sbill 	if(namc==0)
233*3346Swnj 	    for (segnum=0; segnum != -1;    /* for all dir. segments */
234*3346Swnj 		 segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) {
235*3346Swnj 		last = rt_last + segnum*2*RT_BLOCK;
236*3346Swnj 		for(de=((char *)&rt_dir[segnum])+10; de <= last;
237*3346Swnj 		    de += rt_entsiz) {
238954Sbill 			if(rtls(rt(de))) {
239*3346Swnj 				nleft = (last - de) / rt_entsiz;
240*3346Swnj 				printf("\n%d entries remaining",nleft);
241*3346Swnj 				printf(" in directory segment %d.\n",segnum+1);
242954Sbill 				break;
243954Sbill 			}
244954Sbill 		}
245*3346Swnj 	    }
246954Sbill 	else
247954Sbill 		for(i = 0; i < namc; i++) {
248954Sbill 			if(dope = lookup(namv[i])) {
249954Sbill 				rde = dope->rtdope;
250954Sbill 				rtls(rde);
251954Sbill 				namv[i] = 0;
252954Sbill 			}
253954Sbill 		}
254954Sbill }
255954Sbill rtls(de)
256954Sbill register struct rt_ent *de;
257954Sbill {
258954Sbill 	int month,day,year;
259954Sbill 	char name[12], ext[4];
260954Sbill 
261954Sbill 	if(flg['v'-'a'])
262954Sbill 		switch(de->rt_stat) {
263954Sbill 		case RT_TEMP:
264954Sbill 			printf("Tempfile:\n");
265954Sbill 		case RT_FILE:
266954Sbill 			unrad50(2,de->rt_name,name);
267954Sbill 			unrad50(1,&(de->rt_name[2]),ext);
268954Sbill 			day = de->rt_date.rt_dy;
269954Sbill 			year = de->rt_date.rt_yr + 72;
270954Sbill 			month = de->rt_date.rt_mo;
271954Sbill 			printf("%6.6s  %3.3s	%02d/%02d/%02d	%d\n",name,
272954Sbill 				ext,month,day,year,de->rt_len);
273954Sbill 			break;
274954Sbill 
275954Sbill 		case RT_NULL:
276954Sbill 			printf("%-25.9s	%d\n","<UNUSED>",de->rt_len);
277954Sbill 			break;
278954Sbill 
279954Sbill 		case RT_ESEG:
280954Sbill 			return(1);
281954Sbill 		}
282954Sbill 	else {
283954Sbill 		switch(de->rt_stat) {
284954Sbill 		case RT_TEMP:
285954Sbill 		case RT_FILE:
286954Sbill 			sunrad50(name,de->rt_name);
287954Sbill 			printf(name);putchar('\n');
288954Sbill 			break;
289954Sbill 
290954Sbill 		case RT_ESEG:
291954Sbill 			return(1);
292954Sbill 
293954Sbill 		case RT_NULL:
294954Sbill 			;
295954Sbill 		}
296954Sbill 	}
297954Sbill 	return(0);
298954Sbill }
299954Sbill xcmd()
300954Sbill {
301954Sbill 	register char *de;
302*3346Swnj 	int segnum;
303*3346Swnj 	register char *last;
304954Sbill 	char name[12];
305954Sbill 	register int i;
306954Sbill 
307954Sbill 	rt_init();
308954Sbill 	if(namc==0)
309*3346Swnj 	    for (segnum=0; segnum != -1;    /* for all dir. segments */
310*3346Swnj 		 segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) {
311*3346Swnj 		last = rt_last + segnum*2*RT_BLOCK;
312*3346Swnj 		for(de=((char *)&rt_dir[segnum])+10; de <= last;
313*3346Swnj 		    de += rt_entsiz) {
314954Sbill 			sunrad50(name,rt(de)->rt_name);
315954Sbill 			rtx(name);
316954Sbill 		}
317*3346Swnj 	    }
318954Sbill 
319954Sbill 	else
320954Sbill 		for(i = 0; i < namc; i++)
321954Sbill 		if(rtx(namv[i])==0) namv[i] = 0;
322954Sbill }
323954Sbill rtx(name)
324954Sbill char *name;
325954Sbill {
326954Sbill 	register FLDOPE *dope;
327954Sbill 	FLDOPE *lookup();
328954Sbill 	register startad, count;
329954Sbill 	int file; char buff[512];
330954Sbill 
331954Sbill 
332954Sbill 	if(dope = lookup(name)) {
333954Sbill 		if(flg['v' - 'a'])
334954Sbill 			rtls(dope->rtdope);
335954Sbill 		else
336954Sbill 			printf("x - %s\n",name);
337954Sbill 
338954Sbill 		file = creat(name, 0666);
339954Sbill 		if(file < 0) return(1);
340954Sbill 		count = dope->count;
341954Sbill 		startad = dope->startad;
342954Sbill 		for( ; count > 0 ; count -= 512) {
343954Sbill 			lread(startad,512,buff);
344954Sbill 			write(file,buff,512);
345954Sbill 			startad += 512;
346954Sbill 		}
347954Sbill 		close(file);
348954Sbill 		return(0);
349954Sbill 	}
350954Sbill 	return(1);
351954Sbill }
352954Sbill rt_init()
353954Sbill {
354954Sbill 	static initized = 0;
355954Sbill 	register char *de;
356*3346Swnj 	register i;
357*3346Swnj 	int mode, dirnum;
358*3346Swnj 	register char *last;
359954Sbill 
360954Sbill 	if(initized) return;
361954Sbill 	initized = 1;
362954Sbill 	if(flag('c') || flag('d') || flag('r'))
363954Sbill 		mode = 2;
364954Sbill 	else
365954Sbill 		mode = 0;
366954Sbill 	if((floppydes = open(defdev,mode)) < 0)
367954Sbill 		dbprintf("Floppy open failed\n");
368*3346Swnj 	if(flag('c')==0) {
369*3346Swnj 		lread(6*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[0]);
370*3346Swnj 		dirnum = rt_dir[0].rt_axhead.rt_numseg;
371*3346Swnj 		if (dirnum > RT_DIRSIZE) {
372*3346Swnj 		   fprintf(stderr,"arff: too many directory segments\n");
373*3346Swnj 		   exit(1);
374*3346Swnj 		}
375*3346Swnj 		for (i=1; i<dirnum; i++)
376*3346Swnj 		   lread((6+2*i)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[i]);
377*3346Swnj 	}
378954Sbill 
379*3346Swnj 	rt_entsiz = 2*rt_dir[0].rt_axhead.rt_entpad + 14;
380*3346Swnj 	rt_entsiz = 14;			/* assume rt_entpad = 0 ??? */
381*3346Swnj 	rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz;
382*3346Swnj 	rt_nleft = 0;
383*3346Swnj 
384*3346Swnj 	for (i=0; i<dirnum; i++) {
385*3346Swnj   	    last = rt_last + i*2*RT_BLOCK;
386*3346Swnj 	    for(de=((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) {
387954Sbill 		if(rt(de)->rt_stat==RT_ESEG) break;
388*3346Swnj 	    }
389*3346Swnj 	    rt_curend[i] = rt(de);
390*3346Swnj 	    rt_nleft += (last - de) / rt_entsiz;
391954Sbill 	}
392954Sbill }
393954Sbill 
394954Sbill static FLDOPE result;
395954Sbill FLDOPE *
396954Sbill lookup(name)
397954Sbill char * name;
398954Sbill {
399954Sbill 	unsigned short rname[3];
400954Sbill 	register char *de;
401*3346Swnj 	int segnum;
402*3346Swnj 	register char *last;
403954Sbill 	register index;
404954Sbill 
405954Sbill 	srad50(name,rname);
406954Sbill 
407954Sbill 	/*
408954Sbill 	 *  Search for name, accumulate blocks in index
409954Sbill 	 */
410954Sbill 	rt_init();
411*3346Swnj 	for (segnum=0; segnum != -1;    /* for all dir. segments */
412*3346Swnj              segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) {
413*3346Swnj 	    index = 0;
414*3346Swnj 	    last = rt_last + segnum*2*RT_BLOCK;
415*3346Swnj 	    for(de=((char *)&rt_dir[segnum])+10;
416*3346Swnj 		rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) {
417954Sbill 		switch(rt(de)->rt_stat) {
418954Sbill 		case RT_ESEG:
419*3346Swnj 		        exit(1);
420954Sbill 		case RT_FILE:
421954Sbill 		case RT_TEMP:
422954Sbill 		if(samename(rname,rt(de)->rt_name))
423954Sbill 			goto found;
424954Sbill 		case RT_NULL:
425954Sbill 			index += rt(de)->rt_len;
426954Sbill 		}
427*3346Swnj 	    }
428*3346Swnj         }
429954Sbill 	return((FLDOPE *) 0);
430954Sbill found:	result.count = rt(de)->rt_len * 512;
431*3346Swnj 	result.startad = 512 * (rt_dir[segnum].rt_axhead.rt_stfile + index);
432954Sbill 	result.rtdope = (struct rt_ent *) de;
433954Sbill 	return(&result);
434954Sbill }
435954Sbill static
436954Sbill samename(a,b)
437954Sbill unsigned short a[3],b[3];
438954Sbill {
439954Sbill 	return( a[0]==b[0] && a[1]==b[1] && a[2]==b[2] );
440954Sbill }
441954Sbill 
442954Sbill 
443954Sbill rad50(cp,out)
444954Sbill register unsigned char *cp;
445954Sbill unsigned short *out;
446954Sbill {
447954Sbill 	register index;
448954Sbill 	register temp;
449954Sbill 
450954Sbill 	for(index = 0;*cp; index++) {
451954Sbill 
452954Sbill 		temp = Ain1 * table[*cp++];
453954Sbill 		if(*cp!=0) {
454954Sbill 			temp += Ain2 * table[*cp++];
455954Sbill 
456954Sbill 			if(*cp!=0)
457954Sbill 				temp += table[*cp++];
458954Sbill 		}
459954Sbill 
460954Sbill 		out[index] = temp;
461954Sbill 	}
462954Sbill }
463954Sbill #define reduce(x,p,q) \
464954Sbill 	(x = v[p/q], p %= q);
465954Sbill 
466954Sbill unrad50(count,in,cp)
467954Sbill unsigned short *in;
468954Sbill register char *cp;
469954Sbill {
470954Sbill 	register i, temp; register unsigned char *v = (unsigned char *) val;
471954Sbill 
472954Sbill 	for(i = 0; i < count; i++) {
473954Sbill 		temp = in[i];
474954Sbill 
475954Sbill 		reduce (*cp++,temp,Ain1);
476954Sbill 		reduce (*cp++,temp,Ain2);
477954Sbill 		reduce (*cp++,temp,1);
478954Sbill 	}
479954Sbill 	*cp=0;
480954Sbill }
481954Sbill 
482954Sbill srad50(name,rname)
483954Sbill register char * name;
484954Sbill register unsigned short *rname;
485954Sbill {
486954Sbill 	register index; register char *cp;
487954Sbill 	char file[7],ext[4];
488954Sbill 	/*
489954Sbill 	 * Find end of pathname
490954Sbill 	 */
491954Sbill 	for(cp = name; *cp++; );
492954Sbill 	while(cp >= name && *--cp != '/');
493954Sbill 	cp++;
494954Sbill 	/*
495954Sbill 	 * Change to rad50
496954Sbill 	 *
497954Sbill 	 */
498954Sbill 	for(index = 0; *cp; ){
499954Sbill 		file[index++] = *cp++;
500954Sbill 		if(*cp=='.') {
501954Sbill 			cp++;
502954Sbill 			break;
503954Sbill 		}
504954Sbill 		if(index>=6) {
505954Sbill 			break;
506954Sbill 		}
507954Sbill 	}
508954Sbill 	file[index] = 0;
509954Sbill 	for(index = 0; *cp; ){
510954Sbill 		ext[index++] = *cp++;
511954Sbill 		if(*cp=='.' || index>=3) {
512954Sbill 			break;
513954Sbill 		}
514954Sbill 	}
515954Sbill 	ext[index]=0;
516954Sbill 	rname[0] = 0;
517954Sbill 	rname[1] = 0;
518954Sbill 	rname[2] = 0;
519954Sbill 	rad50((unsigned char *)file,rname);
520954Sbill 	rad50((unsigned char *)ext,rname+2);
521954Sbill }
522954Sbill sunrad50(name,rname)
523954Sbill unsigned short rname[3];
524954Sbill register char *name;
525954Sbill {
526954Sbill 	register char *cp, *cp2;
527954Sbill 	char ext[4];
528954Sbill 
529954Sbill 	unrad50(2,rname,name);
530954Sbill 	unrad50(1,rname + 2,ext);
531954Sbill 	/* Jam name and extension together with a dot
532954Sbill 	   deleting white space */
533954Sbill 	for(cp = name; *cp++;);--cp;  while(*--cp==' ' && cp>=name);
534954Sbill 	*++cp = '.';cp++;
535954Sbill 	for(cp2=ext; *cp2!=' ' && cp2 < ext + 3;) {
536954Sbill 		*cp++ = *cp2++;
537954Sbill 	}
538954Sbill 	*cp=0;
539954Sbill 	if(cp[-1]=='.') cp[-1] = 0;
540954Sbill }
541954Sbill 
542954Sbill static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789";
543954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789";
544954Sbill static char table[256] = {
545954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
546954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
547954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
548954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 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, 29,
551954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
552954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
553954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
554954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
555954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
556954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
557954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
558954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
559954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
560954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 };
561954Sbill 
562954Sbill long trans(logical)
563954Sbill register int logical;
564954Sbill {
565954Sbill 	/*  Logical to physical adress translation */
566954Sbill 	register int sector, bytes, track;
567954Sbill 
568954Sbill 	logical += 26 * 128;
569954Sbill 	bytes = (logical & 127);
570954Sbill 	logical >>= 7;
571954Sbill 	sector = logical % 26;
572954Sbill 	if(sector >= 13)
573954Sbill 		sector = sector *2 +1;
574954Sbill 	else
575954Sbill 		sector *= 2;
576954Sbill 	sector += 26 + ((track = (logical / 26)) - 1) * 6;
577954Sbill 	sector %= 26;
578954Sbill 	return( (((track *26) + sector) << 7) + bytes);
579954Sbill }
580954Sbill lread(startad,count,obuff)
581954Sbill register startad, count;
582954Sbill register char * obuff;
583954Sbill {
584954Sbill 	long trans();
585954Sbill 	extern floppydes;
586954Sbill 	rt_init();
587954Sbill 	if(flg['m'-'a']==0)
588954Sbill 		while( (count -= 128) >= 0) {
589954Sbill 			lseek(floppydes, trans(startad), 0);
590954Sbill 			read(floppydes,obuff,128);
591954Sbill 			obuff += 128;
592954Sbill 			startad += 128;
593954Sbill 		}
594954Sbill 	else
595954Sbill 		while( (count -= 512) >= 0) {
596954Sbill 			lseek(floppydes,(long) (startad), 0);
597954Sbill 			read(floppydes,obuff,512);
598954Sbill 			obuff += 512;
599954Sbill 			startad += 512;
600954Sbill 		}
601954Sbill }
602954Sbill lwrite(startad,count,obuff)
603954Sbill register startad, count;
604954Sbill register char * obuff;
605954Sbill {
606954Sbill 	long trans();
607954Sbill 	extern floppydes;
608954Sbill 	rt_init();
609954Sbill 	if(flg['m'-'a']==0)
610954Sbill 		while( (count -= 128) >= 0) {
611954Sbill 			lseek(floppydes, trans(startad), 0);
612954Sbill 			write(floppydes,obuff,128);
613954Sbill 			obuff += 128;
614954Sbill 			startad += 128;
615954Sbill 		}
616954Sbill 	else
617954Sbill 		while( (count -= 512) >= 0) {
618954Sbill 			lseek(floppydes,(long) (startad), 0);
619954Sbill 			write(floppydes,obuff,512);
620954Sbill 			obuff += 512;
621954Sbill 			startad += 512;
622954Sbill 		}
623954Sbill }
624954Sbill 
625954Sbill rcmd()
626954Sbill {
627954Sbill 	register int i;
628*3346Swnj 	int debug;
629954Sbill 
630954Sbill 	rt_init();
631954Sbill 	if(namc>0)
632954Sbill 		for(i = 0; i < namc; i++)
633*3346Swnj 			if((debug = rtr(namv[i]))==0) namv[i]=0;
634*3346Swnj 			else printf("debug-rtr returns %d\n",debug);
635954Sbill 
636954Sbill 
637954Sbill }
638954Sbill 
639954Sbill rtr(name)
640954Sbill char *name;
641954Sbill {
642954Sbill 	register FLDOPE *dope; register struct rt_ent *de;
643954Sbill 	struct stat buf; register struct stat *bufp = &buf;
644*3346Swnj 	int segnum;
645*3346Swnj 	register char *last;
646954Sbill 
647954Sbill 	if(stat(name,bufp)<0) return(1);
648954Sbill 	if(dope = lookup(name)) {
649954Sbill 		/* can replace, no problem */
650954Sbill 		de = dope->rtdope;
651954Sbill 		if(bufp->st_size <= (de->rt_len * 512))
652954Sbill 			printf("r - %s\n",name),
653954Sbill 			toflop(name,bufp->st_size,dope);
654954Sbill 		else {
655954Sbill 			printf("%s will not fit in currently used file on floppy\n",name);
656954Sbill 			return(1);
657954Sbill 		}
658954Sbill 	} else {
659*3346Swnj 	    /* Search for vacant spot */
660*3346Swnj 	    for (segnum=0; segnum != -1;    /* for all dir. segments */
661*3346Swnj 		 segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) {
662*3346Swnj 		last = rt_last + segnum*2*RT_BLOCK;
663*3346Swnj 		for(de = rt_dir[segnum].rt_ents;
664*3346Swnj 		    rt(de)->rt_stat != RT_ESEG; de++) {
665954Sbill 			switch((de)->rt_stat) {
666954Sbill 			case RT_NULL:
667954Sbill 				if(bufp->st_size <= (de->rt_len * 512)) {
668954Sbill 					printf("a - %s\n",name),
669*3346Swnj 					mkent(de,segnum,bufp,name);
670954Sbill 					goto found;
671954Sbill 				}
672954Sbill 				continue;
673954Sbill 			case RT_ESEG:
674*3346Swnj 				exit(1);
675954Sbill 			}
676954Sbill 		}
677*3346Swnj 	    }
678*3346Swnj 	    return(3);
679954Sbill 	}
680954Sbill found:	if(dope=lookup(name)) {
681954Sbill 		toflop(name,bufp->st_size,dope);
682954Sbill 		return(0);
683954Sbill 	}
684954Sbill 	return(7);
685954Sbill 
686954Sbill }
687*3346Swnj mkent(de,segnum,bufp,name)
688954Sbill register struct rt_ent *de;
689*3346Swnj int segnum;
690954Sbill register struct stat *bufp;
691954Sbill char *name;
692954Sbill {
693954Sbill 	struct tm *localtime(); register struct tm *timp;
694954Sbill 	register struct rt_ent *workp; int count;
695954Sbill 
696954Sbill 	count = (((bufp->st_size -1) >>9) + 1);
697954Sbill 						/* Make sure there is room */
698954Sbill 	if(de->rt_len==count)
699954Sbill 		goto overwrite;
700*3346Swnj 	if(rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) {
701*3346Swnj 						/* no entries left on segment */
702954Sbill 		if(flg['o'-'a'])
703954Sbill 			goto overwrite;
704*3346Swnj 		fprintf(stderr,"Directory segment #%d full on  %s\n",segnum+1,
705*3346Swnj                     defdev);
706954Sbill 		exit(1);
707954Sbill 	}
708954Sbill 					/* copy directory entries up */
709*3346Swnj 	for(workp = rt_curend[segnum]+1; workp > de; workp--)
710954Sbill 		*workp = workp[-1];
711954Sbill 	de[1].rt_len -= count;
712954Sbill 	de->rt_len = count;
713*3346Swnj 	rt_curend[segnum]++;
714954Sbill 	rt_nleft--;
715954Sbill overwrite:
716954Sbill 	srad50(name,de->rt_name);
717954Sbill 	timp = localtime(&bufp->st_mtime);
718954Sbill 	de->rt_date.rt_dy = timp->tm_mday + 1;
719954Sbill 	de->rt_date.rt_mo = timp->tm_mon + 1;
720954Sbill 	de->rt_date.rt_yr = timp->tm_year - 72;
721954Sbill 	de->rt_stat = RT_FILE;
722954Sbill 	de->rt_pad = 0;
723954Sbill 	de->rt_chan = 0;
724954Sbill 	de->rt_job = 0;
725*3346Swnj 	lwrite((6+segnum*2)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[segnum]);
726954Sbill 
727954Sbill }
728954Sbill 
729954Sbill toflop(name,ocount,dope)
730954Sbill char *name;
731954Sbill register FLDOPE *dope;
732954Sbill long ocount;
733954Sbill {
734954Sbill 	register file, n, startad = dope->startad, count = ocount;
735954Sbill 	char buff[512];
736954Sbill 
737954Sbill 	file = open(name,0);
738954Sbill 	if(file < 0) {
739954Sbill 		printf("arff: couldn't open %s\n",name);exit(1);}
740954Sbill 	for( ; count >= 512; count -= 512) {
741954Sbill 		read(file,buff,512);
742954Sbill 		lwrite(startad,512,buff);
743954Sbill 		startad += 512;
744954Sbill 	}
745954Sbill 	read(file,buff,count);
746954Sbill 	close(file);
747954Sbill 	if(count <= 0) return;
748954Sbill 	for(n = count; n < 512; n ++) buff[n] = 0;
749954Sbill 	lwrite(startad,512,buff);
750954Sbill 	count = (dope->rtdope->rt_len * 512 - ocount) / 512 ;
751954Sbill 	if(count <= 0) return;
752954Sbill 	for( ; count > 0 ; count--) {
753954Sbill 		startad += 512;
754954Sbill 		lwrite(startad,512,zeroes);
755954Sbill 	}
756954Sbill 
757954Sbill }
758954Sbill dcmd()
759954Sbill {
760954Sbill 	register int i;
761954Sbill 
762954Sbill 	rt_init();
763954Sbill 	if(namc)
764954Sbill 		for(i = 0; i < namc; i++)
765954Sbill 			if(rtk(namv[i])==0) namv[i]=0;
766954Sbill 	if(dirdirty)
767954Sbill 		scrunch();
768954Sbill 
769954Sbill }
770954Sbill rtk(name)
771954Sbill char *name;
772954Sbill {
773954Sbill 	register FLDOPE *dope;
774954Sbill 	register struct rt_ent *de;
775954Sbill 	FLDOPE *lookup();
776954Sbill 
777954Sbill 	if(dope = lookup(name)) {
778954Sbill 		printf("d - %s\n",name);
779954Sbill 		de = dope->rtdope;
780954Sbill 		de->rt_stat = RT_NULL;
781954Sbill 		de->rt_name[0] = 0;
782954Sbill 		de->rt_name[1] = 0;
783954Sbill 		de->rt_name[2] = 0;
784954Sbill 		* ((unsigned short *) & (de->rt_date)) = 0;
785954Sbill 		dirdirty = 1;
786954Sbill 		return(0);
787954Sbill 	}
788954Sbill 	return(1);
789954Sbill }
790954Sbill scrunch() {
791*3346Swnj 	register struct rt_ent *de , *workp;
792*3346Swnj 	register segnum;
793*3346Swnj 	for (segnum=0; segnum != -1;    /* for all dir. segments */
794*3346Swnj 	     segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) {
795*3346Swnj 	    dirdirty = 0;
796*3346Swnj 	    for(de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) {
797954Sbill 		if(de->rt_stat==RT_NULL && de[1].rt_stat==RT_NULL) {
798954Sbill 			(de+1)->rt_len += de->rt_len;
799*3346Swnj 			for(workp = de; workp < rt_curend[segnum]; workp++)
800954Sbill 				*workp = workp[1];
801954Sbill 			de--;
802*3346Swnj 			rt_curend[segnum]--;
803954Sbill 			rt_nleft++;
804*3346Swnj 			dirdirty = 1;
805954Sbill 		}
806*3346Swnj 	    }
807*3346Swnj 	    if (dirdirty)
808*3346Swnj 	    lwrite((6+segnum*2)*RT_BLOCK,2*RT_BLOCK,(char *)&rt_dir[segnum]);
809954Sbill 	}
810954Sbill }
811