| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: rpm2pkg.c,v 1.8 2009/06/14 22:44:34 joerg Exp $ */ | | 1 | /* $NetBSD: rpm2pkg.c,v 1.9 2010/06/13 13:08:52 tron Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2004-2009 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2004-2009 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Matthias Scheler. | | 8 | * by Matthias Scheler. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -24,68 +24,78 @@ | | | @@ -24,68 +24,78 @@ |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. | | 29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | #include <sys/types.h> | | 32 | #include <sys/types.h> |
33 | #include <sys/stat.h> | | 33 | #include <sys/stat.h> |
34 | | | 34 | |
35 | #include <errno.h> | | 35 | #include <errno.h> |
36 | #include <fcntl.h> | | 36 | #include <fcntl.h> |
| | | 37 | #include <stdbool.h> |
37 | #include <stdio.h> | | 38 | #include <stdio.h> |
38 | #include <stdlib.h> | | 39 | #include <stdlib.h> |
39 | #include <string.h> | | 40 | #include <string.h> |
40 | #include <unistd.h> | | 41 | #include <unistd.h> |
41 | | | 42 | |
42 | #include <bzlib.h> | | 43 | #include <bzlib.h> |
43 | #include <rpmlib.h> | | | |
44 | #include <zlib.h> | | 44 | #include <zlib.h> |
45 | | | 45 | |
| | | 46 | /* |
| | | 47 | * Lead of an RPM archive as described here: |
| | | 48 | * http://www.rpm.org/max-rpm/s1-rpm-file-format-rpm-file-format.html |
| | | 49 | */ |
| | | 50 | static const unsigned char RPMMagic[] = { 0xed, 0xab, 0xee, 0xdb }; |
| | | 51 | |
| | | 52 | #define RPM_LEAD_SIZE 96 |
| | | 53 | |
| | | 54 | /* Magic bytes for "bzip2" and "gzip" compressed files. */ |
| | | 55 | static const unsigned char BZipMagic[] = { 'B', 'Z', 'h' }; |
| | | 56 | static const unsigned char GZipMagic[] = { 0x1f, 0x8b, 0x08 }; |
| | | 57 | |
| | | 58 | /* Structure of a cpio(1) archive. */ |
46 | #define C_IRUSR 0000400 | | 59 | #define C_IRUSR 0000400 |
47 | #define C_IWUSR 0000200 | | 60 | #define C_IWUSR 0000200 |
48 | #define C_IXUSR 0000100 | | 61 | #define C_IXUSR 0000100 |
49 | #define C_IRGRP 0000040 | | 62 | #define C_IRGRP 0000040 |
50 | #define C_IWGRP 0000020 | | 63 | #define C_IWGRP 0000020 |
51 | #define C_IXGRP 0000010 | | 64 | #define C_IXGRP 0000010 |
52 | #define C_IROTH 0000004 | | 65 | #define C_IROTH 0000004 |
53 | #define C_IWOTH 0000002 | | 66 | #define C_IWOTH 0000002 |
54 | #define C_IXOTH 0000001 | | 67 | #define C_IXOTH 0000001 |
55 | #define C_ISUID 0004000 | | 68 | #define C_ISUID 0004000 |
56 | #define C_ISGID 0002000 | | 69 | #define C_ISGID 0002000 |
57 | #define C_ISVTX 0001000 | | 70 | #define C_ISVTX 0001000 |
58 | #define C_ISDIR 0040000 | | 71 | #define C_ISDIR 0040000 |
59 | #define C_ISREG 0100000 | | 72 | #define C_ISREG 0100000 |
60 | #define C_ISCHR 0020000 | | 73 | #define C_ISCHR 0020000 |
61 | #define C_ISLNK 0120000 | | 74 | #define C_ISLNK 0120000 |
62 | | | 75 | |
63 | char CPIOMagic[] = {'0','7','0','7','0','1'}; | | 76 | static const unsigned char CPIOMagic[] = {'0','7','0','7','0','1'}; |
64 | | | 77 | |
65 | #define CPIO_END_MARKER "TRAILER!!!" | | 78 | #define CPIO_END_MARKER "TRAILER!!!" |
66 | #define CPIO_FIELD_LENGTH 8 | | 79 | #define CPIO_FIELD_LENGTH 8 |
67 | | | 80 | |
68 | #define CPIO_HDR_INODE 0 | | 81 | #define CPIO_HDR_INODE 0 |
69 | #define CPIO_HDR_MODE 1 | | 82 | #define CPIO_HDR_MODE 1 |
70 | #define CPIO_HDR_FILESIZE 6 | | 83 | #define CPIO_HDR_FILESIZE 6 |
71 | #define CPIO_HDR_NAMESIZE 11 | | 84 | #define CPIO_HDR_NAMESIZE 11 |
72 | #define CPIO_NUM_HEADERS 13 | | 85 | #define CPIO_NUM_HEADERS 13 |
73 | | | 86 | |
74 | #define CP_IFMT 0170000 | | 87 | #define CP_IFMT 0170000 |
75 | | | 88 | |
76 | #define TRUE 1 | | | |
77 | #define FALSE 0 | | | |
78 | | | | |
79 | typedef struct ModeMapStruct { | | 89 | typedef struct ModeMapStruct { |
80 | unsigned long mm_CPIOMode; | | 90 | unsigned long mm_CPIOMode; |
81 | mode_t mm_SysMode; | | 91 | mode_t mm_SysMode; |
82 | } ModeMap; | | 92 | } ModeMap; |
83 | | | 93 | |
84 | ModeMap ModeMapTab[] = { | | 94 | ModeMap ModeMapTab[] = { |
85 | {C_IRUSR, S_IRUSR}, | | 95 | {C_IRUSR, S_IRUSR}, |
86 | {C_IWUSR, S_IWUSR}, | | 96 | {C_IWUSR, S_IWUSR}, |
87 | {C_IXUSR, S_IXUSR}, | | 97 | {C_IXUSR, S_IXUSR}, |
88 | {C_IRGRP, S_IRGRP}, | | 98 | {C_IRGRP, S_IRGRP}, |
89 | {C_IWGRP, S_IWGRP}, | | 99 | {C_IWGRP, S_IWGRP}, |
90 | {C_IXGRP, S_IXGRP}, | | 100 | {C_IXGRP, S_IXGRP}, |
91 | {C_IROTH, S_IROTH}, | | 101 | {C_IROTH, S_IROTH}, |
| @@ -114,153 +124,207 @@ typedef void PListEntryFunc(PListEntry * | | | @@ -114,153 +124,207 @@ typedef void PListEntryFunc(PListEntry * |
114 | | | 124 | |
115 | #define PLIST_ORDER_FORWARD 0 | | 125 | #define PLIST_ORDER_FORWARD 0 |
116 | #define PLIST_ORDER_BACKWARD 1 | | 126 | #define PLIST_ORDER_BACKWARD 1 |
117 | | | 127 | |
118 | #define INVERT_PLIST_ORDER(o) (1 - (o)) | | 128 | #define INVERT_PLIST_ORDER(o) (1 - (o)) |
119 | | | 129 | |
120 | typedef struct FileHandleStruct { | | 130 | typedef struct FileHandleStruct { |
121 | FILE *fh_File; | | 131 | FILE *fh_File; |
122 | BZFILE *fh_BZFile; | | 132 | BZFILE *fh_BZFile; |
123 | gzFile *fh_GZFile; | | 133 | gzFile *fh_GZFile; |
124 | off_t fh_Pos; | | 134 | off_t fh_Pos; |
125 | } FileHandle; | | 135 | } FileHandle; |
126 | | | 136 | |
127 | static int | | 137 | static bool |
128 | InitBuffer(void **Buffer, size_t *BufferSizePtr) | | 138 | InitBuffer(void **Buffer, size_t *BufferSizePtr) |
129 | { | | 139 | { |
130 | if (*Buffer == NULL) { | | 140 | if (*Buffer == NULL) { |
131 | size_t BufferSize; | | 141 | size_t BufferSize; |
132 | | | 142 | |
133 | BufferSize = sysconf(_SC_PAGESIZE) * 256; | | 143 | BufferSize = sysconf(_SC_PAGESIZE) * 256; |
134 | while ((*Buffer = malloc(BufferSize)) == NULL) { | | 144 | while ((*Buffer = malloc(BufferSize)) == NULL) { |
135 | BufferSize >>= 1; | | 145 | BufferSize >>= 1; |
136 | if (BufferSize == 0) | | 146 | if (BufferSize == 0) |
137 | return FALSE; | | 147 | return false; |
138 | } | | 148 | } |
139 | *BufferSizePtr = BufferSize; | | 149 | *BufferSizePtr = BufferSize; |
140 | } | | 150 | } |
141 | return TRUE; | | 151 | return true; |
142 | } | | 152 | } |
143 | | | 153 | |
144 | static void | | 154 | static void |
145 | Close(FileHandle *fh) | | 155 | Close(FileHandle *fh) |
146 | { | | 156 | { |
147 | if (fh->fh_BZFile != NULL) { | | 157 | if (fh->fh_BZFile != NULL) { |
148 | int bzerror; | | 158 | int bzerror; |
149 | | | 159 | |
150 | (void)BZ2_bzReadClose(&bzerror, fh->fh_BZFile); | | 160 | (void)BZ2_bzReadClose(&bzerror, fh->fh_BZFile); |
151 | (void)fclose(fh->fh_File); | | 161 | (void)fclose(fh->fh_File); |
152 | } else { | | 162 | } else { |
153 | (void)gzclose(fh->fh_GZFile); | | 163 | (void)gzclose(fh->fh_GZFile); |
154 | } | | 164 | } |
155 | free(fh); | | 165 | free(fh); |
156 | } | | 166 | } |
157 | | | 167 | |
| | | 168 | static bool |
| | | 169 | IsRPMFile(int fd) |
| | | 170 | { |
| | | 171 | char buffer[RPM_LEAD_SIZE]; |
| | | 172 | |
| | | 173 | if (read(fd, buffer, sizeof(buffer)) != sizeof(buffer)) |
| | | 174 | return false; |
| | | 175 | |
| | | 176 | return (memcmp(buffer, RPMMagic, sizeof(RPMMagic)) == 0); |
| | | 177 | } |
| | | 178 | |
158 | static FileHandle * | | 179 | static FileHandle * |
159 | Open(int fd) | | 180 | Open(int fd) |
160 | { | | 181 | { |
| | | 182 | unsigned char buffer[4096]; |
| | | 183 | size_t bzMatch, gzMatch; |
| | | 184 | int archive_type; |
161 | off_t offset; | | 185 | off_t offset; |
162 | char Magic[3]; | | | |
163 | FileHandle *fh; | | 186 | FileHandle *fh; |
164 | | | 187 | |
165 | if ((offset = lseek(fd, 0, SEEK_CUR)) < 0) | | 188 | bzMatch = 0; |
166 | return NULL; | | 189 | gzMatch = 0; |
167 | if (read(fd, Magic, sizeof (Magic)) != sizeof (Magic)) | | 190 | archive_type = 0; |
168 | return NULL; | | 191 | offset = 0; |
169 | if (lseek(fd, offset, SEEK_SET) != offset) | | 192 | do { |
| | | 193 | ssize_t bytes, i; |
| | | 194 | |
| | | 195 | bytes = read(fd, buffer, sizeof(buffer)); |
| | | 196 | if (bytes <= 0) |
| | | 197 | return NULL; |
| | | 198 | |
| | | 199 | for (i = 0; i < bytes; i++) { |
| | | 200 | /* Look for bzip2 header. */ |
| | | 201 | if (buffer[i] == BZipMagic[bzMatch]) { |
| | | 202 | bzMatch++; |
| | | 203 | if (bzMatch == sizeof(BZipMagic)) { |
| | | 204 | archive_type = 1; |
| | | 205 | offset = i - bytes - |
| | | 206 | sizeof(BZipMagic) + 1; |
| | | 207 | break; |
| | | 208 | } |
| | | 209 | } else { |
| | | 210 | bzMatch = 0; |
| | | 211 | } |
| | | 212 | |
| | | 213 | /* Look for gzip header. */ |
| | | 214 | if (buffer[i] == GZipMagic[gzMatch]) { |
| | | 215 | gzMatch++; |
| | | 216 | if (gzMatch == sizeof(GZipMagic)) { |
| | | 217 | archive_type = 2; |
| | | 218 | offset = i - bytes - |
| | | 219 | sizeof(GZipMagic) + 1; |
| | | 220 | break; |
| | | 221 | } |
| | | 222 | } else { |
| | | 223 | gzMatch = 0; |
| | | 224 | } |
| | | 225 | |
| | | 226 | offset++; |
| | | 227 | } |
| | | 228 | } while (archive_type == 0); |
| | | 229 | |
| | | 230 | /* Go back to the beginning of the archive. */ |
| | | 231 | if (lseek(fd, offset, SEEK_CUR) < RPM_LEAD_SIZE) |
170 | return NULL; | | 232 | return NULL; |
171 | | | 233 | |
172 | if ((fh = calloc(1, sizeof (FileHandle))) == NULL) | | 234 | if ((fh = calloc(1, sizeof (FileHandle))) == NULL) |
173 | return NULL; | | 235 | return NULL; |
174 | | | 236 | |
175 | if ((Magic[0] == 'B') && (Magic[1] == 'Z') && (Magic[2] == 'h')) { | | 237 | if (archive_type == 1) { |
| | | 238 | /* bzip2 archive */ |
176 | int bzerror; | | 239 | int bzerror; |
177 | | | 240 | |
178 | if ((fd = dup(fd)) < 0) { | | 241 | if ((fd = dup(fd)) < 0) { |
179 | free(fh); | | 242 | free(fh); |
180 | return NULL; | | 243 | return NULL; |
181 | } | | 244 | } |
182 | if ((fh->fh_File = fdopen(fd, "rb")) == NULL) { | | 245 | if ((fh->fh_File = fdopen(fd, "rb")) == NULL) { |
183 | perror("fdopen"); | | 246 | perror("fdopen"); |
184 | (void)close(fd); | | 247 | (void)close(fd); |
185 | free(fh); | | 248 | free(fh); |
186 | return NULL; | | 249 | return NULL; |
187 | } | | 250 | } |
188 | if ((fh->fh_BZFile = BZ2_bzReadOpen(&bzerror, fh->fh_File, 0, | | 251 | if ((fh->fh_BZFile = BZ2_bzReadOpen(&bzerror, fh->fh_File, 0, |
189 | 0, NULL, 0)) == NULL) { | | 252 | 0, NULL, 0)) == NULL) { |
190 | (void)fclose(fh->fh_File); | | 253 | (void)fclose(fh->fh_File); |
191 | free(fh); | | 254 | free(fh); |
192 | return (NULL); | | 255 | return (NULL); |
193 | } | | 256 | } |
194 | } else { | | 257 | } else { |
| | | 258 | /* gzip archive */ |
195 | if ((fh->fh_GZFile = gzdopen(fd, "r")) == NULL) { | | 259 | if ((fh->fh_GZFile = gzdopen(fd, "r")) == NULL) { |
196 | free(fh); | | 260 | free(fh); |
197 | return (NULL); | | 261 | return (NULL); |
198 | } | | 262 | } |
199 | } | | 263 | } |
200 | | | 264 | |
201 | return (fh); | | 265 | return (fh); |
202 | } | | 266 | } |
203 | | | 267 | |
204 | static int | | 268 | static int |
205 | Read(FileHandle *fh, void *buffer, int length) | | 269 | Read(FileHandle *fh, void *buffer, int length) |
206 | { | | 270 | { |
207 | int bzerror, bytes; | | 271 | int bzerror, bytes; |
208 | | | 272 | |
209 | bytes = (fh->fh_BZFile != NULL) ? | | 273 | bytes = (fh->fh_BZFile != NULL) ? |
210 | BZ2_bzRead(&bzerror, fh->fh_BZFile, buffer, length) : | | 274 | BZ2_bzRead(&bzerror, fh->fh_BZFile, buffer, length) : |
211 | gzread(fh->fh_GZFile, buffer, length); | | 275 | gzread(fh->fh_GZFile, buffer, length); |
212 | if (bytes > 0) | | 276 | if (bytes > 0) |
213 | fh->fh_Pos += bytes; | | 277 | fh->fh_Pos += bytes; |
214 | | | 278 | |
215 | return (bytes == length); | | 279 | return (bytes == length); |
216 | } | | 280 | } |
217 | | | 281 | |
218 | static int | | 282 | static bool |
219 | SkipAndAlign(FileHandle *fh, off_t Skip) | | 283 | SkipAndAlign(FileHandle *fh, off_t Skip) |
220 | | | 284 | |
221 | { | | 285 | { |
222 | off_t NewPos; | | 286 | off_t NewPos; |
223 | | | 287 | |
224 | NewPos = (fh->fh_Pos + Skip + 3) & ~3; | | 288 | NewPos = (fh->fh_Pos + Skip + 3) & ~3; |
225 | if (fh->fh_Pos == NewPos) | | 289 | if (fh->fh_Pos == NewPos) |
226 | return TRUE; | | 290 | return true; |
227 | | | 291 | |
228 | if (fh->fh_GZFile != NULL) { | | 292 | if (fh->fh_GZFile != NULL) { |
229 | if (gzseek(fh->fh_GZFile, NewPos, SEEK_SET) == NewPos) { | | 293 | if (gzseek(fh->fh_GZFile, NewPos, SEEK_SET) == NewPos) { |
230 | fh->fh_Pos = NewPos; | | 294 | fh->fh_Pos = NewPos; |
231 | return TRUE; | | 295 | return true; |
232 | } | | 296 | } |
233 | return FALSE; | | 297 | return false; |
234 | } else { | | 298 | } else { |
235 | static void *Buffer = NULL; | | 299 | static void *Buffer = NULL; |
236 | static size_t BufferSize = 0; | | 300 | static size_t BufferSize = 0; |
237 | | | 301 | |
238 | if (!InitBuffer(&Buffer, &BufferSize)) | | 302 | if (!InitBuffer(&Buffer, &BufferSize)) |
239 | return FALSE; | | 303 | return false; |
240 | | | 304 | |
241 | while (fh->fh_Pos < NewPos) { | | 305 | while (fh->fh_Pos < NewPos) { |
242 | off_t Length; | | 306 | off_t Length; |
243 | int Chunk; | | 307 | int Chunk; |
244 | | | 308 | |
245 | Length = NewPos - fh->fh_Pos; | | 309 | Length = NewPos - fh->fh_Pos; |
246 | Chunk = (Length > (off_t)BufferSize) ? | | 310 | Chunk = (Length > (off_t)BufferSize) ? |
247 | (off_t)BufferSize : Length; | | 311 | (off_t)BufferSize : Length; |
248 | if (!Read(fh, Buffer, Chunk)) | | 312 | if (!Read(fh, Buffer, Chunk)) |
249 | return FALSE; | | 313 | return false; |
250 | } | | 314 | } |
251 | } | | 315 | } |
252 | | | 316 | |
253 | return TRUE; | | 317 | return true; |
254 | } | | 318 | } |
255 | | | 319 | |
256 | static PListEntry * | | 320 | static PListEntry * |
257 | InsertPListEntry(PListEntry **Tree,char *Name) | | 321 | InsertPListEntry(PListEntry **Tree,char *Name) |
258 | { | | 322 | { |
259 | PListEntry *Node; | | 323 | PListEntry *Node; |
260 | | | 324 | |
261 | while ((Node = *Tree) != NULL) { | | 325 | while ((Node = *Tree) != NULL) { |
262 | Tree = (strcmp(Name, Node->pe_Name) <0) ? | | 326 | Tree = (strcmp(Name, Node->pe_Name) <0) ? |
263 | &Node->pe_Left : &Node->pe_Right; | | 327 | &Node->pe_Left : &Node->pe_Right; |
264 | } | | 328 | } |
265 | | | 329 | |
266 | if ((Node = calloc(1, sizeof (PListEntry) + strlen(Name))) == NULL) { | | 330 | if ((Node = calloc(1, sizeof (PListEntry) + strlen(Name))) == NULL) { |
| @@ -403,248 +467,248 @@ GetData(FileHandle *In, unsigned long Le | | | @@ -403,248 +467,248 @@ GetData(FileHandle *In, unsigned long Le |
403 | char *Ptr; | | 467 | char *Ptr; |
404 | | | 468 | |
405 | if ((Ptr = malloc(Length + 1)) != NULL) { | | 469 | if ((Ptr = malloc(Length + 1)) != NULL) { |
406 | if (Read(In, Ptr, Length) && SkipAndAlign(In, 0)) { | | 470 | if (Read(In, Ptr, Length) && SkipAndAlign(In, 0)) { |
407 | Ptr[Length] = '\0'; | | 471 | Ptr[Length] = '\0'; |
408 | return Ptr; | | 472 | return Ptr; |
409 | } | | 473 | } |
410 | free(Ptr); | | 474 | free(Ptr); |
411 | } | | 475 | } |
412 | | | 476 | |
413 | return NULL; | | 477 | return NULL; |
414 | } | | 478 | } |
415 | | | 479 | |
416 | static int | | 480 | static bool |
417 | GetCPIOHeader(FileHandle *In, unsigned long *Fields, char **Name) | | 481 | GetCPIOHeader(FileHandle *In, unsigned long *Fields, char **Name) |
418 | { | | 482 | { |
419 | char Buffer[CPIO_NUM_HEADERS*CPIO_FIELD_LENGTH], *Ptr; | | 483 | char Buffer[CPIO_NUM_HEADERS * CPIO_FIELD_LENGTH], *Ptr; |
420 | int Index; | | 484 | int Index; |
421 | unsigned long Value; | | 485 | unsigned long Value; |
422 | | | 486 | |
423 | *Name = NULL; | | 487 | *Name = NULL; |
424 | | | 488 | |
425 | if (!Read(In, Buffer, sizeof (CPIOMagic))) | | 489 | if (!Read(In, Buffer, sizeof (CPIOMagic))) |
426 | return FALSE; | | 490 | return false; |
427 | if (memcmp(Buffer, CPIOMagic, sizeof (CPIOMagic)) != 0) | | 491 | if (memcmp(Buffer, CPIOMagic, sizeof (CPIOMagic)) != 0) |
428 | return FALSE; | | 492 | return false; |
429 | | | 493 | |
430 | if (!Read(In, Buffer, sizeof (Buffer))) | | 494 | if (!Read(In, Buffer, sizeof (Buffer))) |
431 | return FALSE; | | 495 | return false; |
432 | | | 496 | |
433 | Ptr = Buffer; | | 497 | Ptr = Buffer; |
434 | Index = sizeof (Buffer); | | 498 | Index = sizeof (Buffer); |
435 | Value = 0; | | 499 | Value = 0; |
436 | while (Index-- > 0) { | | 500 | while (Index-- > 0) { |
437 | Value <<= 4; | | 501 | Value <<= 4; |
438 | if ((*Ptr >= '0') && (*Ptr <= '9')) { | | 502 | if ((*Ptr >= '0') && (*Ptr <= '9')) { |
439 | Value += (unsigned long)(*Ptr++-'0'); | | 503 | Value += (unsigned long)(*Ptr++-'0'); |
440 | } else if ((*Ptr >= 'A') && (*Ptr <= 'F')) { | | 504 | } else if ((*Ptr >= 'A') && (*Ptr <= 'F')) { |
441 | Value += (unsigned long)(*Ptr++-'A') + 10; | | 505 | Value += (unsigned long)(*Ptr++-'A') + 10; |
442 | } else if ((*Ptr >= 'a') && (*Ptr <= 'f')) { | | 506 | } else if ((*Ptr >= 'a') && (*Ptr <= 'f')) { |
443 | Value += (unsigned long)(*Ptr++-'a') + 10; | | 507 | Value += (unsigned long)(*Ptr++-'a') + 10; |
444 | } else { | | 508 | } else { |
445 | return FALSE; | | 509 | return false; |
446 | } | | 510 | } |
447 | | | 511 | |
448 | if ((Index % CPIO_FIELD_LENGTH) == 0) { | | 512 | if ((Index % CPIO_FIELD_LENGTH) == 0) { |
449 | *Fields++ = Value; | | 513 | *Fields++ = Value; |
450 | Value = 0; | | 514 | Value = 0; |
451 | } | | 515 | } |
452 | } | | 516 | } |
453 | | | 517 | |
454 | Value = Fields[CPIO_HDR_NAMESIZE - CPIO_NUM_HEADERS]; | | 518 | Value = Fields[CPIO_HDR_NAMESIZE - CPIO_NUM_HEADERS]; |
455 | if ((*Name = GetData(In, Value)) == NULL) | | 519 | if ((*Name = GetData(In, Value)) == NULL) |
456 | return FALSE; | | 520 | return false; |
457 | return ((*Name)[Value -1 ] == '\0'); | | 521 | return ((*Name)[Value -1 ] == '\0'); |
458 | } | | 522 | } |
459 | | | 523 | |
460 | static mode_t | | 524 | static mode_t |
461 | ConvertMode(unsigned long CPIOMode) | | 525 | ConvertMode(unsigned long CPIOMode) |
462 | { | | 526 | { |
463 | mode_t Mode; | | 527 | mode_t Mode; |
464 | ModeMap *Ptr; | | 528 | ModeMap *Ptr; |
465 | | | 529 | |
466 | Mode = 0; | | 530 | Mode = 0; |
467 | Ptr = ModeMapTab; | | 531 | Ptr = ModeMapTab; |
468 | while (Ptr->mm_CPIOMode != 0) { | | 532 | while (Ptr->mm_CPIOMode != 0) { |
469 | if ((CPIOMode & Ptr->mm_CPIOMode) != 0) | | 533 | if ((CPIOMode & Ptr->mm_CPIOMode) != 0) |
470 | Mode |= Ptr->mm_SysMode; | | 534 | Mode |= Ptr->mm_SysMode; |
471 | Ptr++; | | 535 | Ptr++; |
472 | } | | 536 | } |
473 | | | 537 | |
474 | return Mode; | | 538 | return Mode; |
475 | } | | 539 | } |
476 | | | 540 | |
477 | static int | | 541 | static bool |
478 | MakeTargetDir(char *Name, PListEntry **Dirs, int MarkNonEmpty) | | 542 | MakeTargetDir(char *Name, PListEntry **Dirs, int MarkNonEmpty) |
479 | { | | 543 | { |
480 | char *Basename; | | 544 | char *Basename; |
481 | PListEntry *Dir; | | 545 | PListEntry *Dir; |
482 | struct stat Stat; | | 546 | struct stat Stat; |
483 | int Result; | | 547 | int Result; |
484 | | | 548 | |
485 | if ((Basename = strrchr(Name, '/')) == NULL) | | 549 | if ((Basename = strrchr(Name, '/')) == NULL) |
486 | return TRUE; | | 550 | return true; |
487 | | | 551 | |
488 | *Basename = '\0'; | | 552 | *Basename = '\0'; |
489 | if ((Dir = FindPListEntry(*Dirs, Name)) != NULL) { | | 553 | if ((Dir = FindPListEntry(*Dirs, Name)) != NULL) { |
490 | *Basename = '/'; | | 554 | *Basename = '/'; |
491 | Dir->pe_DirEmpty = !MarkNonEmpty; | | 555 | Dir->pe_DirEmpty = !MarkNonEmpty; |
492 | return TRUE; | | 556 | return true; |
493 | } | | 557 | } |
494 | | | 558 | |
495 | if (!MakeTargetDir(Name, Dirs, TRUE)) { | | 559 | if (!MakeTargetDir(Name, Dirs, true)) { |
496 | *Basename = '/'; | | 560 | *Basename = '/'; |
497 | return FALSE; | | 561 | return false; |
498 | } | | 562 | } |
499 | | | 563 | |
500 | if (stat(Name, &Stat) == 0) { | | 564 | if (stat(Name, &Stat) == 0) { |
501 | Result = S_ISDIR(Stat.st_mode); | | 565 | Result = S_ISDIR(Stat.st_mode); |
502 | } else if (errno != ENOENT) { | | 566 | } else if (errno != ENOENT) { |
503 | Result = FALSE; | | 567 | Result = false; |
504 | } else if ((Result = (mkdir(Name, S_IRWXU|S_IRWXG|S_IRWXO) == 0))) { | | 568 | } else if ((Result = (mkdir(Name, S_IRWXU|S_IRWXG|S_IRWXO) == 0))) { |
505 | InsertPListEntry(Dirs, Name)->pe_DirMode = | | 569 | InsertPListEntry(Dirs, Name)->pe_DirMode = |
506 | S_IRWXU|S_IRWXG|S_IRWXO; | | 570 | S_IRWXU|S_IRWXG|S_IRWXO; |
507 | } | | 571 | } |
508 | | | 572 | |
509 | *Basename = '/'; | | 573 | *Basename = '/'; |
510 | return Result; | | 574 | return Result; |
511 | } | | 575 | } |
512 | | | 576 | |
513 | static int | | 577 | static bool |
514 | MakeDir(char *Name, mode_t Mode, int *OldDir) | | 578 | MakeDir(char *Name, mode_t Mode, int *OldDir) |
515 | { | | 579 | { |
516 | struct stat Stat; | | 580 | struct stat Stat; |
517 | | | 581 | |
518 | *OldDir = FALSE; | | 582 | *OldDir = false; |
519 | if (mkdir(Name, Mode) == 0) | | 583 | if (mkdir(Name, Mode) == 0) |
520 | return TRUE; | | 584 | return true; |
521 | | | 585 | |
522 | if ((errno != EEXIST) || (lstat(Name, &Stat) < 0) || | | 586 | if ((errno != EEXIST) || (lstat(Name, &Stat) < 0) || |
523 | !S_ISDIR(Stat.st_mode)) { | | 587 | !S_ISDIR(Stat.st_mode)) { |
524 | return FALSE; | | 588 | return false; |
525 | } | | 589 | } |
526 | | | 590 | |
527 | *OldDir = TRUE; | | 591 | *OldDir = true; |
528 | return TRUE; | | 592 | return true; |
529 | } | | 593 | } |
530 | | | 594 | |
531 | static int | | 595 | static bool |
532 | MakeSymLink(char *Link, char *Name) | | 596 | MakeSymLink(char *Link, char *Name) |
533 | { | | 597 | { |
534 | struct stat Stat; | | 598 | struct stat Stat; |
535 | | | 599 | |
536 | if (symlink(Link, Name) == 0) return TRUE; | | 600 | if (symlink(Link, Name) == 0) return true; |
537 | | | 601 | |
538 | if ((errno != EEXIST) || (lstat(Name, &Stat) < 0) || | | 602 | if ((errno != EEXIST) || (lstat(Name, &Stat) < 0) || |
539 | !S_ISLNK(Stat.st_mode)) { | | 603 | !S_ISLNK(Stat.st_mode)) { |
540 | return FALSE; | | 604 | return false; |
541 | } | | 605 | } |
542 | | | 606 | |
543 | return ((unlink(Name) == 0) && (symlink(Link, Name) == 0)); | | 607 | return ((unlink(Name) == 0) && (symlink(Link, Name) == 0)); |
544 | } | | 608 | } |
545 | | | 609 | |
546 | static int | | 610 | static bool |
547 | WriteFile(FileHandle *In, char *Name, mode_t Mode, unsigned long Length, | | 611 | WriteFile(FileHandle *In, char *Name, mode_t Mode, unsigned long Length, |
548 | char *Link) | | 612 | char *Link) |
549 | { | | 613 | { |
550 | int Out; | | 614 | int Out; |
551 | struct stat Stat; | | 615 | struct stat Stat; |
552 | static void *Buffer = NULL; | | 616 | static void *Buffer = NULL; |
553 | static size_t BufferSize = 0; | | 617 | static size_t BufferSize = 0; |
554 | | | 618 | |
555 | if ((lstat(Name, &Stat) == 0) && | | 619 | if ((lstat(Name, &Stat) == 0) && |
556 | (!S_ISREG(Stat.st_mode) || (unlink(Name) < 0))) { | | 620 | (!S_ISREG(Stat.st_mode) || (unlink(Name) < 0))) { |
557 | return FALSE; | | 621 | return false; |
558 | } | | 622 | } |
559 | | | 623 | |
560 | if (!InitBuffer(&Buffer, &BufferSize)) | | 624 | if (!InitBuffer(&Buffer, &BufferSize)) |
561 | return FALSE; | | 625 | return false; |
562 | | | 626 | |
563 | if (Link != NULL) { | | 627 | if (Link != NULL) { |
564 | if (link(Link, Name) < 0) | | 628 | if (link(Link, Name) < 0) |
565 | return FALSE; | | 629 | return false; |
566 | Out = open(Name, O_WRONLY, Mode); | | 630 | Out = open(Name, O_WRONLY, Mode); |
567 | } else { | | 631 | } else { |
568 | Out = open(Name, O_WRONLY|O_CREAT, Mode); | | 632 | Out = open(Name, O_WRONLY|O_CREAT, Mode); |
569 | } | | 633 | } |
570 | if (Out < 0) | | 634 | if (Out < 0) |
571 | return FALSE; | | 635 | return false; |
572 | | | 636 | |
573 | while (Length > 0) { | | 637 | while (Length > 0) { |
574 | int Chunk; | | 638 | int Chunk; |
575 | | | 639 | |
576 | Chunk = (Length > BufferSize) ? BufferSize : Length; | | 640 | Chunk = (Length > BufferSize) ? BufferSize : Length; |
577 | if (!Read(In, Buffer, Chunk) || | | 641 | if (!Read(In, Buffer, Chunk) || |
578 | (write(Out, Buffer, Chunk) != Chunk)) | | 642 | (write(Out, Buffer, Chunk) != Chunk)) |
579 | break; | | 643 | break; |
580 | Length -= Chunk; | | 644 | Length -= Chunk; |
581 | } | | 645 | } |
582 | | | 646 | |
583 | if ((close(Out) == 0) && (Length == 0)) | | 647 | if ((close(Out) == 0) && (Length == 0)) |
584 | return SkipAndAlign(In, 0); | | 648 | return SkipAndAlign(In, 0); |
585 | | | 649 | |
586 | (void)unlink(Name); | | 650 | (void)unlink(Name); |
587 | return FALSE; | | 651 | return false; |
588 | } | | 652 | } |
589 | | | 653 | |
590 | static void | | 654 | static void |
591 | CheckSymLinks(PListEntry **Links, PListEntry **Files, PListEntry **Dirs) | | 655 | CheckSymLinks(PListEntry **Links, PListEntry **Files, PListEntry **Dirs) |
592 | { | | 656 | { |
593 | PListEntry *Link; | | 657 | PListEntry *Link; |
594 | | | 658 | |
595 | while ((Link = *Links) != NULL) { | | 659 | while ((Link = *Links) != NULL) { |
596 | struct stat Stat; | | 660 | struct stat Stat; |
597 | PListEntry *Ptr; | | 661 | PListEntry *Ptr; |
598 | char *Basename; | | 662 | char *Basename; |
599 | | | 663 | |
600 | if (Link->pe_Left != NULL) | | 664 | if (Link->pe_Left != NULL) |
601 | CheckSymLinks(&Link->pe_Left, Files, Dirs); | | 665 | CheckSymLinks(&Link->pe_Left, Files, Dirs); |
602 | | | 666 | |
603 | if ((stat(Link->pe_Name, &Stat) < 0) || | | 667 | if ((stat(Link->pe_Name, &Stat) < 0) || |
604 | !S_ISREG(Stat.st_mode)) { | | 668 | !S_ISREG(Stat.st_mode)) { |
605 | Links = &Link->pe_Right; | | 669 | Links = &Link->pe_Right; |
606 | continue; | | 670 | continue; |
607 | } | | 671 | } |
608 | | | 672 | |
609 | (void)InsertPListEntry(Files, Link->pe_Name); | | 673 | (void)InsertPListEntry(Files, Link->pe_Name); |
610 | if ((Basename = strrchr(Link->pe_Name, '/')) != NULL) { | | 674 | if ((Basename = strrchr(Link->pe_Name, '/')) != NULL) { |
611 | *Basename = '\0'; | | 675 | *Basename = '\0'; |
612 | if ((Ptr = FindPListEntry(*Dirs, | | 676 | if ((Ptr = FindPListEntry(*Dirs, |
613 | Link->pe_Name)) != NULL) | | 677 | Link->pe_Name)) != NULL) |
614 | Ptr->pe_DirEmpty = FALSE; | | 678 | Ptr->pe_DirEmpty = false; |
615 | } | | 679 | } |
616 | | | 680 | |
617 | if (Link->pe_Right == NULL) { | | 681 | if (Link->pe_Right == NULL) { |
618 | *Links = Link->pe_Left; | | 682 | *Links = Link->pe_Left; |
619 | free(Link); | | 683 | free(Link); |
620 | break; | | 684 | break; |
621 | } | | 685 | } |
622 | | | 686 | |
623 | *Links = Link->pe_Right; | | 687 | *Links = Link->pe_Right; |
624 | Ptr = Link->pe_Left; | | 688 | Ptr = Link->pe_Left; |
625 | free(Link); | | 689 | free(Link); |
626 | | | 690 | |
627 | if (Ptr == NULL) | | 691 | if (Ptr == NULL) |
628 | continue; | | 692 | continue; |
629 | | | 693 | |
630 | Link = *Links; | | 694 | Link = *Links; |
631 | while (Link->pe_Left != NULL) | | 695 | while (Link->pe_Left != NULL) |
632 | Link = Link->pe_Left; | | 696 | Link = Link->pe_Left; |
633 | Link->pe_Left = Ptr; | | 697 | Link->pe_Left = Ptr; |
634 | } | | 698 | } |
635 | } | | 699 | } |
636 | | | 700 | |
637 | static int | | 701 | static bool |
638 | CheckPrefix(char *Prefix, char *Name) | | 702 | CheckPrefix(char *Prefix, char *Name) |
639 | { | | 703 | { |
640 | int Length; | | 704 | int Length; |
641 | | | 705 | |
642 | Length = strlen(Prefix); | | 706 | Length = strlen(Prefix); |
643 | return ((strncmp(Prefix, Name, Length) == 0) && | | 707 | return ((strncmp(Prefix, Name, Length) == 0) && |
644 | ((Name[Length] == '\0') || (Name[Length] == '/'))); | | 708 | ((Name[Length] == '\0') || (Name[Length] == '/'))); |
645 | } | | 709 | } |
646 | | | 710 | |
647 | static char * | | 711 | static char * |
648 | StripPrefix(char *Name, int Count) | | 712 | StripPrefix(char *Name, int Count) |
649 | { | | 713 | { |
650 | char *NewName; | | 714 | char *NewName; |
| @@ -660,29 +724,28 @@ StripPrefix(char *Name, int Count) | | | @@ -660,29 +724,28 @@ StripPrefix(char *Name, int Count) |
660 | NewName++; | | 724 | NewName++; |
661 | } | | 725 | } |
662 | (void)memmove(Name, NewName, strlen(NewName) + 1); | | 726 | (void)memmove(Name, NewName, strlen(NewName) + 1); |
663 | | | 727 | |
664 | return Name; | | 728 | return Name; |
665 | } | | 729 | } |
666 | | | 730 | |
667 | int | | 731 | int |
668 | main(int argc, char **argv) | | 732 | main(int argc, char **argv) |
669 | { | | 733 | { |
670 | char *Progname; | | 734 | char *Progname; |
671 | FILE *PListFile; | | 735 | FILE *PListFile; |
672 | char **Ignore, *Prefix; | | 736 | char **Ignore, *Prefix; |
673 | int Opt, Index, FD, IsSource, StripCount; | | 737 | int Opt, Index, FD, StripCount; |
674 | PListEntry *Files, *Links, *Dirs; | | 738 | PListEntry *Files, *Links, *Dirs; |
675 | Header Hdr; | | | |
676 | FileHandle *In; | | 739 | FileHandle *In; |
677 | | | 740 | |
678 | Progname = strrchr(argv[0], '/'); | | 741 | Progname = strrchr(argv[0], '/'); |
679 | if (Progname == NULL) | | 742 | if (Progname == NULL) |
680 | Progname = argv[0]; | | 743 | Progname = argv[0]; |
681 | else | | 744 | else |
682 | Progname ++; | | 745 | Progname ++; |
683 | | | 746 | |
684 | PListFile = NULL; | | 747 | PListFile = NULL; |
685 | Ignore = NULL; | | 748 | Ignore = NULL; |
686 | Prefix = NULL; | | 749 | Prefix = NULL; |
687 | StripCount = 0; | | 750 | StripCount = 0; |
688 | while ((Opt = getopt(argc, argv, "s:d:f:i:p:")) != -1) { | | 751 | while ((Opt = getopt(argc, argv, "s:d:f:i:p:")) != -1) { |
| @@ -732,38 +795,30 @@ main(int argc, char **argv) | | | @@ -732,38 +795,30 @@ main(int argc, char **argv) |
732 | Prefix = StrCat(Prefix, "/"); | | 795 | Prefix = StrCat(Prefix, "/"); |
733 | | | 796 | |
734 | Files = NULL; | | 797 | Files = NULL; |
735 | Links = NULL; | | 798 | Links = NULL; |
736 | Dirs = NULL; | | 799 | Dirs = NULL; |
737 | for (Index = 0; Index < argc ; Index++) { | | 800 | for (Index = 0; Index < argc ; Index++) { |
738 | PListEntry *Last; | | 801 | PListEntry *Last; |
739 | | | 802 | |
740 | if ((FD = open(argv[Index], O_RDONLY, 0)) < 0) { | | 803 | if ((FD = open(argv[Index], O_RDONLY, 0)) < 0) { |
741 | perror(argv[Index]); | | 804 | perror(argv[Index]); |
742 | return EXIT_FAILURE; | | 805 | return EXIT_FAILURE; |
743 | } | | 806 | } |
744 | | | 807 | |
745 | switch (rpmReadPackageHeader(FD, &Hdr, &IsSource, NULL, | | 808 | if (!IsRPMFile(FD)) { |
746 | NULL)) { | | | |
747 | case 0: | | | |
748 | break; | | | |
749 | case 1: | | | |
750 | (void)fprintf(stderr, | | 809 | (void)fprintf(stderr, |
751 | "%s: file is not an RPM package.\n", argv[Index]); | | 810 | "%s: file is not an RPM package.\n", argv[Index]); |
752 | return EXIT_FAILURE; | | 811 | return EXIT_FAILURE; |
753 | default: | | | |
754 | (void)fprintf(stderr, "%s: error reading header.\n", | | | |
755 | argv[Index]); | | | |
756 | return EXIT_FAILURE; | | | |
757 | } | | 812 | } |
758 | | | 813 | |
759 | if ((In = Open(FD)) == NULL) { | | 814 | if ((In = Open(FD)) == NULL) { |
760 | (void)fprintf(stderr, | | 815 | (void)fprintf(stderr, |
761 | "%s: cannot read cpio data.\n", argv[Index]); | | 816 | "%s: cannot read cpio data.\n", argv[Index]); |
762 | return EXIT_FAILURE; | | 817 | return EXIT_FAILURE; |
763 | } | | 818 | } |
764 | | | 819 | |
765 | Last = NULL; | | 820 | Last = NULL; |
766 | for (;;) { | | 821 | for (;;) { |
767 | unsigned long Fields[CPIO_NUM_HEADERS]; | | 822 | unsigned long Fields[CPIO_NUM_HEADERS]; |
768 | char *Name; | | 823 | char *Name; |
769 | mode_t Mode; | | 824 | mode_t Mode; |
| @@ -815,59 +870,59 @@ main(int argc, char **argv) | | | @@ -815,59 +870,59 @@ main(int argc, char **argv) |
815 | Length = Fields[CPIO_HDR_FILESIZE]; | | 870 | Length = Fields[CPIO_HDR_FILESIZE]; |
816 | switch (Fields[CPIO_HDR_MODE] & CP_IFMT) { | | 871 | switch (Fields[CPIO_HDR_MODE] & CP_IFMT) { |
817 | case C_ISDIR: { | | 872 | case C_ISDIR: { |
818 | PListEntry *Dir; | | 873 | PListEntry *Dir; |
819 | int OldDir; | | 874 | int OldDir; |
820 | | | 875 | |
821 | if (Length != 0) { | | 876 | if (Length != 0) { |
822 | (void)fprintf(stderr, | | 877 | (void)fprintf(stderr, |
823 | "%s: error in cpio file.\n", | | 878 | "%s: error in cpio file.\n", |
824 | argv[Index]); | | 879 | argv[Index]); |
825 | return EXIT_FAILURE; | | 880 | return EXIT_FAILURE; |
826 | } | | 881 | } |
827 | | | 882 | |
828 | if (!MakeTargetDir(Name, &Dirs, TRUE)) { | | 883 | if (!MakeTargetDir(Name, &Dirs, true)) { |
829 | (void)fprintf(stderr, | | 884 | (void)fprintf(stderr, |
830 | "%s: can't create parent " | | 885 | "%s: can't create parent " |
831 | "directories for \"%s\".\n", | | 886 | "directories for \"%s\".\n", |
832 | argv[Index], Name); | | 887 | argv[Index], Name); |
833 | return EXIT_FAILURE; | | 888 | return EXIT_FAILURE; |
834 | } | | 889 | } |
835 | | | 890 | |
836 | if (!MakeDir(Name, Mode, &OldDir)) { | | 891 | if (!MakeDir(Name, Mode, &OldDir)) { |
837 | (void)fprintf(stderr, | | 892 | (void)fprintf(stderr, |
838 | "%s: can't create directory " | | 893 | "%s: can't create directory " |
839 | "\"%s\".\n", argv[Index], Name); | | 894 | "\"%s\".\n", argv[Index], Name); |
840 | return EXIT_FAILURE; | | 895 | return EXIT_FAILURE; |
841 | } | | 896 | } |
842 | | | 897 | |
843 | if (!OldDir) { | | 898 | if (!OldDir) { |
844 | Dir = InsertPListEntry(&Dirs, Name); | | 899 | Dir = InsertPListEntry(&Dirs, Name); |
845 | Dir->pe_DirEmpty = TRUE; | | 900 | Dir->pe_DirEmpty = true; |
846 | Dir->pe_DirMode = Mode; | | 901 | Dir->pe_DirMode = Mode; |
847 | } | | 902 | } |
848 | break; | | 903 | break; |
849 | } | | 904 | } |
850 | case C_ISLNK: { | | 905 | case C_ISLNK: { |
851 | char *Link; | | 906 | char *Link; |
852 | | | 907 | |
853 | if ((Link = GetData(In, Length)) == NULL) { | | 908 | if ((Link = GetData(In, Length)) == NULL) { |
854 | (void)fprintf(stderr, | | 909 | (void)fprintf(stderr, |
855 | "%s: error in cpio file.\n", | | 910 | "%s: error in cpio file.\n", |
856 | argv[Index]); | | 911 | argv[Index]); |
857 | return EXIT_FAILURE; | | 912 | return EXIT_FAILURE; |
858 | } | | 913 | } |
859 | | | 914 | |
860 | if (!MakeTargetDir(Name, &Dirs, TRUE)) { | | 915 | if (!MakeTargetDir(Name, &Dirs, true)) { |
861 | (void)fprintf(stderr, | | 916 | (void)fprintf(stderr, |
862 | "%s: can't create parent " | | 917 | "%s: can't create parent " |
863 | "directories for \"%s\".\n", | | 918 | "directories for \"%s\".\n", |
864 | argv[Index], Name); | | 919 | argv[Index], Name); |
865 | return EXIT_FAILURE; | | 920 | return EXIT_FAILURE; |
866 | } | | 921 | } |
867 | | | 922 | |
868 | if (*Link == '/') { | | 923 | if (*Link == '/') { |
869 | char *Ptr; | | 924 | char *Ptr; |
870 | | | 925 | |
871 | (void)memmove(Link, Link + 1, | | 926 | (void)memmove(Link, Link + 1, |
872 | strlen(Link + 1) + 1); | | 927 | strlen(Link + 1) + 1); |
873 | Ptr = Name; | | 928 | Ptr = Name; |
| @@ -886,27 +941,27 @@ main(int argc, char **argv) | | | @@ -886,27 +941,27 @@ main(int argc, char **argv) |
886 | } | | 941 | } |
887 | | | 942 | |
888 | if (!MakeSymLink(Link, Name)) { | | 943 | if (!MakeSymLink(Link, Name)) { |
889 | (void)fprintf(stderr, | | 944 | (void)fprintf(stderr, |
890 | "%s: can't create symbolic link " | | 945 | "%s: can't create symbolic link " |
891 | "\"%s\".\n", argv[Index], Name); | | 946 | "\"%s\".\n", argv[Index], Name); |
892 | return EXIT_FAILURE; | | 947 | return EXIT_FAILURE; |
893 | } | | 948 | } |
894 | | | 949 | |
895 | InsertPListEntry(&Links, Name)->pe_Link = Link; | | 950 | InsertPListEntry(&Links, Name)->pe_Link = Link; |
896 | break; | | 951 | break; |
897 | } | | 952 | } |
898 | case C_ISREG: | | 953 | case C_ISREG: |
899 | if (!MakeTargetDir(Name, &Dirs, TRUE)) { | | 954 | if (!MakeTargetDir(Name, &Dirs, true)) { |
900 | (void)fprintf(stderr, | | 955 | (void)fprintf(stderr, |
901 | "%s: can't create parent " | | 956 | "%s: can't create parent " |
902 | "directories for \"%s\".\n", | | 957 | "directories for \"%s\".\n", |
903 | argv[Index], Name); | | 958 | argv[Index], Name); |
904 | return EXIT_FAILURE; | | 959 | return EXIT_FAILURE; |
905 | } | | 960 | } |
906 | | | 961 | |
907 | | | 962 | |
908 | if ((Last != NULL) && (Last->pe_INode != | | 963 | if ((Last != NULL) && (Last->pe_INode != |
909 | Fields[CPIO_HDR_INODE])) { | | 964 | Fields[CPIO_HDR_INODE])) { |
910 | Last = NULL; | | 965 | Last = NULL; |
911 | } | | 966 | } |
912 | | | 967 | |