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