xref: /csrg-svn/old/arff/arff.c (revision 9877)
1*9877Ssam #ifndef lint
2*9877Ssam static	char sccsid[] = "@(#)arff.c	4.12 (Berkeley) 82/12/23";
3*9877Ssam #endif
44879Ssam 
5954Sbill #include <sys/types.h>
6954Sbill #include <sys/stat.h>
7954Sbill #include <time.h>
8954Sbill #include <signal.h>
9954Sbill #include <stdio.h>
104879Ssam 
11954Sbill #define dbprintf printf
124879Ssam 
13954Sbill struct rt_dat {
144879Ssam 	u_short	rt_yr:5;	/* year-1972 */
154879Ssam 	u_short	rt_dy:5;	/* day */
164879Ssam 	u_short	rt_mo:5;	/* month */
17954Sbill };
184879Ssam 
19954Sbill struct	rt_axent {
20954Sbill 	char	rt_sent[14];
21954Sbill };
22954Sbill 
23954Sbill struct rt_ent {
244879Ssam 	char	rt_pad;		/* unusued */
254879Ssam 	char	rt_stat;	/* type of entry, or end of seg */
264879Ssam 	u_short	rt_name[3];	/* name, 3 words in rad50 form */
277319Swnj 	u_short	rt_len;		/* length of file */
284879Ssam 	char	rt_chan;	/* only used in temporary files */
294879Ssam 	char	rt_job;		/* only used in temporary files */
30*9877Ssam 	struct	rt_dat rt_date;	/* creation date */
31954Sbill };
324879Ssam 
334879Ssam #define RT_TEMP		1
344879Ssam #define RT_NULL		2
354879Ssam #define RT_FILE		4
364879Ssam #define RT_ESEG		8
374879Ssam 
384879Ssam #define RT_BLOCK	512	/* block size */
394879Ssam #define RT_DIRSIZE	31	/* max # of directory segments */
404879Ssam 
41954Sbill struct rt_head {
424879Ssam 	short	rt_numseg;	/* # of segments available */
434879Ssam 	short	rt_nxtseg;	/* # of next logical segment */
444879Ssam 	short	rt_lstseg;	/* highest seg currently open */
454879Ssam 	u_short	rt_entpad;	/* extra words/directory entry */
464879Ssam 	short	rt_stfile;	/* block # where files begin */
47954Sbill };
484879Ssam 
49954Sbill struct	rt_dir {
50954Sbill 	struct rt_head	rt_axhead;
51954Sbill 	struct rt_ent	rt_ents[72];
524879Ssam 	char		_dirpad[6];
53954Sbill };
544879Ssam 
55954Sbill typedef struct fldope {
56954Sbill 	int	startad;
57954Sbill 	int	count;
58954Sbill struct	rt_ent	*rtdope;
59954Sbill } FLDOPE;
604879Ssam 
61954Sbill FLDOPE *lookup();
624879Ssam 
63*9877Ssam #define	rt(p)	((struct rt_ent *) p )
64*9877Ssam #define	Ain1	03100
65*9877Ssam #define	Ain2	050
66*9877Ssam #define	flag(c)	(flg[('c') - 'a'])
67954Sbill 
68*9877Ssam char	*man = "rxtd";
69*9877Ssam char	zeroes[512];
70954Sbill 
71954Sbill extern char *val;
72954Sbill extern char table[256];
734879Ssam struct rt_dir rt_dir[RT_DIRSIZE] = {
74*9877Ssam 	{ 4, 0, 1, 0, 14 },
75*9877Ssam 	{ { 0, RT_NULL, { 0, 0, 0 }, 494, 0 },
76*9877Ssam 	  { 0, RT_ESEG } }
774879Ssam };
78954Sbill 
794879Ssam int	rt_entsiz;
804879Ssam int	rt_nleft;
814879Ssam struct rt_ent *rt_curend[RT_DIRSIZE];
824879Ssam int	floppydes;
834879Ssam int	dirdirty;
844879Ssam char	*rt_last;
854879Ssam char	*defdev = "/dev/floppy";
86954Sbill 
874879Ssam char *opt = "vf";
884879Ssam 
89954Sbill int	signum[] = {SIGHUP, SIGINT, SIGQUIT, 0};
904879Ssam extern long lseek();
914879Ssam int	rcmd(), dcmd(), xcmd(), tcmd();
924879Ssam 
93954Sbill int	(*comfun)();
94954Sbill char	flg[26];
95954Sbill char	**namv;
96954Sbill int	namc;
97954Sbill int	file;
98954Sbill 
99954Sbill main(argc, argv)
1004879Ssam 	char *argv[];
101954Sbill {
102954Sbill 	register char *cp;
103954Sbill 
1044879Ssam 	if (argc < 2)
105954Sbill 		usage();
106954Sbill 	cp = argv[1];
1074879Ssam 	for (cp = argv[1]; *cp; cp++)
1084879Ssam 		switch (*cp) {
109954Sbill 
1104879Ssam 		case 'm':
1114879Ssam 		case 'v':
1124879Ssam 		case 'u':
1134879Ssam 		case 'w':
1144879Ssam 			flg[*cp-'a']++;
1154879Ssam 			continue;
1164879Ssam 		case 'c':
1174879Ssam 			{
1184879Ssam #define SURE	"Last chance before clobbering floppy?"
1194879Ssam 				int tty;
1204879Ssam 				char response[128];
121954Sbill 
1224879Ssam 				tty = open("/dev/tty", 2);
1234879Ssam 				write(tty, SURE, sizeof(SURE));
1244879Ssam 				read(tty, response, sizeof(response));
1254879Ssam 				if (*response != 'y')
1264879Ssam 					exit(50);
1274879Ssam 				flag(c)++;
1284879Ssam 				close(tty);
1294879Ssam 			}
1304879Ssam 			dirdirty++;
1314879Ssam 			continue;
132954Sbill 
1334879Ssam 		case 'r':
1344879Ssam 			setcom(rcmd);
1354879Ssam 			flag(r)++;
1364879Ssam 			continue;
137954Sbill 
1384879Ssam 		case 'd':
1394879Ssam 			setcom(dcmd);
1404879Ssam 			flag(d)++;
1414879Ssam 			continue;
142954Sbill 
1434879Ssam 		case 'x':
1444879Ssam 			setcom(xcmd);
1454879Ssam 			continue;
146954Sbill 
1474879Ssam 		case 't':
1484879Ssam 			setcom(tcmd);
1494879Ssam 			continue;
150954Sbill 
1514879Ssam 		case 'f':
1524879Ssam 			defdev = argv[2];
1534879Ssam 			argv++;
1544879Ssam 			argc--;
1554879Ssam 			continue;
1564879Ssam 
1574879Ssam 		default:
1584879Ssam 			fprintf(stderr, "arff: bad option `%c'\n", *cp);
1594879Ssam 			exit(1);
1604879Ssam 		}
1614879Ssam 
162954Sbill 	namv = argv+2;
163954Sbill 	namc = argc-2;
1644879Ssam 	if (comfun == 0) {
1654879Ssam 		if (flag(u) == 0) {
1664879Ssam 			fprintf(stderr, "arff: one of [%s] must be specified\n",
1674879Ssam 				man);
168954Sbill 			exit(1);
169954Sbill 		}
170954Sbill 		setcom(rcmd);
171954Sbill 	}
172954Sbill 	(*comfun)();
173954Sbill 	exit(notfound());
174954Sbill }
175954Sbill 
176954Sbill setcom(fun)
1774879Ssam 	int (*fun)();
178954Sbill {
1794879Ssam 	if (comfun != 0) {
180954Sbill 		fprintf(stderr, "arff: only one of [%s] allowed\n", man);
181954Sbill 		exit(1);
182954Sbill 	}
183954Sbill 	comfun = fun;
184954Sbill }
185954Sbill 
186954Sbill usage()
187954Sbill {
1883356Swnj 	fprintf(stderr, "usage: ar [%s][%s] archive files ...\n", opt, man);
189954Sbill 	exit(1);
190954Sbill }
191954Sbill 
192954Sbill notfound()
193954Sbill {
1944879Ssam 	register i, n = 0;
195954Sbill 
1964879Ssam 	for (i = 0; i < namc; i++)
1974879Ssam 		if (namv[i]) {
198954Sbill 			fprintf(stderr, "arff: %s not found\n", namv[i]);
199954Sbill 			n++;
200954Sbill 		}
201*9877Ssam 	return (n);
202954Sbill }
203954Sbill 
204954Sbill mesg(c)
205954Sbill {
2064879Ssam 	if (flag(v))
2074879Ssam 		if (c != 'c' || flag(v) > 1)
208954Sbill 			printf("%c - %s\n", c, file);
209954Sbill }
210954Sbill 
211954Sbill tcmd()
212954Sbill {
2134879Ssam 	register char *de, *last;
214954Sbill 	FLDOPE *lookup(), *dope;
2154879Ssam 	int segnum, nleft;
2164879Ssam 	register i;
217954Sbill 	register struct rt_ent *rde;
218954Sbill 
219954Sbill 	rt_init();
220*9877Ssam 	if (namc != 0) {
2214879Ssam 		for (i = 0; i < namc; i++)
2224879Ssam 			if (dope = lookup(namv[i])) {
223954Sbill 				rde = dope->rtdope;
224954Sbill 				rtls(rde);
225954Sbill 				namv[i] = 0;
226954Sbill 			}
227*9877Ssam 		return;
228*9877Ssam 	}
229*9877Ssam 	for (segnum = 0; segnum != -1;
230*9877Ssam 	  segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) {
231*9877Ssam 		last = rt_last + segnum*2*RT_BLOCK;
232*9877Ssam 		for (de = ((char *)&rt_dir[segnum])+10; de <= last;
233*9877Ssam 		    de += rt_entsiz)
234*9877Ssam 			if (rtls(rt(de))) {
235*9877Ssam 				nleft = (last-de)/rt_entsiz;
236*9877Ssam #define ENTRIES "\n%d entries remaining in directory segment %d.\n"
237*9877Ssam 				printf(ENTRIES, nleft, segnum+1);
238*9877Ssam 				break;
239*9877Ssam 			}
240*9877Ssam 	}
241954Sbill }
2424879Ssam 
243954Sbill rtls(de)
2444879Ssam 	register struct rt_ent *de;
245954Sbill {
2464879Ssam 	int month, day, year;
247954Sbill 	char name[12], ext[4];
248954Sbill 
2494879Ssam 	switch (de->rt_stat) {
2504879Ssam 
2514879Ssam 	case RT_TEMP:
2524879Ssam 		if (flag(v))
253954Sbill 			printf("Tempfile:\n");
2544879Ssam 		/* fall thru...*/
255954Sbill 
2564879Ssam 	case RT_FILE:
2574879Ssam 		if (!flag(v)) {
2584879Ssam 			sunrad50(name, de->rt_name);
2594879Ssam 			printf("%s\n", name);
260954Sbill 			break;
261954Sbill 		}
2624879Ssam 		unrad50(2, de->rt_name, name);
2634879Ssam 		unrad50(1, &(de->rt_name[2]), ext);
2644879Ssam 		day = de->rt_date.rt_dy;
2654879Ssam 		year = de->rt_date.rt_yr+72;
2664879Ssam 		month = de->rt_date.rt_mo;
2674879Ssam 		printf("%6.6s  %3.3s	%02d/%02d/%02d	%d\n",name,
2684879Ssam 			ext, month, day, year, de->rt_len);
2694879Ssam 		break;
270954Sbill 
2714879Ssam 	case RT_NULL:
2724879Ssam 		printf("%-25.9s	%d\n","<UNUSED>", de->rt_len);
2734879Ssam 		break;
274954Sbill 
2754879Ssam 	case RT_ESEG:
276*9877Ssam 		return (1);
277954Sbill 	}
278*9877Ssam 	return (0);
279954Sbill }
2804879Ssam 
281954Sbill xcmd()
282954Sbill {
2834879Ssam 	register char *de, *last;
2843346Swnj 	int segnum;
285954Sbill 	char name[12];
286954Sbill 	register int i;
287954Sbill 
288954Sbill 	rt_init();
289*9877Ssam 	if (namc != 0) {
2904879Ssam 		for (i = 0; i < namc; i++)
2914879Ssam 			if (rtx(namv[i]) == 0)
2924879Ssam 				namv[i] = 0;
293*9877Ssam 		return;
294*9877Ssam 	}
295*9877Ssam 	for (segnum = 0; segnum != -1;
296*9877Ssam 	     segnum = rt_dir[segnum].rt_axhead.rt_nxtseg-1)
297*9877Ssam 		for (last = rt_last+(segnum*2*RT_BLOCK),
298*9877Ssam 		     de = ((char *)&rt_dir[segnum])+10; de <= last;
299*9877Ssam 		     de += rt_entsiz)
300*9877Ssam 			switch (rt(de)->rt_stat) {
301*9877Ssam 
302*9877Ssam 			case RT_ESEG:
303*9877Ssam 				return;
304*9877Ssam 
305*9877Ssam 			case RT_TEMP:
306*9877Ssam 			case RT_FILE:
307*9877Ssam 				sunrad50(name,rt(de)->rt_name);
308*9877Ssam 				rtx(name);
309*9877Ssam 
310*9877Ssam 			case RT_NULL:
311*9877Ssam 				break;
312*9877Ssam 			}
313954Sbill }
3144879Ssam 
315954Sbill rtx(name)
3164879Ssam 	char *name;
317954Sbill {
318954Sbill 	register FLDOPE *dope;
319954Sbill 	FLDOPE *lookup();
320954Sbill 	register startad, count;
3214879Ssam 	int file;
3224879Ssam 	char buff[512];
323954Sbill 
324954Sbill 
3254879Ssam 	if (dope = lookup(name)) {
3264879Ssam 		if (flag(v))
327954Sbill 			rtls(dope->rtdope);
328954Sbill 		else
329954Sbill 			printf("x - %s\n",name);
330954Sbill 
3314879Ssam 		if ((file = creat(name, 0666)) < 0)
332*9877Ssam 			return (1);
333954Sbill 		count = dope->count;
334954Sbill 		startad = dope->startad;
335954Sbill 		for( ; count > 0 ; count -= 512) {
3364879Ssam 			lread(startad, 512, buff);
3374879Ssam 			write(file, buff, 512);
338954Sbill 			startad += 512;
339954Sbill 		}
340954Sbill 		close(file);
341*9877Ssam 		return (0);
342954Sbill 	}
343*9877Ssam 	return (1);
344954Sbill }
3454879Ssam 
346954Sbill rt_init()
347954Sbill {
348954Sbill 	static initized = 0;
3494879Ssam 	register char *de, *last;
3503346Swnj 	register i;
3513799Shickman 	int dirnum;
3523799Shickman 	char *mode;
3533799Shickman 	FILE *temp_floppydes;
354954Sbill 
3554879Ssam 	if (initized)
3564879Ssam 		return;
357954Sbill 	initized = 1;
3584879Ssam 	if (flag(c) || flag(d) || flag(r))
3593799Shickman 		mode = "r+";
360954Sbill 	else
3613799Shickman 		mode = "r";
3624879Ssam 	if ((temp_floppydes = fopen(defdev, mode)) == NULL) {
3633799Shickman 		perror(defdev);
3643356Swnj 		exit(1);
3653799Shickman 	} else
3663799Shickman 		floppydes = fileno(temp_floppydes);
3674879Ssam 	if (!flag(c)) {
3684879Ssam 		lread(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]);
3693346Swnj 		dirnum = rt_dir[0].rt_axhead.rt_numseg;
3703346Swnj 		if (dirnum > RT_DIRSIZE) {
3714879Ssam 			fprintf(stderr,"arff: too many directory segments\n");
3724879Ssam 			exit(1);
3733346Swnj 		}
3744879Ssam 		for (i = 1; i < dirnum; i++)
3754879Ssam 			lread((6+2*i)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[i]);
3763489Sroot 	} else
3773489Sroot 		dirnum = 1;
378954Sbill 
3793346Swnj 	rt_entsiz = 2*rt_dir[0].rt_axhead.rt_entpad + 14;
3803346Swnj 	rt_entsiz = 14;			/* assume rt_entpad = 0 ??? */
3813346Swnj 	rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz;
3823346Swnj 	rt_nleft = 0;
3833346Swnj 
3844879Ssam 	for (i = 0; i < dirnum; i++) {
3854879Ssam 		last = rt_last + i*2*RT_BLOCK;
3864879Ssam 		for (de = ((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz)
3874879Ssam 			if (rt(de)->rt_stat == RT_ESEG)
3884879Ssam 				break;
3894879Ssam 		rt_curend[i] = rt(de);
3904879Ssam 		rt_nleft += (last-de)/rt_entsiz;
391954Sbill 	}
392954Sbill }
393954Sbill 
394954Sbill static FLDOPE result;
3954879Ssam 
396954Sbill FLDOPE *
397954Sbill lookup(name)
3984879Ssam 	char *name;
399954Sbill {
400954Sbill 	unsigned short rname[3];
4014879Ssam 	register char *de, *last;
4023346Swnj 	int segnum;
403954Sbill 	register index;
404954Sbill 
405954Sbill 	srad50(name,rname);
406954Sbill 
4073356Swnj 	/*
408954Sbill 	 *  Search for name, accumulate blocks in index
409954Sbill 	 */
410954Sbill 	rt_init();
4114879Ssam 	for (segnum = 0; segnum != -1;
4124879Ssam 	     segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1)
4134879Ssam 	{
4144879Ssam 		index = 0;
4154879Ssam 		last = rt_last + segnum*2*RT_BLOCK;
4164879Ssam 		for (de=((char *)&rt_dir[segnum])+10;
4174879Ssam 		     rt(de)->rt_stat != RT_ESEG; de += rt_entsiz)
4184879Ssam 			switch(rt(de)->rt_stat) {
4194879Ssam 
4204879Ssam 			case RT_FILE:
4214879Ssam 			case RT_TEMP:
4224879Ssam 				if(samename(rname,rt(de)->rt_name)) {
4234879Ssam 					result.count = rt(de)->rt_len * 512;
4244879Ssam 					result.startad = 512*
4254879Ssam 						(rt_dir[segnum].rt_axhead.rt_stfile + index);
4264879Ssam 					result.rtdope = (struct rt_ent *) de;
427*9877Ssam 					return (&result);
4284879Ssam 				}
4294879Ssam 
4304879Ssam 			case RT_NULL:
4314879Ssam 				index += rt(de)->rt_len;
4324879Ssam 			}
4333346Swnj         }
434*9877Ssam 	return ((FLDOPE *) 0);
4354879Ssam 
436954Sbill }
4374879Ssam 
438954Sbill static
4394879Ssam samename(a, b)
4404879Ssam 	u_short a[], b[];
441954Sbill {
442*9877Ssam 	return (*a == *b && a[1] == b[1] && a[2] == b[2] );
443954Sbill }
444954Sbill 
4454879Ssam rad50(cp, out)
4464879Ssam 	register u_char *cp;
4474879Ssam 	u_short *out;
448954Sbill {
4494879Ssam 	register index, temp;
450954Sbill 
4514879Ssam 	for (index = 0; *cp; index++) {
452954Sbill 		temp = Ain1 * table[*cp++];
4534879Ssam 		if (*cp!=0) {
454954Sbill 			temp += Ain2 * table[*cp++];
455954Sbill 			if(*cp!=0)
456954Sbill 				temp += table[*cp++];
457954Sbill 		}
458954Sbill 		out[index] = temp;
459954Sbill 	}
460954Sbill }
461954Sbill 
4624879Ssam #define reduce(x, p, q) (x = v[p/q], p %= q);
4634879Ssam 
4644879Ssam unrad50(count, in, cp)
4654879Ssam 	u_short *in;
4664879Ssam 	register char *cp;
467954Sbill {
4684879Ssam 	register i, temp;
4694879Ssam 	register u_char *v = (u_char *) val;
470954Sbill 
4714879Ssam 	for (i = 0; i < count; i++) {
472954Sbill 		temp = in[i];
4734879Ssam 		reduce(*cp++, temp, Ain1);
4744879Ssam 		reduce(*cp++, temp, Ain2);
4754879Ssam 		reduce(*cp++, temp, 1);
476954Sbill 	}
477954Sbill 	*cp=0;
478954Sbill }
479954Sbill 
4804879Ssam srad50(name, rname)
4814879Ssam 	register char *name;
4824879Ssam 	register u_short *rname;
483954Sbill {
4844879Ssam 	register index;
4854879Ssam 	register char *cp;
4864879Ssam 	char file[7], ext[4];
4874879Ssam 
4883356Swnj 	/*
489954Sbill 	 * Find end of pathname
490954Sbill 	 */
4914879Ssam 	for (cp = name; *cp++; )
4924879Ssam 		;
4934879Ssam 	while (cp >= name && *--cp != '/')
4944879Ssam 		;
495954Sbill 	cp++;
4963356Swnj 	/*
497954Sbill 	 * Change to rad50
498954Sbill 	 */
4994879Ssam 	for (index = 0; *cp; ) {
500954Sbill 		file[index++] = *cp++;
5014879Ssam 		if (*cp == '.') {
502954Sbill 			cp++;
503954Sbill 			break;
504954Sbill 		}
5054879Ssam 		if (index >= 6) {
506954Sbill 			break;
507954Sbill 		}
508954Sbill 	}
509954Sbill 	file[index] = 0;
5104879Ssam 	for (index = 0; *cp; ) {
511954Sbill 		ext[index++] = *cp++;
5124879Ssam 		if (*cp == '.' || index >= 3)
513954Sbill 			break;
514954Sbill 	}
515954Sbill 	ext[index]=0;
5164879Ssam 	rname[0] = rname[1] = rname[2] = 0;
5174879Ssam 	rad50((u_char *)file, rname);
5184879Ssam 	rad50((u_char *)ext, rname+2);
519954Sbill }
5204879Ssam 
5214879Ssam sunrad50(name, rname)
5224879Ssam 	u_short rname[];
5234879Ssam 	register char *name;
524954Sbill {
525954Sbill 	register char *cp, *cp2;
526954Sbill 	char ext[4];
527954Sbill 
5284879Ssam 	unrad50(2, rname, name);
5294879Ssam 	unrad50(1, rname + 2, ext);
5304879Ssam 	/*
5314879Ssam 	 * Jam name and extension together with a dot
5324879Ssam 	 * deleting white space
5334879Ssam 	 */
5344879Ssam 	for (cp = name; *cp++;)
5354879Ssam 		;
5364879Ssam 	--cp;
5374879Ssam 	while (*--cp == ' ' && cp >= name)
5384879Ssam 		;
5394879Ssam 	*++cp = '.';
5404879Ssam 	cp++;
5414879Ssam 	for (cp2 = ext; *cp2 != ' ' && cp2 < ext+3;)
542954Sbill 		*cp++ = *cp2++;
543954Sbill 	*cp=0;
5444879Ssam 	if (cp[-1] == '.')
5454879Ssam 		cp[-1] = 0;
546954Sbill }
547954Sbill 
548954Sbill static char *oval = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$.@0123456789";
549954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789";
5504879Ssam 
551954Sbill static char table[256] = {
552954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
553954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
554954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
555954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
556954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
557954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
558954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
559954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
560954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
561954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
562954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
563954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
564954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
565954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
566954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
567954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 };
568954Sbill 
5694879Ssam /*
5704879Ssam  * Logical to physical adress translation
5714879Ssam  */
5724879Ssam long
5734879Ssam trans(logical)
5744879Ssam 	register int logical;
575954Sbill {
576954Sbill 	register int sector, bytes, track;
577954Sbill 
5784879Ssam 	logical += 26*128;
5794879Ssam 	bytes = (logical&127);
580954Sbill 	logical >>= 7;
5814879Ssam 	sector = logical%26;
582954Sbill 	if(sector >= 13)
5834879Ssam 		sector = sector*2+1;
584954Sbill 	else
585954Sbill 		sector *= 2;
5864879Ssam 	sector += 26 + ((track = (logical/26))-1)*6;
587954Sbill 	sector %= 26;
588*9877Ssam 	return ((((track*26)+sector) << 7) + bytes);
589954Sbill }
5904879Ssam 
5914879Ssam lread(startad, count, obuff)
5924879Ssam 	register startad, count;
5934879Ssam 	register char *obuff;
594954Sbill {
595954Sbill 	long trans();
596954Sbill 	extern floppydes;
5974879Ssam 	register int size = flag(m) ? 512 : 128;
5984879Ssam 
599954Sbill 	rt_init();
6004879Ssam 	while ((count -= size) >= 0) {
6014879Ssam 		lseek(floppydes, flag(m) ?
6024879Ssam 			(long)startad : trans(startad), 0);
6034879Ssam 		if (read(floppydes, obuff, size) != size)
6044879Ssam 			fprintf(stderr, "arff: read error block %d\n",
6054879Ssam 				startad/size);
6064879Ssam 		obuff += size;
6074879Ssam 		startad += size;
6084879Ssam 	}
609954Sbill }
6104879Ssam 
6114879Ssam lwrite(startad, count, obuff)
6124879Ssam 	register startad, count;
6134879Ssam 	register char *obuff;
614954Sbill {
615954Sbill 	long trans();
616954Sbill 	extern floppydes;
6174879Ssam 	register int size = flag(m) ? 512 : 128;
6184879Ssam 
619954Sbill 	rt_init();
6204879Ssam 	while ((count -= size) >= 0) {
6214879Ssam 		lseek(floppydes, flag(m) ?
6224879Ssam 			(long)startad : trans(startad), 0);
6234879Ssam 		if (write(floppydes, obuff, size) != size)
6244879Ssam 			fprintf(stderr, "arff: write error block %d\n",
6254879Ssam 				startad/size);
6264879Ssam 		obuff += size;
6274879Ssam 		startad += size;
6284879Ssam 	}
629954Sbill }
630954Sbill 
631954Sbill rcmd()
632954Sbill {
633954Sbill 	register int i;
634954Sbill 
635954Sbill 	rt_init();
6364879Ssam 	if (namc > 0)
6374879Ssam 		for (i = 0; i < namc; i++)
6384879Ssam 			if (rtr(namv[i]) == 0)
6394879Ssam 				namv[i] = 0;
640954Sbill }
641954Sbill 
642954Sbill rtr(name)
6434879Ssam 	char *name;
644954Sbill {
6454879Ssam 	register FLDOPE *dope;
6464879Ssam 	register struct rt_ent *de;
6474879Ssam 	struct stat buf;
6484879Ssam 	register struct stat *bufp = &buf;
6493346Swnj 	int segnum;
6503346Swnj 	register char *last;
651954Sbill 
6524879Ssam 	if (stat(name, bufp) < 0) {
6533489Sroot 		perror(name);
654*9877Ssam 		return (-1);
6553489Sroot 	}
6564879Ssam 	if (dope = lookup(name)) {
657954Sbill 		/* can replace, no problem */
658954Sbill 		de = dope->rtdope;
6594879Ssam 		if (bufp->st_size <= (de->rt_len * 512))
660954Sbill 			printf("r - %s\n",name),
6614879Ssam 			toflop(name, bufp->st_size, dope);
662954Sbill 		else {
663*9877Ssam 			fprintf(stderr,
664*9877Ssam 			  "%s will not fit in currently used file on floppy\n",
665*9877Ssam 			  name);
666*9877Ssam 			return (-1);
667954Sbill 		}
668*9877Ssam 		goto found;
669*9877Ssam 	}
670*9877Ssam 	/*
671*9877Ssam 	 * Search for vacant spot
672*9877Ssam 	 */
673*9877Ssam 	for (segnum = 0; segnum != -1;
674*9877Ssam 	     segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1)
675*9877Ssam 	{
676*9877Ssam 		last = rt_last + segnum*2*RT_BLOCK;
677*9877Ssam 		for (de = rt_dir[segnum].rt_ents;
678*9877Ssam 		    rt(de)->rt_stat != RT_ESEG; de++)
679*9877Ssam 			if ((de)->rt_stat == RT_NULL) {
680*9877Ssam 				if (bufp->st_size <= (de->rt_len*512)) {
681*9877Ssam 					printf("a - %s\n",name),
682*9877Ssam 					mkent(de, segnum, bufp,name);
683*9877Ssam 					goto found;
684954Sbill 				}
685*9877Ssam 				continue;
686*9877Ssam 			}
687954Sbill 	}
688*9877Ssam 	printf("%s: no slot for file\n", name);
689*9877Ssam 	return (-1);
6904879Ssam 
6914879Ssam found:
6924879Ssam 	if (dope = lookup(name)) {
6934879Ssam 		toflop(name, bufp->st_size, dope);
6943489Sroot 		return (0);
695954Sbill 	}
6963489Sroot 	printf("%s: internal error, added then not found\n", name);
6973489Sroot 	return (-1);
6984879Ssam }
699954Sbill 
7004879Ssam mkent(de, segnum, bufp, name)
7014879Ssam 	register struct rt_ent *de;
7024879Ssam 	int segnum;
7034879Ssam 	register struct stat *bufp;
7044879Ssam 	char *name;
705954Sbill {
7064879Ssam 	struct tm *localtime();
7074879Ssam 	register struct tm *timp;
7084879Ssam 	register struct rt_ent *workp;
7094879Ssam 	int count;
710954Sbill 
711954Sbill 	count = (((bufp->st_size -1) >>9) + 1);
7124879Ssam 	/* make sure there is room */
7134879Ssam 	if (de->rt_len == count)
714954Sbill 		goto overwrite;
7154879Ssam 	if ((char *)rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) {
7164879Ssam 		/* no entries left on segment */
7174879Ssam 		if (flag(o))
718954Sbill 			goto overwrite;
719*9877Ssam 		fprintf(stderr, "Directory segment #%d full on  %s\n",
720*9877Ssam 			segnum+1, defdev);
721954Sbill 		exit(1);
722954Sbill 	}
7234879Ssam 	/* copy directory entries up */
7244879Ssam 	for (workp = rt_curend[segnum]+1; workp > de; workp--)
725954Sbill 		*workp = workp[-1];
726954Sbill 	de[1].rt_len -= count;
727954Sbill 	de->rt_len = count;
7283346Swnj 	rt_curend[segnum]++;
729954Sbill 	rt_nleft--;
7304879Ssam 
731954Sbill overwrite:
732954Sbill 	srad50(name,de->rt_name);
733954Sbill 	timp = localtime(&bufp->st_mtime);
7347320Swnj 	de->rt_date.rt_dy = timp->tm_mday;
735954Sbill 	de->rt_date.rt_mo = timp->tm_mon + 1;
736954Sbill 	de->rt_date.rt_yr = timp->tm_year - 72;
737954Sbill 	de->rt_stat = RT_FILE;
738954Sbill 	de->rt_pad = 0;
739954Sbill 	de->rt_chan = 0;
740954Sbill 	de->rt_job = 0;
7414879Ssam 	lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[segnum]);
742954Sbill }
743954Sbill 
7444879Ssam toflop(name, ocount, dope)
7454879Ssam 	char *name;
7464879Ssam 	register FLDOPE *dope;
7474879Ssam 	long ocount;
748954Sbill {
749954Sbill 	register file, n, startad = dope->startad, count = ocount;
750954Sbill 	char buff[512];
751954Sbill 
7524879Ssam 	file = open(name, 0);
7534879Ssam 	if (file < 0) {
7544879Ssam 		fprintf(stderr, "arff: couldn't open %s\n",name);
7554879Ssam 		exit(1);
7564879Ssam 	}
757954Sbill 	for( ; count >= 512; count -= 512) {
7584879Ssam 		read(file, buff, 512);
7594879Ssam 		lwrite(startad, 512, buff);
760954Sbill 		startad += 512;
761954Sbill 	}
7624879Ssam 	read(file, buff, count);
763954Sbill 	close(file);
7644879Ssam 	if (count <= 0)
7654879Ssam 		return;
7664879Ssam 	for (n = count; n < 512; n ++)
7674879Ssam 		buff[n] = 0;
7684879Ssam 	lwrite(startad, 512, buff);
7694879Ssam 	count = (dope->rtdope->rt_len*512-ocount)/512 ;
7704879Ssam 	if (count <= 0)
7714879Ssam 		return;
7724879Ssam 	for ( ; count > 0 ; count--) {
773954Sbill 		startad += 512;
7744879Ssam 		lwrite(startad, 512, zeroes);
775954Sbill 	}
7764879Ssam }
777954Sbill 
778954Sbill dcmd()
779954Sbill {
780954Sbill 	register int i;
781954Sbill 
782954Sbill 	rt_init();
7834879Ssam 	if (namc)
7844879Ssam 		for (i = 0; i < namc; i++)
7854879Ssam 			if (rtk(namv[i])==0)
7864879Ssam 				namv[i]=0;
7874879Ssam 	if (dirdirty)
788954Sbill 		scrunch();
789954Sbill }
7904879Ssam 
791954Sbill rtk(name)
7924879Ssam 	char *name;
793954Sbill {
794954Sbill 	register FLDOPE *dope;
795954Sbill 	register struct rt_ent *de;
796954Sbill 	FLDOPE *lookup();
797954Sbill 
7984879Ssam 	if (dope = lookup(name)) {
799954Sbill 		printf("d - %s\n",name);
800954Sbill 		de = dope->rtdope;
801954Sbill 		de->rt_stat = RT_NULL;
802954Sbill 		de->rt_name[0] = 0;
803954Sbill 		de->rt_name[1] = 0;
804954Sbill 		de->rt_name[2] = 0;
805*9877Ssam 		*((u_short *)&(de->rt_date)) = 0;
806954Sbill 		dirdirty = 1;
807*9877Ssam 		return (0);
808954Sbill 	}
809*9877Ssam 	return (1);
810954Sbill }
8114879Ssam 
8124879Ssam scrunch()
8134879Ssam {
8143346Swnj 	register struct rt_ent *de , *workp;
8153346Swnj 	register segnum;
8164879Ssam 
8174879Ssam 	for (segnum = 0; segnum != -1;
8183346Swnj 	     segnum = rt_dir[segnum].rt_axhead.rt_nxtseg - 1) {
8194879Ssam 		dirdirty = 0;
8204879Ssam 		for (de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++)
821*9877Ssam 			if (de->rt_stat == RT_NULL &&
822*9877Ssam 			    de[1].rt_stat == RT_NULL) {
8234879Ssam 				(de+1)->rt_len += de->rt_len;
8244879Ssam 				for (workp = de; workp < rt_curend[segnum]; workp++)
8254879Ssam 					*workp = workp[1];
8264879Ssam 				de--;
8274879Ssam 				rt_curend[segnum]--;
8284879Ssam 				rt_nleft++;
8294879Ssam 				dirdirty = 1;
8304879Ssam 			}
8314879Ssam 		if (dirdirty)
8324879Ssam 			lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK,
8334879Ssam 				(char *)&rt_dir[segnum]);
834954Sbill 	}
835954Sbill }
836