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

Defined functions

dcmd defined in line 866; used 2 times
lookup defined in line 437; used 9 times
lread defined in line 630; used 3 times
lwrite defined in line 650; used 8 times
main defined in line 122; never used
mkent defined in line 746; used 1 times
notfound defined in line 203; used 1 times
rad50 defined in line 485; used 2 times
rcmd defined in line 670; used 3 times
rt_init defined in line 353; used 7 times
rtk defined in line 879; used 1 times
rtls defined in line 247; used 3 times
rtr defined in line 681; used 1 times
rtx defined in line 322; used 2 times
samename defined in line 478; used 1 times
scrunch defined in line 900; used 2 times
setcom defined in line 187; used 5 times
srad50 defined in line 520; used 2 times
sunrad50 defined in line 561; used 2 times
tcmd defined in line 215; used 2 times
toflop defined in line 832; used 2 times
trans defined in line 611; used 4 times
unrad50 defined in line 504; used 4 times
usage defined in line 197; used 1 times
xcmd defined in line 285; used 2 times

Defined variables

copyright defined in line 8; never used
defdev defined in line 110; used 5 times
dirdirty defined in line 108; used 4 times
flg defined in line 118; used 2 times
floppydes defined in line 107; used 7 times
man defined in line 87; used 3 times
namc defined in line 120; used 10 times
namv defined in line 119; used 11 times
opt defined in line 112; used 1 times
result defined in line 435; used 4 times
rt_curend defined in line 106; used 9 times
rt_dir defined in line 92; used 42 times
rt_entsiz defined in line 104; used 10 times
rt_last defined in line 109; used 5 times
rt_nleft defined in line 105; used 4 times
rt_nulldir defined in line 98; used 1 times
sccsid defined in line 14; never used
table defined in line 590; used 4 times
val defined in line 588; used 2 times
zeroes defined in line 88; used 1 times

Defined struct's

fldope defined in line 74; never used
rt_axent defined in line 32; never used
rt_dat defined in line 26; used 2 times
  • in line 43(2)
rt_dir defined in line 62; used 4 times
  • in line 92(2), 98(2)
rt_ent defined in line 36; used 22 times
rt_head defined in line 54; used 2 times
  • in line 63(2)

Defined typedef's

FLDOPE defined in line 78; used 11 times

Defined macros

Ain1 defined in line 83; used 2 times
Ain2 defined in line 84; used 2 times
ENTRIES defined in line 240; used 1 times
RT_BLOCK defined in line 51; used 18 times
RT_DIRSIZE defined in line 52; used 3 times
RT_ESEG defined in line 49; used 6 times
RT_FILE defined in line 48; used 1 times
RT_NULL defined in line 47; used 8 times
RT_TEMP defined in line 46; never used
SURE defined in line 373; used 2 times
  • in line 374(2)
dbprintf defined in line 24; never used
flag defined in line 85; used 17 times
rd_entpad defined in line 71; used 3 times
rd_lstseg defined in line 70; used 2 times
rd_numseg defined in line 68; used 5 times
rd_nxtseg defined in line 69; used 8 times
rd_stfile defined in line 72; used 4 times
reduce defined in line 502; used 3 times
rt defined in line 82; used 11 times
Last modified: 1986-02-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2735
Valid CSS Valid XHTML 1.0 Strict