|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: char copyright[] =
9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10: All rights reserved.\n";
11: #endif not lint
12:
13: #ifndef lint
14: static char sccsid[] = "@(#)arff.c 5.7 (Berkeley) 5/11/89";
15: #endif not lint
16:
17: #include <sys/types.h>
18: #include <sys/stat.h>
19: #include <sys/time.h>
20: #include <sys/signal.h>
21: #include <sys/file.h>
22: #include <stdio.h>
23: #include "pathnames.h"
24:
25: #define dbprintf printf
26:
27: struct rt_dat {
28: u_short rt_yr:5; /* year-1972 */
29: u_short rt_dy:5; /* day */
30: u_short rt_mo:5; /* month */
31: };
32:
33: struct rt_axent {
34: char rt_sent[14];
35: };
36:
37: struct rt_ent {
38: char rt_pad; /* unusued */
39: u_char rt_stat; /* type of entry, or end of seg */
40: u_short rt_name[3]; /* name, 3 words in rad50 form */
41: u_short rt_len; /* length of file */
42: u_char rt_chan; /* only used in temporary files */
43: char rt_job; /* only used in temporary files */
44: struct rt_dat rt_date; /* creation date */
45: };
46:
47: #define RT_TEMP 1
48: #define RT_NULL 2
49: #define RT_FILE 4
50: #define RT_PFILE (0200|RT_FILE) /* protected file */
51: #define RT_ESEG 8
52:
53: #define RT_BLOCK 512 /* block size */
54: #define RT_DIRSIZE 31 /* max # of directory segments */
55:
56: struct rt_head {
57: short rt_numseg; /* # of segments available */
58: short rt_nxtseg; /* # of next logical segment */
59: short rt_lstseg; /* highest seg currently open */
60: u_short rt_entpad; /* extra words/directory entry */
61: short rt_stfile; /* block # where files begin */
62: };
63:
64: struct rt_dir {
65: struct rt_head rt_axhead;
66: struct rt_ent rt_ents[72];
67: char _dirpad[6];
68: };
69:
70: #define rd_numseg rt_axhead.rt_numseg
71: #define rd_nxtseg rt_axhead.rt_nxtseg
72: #define rd_lstseg rt_axhead.rt_lstseg
73: #define rd_entpad rt_axhead.rt_entpad
74: #define rd_stfile rt_axhead.rt_stfile
75:
76: typedef struct fldope {
77: int startad;
78: int count;
79: struct rt_ent *rtdope;
80: } FLDOPE;
81:
82: FLDOPE *lookup();
83:
84: #define rt(p) ((struct rt_ent *) p )
85: #define Ain1 03100
86: #define Ain2 050
87: #define flag(c) (flg[('c') - 'a'])
88:
89: char *man = "rxtd";
90: char zeroes[512];
91:
92: extern char *val;
93: extern char table[256];
94: struct rt_dir rt_dir[RT_DIRSIZE] = {
95: {
96: { 4, 0, 1, 0, 14 },
97: { { 0, RT_NULL, { 0, 0, 0 }, 486, 0 },
98: { 0, RT_ESEG } }
99: }
100: };
101:
102: struct rt_dir rt_nulldir = {
103: { 0, 0, 0, 0, 0 },
104: { { 0, RT_NULL, { 0, 0, 0 }, 0, 0 },
105: { 0, RT_ESEG } }
106: };
107:
108: int rt_entsiz;
109: int rt_nleft;
110: struct rt_ent *rt_curend[RT_DIRSIZE];
111: int floppydes;
112: int dirdirty;
113: char *rt_last;
114: char *defdev = _PATH_FLOPPY;
115:
116: char *opt = "vfbcm";
117:
118: extern long lseek();
119: int rcmd(), dcmd(), xcmd(), tcmd();
120:
121: int (*comfun)();
122: char flg[26];
123: char **namv;
124: int namc;
125:
126: main(argc, argv)
127: char *argv[];
128: {
129: register char *cp;
130:
131: if (argc < 2)
132: usage();
133: for (cp = argv[1]; *cp; cp++)
134: switch (*cp) {
135:
136: case 'm':
137: case 'v':
138: case 'u':
139: case 'w':
140: case 'b':
141: flg[*cp-'a']++;
142: continue;
143: case 'c':
144: flag(c)++;
145: dirdirty++;
146: continue;
147:
148: case 'r':
149: setcom(rcmd);
150: flag(r)++;
151: continue;
152:
153: case 'd':
154: setcom(dcmd);
155: flag(d)++;
156: continue;
157:
158: case 'x':
159: setcom(xcmd);
160: continue;
161:
162: case 't':
163: setcom(tcmd);
164: continue;
165:
166: case 'f':
167: defdev = argv[2];
168: argv++;
169: argc--;
170: continue;
171:
172: default:
173: fprintf(stderr, "arff: bad option `%c'\n", *cp);
174: exit(1);
175: }
176:
177: namv = argv+2;
178: namc = argc-2;
179: if (comfun == 0) {
180: if (flag(u) == 0) {
181: fprintf(stderr, "arff: one of [%s] must be specified\n",
182: man);
183: exit(1);
184: }
185: setcom(rcmd);
186: }
187: (*comfun)();
188: exit(notfound());
189: }
190:
191: setcom(fun)
192: int (*fun)();
193: {
194: if (comfun != 0) {
195: fprintf(stderr, "arff: only one of [%s] allowed\n", man);
196: exit(1);
197: }
198: comfun = fun;
199: }
200:
201: usage()
202: {
203: fprintf(stderr, "usage: ar [%s][%s] archive files ...\n", opt, man);
204: exit(1);
205: }
206:
207: notfound()
208: {
209: register i, n = 0;
210:
211: for (i = 0; i < namc; i++)
212: if (namv[i]) {
213: fprintf(stderr, "arff: %s not found\n", namv[i]);
214: n++;
215: }
216: return (n);
217: }
218:
219: tcmd()
220: {
221: register char *de, *last;
222: FLDOPE *lookup(), *dope;
223: int segnum, nleft;
224: register i;
225: register struct rt_ent *rde;
226:
227: rt_init();
228: if (namc != 0) {
229: for (i = 0; i < namc; i++)
230: if (dope = lookup(namv[i])) {
231: rde = dope->rtdope;
232: (void) rtls(rde);
233: namv[i] = 0;
234: }
235: return;
236: }
237: for (segnum = 0; segnum != -1;
238: segnum = rt_dir[segnum].rd_nxtseg - 1) {
239: last = rt_last + segnum*2*RT_BLOCK;
240: for (de = ((char *)&rt_dir[segnum])+10; de <= last;
241: de += rt_entsiz)
242: if (rtls(rt(de))) {
243: nleft = (last-de)/rt_entsiz;
244: #define ENTRIES "\n%d entries remaining in directory segment %d.\n"
245: printf(ENTRIES, nleft, segnum+1);
246: break;
247: }
248: }
249: }
250:
251: rtls(de)
252: register struct rt_ent *de;
253: {
254: int month, day, year;
255: char name[12], ext[4];
256:
257: switch (de->rt_stat) {
258:
259: case RT_TEMP:
260: if (flag(v))
261: printf("Tempfile:\n");
262: /* fall thru...*/
263:
264: case RT_FILE:
265: case RT_PFILE:
266: if (!flag(v)) {
267: sunrad50(name, de->rt_name);
268: printf("%s\n", name);
269: break;
270: }
271: unrad50(2, de->rt_name, name);
272: unrad50(1, &(de->rt_name[2]), ext);
273: day = de->rt_date.rt_dy;
274: year = de->rt_date.rt_yr+72;
275: month = de->rt_date.rt_mo;
276: printf("%6.6s %3.3s %02d/%02d/%02d %d\n",name,
277: ext, month, day, year, de->rt_len);
278: break;
279:
280: case RT_NULL:
281: printf("%-25.9s %d\n","<UNUSED>", de->rt_len);
282: break;
283:
284: case RT_ESEG:
285: return (1);
286: }
287: return (0);
288: }
289:
290: xcmd()
291: {
292: register char *de, *last;
293: int segnum;
294: char name[12];
295: register int i;
296:
297: rt_init();
298: if (namc != 0) {
299: for (i = 0; i < namc; i++)
300: if (rtx(namv[i]) == 0)
301: namv[i] = 0;
302: return;
303: }
304: for (segnum = 0; segnum != -1;
305: segnum = rt_dir[segnum].rd_nxtseg-1)
306: for (last = rt_last+(segnum*2*RT_BLOCK),
307: de = ((char *)&rt_dir[segnum])+10; de <= last;
308: de += rt_entsiz) {
309: switch (rt(de)->rt_stat) {
310:
311: case RT_ESEG:
312: break; /* exit loop and try next segment */
313:
314: case RT_TEMP:
315: case RT_FILE:
316: case RT_PFILE:
317: sunrad50(name,rt(de)->rt_name);
318: (void) rtx(name);
319:
320: case RT_NULL:
321: default:
322: continue;
323: }
324: break;
325: }
326: }
327:
328: rtx(name)
329: char *name;
330: {
331: register FLDOPE *dope;
332: FLDOPE *lookup();
333: register startad, count;
334: int file;
335: char buff[512];
336:
337:
338: if (dope = lookup(name)) {
339: if (flag(v))
340: (void) rtls(dope->rtdope);
341: else
342: printf("x - %s\n",name);
343:
344: if ((file = creat(name, 0666)) < 0)
345: return (1);
346: count = dope->count;
347: startad = dope->startad;
348: for( ; count > 0 ; count -= 512) {
349: (void) lread(startad, 512, buff);
350: (void) write(file, buff, 512);
351: startad += 512;
352: }
353: (void) close(file);
354: return (0);
355: }
356: return (1);
357: }
358:
359: rt_init()
360: {
361: static initized = 0;
362: register char *de, *last;
363: register i;
364: int dirnum;
365: char *mode;
366: FILE *temp_floppydes;
367:
368: if (initized)
369: return;
370: initized = 1;
371: if (flag(c)) {
372: struct stat sb;
373: char response[128];
374: int tty;
375:
376: if (stat(defdev, &sb) >= 0 && (sb.st_mode & S_IFMT) == S_IFREG)
377: goto ignore;
378: tty = open(_PATH_TTY, O_RDWR);
379: #define SURE "Are you sure you want to clobber the floppy? "
380: (void) write(tty, SURE, sizeof (SURE));
381: (void) read(tty, response, sizeof (response));
382: if (*response != 'y')
383: exit(50);
384: (void) close(tty);
385: ignore:
386: ;
387: }
388: if (flag(c) || flag(d) || flag(r))
389: mode = "r+";
390: else
391: mode = "r";
392: if ((temp_floppydes = fopen(defdev, mode)) == NULL) {
393: perror(defdev);
394: exit(1);
395: } else
396: floppydes = fileno(temp_floppydes);
397: if (!flag(c)) {
398: if (lread(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]))
399: exit(2);
400: dirnum = rt_dir[0].rd_numseg;
401: /* check for blank/uninitialized diskette */
402: if (dirnum <= 0) {
403: fprintf(stderr,"arff: bad directory format\n");
404: exit(1);
405: }
406: if (dirnum > RT_DIRSIZE) {
407: fprintf(stderr,"arff: too many directory segments\n");
408: exit(1);
409: }
410: for (i = 1; i < dirnum; i++)
411: if (lread((6+2*i)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[i]))
412: exit(1);
413: } else {
414: dirnum = 1;
415: if (flag(b)) {
416: rt_dir[0].rd_numseg = 31;
417: rt_dir[0].rd_stfile = 68;
418: rt_dir[0].rt_ents[0].rt_len = 20480 - 68;
419: }
420: }
421:
422: rt_entsiz = 2*rt_dir[0].rd_entpad + 14;
423: /*
424: * We assume that the directory entries have no padding. This
425: * may not be a valid assumption, but there are numerous point
426: * in the code where it assumes it is an rt_ent structure and
427: * not an rt_entsiz sized structure.
428: */
429: rt_entsiz = 14;
430: rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz;
431: rt_nleft = 0;
432:
433: for (i = 0; i < dirnum; i++) {
434: last = rt_last + i*2*RT_BLOCK;
435: for (de = ((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz)
436: if (rt(de)->rt_stat == RT_ESEG)
437: break;
438: rt_curend[i] = rt(de);
439: rt_nleft += (last-de)/rt_entsiz;
440: }
441: }
442:
443: static FLDOPE result;
444:
445: FLDOPE *
446: lookup(name)
447: char *name;
448: {
449: unsigned short rname[3];
450: register char *de;
451: int segnum;
452: register index;
453:
454: srad50(name,rname);
455:
456: /*
457: * Search for name, accumulate blocks in index
458: */
459: rt_init();
460: for (segnum = 0; segnum != -1;
461: segnum = rt_dir[segnum].rd_nxtseg - 1)
462: {
463: index = 0;
464: for (de=((char *)&rt_dir[segnum])+10;
465: rt(de)->rt_stat != RT_ESEG; de += rt_entsiz)
466: switch(rt(de)->rt_stat) {
467:
468: case RT_FILE:
469: case RT_PFILE:
470: case RT_TEMP:
471: if(samename(rname,rt(de)->rt_name)) {
472: result.count = rt(de)->rt_len * 512;
473: result.startad = 512*
474: (rt_dir[segnum].rd_stfile + index);
475: result.rtdope = (struct rt_ent *) de;
476: return (&result);
477: }
478:
479: case RT_NULL:
480: index += rt(de)->rt_len;
481: }
482: }
483: return ((FLDOPE *) 0);
484:
485: }
486:
487: static
488: samename(a, b)
489: u_short a[], b[];
490: {
491: return (*a == *b && a[1] == b[1] && a[2] == b[2] );
492: }
493:
494: rad50(cp, out)
495: register u_char *cp;
496: u_short *out;
497: {
498: register index, temp;
499:
500: for (index = 0; *cp; index++) {
501: temp = Ain1 * table[*cp++];
502: if (*cp!=0) {
503: temp += Ain2 * table[*cp++];
504: if(*cp!=0)
505: temp += table[*cp++];
506: }
507: out[index] = temp;
508: }
509: }
510:
511: #define reduce(x, p, q) (x = v[p/q], p %= q);
512:
513: unrad50(count, in, cp)
514: u_short *in;
515: register char *cp;
516: {
517: register i, temp;
518: register u_char *v = (u_char *) val;
519:
520: for (i = 0; i < count; i++) {
521: temp = in[i];
522: reduce(*cp++, temp, Ain1);
523: reduce(*cp++, temp, Ain2);
524: reduce(*cp++, temp, 1);
525: }
526: *cp=0;
527: }
528:
529: srad50(name, rname)
530: register char *name;
531: register u_short *rname;
532: {
533: register index;
534: register char *cp;
535: char file[7], ext[4];
536:
537: /*
538: * Find end of pathname
539: */
540: for (cp = name; *cp++; )
541: ;
542: while (cp >= name && *--cp != '/')
543: ;
544: cp++;
545: /*
546: * Change to rad50
547: */
548: for (index = 0; *cp; ) {
549: file[index++] = *cp++;
550: if (*cp == '.') {
551: cp++;
552: break;
553: }
554: if (index >= 6) {
555: break;
556: }
557: }
558: file[index] = 0;
559: for (index = 0; *cp; ) {
560: ext[index++] = *cp++;
561: if (*cp == '.' || index >= 3)
562: break;
563: }
564: ext[index]=0;
565: rname[0] = rname[1] = rname[2] = 0;
566: rad50((u_char *)file, rname);
567: rad50((u_char *)ext, rname+2);
568: }
569:
570: sunrad50(name, rname)
571: u_short rname[];
572: register char *name;
573: {
574: register char *cp, *cp2;
575: char ext[4];
576:
577: unrad50(2, rname, name);
578: unrad50(1, rname + 2, ext);
579: /*
580: * Jam name and extension together with a dot
581: * deleting white space
582: */
583: for (cp = name; *cp++;)
584: ;
585: --cp;
586: while (*--cp == ' ' && cp >= name)
587: ;
588: *++cp = '.';
589: cp++;
590: for (cp2 = ext; *cp2 != ' ' && cp2 < ext+3;)
591: *cp++ = *cp2++;
592: *cp=0;
593: if (cp[-1] == '.')
594: cp[-1] = 0;
595: }
596:
597: static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789";
598:
599: static char table[256] = {
600: 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
601: 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
602: 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
603: 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
604: 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
605: 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
606: 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
607: 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
608: 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
609: 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
610: 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
611: 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
612: 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
613: 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
614: 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
615: 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 };
616:
617: /*
618: * Logical to physical adress translation
619: */
620: long
621: trans(logical)
622: register int logical;
623: {
624: register int sector, bytes, track;
625:
626: logical += 26*128;
627: bytes = (logical&127);
628: logical >>= 7;
629: sector = logical%26;
630: if(sector >= 13)
631: sector = sector*2+1;
632: else
633: sector *= 2;
634: sector += 26 + ((track = (logical/26))-1)*6;
635: sector %= 26;
636: return ((((track*26)+sector) << 7) + bytes);
637: }
638:
639: lread(startad, count, obuff)
640: register startad, count;
641: register char *obuff;
642: {
643: long trans();
644: extern floppydes;
645: register int size = flag(m) ? 512 : 128;
646: int error = 0;
647: extern int errno;
648:
649: rt_init();
650: while ((count -= size) >= 0) {
651: (void) lseek(floppydes, flag(m) ?
652: (long)startad : trans(startad), 0);
653: if (read(floppydes, obuff, size) != size) {
654: error = errno;
655: fprintf(stderr, "arff: read error block %d: ",
656: startad/size);
657: errno = error;
658: perror("");
659: }
660: obuff += size;
661: startad += size;
662: }
663: return (error);
664: }
665:
666: lwrite(startad, count, obuff)
667: register startad, count;
668: register char *obuff;
669: {
670: long trans();
671: extern floppydes;
672: register int size = flag(m) ? 512 : 128;
673:
674: rt_init();
675: while ((count -= size) >= 0) {
676: (void) lseek(floppydes, flag(m) ?
677: (long)startad : trans(startad), 0);
678: if (write(floppydes, obuff, size) != size)
679: fprintf(stderr, "arff: write error block %d\n",
680: startad/size);
681: obuff += size;
682: startad += size;
683: }
684: }
685:
686: rcmd()
687: {
688: register int i;
689:
690: rt_init();
691: if (namc > 0)
692: for (i = 0; i < namc; i++)
693: if (rtr(namv[i]) == 0)
694: namv[i] = 0;
695: }
696:
697: rtr(name)
698: char *name;
699: {
700: register FLDOPE *dope;
701: register struct rt_ent *de;
702: struct stat buf;
703: register struct stat *bufp = &buf;
704: int segnum;
705: char type;
706:
707: if (stat(name, bufp) < 0) {
708: perror(name);
709: return (-1);
710: }
711: type = 'a';
712: if (dope = lookup(name)) {
713: /* can replace, no problem */
714: de = dope->rtdope;
715: if (bufp->st_size <= (de->rt_len * 512)) {
716: printf("r - %s\n",name);
717: toflop(name, bufp->st_size, dope);
718: goto found;
719: } else {
720: de = dope->rtdope;
721: type = 'r';
722: de->rt_stat = RT_NULL;
723: de->rt_name[0] = 0;
724: de->rt_name[1] = 0;
725: de->rt_name[2] = 0;
726: *((u_short *)&(de->rt_date)) = 0;
727: scrunch();
728: }
729: }
730: /*
731: * Search for vacant spot
732: */
733: for (segnum = 0; segnum != -1;
734: segnum = rt_dir[segnum].rd_nxtseg - 1)
735: {
736: for (de = rt_dir[segnum].rt_ents;
737: rt(de)->rt_stat != RT_ESEG; de++)
738: if ((de)->rt_stat == RT_NULL) {
739: if (bufp->st_size <= (de->rt_len*512)) {
740: printf("%c - %s\n", type, name),
741: mkent(de, segnum, bufp,name);
742: goto found;
743: }
744: continue;
745: }
746: }
747: if (type == 'r')
748: printf("%s: no slot for file, file deleted\n",name);
749: else
750: printf("%s: no slot for file\n", name);
751: return (-1);
752:
753: found:
754: if (dope = lookup(name)) {
755: toflop(name, bufp->st_size, dope);
756: return (0);
757: }
758: printf("%s: internal error, added then not found\n", name);
759: return (-1);
760: }
761:
762: mkent(de, segnum, bufp, name)
763: register struct rt_ent *de;
764: int segnum;
765: register struct stat *bufp;
766: char *name;
767: {
768: struct tm *localtime();
769: register struct tm *timp;
770: register struct rt_ent *workp;
771: int count;
772:
773: count = (((bufp->st_size -1) >>9) + 1);
774: /* make sure there is room */
775: if (de->rt_len == count)
776: goto overwrite;
777: if ((char *)rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) {
778: /* no entries left on segment, trying adding new segment */
779: if (rt_dir[0].rd_numseg > rt_dir[0].rd_lstseg) {
780: short newseg;
781: register int i;
782: int maxseg;
783: short size;
784:
785: newseg = rt_dir[0].rd_lstseg++;
786: rt_dir[newseg] = rt_nulldir;
787: rt_dir[newseg].rd_nxtseg = rt_dir[segnum].rd_nxtseg;
788: rt_dir[segnum].rd_nxtseg = newseg + 1;
789: rt_dir[newseg].rd_entpad = rt_dir[0].rd_entpad;
790: rt_dir[newseg].rd_numseg = rt_dir[0].rd_numseg;
791: size = 0;
792: maxseg = 0;
793: for(i = newseg - 1; i >= 0; i--) {
794: workp = rt_curend[i] - 1;
795: if (workp->rt_stat != RT_NULL)
796: continue;
797: if (workp->rt_len < size)
798: continue;
799: size = workp->rt_len;
800: maxseg = i;
801: }
802: size = 0;
803: for (workp = &rt_dir[maxseg].rt_ents[0];
804: workp->rt_stat != RT_ESEG; workp++) {
805: size += workp->rt_len;
806: }
807: workp--;
808: rt_dir[newseg].rt_ents[0].rt_len = workp->rt_len;
809: rt_dir[newseg].rd_stfile =
810: rt_dir[maxseg].rd_stfile + size - workp->rt_len;
811: workp->rt_len = 0;
812: rt_curend[newseg] = &rt_dir[newseg].rt_ents[1];
813: lwrite(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]);
814: if (segnum != 0)
815: lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK,
816: (char *)&rt_dir[segnum]);
817: lwrite((6+newseg*2)*RT_BLOCK, 2*RT_BLOCK,
818: (char *)&rt_dir[newseg]);
819: segnum = newseg;
820: de = &rt_dir[newseg].rt_ents[0];
821: } else {
822: fprintf(stderr, "All directory segments full on %s\n",
823: defdev);
824: exit(1);
825: }
826: }
827: /* copy directory entries up */
828: for (workp = rt_curend[segnum]+1; workp > de; workp--)
829: *workp = workp[-1];
830: de[1].rt_len -= count;
831: de->rt_len = count;
832: rt_curend[segnum]++;
833: rt_nleft--;
834:
835: overwrite:
836: srad50(name,de->rt_name);
837: timp = localtime(&bufp->st_mtime);
838: de->rt_date.rt_dy = timp->tm_mday;
839: de->rt_date.rt_mo = timp->tm_mon + 1;
840: de->rt_date.rt_yr = timp->tm_year - 72;
841: de->rt_stat = RT_FILE;
842: de->rt_pad = 0;
843: de->rt_chan = 0;
844: de->rt_job = 0;
845: lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[segnum]);
846: }
847:
848: toflop(name, ocount, dope)
849: char *name;
850: register FLDOPE *dope;
851: long ocount;
852: {
853: register file, n, startad = dope->startad, count = ocount;
854: char buff[512];
855:
856: file = open(name, 0);
857: if (file < 0) {
858: fprintf(stderr, "arff: couldn't open %s\n",name);
859: exit(1);
860: }
861: for( ; count >= 512; count -= 512) {
862: (void) read(file, buff, 512);
863: lwrite(startad, 512, buff);
864: startad += 512;
865: }
866: (void) read(file, buff, count);
867: (void) close(file);
868: if (count <= 0)
869: return;
870: for (n = count; n < 512; n ++)
871: buff[n] = 0;
872: lwrite(startad, 512, buff);
873: count = (dope->rtdope->rt_len*512-ocount)/512 ;
874: if (count <= 0)
875: return;
876: for ( ; count > 0 ; count--) {
877: startad += 512;
878: lwrite(startad, 512, zeroes);
879: }
880: }
881:
882: dcmd()
883: {
884: register int i;
885:
886: rt_init();
887: if (namc)
888: for (i = 0; i < namc; i++)
889: if (rtk(namv[i])==0)
890: namv[i]=0;
891: if (dirdirty)
892: scrunch();
893: }
894:
895: rtk(name)
896: char *name;
897: {
898: register FLDOPE *dope;
899: register struct rt_ent *de;
900: FLDOPE *lookup();
901:
902: if (dope = lookup(name)) {
903: printf("d - %s\n",name);
904: de = dope->rtdope;
905: de->rt_stat = RT_NULL;
906: de->rt_name[0] = 0;
907: de->rt_name[1] = 0;
908: de->rt_name[2] = 0;
909: *((u_short *)&(de->rt_date)) = 0;
910: dirdirty = 1;
911: return (0);
912: }
913: return (1);
914: }
915:
916: scrunch()
917: {
918: register struct rt_ent *de , *workp;
919: register segnum;
920:
921: for (segnum = 0; segnum != -1;
922: segnum = rt_dir[segnum].rd_nxtseg - 1) {
923: for (de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++)
924: if (de->rt_stat == RT_NULL &&
925: (de+1)->rt_stat == RT_NULL) {
926: (de+1)->rt_len += de->rt_len;
927: for (workp=de; workp<rt_curend[segnum]; workp++)
928: *workp = workp[1];
929: de--;
930: rt_curend[segnum]--;
931: rt_nleft++;
932: }
933: lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK,
934: (char *)&rt_dir[segnum]);
935: }
936: dirdirty = 0;
937: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.