2000-08-28 03:27:03 +08:00
|
|
|
/** \ingroup header
|
|
|
|
* \file lib/package.c
|
|
|
|
*/
|
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
#include "system.h"
|
1997-11-18 11:13:56 +08:00
|
|
|
|
1996-02-15 01:54:37 +08:00
|
|
|
#include <netinet/in.h>
|
1996-01-06 02:12:55 +08:00
|
|
|
|
1999-07-14 05:37:57 +08:00
|
|
|
#include <rpmlib.h>
|
1998-07-31 06:09:42 +08:00
|
|
|
|
1996-02-27 06:45:10 +08:00
|
|
|
#include "misc.h"
|
1996-01-06 02:12:55 +08:00
|
|
|
#include "rpmlead.h"
|
1996-02-22 06:20:51 +08:00
|
|
|
#include "signature.h"
|
2000-12-13 04:03:45 +08:00
|
|
|
#include "debug.h"
|
1996-01-06 08:07:50 +08:00
|
|
|
|
2001-01-09 12:07:49 +08:00
|
|
|
#define alloca_strdup(_s) strcpy(alloca(strlen(_s)+1), (_s))
|
|
|
|
|
2000-10-29 01:16:25 +08:00
|
|
|
/*@access Header@*/ /* XXX compared with NULL */
|
|
|
|
|
2000-12-03 05:53:44 +08:00
|
|
|
void headerMergeLegacySigs(Header h, const Header sig)
|
|
|
|
{
|
2001-06-12 12:10:21 +08:00
|
|
|
HFD_t hfd = (HFD_t) headerFreeData;
|
|
|
|
HAE_t hae = (HAE_t) headerAddEntry;
|
2000-12-03 05:53:44 +08:00
|
|
|
HeaderIterator hi;
|
|
|
|
int_32 tag, type, count;
|
|
|
|
const void * ptr;
|
|
|
|
|
2001-09-25 05:53:14 +08:00
|
|
|
/*@-mods@*/ /* FIX: undocumented modification of sig */
|
2000-12-03 05:53:44 +08:00
|
|
|
for (hi = headerInitIterator(sig);
|
2001-09-25 05:53:14 +08:00
|
|
|
/*@=mods@*/
|
2000-12-03 05:53:44 +08:00
|
|
|
headerNextIterator(hi, &tag, &type, &ptr, &count);
|
2001-06-12 12:10:21 +08:00
|
|
|
ptr = hfd(ptr, type))
|
2000-12-03 05:53:44 +08:00
|
|
|
{
|
|
|
|
switch (tag) {
|
2001-10-14 06:01:38 +08:00
|
|
|
case RPMSIGTAG_SIZE:
|
|
|
|
tag = RPMTAG_SIGSIZE;
|
|
|
|
/*@switchbreak@*/ break;
|
|
|
|
case RPMSIGTAG_LEMD5_1:
|
|
|
|
tag = RPMTAG_SIGLEMD5_1;
|
|
|
|
/*@switchbreak@*/ break;
|
|
|
|
case RPMSIGTAG_PGP:
|
|
|
|
tag = RPMTAG_SIGPGP;
|
|
|
|
/*@switchbreak@*/ break;
|
|
|
|
case RPMSIGTAG_LEMD5_2:
|
|
|
|
tag = RPMTAG_SIGLEMD5_2;
|
|
|
|
/*@switchbreak@*/ break;
|
|
|
|
case RPMSIGTAG_MD5:
|
|
|
|
tag = RPMTAG_SIGMD5;
|
|
|
|
/*@switchbreak@*/ break;
|
|
|
|
case RPMSIGTAG_GPG:
|
|
|
|
tag = RPMTAG_SIGGPG;
|
|
|
|
/*@switchbreak@*/ break;
|
|
|
|
case RPMSIGTAG_PGP5:
|
|
|
|
tag = RPMTAG_SIGPGP5;
|
|
|
|
/*@switchbreak@*/ break;
|
2001-03-15 07:09:09 +08:00
|
|
|
default:
|
2001-06-12 12:10:21 +08:00
|
|
|
if (!(tag >= HEADER_SIGBASE && tag < HEADER_TAGBASE))
|
|
|
|
continue;
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
2000-12-03 05:53:44 +08:00
|
|
|
}
|
2001-05-04 05:00:18 +08:00
|
|
|
if (ptr == NULL) continue; /* XXX can't happen */
|
2000-12-03 05:53:44 +08:00
|
|
|
if (!headerIsEntry(h, tag))
|
2001-06-12 12:10:21 +08:00
|
|
|
(void) hae(h, tag, type, ptr, count);
|
2000-12-03 05:53:44 +08:00
|
|
|
}
|
2001-06-20 00:59:23 +08:00
|
|
|
hi = headerFreeIterator(hi);
|
2000-12-03 05:53:44 +08:00
|
|
|
}
|
|
|
|
|
2001-02-12 06:02:29 +08:00
|
|
|
Header headerRegenSigHeader(const Header h)
|
|
|
|
{
|
2001-06-12 12:10:21 +08:00
|
|
|
HFD_t hfd = (HFD_t) headerFreeData;
|
2001-02-12 06:02:29 +08:00
|
|
|
Header sig = rpmNewSignature();
|
|
|
|
HeaderIterator hi;
|
|
|
|
int_32 tag, stag, type, count;
|
|
|
|
const void * ptr;
|
|
|
|
|
2001-09-25 05:53:14 +08:00
|
|
|
/*@-mods@*/ /* FIX: undocumented modification of h */
|
2001-02-12 06:02:29 +08:00
|
|
|
for (hi = headerInitIterator(h);
|
2001-09-25 05:53:14 +08:00
|
|
|
/*@=mods@*/
|
2001-02-12 06:02:29 +08:00
|
|
|
headerNextIterator(hi, &tag, &type, &ptr, &count);
|
2001-06-12 12:10:21 +08:00
|
|
|
ptr = hfd(ptr, type))
|
2001-02-12 06:02:29 +08:00
|
|
|
{
|
|
|
|
switch (tag) {
|
2001-10-14 06:01:38 +08:00
|
|
|
case RPMTAG_SIGSIZE:
|
|
|
|
stag = RPMSIGTAG_SIZE;
|
|
|
|
/*@switchbreak@*/ break;
|
|
|
|
case RPMTAG_SIGLEMD5_1:
|
|
|
|
stag = RPMSIGTAG_LEMD5_1;
|
|
|
|
/*@switchbreak@*/ break;
|
|
|
|
case RPMTAG_SIGPGP:
|
|
|
|
stag = RPMSIGTAG_PGP;
|
|
|
|
/*@switchbreak@*/ break;
|
|
|
|
case RPMTAG_SIGLEMD5_2:
|
|
|
|
stag = RPMSIGTAG_LEMD5_2;
|
|
|
|
/*@switchbreak@*/ break;
|
|
|
|
case RPMTAG_SIGMD5:
|
|
|
|
stag = RPMSIGTAG_MD5;
|
|
|
|
/*@switchbreak@*/ break;
|
|
|
|
case RPMTAG_SIGGPG:
|
|
|
|
stag = RPMSIGTAG_GPG;
|
|
|
|
/*@switchbreak@*/ break;
|
|
|
|
case RPMTAG_SIGPGP5:
|
|
|
|
stag = RPMSIGTAG_PGP5;
|
|
|
|
/*@switchbreak@*/ break;
|
2001-02-12 06:02:29 +08:00
|
|
|
default:
|
2001-06-12 12:10:21 +08:00
|
|
|
if (!(tag >= HEADER_SIGBASE && tag < HEADER_TAGBASE))
|
|
|
|
continue;
|
|
|
|
stag = tag;
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
2001-02-12 06:02:29 +08:00
|
|
|
}
|
2001-05-04 05:00:18 +08:00
|
|
|
if (ptr == NULL) continue; /* XXX can't happen */
|
2001-02-12 06:02:29 +08:00
|
|
|
if (!headerIsEntry(sig, stag))
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddEntry(sig, stag, type, ptr, count);
|
2001-02-12 06:02:29 +08:00
|
|
|
}
|
2001-06-20 00:59:23 +08:00
|
|
|
hi = headerFreeIterator(hi);
|
2001-02-12 06:02:29 +08:00
|
|
|
return sig;
|
|
|
|
}
|
|
|
|
|
2000-08-23 21:02:13 +08:00
|
|
|
/**
|
|
|
|
* Retrieve package components from file handle.
|
|
|
|
* @param fd file handle
|
|
|
|
* @param leadPtr address of lead (or NULL)
|
|
|
|
* @param sigs address of signatures (or NULL)
|
|
|
|
* @param hdrPtr address of header (or NULL)
|
2001-02-13 03:02:15 +08:00
|
|
|
* @return rpmRC return code
|
2000-08-23 21:02:13 +08:00
|
|
|
*/
|
2001-06-01 06:31:14 +08:00
|
|
|
static rpmRC readPackageHeaders(FD_t fd,
|
|
|
|
/*@null@*/ /*@out@*/ struct rpmlead * leadPtr,
|
|
|
|
/*@null@*/ /*@out@*/ Header * sigs,
|
|
|
|
/*@null@*/ /*@out@*/ Header * hdrPtr)
|
2000-10-29 01:16:25 +08:00
|
|
|
/*@modifies fd, *leadPtr, *sigs, *hdrPtr @*/
|
1999-07-14 07:33:02 +08:00
|
|
|
{
|
1999-07-09 06:10:33 +08:00
|
|
|
Header hdrBlock;
|
|
|
|
struct rpmlead leadBlock;
|
1999-09-18 04:52:46 +08:00
|
|
|
Header * hdr = NULL;
|
1999-07-09 06:10:33 +08:00
|
|
|
struct rpmlead * lead;
|
|
|
|
char * defaultPrefix;
|
|
|
|
struct stat sb;
|
2001-02-13 03:02:15 +08:00
|
|
|
rpmRC rc;
|
1999-07-09 06:10:33 +08:00
|
|
|
|
|
|
|
hdr = hdrPtr ? hdrPtr : &hdrBlock;
|
|
|
|
lead = leadPtr ? leadPtr : &leadBlock;
|
|
|
|
|
2001-05-01 06:32:22 +08:00
|
|
|
memset(&sb, 0, sizeof(sb));
|
|
|
|
(void) fstat(Fileno(fd), &sb);
|
1999-07-09 06:10:33 +08:00
|
|
|
/* 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;
|
|
|
|
|
2000-11-07 21:16:43 +08:00
|
|
|
if (readLead(fd, lead))
|
2001-02-13 03:02:15 +08:00
|
|
|
return RPMRC_FAIL;
|
1999-07-09 06:10:33 +08:00
|
|
|
|
|
|
|
if (lead->magic[0] != RPMLEAD_MAGIC0 || lead->magic[1] != RPMLEAD_MAGIC1 ||
|
|
|
|
lead->magic[2] != RPMLEAD_MAGIC2 || lead->magic[3] != RPMLEAD_MAGIC3) {
|
2001-02-13 03:02:15 +08:00
|
|
|
return RPMRC_BADMAGIC;
|
1999-07-09 06:10:33 +08:00
|
|
|
}
|
|
|
|
|
2000-05-31 03:30:28 +08:00
|
|
|
switch (lead->major) {
|
1999-07-09 06:10:33 +08:00
|
|
|
case 1:
|
2001-01-09 12:07:49 +08:00
|
|
|
rpmError(RPMERR_NEWPACKAGE,
|
2001-01-16 07:09:42 +08:00
|
|
|
_("packaging version 1 is not supported by this version of RPM\n"));
|
2001-02-13 03:02:15 +08:00
|
|
|
return RPMRC_FAIL;
|
2000-07-15 22:53:54 +08:00
|
|
|
/*@notreached@*/ break;
|
1999-07-09 06:10:33 +08:00
|
|
|
case 2:
|
|
|
|
case 3:
|
2000-05-31 03:30:28 +08:00
|
|
|
case 4:
|
2001-02-13 03:02:15 +08:00
|
|
|
rc = rpmReadSignature(fd, sigs, lead->signature_type);
|
|
|
|
if (rc == RPMRC_FAIL)
|
|
|
|
return rc;
|
2001-01-09 12:07:49 +08:00
|
|
|
*hdr = headerRead(fd, (lead->major >= 3)
|
|
|
|
? HEADER_MAGIC_YES : HEADER_MAGIC_NO);
|
1999-07-09 06:10:33 +08:00
|
|
|
if (*hdr == NULL) {
|
2000-11-07 21:16:43 +08:00
|
|
|
if (sigs != NULL)
|
2001-05-23 22:25:19 +08:00
|
|
|
*sigs = rpmFreeSignature(*sigs);
|
2001-02-13 03:02:15 +08:00
|
|
|
return RPMRC_FAIL;
|
1999-07-09 06:10:33 +08:00
|
|
|
}
|
|
|
|
|
2001-02-13 03:02:15 +08:00
|
|
|
/*
|
|
|
|
* We don't use these entries (and rpm >= 2 never has) and they are
|
|
|
|
* pretty misleading. Let's just get rid of them so they don't confuse
|
|
|
|
* anyone.
|
|
|
|
*/
|
1999-10-07 06:50:55 +08:00
|
|
|
if (headerIsEntry(*hdr, RPMTAG_FILEUSERNAME))
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerRemoveEntry(*hdr, RPMTAG_FILEUIDS);
|
1999-10-07 06:50:55 +08:00
|
|
|
if (headerIsEntry(*hdr, RPMTAG_FILEGROUPNAME))
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerRemoveEntry(*hdr, RPMTAG_FILEGIDS);
|
1999-10-07 06:50:55 +08:00
|
|
|
|
2001-04-21 14:02:09 +08:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
1999-07-09 06:10:33 +08:00
|
|
|
if (headerGetEntry(*hdr, RPMTAG_DEFAULTPREFIX, NULL,
|
2001-06-12 12:10:21 +08:00
|
|
|
(void **) &defaultPrefix, NULL))
|
|
|
|
{
|
2001-01-09 12:07:49 +08:00
|
|
|
defaultPrefix =
|
|
|
|
stripTrailingChar(alloca_strdup(defaultPrefix), '/');
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddEntry(*hdr, RPMTAG_PREFIXES, RPM_STRING_ARRAY_TYPE,
|
1999-07-09 06:10:33 +08:00
|
|
|
&defaultPrefix, 1);
|
|
|
|
}
|
|
|
|
|
2001-02-13 03:02:15 +08:00
|
|
|
/*
|
|
|
|
* 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).
|
|
|
|
*/
|
2000-12-03 05:53:44 +08:00
|
|
|
if (lead->major < 4)
|
2000-05-31 03:30:28 +08:00
|
|
|
compressFilelist(*hdr);
|
1999-10-06 23:51:14 +08:00
|
|
|
|
1999-07-09 06:10:33 +08:00
|
|
|
/* XXX binary rpms always have RPMTAG_SOURCERPM, source rpms do not */
|
|
|
|
if (lead->type == RPMLEAD_SOURCE) {
|
2001-06-04 21:55:58 +08:00
|
|
|
int_32 one = 1;
|
1999-07-09 06:10:33 +08:00
|
|
|
if (!headerIsEntry(*hdr, RPMTAG_SOURCEPACKAGE))
|
2001-05-01 06:32:22 +08:00
|
|
|
(void)headerAddEntry(*hdr, RPMTAG_SOURCEPACKAGE, RPM_INT32_TYPE,
|
2001-06-04 21:55:58 +08:00
|
|
|
&one, 1);
|
2000-05-31 03:30:28 +08:00
|
|
|
} else if (lead->major < 4) {
|
2001-02-13 03:02:15 +08:00
|
|
|
/* Retrofit "Provide: name = EVR" for binary packages. */
|
2000-04-14 01:59:10 +08:00
|
|
|
providePackageNVR(*hdr);
|
1999-07-09 06:10:33 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2000-07-15 22:53:54 +08:00
|
|
|
rpmError(RPMERR_NEWPACKAGE, _("only packaging with major numbers <= 4 "
|
2001-01-16 07:09:42 +08:00
|
|
|
"is supported by this version of RPM\n"));
|
2001-02-13 03:02:15 +08:00
|
|
|
return RPMRC_FAIL;
|
1999-09-18 04:52:46 +08:00
|
|
|
/*@notreached@*/ break;
|
1999-07-09 06:10:33 +08:00
|
|
|
}
|
|
|
|
|
2000-12-03 05:53:44 +08:00
|
|
|
if (hdrPtr == NULL)
|
2001-05-23 22:25:19 +08:00
|
|
|
*hdr = headerFree(*hdr);
|
1999-07-09 06:10:33 +08:00
|
|
|
|
2001-02-13 03:02:15 +08:00
|
|
|
return RPMRC_OK;
|
1999-07-09 06:10:33 +08:00
|
|
|
}
|
|
|
|
|
2001-02-13 03:02:15 +08:00
|
|
|
rpmRC rpmReadPackageInfo(FD_t fd, Header * sigp, Header * hdrp)
|
1999-07-14 07:33:02 +08:00
|
|
|
{
|
2001-02-13 03:02:15 +08:00
|
|
|
rpmRC rc = readPackageHeaders(fd, NULL, sigp, hdrp);
|
2001-07-11 10:16:16 +08:00
|
|
|
if (rc != RPMRC_OK)
|
2001-01-16 22:10:21 +08:00
|
|
|
return rc;
|
2001-06-01 06:31:14 +08:00
|
|
|
if (hdrp == NULL || sigp == NULL)
|
|
|
|
return rc;
|
|
|
|
if (*hdrp && *sigp)
|
2000-12-03 05:53:44 +08:00
|
|
|
headerMergeLegacySigs(*hdrp, *sigp);
|
|
|
|
return rc;
|
1999-07-09 06:10:33 +08:00
|
|
|
}
|
|
|
|
|
2001-02-13 03:02:15 +08:00
|
|
|
rpmRC rpmReadPackageHeader(FD_t fd, Header * hdrp, int * isSource, int * major,
|
1999-07-14 07:33:02 +08:00
|
|
|
int * minor)
|
|
|
|
{
|
1999-07-09 06:10:33 +08:00
|
|
|
struct rpmlead lead;
|
2000-12-03 05:53:44 +08:00
|
|
|
Header sig = NULL;
|
2001-02-13 03:02:15 +08:00
|
|
|
rpmRC rc = readPackageHeaders(fd, &lead, &sig, hdrp);
|
2000-12-03 05:53:44 +08:00
|
|
|
|
2001-07-11 10:16:16 +08:00
|
|
|
if (rc != RPMRC_OK)
|
2000-12-03 05:53:44 +08:00
|
|
|
goto exit;
|
1999-07-09 06:10:33 +08:00
|
|
|
|
2000-12-03 05:53:44 +08:00
|
|
|
if (hdrp && *hdrp && sig) {
|
|
|
|
headerMergeLegacySigs(*hdrp, sig);
|
2001-05-23 22:25:19 +08:00
|
|
|
sig = rpmFreeSignature(sig);
|
2000-12-03 05:53:44 +08:00
|
|
|
}
|
1999-07-09 06:10:33 +08:00
|
|
|
|
|
|
|
if (isSource) *isSource = lead.type == RPMLEAD_SOURCE;
|
2001-09-25 05:53:14 +08:00
|
|
|
/*@-mods@*/ /* FIX: undocumented modification */
|
1999-07-09 06:10:33 +08:00
|
|
|
if (major) *major = lead.major;
|
|
|
|
if (minor) *minor = lead.minor;
|
2001-04-30 06:43:01 +08:00
|
|
|
/*@=mods@*/
|
1999-07-09 06:10:33 +08:00
|
|
|
|
2000-12-03 05:53:44 +08:00
|
|
|
exit:
|
|
|
|
return rc;
|
1999-07-09 06:10:33 +08:00
|
|
|
}
|