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