Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/paxlib/calib/calib.c
1811 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 2004-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* *
20
***********************************************************************/
21
#pragma prototyped
22
23
/*
24
* pax calib format
25
*
26
* test registry
27
*
28
* 0x00200 disable auto-sequence
29
* 0x00400 disable latest version selection
30
* 0x00800 trace directory type { 0 1 }
31
* 0x01000 disable ibm => standard cobol conversions
32
* 0x02000 trace all directory types
33
* 0x04000 trace partial output record buffers
34
* 0x08000 trace record headers in decimal
35
* 0x10000 trace record headers in base 4
36
* 0x20000 trace record headers in base 4 (alternate format)
37
*/
38
39
#include <paxlib.h>
40
#include <codex.h>
41
#include <ccode.h>
42
#include <ctype.h>
43
#include <tm.h>
44
45
#include "camap.c"
46
47
#define MAGIC "\301\304\331\100\323\311\302\331\306"
48
#define CHUNK 64
49
50
typedef struct Cadir_s
51
{
52
unsigned short offset;
53
unsigned short blocks;
54
size_t size;
55
} Cadir_t;
56
57
typedef struct Ar_s
58
{
59
char* format;
60
char* suffix;
61
unsigned char* map;
62
unsigned char* imap;
63
unsigned char* buffer;
64
unsigned char* next;
65
int camap;
66
int count;
67
int digits;
68
int flags;
69
int increment;
70
int linesize;
71
int position;
72
int sequence;
73
int version;
74
size_t bufsize;
75
size_t blocksize;
76
size_t nblocks;
77
size_t block;
78
size_t headsize;
79
size_t line;
80
size_t buf;
81
size_t left;
82
Cadir_t* dirs;
83
Cadir_t* dir;
84
void* cam;
85
} Ar_t;
86
87
#define CALIB_LINE 256
88
89
#define cabcd5(x) ((((unsigned char*)x)[0]>>4)*10000+(((unsigned char*)x)[0]&0xf)*1000+(((unsigned char*)x)[1]>>4)*100+(((unsigned char*)x)[1]&0xf)*10+(((unsigned char*)x)[2]>>4))
90
#define casize2(x) ((((unsigned char*)x)[0]<<8)|(((unsigned char*)x)[1]))
91
#define casize3(x) ((((unsigned char*)x)[0]<<16)|(((unsigned char*)x)[1]<<8)|(((unsigned char*)x)[2]))
92
#define casize4(x) ((((unsigned char*)x)[0]<<24)|(((unsigned char*)x)[1]<<16)|(((unsigned char*)x)[2]<<8)|(((unsigned char*)x)[3]))
93
94
/*
95
* cobol keyword map
96
*/
97
98
static const char* cakey[] =
99
{
100
"FILLER ",
101
"PICTURE ",
102
"USAGE ",
103
"VALUE ",
104
"PERFORM ",
105
"SUBTRACT ",
106
"COMPUTE ",
107
"COMPUTATIONAL",
108
"COMP",
109
"REDEFINES ",
110
"RENAMES ",
111
"JUSTIFIED ",
112
"GIVING ",
113
"USING ",
114
"CALL ",
115
"ALTER ",
116
"EQUAL ",
117
"GREATER ",
118
"POSITIVE ",
119
"NEGATIVE ",
120
"ELSE ",
121
"OTHERWISE ",
122
"{22}",
123
"VARYING ",
124
"FROM ",
125
"UNTIL ",
126
"THRU ",
127
"ROUNDED ",
128
"GO TO ",
129
"MOVE ",
130
"ZERO ",
131
"ZEROS ",
132
"DEPENDING ",
133
"PIC ",
134
"BLANK ",
135
"OCCURS ",
136
"{36}",
137
"{37}",
138
"{38}",
139
"{39}",
140
"{40}",
141
"{41}",
142
"{42}",
143
"{43}",
144
"{44}",
145
"{45}",
146
"{46}",
147
"{47}",
148
"{48}",
149
"{49}",
150
"{50}",
151
"{51}",
152
"{52}",
153
"{53}",
154
"{54}",
155
"{55}",
156
"{56}",
157
"{57}",
158
"{58}",
159
"{59}",
160
"{60}",
161
"{61}",
162
"{62}",
163
"{63}",
164
"{64}",
165
"{65}",
166
"{66}",
167
"{67}",
168
"{68}",
169
"{69}",
170
"{70}",
171
"{71}",
172
"{72}",
173
"{73}",
174
"{74}",
175
"{75}",
176
"{76}",
177
"{77}",
178
"{78}",
179
"{79}",
180
"{80}",
181
"{81}",
182
"{82}",
183
"{83}",
184
"{84}",
185
"{85}",
186
"{86}",
187
"{87}",
188
"{88}",
189
"{89}",
190
"{90}",
191
"{91}",
192
"{92}",
193
"{93}",
194
"{94}",
195
"{95}",
196
"{96}",
197
"{97}",
198
"{98}",
199
"{99}",
200
"{100}",
201
"{101}",
202
"{102}",
203
"{103}",
204
"{104}",
205
"{105}",
206
"{106}",
207
"{107}",
208
"{108}",
209
"{109}",
210
"{110}",
211
"{111}",
212
"{112}",
213
"{113}",
214
"{114}",
215
"{115}",
216
"{116}",
217
"{117}",
218
"{118}",
219
"{119}",
220
"{120}",
221
"{121}",
222
"{122}",
223
"{123}",
224
"{124}",
225
"{125}",
226
"{126}",
227
"{127}",
228
};
229
230
/*
231
* return next nbits nibble from the input line
232
*/
233
234
#define cagetbits(ar,n) ((n)<=(ar)->left? \
235
((((ar)->buf)>>((ar)->left-=(n)))&((1L<<(n))-1)):\
236
_cagetbits((ar), (n)))
237
238
static int
239
_cagetbits(Ar_t* ar, int nbits)
240
{
241
int c;
242
243
while (ar->left <= 8 * (sizeof(ar->buf) - 1))
244
{
245
if (ar->count-- > 0)
246
{
247
c = *ar->next++;
248
ar->buf <<= 8;
249
ar->buf |= c;
250
ar->left += 8;
251
}
252
else if (ar->left < nbits)
253
return 0;
254
else
255
break;
256
}
257
return cagetbits(ar, nbits);
258
}
259
260
static int
261
calib_done(Pax_t* pax, register Paxarchive_t* ap)
262
{
263
Ar_t* ar;
264
265
if (ar = (Ar_t*)ap->data)
266
{
267
if (ar->cam)
268
camap_close(ar->cam);
269
if (ar->dirs)
270
free(ar->dirs);
271
free(ar);
272
ap->data = 0;
273
}
274
return 0;
275
}
276
277
static int
278
calib_getprologue(Pax_t* pax, Paxformat_t* fp, register Paxarchive_t* ap, Paxfile_t* f, unsigned char* buf, size_t size)
279
{
280
register Ar_t* ar;
281
register Cadir_t* dp;
282
register Cadir_t* de;
283
register Cadir_t* db;
284
unsigned char hdr[30];
285
unsigned char dir[22];
286
unsigned char blk[16];
287
off_t n;
288
size_t m;
289
int j;
290
int k;
291
292
if (sizeof(hdr) <= size)
293
memcpy(hdr, buf, sizeof(hdr));
294
else if (paxread(pax, ap, hdr, (off_t)sizeof(hdr), (off_t)sizeof(hdr), 0) <= 0)
295
return 0;
296
else
297
paxunread(pax, ap, hdr, sizeof(hdr));
298
if (memcmp(hdr, MAGIC, sizeof(MAGIC) - 1))
299
return 0;
300
if (!(ar = newof(0, Ar_t, 1, 0)))
301
{
302
paxnospace(pax);
303
return -1;
304
}
305
ar->imap = (ar->map = ccmap(CC_EBCDIC_O, CC_NATIVE)) ? ar->map : ccmap(0, 0);
306
ar->bufsize = casize2(&hdr[24]);
307
ar->linesize = 80;
308
db = dp = de = 0;
309
j = 3;
310
do
311
{
312
n = j * ar->bufsize;
313
if (paxseek(pax, ap, n, SEEK_SET, 1) != n)
314
(*pax->errorf)(NiL, pax, 3, "%s: %s format block header seek error", ap->name, ap->format->name);
315
if (paxread(pax, ap, blk, (off_t)sizeof(blk), (off_t)sizeof(blk), 0) <= 0)
316
(*pax->errorf)(NiL, pax, 3, "%s: %s format block header read error", ap->name, ap->format->name);
317
j = casize2(&blk[10]);
318
k = casize2(&blk[12]);
319
if (pax->test & 0x20000)
320
(*pax->errorf)(NiL, pax, 1, "blk %c%c%c%c%c%c%c%c %02x %02x %02x %02x %02x %02x %02x %02x", ccmapchr(ar->map, blk[0]), ccmapchr(ar->map, blk[1]), ccmapchr(ar->map, blk[2]), ccmapchr(ar->map, blk[3]), ccmapchr(ar->map, blk[4]), ccmapchr(ar->map, blk[5]), ccmapchr(ar->map, blk[6]), ccmapchr(ar->map, blk[7]), blk[8], blk[9], blk[10], blk[11], blk[12], blk[13], blk[14], blk[15]);
321
while (k-- > 0)
322
{
323
if (paxread(pax, ap, dir, (off_t)sizeof(dir), (off_t)sizeof(dir), 0) <= 0)
324
(*pax->errorf)(NiL, pax, 3, "%s: %s format header read error", ap->name, ap->format->name);
325
if (pax->test & 0x20000)
326
(*pax->errorf)(NiL, pax, 1, "dir %c%c%c%c%c%c%c%c %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", ccmapchr(ar->map, dir[0]), ccmapchr(ar->map, dir[1]), ccmapchr(ar->map, dir[2]), ccmapchr(ar->map, dir[3]), ccmapchr(ar->map, dir[4]), ccmapchr(ar->map, dir[5]), ccmapchr(ar->map, dir[6]), ccmapchr(ar->map, dir[7]), dir[8], dir[9], dir[10], dir[11], dir[12], dir[13], dir[14], dir[15], dir[16], dir[17], dir[18], dir[19], dir[20], dir[21]);
327
if (dp >= de)
328
{
329
m = dp - db + CHUNK;
330
if (!(db = newof(db, Cadir_t, m, 0)))
331
{
332
free(ar);
333
paxnospace(pax);
334
return -1;
335
}
336
dp = db + m - CHUNK;
337
de = db + m - 1;
338
}
339
dp->offset = casize2(&dir[9]);
340
dp->blocks = dir[14];
341
dp->size = cabcd5(&dir[15]) * ar->linesize;
342
ccmapstr(ar->map, dir, sizeof(dir));
343
dp++;
344
}
345
} while (j);
346
dp->offset = 0;
347
dp->size = 0;
348
ar->dirs = ar->dir = db;
349
ap->data = ar;
350
if (!(ar->cam = camap_open()))
351
{
352
calib_done(pax, ap);
353
return -1;
354
}
355
return 1;
356
}
357
358
static int
359
calib_getdata(Pax_t* pax, register Paxarchive_t* ap, register Paxfile_t* f, int wfd)
360
{
361
register Ar_t* ar = (Ar_t*)ap->data;
362
const char* s;
363
unsigned char* out;
364
long sequence;
365
int c;
366
int bits;
367
int flags;
368
int generate;
369
int noted;
370
int oline;
371
int version;
372
unsigned char* hdr;
373
unsigned char* b;
374
unsigned char* m;
375
char* ofile;
376
char* suffix;
377
size_t block;
378
size_t index;
379
ssize_t z;
380
off_t n;
381
Sfio_t* wfp;
382
char from[CALIB_LINE + 1];
383
char to[CALIB_LINE + 1];
384
char comment[CALIB_LINE + 1];
385
unsigned char outbuf[5 * CALIB_LINE + 1];
386
387
/* 10 20 30 40 50 60 */
388
/*01234567890123456789012345678901234567890123456789012345678901234*/
389
static char map[] = "? ~.<(+|&!$*);^-/,%_>?:#@'=\"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
390
391
if (ar->suffix)
392
{
393
wfp = 0;
394
suffix = 0;
395
}
396
else if (wfd < 0)
397
return 1;
398
else if (!(wfp = sfnew(NiL, NiL, SF_UNBOUND, wfd, SF_WRITE)))
399
{
400
(*pax->errorf)(NiL, pax, 2, "%s: cannot write", f->name);
401
return -1;
402
}
403
else if (ar->camap)
404
camap_init(ar->cam);
405
comment[0] = from[0] = to[0] = 0;
406
sequence = ar->digits && ar->increment && (ar->position + ar->digits) <= ar->linesize ? ar->sequence : -1;
407
noted = !wfp || !pax->warn;
408
if (pax->test & 0x00200)
409
sequence = -1;
410
generate = ar->flags != 0xf1;
411
block = 0;
412
oline = error_info.line;
413
error_info.line = 0;
414
ofile = error_info.file;
415
error_info.file = f->name;
416
version = (pax->test & 0x00400) ? -1 : ar->version;
417
for (;;)
418
{
419
block++;
420
while (ar->line <= ar->blocksize - ar->headsize + 1)
421
{
422
ar->next = &ar->buffer[index = ar->line];
423
hdr = ar->next;
424
flags = ar->next[1];
425
if (flags & 0x0c)
426
break;
427
ar->line += ar->next[0];
428
ar->next += ar->headsize;
429
if (flags & 0x80)
430
{
431
ar->next += 2;
432
if (!(flags & 0x01))
433
ar->next += 1;
434
}
435
if (version >= 0 && hdr[ar->headsize - 3] != version)
436
continue;
437
while ((ar->count = ar->next[-1]) == 1 && ar->next[0] == 0)
438
ar->next += 2;
439
error_info.line++;
440
if (pax->test & 0x08000)
441
(*pax->errorf)(NiL, pax, 0, "%03d %3u %3u %5u %3u %03o %4u %4u %4u %4u %4u %4o %4o %4o %4u %4u", error_info.line, ar->count, ar->next - hdr, ar->next - ar->buffer, hdr[0], hdr[1], hdr[2], hdr[3], hdr[4], hdr[5], hdr[6], hdr[7], hdr[8], hdr[9], hdr[10], hdr[11]);
442
if (pax->test & 0x10000)
443
(*pax->errorf)(NiL, pax, 0, "%03d %3u %3u %3u %03o %04..4u %04..4u %04..4u %04..4u %04..4u %04..4u %04..4u %04..4u %04..4u %04..4u", error_info.line, ar->count, ar->next - hdr, hdr[0], hdr[1], hdr[2], hdr[3], hdr[4], hdr[5], hdr[6], hdr[7], hdr[8], hdr[9], hdr[10], hdr[11]);
444
if (pax->test & 0x20000)
445
(*pax->errorf)(NiL, pax, 0, "%03d %3d %03d:%02x:%04..4u:%03u | %03d:%02x:%04..4u:%03u %03d:%02x:%04..4u:%03u %03d:%02x:%04..4u:%03u %03d:%02x:%04..4u:%03u %03d:%02x:%04..4u:%03u %03d:%02x:%04..4u:%03u",
446
error_info.line,
447
ar->count,
448
ar->next[-1], ar->next[-1], ar->next[-1], ar->next[-1] & 0x7f,
449
ar->next[0], ar->next[0], ar->next[0], ar->next[0] & 0x7f,
450
ar->next[1], ar->next[1], ar->next[1], ar->next[1] & 0x7f,
451
ar->next[2], ar->next[2], ar->next[2], ar->next[2] & 0x7f,
452
ar->next[3], ar->next[3], ar->next[3], ar->next[3] & 0x7f,
453
ar->next[4], ar->next[4], ar->next[4], ar->next[4] & 0x7f,
454
ar->next[5], ar->next[5], ar->next[5], ar->next[5] & 0x7f);
455
if (flags & 0x40)
456
{
457
bits = 8;
458
m = ar->imap;
459
}
460
else
461
{
462
bits = 6;
463
m = (unsigned char*)map;
464
}
465
out = outbuf;
466
if (pax->warn)
467
noted = 0;
468
while (ar->count && (ar->next - ar->buffer) < ar->line)
469
{
470
if (ar->count < 64)
471
{
472
ar->left = 0;
473
while ((c = cagetbits(ar, bits)) || bits == 8 && ar->count > 0)
474
if (out < &outbuf[ar->linesize])
475
*out++ = m[c];
476
else if (!noted)
477
{
478
noted = 1;
479
(*pax->errorf)(NiL, pax, 2, "%s: overbyte (bits=%d offset=%I*u+%I*u block=%I*u)", ap->name, bits, sizeof(off_t), paxseek(pax, ap, (off_t)0, SEEK_CUR, 0) - ar->bufsize, sizeof(index), index, sizeof(block), block);
480
}
481
if ((ar->next - ar->buffer) >= ar->line)
482
break;
483
if ((c = (*ar->next ^ 64)) & 0x80)
484
c = 0;
485
else
486
ar->next++;
487
}
488
else if (ar->count & 0x80)
489
{
490
if (pax->test & 0x04000)
491
(*pax->errorf)(NiL, pax, 1, "part c=%d n=%d k=%d \"%-.*s\"", c, out - outbuf, ar->count & 0x7f, out - outbuf, outbuf);
492
goto key;
493
}
494
else if ((c = ar->count - 64) & 0x80)
495
c = (c + 64) & 0x7f;
496
if (pax->test & 0x04000)
497
(*pax->errorf)(NiL, pax, 1, "part c=%d:%d:%d r=%d:%d bits=%d n=%d x=%u \"%-.*s\"", c, &outbuf[ar->linesize] - out, c ^ 64, ar->next - ar->buffer, ar->line, bits, out - outbuf, *ar->next, out - outbuf, outbuf);
498
if (c > (&outbuf[ar->linesize] - out))
499
{
500
ar->count = c ^ 64;
501
if (bits == 8 && ar->count <= (&outbuf[ar->linesize] - out))
502
continue;
503
goto key;
504
}
505
else if (c > 0)
506
{
507
memset(out, ' ', c);
508
out += c;
509
}
510
while ((ar->next - ar->buffer) < ar->line && (ar->count = *ar->next++) & 0x80)
511
{
512
key:
513
s = cakey[ar->count & 0x7f];
514
if (pax->warn && *s == '{') /*'}'*/
515
(*pax->errorf)(NiL, pax, 1, "%s: keyword %s (bits=%d offset=%I*u+%I*u block=%I*u)", ap->name, s, bits, sizeof(off_t), paxseek(pax, ap, (off_t)0, SEEK_CUR, 0) - ar->bufsize, sizeof(index), index, sizeof(block), block);
516
while (c = *s++)
517
if (out < &outbuf[ar->linesize])
518
*out++ = c;
519
else
520
{
521
if (!noted)
522
{
523
noted = 1;
524
(*pax->errorf)(NiL, pax, 2, "%s: key overbyte (bits=%d offset=%I*u+%I*u block=%I*u)", ap->name, bits, sizeof(off_t), paxseek(pax, ap, (off_t)0, SEEK_CUR, 0) - ar->bufsize, sizeof(index), index, sizeof(block), block);
525
}
526
break;
527
}
528
}
529
}
530
if (!wfp)
531
{
532
if (flags & 0x01)
533
{
534
for (b = outbuf; b < out && *b == ' '; b++);
535
for (; b < out && isdigit(*b); b++);
536
for (; b < out && *b == ' '; b++);
537
for (m = b; b < out && *b != ' '; b++);
538
if ((out - b) > 6 && *m == '/' && *(m + 1) == '*')
539
{
540
while ((out - ++b) > 4)
541
{
542
if (*b == 'R' && *(b + 1) == 'E' && *(b + 2) == 'X' && *(b + 3) == 'X')
543
{
544
suffix = ".REXX";
545
break;
546
}
547
}
548
if (suffix)
549
break;
550
continue;
551
}
552
if (m == outbuf)
553
{
554
if ((b - m) == 7 && strneq((char*)m, "NEWPAGE", 7) || (b - m) == 4 && strneq((char*)m, "FILE", 4))
555
{
556
suffix = ".EZT";
557
break;
558
}
559
else if ((out - outbuf) > 2 && m[0] == 'C' && (m[1] == ' ' || m[1] == '*'))
560
{
561
suffix = ".F";
562
break;
563
}
564
}
565
else if ((b - m) == 7 && strneq((char*)m, "INCLUDE", 7) || (b - m) == 4 && strneq((char*)m, "NAME", 4))
566
{
567
suffix = ".LNK";
568
break;
569
}
570
else if ((b - m) == 5 && (strneq((char*)m, "TITLE", 5) || strneq((char*)m, "SPACE", 5)))
571
{
572
suffix = ".ASM";
573
break;
574
}
575
else if ((b - m) == 3 && strneq((char*)m, "DCL", 3))
576
{
577
suffix = ".PLI";
578
break;
579
}
580
else if ((b - m) == 10 && strneq((char*)m, "SUBROUTINE", 10) || (b - m) == 9 && strneq((char*)m, "DIMENSION", 9) || (b - m) == 6 && strneq((char*)m, "COMMON", 6) || b < out && (b - m) >= 6 && strneq((char*)m, "FORMAT", 6) && (m[6] == '(' || m[6] == ' '))
581
{
582
suffix = ".F";
583
break;
584
}
585
if (b < out && *m++ == '.' && ((b - m) == 7 && strneq((char*)m, "REPLACE", 7) || (b - m) == 5 && strneq((char*)m, "QUOTE", 5) || (b - m) > 4 && strneq((char*)m, "END-", 4)))
586
{
587
suffix = ".QBL";
588
break;
589
}
590
if ((b - outbuf) > 6)
591
{
592
if (outbuf[6] == ' ')
593
{
594
for (b = outbuf + 7; b < out && *b == ' '; b++);
595
for (m = b; b < out && *b != ' '; b++);
596
if (b < out && (b - m) == 2 && isdigit(m[0]) && isdigit(m[1]))
597
{
598
for (; b < out && *b != '.'; b++);
599
if (b < out && *b == '.')
600
{
601
suffix = ".CPY";
602
break;
603
}
604
}
605
else
606
{
607
for (; b < out && *b == ' '; b++);
608
for (m = b; b < out && *b != '.'; b++);
609
if (b < out && (b - m) == 8 && strneq((char*)m, "DIVISION", 8))
610
{
611
suffix = ".COB";
612
break;
613
}
614
}
615
}
616
else if (outbuf[6] == '*')
617
suffix = ".CPY";
618
}
619
}
620
}
621
else if (flags & 0x01)
622
{
623
if (sequence >= 0)
624
{
625
if ((b = outbuf + ar->position) >= out || *b == ' ' || isdigit(*b) || (out - outbuf) == ar->linesize && (b = out - ar->digits))
626
{
627
if ((c = ar->position - (out - outbuf)) > 0)
628
{
629
memset(out, ' ', c);
630
out += c;
631
}
632
b += sfsprintf((char*)b, ar->digits+1, "%0.*lu", ar->digits, generate ? sequence : casize3(&hdr[2]));
633
if (out < b)
634
out = b;
635
}
636
sequence += ar->increment;
637
}
638
for (; out > outbuf && *(out - 1) == ' '; out--);
639
*out++ = '\n';
640
if ((out - outbuf) > 10 && outbuf[6] == '*' && outbuf[7] == '/')
641
{
642
if ((out - outbuf) == 11 && outbuf[8] == '/' && (outbuf[9] == '*' || outbuf[9] == ' ' || !outbuf[9]))
643
from[0] = to[0] = 0;
644
else
645
{
646
m = 0;
647
for (b = outbuf + 8; b < out; b++)
648
if (*b == '/')
649
{
650
if (!m)
651
m = b;
652
else
653
{
654
if (*++b == '*' || *b == ' ' || *b == '\n')
655
{
656
c = m - outbuf - 8;
657
memcpy(from, outbuf + 8, c);
658
from[c] = 0;
659
c = b - m - 2;
660
memcpy(to, m + 1, c);
661
to[c] = 0;
662
}
663
break;
664
}
665
}
666
}
667
}
668
else if (!pax->strict && !(pax->test & 0x01000) && outbuf[0] == '-' && outbuf[1] == 'I' && outbuf[2] == 'N' && outbuf[3] == 'C' && outbuf[4] == ' ')
669
{
670
for (b = outbuf + 5; *b == ' '; b++);
671
for (m = b; m < (out - 1) && *m != ' '; m++);
672
if (from[0])
673
c = sfsprintf((char*)outbuf, sizeof(outbuf), " COPY %-.*s REPLACING ==%s== BY ==%s==.\n", m - b, b, from, to);
674
else
675
c = sfsprintf((char*)outbuf, sizeof(outbuf), " COPY %-.*s.\n", m - b, b);
676
out = outbuf + c;
677
}
678
z = out - outbuf;
679
if (sfwrite(wfp, outbuf, z) != z || ar->camap && camap_write(ar->cam, outbuf, z) < 0)
680
{
681
(*pax->errorf)(NiL, pax, 2, "%s: write error", f->name);
682
goto bad;
683
}
684
}
685
else
686
{
687
error_info.line--;
688
if (pax->warn)
689
{
690
for (b = outbuf; b < out && *b == ' '; b++);
691
for (; out > outbuf && *(out - 1) == ' '; out--);
692
*out = 0;
693
if (!streq((char*)b, comment))
694
(*pax->errorf)(NiL, pax, 0, "comment %s \"%s\"", error_info.file, strcpy(comment, (char*)b));
695
}
696
}
697
}
698
if (!wfp)
699
break;
700
if (--ar->nblocks <= 0)
701
break;
702
if (ar->buffer[2] == 0xff)
703
{
704
n = casize2(ar->buffer + ar->blocksize + (block != 1)) * ar->bufsize;
705
if (paxseek(pax, ap, n, SEEK_SET, 1) != n)
706
(*pax->errorf)(NiL, pax, 3, "%s: %s format data seek error", ap->name, ap->format->name);
707
}
708
if (!(ar->buffer = (unsigned char*)paxget(pax, ap, (off_t)ar->bufsize, NiL)))
709
(*pax->errorf)(NiL, pax, 3, "%s: format member read error (offset=%I*u block=%I*u)", ap->name, sizeof(off_t), paxseek(pax, ap, (off_t)0, SEEK_CUR, 0), sizeof(block), block);
710
ar->blocksize = casize2(ar->buffer);
711
ar->next = ar->buffer;
712
ar->line = 4;
713
}
714
error_info.line = oline;
715
error_info.file = ofile;
716
if (wfp)
717
{
718
if (sfsync(wfp) || ar->camap && camap_done(ar->cam, f->name, wfd) < 0)
719
{
720
(*pax->errorf)(NiL, pax, 2, "%s: write error", f->name);
721
goto bad;
722
}
723
wfp->_file = -1;
724
sfclose(wfp);
725
}
726
else if (suffix)
727
strcpy(ar->suffix, suffix);
728
return 1;
729
bad:
730
wfp->_file = -1;
731
sfclose(wfp);
732
return -1;
733
}
734
735
static int
736
calib_getheader(Pax_t* pax, register Paxarchive_t* ap, register Paxfile_t* f)
737
{
738
register Ar_t* ar = (Ar_t*)ap->data;
739
register unsigned char* h;
740
register off_t n;
741
char* s;
742
char* t;
743
char* v;
744
int i;
745
int j;
746
int k;
747
int x;
748
char suf[4];
749
750
if (!ar->dir->offset)
751
return 0;
752
n = ar->bufsize * ar->dir->offset;
753
if (paxseek(pax, ap, n, SEEK_SET, 1) != n)
754
(*pax->errorf)(NiL, pax, 3, "%s: %s format member seek error", ap->name, ap->format->name);
755
ar->nblocks = ar->dir->blocks;
756
if (!(ar->buffer = (unsigned char*)paxget(pax, ap, (off_t)ar->bufsize, NiL)))
757
(*pax->errorf)(NiL, pax, 3, "%s: %s format member read error", ap->name, ap->format->name);
758
ar->blocksize = casize2(&ar->buffer[0]) + 1;
759
ar->headsize = 6;
760
ar->version = -1;
761
ar->next = ar->buffer;
762
s = 0;
763
k = 0;
764
for (j = 1, x = 0, h = ar->buffer + 4; !x && h < ar->buffer + ar->bufsize; j++, h += i)
765
{
766
if ((i = *h) == 78)
767
{
768
j = h[2];
769
if (j == 5 && !h[1] && !h[3])
770
x = 1;
771
i -= 6;
772
h += 6;
773
}
774
else
775
{
776
if (j == 5)
777
x = 1;
778
i -= 2;
779
h += 2;
780
}
781
if (!(k & (1<<j)))
782
{
783
k |= (1<<j);
784
if (pax->test & 0x02000)
785
{
786
int y;
787
788
sfprintf(sfstderr, "head %-8s %d", f->name, j);
789
for (y = 0; y < i; y++)
790
sfprintf(sfstderr, " %02x", h[y]);
791
sfprintf(sfstderr, "\n");
792
}
793
switch (j)
794
{
795
case 0:
796
switch (ar->flags = h[32])
797
{
798
case 0x40:
799
ar->headsize = 5;
800
break;
801
case 0xf1:
802
ar->headsize = 8;
803
break;
804
}
805
ar->version = h[-3];
806
ar->position = h[33];
807
ar->digits = h[34] + 1;
808
ar->increment = casize2(&h[35]);
809
if ((ar->sequence = casize2(&h[37])) > 0x7fff)
810
ar->sequence = ar->sequence - 0x10000;
811
ar->sequence += ar->increment;
812
ccmapstr(ar->map, h, 24);
813
f->name = paxstash(pax, &ap->stash.head, (char*)h, 28);
814
for (s = f->name + 8; *(s - 1) == ' '; s--);
815
*(ar->suffix = s) = 0;
816
f->st->st_mtime = f->st->st_ctime = f->st->st_atime = tmscan(sfprints("%-.6s%02u%02u%02u", memcmp(h + 18, "000000", 6) ? (h + 18) : (h + 12), h[24], h[25], h[26]), NiL, "%y%m%d%H%M%S", NiL, NiL, 0);
817
if (pax->test & 0x00800)
818
(*pax->errorf)(NiL, pax, 0, "head %-8s %d %03o %03o %03o %03o %03o %03o %03o", f->name, j, h[32], h[33], h[34], h[35], h[36], h[37], h[38]);
819
break;
820
case 1:
821
switch (ar->flags = h[32])
822
{
823
case 0x40:
824
ar->headsize = 3;
825
break;
826
}
827
if (h[31] == 0x48)
828
{
829
ar->digits = 0;
830
ar->linesize = 133;
831
}
832
else
833
{
834
ar->position = h[33];
835
ar->digits = h[34] + 1;
836
ar->increment = casize2(&h[35]);
837
if ((ar->sequence = casize2(&h[37])) > 0x7fff)
838
ar->sequence = ar->sequence - 0x10000;
839
ar->sequence += ar->increment;
840
}
841
ccmapstr(ar->map, h, 32);
842
f->name = paxstash(pax, &ap->stash.head, (char*)h, 13);
843
for (s = f->name + 8; *(s - 1) == ' '; s--);
844
*(ar->suffix = s) = 0;
845
f->st->st_mtime = f->st->st_ctime = f->st->st_atime = tmscan(sfprints("%-.6s%-.4s00", memcmp(h + 18, "000000", 6) ? (h + 18) : (h + 12), h + 24), NiL, "%m%d%y%H%M%S", NiL, NiL, 0);
846
if (pax->test & 0x00800)
847
(*pax->errorf)(NiL, pax, 0, "head %-8s %d %03o %03o %03o %03o %03o %03o %03o", f->name, j, h[32], h[33], h[34], h[35], h[36], h[37], h[38]);
848
break;
849
case 5:
850
if (s)
851
{
852
switch (h[38])
853
{
854
case 0x31:
855
v = "PLI";
856
break;
857
case 0x32:
858
case 0x42:
859
case 0x4c:
860
v = "COB";
861
break;
862
case 0x43:
863
v = "EST";
864
break;
865
case 0x4d:
866
v = "ASM";
867
break;
868
default:
869
t = (char*)h + 34;
870
ccmapstr(ar->map, t, 3);
871
v = suf;
872
while (t < ((char*)h + 37) && *t != ' ')
873
*v++ = *t++;
874
*v = 0;
875
if (!*(v = suf))
876
{
877
if (ar->linesize == 133)
878
{
879
v = "LST";
880
ar->suffix = 0;
881
}
882
else
883
switch (h[38])
884
{
885
case 0x00:
886
case 0x02:
887
v = "COB";
888
break;
889
case 0x01:
890
case 0x0a:
891
v = 0;
892
break;
893
default:
894
v = 0;
895
if (pax->warn)
896
(*pax->errorf)(NiL, pax, 1, "%s: no suffix for type=%02x", f->name, h[38]);
897
break;
898
}
899
}
900
else if (streq(v, "CB2") || streq(v, "CBL"))
901
v = "COB";
902
else if (streq(v, "PL1"))
903
v = "PLI";
904
break;
905
}
906
if (v)
907
{
908
*s++ = '.';
909
strcpy(s, v);
910
if (streq(v, "EZT") || streq(v, "PLI"))
911
ar->suffix = 0;
912
}
913
}
914
break;
915
}
916
}
917
}
918
for (s = f->name; *s; s++)
919
if (!isalnum(*s) && *s != '.')
920
*s = '_';
921
ar->line = h - ar->buffer;
922
ar->camap = 0;
923
if (ar->suffix)
924
{
925
calib_getdata(pax, ap, f, -1);
926
ar->line = h - ar->buffer;
927
ar->suffix = 0;
928
}
929
for (i = 0, s = f->name; *s; s++)
930
if (*s == '.')
931
{
932
if (!(pax->test & 0x01000) && (!strcasecmp(s + 1, "COB") || !strcasecmp(s + 1, "CPY")))
933
ar->camap = 1;
934
break;
935
}
936
else if (islower(*s))
937
i = 1;
938
if (i && *s)
939
while (*++s)
940
if (isupper(*s))
941
*s = tolower(*s);
942
f->linkpath = 0;
943
f->st->st_dev = 0;
944
f->st->st_ino = 0;
945
f->st->st_mode = X_IFREG|X_IRUSR|X_IWUSR|X_IRGRP|X_IROTH;
946
f->st->st_uid = pax->uid;
947
f->st->st_gid = pax->gid;
948
f->st->st_nlink = 1;
949
IDEVICE(f->st, 0);
950
f->st->st_size = ar->dir->size;
951
ar->dir++;
952
return 1;
953
}
954
955
Paxformat_t pax_calib_format =
956
{
957
"ca-librarian",
958
"calib|librarian",
959
"mvs CA-librarian file",
960
0,
961
PAX_ARCHIVE|PAX_NOHARDLINKS|PAX_IN,
962
PAX_DEFBUFFER,
963
PAX_DEFBLOCKS,
964
0,
965
PAXNEXT(calib),
966
0,
967
calib_done,
968
calib_getprologue,
969
calib_getheader,
970
calib_getdata,
971
};
972
973
PAXLIB(calib)
974
975