Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/pax/pax-pds.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1987-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
* *
19
***********************************************************************/
20
#pragma prototyped
21
22
/*
23
* pax pds format
24
*/
25
26
#include "format.h"
27
28
#include <tm.h>
29
30
typedef struct Pdsdir_s
31
{
32
char* link;
33
unsigned long block;
34
time_t time;
35
char name[9];
36
} Pdsdir_t;
37
38
typedef struct Pds_s
39
{
40
char* format;
41
unsigned char* map;
42
size_t index;
43
size_t size;
44
Pdsdir_t dir[1];
45
} Pds_t;
46
47
static int
48
pds_getprologue(Pax_t* pax, Format_t* fp, register Archive_t* ap, File_t* f, unsigned char* buf, size_t size)
49
{
50
register Pds_t* pds;
51
register unsigned char* b;
52
register unsigned char* e;
53
register size_t n;
54
register size_t i;
55
register size_t m;
56
size_t links;
57
58
if (size < 256 || buf[0] != 0)
59
return 0;
60
b = buf;
61
e = b + b[1];
62
while (b != e)
63
{
64
n = 12 + 2 * (b[11] & 0x1f);
65
if ((e - b) < n)
66
return 0;
67
b += n;
68
}
69
i = 0;
70
m = 32;
71
if (!(pds = newof(0, Pds_t, 1, (m - 1) * sizeof(Pdsdir_t))))
72
nospace();
73
pds->map = ccmap(CC_EBCDIC_O, CC_NATIVE);
74
links = 0;
75
while ((b = (unsigned char*)paxget(pax, ap, -256, NiL)) && !b[0])
76
{
77
n = b[1];
78
b += 2;
79
e = b + n;
80
while ((e - b) >= 12)
81
{
82
if (b[0] == 0xff && !memcmp(b, "\xff\xff\xff\xff\xff\xff\xff\xff", 8))
83
goto done;
84
n = 12 + 2 * (b[11] & 0x1f);
85
if ((e - b) < n)
86
break;
87
if (i >= m)
88
{
89
m += 32;
90
if (!(pds = newof(pds, Pds_t, 1, (m - 1) * sizeof(Pdsdir_t))))
91
nospace();
92
}
93
memcpy(pds->dir[i].name, b, 8);
94
ccmapstr(pds->map, pds->dir[i].name, 8);
95
pds->dir[i].block = (b[8] << 16) | (b[9] << 8) | b[10];
96
pds->dir[i].time = (n > 25) ? tmscan(sfprints("%02x %02x%01x %02x %02x", b[21], b[22], b[23] >> 4, b[24], b[25]), NiL, "%y %j %H %M", NiL, NiL, 0) : NOW;
97
if (b[11] & 0x80)
98
{
99
links++;
100
pds->dir[i].link = &pds->dir[i].name[0];
101
}
102
else
103
pds->dir[i].link = 0;
104
b += n;
105
for (n = 8; n > 0 && pds->dir[i].name[n - 1] == ' '; n--);
106
pds->dir[i].name[n] = 0;
107
i++;
108
}
109
}
110
done:
111
if (!(pds->size = i))
112
{
113
free(pds);
114
return 0;
115
}
116
m = 0;
117
while (links > 0)
118
{
119
while (!pds->dir[m].link)
120
m++;
121
for (n = 0; n < i; n++)
122
if (n != m && pds->dir[n].block == pds->dir[m].block)
123
break;
124
if (n < m)
125
{
126
pds->dir[n].link = pds->dir[m].name;
127
pds->dir[m].link = 0;
128
}
129
else if (n < i)
130
pds->dir[m].link = pds->dir[n].name;
131
else
132
pds->dir[m].link = 0;
133
m++;
134
links--;
135
}
136
pds->format = pax_pds_format.name;
137
ap->data = pds;
138
return 1;
139
}
140
141
static int
142
pds_done(Pax_t* pax, register Archive_t* ap)
143
{
144
if (ap->data)
145
{
146
free(ap->data);
147
ap->data = 0;
148
}
149
return 0;
150
}
151
152
static int
153
pds_getheader(Pax_t* pax, register Archive_t* ap, register File_t* f)
154
{
155
register Pds_t* pds = (Pds_t*)ap->data;
156
register Pdsdir_t* dp;
157
158
if (pds->index >= pds->size)
159
return 0;
160
dp = pds->dir + pds->index++;
161
f->name = dp->name;
162
f->linkpath = dp->link;
163
f->st->st_atime = f->st->st_mtime = dp->time;
164
f->st->st_dev = 0;
165
f->st->st_ino = 0;
166
f->st->st_mode = X_IFREG|X_IRUSR|X_IWUSR|X_IRGRP|X_IROTH;
167
f->st->st_uid = state.uid;
168
f->st->st_gid = state.gid;
169
f->st->st_nlink = 1;
170
IDEVICE(f->st, 0);
171
f->st->st_size = dp->block;
172
return 1;
173
}
174
175
static int
176
pds_getdata(Pax_t* pax, register Archive_t* ap, register File_t* f, int wfd)
177
{
178
return 1;
179
}
180
181
Format_t pax_pds_format =
182
{
183
"pds",
184
0,
185
"mvs partitioned dataset",
186
0,
187
ARCHIVE|NOHARDLINKS,
188
DEFBUFFER,
189
DEFBLOCKS,
190
0,
191
PAXNEXT(pds),
192
0,
193
pds_done,
194
pds_getprologue,
195
pds_getheader,
196
pds_getdata,
197
};
198
199
PAXLIB(pds)
200
201