151 lines
3.9 KiB
C
151 lines
3.9 KiB
C
#include "system.h"
|
|
|
|
#ifdef __LCLINT__
|
|
#define ntohl(_x) (_x)
|
|
#define ntohs(_x) (_x)
|
|
#define htonl(_x) (_x)
|
|
#define htons(_x) (_x)
|
|
#else
|
|
#include <netinet/in.h>
|
|
#endif /* __LCLINT__ */
|
|
|
|
#include <rpmlib.h>
|
|
|
|
#include "misc.h"
|
|
#include "rpmlead.h"
|
|
#include "signature.h"
|
|
|
|
/* 0 = success */
|
|
/* 1 = bad magic */
|
|
/* 2 = error */
|
|
static int readPackageHeaders(FD_t fd, /*@out@*/struct rpmlead * leadPtr,
|
|
/*@out@*/Header * sigs, /*@out@*/Header * hdrPtr)
|
|
{
|
|
Header hdrBlock;
|
|
struct rpmlead leadBlock;
|
|
Header * hdr = NULL;
|
|
struct rpmlead * lead;
|
|
int_8 arch;
|
|
int isSource;
|
|
char * defaultPrefix;
|
|
struct stat sb;
|
|
int_32 true = 1;
|
|
|
|
hdr = hdrPtr ? hdrPtr : &hdrBlock;
|
|
lead = leadPtr ? leadPtr : &leadBlock;
|
|
|
|
fstat(Fileno(fd), &sb);
|
|
/* if fd points to a socket, pipe, etc, sb.st_size is *always* zero */
|
|
if (S_ISREG(sb.st_mode) && sb.st_size < sizeof(*lead)) return 1;
|
|
|
|
if (readLead(fd, lead)) {
|
|
return 2;
|
|
}
|
|
|
|
if (lead->magic[0] != RPMLEAD_MAGIC0 || lead->magic[1] != RPMLEAD_MAGIC1 ||
|
|
lead->magic[2] != RPMLEAD_MAGIC2 || lead->magic[3] != RPMLEAD_MAGIC3) {
|
|
return 1;
|
|
}
|
|
|
|
switch (lead->major) {
|
|
case 1:
|
|
rpmError(RPMERR_NEWPACKAGE, _("packaging version 1 is not"
|
|
" supported by this version of RPM"));
|
|
return 2;
|
|
/*@notreached@*/ break;
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
if (rpmReadSignature(fd, sigs, lead->signature_type)) {
|
|
return 2;
|
|
}
|
|
*hdr = headerRead(fd, (lead->major >= 3) ?
|
|
HEADER_MAGIC_YES : HEADER_MAGIC_NO);
|
|
if (*hdr == NULL) {
|
|
if (sigs != NULL) {
|
|
headerFree(*sigs);
|
|
}
|
|
return 2;
|
|
}
|
|
|
|
/* We don't use these entries (and rpm >= 2 never have) and they are
|
|
pretty misleading. Let's just get rid of them so they don't confuse
|
|
anyone. */
|
|
if (headerIsEntry(*hdr, RPMTAG_FILEUSERNAME))
|
|
headerRemoveEntry(*hdr, RPMTAG_FILEUIDS);
|
|
if (headerIsEntry(*hdr, RPMTAG_FILEGROUPNAME))
|
|
headerRemoveEntry(*hdr, RPMTAG_FILEGIDS);
|
|
|
|
/* We switched the way we do relocateable packages. We fix some of
|
|
it up here, though the install code still has to be a bit
|
|
careful. This fixup makes queries give the new values though,
|
|
which is quite handy. */
|
|
if (headerGetEntry(*hdr, RPMTAG_DEFAULTPREFIX, NULL,
|
|
(void **) &defaultPrefix, NULL)) {
|
|
defaultPrefix = strcpy(alloca(strlen(defaultPrefix) + 1),
|
|
defaultPrefix);
|
|
stripTrailingSlashes(defaultPrefix);
|
|
headerAddEntry(*hdr, RPMTAG_PREFIXES, RPM_STRING_ARRAY_TYPE,
|
|
&defaultPrefix, 1);
|
|
}
|
|
|
|
/* The file list was moved to a more compressed format which not
|
|
only saves memory (nice), but gives fingerprinting a nice, fat
|
|
speed boost (very nice). Go ahead and convert old headers to
|
|
the new style (this is a noop for new headers) */
|
|
if (lead->major < 4) {
|
|
compressFilelist(*hdr);
|
|
}
|
|
|
|
/* XXX binary rpms always have RPMTAG_SOURCERPM, source rpms do not */
|
|
if (lead->type == RPMLEAD_SOURCE) {
|
|
if (!headerIsEntry(*hdr, RPMTAG_SOURCEPACKAGE))
|
|
headerAddEntry(*hdr, RPMTAG_SOURCEPACKAGE, RPM_INT32_TYPE,
|
|
&true, 1);
|
|
} else if (lead->major < 4) {
|
|
/* Retrofit "Provide: name = EVR" for binary packages. */
|
|
providePackageNVR(*hdr);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
rpmError(RPMERR_NEWPACKAGE, _("only packaging with major numbers <= 4 "
|
|
"is supported by this version of RPM"));
|
|
return 2;
|
|
/*@notreached@*/ break;
|
|
}
|
|
|
|
if (hdrPtr == NULL) {
|
|
headerFree(*hdr);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* 0 = success */
|
|
/* 1 = bad magic */
|
|
/* 2 = error */
|
|
int rpmReadPackageInfo(FD_t fd, Header * signatures, Header * hdr)
|
|
{
|
|
return readPackageHeaders(fd, NULL, signatures, hdr);
|
|
}
|
|
|
|
/* 0 = success */
|
|
/* 1 = bad magic */
|
|
/* 2 = error */
|
|
int rpmReadPackageHeader(FD_t fd, Header * hdr, int * isSource, int * major,
|
|
int * minor)
|
|
{
|
|
int rc;
|
|
struct rpmlead lead;
|
|
|
|
rc = readPackageHeaders(fd, &lead, NULL, hdr);
|
|
if (rc) return rc;
|
|
|
|
if (isSource) *isSource = lead.type == RPMLEAD_SOURCE;
|
|
if (major) *major = lead.major;
|
|
if (minor) *minor = lead.minor;
|
|
|
|
return 0;
|
|
}
|