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