Sun Jun 13 13:08:52 2010 UTC ()
Update "rpm2pkg" to version 3.0. Changes since version 2.3:
- Don't use the original "rpm" libraries. All we need to do is to identify
  a file as an RPM file and afterwards find the BZip2 or GZip compressed
  section at the end of the file.
- Use C99's "stdbool.h" instead of home-grown defines.


(tron)
diff -r1.43 -r1.44 pkgsrc/pkgtools/rpm2pkg/Makefile
diff -r1.8 -r1.9 pkgsrc/pkgtools/rpm2pkg/files/rpm2pkg.c

cvs diff -r1.43 -r1.44 pkgsrc/pkgtools/rpm2pkg/Makefile (expand / switch to unified diff)

--- pkgsrc/pkgtools/rpm2pkg/Makefile 2009/06/14 22:44:34 1.43
+++ pkgsrc/pkgtools/rpm2pkg/Makefile 2010/06/13 13:08:51 1.44
@@ -1,45 +1,49 @@ @@ -1,45 +1,49 @@
1# $NetBSD: Makefile,v 1.43 2009/06/14 22:44:34 joerg Exp $ 1# $NetBSD: Makefile,v 1.44 2010/06/13 13:08:51 tron Exp $
2 2
3DISTNAME= rpm2pkg-2.3 3DISTNAME= rpm2pkg-3.0
4CATEGORIES= pkgtools 4CATEGORIES= pkgtools
5MASTER_SITES= # empty 5MASTER_SITES= # empty
6DISTFILES= # empty 6DISTFILES= # empty
7 7
8OWNER= tron@NetBSD.org 8OWNER= tron@NetBSD.org
9HOMEPAGE= http://www.NetBSD.org/docs/pkgsrc/ 9HOMEPAGE= http://www.NetBSD.org/docs/pkgsrc/
10COMMENT= Convert RPM archives to NetBSD packages 10COMMENT= Convert RPM archives to NetBSD packages
11LICENSE= modified-bsd 11LICENSE= modified-bsd
12 12
13CONFLICTS+= suse-base<=6.4 13CONFLICTS+= suse-base<=6.4
14 14
15PKG_DESTDIR_SUPPORT= user-destdir 15PKG_DESTDIR_SUPPORT= user-destdir
16 16
 17USE_LANGUAGES= c99
17WRKSRC= ${WRKDIR} 18WRKSRC= ${WRKDIR}
18 19
19CPPFLAGS+= ${BUILDLINK_CPPFLAGS.bzip2} ${BUILDLINK_CPPFLAGS.rpm} \ 20CPPFLAGS+= ${BUILDLINK_CPPFLAGS.bzip2} ${BUILDLINK_CPPFLAGS.rpm} \
20 ${BUILDLINK_CPPFLAGS.zlib} 21 ${BUILDLINK_CPPFLAGS.zlib}
21LIBS+= -lrpm -lintl -lz -lbz2 22LIBS+= -lintl -lz -lbz2
22 23
23.include "../../mk/compiler.mk" 24.include "../../mk/compiler.mk"
24 25
25.if !empty(CC_VERSION:Mgcc-*) 26.if !empty(CC_VERSION:Mgcc-*)
26CFLAGS+= -Wall -Wshadow -Wsign-compare -Wunused-value 27CFLAGS+= -Wall -Wshadow -Wsign-compare -Wunused-value
27.endif 28.endif
28 29
 30.if ${OPSYS} == "NetBSD" && defined(USE_SSP) && (${USE_SSP} != "no")
 31CFLAGS+= -fstack-protector -Wstack-protector --param ssp-buffer-size=1
 32.endif
 33
29INSTALLATION_DIRS= ${PKGMANDIR}/man8 sbin 34INSTALLATION_DIRS= ${PKGMANDIR}/man8 sbin
30 35
31do-build: 36do-build:
32 cd ${WRKSRC}; ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} -o rpm2pkg \ 37 cd ${WRKSRC}; ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} -o rpm2pkg \
33 ${FILESDIR}/rpm2pkg.c ${LIBS} 38 ${FILESDIR}/rpm2pkg.c ${LIBS}
34 39
35do-install: 40do-install:
36 ${INSTALL_PROGRAM} ${WRKSRC}/rpm2pkg ${DESTDIR}${PREFIX}/sbin 41 ${INSTALL_PROGRAM} ${WRKSRC}/rpm2pkg ${DESTDIR}${PREFIX}/sbin
37 ${INSTALL_MAN} ${FILESDIR}/rpm2pkg.8 ${DESTDIR}${PREFIX}/${PKGMANDIR}/man8 42 ${INSTALL_MAN} ${FILESDIR}/rpm2pkg.8 ${DESTDIR}${PREFIX}/${PKGMANDIR}/man8
38 43
39.include "../../archivers/bzip2/buildlink3.mk" 44.include "../../archivers/bzip2/buildlink3.mk"
40.include "../../devel/gettext-lib/buildlink3.mk" 45.include "../../devel/gettext-lib/buildlink3.mk"
41.include "../../devel/zlib/buildlink3.mk" 46.include "../../devel/zlib/buildlink3.mk"
42.include "../../misc/rpm/buildlink3.mk" 
43.include "../../mk/bdb.buildlink3.mk" 47.include "../../mk/bdb.buildlink3.mk"
44 48
45.include "../../mk/bsd.pkg.mk" 49.include "../../mk/bsd.pkg.mk"

cvs diff -r1.8 -r1.9 pkgsrc/pkgtools/rpm2pkg/files/rpm2pkg.c (expand / switch to unified diff)

--- pkgsrc/pkgtools/rpm2pkg/files/rpm2pkg.c 2009/06/14 22:44:34 1.8
+++ pkgsrc/pkgtools/rpm2pkg/files/rpm2pkg.c 2010/06/13 13:08:52 1.9
@@ -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 */
 50static 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. */
 55static const unsigned char BZipMagic[] = { 'B', 'Z', 'h' };
 56static 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
63char CPIOMagic[] = {'0','7','0','7','0','1'}; 76static 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 
79typedef struct ModeMapStruct { 89typedef 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
84ModeMap ModeMapTab[] = { 94ModeMap 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
120typedef struct FileHandleStruct { 130typedef 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
127static int 137static bool
128InitBuffer(void **Buffer, size_t *BufferSizePtr) 138InitBuffer(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
144static void 154static void
145Close(FileHandle *fh) 155Close(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
 168static bool
 169IsRPMFile(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
158static FileHandle * 179static FileHandle *
159Open(int fd) 180Open(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
204static int 268static int
205Read(FileHandle *fh, void *buffer, int length) 269Read(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
218static int 282static bool
219SkipAndAlign(FileHandle *fh, off_t Skip) 283SkipAndAlign(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
256static PListEntry * 320static PListEntry *
257InsertPListEntry(PListEntry **Tree,char *Name) 321InsertPListEntry(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
416static int 480static bool
417GetCPIOHeader(FileHandle *In, unsigned long *Fields, char **Name) 481GetCPIOHeader(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
460static mode_t 524static mode_t
461ConvertMode(unsigned long CPIOMode) 525ConvertMode(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
477static int 541static bool
478MakeTargetDir(char *Name, PListEntry **Dirs, int MarkNonEmpty) 542MakeTargetDir(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
513static int 577static bool
514MakeDir(char *Name, mode_t Mode, int *OldDir) 578MakeDir(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
531static int 595static bool
532MakeSymLink(char *Link, char *Name) 596MakeSymLink(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
546static int 610static bool
547WriteFile(FileHandle *In, char *Name, mode_t Mode, unsigned long Length, 611WriteFile(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
590static void 654static void
591CheckSymLinks(PListEntry **Links, PListEntry **Files, PListEntry **Dirs) 655CheckSymLinks(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
637static int 701static bool
638CheckPrefix(char *Prefix, char *Name) 702CheckPrefix(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
647static char * 711static char *
648StripPrefix(char *Name, int Count) 712StripPrefix(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
667int 731int
668main(int argc, char **argv) 732main(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