Start beating a little bit of sense into the braindamaged rpmlead API
[platform/upstream/rpm.git] / lib / rpmlead.c
1 /** \ingroup lead
2  * \file lib/rpmlead.c
3  */
4
5 #include "system.h"
6
7 #include <errno.h>
8 #include <netinet/in.h>
9
10 #include <rpm/rpmlib.h>         /* rpmGetOs/ArchInfo() */
11 #include <rpm/rpmlog.h>
12 #include <rpm/rpmstring.h>
13
14 #include "lib/signature.h"
15 #include "lib/rpmlead.h"
16
17 #include "debug.h"
18
19 static unsigned char const lead_magic[] = {
20     RPMLEAD_MAGIC0, RPMLEAD_MAGIC1, RPMLEAD_MAGIC2, RPMLEAD_MAGIC3
21 };
22
23 /** \ingroup lead
24  * The lead data structure.
25  * The lead needs to be 8 byte aligned.
26  * @deprecated The lead (except for signature_type) is legacy.
27  * @todo Don't use any information from lead.
28  */
29 struct rpmlead_s {
30     unsigned char magic[4];
31     unsigned char major;
32     unsigned char minor;
33     short type;
34     short archnum;
35     char name[66];
36     short osnum;
37     short signature_type;       /*!< Signature header type (RPMSIG_HEADERSIG) */
38     char reserved[16];      /*!< Pad to 96 bytes -- 8 byte aligned! */
39 };
40
41 rpmlead rpmLeadNew(void)
42 {
43     return xcalloc(1, sizeof(struct rpmlead_s));
44 }
45
46 rpmlead rpmLeadFromHeader(Header h)
47 {
48     rpmlead l = NULL;
49
50     if (h != NULL) {
51         int archnum, osnum;
52         char * nevr = headerGetAsString(h, RPMTAG_NEVR);
53
54         /* FIXME: should grab these from header instead (RhBug:717898) */
55         rpmGetArchInfo(NULL, &archnum);
56         rpmGetOsInfo(NULL, &osnum);
57
58         l = rpmLeadNew();
59         l->major = 3;
60         l->minor = 0;
61         l->archnum = archnum;
62         l->osnum = osnum;
63         l->signature_type = RPMSIGTYPE_HEADERSIG;
64         l->type = (headerIsSource(h) ? 1 : 0);
65
66         memcpy(l->magic, lead_magic, sizeof(l->magic));
67         rstrlcpy(l->name, nevr, sizeof(l->name));
68
69         free(nevr);
70     }
71
72     return l;
73 }
74
75 rpmlead rpmLeadFree(rpmlead lead)
76 {
77     assert(lead != NULL);
78     free(lead);
79     return NULL;
80 }
81
82 /* The lead needs to be 8 byte aligned */
83 rpmRC rpmLeadWrite(FD_t fd, rpmlead lead)
84 {
85     struct rpmlead_s l;
86     assert(lead != NULL);
87
88     memcpy(&l, lead, sizeof(l));
89     
90     l.type = htons(lead->type);
91     l.archnum = htons(lead->archnum);
92     l.osnum = htons(lead->osnum);
93     l.signature_type = htons(lead->signature_type);
94         
95     if (Fwrite(&l, 1, sizeof(l), fd) != sizeof(l))
96         return RPMRC_FAIL;
97
98     return RPMRC_OK;
99 }
100
101 rpmRC rpmLeadCheck(rpmlead lead, const char **msg)
102 {
103     if (memcmp(lead->magic, lead_magic, sizeof(lead_magic))) {
104         if (msg) *msg = _("not an rpm package");
105         return RPMRC_NOTFOUND;
106     }
107     if (lead->signature_type != RPMSIGTYPE_HEADERSIG) {
108         if (msg) *msg = _("illegal signature type");
109         return RPMRC_FAIL;
110     }
111     if (lead->major < 3 || lead->major > 4) {
112         if (msg) *msg = _("unsupported RPM package version");
113         return RPMRC_FAIL;
114     }
115     return RPMRC_OK;
116 }
117
118 rpmRC rpmLeadRead(FD_t fd, rpmlead lead)
119 {
120     assert(lead != NULL);
121     memset(lead, 0, sizeof(*lead));
122     if (Fread(lead, 1, sizeof(*lead), fd) != sizeof(*lead)) {
123         if (Ferror(fd)) {
124             rpmlog(RPMLOG_ERR, _("read failed: %s (%d)\n"),
125                         Fstrerror(fd), errno);
126             return RPMRC_FAIL;
127         } else {
128             rpmlog(RPMLOG_ERR, _("not an rpm package\n"));
129             return RPMRC_NOTFOUND;
130         }
131     }
132     lead->type = ntohs(lead->type);
133     lead->archnum = ntohs(lead->archnum);
134     lead->osnum = ntohs(lead->osnum);
135     lead->signature_type = ntohs(lead->signature_type);
136
137     return RPMRC_OK;
138 }
139
140 int rpmLeadType(rpmlead lead)
141 {
142     return lead ? lead->type : -1;
143 }