summaryrefslogtreecommitdiff
path: root/lib/rpmlead.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rpmlead.c')
-rw-r--r--lib/rpmlead.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/lib/rpmlead.c b/lib/rpmlead.c
new file mode 100644
index 0000000..d41a413
--- /dev/null
+++ b/lib/rpmlead.c
@@ -0,0 +1,141 @@
+/** \ingroup lead
+ * \file lib/rpmlead.c
+ */
+
+#include "system.h"
+
+#include <errno.h>
+#include <netinet/in.h>
+
+#include <rpm/rpmlib.h> /* rpmGetOs/ArchInfo() */
+#include <rpm/rpmlog.h>
+#include <rpm/rpmstring.h>
+
+#include "lib/signature.h"
+#include "lib/rpmlead.h"
+
+#include "debug.h"
+
+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! */
+};
+
+rpmlead rpmLeadNew(void)
+{
+ int archnum, osnum;
+ rpmlead l = xcalloc(1, sizeof(*l));
+
+ rpmGetArchInfo(NULL, &archnum);
+ rpmGetOsInfo(NULL, &osnum);
+
+ l->major = 3;
+ l->minor = 0;
+ l->archnum = archnum;
+ l->osnum = osnum;
+ l->signature_type = RPMSIGTYPE_HEADERSIG;
+ return l;
+}
+
+rpmlead rpmLeadFromHeader(Header h)
+{
+ char * nevr;
+ assert(h != NULL);
+ rpmlead l = rpmLeadNew();
+
+ l->type = (headerIsSource(h) ? 1 : 0);
+ nevr = headerGetAsString(h, RPMTAG_NEVR);
+ rstrlcpy(l->name, nevr, sizeof(l->name));
+ free(nevr);
+
+ return l;
+}
+
+rpmlead rpmLeadFree(rpmlead lead)
+{
+ assert(lead != NULL);
+ free(lead);
+ return NULL;
+}
+
+/* The lead needs to be 8 byte aligned */
+rpmRC rpmLeadWrite(FD_t fd, rpmlead lead)
+{
+ struct rpmlead_s l;
+ assert(lead != NULL);
+
+ memcpy(&l, lead, sizeof(l));
+
+ memcpy(&l.magic, lead_magic, sizeof(l.magic));
+ l.type = htons(lead->type);
+ l.archnum = htons(lead->archnum);
+ l.osnum = htons(lead->osnum);
+ l.signature_type = htons(lead->signature_type);
+
+ if (Fwrite(&l, 1, sizeof(l), fd) != sizeof(l))
+ return RPMRC_FAIL;
+
+ return RPMRC_OK;
+}
+
+rpmRC rpmLeadCheck(rpmlead lead, const char **msg)
+{
+ if (memcmp(lead->magic, lead_magic, sizeof(lead_magic))) {
+ if (msg) *msg = _("not an rpm package");
+ return RPMRC_NOTFOUND;
+ }
+ if (lead->signature_type != RPMSIGTYPE_HEADERSIG) {
+ if (msg) *msg = _("illegal signature type");
+ return RPMRC_FAIL;
+ }
+ if (lead->major < 3 || lead->major > 4) {
+ if (msg) *msg = _("unsupported RPM package version");
+ return RPMRC_FAIL;
+ }
+ return RPMRC_OK;
+}
+
+rpmRC rpmLeadRead(FD_t fd, rpmlead lead)
+{
+ assert(lead != NULL);
+ memset(lead, 0, sizeof(*lead));
+ /* FIX: remove timed read */
+ if (timedRead(fd, (char *)lead, sizeof(*lead)) != sizeof(*lead)) {
+ if (Ferror(fd)) {
+ rpmlog(RPMLOG_ERR, _("read failed: %s (%d)\n"),
+ Fstrerror(fd), errno);
+ return RPMRC_FAIL;
+ } else {
+ rpmlog(RPMLOG_ERR, _("not an rpm package\n"));
+ return RPMRC_NOTFOUND;
+ }
+ }
+ lead->type = ntohs(lead->type);
+ lead->archnum = ntohs(lead->archnum);
+ lead->osnum = ntohs(lead->osnum);
+ lead->signature_type = ntohs(lead->signature_type);
+
+ return RPMRC_OK;
+}
+
+int rpmLeadType(rpmlead lead)
+{
+ return lead ? lead->type : -1;
+}