Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libardir/ar-aixbig.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 2002-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
* aixbig archive format method
24
*/
25
26
#include <ardirlib.h>
27
#include <tm.h>
28
29
#define MAGIC "<bigaf>\n"
30
#define MAGIC_SIZE 8
31
32
typedef struct Header_s
33
{
34
char fl_magic[MAGIC_SIZE];
35
char fl_memoff[20];
36
char fl_gstoff[20];
37
char fl_gst64off[20];
38
char fl_fstmoff[20];
39
char fl_lstmoff[20];
40
char fl_freeoff[20];
41
} Header_t;
42
43
typedef struct Member_s
44
{
45
char ar_size[20];
46
char ar_nxtmem[20];
47
char ar_prvmem[20];
48
char ar_date[12];
49
char ar_uid[12];
50
char ar_gid[12];
51
char ar_mode[12];
52
char ar_namlen[4];
53
union
54
{
55
char ar_name[2];
56
char ar_fmag[2];
57
} _ar_name;
58
} Member_t;
59
60
typedef struct State_s /* method state */
61
{
62
off_t current; /* current dirent offset */
63
off_t offset; /* next dirent offset */
64
off_t last; /* last member offset */
65
Member_t member; /* current member */
66
int term; /* trailing '\0' for member */
67
char* name; /* current member name */
68
size_t namesize; /* max size for name */
69
} State_t;
70
71
/*
72
* closef
73
*/
74
75
static int
76
aixbigclose(Ardir_t* ar)
77
{
78
State_t* state;
79
80
if (ar && (state = (State_t*)ar->data))
81
{
82
if (state->name)
83
free(state->name);
84
free(state);
85
}
86
return 0;
87
}
88
89
/*
90
* openf
91
*/
92
93
static int
94
aixbigopen(Ardir_t* ar, char* buf, size_t n)
95
{
96
Header_t* hdr;
97
State_t* state;
98
long m;
99
100
if (n <= sizeof(Header_t))
101
return -1;
102
hdr = (Header_t*)buf;
103
if (memcmp(hdr->fl_magic, MAGIC, MAGIC_SIZE))
104
return -1;
105
if (!(state = newof(0, State_t, 1, 0)))
106
return -1;
107
ar->data = (void*)state;
108
if (sfsscanf(hdr->fl_gstoff, "%ld", &m) != 1)
109
goto nope;
110
if (sfsscanf(hdr->fl_fstmoff, "%ld", &m) != 1)
111
goto nope;
112
state->offset = m;
113
if (sfsscanf(hdr->fl_memoff, "%ld", &m) != 1)
114
goto nope;
115
state->last = m;
116
return 0;
117
nope:
118
aixbigclose(ar);
119
return -1;
120
}
121
122
/*
123
* nextf
124
*/
125
126
static Ardirent_t*
127
aixbignext(Ardir_t* ar)
128
{
129
State_t* state = (State_t*)ar->data;
130
long n;
131
unsigned long u;
132
133
if ((state->current = state->offset) >= state->last)
134
return 0;
135
if (lseek(ar->fd, state->offset, SEEK_SET) != state->offset)
136
{
137
ar->error = errno;
138
return 0;
139
}
140
if (read(ar->fd, (char*)&state->member, sizeof(state->member)) != sizeof(state->member))
141
{
142
if ((n = read(ar->fd, (char*)&state->member, 1)) < 0)
143
ar->error = errno;
144
else if (n > 0)
145
ar->error = EINVAL;
146
return 0;
147
148
}
149
if (sfsscanf(state->member.ar_namlen, "%ld", &n) != 1)
150
{
151
ar->error = EINVAL;
152
return 0;
153
}
154
if (n >= state->namesize)
155
{
156
state->namesize = roundof(n + 1, 256);
157
if (!(state->name = newof(state->name, char, state->namesize, 0)))
158
{
159
ar->error = errno;
160
return 0;
161
}
162
ar->dirent.name = state->name;
163
}
164
memcpy(state->name, state->member._ar_name.ar_name, 2);
165
if (n > 2)
166
{
167
if (read(ar->fd, state->name + 2, n - 2) != (n - 2))
168
{
169
ar->error = errno;
170
return 0;
171
}
172
if (lseek(ar->fd, -(Sfoff_t)(n - 2), SEEK_CUR) < 0)
173
{
174
ar->error = errno;
175
return 0;
176
}
177
}
178
state->name[n] = 0;
179
ar->dirent.offset = state->offset + sizeof(Member_t) + n - 2;
180
if (sfsscanf(state->member.ar_date, "%lu", &u) != 1)
181
{
182
ar->error = EINVAL;
183
return 0;
184
}
185
ar->dirent.mtime = u;
186
if (sfsscanf(state->member.ar_uid, "%lu", &u) != 1)
187
{
188
ar->error = EINVAL;
189
return 0;
190
}
191
ar->dirent.uid = u;
192
if (sfsscanf(state->member.ar_gid, "%lu", &u) != 1)
193
{
194
ar->error = EINVAL;
195
return 0;
196
}
197
ar->dirent.gid = u;
198
if (sfsscanf(state->member.ar_mode, "%lo", &u) != 1)
199
{
200
ar->error = EINVAL;
201
return 0;
202
}
203
ar->dirent.mode = u;
204
if (sfsscanf(state->member.ar_size, "%ld", &u) != 1)
205
{
206
ar->error = EINVAL;
207
return 0;
208
}
209
ar->dirent.size = u;
210
if (sfsscanf(state->member.ar_nxtmem, "%ld", &u) != 1)
211
{
212
ar->error = EINVAL;
213
return 0;
214
}
215
state->offset = u;
216
return &ar->dirent;
217
}
218
219
/*
220
* changef
221
*/
222
223
static int
224
aixbigchange(Ardir_t* ar, Ardirent_t* ent)
225
{
226
State_t* state = (State_t*)ar->data;
227
off_t o;
228
char buf[sizeof(state->member.ar_date) + 1];
229
230
o = state->current + offsetof(Member_t, ar_date);
231
if (lseek(ar->fd, o, SEEK_SET) != o)
232
{
233
ar->error = errno;
234
return -1;
235
}
236
sfsprintf(buf, sizeof(buf), "%-*lu", sizeof(buf) - 1, (unsigned long)ent->mtime);
237
if (write(ar->fd, buf, sizeof(buf) - 1) != (sizeof(buf) - 1))
238
{
239
ar->error = errno;
240
return -1;
241
}
242
return 0;
243
}
244
245
Ardirmeth_t ar_aixbig =
246
{
247
"aixbig",
248
"aixbig archive",
249
aixbigopen,
250
aixbignext,
251
aixbigchange,
252
0,
253
0,
254
aixbigclose,
255
ar_aixbig_next
256
};
257
258