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