rpm
5.4.10
Main Page
Related Pages
Modules
Data Structures
Files
File List
Globals
rpmio
cpio.c
Go to the documentation of this file.
1
5
#undef JBJ_WRITEPAD
6
7
#include "system.h"
8
9
#include <
rpmio.h
>
10
#include <
ugid.h
>
11
#include <
cpio.h
>
12
#define _IOSM_INTERNAL
13
#include <
iosm.h
>
14
15
#include "
debug.h
"
16
17
/*@access IOSM_t @*/
18
19
/*@unchecked@*/
20
int
_cpio_debug
= 0;
21
30
static
int
strntoul
(
const
char
*str,
/*@null@*/
/*@out@*/
char
**endptr,
31
int
base,
size_t
num)
32
/*@modifies *endptr @*/
33
/*@requires maxSet(endptr) >= 0 @*/
34
{
35
char
* buf;
36
char
* end;
37
unsigned
long
ret;
38
39
buf = (
char
*)
alloca
(num + 1);
40
strncpy(buf, str, num);
41
buf[num] =
'\0'
;
42
43
ret = strtoul(buf, &end, base);
44
if
(endptr != NULL) {
45
if
(*end !=
'\0'
)
46
*endptr = ((
char
*)str) + (end - buf);
/* XXX discards const */
47
else
48
*endptr = ((
char
*)str) + strlen(buf);
49
}
50
51
return
ret;
52
}
53
54
/* Translate archive read/write ssize_t return for iosmStage(). */
55
#define _IOSMRC(_rc) \
56
if ((_rc) <= 0) return ((_rc) ? (int) -rc : IOSMERR_HDR_TRAILER)
57
58
static
ssize_t
cpioRead
(
void
* _iosm,
void
* buf,
size_t
count)
59
/*@globals fileSystem @*/
60
/*@modifies _iosm, *buf, fileSystem @*/
61
{
62
IOSM_t
iosm = (
IOSM_t
) _iosm;
63
char
* t = (
char
*) buf;
64
size_t
nb = 0;
65
size_t
rc;
66
67
if
(
_cpio_debug
)
68
fprintf(stderr,
" cpioRead(%p, %p[%u])\n"
, iosm, buf, (
unsigned
)count);
69
70
while
(count > 0) {
71
72
/* Read next cpio block. */
73
iosm->
wrlen
= count;
74
rc =
_iosmNext
(iosm,
IOSM_DREAD
);
75
if
(!rc && iosm->
rdnb
!= iosm->
wrlen
)
76
rc =
IOSMERR_READ_FAILED
;
77
if
(rc)
return
-rc;
78
79
/* Append to buffer. */
80
rc = (count > iosm->
rdnb
? iosm->
rdnb
: count);
81
if
(buf != iosm->
wrbuf
)
82
memcpy(t + nb, iosm->
wrbuf
, rc);
83
nb += rc;
84
count -= rc;
85
}
86
return
nb;
87
}
88
89
#define GET_NUM_FIELD(phys, log) \
90
log = strntoul(phys, &end, 16, sizeof(phys)); \
91
if ( (end - phys) != sizeof(phys) ) return IOSMERR_BAD_HEADER;
92
#define SET_NUM_FIELD(phys, val, space) \
93
sprintf(space, "%8.8lx", (unsigned long) (val)); \
94
memcpy(phys, space, 8)
95
96
int
cpioHeaderRead
(
void
* _iosm,
struct
stat * st)
97
{
98
IOSM_t
iosm = (
IOSM_t
) _iosm;
99
cpioHeader
hdr = (
cpioHeader
) iosm->
wrbuf
;
100
size_t
nb;
101
char
* end;
102
int
major
,
minor
;
103
ssize_t rc = 0;
104
105
if (
_cpio_debug
)
106
fprintf(stderr,
" cpioHeaderRead(%p, %p)\n"
, iosm, st);
107
108
/* Read next header. */
109
rc =
cpioRead
(iosm, hdr,
PHYS_HDR_SIZE
);
110
_IOSMRC
(rc);
111
112
/* Verify header magic. */
113
if
(strncmp(
CPIO_CRC_MAGIC
, hdr->
magic
,
sizeof
(
CPIO_CRC_MAGIC
)-1) &&
114
strncmp(
CPIO_NEWC_MAGIC
, hdr->
magic
,
sizeof
(
CPIO_NEWC_MAGIC
)-1))
115
return
IOSMERR_BAD_MAGIC
;
116
117
/* Convert header to stat(2). */
118
GET_NUM_FIELD
(hdr->
inode
, st->st_ino);
119
GET_NUM_FIELD
(hdr->
mode
, st->st_mode);
120
GET_NUM_FIELD
(hdr->
uid
, st->st_uid);
121
GET_NUM_FIELD
(hdr->
gid
, st->st_gid);
122
GET_NUM_FIELD
(hdr->
nlink
, st->st_nlink);
123
GET_NUM_FIELD
(hdr->
mtime
, st->st_mtime);
124
GET_NUM_FIELD
(hdr->
filesize
, st->st_size);
125
126
GET_NUM_FIELD
(hdr->
devMajor
, major);
127
GET_NUM_FIELD
(hdr->
devMinor
,
minor
);
128
/*@-shiftimplementation@*/
129
st->st_dev =
Makedev
(major,
minor
);
130
/*@=shiftimplementation@*/
131
132
GET_NUM_FIELD
(hdr->
rdevMajor
, major);
133
GET_NUM_FIELD
(hdr->
rdevMinor
,
minor
);
134
/*@-shiftimplementation@*/
135
st->st_rdev =
Makedev
(major,
minor
);
136
/*@=shiftimplementation@*/
137
138
GET_NUM_FIELD
(hdr->
namesize
, nb);
139
if
(nb >= iosm->
wrsize
)
140
return
IOSMERR_BAD_HEADER
;
141
142
/* Read file name. */
143
{
char
* t = (
char
*)
xmalloc
(nb + 1);
144
rc =
cpioRead
(iosm, t, nb);
145
if
(rc < 0) {
146
t =
_free
(t);
147
iosm->
path
= NULL;
148
}
else
{
149
_IOSMRC
(rc);
150
t[nb] =
'\0'
;
151
iosm->
path
= t;
152
}
153
}
154
155
/* Read link name. */
156
if
(
S_ISLNK
(st->st_mode)) {
157
char
* t;
158
159
/* Make sure block aligned. */
160
rc =
_iosmNext
(iosm,
IOSM_POS
);
161
if
(rc)
return
(
int
) -rc;
162
163
nb = (size_t) st->st_size;
164
t = (
char
*)
xmalloc
(nb + 1);
165
rc =
cpioRead
(iosm, t, nb);
166
if
(rc < 0) {
167
t =
_free
(t);
168
iosm->
lpath
= NULL;
169
}
else
{
170
_IOSMRC
(rc);
171
t[nb] =
'\0'
;
172
iosm->
lpath
= t;
173
}
174
}
175
176
rc = 0;
177
178
/*@-usereleased@*/
179
if
(
_cpio_debug
)
180
fprintf(stderr,
"\t %06o%3d (%4d,%4d)%12lu %s\n\t-> %s\n"
,
181
(
unsigned
)st->st_mode, (
int
)st->st_nlink,
182
(
int
)st->st_uid, (
int
)st->st_gid, (
unsigned
long
)st->st_size,
183
(iosm->
path
? iosm->
path
:
""
), (iosm->
lpath
? iosm->
lpath
:
""
));
184
/*@=usereleased@*/
185
186
return
(
int
) rc;
187
}
188
189
static
ssize_t
cpioWrite
(
void
* _iosm,
const
void
*buf,
size_t
count)
190
/*@globals fileSystem @*/
191
/*@modifies _iosm, fileSystem @*/
192
{
193
IOSM_t
iosm = (
IOSM_t
) _iosm;
194
const
char
* s = (
const
char
*) buf;
195
size_t
nb = 0;
196
size_t
rc;
197
198
if
(
_cpio_debug
)
199
fprintf(stderr,
"\t cpioWrite(%p, %p[%u])\n"
, iosm, buf, (
unsigned
)count);
200
201
while
(count > 0) {
202
203
/* XXX DWRITE uses rdnb for I/O length. */
204
iosm->
rdnb
= count;
205
if
(s != iosm->
rdbuf
)
206
memmove(iosm->
rdbuf
, s + nb, iosm->
rdnb
);
207
208
rc =
_iosmNext
(iosm,
IOSM_DWRITE
);
209
if
(!rc && iosm->
rdnb
!= iosm->
wrnb
)
210
rc =
IOSMERR_WRITE_FAILED
;
211
if
(rc)
return
-rc;
212
213
nb += iosm->
rdnb
;
214
count -= iosm->
rdnb
;
215
}
216
217
#if defined(JBJ_WRITEPAD)
218
/* Pad to next block boundary. */
219
if
((rc =
_iosmNext
(iosm,
IOSM_PAD
)) != 0)
return
-rc;
220
#endif
221
222
return
nb;
223
}
224
225
int
cpioHeaderWrite
(
void
* _iosm,
struct
stat * st)
226
{
227
IOSM_t
iosm = (
IOSM_t
) _iosm;
228
cpioHeader
hdr = (
cpioHeader
) iosm->
rdbuf
;
229
const
char
* path = (iosm && iosm->
path
? iosm->
path
:
""
);
230
const
char
* lpath = (iosm && iosm->
lpath
? iosm->
lpath
:
""
);
231
char
field[64];
232
size_t
nb;
233
dev_t dev;
234
ssize_t rc = 0;
235
236
if
(
_cpio_debug
)
237
fprintf(stderr,
" cpioHeaderWrite(%p, %p)\n"
, iosm, st);
238
239
memcpy(hdr->
magic
,
CPIO_NEWC_MAGIC
,
sizeof
(hdr->
magic
));
240
SET_NUM_FIELD
(hdr->
inode
, st->st_ino, field);
241
SET_NUM_FIELD
(hdr->
mode
, st->st_mode, field);
242
SET_NUM_FIELD
(hdr->
uid
, st->st_uid, field);
243
SET_NUM_FIELD
(hdr->
gid
, st->st_gid, field);
244
SET_NUM_FIELD
(hdr->
nlink
, st->st_nlink, field);
245
SET_NUM_FIELD
(hdr->
mtime
, st->st_mtime, field);
246
SET_NUM_FIELD
(hdr->
filesize
, st->st_size, field);
247
248
dev =
major
((
unsigned
)st->st_dev);
SET_NUM_FIELD
(hdr->
devMajor
, dev, field);
249
dev =
minor
((
unsigned
)st->st_dev);
SET_NUM_FIELD
(hdr->
devMinor
, dev, field);
250
dev =
major
((
unsigned
)st->st_rdev);
SET_NUM_FIELD
(hdr->
rdevMajor
, dev, field);
251
dev =
minor
((
unsigned
)st->st_rdev);
SET_NUM_FIELD
(hdr->
rdevMinor
, dev, field);
252
253
nb = strlen(path) + 1;
SET_NUM_FIELD
(hdr->
namesize
, nb, field);
254
memcpy(hdr->
checksum
,
"00000000"
, 8);
255
256
/* XXX Coalesce hdr+name into single I/O. */
257
memcpy(iosm->
rdbuf
+
PHYS_HDR_SIZE
, path, nb);
258
nb +=
PHYS_HDR_SIZE
;
259
rc =
cpioWrite
(iosm, hdr, nb);
260
_IOSMRC
(rc);
261
262
if
(
S_ISLNK
(st->st_mode)) {
263
#if !defined(JBJ_WRITEPAD)
264
rc =
_iosmNext
(iosm,
IOSM_PAD
);
265
if
(rc)
return
(
int
) rc;
266
#endif
267
268
nb = strlen(lpath);
269
rc =
cpioWrite
(iosm, lpath, nb);
270
_IOSMRC
(rc);
271
}
272
273
#if !defined(JBJ_WRITEPAD)
274
rc =
_iosmNext
(iosm,
IOSM_PAD
);
275
#endif
276
277
return
(
int
) rc;
278
}
279
280
int
cpioTrailerWrite
(
void
* _iosm)
281
{
282
IOSM_t
iosm = (
IOSM_t
) _iosm;
283
cpioHeader
hdr = (
cpioHeader
) iosm->
rdbuf
;
284
size_t
nb;
285
ssize_t rc = 0;
286
287
if (
_cpio_debug
)
288
fprintf(stderr,
" cpioTrailerWrite(%p)\n"
, iosm);
289
290
memset(hdr, (
int
)
'0'
,
PHYS_HDR_SIZE
);
291
memcpy(hdr->
magic
,
CPIO_NEWC_MAGIC
,
sizeof
(hdr->
magic
));
292
memcpy(hdr->
nlink
,
"00000001"
, 8);
293
memcpy(hdr->
namesize
,
"0000000b"
, 8);
294
295
nb =
sizeof
(
CPIO_TRAILER
);
296
/* XXX Coalesce hdr+trailer into single I/O. */
297
memcpy(iosm->
rdbuf
+
PHYS_HDR_SIZE
,
CPIO_TRAILER
, nb);
298
nb +=
PHYS_HDR_SIZE
;
299
300
rc =
cpioWrite
(iosm, hdr, nb);
301
_IOSMRC
(rc);
302
303
/*
304
* GNU cpio pads to 512 bytes here, but we don't. This may matter for
305
* tape device(s) and/or concatenated cpio archives. <shrug>
306
*/
307
#if !defined(JBJ_WRITEPAD)
308
rc =
_iosmNext
(iosm,
IOSM_PAD
);
309
#endif
310
rc = 0;
311
312
return
(
int
) rc;
313
}
314
Generated on Mon Nov 5 2012 15:32:19 for rpm by
1.8.1.2