Import of pkgsrc-2013Q2

This commit is contained in:
2013-09-26 17:14:40 +02:00
commit 785076ae39
74991 changed files with 4380255 additions and 0 deletions

3
pkgtools/rpm2pkg/DESCR Normal file
View File

@@ -0,0 +1,3 @@
"rpm2pkg" can be used to convert RedHat Package Manager archives used by
many Linux distribution like e.g. Red Hat or SuSE into NetBSD packages.
It will extract the RPM files and create a NetBSD package list on the fly.

48
pkgtools/rpm2pkg/Makefile Normal file
View File

@@ -0,0 +1,48 @@
# $NetBSD: Makefile,v 1.63 2013/02/21 22:39:58 wiz Exp $
DISTNAME= rpm2pkg-3.2.3
CATEGORIES= pkgtools
MASTER_SITES= # empty
DISTFILES= # empty
NO_CHECKSUM= yes
OWNER= tron@NetBSD.org
HOMEPAGE= http://www.pkgsrc.org/
COMMENT= Convert RPM archives to NetBSD packages
LICENSE= modified-bsd
CONFLICTS+= suse-base<=6.4
MANCOMPRESSED_IF_MANZ= yes
USE_BSD_MAKEFILE= yes
USE_LANGUAGES= c99
MAKE_ENV+= FILESDIR=${FILESDIR:Q}
MAKE_FILE= ${FILESDIR}/Makefile
WRKSRC= ${WRKDIR}
INSTALLATION_DIRS= ${PKGMANDIR}/man8 sbin
.include "../../mk/compiler.mk"
.if !empty(CC_VERSION:Mclang*)
MAKE_FLAGS+= ACTIVE_CC=clang
.endif
.include "../../mk/bsd.prefs.mk"
.if defined(PKG_DEVELOPER) && ${PKG_DEVELOPER} != "no"
MAKE_ENV+= WARNS=4
.else
MAKE_ENV+= NOGCCERROR=yes
.endif
do-install:
${INSTALL_PROGRAM} ${WRKSRC}/rpm2pkg ${DESTDIR}${PREFIX}/sbin
${INSTALL_MAN} ${FILESDIR}/rpm2pkg.8 \
${DESTDIR}${PREFIX}/${PKGMANDIR}/man8
.include "../../archivers/bzip2/buildlink3.mk"
.include "../../archivers/xz/buildlink3.mk"
.include "../../devel/zlib/buildlink3.mk"
.include "../../mk/bsd.pkg.mk"

3
pkgtools/rpm2pkg/PLIST Normal file
View File

@@ -0,0 +1,3 @@
@comment $NetBSD: PLIST,v 1.3 2011/01/19 16:23:02 tron Exp $
sbin/rpm2pkg
man/man8/rpm2pkg.8

View File

@@ -0,0 +1,17 @@
# $NetBSD: Makefile,v 1.4 2011/04/12 22:36:11 tron Exp $
PROG= rpm2pkg
SRCS= fileio.c package-list.c parse-rpm.c rpm2pkg.c
SRCS+= fileio-bzlib.c fileio-lzma.c fileio-plain.c fileio-zlib.c
MAN=
BINDIR= ${PREFIX}/sbin
LDADD= -lbz2 -llzma -lz
#WARNS= 4
#CFLAGS+= -g
#LDFLAGS+= -g
.PATH: ${FILESDIR}
.include <bsd.prog.mk>

View File

@@ -0,0 +1,101 @@
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matthias Scheler.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#define FILEIO_INTERNAL /**/
#include "fileio.h"
#include <bzlib.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct {
FILE *id_File;
int id_bzerror;
BZFILE *id_BZFile;
} InstData;
static void
BZLibCloseFunc(FileHandle *fh)
{
InstData *id;
id = fh->fh_InstData;
if (id->id_BZFile != NULL)
(void)BZ2_bzReadClose(&id->id_bzerror, id->id_BZFile);
if (id->id_File != NULL)
(void)fclose(id->id_File);
}
static ssize_t
BZLibReadFunc(FileHandle *fh, void *buffer, size_t bytes)
{
InstData *id;
int rbytes;
id = fh->fh_InstData;
rbytes = BZ2_bzRead(&id->id_bzerror, id->id_BZFile, buffer, bytes);
switch (id->id_bzerror) {
case BZ_OK:
case BZ_STREAM_END:
return rbytes;
default:
return -1;
}
}
FileHandle *
FileHandleBZLib(int *fd_p)
{
FileHandle *fh;
InstData *id;
fh = FileHandleCreate(BZLibCloseFunc, BZLibReadFunc, sizeof(*id));
if (fh == NULL)
return NULL;
id = fh->fh_InstData;
if ((id->id_File = fdopen(*fd_p, "rb")) == NULL) {
FileHandleClose(fh);
return NULL;
}
*fd_p = -1;
if ((id->id_BZFile = BZ2_bzReadOpen(&id->id_bzerror, id->id_File, 0, 0,
NULL, 0)) == NULL) {
FileHandleClose(fh);
return NULL;
}
return fh;
}

View File

@@ -0,0 +1,134 @@
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matthias Scheler.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#define FILEIO_INTERNAL /**/
#include "fileio.h"
#include <inttypes.h>
#include <lzma.h>
typedef struct {
lzma_stream id_Stream;
int id_FD;
size_t id_Chunk;
uint8_t id_Buffer[1 << 16];
} InstData;
static void
LZMACloseFunc(FileHandle *fh)
{
InstData *id;
id = fh->fh_InstData;
if (id != NULL) {
lzma_end(&id->id_Stream);
if (id->id_FD >= 0)
(void)close(id->id_FD);
fh->fh_InstData = NULL;
}
}
static ssize_t
LZMAReadFunc(FileHandle *fh, void *buffer, size_t bytes)
{
InstData *id;
lzma_stream *stream;
ssize_t rbytes;
lzma_ret ret;
id = fh->fh_InstData;
if (id == NULL)
return 0;
stream = &id->id_Stream;
if (stream->avail_in == 0 && id->id_FD >= 0) {
rbytes = read(id->id_FD, id->id_Buffer, id->id_Chunk);
if (rbytes < 0) {
LZMACloseFunc(fh);
return rbytes;
}
if (rbytes > 0) {
stream->next_in = id->id_Buffer;
stream->avail_in = rbytes;
id->id_Chunk = sizeof(id->id_Buffer);
} else {
(void)close(id->id_FD);
id->id_FD = -1;
}
}
stream->next_out = buffer;
stream->avail_out = bytes;
ret = lzma_code(stream,
(stream->avail_in > 0) ? LZMA_RUN : LZMA_FINISH);
rbytes = (ret == LZMA_OK || ret == LZMA_STREAM_END) ?
(ssize_t)(bytes - stream->avail_out) : -1;
if (ret != LZMA_OK)
LZMACloseFunc(fh);
return rbytes;
}
FileHandle *
FileHandleLZMA(int *fd_p)
{
FileHandle *fh;
InstData *id;
off_t offset;
fh = FileHandleCreate(LZMACloseFunc, LZMAReadFunc, sizeof(*id));
if (fh == NULL)
return NULL;
id = fh->fh_InstData;
if (lzma_auto_decoder(&id->id_Stream, 1U << 30,
LZMA_CONCATENATED) != LZMA_OK) {
fh->fh_InstData = NULL;
FileHandleClose(fh);
return NULL;
}
id->id_FD = *fd_p;
*fd_p = -1;
id->id_Chunk = sizeof(id->id_Buffer);
offset = lseek(id->id_FD, 0, SEEK_CUR);
if (offset != -1) {
id->id_Chunk = sizeof(id->id_Buffer) -
(size_t)offset % sizeof(id->id_Buffer);
}
return fh;
}

View File

@@ -0,0 +1,67 @@
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matthias Scheler.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#define FILEIO_INTERNAL /**/
#include "fileio.h"
#include <stdlib.h>
static void
PlainCloseFunc(FileHandle *fh)
{
int *fd_p = fh->fh_InstData;
if (*fd_p >= 0)
(void)close(*fd_p);
}
static ssize_t
PlainReadFunc(FileHandle *fh, void *buffer, size_t bytes)
{
int *fd_p = fh->fh_InstData;
return read(*fd_p, buffer, bytes);
}
FileHandle *
FileHandlePlain(int *fd_p)
{
FileHandle *fh;
fh = FileHandleCreate(PlainCloseFunc, PlainReadFunc, sizeof(int));
if (fh != NULL) {
int *new_fd_p = fh->fh_InstData;
*new_fd_p = *fd_p;
*fd_p = -1;
}
return fh;
}

View File

@@ -0,0 +1,68 @@
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matthias Scheler.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#define FILEIO_INTERNAL /**/
#include "fileio.h"
#include <zlib.h>
static void
ZLibCloseFunc(FileHandle *fh)
{
gzFile mygzfile = fh->fh_InstData;
if (mygzfile != NULL)
(void)gzclose(mygzfile);
}
static ssize_t
ZLibReadFunc(FileHandle *fh, void *buffer, size_t bytes)
{
gzFile mygzfile = fh->fh_InstData;
return gzread(mygzfile, buffer, bytes);
}
FileHandle *
FileHandleZLib(int *fd_p)
{
FileHandle *fh;
fh = FileHandleCreate(ZLibCloseFunc, ZLibReadFunc, 0);
if (fh != NULL) {
fh->fh_InstData = gzdopen(*fd_p, "r");
if (fh->fh_InstData != NULL) {
*fd_p = -1;
} else {
FileHandleClose(fh);
fh = NULL;
}
}
return fh;
}

View File

@@ -0,0 +1,87 @@
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matthias Scheler.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#define FILEIO_INTERNAL /**/
#include "fileio.h"
#include <stdlib.h>
FileHandle *
FileHandleCreate(FileHandleCloseFunc close_func, FileHandleReadFunc read_func,
size_t inst_size)
{
FileHandle *fh;
if ((fh = calloc(1, sizeof(*fh) + inst_size)) == NULL)
return NULL;
fh->fh_CloseFunc = close_func;
fh->fh_ReadFunc = read_func;
if (inst_size > 0)
fh->fh_InstData = &fh[1];
return fh;
}
void
FileHandleClose(FileHandle *fh)
{
fh->fh_CloseFunc(fh);
free(fh);
}
bool
FileHandleRead(FileHandle *fh, void *buffer, size_t bytes)
{
char *ptr;
ptr = buffer;
while (bytes > 0) {
ssize_t rbytes;
rbytes = fh->fh_ReadFunc(fh, ptr, bytes);
if (rbytes <= 0)
break;
ptr += rbytes;
bytes -= rbytes;
fh->fh_Pos += rbytes;
}
return (bytes == 0);
}
off_t
FileHandleGetPos(const FileHandle *fh)
{
return fh->fh_Pos;
}

View File

@@ -0,0 +1,66 @@
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matthias Scheler.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FILEIO_H
#define FILEIO_H
#include <stdbool.h>
#include <unistd.h>
typedef struct FileHandleStruct FileHandle;
extern void FileHandleClose(FileHandle *);
extern bool FileHandleRead(FileHandle *, void *, size_t);
extern off_t FileHandleGetPos(const FileHandle *fh);
extern FileHandle *FileHandleBZLib(int *);
extern FileHandle *FileHandleLZMA(int *);
extern FileHandle *FileHandlePlain(int *);
extern FileHandle *FileHandleZLib(int *);
#ifdef FILEIO_INTERNAL
typedef void (*FileHandleCloseFunc)(struct FileHandleStruct *);
typedef ssize_t (*FileHandleReadFunc)(struct FileHandleStruct *, void *,size_t);
struct FileHandleStruct {
FileHandleCloseFunc fh_CloseFunc;
FileHandleReadFunc fh_ReadFunc;
void *fh_InstData;
off_t fh_Pos;
};
extern FileHandle *FileHandleCreate(FileHandleCloseFunc, FileHandleReadFunc,
size_t);
#endif /* FILEIO_INTERNAL */
#endif /* !FILEIO_H */

View File

@@ -0,0 +1,99 @@
/* $NetBSD: package-list.c,v 1.2 2011/01/12 08:47:52 tron Exp $ */
/*-
* Copyright (c) 2001-2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matthias Scheler.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "package-list.h"
#include <stdlib.h>
#include <string.h>
PListEntry *
PListInsert(PListEntry **Tree,char *Name)
{
PListEntry *Node;
while ((Node = *Tree) != NULL) {
Tree = (strcmp(Name, Node->pe_Name) <0) ?
&Node->pe_Left : &Node->pe_Right;
}
if ((Node = calloc(1, sizeof (PListEntry) + strlen(Name))) == NULL) {
perror("calloc");
exit(EXIT_FAILURE);
}
(void)strcpy(Node->pe_Name, Name);
return *Tree = Node;
}
PListEntry *
PListFind(PListEntry *Tree, char *Name)
{
while (Tree != NULL) {
int Result;
if ((Result = strcmp(Name, Tree->pe_Name)) == 0) break;
Tree = (Result < 0) ? Tree->pe_Left : Tree->pe_Right;
}
return Tree;
}
static void
PListWalk(PListEntry *Tree, PListEntryFunc Func, FILE *Out)
{
while (Tree != NULL) {
if (Tree->pe_Childs[0] != NULL)
PListWalk(Tree->pe_Childs[0], Func, Out);
Func(Tree, Out);
Tree = Tree->pe_Childs[1];
}
}
static void
PListEntryFile(PListEntry *node, FILE *out)
{
(void)fprintf(out, "%s\n", node->pe_Name);
}
static void
PListEntryMakeDir(PListEntry *node, FILE *out)
{
if (node->pe_DirEmpty)
(void)fprintf(out, "@pkgdir %s\n", node->pe_Name);
}
void
PListWrite(PListEntry *files, PListEntry *dirs, FILE *out)
{
PListWalk(files, PListEntryFile, out);
PListWalk(dirs, PListEntryMakeDir, out);
}

View File

@@ -0,0 +1,55 @@
/* $NetBSD: package-list.h,v 1.1 2011/01/12 00:26:33 tron Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matthias Scheler.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PACKAGE_LIST_H
#define PACKAGE_LIST_H
#include <stdio.h>
typedef struct PListEntryStruct PListEntry;
struct PListEntryStruct {
PListEntry *pe_Childs[2];
int pe_DirEmpty;
unsigned long pe_INode;
char *pe_Link;
char pe_Name[1];
};
#define pe_Left pe_Childs[0]
#define pe_Right pe_Childs[1]
typedef void PListEntryFunc(PListEntry *, FILE *);
extern PListEntry *PListInsert(PListEntry **, char *);
extern PListEntry *PListFind(PListEntry *, char *);
extern void PListWrite(PListEntry *, PListEntry *, FILE *);
#endif /* !PACKAGE_LIST_H */

View File

@@ -0,0 +1,165 @@
/* $NetBSD: parse-rpm.c,v 1.1 2011/01/12 00:26:33 tron Exp $ */
/*-
* Copyright (c) 2001-2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matthias Scheler.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "parse-rpm.h"
#include <sys/types.h>
#include <arpa/inet.h>
#include <inttypes.h>
#include <string.h>
/*
* The following definitions are based on the documentation of the
* RPM format which can be found here:
*
* http://www.rpm.org/max-rpm/s1-rpm-file-format-rpm-file-format.html
*/
/* Lead of an RPM archive. */
typedef struct RPMLead_s {
uint8_t magic[4];
uint8_t major, minor;
int16_t type;
int16_t archnum;
int8_t name[66];
int16_t osnum;
uint16_t signature_type;
int8_t reserved[16];
} RPMLead;
static const uint8_t RPMLeadMagic[] = { 0xed, 0xab, 0xee, 0xdb };
/* Header section of an RPM archive. */
typedef struct RPMHeader_s {
uint8_t magic[3];
uint8_t version;
uint8_t reserved[4];
uint32_t indexSize;
uint32_t dataSize;
} RPMHeader;
static const uint8_t RPMHeaderMagic[] = { 0x8e, 0xad, 0xe8 };
/* Magic bytes for "bzip2" and "gzip" compressed files. */
static const unsigned char BZipMagic[] = { 'B', 'Z', 'h' };
static const unsigned char GZipMagic[] = { 0x1f, 0x8b, 0x08 };
/* Magic bytes for a cpio(1) archive. */
static const unsigned char CPIOMagic[] = {'0','7','0','7','0','1'};
/* Check whether we got an RPM file and find the data section. */
bool
IsRPMFile(int fd)
{
RPMLead rpmLead;
bool padding;
RPMHeader rpmHeader;
/* Check for RPM lead. */
if (read(fd, &rpmLead, sizeof(RPMLead)) != sizeof(RPMLead))
return false;
if (memcmp(rpmLead.magic, RPMLeadMagic, sizeof(RPMLeadMagic)) != 0)
return false;
/* We don't support very old RPMs. */
if (rpmLead.major < 3)
return false;
/*
* The RPM file format has a horrible requirement for extra padding
* depending on what type of signature is used.
*/
padding = htons(rpmLead.signature_type) == 5;
/* Skip over RPM header(s). */
while (read(fd, &rpmHeader, sizeof(RPMHeader)) == sizeof(RPMHeader)) {
uint32_t indexSize, dataSize;
off_t offset;
/* Did we find another header? */
if (memcmp(rpmHeader.magic, RPMHeaderMagic,
sizeof(RPMHeaderMagic)) != 0) {
/* Nope, seek backwards and return. */
return (lseek(fd, -(off_t)sizeof(RPMHeader),
SEEK_CUR) != -1);
}
/* Find out how large the header is ... */
indexSize = htonl(rpmHeader.indexSize);
dataSize = htonl(rpmHeader.dataSize);
/* .. and skip over it. */
offset = indexSize * 4 * sizeof(uint32_t) + dataSize;
if (padding) {
offset = ((offset + 7) / 8) * 8;
padding = false;
}
if (lseek(fd, offset, SEEK_CUR) == -1)
return false;
}
return false;
}
FileHandle *
OpenRPM(int *fd_p)
{
unsigned char buffer[8];
FileHandle *fh;
/*
* Read enough bytes to identify the compression and seek back to
* the beginning of the data section.
*/
if (read(*fd_p, buffer, sizeof(buffer)) != sizeof(buffer) ||
lseek(*fd_p, -(off_t)sizeof(buffer), SEEK_CUR) == -1) {
return NULL;
}
/* Determine the compression method. */
if (memcmp(buffer, CPIOMagic, sizeof(CPIOMagic)) == 0) {
/* uncompressed data */
fh = FileHandlePlain(fd_p);
} else if (memcmp(buffer, BZipMagic, sizeof(BZipMagic)) == 0) {
/* bzip2 archive */
fh = FileHandleBZLib(fd_p);
} else if (memcmp(buffer, GZipMagic, sizeof(GZipMagic)) == 0) {
/* gzip archive */
fh = FileHandleZLib(fd_p);
} else {
/* lzma ... hopefully */
fh = FileHandleLZMA(fd_p);
}
return fh;
}

View File

@@ -0,0 +1,38 @@
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matthias Scheler.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PARSE_RPM_H
#define PARSE_RPM_H
#include "fileio.h"
extern bool IsRPMFile(int);
extern FileHandle *OpenRPM(int *);
#endif /* !PARSE_RPM_H */

View File

@@ -0,0 +1,151 @@
.\"
.\" Copyright (c) 2001, 2011 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
.\" by Emmanuel Dreyfus.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd January 12, 2011
.Dt RPM2PKG 8
.Os
.Sh NAME
.Nm rpm2pkg
.Nd RPM to BSD package conversion helper
.Sh SYNOPSIS
.Nm
.Op Fl d Ar directory
.Op Fl f Ar package_list
.Op Fl i Ar ignored_dir
.Op Fl p Ar prefix
.Op Fl s Ar strip_path_count
.Ar rpm_file ...
.Sh DESCRIPTION
.Nm
helps in building BSD packages from RPM files by unpacking each specified
.Ar rpm_file ,
and by building a
.Ar package_list
according to what was extracted.
The
.Ar package_list
has the format expected by the
.Nx
package system.
.Pp
.Nm
also provides a mechanism that helps in selecting what is actually
extracted from the RPM files.
It is therefore possible to reject files that are of no interest
when building a BSD package.
This is especially useful for files that are to be extracted in
.Pa /var
or
.Pa /etc .
.Pp
The following options are available:
.Bl -tag -width indent
.It Fl d Ar directory
Change working directory to
.Ar directory .
.It Fl f Ar package_list
Produce a
.Nx
package list
.Ar package_list
from what was actually extracted from the RPM files archives.
.It Fl i Ar ignored_dir
Do not extract files contained in the
.Ar ignored_dir
directory of the RPM file's archives.
.It Fl p Ar prefix
Use
.Ar prefix
when extracting files.
.It Fl s Ar strip_path_count
Strip
.Ar strip_path_count
leading directories in file names.
.El
.Sh EXAMPLES
.Nm
.Fl d Ar /usr/pkg
.Fl f Ar /usr/pkgsrc/emulator/more_linux_lib/work/PLIST_DYNAMIC
.Fl p Ar emul/linux
.Fl i Ar tmp
.Fl i Ar var
.Fl i Ar usr/tmp
.Ar /usr/pkgsrc/distfiles/more_linux_lib/foo.rpm
.Ar /usr/pkgsrc/distfiles/more_linux_lib/bar.rpm
.Pp
This will extract
.Pa foo.rpm
and
.Pa bar.rpm
into
.Pa /usr/pkg/emul/linux .
A packing list called
.Pa PLIST_DYNAMIC
will be created, with pathnames relative to
.Pa /usr/pkg ,
because this is the directory into which we asked
.Nm
to change with the
.Fl d
option.
.Pp
.Nm
will not extract files contained in the
.Pa tmp ,
.Pa var ,
or
.Pa usr/tmp
directories of the RPM file's archives.
.Pp
.Nm
.Fl s Ar 1
.Fl d Ar /usr/pkg
.Ar /usr/pkgsrc/distfiles/pack/bar.rpm
.Pp
This will extract the
.Ar bar.rpm
file in
.Pa /usr/pkg
while striping the leading directory of files path in
.Ar bar.rpm .
This is useful for dealing with RPM archives that contains files like
.Pa usr/bin/foo ,
which you would like to go in
.Pa /usr/pkg/bin .
.Sh COMPATIBILITY
.Nm
should work with any regular RPM file.
.Sh SEE ALSO
.Xr cpio 1 ,
.Xr rpm 8 ,
.Xr rpm2cpio 8
.Sh AUTHORS
.An Matthias Scheler Aq tron@netbsd.org
.br
This man page was written by
.An Emmanuel Dreyfus Aq manu@netbsd.org

View File

@@ -0,0 +1,658 @@
/* $NetBSD: rpm2pkg.c,v 1.21 2011/04/12 22:12:42 tron Exp $ */
/*-
* Copyright (c) 2001-2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matthias Scheler.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "fileio.h"
#include "package-list.h"
#include "parse-rpm.h"
/* Structure of a cpio(1) archive. */
#define C_IRUSR 0000400
#define C_IWUSR 0000200
#define C_IXUSR 0000100
#define C_IRGRP 0000040
#define C_IWGRP 0000020
#define C_IXGRP 0000010
#define C_IROTH 0000004
#define C_IWOTH 0000002
#define C_IXOTH 0000001
#define C_ISUID 0004000
#define C_ISGID 0002000
#define C_ISVTX 0001000
#define C_ISDIR 0040000
#define C_ISREG 0100000
#define C_ISCHR 0020000
#define C_ISLNK 0120000
static const unsigned char CPIOMagic[] = {'0','7','0','7','0','1'};
#define CPIO_END_MARKER "TRAILER!!!"
#define CPIO_FIELD_LENGTH 8
#define CPIO_HDR_INODE 0
#define CPIO_HDR_MODE 1
#define CPIO_HDR_FILESIZE 6
#define CPIO_HDR_NAMESIZE 11
#define CPIO_NUM_HEADERS 13
#define CP_IFMT 0170000
typedef struct ModeMapStruct {
unsigned long mm_CPIOMode;
mode_t mm_SysMode;
} ModeMap;
ModeMap ModeMapTab[] = {
{C_IRUSR, S_IRUSR},
{C_IWUSR, S_IWUSR},
{C_IXUSR, S_IXUSR},
{C_IRGRP, S_IRGRP},
{C_IWGRP, S_IWGRP},
{C_IXGRP, S_IXGRP},
{C_IROTH, S_IROTH},
{C_IWOTH, S_IWOTH},
{C_IXOTH, S_IXOTH},
{C_ISUID, S_ISUID},
{C_ISGID, S_ISGID},
{C_ISVTX, S_ISVTX},
{0, 0}
};
static bool
SkipAndAlign(FileHandle *fh, off_t skip)
{
off_t old_pos, new_pos;
char buffer[1 << 16];
old_pos = FileHandleGetPos(fh);
new_pos = (old_pos + skip + 3) & ~3;
if (old_pos == new_pos)
return true;
while (old_pos < new_pos) {
off_t length;
size_t chunk;
length = new_pos - old_pos;
chunk = (length > (off_t)sizeof(buffer)) ?
(off_t)sizeof(buffer) : length;
if (!FileHandleRead(fh, buffer, chunk))
return false;
old_pos = FileHandleGetPos(fh);
}
return true;
}
static char *
StrCat(const char *prefix, const char *suffix)
{
size_t prefix_length;
char *str;
prefix_length = strlen(prefix);
if ((str = malloc(prefix_length + strlen(suffix) + 1)) == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
(void)memcpy(str, prefix, prefix_length);
(void)strcpy(&str[prefix_length], suffix);
return str;
}
static char **
ArrayAdd(char **array, char *string)
{
size_t old;
old = 0;
if (array != NULL) {
while (array[old] != NULL)
old++;
}
if ((array = realloc(array, sizeof(char *) * (old + 2))) == NULL) {
perror("realloc");
exit(EXIT_FAILURE);
}
array[old++] = string;
array[old] = NULL;
return array;
}
static void
Usage(char *Progname)
{
(void)fprintf(stderr,
"Usage: %s [-d directory] [-f packlist] [[-i ignorepath] ...]\n"
" [-p prefix] [-s stripcount] rpmfile [...]\n",
Progname);
exit(EXIT_FAILURE);
}
static char *
GetData(FileHandle *In, unsigned long Length)
{
char *Ptr;
if ((Ptr = malloc(Length + 1)) != NULL) {
if (FileHandleRead(In, Ptr, Length) && SkipAndAlign(In, 0)) {
Ptr[Length] = '\0';
return Ptr;
}
free(Ptr);
}
return NULL;
}
static bool
GetCPIOHeader(FileHandle *in, unsigned long *fields, char **name)
{
char buffer[CPIO_NUM_HEADERS][CPIO_FIELD_LENGTH];
char header[CPIO_FIELD_LENGTH + 1];
size_t i, j;
unsigned long namelen;
*name = NULL;
if (!FileHandleRead(in, buffer, sizeof(CPIOMagic)))
return false;
if (memcmp(buffer, CPIOMagic, sizeof(CPIOMagic)) != 0)
return false;
if (!FileHandleRead(in, buffer, sizeof(buffer)))
return false;
header[CPIO_FIELD_LENGTH] = '\0';
for (i = 0; i < CPIO_NUM_HEADERS; i++) {
for (j = 0; j < CPIO_FIELD_LENGTH; j++) {
if (!isxdigit((unsigned char)buffer[i][j]))
return false;
header[j] = buffer[i][j];
}
fields[i] = strtoul(header, NULL, 16);
}
namelen = fields[CPIO_HDR_NAMESIZE];
if ((*name = GetData(in, namelen)) == NULL)
return false;
return ((*name)[namelen - 1] == '\0');
}
static mode_t
ConvertMode(unsigned long cpio_mode)
{
mode_t mode;
ModeMap *ptr;
for (ptr = ModeMapTab, mode = 0; ptr->mm_CPIOMode != 0; ptr++) {
if (cpio_mode & ptr->mm_CPIOMode)
mode |= ptr->mm_SysMode;
}
return mode;
}
static bool
MakeTargetDir(char *Name, PListEntry **Dirs)
{
char *Basename;
PListEntry *Dir;
struct stat Stat;
int Result;
if ((Basename = strrchr(Name, '/')) == NULL)
return true;
*Basename = '\0';
if ((Dir = PListFind(*Dirs, Name)) != NULL) {
*Basename = '/';
Dir->pe_DirEmpty = false;
return true;
}
if (!MakeTargetDir(Name, Dirs)) {
*Basename = '/';
return false;
}
if (stat(Name, &Stat) == 0) {
Result = S_ISDIR(Stat.st_mode);
} else if (errno != ENOENT) {
Result = false;
} else if ((Result = (mkdir(Name, S_IRWXU|S_IRWXG|S_IRWXO) == 0))) {
(void)PListInsert(Dirs, Name);
}
*Basename = '/';
return Result;
}
static bool
MakeDir(char *name, mode_t mode, bool *old_dir)
{
struct stat sb;
*old_dir = false;
if (mkdir(name, mode) == 0)
return true;
if (errno != EEXIST || lstat(name, &sb) < 0 || !S_ISDIR(sb.st_mode))
return false;
*old_dir = true;
return true;
}
static bool
MakeSymLink(char *Link, char *Name)
{
struct stat Stat;
if (symlink(Link, Name) == 0) return true;
if ((errno != EEXIST) || (lstat(Name, &Stat) < 0) ||
!S_ISLNK(Stat.st_mode)) {
return false;
}
return ((unlink(Name) == 0) && (symlink(Link, Name) == 0));
}
static bool
WriteFile(FileHandle *in, char *name, mode_t mode, unsigned long length,
const char *link_target)
{
int outfd;
struct stat sb;
char buffer[1 << 16];
if ((lstat(name, &sb) == 0) &&
(!S_ISREG(sb.st_mode) || (unlink(name) < 0))) {
return false;
}
if (link_target != NULL) {
if (link(link_target, name) < 0)
return false;
outfd = open(name, O_WRONLY, mode);
} else {
outfd = open(name, O_WRONLY|O_CREAT, mode);
}
if (outfd < 0)
return false;
while (length > 0) {
ssize_t chunk;
chunk = (length > sizeof(buffer)) ? sizeof(buffer) : length;
if (!FileHandleRead(in, buffer, chunk) ||
write(outfd, buffer, chunk) != chunk)
break;
length -= chunk;
}
if (close(outfd) == 0 && length == 0)
return SkipAndAlign(in, 0);
(void)unlink(name);
return false;
}
static bool
CheckPrefix(const char *prefix, char *name)
{
size_t length;
length = strlen(prefix);
return ((strncmp(prefix, name, length) == 0) &&
((name[length] == '\0') || (name[length] == '/')));
}
static bool
StripPrefix(char *name, int stripcount)
{
char *new_name;
if (stripcount <= 0)
return true;
new_name = name;
while (stripcount-- > 0) {
new_name = strchr(new_name, '/');
if (new_name == NULL)
return false;
new_name++;
}
(void)memmove(name, new_name, strlen(new_name) + 1);
return true;
}
static void
ProcessRPM(const char *filename, PListEntry **files, PListEntry **dirs,
char **ignore, const char *prefix, int stripcount)
{
int fd;
FileHandle *in;
PListEntry *last;
if ((fd = open(filename, O_RDONLY, 0)) < 0) {
perror(filename);
exit(EXIT_FAILURE);
}
if (!IsRPMFile(fd)) {
(void)fprintf(stderr, "%s: file is not an RPM package.\n",
filename);
exit(EXIT_FAILURE);
}
if ((in = OpenRPM(&fd)) == NULL) {
(void)fprintf(stderr, "%s: cannot get RPM data.\n", filename);
exit(EXIT_FAILURE);
}
if (fd >= 0) {
(void)close(fd);
fd = -1;
}
last = NULL;
for (;;) {
unsigned long fields[CPIO_NUM_HEADERS];
char *name;
mode_t mode;
unsigned long length;
if (!GetCPIOHeader(in, fields, &name)) {
(void)fprintf(stderr,
"%s: error in cpio header.\n",
filename);
exit(EXIT_FAILURE);
}
if (strcmp(name, CPIO_END_MARKER) == 0) {
free(name);
break;
}
if (*name == '\0')
fields[CPIO_HDR_MODE] = 0;
if (ignore != NULL) {
char **ptr;
for (ptr = ignore; *ptr != NULL; ptr++) {
if (CheckPrefix(*ptr, name)) {
fields[CPIO_HDR_MODE] = 0;
break;
}
}
}
if (fields[CPIO_HDR_MODE] != 0 &&
!StripPrefix(name, stripcount)) {
(void)fprintf(stderr,
"%s: Leading path to strip too "
"big (-s %d)\n",
filename, stripcount);
exit(EXIT_FAILURE);
}
if (prefix != NULL) {
char *fullname;
fullname = StrCat(prefix, name);
free(name);
name = fullname;
}
mode = ConvertMode(fields[CPIO_HDR_MODE]);
length = fields[CPIO_HDR_FILESIZE];
switch (fields[CPIO_HDR_MODE] & CP_IFMT) {
case C_ISDIR: {
PListEntry *dir;
bool old_dir;
if (length != 0) {
(void)fprintf(stderr,
"%s: error in cpio file.\n",
filename);
exit(EXIT_FAILURE);
}
if (!MakeTargetDir(name, dirs)) {
(void)fprintf(stderr,
"%s: can't create parent "
"directories for \"%s\".\n",
filename, name);
exit(EXIT_FAILURE);
}
if (!MakeDir(name, mode, &old_dir)) {
(void)fprintf(stderr,
"%s: can't create directory "
"\"%s\".\n", filename, name);
exit(EXIT_FAILURE);
}
if (!old_dir) {
dir = PListInsert(dirs, name);
dir->pe_DirEmpty = true;
}
break;
}
case C_ISLNK: {
char *link_target;
if ((link_target = GetData(in, length)) == NULL) {
(void)fprintf(stderr,
"%s: error in cpio file.\n",
filename);
exit(EXIT_FAILURE);
}
if (!MakeTargetDir(name, dirs)) {
(void)fprintf(stderr,
"%s: can't create parent "
"directories for \"%s\".\n",
filename, name);
exit(EXIT_FAILURE);
}
if (*link_target == '/') {
char *ptr;
(void)memmove(link_target, link_target + 1,
strlen(link_target));
ptr = name;
if (prefix != NULL)
ptr += strlen(prefix);
while ((ptr = strchr(ptr, '/')) != NULL) {
char *new_link_target;
new_link_target = StrCat("../",
link_target);
free(link_target);
link_target = new_link_target;
ptr++;
}
}
if (!MakeSymLink(link_target, name)) {
(void)fprintf(stderr,
"%s: can't create symbolic link "
"\"%s\".\n", filename, name);
exit(EXIT_FAILURE);
}
PListInsert(files, name)->pe_Link = link_target;
break;
}
case C_ISREG:
if (!MakeTargetDir(name, dirs)) {
(void)fprintf(stderr,
"%s: can't create parent "
"directories for \"%s\".\n",
filename, name);
exit(EXIT_FAILURE);
}
if ((last != NULL) && (last->pe_INode !=
fields[CPIO_HDR_INODE])) {
last = NULL;
}
if (!WriteFile(in, name, mode, length,
(last != NULL)? last->pe_Name : NULL)) {
(void)fprintf(stderr,
"%s: can't write file \"%s\".\n",
filename, name);
exit(EXIT_FAILURE);
}
last = PListInsert(files, name);
last->pe_INode = fields[CPIO_HDR_INODE];
break;
default:
if (length > 0 && !SkipAndAlign(in, length)) {
(void)fprintf(stderr,
"%s: error in cpio file.\n",
filename);
exit(EXIT_FAILURE);
}
}
free(name);
}
FileHandleClose(in);
}
int
main(int argc, char **argv)
{
char *progname;
FILE *plist_file;
char **ignore, *prefix;
int opt, stripcount, i;
PListEntry *files, *dirs;
progname = strrchr(argv[0], '/');
if (progname == NULL)
progname = argv[0];
else
progname++;
plist_file = NULL;
ignore = NULL;
prefix = NULL;
stripcount = 0;
while ((opt = getopt(argc, argv, "d:f:i:p:s:")) != -1) {
switch (opt) {
case 'd':
if (chdir(optarg)) {
perror(optarg);
return EXIT_FAILURE;
}
break;
case 'f':
if (plist_file != NULL)
(void)fclose(plist_file);
if ((plist_file = fopen(optarg, "a")) == NULL) {
perror(optarg);
return EXIT_FAILURE;
}
break;
case 'i':
ignore = ArrayAdd(ignore, optarg);
break;
case 'p':
if (strlen(optarg) > 0)
prefix = optarg;
break;
case 's':
stripcount = atoi(optarg);
if (stripcount <= 0) {
(void)fprintf(stderr,
"%s: -s argument \"%s\" "
"must be a positive integer.\n",
progname, optarg);
return EXIT_FAILURE;
}
break;
default:
Usage(progname);
}
}
if (argc == optind)
Usage(progname);
if (prefix != NULL && prefix[strlen(prefix) - 1] != '/')
prefix = StrCat(prefix, "/");
files = NULL;
dirs = NULL;
for (i = optind; i < argc ; i++)
ProcessRPM(argv[i], &files, &dirs, ignore, prefix, stripcount);
if (plist_file != NULL) {
PListWrite(files, dirs, plist_file);
(void)fclose(plist_file);
}
return EXIT_SUCCESS;
}