|
|
2ff057 |
/** \ingroup lead
|
|
|
2ff057 |
* \file lib/rpmlead.c
|
|
|
2ff057 |
*/
|
|
|
2ff057 |
|
|
|
2ff057 |
#include "system.h"
|
|
|
2ff057 |
|
|
|
2ff057 |
#include <errno.h>
|
|
|
2ff057 |
#include <netinet/in.h>
|
|
|
2ff057 |
|
|
|
2ff057 |
#include <rpm/rpmlib.h> /* rpmGetOs/ArchInfo() */
|
|
|
2ff057 |
#include <rpm/rpmlog.h>
|
|
|
2ff057 |
#include <rpm/rpmstring.h>
|
|
|
2ff057 |
|
|
|
2ff057 |
#include "lib/signature.h"
|
|
|
2ff057 |
#include "lib/header_internal.h" /* Freadall() */
|
|
|
2ff057 |
#include "lib/rpmlead.h"
|
|
|
2ff057 |
|
|
|
2ff057 |
#include "debug.h"
|
|
|
2ff057 |
|
|
|
2ff057 |
/* A long time ago in a galaxy far far away, signatures were not in a header */
|
|
|
2ff057 |
#define RPMSIGTYPE_HEADERSIG 5
|
|
|
2ff057 |
|
|
|
2ff057 |
static unsigned char const lead_magic[] = {
|
|
|
2ff057 |
RPMLEAD_MAGIC0, RPMLEAD_MAGIC1, RPMLEAD_MAGIC2, RPMLEAD_MAGIC3
|
|
|
2ff057 |
};
|
|
|
2ff057 |
|
|
|
2ff057 |
/** \ingroup lead
|
|
|
2ff057 |
* The lead data structure.
|
|
|
2ff057 |
* The lead needs to be 8 byte aligned.
|
|
|
2ff057 |
* @deprecated The lead (except for signature_type) is legacy.
|
|
|
2ff057 |
* @todo Don't use any information from lead.
|
|
|
2ff057 |
*/
|
|
|
2ff057 |
struct rpmlead_s {
|
|
|
2ff057 |
unsigned char magic[4];
|
|
|
2ff057 |
unsigned char major;
|
|
|
2ff057 |
unsigned char minor;
|
|
|
2ff057 |
short type;
|
|
|
2ff057 |
short archnum;
|
|
|
2ff057 |
char name[66];
|
|
|
2ff057 |
short osnum;
|
|
|
2ff057 |
short signature_type; /*!< Signature header type (RPMSIG_HEADERSIG) */
|
|
|
2ff057 |
char reserved[16]; /*!< Pad to 96 bytes -- 8 byte aligned! */
|
|
|
2ff057 |
};
|
|
|
2ff057 |
|
|
|
2ff057 |
static int rpmLeadFromHeader(Header h, struct rpmlead_s *l)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (h != NULL) {
|
|
|
2ff057 |
int archnum, osnum;
|
|
|
2ff057 |
char * nevr = headerGetAsString(h, RPMTAG_NEVR);
|
|
|
2ff057 |
|
|
|
2ff057 |
/* FIXME: should grab these from header instead (RhBug:717898) */
|
|
|
2ff057 |
rpmGetArchInfo(NULL, &archnum);
|
|
|
2ff057 |
rpmGetOsInfo(NULL, &osnum);
|
|
|
2ff057 |
|
|
|
2ff057 |
memset(l, 0, sizeof(*l));
|
|
|
2ff057 |
l->major = 3;
|
|
|
2ff057 |
l->minor = 0;
|
|
|
2ff057 |
l->archnum = archnum;
|
|
|
2ff057 |
l->osnum = osnum;
|
|
|
2ff057 |
l->signature_type = RPMSIGTYPE_HEADERSIG;
|
|
|
2ff057 |
l->type = (headerIsSource(h) ? 1 : 0);
|
|
|
2ff057 |
|
|
|
2ff057 |
memcpy(l->magic, lead_magic, sizeof(l->magic));
|
|
|
2ff057 |
rstrlcpy(l->name, nevr, sizeof(l->name));
|
|
|
2ff057 |
|
|
|
2ff057 |
free(nevr);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
return (h != NULL);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
/* The lead needs to be 8 byte aligned */
|
|
|
2ff057 |
rpmRC rpmLeadWrite(FD_t fd, Header h)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmRC rc = RPMRC_FAIL;
|
|
|
2ff057 |
struct rpmlead_s l;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (rpmLeadFromHeader(h, &l)) {
|
|
|
2ff057 |
|
|
|
2ff057 |
l.type = htons(l.type);
|
|
|
2ff057 |
l.archnum = htons(l.archnum);
|
|
|
2ff057 |
l.osnum = htons(l.osnum);
|
|
|
2ff057 |
l.signature_type = htons(l.signature_type);
|
|
|
2ff057 |
|
|
|
2ff057 |
if (Fwrite(&l, 1, sizeof(l), fd) == sizeof(l))
|
|
|
2ff057 |
rc = RPMRC_OK;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static rpmRC rpmLeadCheck(struct rpmlead_s *lead, char **msg)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (memcmp(lead->magic, lead_magic, sizeof(lead_magic))) {
|
|
|
2ff057 |
*msg = xstrdup(_("not an rpm package"));
|
|
|
2ff057 |
return RPMRC_NOTFOUND;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
if (lead->signature_type != RPMSIGTYPE_HEADERSIG) {
|
|
|
2ff057 |
*msg = xstrdup(_("illegal signature type"));
|
|
|
2ff057 |
return RPMRC_FAIL;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
if (lead->major < 3 || lead->major > 4) {
|
|
|
2ff057 |
*msg = xstrdup(_("unsupported RPM package version"));
|
|
|
2ff057 |
return RPMRC_FAIL;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return RPMRC_OK;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmRC rpmLeadRead(FD_t fd, char **emsg)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmRC rc = RPMRC_OK;
|
|
|
2ff057 |
struct rpmlead_s l;
|
|
|
2ff057 |
char *err = NULL;
|
|
|
2ff057 |
|
|
|
2ff057 |
memset(&l, 0, sizeof(l));
|
|
|
2ff057 |
if (Freadall(fd, &l, sizeof(l)) != sizeof(l)) {
|
|
|
2ff057 |
if (Ferror(fd)) {
|
|
|
2ff057 |
rasprintf(&err, _("read failed: %s (%d)\n"), Fstrerror(fd), errno);
|
|
|
2ff057 |
rc = RPMRC_FAIL;
|
|
|
2ff057 |
} else {
|
|
|
2ff057 |
err = xstrdup(_("not an rpm package\n"));
|
|
|
2ff057 |
rc = RPMRC_NOTFOUND;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
} else {
|
|
|
2ff057 |
l.type = ntohs(l.type);
|
|
|
2ff057 |
l.archnum = ntohs(l.archnum);
|
|
|
2ff057 |
l.osnum = ntohs(l.osnum);
|
|
|
2ff057 |
l.signature_type = ntohs(l.signature_type);
|
|
|
2ff057 |
rc = rpmLeadCheck(&l, &err;;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
if (rc != RPMRC_OK) {
|
|
|
2ff057 |
if (emsg != NULL)
|
|
|
2ff057 |
*emsg = err;
|
|
|
2ff057 |
else
|
|
|
2ff057 |
free(err);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
return rc;
|
|
|
2ff057 |
}
|