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