xref: /csrg-svn/old/arff/arff.c (revision 7320)
1*7320Swnj static	char *sccsid = "@(#)arff.c	4.10 (Berkeley) 82/06/27";
24879Ssam 
3954Sbill #include <sys/types.h>
4954Sbill #include <sys/stat.h>
5954Sbill #include <time.h>
6954Sbill #include <signal.h>
7954Sbill #include <stdio.h>
84879Ssam 
9954Sbill #define dbprintf printf
104879Ssam 
11954Sbill struct rt_dat {
124879Ssam 	u_short	rt_yr:5;	/* year-1972 */
134879Ssam 	u_short	rt_dy:5;	/* day */
144879Ssam 	u_short	rt_mo:5;	/* month */
15954Sbill };
164879Ssam 
17954Sbill struct	rt_axent {
18954Sbill 	char	rt_sent[14];
19954Sbill };
20954Sbill 
21954Sbill struct rt_ent {
224879Ssam 	char	rt_pad;		/* unusued */
234879Ssam 	char	rt_stat;	/* type of entry, or end of seg */
244879Ssam 	u_short	rt_name[3];	/* name, 3 words in rad50 form */
257319Swnj 	u_short	rt_len;		/* length of file */
264879Ssam 	char	rt_chan;	/* only used in temporary files */
274879Ssam 	char	rt_job;		/* only used in temporary files */
284879Ssam 	struct rt_dat rt_date;	/* creation date */
29954Sbill };
304879Ssam 
314879Ssam #define RT_TEMP		1
324879Ssam #define RT_NULL		2
334879Ssam #define RT_FILE		4
344879Ssam #define RT_ESEG		8
354879Ssam 
364879Ssam #define RT_BLOCK	512	/* block size */
374879Ssam #define RT_DIRSIZE	31	/* max # of directory segments */
384879Ssam 
39954Sbill struct rt_head {
404879Ssam 	short	rt_numseg;	/* # of segments available */
414879Ssam 	short	rt_nxtseg;	/* # of next logical segment */
424879Ssam 	short	rt_lstseg;	/* highest seg currently open */
434879Ssam 	u_short	rt_entpad;	/* extra words/directory entry */
444879Ssam 	short	rt_stfile;	/* block # where files begin */
45954Sbill };
464879Ssam 
47954Sbill struct	rt_dir {
48954Sbill 	struct rt_head	rt_axhead;
49954Sbill 	struct rt_ent	rt_ents[72];
504879Ssam 	char		_dirpad[6];
51954Sbill };
524879Ssam 
533346Swnj extern struct rt_dir	rt_dir[RT_DIRSIZE];
54954Sbill extern int		rt_entsiz;
55954Sbill extern int		floppydes;
56954Sbill extern char		*rt_last;
574879Ssam 
58954Sbill typedef struct fldope {
59954Sbill 	int	startad;
60954Sbill 	int	count;
61954Sbill struct	rt_ent	*rtdope;
62954Sbill } FLDOPE;
634879Ssam 
64954Sbill FLDOPE *lookup();
654879Ssam 
66954Sbill #define rt(p) ((struct rt_ent *) p )
67954Sbill #define Ain1 03100
68954Sbill #define Ain2 050
694879Ssam #define flag(c) (flg[('c') - 'a'])
70954Sbill 
714879Ssam char *man = "rxtd";
724879Ssam char zeroes[512];
73954Sbill 
74954Sbill extern char *val;
75954Sbill extern char table[256];
764879Ssam struct rt_dir rt_dir[RT_DIRSIZE] = {
774879Ssam 	{4, 0, 1, 0, 14},
784879Ssam 	{ {0, RT_NULL, {0, 0, 0}, 494, 0}, {0, RT_ESEG} }
794879Ssam };
80954Sbill 
814879Ssam int	rt_entsiz;
824879Ssam int	rt_nleft;
834879Ssam struct rt_ent *rt_curend[RT_DIRSIZE];
844879Ssam int	floppydes;
854879Ssam int	dirdirty;
864879Ssam char	*rt_last;
874879Ssam char	*defdev = "/dev/floppy";
88954Sbill 
894879Ssam char *opt = "vf";
904879Ssam 
91954Sbill int	signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};
924879Ssam extern long lseek();
934879Ssam int	rcmd(), dcmd(), xcmd(), tcmd();
944879Ssam 
95954Sbill int	(*comfun)();
96954Sbill char	flg[26];
97954Sbill char	**namv;
98954Sbill int	namc;
99954Sbill int	file;
100954Sbill 
101954Sbill main(argc, argv)
1024879Ssam 	char *argv[];
103954Sbill {
104954Sbill 	register char *cp;
105954Sbill 
1064879Ssam 	if (argc < 2)
107954Sbill 		usage();
108954Sbill 	cp = argv[1];
1094879Ssam 	for (cp = argv[1]; *cp; cp++)
1104879Ssam 		switch (*cp) {
111954Sbill 
1124879Ssam 		case 'm':
1134879Ssam 		case 'v':
1144879Ssam 		case 'u':
1154879Ssam 		case 'w':
1164879Ssam 			flg[*cp-'a']++;
1174879Ssam 			continue;
1184879Ssam 		case 'c':
1194879Ssam 			{
1204879Ssam #define SURE	"Last chance before clobbering floppy?"
1214879Ssam 				int tty;
1224879Ssam 				char response[128];
123954Sbill 
1244879Ssam 				tty = open("/dev/tty", 2);
1254879Ssam 				write(tty, SURE, sizeof(SURE));
1264879Ssam 				read(tty, response, sizeof(response));
1274879Ssam 				if (*response != 'y')
1284879Ssam 					exit(50);
1294879Ssam 				flag(c)++;
1304879Ssam 				close(tty);
1314879Ssam 			}
1324879Ssam 			dirdirty++;
1334879Ssam 			continue;
134954Sbill 
1354879Ssam 		case 'r':
1364879Ssam 			setcom(rcmd);
1374879Ssam 			flag(r)++;
1384879Ssam 			continue;
139954Sbill 
1404879Ssam 		case 'd':
1414879Ssam 			setcom(dcmd);
1424879Ssam 			flag(d)++;
1434879Ssam 			continue;
144954Sbill 
1454879Ssam 		case 'x':
1464879Ssam 			setcom(xcmd);
1474879Ssam 			continue;
148954Sbill 
1494879Ssam 		case 't':
1504879Ssam 			setcom(tcmd);
1514879Ssam 			continue;
152954Sbill 
1534879Ssam 		case 'f':
1544879Ssam 			defdev = argv[2];
1554879Ssam 			argv++;
1564879Ssam 			argc--;
1574879Ssam 			continue;
1584879Ssam 
1594879Ssam 		default:
1604879Ssam 			fprintf(stderr, "arff: bad option `%c'\n", *cp);
1614879Ssam 			exit(1);
1624879Ssam 		}
1634879Ssam 
164954Sbill 	namv = argv+2;
165954Sbill 	namc = argc-2;
1664879Ssam 	if (comfun == 0) {
1674879Ssam 		if (flag(u) == 0) {
1684879Ssam 			fprintf(stderr, "arff: one of [%s] must be specified\n",
1694879Ssam 				man);
170954Sbill 			exit(1);
171954Sbill 		}
172954Sbill 		setcom(rcmd);
173954Sbill 	}
174954Sbill 	(*comfun)();
175954Sbill 	exit(notfound());
176954Sbill }
177954Sbill 
178954Sbill setcom(fun)
1794879Ssam 	int (*fun)();
180954Sbill {
1814879Ssam 	if (comfun != 0) {
182954Sbill 		fprintf(stderr, "arff: only one of [%s] allowed\n", man);
183954Sbill 		exit(1);
184954Sbill 	}
185954Sbill 	comfun = fun;
186954Sbill }
187954Sbill 
188954Sbill usage()
189954Sbill {
1903356Swnj 	fprintf(stderr, "usage: ar [%s][%s] archive files ...\n", opt, man);
191954Sbill 	exit(1);
192954Sbill }
193954Sbill 
194954Sbill notfound()
195954Sbill {
1964879Ssam 	register i, n = 0;
197954Sbill 
1984879Ssam 	for (i = 0; i < namc; i++)
1994879Ssam 		if (namv[i]) {
200954Sbill 			fprintf(stderr, "arff: %s not found\n", namv[i]);
201954Sbill 			n++;
202954Sbill 		}
203954Sbill 	return(n);
204954Sbill }
205954Sbill 
206954Sbill mesg(c)
207954Sbill {
2084879Ssam 	if (flag(v))
2094879Ssam 		if (c != 'c' || flag(v) > 1)
210954Sbill 			printf("%c - %s\n", c, file);
211954Sbill }
212954Sbill 
213954Sbill tcmd()
214954Sbill {
2154879Ssam 	register char *de, *last;
216954Sbill 	FLDOPE *lookup(), *dope;
2174879Ssam 	int segnum, nleft;
2184879Ssam 	register i;
219954Sbill 	register struct rt_ent *rde;
220954Sbill 
221954Sbill 	rt_init();
2224879Ssam 	if (namc == 0)
2234879Ssam 		for (segnum = 0; segnum != -1;
2244879Ssam 		     segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1)
2254879Ssam 		{
2264879Ssam 			last = rt_last + segnum*2*RT_BLOCK;
2274879Ssam 			for (de = ((char *)&rt_dir[segnum])+10; de <= last;
2284879Ssam 			    de += rt_entsiz)
2294879Ssam 				if (rtls(rt(de))) {
2304879Ssam 					nleft = (last-de)/rt_entsiz;
2314879Ssam #define ENTRIES "\n%d entries remaining in directory segment %d.\n"
2324879Ssam 					printf(ENTRIES, nleft, segnum+1);
2334879Ssam 					break;
2344879Ssam 				}
235954Sbill 		}
236954Sbill 	else
2374879Ssam 		for (i = 0; i < namc; i++)
2384879Ssam 			if (dope = lookup(namv[i])) {
239954Sbill 				rde = dope->rtdope;
240954Sbill 				rtls(rde);
241954Sbill 				namv[i] = 0;
242954Sbill 			}
243954Sbill }
2444879Ssam 
245954Sbill rtls(de)
2464879Ssam 	register struct rt_ent *de;
247954Sbill {
2484879Ssam 	int month, day, year;
249954Sbill 	char name[12], ext[4];
250954Sbill 
2514879Ssam 	switch (de->rt_stat) {
2524879Ssam 
2534879Ssam 	case RT_TEMP:
2544879Ssam 		if (flag(v))
255954Sbill 			printf("Tempfile:\n");
2564879Ssam 		/* fall thru...*/
257954Sbill 
2584879Ssam 	case RT_FILE:
2594879Ssam 		if (!flag(v)) {
2604879Ssam 			sunrad50(name, de->rt_name);
2614879Ssam 			printf("%s\n", name);
262954Sbill 			break;
263954Sbill 		}
2644879Ssam 		unrad50(2, de->rt_name, name);
2654879Ssam 		unrad50(1, &(de->rt_name[2]), ext);
2664879Ssam 		day = de->rt_date.rt_dy;
2674879Ssam 		year = de->rt_date.rt_yr+72;
2684879Ssam 		month = de->rt_date.rt_mo;
2694879Ssam 		printf("%6.6s  %3.3s	%02d/%02d/%02d	%d\n",name,
2704879Ssam 			ext, month, day, year, de->rt_len);
2714879Ssam 		break;
272954Sbill 
2734879Ssam 	case RT_NULL:
2744879Ssam 		printf("%-25.9s	%d\n","<UNUSED>", de->rt_len);
2754879Ssam 		break;
276954Sbill 
2774879Ssam 	case RT_ESEG:
2784879Ssam 		return(1);
279954Sbill 	}
280954Sbill 	return(0);
281954Sbill }
2824879Ssam 
283954Sbill xcmd()
284954Sbill {
2854879Ssam 	register char *de, *last;
2863346Swnj 	int segnum;
287954Sbill 	char name[12];
288954Sbill 	register int i;
289954Sbill 
290954Sbill 	rt_init();
2914879Ssam 	if (namc == 0)
2924879Ssam 		for (segnum = 0; segnum != -1;
2934879Ssam 		     segnum = rt_dir[segnum].rt_axhead.rt_nxtseg-1)
2944879Ssam 			for (last = rt_last+(segnum*2*RT_BLOCK),
2954879Ssam 			     de = ((char *)&rt_dir[segnum])+10; de <= last;
2964879Ssam 			     de += rt_entsiz)
2974879Ssam 				sunrad50(name, rt(de)->rt_name), rtx(name);
298954Sbill 	else
2994879Ssam 		for (i = 0; i < namc; i++)
3004879Ssam 			if (rtx(namv[i]) == 0)
3014879Ssam 				namv[i] = 0;
302954Sbill }
3034879Ssam 
304954Sbill rtx(name)
3054879Ssam 	char *name;
306954Sbill {
307954Sbill 	register FLDOPE *dope;
308954Sbill 	FLDOPE *lookup();
309954Sbill 	register startad, count;
3104879Ssam 	int file;
3114879Ssam 	char buff[512];
312954Sbill 
313954Sbill 
3144879Ssam 	if (dope = lookup(name)) {
3154879Ssam 		if (flag(v))
316954Sbill 			rtls(dope->rtdope);
317954Sbill 		else
318954Sbill 			printf("x - %s\n",name);
319954Sbill 
3204879Ssam 		if ((file = creat(name, 0666)) < 0)
3214879Ssam 			return(1);
322954Sbill 		count = dope->count;
323954Sbill 		startad = dope->startad;
324954Sbill 		for( ; count > 0 ; count -= 512) {
3254879Ssam 			lread(startad, 512, buff);
3264879Ssam 			write(file, buff, 512);
327954Sbill 			startad += 512;
328954Sbill 		}
329954Sbill 		close(file);
330954Sbill 		return(0);
331954Sbill 	}
332954Sbill 	return(1);
333954Sbill }
3344879Ssam 
335954Sbill rt_init()
336954Sbill {
337954Sbill 	static initized = 0;
3384879Ssam 	register char *de, *last;
3393346Swnj 	register i;
3403799Shickman 	int dirnum;
3413799Shickman 	char *mode;
3423799Shickman 	FILE *temp_floppydes;
343954Sbill 
3444879Ssam 	if (initized)
3454879Ssam 		return;
346954Sbill 	initized = 1;
3474879Ssam 	if (flag(c) || flag(d) || flag(r))
3483799Shickman 		mode = "r+";
349954Sbill 	else
3503799Shickman 		mode = "r";
3514879Ssam 	if ((temp_floppydes = fopen(defdev, mode)) == NULL) {
3523799Shickman 		perror(defdev);
3533356Swnj 		exit(1);
3543799Shickman 	} else
3553799Shickman 		floppydes = fileno(temp_floppydes);
3564879Ssam 	if (!flag(c)) {
3574879Ssam 		lread(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]);
3583346Swnj 		dirnum = rt_dir[0].rt_axhead.rt_numseg;
3593346Swnj 		if (dirnum > RT_DIRSIZE) {
3604879Ssam 			fprintf(stderr,"arff: too many directory segments\n");
3614879Ssam 			exit(1);
3623346Swnj 		}
3634879Ssam 		for (i = 1; i < dirnum; i++)
3644879Ssam 			lread((6+2*i)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[i]);
3653489Sroot 	} else
3663489Sroot 		dirnum = 1;
367954Sbill 
3683346Swnj 	rt_entsiz = 2*rt_dir[0].rt_axhead.rt_entpad + 14;
3693346Swnj 	rt_entsiz = 14;			/* assume rt_entpad = 0 ??? */
3703346Swnj 	rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz;
3713346Swnj 	rt_nleft = 0;
3723346Swnj 
3734879Ssam 	for (i = 0; i < dirnum; i++) {
3744879Ssam 		last = rt_last + i*2*RT_BLOCK;
3754879Ssam 		for (de = ((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz)
3764879Ssam 			if (rt(de)->rt_stat == RT_ESEG)
3774879Ssam 				break;
3784879Ssam 		rt_curend[i] = rt(de);
3794879Ssam 		rt_nleft += (last-de)/rt_entsiz;
380954Sbill 	}
381954Sbill }
382954Sbill 
383954Sbill static FLDOPE result;
3844879Ssam 
385954Sbill FLDOPE *
386954Sbill lookup(name)
3874879Ssam 	char *name;
388954Sbill {
389954Sbill 	unsigned short rname[3];
3904879Ssam 	register char *de, *last;
3913346Swnj 	int segnum;
392954Sbill 	register index;
393954Sbill 
394954Sbill 	srad50(name,rname);
395954Sbill 
3963356Swnj 	/*
397954Sbill 	 *  Search for name, accumulate blocks in index
398954Sbill 	 */
399954Sbill 	rt_init();
4004879Ssam 	for (segnum = 0; segnum != -1;
4014879Ssam 	     segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1)
4024879Ssam 	{
4034879Ssam 		index = 0;
4044879Ssam 		last = rt_last + segnum*2*RT_BLOCK;
4054879Ssam 		for (de=((char *)&rt_dir[segnum])+10;
4064879Ssam 		     rt(de)->rt_stat != RT_ESEG; de += rt_entsiz)
4074879Ssam 			switch(rt(de)->rt_stat) {
4084879Ssam 
4094879Ssam 			case RT_FILE:
4104879Ssam 			case RT_TEMP:
4114879Ssam 				if(samename(rname,rt(de)->rt_name)) {
4124879Ssam 					result.count = rt(de)->rt_len * 512;
4134879Ssam 					result.startad = 512*
4144879Ssam 						(rt_dir[segnum].rt_axhead.rt_stfile + index);
4154879Ssam 					result.rtdope = (struct rt_ent *) de;
4164879Ssam 					return(&result);
4174879Ssam 				}
4184879Ssam 
4194879Ssam 			case RT_NULL:
4204879Ssam 				index += rt(de)->rt_len;
4214879Ssam 			}
4223346Swnj         }
423954Sbill 	return((FLDOPE *) 0);
4244879Ssam 
425954Sbill }
4264879Ssam 
427954Sbill static
4284879Ssam samename(a, b)
4294879Ssam 	u_short a[], b[];
430954Sbill {
4314879Ssam 	return(*a == *b && a[1] == b[1] && a[2] == b[2] );
432954Sbill }
433954Sbill 
4344879Ssam rad50(cp, out)
4354879Ssam 	register u_char *cp;
4364879Ssam 	u_short *out;
437954Sbill {
4384879Ssam 	register index, temp;
439954Sbill 
4404879Ssam 	for (index = 0; *cp; index++) {
441954Sbill 		temp = Ain1 * table[*cp++];
4424879Ssam 		if (*cp!=0) {
443954Sbill 			temp += Ain2 * table[*cp++];
444954Sbill 			if(*cp!=0)
445954Sbill 				temp += table[*cp++];
446954Sbill 		}
447954Sbill 		out[index] = temp;
448954Sbill 	}
449954Sbill }
450954Sbill 
4514879Ssam #define reduce(x, p, q) (x = v[p/q], p %= q);
4524879Ssam 
4534879Ssam unrad50(count, in, cp)
4544879Ssam 	u_short *in;
4554879Ssam 	register char *cp;
456954Sbill {
4574879Ssam 	register i, temp;
4584879Ssam 	register u_char *v = (u_char *) val;
459954Sbill 
4604879Ssam 	for (i = 0; i < count; i++) {
461954Sbill 		temp = in[i];
4624879Ssam 		reduce(*cp++, temp, Ain1);
4634879Ssam 		reduce(*cp++, temp, Ain2);
4644879Ssam 		reduce(*cp++, temp, 1);
465954Sbill 	}
466954Sbill 	*cp=0;
467954Sbill }
468954Sbill 
4694879Ssam srad50(name, rname)
4704879Ssam 	register char *name;
4714879Ssam 	register u_short *rname;
472954Sbill {
4734879Ssam 	register index;
4744879Ssam 	register char *cp;
4754879Ssam 	char file[7], ext[4];
4764879Ssam 
4773356Swnj 	/*
478954Sbill 	 * Find end of pathname
479954Sbill 	 */
4804879Ssam 	for (cp = name; *cp++; )
4814879Ssam 		;
4824879Ssam 	while (cp >= name && *--cp != '/')
4834879Ssam 		;
484954Sbill 	cp++;
4853356Swnj 	/*
486954Sbill 	 * Change to rad50
487954Sbill 	 */
4884879Ssam 	for (index = 0; *cp; ) {
489954Sbill 		file[index++] = *cp++;
4904879Ssam 		if (*cp == '.') {
491954Sbill 			cp++;
492954Sbill 			break;
493954Sbill 		}
4944879Ssam 		if (index >= 6) {
495954Sbill 			break;
496954Sbill 		}
497954Sbill 	}
498954Sbill 	file[index] = 0;
4994879Ssam 	for (index = 0; *cp; ) {
500954Sbill 		ext[index++] = *cp++;
5014879Ssam 		if (*cp == '.' || index >= 3)
502954Sbill 			break;
503954Sbill 	}
504954Sbill 	ext[index]=0;
5054879Ssam 	rname[0] = rname[1] = rname[2] = 0;
5064879Ssam 	rad50((u_char *)file, rname);
5074879Ssam 	rad50((u_char *)ext, rname+2);
508954Sbill }
5094879Ssam 
5104879Ssam sunrad50(name, rname)
5114879Ssam 	u_short rname[];
5124879Ssam 	register char *name;
513954Sbill {
514954Sbill 	register char *cp, *cp2;
515954Sbill 	char ext[4];
516954Sbill 
5174879Ssam 	unrad50(2, rname, name);
5184879Ssam 	unrad50(1, rname + 2, ext);
5194879Ssam 	/*
5204879Ssam 	 * Jam name and extension together with a dot
5214879Ssam 	 * deleting white space
5224879Ssam 	 */
5234879Ssam 	for (cp = name; *cp++;)
5244879Ssam 		;
5254879Ssam 	--cp;
5264879Ssam 	while (*--cp == ' ' && cp >= name)
5274879Ssam 		;
5284879Ssam 	*++cp = '.';
5294879Ssam 	cp++;
5304879Ssam 	for (cp2 = ext; *cp2 != ' ' && cp2 < ext+3;)
531954Sbill 		*cp++ = *cp2++;
532954Sbill 	*cp=0;
5334879Ssam 	if (cp[-1] == '.')
5344879Ssam 		cp[-1] = 0;
535954Sbill }
536954Sbill 
537954Sbill static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789";
538954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789";
5394879Ssam 
540954Sbill static char table[256] = {
541954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
542954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
543954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
544954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
545954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
546954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 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, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
550954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
551954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
552954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
553954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
554954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
555954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
556954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 };
557954Sbill 
5584879Ssam /*
5594879Ssam  * Logical to physical adress translation
5604879Ssam  */
5614879Ssam long
5624879Ssam trans(logical)
5634879Ssam 	register int logical;
564954Sbill {
565954Sbill 	register int sector, bytes, track;
566954Sbill 
5674879Ssam 	logical += 26*128;
5684879Ssam 	bytes = (logical&127);
569954Sbill 	logical >>= 7;
5704879Ssam 	sector = logical%26;
571954Sbill 	if(sector >= 13)
5724879Ssam 		sector = sector*2+1;
573954Sbill 	else
574954Sbill 		sector *= 2;
5754879Ssam 	sector += 26 + ((track = (logical/26))-1)*6;
576954Sbill 	sector %= 26;
5774879Ssam 	return((((track*26)+sector) << 7) + bytes);
578954Sbill }
5794879Ssam 
5804879Ssam lread(startad, count, obuff)
5814879Ssam 	register startad, count;
5824879Ssam 	register char *obuff;
583954Sbill {
584954Sbill 	long trans();
585954Sbill 	extern floppydes;
5864879Ssam 	register int size = flag(m) ? 512 : 128;
5874879Ssam 
588954Sbill 	rt_init();
5894879Ssam 	while ((count -= size) >= 0) {
5904879Ssam 		lseek(floppydes, flag(m) ?
5914879Ssam 			(long)startad : trans(startad), 0);
5924879Ssam 		if (read(floppydes, obuff, size) != size)
5934879Ssam 			fprintf(stderr, "arff: read error block %d\n",
5944879Ssam 				startad/size);
5954879Ssam 		obuff += size;
5964879Ssam 		startad += size;
5974879Ssam 	}
598954Sbill }
5994879Ssam 
6004879Ssam lwrite(startad, count, obuff)
6014879Ssam 	register startad, count;
6024879Ssam 	register char *obuff;
603954Sbill {
604954Sbill 	long trans();
605954Sbill 	extern floppydes;
6064879Ssam 	register int size = flag(m) ? 512 : 128;
6074879Ssam 
608954Sbill 	rt_init();
6094879Ssam 	while ((count -= size) >= 0) {
6104879Ssam 		lseek(floppydes, flag(m) ?
6114879Ssam 			(long)startad : trans(startad), 0);
6124879Ssam 		if (write(floppydes, obuff, size) != size)
6134879Ssam 			fprintf(stderr, "arff: write error block %d\n",
6144879Ssam 				startad/size);
6154879Ssam 		obuff += size;
6164879Ssam 		startad += size;
6174879Ssam 	}
618954Sbill }
619954Sbill 
620954Sbill rcmd()
621954Sbill {
622954Sbill 	register int i;
623954Sbill 
624954Sbill 	rt_init();
6254879Ssam 	if (namc > 0)
6264879Ssam 		for (i = 0; i < namc; i++)
6274879Ssam 			if (rtr(namv[i]) == 0)
6284879Ssam 				namv[i] = 0;
629954Sbill }
630954Sbill 
631954Sbill rtr(name)
6324879Ssam 	char *name;
633954Sbill {
6344879Ssam 	register FLDOPE *dope;
6354879Ssam 	register struct rt_ent *de;
6364879Ssam 	struct stat buf;
6374879Ssam 	register struct stat *bufp = &buf;
6383346Swnj 	int segnum;
6393346Swnj 	register char *last;
640954Sbill 
6414879Ssam 	if (stat(name, bufp) < 0) {
6423489Sroot 		perror(name);
6433489Sroot 		return(-1);
6443489Sroot 	}
6454879Ssam 	if (dope = lookup(name)) {
646954Sbill 		/* can replace, no problem */
647954Sbill 		de = dope->rtdope;
6484879Ssam 		if (bufp->st_size <= (de->rt_len * 512))
649954Sbill 			printf("r - %s\n",name),
6504879Ssam 			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 {
6564879Ssam 		/* Search for vacant spot */
6574879Ssam 		for (segnum = 0; segnum != -1;
6584879Ssam 		     segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1)
6594879Ssam 		{
6604879Ssam 			last = rt_last + segnum*2*RT_BLOCK;
6614879Ssam 			for (de = rt_dir[segnum].rt_ents;
6624879Ssam 			    rt(de)->rt_stat != RT_ESEG; de++)
6634879Ssam 				if ((de)->rt_stat == RT_NULL) {
6644879Ssam 					if (bufp->st_size <= (de->rt_len*512)) {
6654879Ssam 						printf("a - %s\n",name),
6664879Ssam 						mkent(de, segnum, bufp,name);
6674879Ssam 						goto found;
6684879Ssam 					}
6694879Ssam 					continue;
670954Sbill 				}
6713346Swnj 	    }
6723489Sroot 	    printf("%s: no slot for file\n", name);
6733489Sroot 	    return (-1);
674954Sbill 	}
6754879Ssam 
6764879Ssam found:
6774879Ssam 	if (dope = lookup(name)) {
6784879Ssam 		toflop(name, bufp->st_size, dope);
6793489Sroot 		return (0);
680954Sbill 	}
6813489Sroot 	printf("%s: internal error, added then not found\n", name);
6823489Sroot 	return (-1);
6834879Ssam }
684954Sbill 
6854879Ssam mkent(de, segnum, bufp, name)
6864879Ssam 	register struct rt_ent *de;
6874879Ssam 	int segnum;
6884879Ssam 	register struct stat *bufp;
6894879Ssam 	char *name;
690954Sbill {
6914879Ssam 	struct tm *localtime();
6924879Ssam 	register struct tm *timp;
6934879Ssam 	register struct rt_ent *workp;
6944879Ssam 	int count;
695954Sbill 
696954Sbill 	count = (((bufp->st_size -1) >>9) + 1);
6974879Ssam 	/* make sure there is room */
6984879Ssam 	if (de->rt_len == count)
699954Sbill 		goto overwrite;
7004879Ssam 	if ((char *)rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) {
7014879Ssam 		/* no entries left on segment */
7024879Ssam 		if (flag(o))
703954Sbill 			goto overwrite;
7043346Swnj 		fprintf(stderr,"Directory segment #%d full on  %s\n",segnum+1,
7054879Ssam 			defdev);
706954Sbill 		exit(1);
707954Sbill 	}
7084879Ssam 	/* copy directory entries up */
7094879Ssam 	for (workp = rt_curend[segnum]+1; workp > de; workp--)
710954Sbill 		*workp = workp[-1];
711954Sbill 	de[1].rt_len -= count;
712954Sbill 	de->rt_len = count;
7133346Swnj 	rt_curend[segnum]++;
714954Sbill 	rt_nleft--;
7154879Ssam 
716954Sbill overwrite:
717954Sbill 	srad50(name,de->rt_name);
718954Sbill 	timp = localtime(&bufp->st_mtime);
719*7320Swnj 	de->rt_date.rt_dy = timp->tm_mday;
720954Sbill 	de->rt_date.rt_mo = timp->tm_mon + 1;
721954Sbill 	de->rt_date.rt_yr = timp->tm_year - 72;
722954Sbill 	de->rt_stat = RT_FILE;
723954Sbill 	de->rt_pad = 0;
724954Sbill 	de->rt_chan = 0;
725954Sbill 	de->rt_job = 0;
7264879Ssam 	lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[segnum]);
727954Sbill }
728954Sbill 
7294879Ssam toflop(name, ocount, dope)
7304879Ssam 	char *name;
7314879Ssam 	register FLDOPE *dope;
7324879Ssam 	long ocount;
733954Sbill {
734954Sbill 	register file, n, startad = dope->startad, count = ocount;
735954Sbill 	char buff[512];
736954Sbill 
7374879Ssam 	file = open(name, 0);
7384879Ssam 	if (file < 0) {
7394879Ssam 		fprintf(stderr, "arff: couldn't open %s\n",name);
7404879Ssam 		exit(1);
7414879Ssam 	}
742954Sbill 	for( ; count >= 512; count -= 512) {
7434879Ssam 		read(file, buff, 512);
7444879Ssam 		lwrite(startad, 512, buff);
745954Sbill 		startad += 512;
746954Sbill 	}
7474879Ssam 	read(file, buff, count);
748954Sbill 	close(file);
7494879Ssam 	if (count <= 0)
7504879Ssam 		return;
7514879Ssam 	for (n = count; n < 512; n ++)
7524879Ssam 		buff[n] = 0;
7534879Ssam 	lwrite(startad, 512, buff);
7544879Ssam 	count = (dope->rtdope->rt_len*512-ocount)/512 ;
7554879Ssam 	if (count <= 0)
7564879Ssam 		return;
7574879Ssam 	for ( ; count > 0 ; count--) {
758954Sbill 		startad += 512;
7594879Ssam 		lwrite(startad, 512, zeroes);
760954Sbill 	}
7614879Ssam }
762954Sbill 
763954Sbill dcmd()
764954Sbill {
765954Sbill 	register int i;
766954Sbill 
767954Sbill 	rt_init();
7684879Ssam 	if (namc)
7694879Ssam 		for (i = 0; i < namc; i++)
7704879Ssam 			if (rtk(namv[i])==0)
7714879Ssam 				namv[i]=0;
7724879Ssam 	if (dirdirty)
773954Sbill 		scrunch();
774954Sbill }
7754879Ssam 
776954Sbill rtk(name)
7774879Ssam 	char *name;
778954Sbill {
779954Sbill 	register FLDOPE *dope;
780954Sbill 	register struct rt_ent *de;
781954Sbill 	FLDOPE *lookup();
782954Sbill 
7834879Ssam 	if (dope = lookup(name)) {
784954Sbill 		printf("d - %s\n",name);
785954Sbill 		de = dope->rtdope;
786954Sbill 		de->rt_stat = RT_NULL;
787954Sbill 		de->rt_name[0] = 0;
788954Sbill 		de->rt_name[1] = 0;
789954Sbill 		de->rt_name[2] = 0;
7904879Ssam 		* ((u_short *)&(de->rt_date)) = 0;
791954Sbill 		dirdirty = 1;
792954Sbill 		return(0);
793954Sbill 	}
794954Sbill 	return(1);
795954Sbill }
7964879Ssam 
7974879Ssam scrunch()
7984879Ssam {
7993346Swnj 	register struct rt_ent *de , *workp;
8003346Swnj 	register segnum;
8014879Ssam 
8024879Ssam 	for (segnum = 0; segnum != -1;
8033346Swnj 	     segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) {
8044879Ssam 		dirdirty = 0;
8054879Ssam 		for (de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++)
8064879Ssam 			if (de->rt_stat == RT_NULL && de[1].rt_stat == RT_NULL) {
8074879Ssam 				(de+1)->rt_len += de->rt_len;
8084879Ssam 				for (workp = de; workp < rt_curend[segnum]; workp++)
8094879Ssam 					*workp = workp[1];
8104879Ssam 				de--;
8114879Ssam 				rt_curend[segnum]--;
8124879Ssam 				rt_nleft++;
8134879Ssam 				dirdirty = 1;
8144879Ssam 			}
8154879Ssam 		if (dirdirty)
8164879Ssam 			lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK,
8174879Ssam 				(char *)&rt_dir[segnum]);
818954Sbill 	}
819954Sbill }
820