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