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