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