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