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