12e57d5edSdist /* 22e57d5edSdist * Copyright (c) 1980 Regents of the University of California. 32e57d5edSdist * All rights reserved. The Berkeley software License Agreement 42e57d5edSdist * specifies the terms and conditions for redistribution. 52e57d5edSdist */ 62e57d5edSdist 7b74381a6Ssam #ifndef lint 82e57d5edSdist char copyright[] = 92e57d5edSdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 102e57d5edSdist All rights reserved.\n"; 112e57d5edSdist #endif not lint 122e57d5edSdist 132e57d5edSdist #ifndef lint 14*2e5d0128Sbloom static char sccsid[] = "@(#)arff.c 5.2 (Berkeley) 02/11/86"; 152e57d5edSdist #endif not lint 16c09a6a34Ssam 171437cf11Sbill #include <sys/types.h> 181437cf11Sbill #include <sys/stat.h> 191bbff716Ssam #include <sys/time.h> 201437cf11Sbill #include <signal.h> 211437cf11Sbill #include <stdio.h> 2219251218Ssam #include <sys/file.h> 23c09a6a34Ssam 241437cf11Sbill #define dbprintf printf 25c09a6a34Ssam 261437cf11Sbill struct rt_dat { 27c09a6a34Ssam u_short rt_yr:5; /* year-1972 */ 28c09a6a34Ssam u_short rt_dy:5; /* day */ 29c09a6a34Ssam u_short rt_mo:5; /* month */ 301437cf11Sbill }; 31c09a6a34Ssam 321437cf11Sbill struct rt_axent { 331437cf11Sbill char rt_sent[14]; 341437cf11Sbill }; 351437cf11Sbill 361437cf11Sbill struct rt_ent { 371437cf11Sbill char rt_pad; /* unusued */ 38c09a6a34Ssam char rt_stat; /* type of entry, or end of seg */ 39c09a6a34Ssam u_short rt_name[3]; /* name, 3 words in rad50 form */ 402ef99505Swnj u_short rt_len; /* length of file */ 41c09a6a34Ssam char rt_chan; /* only used in temporary files */ 42c09a6a34Ssam char rt_job; /* only used in temporary files */ 43c09a6a34Ssam struct rt_dat rt_date; /* creation date */ 441437cf11Sbill }; 45c09a6a34Ssam 461437cf11Sbill #define RT_TEMP 1 471437cf11Sbill #define RT_NULL 2 481437cf11Sbill #define RT_FILE 4 491437cf11Sbill #define RT_ESEG 8 50c09a6a34Ssam 51c09a6a34Ssam #define RT_BLOCK 512 /* block size */ 52d0b9e33eSwnj #define RT_DIRSIZE 31 /* max # of directory segments */ 53c09a6a34Ssam 541437cf11Sbill struct rt_head { 55c09a6a34Ssam short rt_numseg; /* # of segments available */ 56c09a6a34Ssam short rt_nxtseg; /* # of next logical segment */ 57c09a6a34Ssam short rt_lstseg; /* highest seg currently open */ 58c09a6a34Ssam u_short rt_entpad; /* extra words/directory entry */ 59c09a6a34Ssam short rt_stfile; /* block # where files begin */ 601437cf11Sbill }; 61c09a6a34Ssam 621437cf11Sbill struct rt_dir { 631437cf11Sbill struct rt_head rt_axhead; 641437cf11Sbill struct rt_ent rt_ents[72]; 651437cf11Sbill char _dirpad[6]; 661437cf11Sbill }; 67c09a6a34Ssam 68*2e5d0128Sbloom #define rd_numseg rt_axhead.rt_numseg 69*2e5d0128Sbloom #define rd_nxtseg rt_axhead.rt_nxtseg 70*2e5d0128Sbloom #define rd_lstseg rt_axhead.rt_lstseg 71*2e5d0128Sbloom #define rd_entpad rt_axhead.rt_entpad 72*2e5d0128Sbloom #define rd_stfile rt_axhead.rt_stfile 73*2e5d0128Sbloom 741437cf11Sbill typedef struct fldope { 751437cf11Sbill int startad; 761437cf11Sbill int count; 771437cf11Sbill struct rt_ent *rtdope; 781437cf11Sbill } FLDOPE; 79c09a6a34Ssam 801437cf11Sbill FLDOPE *lookup(); 81c09a6a34Ssam 821437cf11Sbill #define rt(p) ((struct rt_ent *) p ) 831437cf11Sbill #define Ain1 03100 841437cf11Sbill #define Ain2 050 85c09a6a34Ssam #define flag(c) (flg[('c') - 'a']) 861437cf11Sbill 87c09a6a34Ssam char *man = "rxtd"; 881437cf11Sbill char zeroes[512]; 89c09a6a34Ssam 901437cf11Sbill extern char *val; 911437cf11Sbill extern char table[256]; 92c09a6a34Ssam struct rt_dir rt_dir[RT_DIRSIZE] = { 93c09a6a34Ssam { 4, 0, 1, 0, 14 }, 94*2e5d0128Sbloom { { 0, RT_NULL, { 0, 0, 0 }, 486, 0 }, 95*2e5d0128Sbloom { 0, RT_ESEG } } 96*2e5d0128Sbloom }; 97*2e5d0128Sbloom 98*2e5d0128Sbloom struct rt_dir rt_nulldir = { 99*2e5d0128Sbloom { 0, 0, 0, 0, 0 }, 100*2e5d0128Sbloom { { 0, RT_NULL, { 0, 0, 0 }, 0, 0 }, 101b74381a6Ssam { 0, RT_ESEG } } 102c09a6a34Ssam }; 103c09a6a34Ssam 1041437cf11Sbill int rt_entsiz; 1051437cf11Sbill int rt_nleft; 106d0b9e33eSwnj struct rt_ent *rt_curend[RT_DIRSIZE]; 1071437cf11Sbill int floppydes; 1081437cf11Sbill int dirdirty; 1091437cf11Sbill char *rt_last; 1101437cf11Sbill char *defdev = "/dev/floppy"; 1111437cf11Sbill 112*2e5d0128Sbloom char *opt = "vfbcm"; 1131437cf11Sbill 114c09a6a34Ssam extern long lseek(); 115c09a6a34Ssam int rcmd(), dcmd(), xcmd(), tcmd(); 116c09a6a34Ssam 1171437cf11Sbill int (*comfun)(); 1181437cf11Sbill char flg[26]; 1191437cf11Sbill char **namv; 1201437cf11Sbill int namc; 1211437cf11Sbill 1221437cf11Sbill main(argc, argv) 1231437cf11Sbill char *argv[]; 1241437cf11Sbill { 1251437cf11Sbill register char *cp; 1261437cf11Sbill 1271437cf11Sbill if (argc < 2) 1281437cf11Sbill usage(); 1291437cf11Sbill for (cp = argv[1]; *cp; cp++) 1301437cf11Sbill switch (*cp) { 131c09a6a34Ssam 1321437cf11Sbill case 'm': 1331437cf11Sbill case 'v': 1341437cf11Sbill case 'u': 1351437cf11Sbill case 'w': 136*2e5d0128Sbloom case 'b': 1371437cf11Sbill flg[*cp-'a']++; 1381437cf11Sbill continue; 1391437cf11Sbill case 'c': 140c09a6a34Ssam flag(c)++; 1411437cf11Sbill dirdirty++; 1421437cf11Sbill continue; 1431437cf11Sbill 1441437cf11Sbill case 'r': 1451437cf11Sbill setcom(rcmd); 146c09a6a34Ssam flag(r)++; 1471437cf11Sbill continue; 1481437cf11Sbill 1491437cf11Sbill case 'd': 1501437cf11Sbill setcom(dcmd); 151c09a6a34Ssam flag(d)++; 1521437cf11Sbill continue; 1531437cf11Sbill 1541437cf11Sbill case 'x': 1551437cf11Sbill setcom(xcmd); 1561437cf11Sbill continue; 1571437cf11Sbill 1581437cf11Sbill case 't': 1591437cf11Sbill setcom(tcmd); 1601437cf11Sbill continue; 1611437cf11Sbill 1621437cf11Sbill case 'f': 1631437cf11Sbill defdev = argv[2]; 1641437cf11Sbill argv++; 1651437cf11Sbill argc--; 1661437cf11Sbill continue; 1671437cf11Sbill 1681437cf11Sbill default: 1691437cf11Sbill fprintf(stderr, "arff: bad option `%c'\n", *cp); 1701437cf11Sbill exit(1); 1711437cf11Sbill } 172c09a6a34Ssam 1731437cf11Sbill namv = argv+2; 1741437cf11Sbill namc = argc-2; 1751437cf11Sbill if (comfun == 0) { 176c09a6a34Ssam if (flag(u) == 0) { 177c09a6a34Ssam fprintf(stderr, "arff: one of [%s] must be specified\n", 178c09a6a34Ssam man); 1791437cf11Sbill exit(1); 1801437cf11Sbill } 1811437cf11Sbill setcom(rcmd); 1821437cf11Sbill } 1831437cf11Sbill (*comfun)(); 1841437cf11Sbill exit(notfound()); 1851437cf11Sbill } 1861437cf11Sbill 1871437cf11Sbill setcom(fun) 1881437cf11Sbill int (*fun)(); 1891437cf11Sbill { 1901437cf11Sbill if (comfun != 0) { 1911437cf11Sbill fprintf(stderr, "arff: only one of [%s] allowed\n", man); 1921437cf11Sbill exit(1); 1931437cf11Sbill } 1941437cf11Sbill comfun = fun; 1951437cf11Sbill } 1961437cf11Sbill 1971437cf11Sbill usage() 1981437cf11Sbill { 199296c7c8aSwnj fprintf(stderr, "usage: ar [%s][%s] archive files ...\n", opt, man); 2001437cf11Sbill exit(1); 2011437cf11Sbill } 2021437cf11Sbill 2031437cf11Sbill notfound() 2041437cf11Sbill { 205c09a6a34Ssam register i, n = 0; 2061437cf11Sbill 2071437cf11Sbill for (i = 0; i < namc; i++) 2081437cf11Sbill if (namv[i]) { 2091437cf11Sbill fprintf(stderr, "arff: %s not found\n", namv[i]); 2101437cf11Sbill n++; 2111437cf11Sbill } 2121437cf11Sbill return (n); 2131437cf11Sbill } 2141437cf11Sbill 2151437cf11Sbill tcmd() 2161437cf11Sbill { 217c09a6a34Ssam register char *de, *last; 2181437cf11Sbill FLDOPE *lookup(), *dope; 219c09a6a34Ssam int segnum, nleft; 220c09a6a34Ssam register i; 2211437cf11Sbill register struct rt_ent *rde; 2221437cf11Sbill 2231437cf11Sbill rt_init(); 224b74381a6Ssam if (namc != 0) { 225b74381a6Ssam for (i = 0; i < namc; i++) 226b74381a6Ssam if (dope = lookup(namv[i])) { 227b74381a6Ssam rde = dope->rtdope; 228*2e5d0128Sbloom (void) rtls(rde); 229b74381a6Ssam namv[i] = 0; 230b74381a6Ssam } 231b74381a6Ssam return; 232b74381a6Ssam } 233c09a6a34Ssam for (segnum = 0; segnum != -1; 234*2e5d0128Sbloom segnum = rt_dir[segnum].rd_nxtseg - 1) { 235d0b9e33eSwnj last = rt_last + segnum*2*RT_BLOCK; 236d0b9e33eSwnj for (de = ((char *)&rt_dir[segnum])+10; de <= last; 237c09a6a34Ssam de += rt_entsiz) 2381437cf11Sbill if (rtls(rt(de))) { 239d0b9e33eSwnj nleft = (last-de)/rt_entsiz; 240c09a6a34Ssam #define ENTRIES "\n%d entries remaining in directory segment %d.\n" 241c09a6a34Ssam printf(ENTRIES, nleft, segnum+1); 2421437cf11Sbill break; 2431437cf11Sbill } 2441437cf11Sbill } 2451437cf11Sbill } 246c09a6a34Ssam 2471437cf11Sbill rtls(de) 2481437cf11Sbill register struct rt_ent *de; 2491437cf11Sbill { 2501437cf11Sbill int month, day, year; 2511437cf11Sbill char name[12], ext[4]; 2521437cf11Sbill 2531437cf11Sbill switch (de->rt_stat) { 254c09a6a34Ssam 2551437cf11Sbill case RT_TEMP: 256c09a6a34Ssam if (flag(v)) 2571437cf11Sbill printf("Tempfile:\n"); 258c09a6a34Ssam /* fall thru...*/ 259c09a6a34Ssam 2601437cf11Sbill case RT_FILE: 261c09a6a34Ssam if (!flag(v)) { 262c09a6a34Ssam sunrad50(name, de->rt_name); 263c09a6a34Ssam printf("%s\n", name); 264c09a6a34Ssam break; 265c09a6a34Ssam } 2661437cf11Sbill unrad50(2, de->rt_name, name); 2671437cf11Sbill unrad50(1, &(de->rt_name[2]), ext); 2681437cf11Sbill day = de->rt_date.rt_dy; 2691437cf11Sbill year = de->rt_date.rt_yr+72; 2701437cf11Sbill month = de->rt_date.rt_mo; 2711437cf11Sbill printf("%6.6s %3.3s %02d/%02d/%02d %d\n",name, 2721437cf11Sbill ext, month, day, year, de->rt_len); 2731437cf11Sbill break; 2741437cf11Sbill 2751437cf11Sbill case RT_NULL: 2761437cf11Sbill printf("%-25.9s %d\n","<UNUSED>", de->rt_len); 2771437cf11Sbill break; 2781437cf11Sbill 2791437cf11Sbill case RT_ESEG: 2801437cf11Sbill return (1); 2811437cf11Sbill } 2821437cf11Sbill return (0); 2831437cf11Sbill } 284c09a6a34Ssam 2851437cf11Sbill xcmd() 2861437cf11Sbill { 287c09a6a34Ssam register char *de, *last; 288d0b9e33eSwnj int segnum; 2891437cf11Sbill char name[12]; 2901437cf11Sbill register int i; 2911437cf11Sbill 2921437cf11Sbill rt_init(); 293b74381a6Ssam if (namc != 0) { 294b74381a6Ssam for (i = 0; i < namc; i++) 295b74381a6Ssam if (rtx(namv[i]) == 0) 296b74381a6Ssam namv[i] = 0; 297b74381a6Ssam return; 298b74381a6Ssam } 299c09a6a34Ssam for (segnum = 0; segnum != -1; 300*2e5d0128Sbloom segnum = rt_dir[segnum].rd_nxtseg-1) 301c09a6a34Ssam for (last = rt_last+(segnum*2*RT_BLOCK), 302c09a6a34Ssam de = ((char *)&rt_dir[segnum])+10; de <= last; 30367f39843Sralph de += rt_entsiz) { 3040200ad53Swnj switch (rt(de)->rt_stat) { 305b74381a6Ssam 3060200ad53Swnj case RT_ESEG: 30767f39843Sralph break; /* exit loop and try next segment */ 308b74381a6Ssam 3090200ad53Swnj case RT_TEMP: 3100200ad53Swnj case RT_FILE: 3110200ad53Swnj sunrad50(name,rt(de)->rt_name); 312*2e5d0128Sbloom (void) rtx(name); 313b74381a6Ssam 3140200ad53Swnj case RT_NULL: 31567f39843Sralph default: 31667f39843Sralph continue; 31767f39843Sralph } 318b74381a6Ssam break; 3190200ad53Swnj } 3201437cf11Sbill } 321c09a6a34Ssam 3221437cf11Sbill rtx(name) 3231437cf11Sbill char *name; 3241437cf11Sbill { 3251437cf11Sbill register FLDOPE *dope; 3261437cf11Sbill FLDOPE *lookup(); 3271437cf11Sbill register startad, count; 328c09a6a34Ssam int file; 329c09a6a34Ssam char buff[512]; 3301437cf11Sbill 3311437cf11Sbill 3321437cf11Sbill if (dope = lookup(name)) { 333c09a6a34Ssam if (flag(v)) 334*2e5d0128Sbloom (void) rtls(dope->rtdope); 3351437cf11Sbill else 3361437cf11Sbill printf("x - %s\n",name); 3371437cf11Sbill 338c09a6a34Ssam if ((file = creat(name, 0666)) < 0) 339c09a6a34Ssam return (1); 3401437cf11Sbill count = dope->count; 3411437cf11Sbill startad = dope->startad; 3421437cf11Sbill for( ; count > 0 ; count -= 512) { 3431437cf11Sbill lread(startad, 512, buff); 344*2e5d0128Sbloom (void) write(file, buff, 512); 3451437cf11Sbill startad += 512; 3461437cf11Sbill } 347*2e5d0128Sbloom (void) close(file); 3481437cf11Sbill return (0); 3491437cf11Sbill } 3501437cf11Sbill return (1); 3511437cf11Sbill } 352c09a6a34Ssam 3531437cf11Sbill rt_init() 3541437cf11Sbill { 3551437cf11Sbill static initized = 0; 356c09a6a34Ssam register char *de, *last; 357d0b9e33eSwnj register i; 358a11ea3b6Shickman int dirnum; 359a11ea3b6Shickman char *mode; 360a11ea3b6Shickman FILE *temp_floppydes; 3611437cf11Sbill 362c09a6a34Ssam if (initized) 363c09a6a34Ssam return; 3641437cf11Sbill initized = 1; 36519251218Ssam if (flag(c)) { 36619251218Ssam struct stat sb; 36719251218Ssam char response[128]; 36819251218Ssam int tty; 36919251218Ssam 37019251218Ssam if (stat(defdev, &sb) >= 0 && (sb.st_mode & S_IFMT) == S_IFREG) 37119251218Ssam goto ignore; 37219251218Ssam tty = open("/dev/tty", O_RDWR); 37319251218Ssam #define SURE "Are you sure you want to clobber the floppy? " 374*2e5d0128Sbloom (void) write(tty, SURE, sizeof (SURE)); 375*2e5d0128Sbloom (void) read(tty, response, sizeof (response)); 37619251218Ssam if (*response != 'y') 37719251218Ssam exit(50); 378*2e5d0128Sbloom (void) close(tty); 37919251218Ssam ignore: 38019251218Ssam ; 38119251218Ssam } 382c09a6a34Ssam if (flag(c) || flag(d) || flag(r)) 383a11ea3b6Shickman mode = "r+"; 3841437cf11Sbill else 385a11ea3b6Shickman mode = "r"; 386a11ea3b6Shickman if ((temp_floppydes = fopen(defdev, mode)) == NULL) { 387a11ea3b6Shickman perror(defdev); 388296c7c8aSwnj exit(1); 389a11ea3b6Shickman } else 390a11ea3b6Shickman floppydes = fileno(temp_floppydes); 391c09a6a34Ssam if (!flag(c)) { 392d0b9e33eSwnj lread(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]); 393*2e5d0128Sbloom dirnum = rt_dir[0].rd_numseg; 394254d8466Shelge /* check for blank/uninitialized diskette */ 395254d8466Shelge if (dirnum <= 0) { 396254d8466Shelge fprintf(stderr,"arff: bad directory format\n"); 397254d8466Shelge exit(1); 398254d8466Shelge } 399d0b9e33eSwnj if (dirnum > RT_DIRSIZE) { 400d0b9e33eSwnj fprintf(stderr,"arff: too many directory segments\n"); 401d0b9e33eSwnj exit(1); 402d0b9e33eSwnj } 403d0b9e33eSwnj for (i = 1; i < dirnum; i++) 404d0b9e33eSwnj lread((6+2*i)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[i]); 405*2e5d0128Sbloom } else { 40619ec2be6Sroot dirnum = 1; 407*2e5d0128Sbloom if (flag(b)) { 408*2e5d0128Sbloom rt_dir[0].rd_numseg = 31; 409*2e5d0128Sbloom rt_dir[0].rd_stfile = 68; 410*2e5d0128Sbloom rt_dir[0].rt_ents[0].rt_len = 20480 - 68; 411*2e5d0128Sbloom } 412*2e5d0128Sbloom } 4131437cf11Sbill 414*2e5d0128Sbloom rt_entsiz = 2*rt_dir[0].rd_entpad + 14; 415*2e5d0128Sbloom /* 416*2e5d0128Sbloom * We assume that the directory entries have no padding. This 417*2e5d0128Sbloom * may not be a valid assumption, but there are numerous point 418*2e5d0128Sbloom * in the code where it assumes it is an rt_ent structure and 419*2e5d0128Sbloom * not an rt_entsiz sized structure. 420*2e5d0128Sbloom */ 421*2e5d0128Sbloom rt_entsiz = 14; 422d0b9e33eSwnj rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz; 423d0b9e33eSwnj rt_nleft = 0; 424d0b9e33eSwnj 425d0b9e33eSwnj for (i = 0; i < dirnum; i++) { 426d0b9e33eSwnj last = rt_last + i*2*RT_BLOCK; 427c09a6a34Ssam for (de = ((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz) 428c09a6a34Ssam if (rt(de)->rt_stat == RT_ESEG) 429c09a6a34Ssam break; 430d0b9e33eSwnj rt_curend[i] = rt(de); 431d0b9e33eSwnj rt_nleft += (last-de)/rt_entsiz; 432d0b9e33eSwnj } 4331437cf11Sbill } 4341437cf11Sbill 4351437cf11Sbill static FLDOPE result; 436c09a6a34Ssam 4371437cf11Sbill FLDOPE * 4381437cf11Sbill lookup(name) 4391437cf11Sbill char *name; 4401437cf11Sbill { 4411437cf11Sbill unsigned short rname[3]; 442*2e5d0128Sbloom register char *de; 443d0b9e33eSwnj int segnum; 4441437cf11Sbill register index; 4451437cf11Sbill 4461437cf11Sbill srad50(name,rname); 4471437cf11Sbill 4481437cf11Sbill /* 4491437cf11Sbill * Search for name, accumulate blocks in index 4501437cf11Sbill */ 4511437cf11Sbill rt_init(); 452c09a6a34Ssam for (segnum = 0; segnum != -1; 453*2e5d0128Sbloom segnum = rt_dir[segnum].rd_nxtseg - 1) 454c09a6a34Ssam { 4551437cf11Sbill index = 0; 456d0b9e33eSwnj for (de=((char *)&rt_dir[segnum])+10; 457c09a6a34Ssam rt(de)->rt_stat != RT_ESEG; de += rt_entsiz) 4581437cf11Sbill switch(rt(de)->rt_stat) { 459c09a6a34Ssam 4601437cf11Sbill case RT_FILE: 4611437cf11Sbill case RT_TEMP: 462c09a6a34Ssam if(samename(rname,rt(de)->rt_name)) { 463c09a6a34Ssam result.count = rt(de)->rt_len * 512; 464c09a6a34Ssam result.startad = 512* 465*2e5d0128Sbloom (rt_dir[segnum].rd_stfile + index); 466c09a6a34Ssam result.rtdope = (struct rt_ent *) de; 467c09a6a34Ssam return (&result); 468c09a6a34Ssam } 469c09a6a34Ssam 4701437cf11Sbill case RT_NULL: 4711437cf11Sbill index += rt(de)->rt_len; 4721437cf11Sbill } 4731437cf11Sbill } 4741437cf11Sbill return ((FLDOPE *) 0); 475c09a6a34Ssam 4761437cf11Sbill } 477c09a6a34Ssam 4781437cf11Sbill static 4791437cf11Sbill samename(a, b) 480c09a6a34Ssam u_short a[], b[]; 4811437cf11Sbill { 482c09a6a34Ssam return (*a == *b && a[1] == b[1] && a[2] == b[2] ); 4831437cf11Sbill } 4841437cf11Sbill 4851437cf11Sbill rad50(cp, out) 486c09a6a34Ssam register u_char *cp; 487c09a6a34Ssam u_short *out; 4881437cf11Sbill { 489c09a6a34Ssam register index, temp; 4901437cf11Sbill 4911437cf11Sbill for (index = 0; *cp; index++) { 4921437cf11Sbill temp = Ain1 * table[*cp++]; 4931437cf11Sbill if (*cp!=0) { 4941437cf11Sbill temp += Ain2 * table[*cp++]; 4951437cf11Sbill if(*cp!=0) 4961437cf11Sbill temp += table[*cp++]; 4971437cf11Sbill } 4981437cf11Sbill out[index] = temp; 4991437cf11Sbill } 5001437cf11Sbill } 501c09a6a34Ssam 502c09a6a34Ssam #define reduce(x, p, q) (x = v[p/q], p %= q); 5031437cf11Sbill 5041437cf11Sbill unrad50(count, in, cp) 505c09a6a34Ssam u_short *in; 5061437cf11Sbill register char *cp; 5071437cf11Sbill { 508c09a6a34Ssam register i, temp; 509c09a6a34Ssam register u_char *v = (u_char *) val; 5101437cf11Sbill 5111437cf11Sbill for (i = 0; i < count; i++) { 5121437cf11Sbill temp = in[i]; 5131437cf11Sbill reduce(*cp++, temp, Ain1); 5141437cf11Sbill reduce(*cp++, temp, Ain2); 5151437cf11Sbill reduce(*cp++, temp, 1); 5161437cf11Sbill } 5171437cf11Sbill *cp=0; 5181437cf11Sbill } 5191437cf11Sbill 5201437cf11Sbill srad50(name, rname) 5211437cf11Sbill register char *name; 522c09a6a34Ssam register u_short *rname; 5231437cf11Sbill { 524c09a6a34Ssam register index; 525c09a6a34Ssam register char *cp; 5261437cf11Sbill char file[7], ext[4]; 527c09a6a34Ssam 5281437cf11Sbill /* 5291437cf11Sbill * Find end of pathname 5301437cf11Sbill */ 531c09a6a34Ssam for (cp = name; *cp++; ) 532c09a6a34Ssam ; 533c09a6a34Ssam while (cp >= name && *--cp != '/') 534c09a6a34Ssam ; 5351437cf11Sbill cp++; 5361437cf11Sbill /* 5371437cf11Sbill * Change to rad50 5381437cf11Sbill */ 5391437cf11Sbill for (index = 0; *cp; ) { 5401437cf11Sbill file[index++] = *cp++; 5411437cf11Sbill if (*cp == '.') { 5421437cf11Sbill cp++; 5431437cf11Sbill break; 5441437cf11Sbill } 5451437cf11Sbill if (index >= 6) { 5461437cf11Sbill break; 5471437cf11Sbill } 5481437cf11Sbill } 5491437cf11Sbill file[index] = 0; 5501437cf11Sbill for (index = 0; *cp; ) { 5511437cf11Sbill ext[index++] = *cp++; 552c09a6a34Ssam if (*cp == '.' || index >= 3) 5531437cf11Sbill break; 5541437cf11Sbill } 5551437cf11Sbill ext[index]=0; 556c09a6a34Ssam rname[0] = rname[1] = rname[2] = 0; 557c09a6a34Ssam rad50((u_char *)file, rname); 558c09a6a34Ssam rad50((u_char *)ext, rname+2); 5591437cf11Sbill } 560c09a6a34Ssam 5611437cf11Sbill sunrad50(name, rname) 562c09a6a34Ssam u_short rname[]; 5631437cf11Sbill register char *name; 5641437cf11Sbill { 5651437cf11Sbill register char *cp, *cp2; 5661437cf11Sbill char ext[4]; 5671437cf11Sbill 5681437cf11Sbill unrad50(2, rname, name); 5691437cf11Sbill unrad50(1, rname + 2, ext); 570c09a6a34Ssam /* 571c09a6a34Ssam * Jam name and extension together with a dot 572c09a6a34Ssam * deleting white space 573c09a6a34Ssam */ 574c09a6a34Ssam for (cp = name; *cp++;) 575c09a6a34Ssam ; 576c09a6a34Ssam --cp; 577c09a6a34Ssam while (*--cp == ' ' && cp >= name) 578c09a6a34Ssam ; 579c09a6a34Ssam *++cp = '.'; 580c09a6a34Ssam cp++; 581c09a6a34Ssam for (cp2 = ext; *cp2 != ' ' && cp2 < ext+3;) 5821437cf11Sbill *cp++ = *cp2++; 5831437cf11Sbill *cp=0; 584c09a6a34Ssam if (cp[-1] == '.') 585c09a6a34Ssam cp[-1] = 0; 5861437cf11Sbill } 5871437cf11Sbill 5881437cf11Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789"; 589c09a6a34Ssam 5901437cf11Sbill static char table[256] = { 5911437cf11Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 5921437cf11Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 5931437cf11Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 5941437cf11Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 5951437cf11Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5961437cf11Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 5971437cf11Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5981437cf11Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 5991437cf11Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 6001437cf11Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 6011437cf11Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29, 6021437cf11Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29, 6031437cf11Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6041437cf11Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29, 6051437cf11Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6061437cf11Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 }; 6071437cf11Sbill 608c09a6a34Ssam /* 609c09a6a34Ssam * Logical to physical adress translation 610c09a6a34Ssam */ 611c09a6a34Ssam long 612c09a6a34Ssam trans(logical) 6131437cf11Sbill register int logical; 6141437cf11Sbill { 6151437cf11Sbill register int sector, bytes, track; 6161437cf11Sbill 6171437cf11Sbill logical += 26*128; 6181437cf11Sbill bytes = (logical&127); 6191437cf11Sbill logical >>= 7; 6201437cf11Sbill sector = logical%26; 6211437cf11Sbill if(sector >= 13) 6221437cf11Sbill sector = sector*2+1; 6231437cf11Sbill else 6241437cf11Sbill sector *= 2; 6251437cf11Sbill sector += 26 + ((track = (logical/26))-1)*6; 6261437cf11Sbill sector %= 26; 6271437cf11Sbill return ((((track*26)+sector) << 7) + bytes); 6281437cf11Sbill } 629c09a6a34Ssam 6301437cf11Sbill lread(startad, count, obuff) 6311437cf11Sbill register startad, count; 6321437cf11Sbill register char *obuff; 6331437cf11Sbill { 6341437cf11Sbill long trans(); 6351437cf11Sbill extern floppydes; 636c09a6a34Ssam register int size = flag(m) ? 512 : 128; 637c09a6a34Ssam 6381437cf11Sbill rt_init(); 639c09a6a34Ssam while ((count -= size) >= 0) { 640*2e5d0128Sbloom (void) lseek(floppydes, flag(m) ? 641c09a6a34Ssam (long)startad : trans(startad), 0); 642c09a6a34Ssam if (read(floppydes, obuff, size) != size) 643c09a6a34Ssam fprintf(stderr, "arff: read error block %d\n", 644c09a6a34Ssam startad/size); 645c09a6a34Ssam obuff += size; 646c09a6a34Ssam startad += size; 6471437cf11Sbill } 6481437cf11Sbill } 649c09a6a34Ssam 6501437cf11Sbill lwrite(startad, count, obuff) 6511437cf11Sbill register startad, count; 6521437cf11Sbill register char *obuff; 6531437cf11Sbill { 6541437cf11Sbill long trans(); 6551437cf11Sbill extern floppydes; 656c09a6a34Ssam register int size = flag(m) ? 512 : 128; 657c09a6a34Ssam 6581437cf11Sbill rt_init(); 659c09a6a34Ssam while ((count -= size) >= 0) { 660*2e5d0128Sbloom (void) lseek(floppydes, flag(m) ? 661c09a6a34Ssam (long)startad : trans(startad), 0); 662c09a6a34Ssam if (write(floppydes, obuff, size) != size) 663c09a6a34Ssam fprintf(stderr, "arff: write error block %d\n", 664c09a6a34Ssam startad/size); 665c09a6a34Ssam obuff += size; 666c09a6a34Ssam startad += size; 6671437cf11Sbill } 6681437cf11Sbill } 6691437cf11Sbill 6701437cf11Sbill rcmd() 6711437cf11Sbill { 6721437cf11Sbill register int i; 6731437cf11Sbill 6741437cf11Sbill rt_init(); 6751437cf11Sbill if (namc > 0) 6761437cf11Sbill for (i = 0; i < namc; i++) 677c09a6a34Ssam if (rtr(namv[i]) == 0) 678c09a6a34Ssam namv[i] = 0; 6791437cf11Sbill } 6801437cf11Sbill 6811437cf11Sbill rtr(name) 6821437cf11Sbill char *name; 6831437cf11Sbill { 684c09a6a34Ssam register FLDOPE *dope; 685c09a6a34Ssam register struct rt_ent *de; 686c09a6a34Ssam struct stat buf; 687c09a6a34Ssam register struct stat *bufp = &buf; 688d0b9e33eSwnj int segnum; 689*2e5d0128Sbloom char type; 6901437cf11Sbill 69119ec2be6Sroot if (stat(name, bufp) < 0) { 69219ec2be6Sroot perror(name); 69319ec2be6Sroot return (-1); 69419ec2be6Sroot } 695*2e5d0128Sbloom type = 'a'; 6961437cf11Sbill if (dope = lookup(name)) { 6971437cf11Sbill /* can replace, no problem */ 6981437cf11Sbill de = dope->rtdope; 699*2e5d0128Sbloom if (bufp->st_size <= (de->rt_len * 512)) { 700*2e5d0128Sbloom printf("r - %s\n",name); 7011437cf11Sbill toflop(name, bufp->st_size, dope); 702b74381a6Ssam goto found; 703*2e5d0128Sbloom } else { 704*2e5d0128Sbloom de = dope->rtdope; 705*2e5d0128Sbloom type = 'r'; 706*2e5d0128Sbloom de->rt_stat = RT_NULL; 707*2e5d0128Sbloom de->rt_name[0] = 0; 708*2e5d0128Sbloom de->rt_name[1] = 0; 709*2e5d0128Sbloom de->rt_name[2] = 0; 710*2e5d0128Sbloom *((u_short *)&(de->rt_date)) = 0; 711*2e5d0128Sbloom scrunch(); 712*2e5d0128Sbloom } 713b74381a6Ssam } 714b74381a6Ssam /* 715b74381a6Ssam * Search for vacant spot 716b74381a6Ssam */ 717c09a6a34Ssam for (segnum = 0; segnum != -1; 718*2e5d0128Sbloom segnum = rt_dir[segnum].rd_nxtseg - 1) 719c09a6a34Ssam { 720d0b9e33eSwnj for (de = rt_dir[segnum].rt_ents; 721c09a6a34Ssam rt(de)->rt_stat != RT_ESEG; de++) 722c09a6a34Ssam if ((de)->rt_stat == RT_NULL) { 7231437cf11Sbill if (bufp->st_size <= (de->rt_len*512)) { 724*2e5d0128Sbloom printf("%c - %s\n", type, name), 725d0b9e33eSwnj mkent(de, segnum, bufp,name); 7261437cf11Sbill goto found; 7271437cf11Sbill } 7281437cf11Sbill continue; 729d0b9e33eSwnj } 730d0b9e33eSwnj } 731*2e5d0128Sbloom if (type = 'r') 732*2e5d0128Sbloom printf("%s: no slot for file, file deleted\n",name); 733*2e5d0128Sbloom else 73419ec2be6Sroot printf("%s: no slot for file\n", name); 73519ec2be6Sroot return (-1); 736c09a6a34Ssam 737c09a6a34Ssam found: 738c09a6a34Ssam if (dope = lookup(name)) { 7391437cf11Sbill toflop(name, bufp->st_size, dope); 7401437cf11Sbill return (0); 7411437cf11Sbill } 74219ec2be6Sroot printf("%s: internal error, added then not found\n", name); 74319ec2be6Sroot return (-1); 7441437cf11Sbill } 745c09a6a34Ssam 746d0b9e33eSwnj mkent(de, segnum, bufp, name) 7471437cf11Sbill register struct rt_ent *de; 748d0b9e33eSwnj int segnum; 7491437cf11Sbill register struct stat *bufp; 7501437cf11Sbill char *name; 7511437cf11Sbill { 752c09a6a34Ssam struct tm *localtime(); 753c09a6a34Ssam register struct tm *timp; 754c09a6a34Ssam register struct rt_ent *workp; 755c09a6a34Ssam int count; 7561437cf11Sbill 7571437cf11Sbill count = (((bufp->st_size -1) >>9) + 1); 758c09a6a34Ssam /* make sure there is room */ 7591437cf11Sbill if (de->rt_len == count) 7601437cf11Sbill goto overwrite; 761c09a6a34Ssam if ((char *)rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) { 762*2e5d0128Sbloom /* no entries left on segment, trying adding new segment */ 763*2e5d0128Sbloom if (rt_dir[0].rd_numseg > rt_dir[0].rd_lstseg) { 764*2e5d0128Sbloom short newseg; 765*2e5d0128Sbloom register int i; 766*2e5d0128Sbloom int maxseg; 767*2e5d0128Sbloom short size; 768*2e5d0128Sbloom 769*2e5d0128Sbloom newseg = rt_dir[0].rd_lstseg++; 770*2e5d0128Sbloom rt_dir[newseg] = rt_nulldir; 771*2e5d0128Sbloom rt_dir[newseg].rd_nxtseg = rt_dir[segnum].rd_nxtseg; 772*2e5d0128Sbloom rt_dir[segnum].rd_nxtseg = newseg + 1; 773*2e5d0128Sbloom rt_dir[newseg].rd_entpad = rt_dir[0].rd_entpad; 774*2e5d0128Sbloom rt_dir[newseg].rd_numseg = rt_dir[0].rd_numseg; 775*2e5d0128Sbloom size = 0; 776*2e5d0128Sbloom maxseg = 0; 777*2e5d0128Sbloom for(i = newseg - 1; i >= 0; i--) { 778*2e5d0128Sbloom workp = rt_curend[i] - 1; 779*2e5d0128Sbloom if (workp->rt_stat != RT_NULL) 780*2e5d0128Sbloom continue; 781*2e5d0128Sbloom if (workp->rt_len < size) 782*2e5d0128Sbloom continue; 783*2e5d0128Sbloom size = workp->rt_len; 784*2e5d0128Sbloom maxseg = i; 785*2e5d0128Sbloom } 786*2e5d0128Sbloom size = 0; 787*2e5d0128Sbloom for (workp = &rt_dir[maxseg].rt_ents[0]; 788*2e5d0128Sbloom workp->rt_stat != RT_ESEG; workp++) { 789*2e5d0128Sbloom size += workp->rt_len; 790*2e5d0128Sbloom } 791*2e5d0128Sbloom workp--; 792*2e5d0128Sbloom rt_dir[newseg].rt_ents[0].rt_len = workp->rt_len; 793*2e5d0128Sbloom rt_dir[newseg].rd_stfile = 794*2e5d0128Sbloom rt_dir[maxseg].rd_stfile + size - workp->rt_len; 795*2e5d0128Sbloom workp->rt_len = 0; 796*2e5d0128Sbloom rt_curend[newseg] = &rt_dir[newseg].rt_ents[1]; 797*2e5d0128Sbloom lwrite(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]); 798*2e5d0128Sbloom if (segnum != 0) 799*2e5d0128Sbloom lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, 800*2e5d0128Sbloom (char *)&rt_dir[segnum]); 801*2e5d0128Sbloom lwrite((6+newseg*2)*RT_BLOCK, 2*RT_BLOCK, 802*2e5d0128Sbloom (char *)&rt_dir[newseg]); 803*2e5d0128Sbloom segnum = newseg; 804*2e5d0128Sbloom de = &rt_dir[newseg].rt_ents[0]; 805*2e5d0128Sbloom } else { 806*2e5d0128Sbloom fprintf(stderr, "All directory segments full on %s\n", 807*2e5d0128Sbloom defdev); 8081437cf11Sbill exit(1); 8091437cf11Sbill } 810*2e5d0128Sbloom } 8111437cf11Sbill /* copy directory entries up */ 812d0b9e33eSwnj for (workp = rt_curend[segnum]+1; workp > de; workp--) 8131437cf11Sbill *workp = workp[-1]; 8141437cf11Sbill de[1].rt_len -= count; 8151437cf11Sbill de->rt_len = count; 816d0b9e33eSwnj rt_curend[segnum]++; 8171437cf11Sbill rt_nleft--; 818c09a6a34Ssam 8191437cf11Sbill overwrite: 8201437cf11Sbill srad50(name,de->rt_name); 8211437cf11Sbill timp = localtime(&bufp->st_mtime); 822b566105aSwnj de->rt_date.rt_dy = timp->tm_mday; 8231437cf11Sbill de->rt_date.rt_mo = timp->tm_mon + 1; 8241437cf11Sbill de->rt_date.rt_yr = timp->tm_year - 72; 8251437cf11Sbill de->rt_stat = RT_FILE; 8261437cf11Sbill de->rt_pad = 0; 8271437cf11Sbill de->rt_chan = 0; 8281437cf11Sbill de->rt_job = 0; 829d0b9e33eSwnj lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[segnum]); 8301437cf11Sbill } 8311437cf11Sbill 8321437cf11Sbill toflop(name, ocount, dope) 8331437cf11Sbill char *name; 8341437cf11Sbill register FLDOPE *dope; 8351437cf11Sbill long ocount; 8361437cf11Sbill { 8371437cf11Sbill register file, n, startad = dope->startad, count = ocount; 8381437cf11Sbill char buff[512]; 8391437cf11Sbill 8401437cf11Sbill file = open(name, 0); 8411437cf11Sbill if (file < 0) { 842c09a6a34Ssam fprintf(stderr, "arff: couldn't open %s\n",name); 843c09a6a34Ssam exit(1); 844c09a6a34Ssam } 8451437cf11Sbill for( ; count >= 512; count -= 512) { 846*2e5d0128Sbloom (void) read(file, buff, 512); 8471437cf11Sbill lwrite(startad, 512, buff); 8481437cf11Sbill startad += 512; 8491437cf11Sbill } 850*2e5d0128Sbloom (void) read(file, buff, count); 851*2e5d0128Sbloom (void) close(file); 852c09a6a34Ssam if (count <= 0) 853c09a6a34Ssam return; 854c09a6a34Ssam for (n = count; n < 512; n ++) 855c09a6a34Ssam buff[n] = 0; 8561437cf11Sbill lwrite(startad, 512, buff); 8571437cf11Sbill count = (dope->rtdope->rt_len*512-ocount)/512 ; 858c09a6a34Ssam if (count <= 0) 859c09a6a34Ssam return; 8601437cf11Sbill for ( ; count > 0 ; count--) { 8611437cf11Sbill startad += 512; 8621437cf11Sbill lwrite(startad, 512, zeroes); 8631437cf11Sbill } 8641437cf11Sbill } 865c09a6a34Ssam 8661437cf11Sbill dcmd() 8671437cf11Sbill { 8681437cf11Sbill register int i; 8691437cf11Sbill 8701437cf11Sbill rt_init(); 8711437cf11Sbill if (namc) 8721437cf11Sbill for (i = 0; i < namc; i++) 873c09a6a34Ssam if (rtk(namv[i])==0) 874c09a6a34Ssam namv[i]=0; 8751437cf11Sbill if (dirdirty) 8761437cf11Sbill scrunch(); 8771437cf11Sbill } 878c09a6a34Ssam 8791437cf11Sbill rtk(name) 8801437cf11Sbill char *name; 8811437cf11Sbill { 8821437cf11Sbill register FLDOPE *dope; 8831437cf11Sbill register struct rt_ent *de; 8841437cf11Sbill FLDOPE *lookup(); 8851437cf11Sbill 8861437cf11Sbill if (dope = lookup(name)) { 8871437cf11Sbill printf("d - %s\n",name); 8881437cf11Sbill de = dope->rtdope; 8891437cf11Sbill de->rt_stat = RT_NULL; 8901437cf11Sbill de->rt_name[0] = 0; 8911437cf11Sbill de->rt_name[1] = 0; 8921437cf11Sbill de->rt_name[2] = 0; 893c09a6a34Ssam *((u_short *)&(de->rt_date)) = 0; 8941437cf11Sbill dirdirty = 1; 8951437cf11Sbill return (0); 8961437cf11Sbill } 8971437cf11Sbill return (1); 8981437cf11Sbill } 899c09a6a34Ssam 900c09a6a34Ssam scrunch() 901c09a6a34Ssam { 902d0b9e33eSwnj register struct rt_ent *de , *workp; 903d0b9e33eSwnj register segnum; 904c09a6a34Ssam 905c09a6a34Ssam for (segnum = 0; segnum != -1; 906*2e5d0128Sbloom segnum = rt_dir[segnum].rd_nxtseg - 1) { 907c09a6a34Ssam for (de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++) 908b74381a6Ssam if (de->rt_stat == RT_NULL && 909254d8466Shelge (de+1)->rt_stat == RT_NULL) { 9101437cf11Sbill (de+1)->rt_len += de->rt_len; 911d0b9e33eSwnj for (workp=de; workp<rt_curend[segnum]; workp++) 9121437cf11Sbill *workp = workp[1]; 9131437cf11Sbill de--; 914d0b9e33eSwnj rt_curend[segnum]--; 9151437cf11Sbill rt_nleft++; 9161437cf11Sbill } 917c09a6a34Ssam lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, 918c09a6a34Ssam (char *)&rt_dir[segnum]); 919d0b9e33eSwnj } 920254d8466Shelge dirdirty = 0; 9211437cf11Sbill } 922