1*48343Sbostic /*-
2*48343Sbostic * Copyright (c) 1980 The Regents of the University of California.
3*48343Sbostic * All rights reserved.
4*48343Sbostic *
5*48343Sbostic * %sccs.include.proprietary.c%
622483Sdist */
722483Sdist
89877Ssam #ifndef lint
922483Sdist char copyright[] =
10*48343Sbostic "@(#) Copyright (c) 1980 The Regents of the University of California.\n\
1122483Sdist All rights reserved.\n";
12*48343Sbostic #endif /* not lint */
134879Ssam
1422483Sdist #ifndef lint
15*48343Sbostic static char sccsid[] = "@(#)arff.c 5.8 (Berkeley) 04/18/91";
16*48343Sbostic #endif /* not lint */
1722483Sdist
18954Sbill #include <sys/types.h>
19954Sbill #include <sys/stat.h>
2013605Ssam #include <sys/time.h>
2137979Sbostic #include <sys/signal.h>
2237979Sbostic #include <sys/file.h>
23954Sbill #include <stdio.h>
2437979Sbostic #include "pathnames.h"
254879Ssam
26954Sbill #define dbprintf printf
274879Ssam
28954Sbill struct rt_dat {
294879Ssam u_short rt_yr:5; /* year-1972 */
304879Ssam u_short rt_dy:5; /* day */
314879Ssam u_short rt_mo:5; /* month */
32954Sbill };
334879Ssam
34954Sbill struct rt_axent {
35954Sbill char rt_sent[14];
36954Sbill };
37954Sbill
38954Sbill struct rt_ent {
394879Ssam char rt_pad; /* unusued */
4030238Sbostic u_char rt_stat; /* type of entry, or end of seg */
414879Ssam u_short rt_name[3]; /* name, 3 words in rad50 form */
427319Swnj u_short rt_len; /* length of file */
4330238Sbostic u_char rt_chan; /* only used in temporary files */
444879Ssam char rt_job; /* only used in temporary files */
459877Ssam struct rt_dat rt_date; /* creation date */
46954Sbill };
474879Ssam
484879Ssam #define RT_TEMP 1
494879Ssam #define RT_NULL 2
504879Ssam #define RT_FILE 4
5130238Sbostic #define RT_PFILE (0200|RT_FILE) /* protected file */
524879Ssam #define RT_ESEG 8
534879Ssam
544879Ssam #define RT_BLOCK 512 /* block size */
554879Ssam #define RT_DIRSIZE 31 /* max # of directory segments */
564879Ssam
57954Sbill struct rt_head {
584879Ssam short rt_numseg; /* # of segments available */
594879Ssam short rt_nxtseg; /* # of next logical segment */
604879Ssam short rt_lstseg; /* highest seg currently open */
614879Ssam u_short rt_entpad; /* extra words/directory entry */
624879Ssam short rt_stfile; /* block # where files begin */
63954Sbill };
644879Ssam
65954Sbill struct rt_dir {
66954Sbill struct rt_head rt_axhead;
67954Sbill struct rt_ent rt_ents[72];
684879Ssam char _dirpad[6];
69954Sbill };
704879Ssam
7126131Sbloom #define rd_numseg rt_axhead.rt_numseg
7226131Sbloom #define rd_nxtseg rt_axhead.rt_nxtseg
7326131Sbloom #define rd_lstseg rt_axhead.rt_lstseg
7426131Sbloom #define rd_entpad rt_axhead.rt_entpad
7526131Sbloom #define rd_stfile rt_axhead.rt_stfile
7626131Sbloom
77954Sbill typedef struct fldope {
78954Sbill int startad;
79954Sbill int count;
80954Sbill struct rt_ent *rtdope;
81954Sbill } FLDOPE;
824879Ssam
83954Sbill FLDOPE *lookup();
844879Ssam
859877Ssam #define rt(p) ((struct rt_ent *) p )
869877Ssam #define Ain1 03100
879877Ssam #define Ain2 050
889877Ssam #define flag(c) (flg[('c') - 'a'])
89954Sbill
909877Ssam char *man = "rxtd";
919877Ssam char zeroes[512];
92954Sbill
93954Sbill extern char *val;
94954Sbill extern char table[256];
954879Ssam struct rt_dir rt_dir[RT_DIRSIZE] = {
9633133Sbostic {
979877Ssam { 4, 0, 1, 0, 14 },
9826131Sbloom { { 0, RT_NULL, { 0, 0, 0 }, 486, 0 },
999877Ssam { 0, RT_ESEG } }
10033133Sbostic }
1014879Ssam };
102954Sbill
10326131Sbloom struct rt_dir rt_nulldir = {
10426131Sbloom { 0, 0, 0, 0, 0 },
10526131Sbloom { { 0, RT_NULL, { 0, 0, 0 }, 0, 0 },
10626131Sbloom { 0, RT_ESEG } }
10726131Sbloom };
10826131Sbloom
1094879Ssam int rt_entsiz;
1104879Ssam int rt_nleft;
1114879Ssam struct rt_ent *rt_curend[RT_DIRSIZE];
1124879Ssam int floppydes;
1134879Ssam int dirdirty;
1144879Ssam char *rt_last;
11537979Sbostic char *defdev = _PATH_FLOPPY;
116954Sbill
11726131Sbloom char *opt = "vfbcm";
1184879Ssam
1194879Ssam extern long lseek();
1204879Ssam int rcmd(), dcmd(), xcmd(), tcmd();
1214879Ssam
122954Sbill int (*comfun)();
123954Sbill char flg[26];
124954Sbill char **namv;
125954Sbill int namc;
126954Sbill
main(argc,argv)127954Sbill main(argc, argv)
1284879Ssam char *argv[];
129954Sbill {
130954Sbill register char *cp;
131954Sbill
1324879Ssam if (argc < 2)
133954Sbill usage();
1344879Ssam for (cp = argv[1]; *cp; cp++)
1354879Ssam switch (*cp) {
136954Sbill
1374879Ssam case 'm':
1384879Ssam case 'v':
1394879Ssam case 'u':
1404879Ssam case 'w':
14126131Sbloom case 'b':
1424879Ssam flg[*cp-'a']++;
1434879Ssam continue;
1444879Ssam case 'c':
14513910Ssam flag(c)++;
1464879Ssam dirdirty++;
1474879Ssam continue;
148954Sbill
1494879Ssam case 'r':
1504879Ssam setcom(rcmd);
1514879Ssam flag(r)++;
1524879Ssam continue;
153954Sbill
1544879Ssam case 'd':
1554879Ssam setcom(dcmd);
1564879Ssam flag(d)++;
1574879Ssam continue;
158954Sbill
1594879Ssam case 'x':
1604879Ssam setcom(xcmd);
1614879Ssam continue;
162954Sbill
1634879Ssam case 't':
1644879Ssam setcom(tcmd);
1654879Ssam continue;
166954Sbill
1674879Ssam case 'f':
1684879Ssam defdev = argv[2];
1694879Ssam argv++;
1704879Ssam argc--;
1714879Ssam continue;
1724879Ssam
1734879Ssam default:
1744879Ssam fprintf(stderr, "arff: bad option `%c'\n", *cp);
1754879Ssam exit(1);
1764879Ssam }
1774879Ssam
178954Sbill namv = argv+2;
179954Sbill namc = argc-2;
1804879Ssam if (comfun == 0) {
1814879Ssam if (flag(u) == 0) {
1824879Ssam fprintf(stderr, "arff: one of [%s] must be specified\n",
1834879Ssam man);
184954Sbill exit(1);
185954Sbill }
186954Sbill setcom(rcmd);
187954Sbill }
188954Sbill (*comfun)();
189954Sbill exit(notfound());
190954Sbill }
191954Sbill
192954Sbill setcom(fun)
1934879Ssam int (*fun)();
194954Sbill {
1954879Ssam if (comfun != 0) {
196954Sbill fprintf(stderr, "arff: only one of [%s] allowed\n", man);
197954Sbill exit(1);
198954Sbill }
199954Sbill comfun = fun;
200954Sbill }
201954Sbill
usage()202954Sbill usage()
203954Sbill {
2043356Swnj fprintf(stderr, "usage: ar [%s][%s] archive files ...\n", opt, man);
205954Sbill exit(1);
206954Sbill }
207954Sbill
notfound()208954Sbill notfound()
209954Sbill {
2104879Ssam register i, n = 0;
211954Sbill
2124879Ssam for (i = 0; i < namc; i++)
2134879Ssam if (namv[i]) {
214954Sbill fprintf(stderr, "arff: %s not found\n", namv[i]);
215954Sbill n++;
216954Sbill }
2179877Ssam return (n);
218954Sbill }
219954Sbill
tcmd()220954Sbill tcmd()
221954Sbill {
2224879Ssam register char *de, *last;
223954Sbill FLDOPE *lookup(), *dope;
2244879Ssam int segnum, nleft;
2254879Ssam register i;
226954Sbill register struct rt_ent *rde;
227954Sbill
228954Sbill rt_init();
2299877Ssam if (namc != 0) {
2304879Ssam for (i = 0; i < namc; i++)
2314879Ssam if (dope = lookup(namv[i])) {
232954Sbill rde = dope->rtdope;
23326131Sbloom (void) rtls(rde);
234954Sbill namv[i] = 0;
235954Sbill }
2369877Ssam return;
2379877Ssam }
2389877Ssam for (segnum = 0; segnum != -1;
23926131Sbloom segnum = rt_dir[segnum].rd_nxtseg - 1) {
2409877Ssam last = rt_last + segnum*2*RT_BLOCK;
2419877Ssam for (de = ((char *)&rt_dir[segnum])+10; de <= last;
2429877Ssam de += rt_entsiz)
2439877Ssam if (rtls(rt(de))) {
2449877Ssam nleft = (last-de)/rt_entsiz;
2459877Ssam #define ENTRIES "\n%d entries remaining in directory segment %d.\n"
2469877Ssam printf(ENTRIES, nleft, segnum+1);
2479877Ssam break;
2489877Ssam }
2499877Ssam }
250954Sbill }
2514879Ssam
rtls(de)252954Sbill rtls(de)
2534879Ssam register struct rt_ent *de;
254954Sbill {
2554879Ssam int month, day, year;
256954Sbill char name[12], ext[4];
257954Sbill
2584879Ssam switch (de->rt_stat) {
2594879Ssam
2604879Ssam case RT_TEMP:
2614879Ssam if (flag(v))
262954Sbill printf("Tempfile:\n");
2634879Ssam /* fall thru...*/
264954Sbill
2654879Ssam case RT_FILE:
26630238Sbostic case RT_PFILE:
2674879Ssam if (!flag(v)) {
2684879Ssam sunrad50(name, de->rt_name);
2694879Ssam printf("%s\n", name);
270954Sbill break;
271954Sbill }
2724879Ssam unrad50(2, de->rt_name, name);
2734879Ssam unrad50(1, &(de->rt_name[2]), ext);
2744879Ssam day = de->rt_date.rt_dy;
2754879Ssam year = de->rt_date.rt_yr+72;
2764879Ssam month = de->rt_date.rt_mo;
2774879Ssam printf("%6.6s %3.3s %02d/%02d/%02d %d\n",name,
2784879Ssam ext, month, day, year, de->rt_len);
2794879Ssam break;
280954Sbill
2814879Ssam case RT_NULL:
2824879Ssam printf("%-25.9s %d\n","<UNUSED>", de->rt_len);
2834879Ssam break;
284954Sbill
2854879Ssam case RT_ESEG:
2869877Ssam return (1);
287954Sbill }
2889877Ssam return (0);
289954Sbill }
2904879Ssam
xcmd()291954Sbill xcmd()
292954Sbill {
2934879Ssam register char *de, *last;
2943346Swnj int segnum;
295954Sbill char name[12];
296954Sbill register int i;
297954Sbill
298954Sbill rt_init();
2999877Ssam if (namc != 0) {
3004879Ssam for (i = 0; i < namc; i++)
3014879Ssam if (rtx(namv[i]) == 0)
3024879Ssam namv[i] = 0;
3039877Ssam return;
3049877Ssam }
3059877Ssam for (segnum = 0; segnum != -1;
30626131Sbloom segnum = rt_dir[segnum].rd_nxtseg-1)
3079877Ssam for (last = rt_last+(segnum*2*RT_BLOCK),
3089877Ssam de = ((char *)&rt_dir[segnum])+10; de <= last;
30915553Sralph de += rt_entsiz) {
3109877Ssam switch (rt(de)->rt_stat) {
3119877Ssam
3129877Ssam case RT_ESEG:
31315553Sralph break; /* exit loop and try next segment */
3149877Ssam
3159877Ssam case RT_TEMP:
3169877Ssam case RT_FILE:
31730238Sbostic case RT_PFILE:
3189877Ssam sunrad50(name,rt(de)->rt_name);
31926131Sbloom (void) rtx(name);
3209877Ssam
3219877Ssam case RT_NULL:
32215553Sralph default:
32315553Sralph continue;
3249877Ssam }
32515553Sralph break;
32615553Sralph }
327954Sbill }
3284879Ssam
rtx(name)329954Sbill rtx(name)
3304879Ssam char *name;
331954Sbill {
332954Sbill register FLDOPE *dope;
333954Sbill FLDOPE *lookup();
334954Sbill register startad, count;
3354879Ssam int file;
3364879Ssam char buff[512];
337954Sbill
338954Sbill
3394879Ssam if (dope = lookup(name)) {
3404879Ssam if (flag(v))
34126131Sbloom (void) rtls(dope->rtdope);
342954Sbill else
343954Sbill printf("x - %s\n",name);
344954Sbill
3454879Ssam if ((file = creat(name, 0666)) < 0)
3469877Ssam return (1);
347954Sbill count = dope->count;
348954Sbill startad = dope->startad;
349954Sbill for( ; count > 0 ; count -= 512) {
35029823Skarels (void) lread(startad, 512, buff);
35126131Sbloom (void) write(file, buff, 512);
352954Sbill startad += 512;
353954Sbill }
35426131Sbloom (void) close(file);
3559877Ssam return (0);
356954Sbill }
3579877Ssam return (1);
358954Sbill }
3594879Ssam
rt_init()360954Sbill rt_init()
361954Sbill {
362954Sbill static initized = 0;
3634879Ssam register char *de, *last;
3643346Swnj register i;
3653799Shickman int dirnum;
3663799Shickman char *mode;
3673799Shickman FILE *temp_floppydes;
368954Sbill
3694879Ssam if (initized)
3704879Ssam return;
371954Sbill initized = 1;
37213910Ssam if (flag(c)) {
37313910Ssam struct stat sb;
37413910Ssam char response[128];
37513910Ssam int tty;
37613910Ssam
37713910Ssam if (stat(defdev, &sb) >= 0 && (sb.st_mode & S_IFMT) == S_IFREG)
37813910Ssam goto ignore;
37937979Sbostic tty = open(_PATH_TTY, O_RDWR);
38013910Ssam #define SURE "Are you sure you want to clobber the floppy? "
38126131Sbloom (void) write(tty, SURE, sizeof (SURE));
38226131Sbloom (void) read(tty, response, sizeof (response));
38313910Ssam if (*response != 'y')
38413910Ssam exit(50);
38526131Sbloom (void) close(tty);
38613910Ssam ignore:
38713910Ssam ;
38813910Ssam }
3894879Ssam if (flag(c) || flag(d) || flag(r))
3903799Shickman mode = "r+";
391954Sbill else
3923799Shickman mode = "r";
3934879Ssam if ((temp_floppydes = fopen(defdev, mode)) == NULL) {
3943799Shickman perror(defdev);
3953356Swnj exit(1);
3963799Shickman } else
3973799Shickman floppydes = fileno(temp_floppydes);
3984879Ssam if (!flag(c)) {
39929823Skarels if (lread(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]))
40029823Skarels exit(2);
40126131Sbloom dirnum = rt_dir[0].rd_numseg;
40212012Shelge /* check for blank/uninitialized diskette */
40312012Shelge if (dirnum <= 0) {
40412012Shelge fprintf(stderr,"arff: bad directory format\n");
40512012Shelge exit(1);
40612012Shelge }
4073346Swnj if (dirnum > RT_DIRSIZE) {
4084879Ssam fprintf(stderr,"arff: too many directory segments\n");
4094879Ssam exit(1);
4103346Swnj }
4114879Ssam for (i = 1; i < dirnum; i++)
41229823Skarels if (lread((6+2*i)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[i]))
41329823Skarels exit(1);
41426131Sbloom } else {
4153489Sroot dirnum = 1;
41626131Sbloom if (flag(b)) {
41726131Sbloom rt_dir[0].rd_numseg = 31;
41826131Sbloom rt_dir[0].rd_stfile = 68;
41926131Sbloom rt_dir[0].rt_ents[0].rt_len = 20480 - 68;
42026131Sbloom }
42126131Sbloom }
422954Sbill
42326131Sbloom rt_entsiz = 2*rt_dir[0].rd_entpad + 14;
42426131Sbloom /*
42526131Sbloom * We assume that the directory entries have no padding. This
42626131Sbloom * may not be a valid assumption, but there are numerous point
42726131Sbloom * in the code where it assumes it is an rt_ent structure and
42826131Sbloom * not an rt_entsiz sized structure.
42926131Sbloom */
43026131Sbloom rt_entsiz = 14;
4313346Swnj rt_last = ((char *) &rt_dir[0]) + 10 + 1014/rt_entsiz*rt_entsiz;
4323346Swnj rt_nleft = 0;
4333346Swnj
4344879Ssam for (i = 0; i < dirnum; i++) {
4354879Ssam last = rt_last + i*2*RT_BLOCK;
4364879Ssam for (de = ((char *)&rt_dir[i])+10; de <= last; de += rt_entsiz)
4374879Ssam if (rt(de)->rt_stat == RT_ESEG)
4384879Ssam break;
4394879Ssam rt_curend[i] = rt(de);
4404879Ssam rt_nleft += (last-de)/rt_entsiz;
441954Sbill }
442954Sbill }
443954Sbill
444954Sbill static FLDOPE result;
4454879Ssam
446954Sbill FLDOPE *
lookup(name)447954Sbill lookup(name)
4484879Ssam char *name;
449954Sbill {
450954Sbill unsigned short rname[3];
45126131Sbloom register char *de;
4523346Swnj int segnum;
453954Sbill register index;
454954Sbill
455954Sbill srad50(name,rname);
456954Sbill
4573356Swnj /*
458954Sbill * Search for name, accumulate blocks in index
459954Sbill */
460954Sbill rt_init();
4614879Ssam for (segnum = 0; segnum != -1;
46226131Sbloom segnum = rt_dir[segnum].rd_nxtseg - 1)
4634879Ssam {
4644879Ssam index = 0;
4654879Ssam for (de=((char *)&rt_dir[segnum])+10;
4664879Ssam rt(de)->rt_stat != RT_ESEG; de += rt_entsiz)
4674879Ssam switch(rt(de)->rt_stat) {
4684879Ssam
4694879Ssam case RT_FILE:
47030238Sbostic case RT_PFILE:
4714879Ssam case RT_TEMP:
4724879Ssam if(samename(rname,rt(de)->rt_name)) {
4734879Ssam result.count = rt(de)->rt_len * 512;
4744879Ssam result.startad = 512*
47526131Sbloom (rt_dir[segnum].rd_stfile + index);
4764879Ssam result.rtdope = (struct rt_ent *) de;
4779877Ssam return (&result);
4784879Ssam }
4794879Ssam
4804879Ssam case RT_NULL:
4814879Ssam index += rt(de)->rt_len;
4824879Ssam }
4833346Swnj }
4849877Ssam return ((FLDOPE *) 0);
4854879Ssam
486954Sbill }
4874879Ssam
488954Sbill static
samename(a,b)4894879Ssam samename(a, b)
4904879Ssam u_short a[], b[];
491954Sbill {
4929877Ssam return (*a == *b && a[1] == b[1] && a[2] == b[2] );
493954Sbill }
494954Sbill
rad50(cp,out)4954879Ssam rad50(cp, out)
4964879Ssam register u_char *cp;
4974879Ssam u_short *out;
498954Sbill {
4994879Ssam register index, temp;
500954Sbill
5014879Ssam for (index = 0; *cp; index++) {
502954Sbill temp = Ain1 * table[*cp++];
5034879Ssam if (*cp!=0) {
504954Sbill temp += Ain2 * table[*cp++];
505954Sbill if(*cp!=0)
506954Sbill temp += table[*cp++];
507954Sbill }
508954Sbill out[index] = temp;
509954Sbill }
510954Sbill }
511954Sbill
5124879Ssam #define reduce(x, p, q) (x = v[p/q], p %= q);
5134879Ssam
unrad50(count,in,cp)5144879Ssam unrad50(count, in, cp)
5154879Ssam u_short *in;
5164879Ssam register char *cp;
517954Sbill {
5184879Ssam register i, temp;
5194879Ssam register u_char *v = (u_char *) val;
520954Sbill
5214879Ssam for (i = 0; i < count; i++) {
522954Sbill temp = in[i];
5234879Ssam reduce(*cp++, temp, Ain1);
5244879Ssam reduce(*cp++, temp, Ain2);
5254879Ssam reduce(*cp++, temp, 1);
526954Sbill }
527954Sbill *cp=0;
528954Sbill }
529954Sbill
srad50(name,rname)5304879Ssam srad50(name, rname)
5314879Ssam register char *name;
5324879Ssam register u_short *rname;
533954Sbill {
5344879Ssam register index;
5354879Ssam register char *cp;
5364879Ssam char file[7], ext[4];
5374879Ssam
5383356Swnj /*
539954Sbill * Find end of pathname
540954Sbill */
5414879Ssam for (cp = name; *cp++; )
5424879Ssam ;
5434879Ssam while (cp >= name && *--cp != '/')
5444879Ssam ;
545954Sbill cp++;
5463356Swnj /*
547954Sbill * Change to rad50
548954Sbill */
5494879Ssam for (index = 0; *cp; ) {
550954Sbill file[index++] = *cp++;
5514879Ssam if (*cp == '.') {
552954Sbill cp++;
553954Sbill break;
554954Sbill }
5554879Ssam if (index >= 6) {
556954Sbill break;
557954Sbill }
558954Sbill }
559954Sbill file[index] = 0;
5604879Ssam for (index = 0; *cp; ) {
561954Sbill ext[index++] = *cp++;
5624879Ssam if (*cp == '.' || index >= 3)
563954Sbill break;
564954Sbill }
565954Sbill ext[index]=0;
5664879Ssam rname[0] = rname[1] = rname[2] = 0;
5674879Ssam rad50((u_char *)file, rname);
5684879Ssam rad50((u_char *)ext, rname+2);
569954Sbill }
5704879Ssam
sunrad50(name,rname)5714879Ssam sunrad50(name, rname)
5724879Ssam u_short rname[];
5734879Ssam register char *name;
574954Sbill {
575954Sbill register char *cp, *cp2;
576954Sbill char ext[4];
577954Sbill
5784879Ssam unrad50(2, rname, name);
5794879Ssam unrad50(1, rname + 2, ext);
5804879Ssam /*
5814879Ssam * Jam name and extension together with a dot
5824879Ssam * deleting white space
5834879Ssam */
5844879Ssam for (cp = name; *cp++;)
5854879Ssam ;
5864879Ssam --cp;
5874879Ssam while (*--cp == ' ' && cp >= name)
5884879Ssam ;
5894879Ssam *++cp = '.';
5904879Ssam cp++;
5914879Ssam for (cp2 = ext; *cp2 != ' ' && cp2 < ext+3;)
592954Sbill *cp++ = *cp2++;
593954Sbill *cp=0;
5944879Ssam if (cp[-1] == '.')
5954879Ssam cp[-1] = 0;
596954Sbill }
597954Sbill
598954Sbill static char *val = " abcdefghijklmnopqrstuvwxyz$.@0123456789";
5994879Ssam
600954Sbill static char table[256] = {
601954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
602954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
603954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
604954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
605954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
606954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
607954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
608954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
609954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
610954Sbill 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
611954Sbill 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
612954Sbill 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
613954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
614954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
615954Sbill 29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
616954Sbill 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 };
617954Sbill
6184879Ssam /*
6194879Ssam * Logical to physical adress translation
6204879Ssam */
6214879Ssam long
trans(logical)6224879Ssam trans(logical)
6234879Ssam register int logical;
624954Sbill {
625954Sbill register int sector, bytes, track;
626954Sbill
6274879Ssam logical += 26*128;
6284879Ssam bytes = (logical&127);
629954Sbill logical >>= 7;
6304879Ssam sector = logical%26;
631954Sbill if(sector >= 13)
6324879Ssam sector = sector*2+1;
633954Sbill else
634954Sbill sector *= 2;
6354879Ssam sector += 26 + ((track = (logical/26))-1)*6;
636954Sbill sector %= 26;
6379877Ssam return ((((track*26)+sector) << 7) + bytes);
638954Sbill }
6394879Ssam
lread(startad,count,obuff)6404879Ssam lread(startad, count, obuff)
6414879Ssam register startad, count;
6424879Ssam register char *obuff;
643954Sbill {
644954Sbill long trans();
645954Sbill extern floppydes;
6464879Ssam register int size = flag(m) ? 512 : 128;
64729823Skarels int error = 0;
64829823Skarels extern int errno;
6494879Ssam
650954Sbill rt_init();
6514879Ssam while ((count -= size) >= 0) {
65226131Sbloom (void) lseek(floppydes, flag(m) ?
6534879Ssam (long)startad : trans(startad), 0);
65429823Skarels if (read(floppydes, obuff, size) != size) {
65529823Skarels error = errno;
65629823Skarels fprintf(stderr, "arff: read error block %d: ",
6574879Ssam startad/size);
65829823Skarels errno = error;
65929823Skarels perror("");
66029823Skarels }
6614879Ssam obuff += size;
6624879Ssam startad += size;
6634879Ssam }
66429823Skarels return (error);
665954Sbill }
6664879Ssam
lwrite(startad,count,obuff)6674879Ssam lwrite(startad, count, obuff)
6684879Ssam register startad, count;
6694879Ssam register char *obuff;
670954Sbill {
671954Sbill long trans();
672954Sbill extern floppydes;
6734879Ssam register int size = flag(m) ? 512 : 128;
6744879Ssam
675954Sbill rt_init();
6764879Ssam while ((count -= size) >= 0) {
67726131Sbloom (void) lseek(floppydes, flag(m) ?
6784879Ssam (long)startad : trans(startad), 0);
6794879Ssam if (write(floppydes, obuff, size) != size)
6804879Ssam fprintf(stderr, "arff: write error block %d\n",
6814879Ssam startad/size);
6824879Ssam obuff += size;
6834879Ssam startad += size;
6844879Ssam }
685954Sbill }
686954Sbill
rcmd()687954Sbill rcmd()
688954Sbill {
689954Sbill register int i;
690954Sbill
691954Sbill rt_init();
6924879Ssam if (namc > 0)
6934879Ssam for (i = 0; i < namc; i++)
6944879Ssam if (rtr(namv[i]) == 0)
6954879Ssam namv[i] = 0;
696954Sbill }
697954Sbill
rtr(name)698954Sbill rtr(name)
6994879Ssam char *name;
700954Sbill {
7014879Ssam register FLDOPE *dope;
7024879Ssam register struct rt_ent *de;
7034879Ssam struct stat buf;
7044879Ssam register struct stat *bufp = &buf;
7053346Swnj int segnum;
70626131Sbloom char type;
707954Sbill
7084879Ssam if (stat(name, bufp) < 0) {
7093489Sroot perror(name);
7109877Ssam return (-1);
7113489Sroot }
71226131Sbloom type = 'a';
7134879Ssam if (dope = lookup(name)) {
714954Sbill /* can replace, no problem */
715954Sbill de = dope->rtdope;
71626131Sbloom if (bufp->st_size <= (de->rt_len * 512)) {
71726131Sbloom printf("r - %s\n",name);
7184879Ssam toflop(name, bufp->st_size, dope);
71926131Sbloom goto found;
72026131Sbloom } else {
72126131Sbloom de = dope->rtdope;
72226131Sbloom type = 'r';
72326131Sbloom de->rt_stat = RT_NULL;
72426131Sbloom de->rt_name[0] = 0;
72526131Sbloom de->rt_name[1] = 0;
72626131Sbloom de->rt_name[2] = 0;
72726131Sbloom *((u_short *)&(de->rt_date)) = 0;
72826131Sbloom scrunch();
729954Sbill }
7309877Ssam }
7319877Ssam /*
7329877Ssam * Search for vacant spot
7339877Ssam */
7349877Ssam for (segnum = 0; segnum != -1;
73526131Sbloom segnum = rt_dir[segnum].rd_nxtseg - 1)
7369877Ssam {
7379877Ssam for (de = rt_dir[segnum].rt_ents;
7389877Ssam rt(de)->rt_stat != RT_ESEG; de++)
7399877Ssam if ((de)->rt_stat == RT_NULL) {
7409877Ssam if (bufp->st_size <= (de->rt_len*512)) {
74126131Sbloom printf("%c - %s\n", type, name),
7429877Ssam mkent(de, segnum, bufp,name);
7439877Ssam goto found;
744954Sbill }
7459877Ssam continue;
7469877Ssam }
747954Sbill }
74830998Sbostic if (type == 'r')
74926131Sbloom printf("%s: no slot for file, file deleted\n",name);
75026131Sbloom else
75126131Sbloom printf("%s: no slot for file\n", name);
7529877Ssam return (-1);
7534879Ssam
7544879Ssam found:
7554879Ssam if (dope = lookup(name)) {
7564879Ssam toflop(name, bufp->st_size, dope);
7573489Sroot return (0);
758954Sbill }
7593489Sroot printf("%s: internal error, added then not found\n", name);
7603489Sroot return (-1);
7614879Ssam }
762954Sbill
mkent(de,segnum,bufp,name)7634879Ssam mkent(de, segnum, bufp, name)
7644879Ssam register struct rt_ent *de;
7654879Ssam int segnum;
7664879Ssam register struct stat *bufp;
7674879Ssam char *name;
768954Sbill {
7694879Ssam struct tm *localtime();
7704879Ssam register struct tm *timp;
7714879Ssam register struct rt_ent *workp;
7724879Ssam int count;
773954Sbill
774954Sbill count = (((bufp->st_size -1) >>9) + 1);
7754879Ssam /* make sure there is room */
7764879Ssam if (de->rt_len == count)
777954Sbill goto overwrite;
7784879Ssam if ((char *)rt_curend[segnum] == (rt_last + (segnum*2*RT_BLOCK))) {
77926131Sbloom /* no entries left on segment, trying adding new segment */
78026131Sbloom if (rt_dir[0].rd_numseg > rt_dir[0].rd_lstseg) {
78126131Sbloom short newseg;
78226131Sbloom register int i;
78326131Sbloom int maxseg;
78426131Sbloom short size;
78526131Sbloom
78626131Sbloom newseg = rt_dir[0].rd_lstseg++;
78726131Sbloom rt_dir[newseg] = rt_nulldir;
78826131Sbloom rt_dir[newseg].rd_nxtseg = rt_dir[segnum].rd_nxtseg;
78926131Sbloom rt_dir[segnum].rd_nxtseg = newseg + 1;
79026131Sbloom rt_dir[newseg].rd_entpad = rt_dir[0].rd_entpad;
79126131Sbloom rt_dir[newseg].rd_numseg = rt_dir[0].rd_numseg;
79226131Sbloom size = 0;
79326131Sbloom maxseg = 0;
79426131Sbloom for(i = newseg - 1; i >= 0; i--) {
79526131Sbloom workp = rt_curend[i] - 1;
79626131Sbloom if (workp->rt_stat != RT_NULL)
79726131Sbloom continue;
79826131Sbloom if (workp->rt_len < size)
79926131Sbloom continue;
80026131Sbloom size = workp->rt_len;
80126131Sbloom maxseg = i;
80226131Sbloom }
80326131Sbloom size = 0;
80426131Sbloom for (workp = &rt_dir[maxseg].rt_ents[0];
80526131Sbloom workp->rt_stat != RT_ESEG; workp++) {
80626131Sbloom size += workp->rt_len;
80726131Sbloom }
80826131Sbloom workp--;
80926131Sbloom rt_dir[newseg].rt_ents[0].rt_len = workp->rt_len;
81026131Sbloom rt_dir[newseg].rd_stfile =
81126131Sbloom rt_dir[maxseg].rd_stfile + size - workp->rt_len;
81226131Sbloom workp->rt_len = 0;
81326131Sbloom rt_curend[newseg] = &rt_dir[newseg].rt_ents[1];
81426131Sbloom lwrite(6*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[0]);
81526131Sbloom if (segnum != 0)
81626131Sbloom lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK,
81726131Sbloom (char *)&rt_dir[segnum]);
81826131Sbloom lwrite((6+newseg*2)*RT_BLOCK, 2*RT_BLOCK,
81926131Sbloom (char *)&rt_dir[newseg]);
82026131Sbloom segnum = newseg;
82126131Sbloom de = &rt_dir[newseg].rt_ents[0];
82226131Sbloom } else {
82326131Sbloom fprintf(stderr, "All directory segments full on %s\n",
82426131Sbloom defdev);
82526131Sbloom exit(1);
82626131Sbloom }
827954Sbill }
8284879Ssam /* copy directory entries up */
8294879Ssam for (workp = rt_curend[segnum]+1; workp > de; workp--)
830954Sbill *workp = workp[-1];
831954Sbill de[1].rt_len -= count;
832954Sbill de->rt_len = count;
8333346Swnj rt_curend[segnum]++;
834954Sbill rt_nleft--;
8354879Ssam
836954Sbill overwrite:
837954Sbill srad50(name,de->rt_name);
838954Sbill timp = localtime(&bufp->st_mtime);
8397320Swnj de->rt_date.rt_dy = timp->tm_mday;
840954Sbill de->rt_date.rt_mo = timp->tm_mon + 1;
841954Sbill de->rt_date.rt_yr = timp->tm_year - 72;
842954Sbill de->rt_stat = RT_FILE;
843954Sbill de->rt_pad = 0;
844954Sbill de->rt_chan = 0;
845954Sbill de->rt_job = 0;
8464879Ssam lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK, (char *)&rt_dir[segnum]);
847954Sbill }
848954Sbill
toflop(name,ocount,dope)8494879Ssam toflop(name, ocount, dope)
8504879Ssam char *name;
8514879Ssam register FLDOPE *dope;
8524879Ssam long ocount;
853954Sbill {
854954Sbill register file, n, startad = dope->startad, count = ocount;
855954Sbill char buff[512];
856954Sbill
8574879Ssam file = open(name, 0);
8584879Ssam if (file < 0) {
8594879Ssam fprintf(stderr, "arff: couldn't open %s\n",name);
8604879Ssam exit(1);
8614879Ssam }
862954Sbill for( ; count >= 512; count -= 512) {
86326131Sbloom (void) read(file, buff, 512);
8644879Ssam lwrite(startad, 512, buff);
865954Sbill startad += 512;
866954Sbill }
86726131Sbloom (void) read(file, buff, count);
86826131Sbloom (void) close(file);
8694879Ssam if (count <= 0)
8704879Ssam return;
8714879Ssam for (n = count; n < 512; n ++)
8724879Ssam buff[n] = 0;
8734879Ssam lwrite(startad, 512, buff);
8744879Ssam count = (dope->rtdope->rt_len*512-ocount)/512 ;
8754879Ssam if (count <= 0)
8764879Ssam return;
8774879Ssam for ( ; count > 0 ; count--) {
878954Sbill startad += 512;
8794879Ssam lwrite(startad, 512, zeroes);
880954Sbill }
8814879Ssam }
882954Sbill
dcmd()883954Sbill dcmd()
884954Sbill {
885954Sbill register int i;
886954Sbill
887954Sbill rt_init();
8884879Ssam if (namc)
8894879Ssam for (i = 0; i < namc; i++)
8904879Ssam if (rtk(namv[i])==0)
8914879Ssam namv[i]=0;
8924879Ssam if (dirdirty)
893954Sbill scrunch();
894954Sbill }
8954879Ssam
rtk(name)896954Sbill rtk(name)
8974879Ssam char *name;
898954Sbill {
899954Sbill register FLDOPE *dope;
900954Sbill register struct rt_ent *de;
901954Sbill FLDOPE *lookup();
902954Sbill
9034879Ssam if (dope = lookup(name)) {
904954Sbill printf("d - %s\n",name);
905954Sbill de = dope->rtdope;
906954Sbill de->rt_stat = RT_NULL;
907954Sbill de->rt_name[0] = 0;
908954Sbill de->rt_name[1] = 0;
909954Sbill de->rt_name[2] = 0;
9109877Ssam *((u_short *)&(de->rt_date)) = 0;
911954Sbill dirdirty = 1;
9129877Ssam return (0);
913954Sbill }
9149877Ssam return (1);
915954Sbill }
9164879Ssam
scrunch()9174879Ssam scrunch()
9184879Ssam {
9193346Swnj register struct rt_ent *de , *workp;
9203346Swnj register segnum;
9214879Ssam
9224879Ssam for (segnum = 0; segnum != -1;
92326131Sbloom segnum = rt_dir[segnum].rd_nxtseg - 1) {
9244879Ssam for (de = rt_dir[segnum].rt_ents; de <= rt_curend[segnum]; de++)
9259877Ssam if (de->rt_stat == RT_NULL &&
92612012Shelge (de+1)->rt_stat == RT_NULL) {
9274879Ssam (de+1)->rt_len += de->rt_len;
92812012Shelge for (workp=de; workp<rt_curend[segnum]; workp++)
9294879Ssam *workp = workp[1];
9304879Ssam de--;
9314879Ssam rt_curend[segnum]--;
9324879Ssam rt_nleft++;
9334879Ssam }
93412012Shelge lwrite((6+segnum*2)*RT_BLOCK, 2*RT_BLOCK,
93512012Shelge (char *)&rt_dir[segnum]);
936954Sbill }
93712012Shelge dirdirty = 0;
938954Sbill }
939