2 * Copyright (c) 2004 Michael Schroeder (mls@suse.de)
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
18 /****************************************************************
25 readhead(int fd, int pad)
27 unsigned char intro[16];
31 l = xread(fd, intro, 16);
36 fprintf(stderr, "header read error\n");
39 if (intro[0] != 0x8e || intro[1] != 0xad || intro[2] != 0xe8 || intro[3] != 0x01)
41 fprintf(stderr, "bad header\n");
44 cnt = intro[8] << 24 | intro[9] << 16 | intro[10] << 8 | intro[11];
45 dcnt = intro[12] << 24 | intro[13] << 16 | intro[14] << 8 | intro[15];
46 if ((dcnt & 7) && pad)
47 dcnt += 8 - (dcnt & 7);
48 h = xmalloc(sizeof(*h) + cnt * 16 + dcnt);
49 memcpy(h->intro, intro, 16);
50 if (xread(fd, h->data, cnt * 16 + dcnt) != cnt * 16 + dcnt)
52 fprintf(stderr, "header read error\n");
58 h->dp = h->data + cnt * 16;
63 readhead_buf(unsigned char *buf, int len, int pad)
70 fprintf(stderr, "bad header\n");
73 if (buf[0] != 0x8e || buf[1] != 0xad || buf[2] != 0xe8 || buf[3] != 0x01)
75 fprintf(stderr, "bad header\n");
78 cnt = buf[8] << 24 | buf[9] << 16 | buf[10] << 8 | buf[11];
79 dcnt = buf[12] << 24 | buf[13] << 16 | buf[14] << 8 | buf[15];
80 if ((dcnt & 7) && pad)
81 dcnt += 8 - (dcnt & 7);
82 if (len < 16 + cnt * 16 + dcnt)
84 fprintf(stderr, "bad header\n");
87 h = xmalloc(sizeof(*h) + cnt * 16 + dcnt);
88 memcpy(h->intro, buf, 16);
89 memcpy(h->data, buf + 16, cnt * 16 + dcnt);
92 h->dp = h->data + cnt * 16;
97 headint32(struct rpmhead *h, int tag, int *cnt)
99 unsigned int i, o, *r;
100 unsigned char *d, taga[4];
107 for (i = 0; i < h->cnt; i++, d += 16)
108 if (d[3] == taga[3] && d[2] == taga[2] && d[1] == taga[1] && d[0] == taga[0])
112 if (d[4] != 0 || d[5] != 0 || d[6] != 0 || d[7] != 4)
114 o = d[8] << 24 | d[9] << 16 | d[10] << 8 | d[11];
115 i = d[12] << 24 | d[13] << 16 | d[14] << 8 | d[15];
116 if (o + 4 * i > h->dcnt)
119 r = xmalloc2(i ? i : 1, sizeof(unsigned int));
122 for (o = 0; o < i; o++, d += 4)
123 r[o] = d[0] << 24 | d[1] << 16 | d[2] << 8 | d[3];
128 headint16(struct rpmhead *h, int tag, int *cnt)
130 unsigned int i, o, *r;
131 unsigned char *d, taga[4];
138 for (i = 0; i < h->cnt; i++, d += 16)
139 if (d[3] == taga[3] && d[2] == taga[2] && d[1] == taga[1] && d[0] == taga[0])
143 if (d[4] != 0 || d[5] != 0 || d[6] != 0 || d[7] != 3)
145 o = d[8] << 24 | d[9] << 16 | d[10] << 8 | d[11];
146 i = d[12] << 24 | d[13] << 16 | d[14] << 8 | d[15];
147 if (o + 2 * i > h->dcnt)
150 r = xmalloc2(i ? i : 1, sizeof(unsigned int));
153 for (o = 0; o < i; o++, d += 2)
154 r[o] = d[0] << 8 | d[1];
159 headstring(struct rpmhead *h, int tag)
162 unsigned char *d, taga[4];
168 for (i = 0; i < h->cnt; i++, d += 16)
169 if (d[3] == taga[3] && d[2] == taga[2] && d[1] == taga[1] && d[0] == taga[0])
173 if (d[4] != 0 || d[5] != 0 || d[6] != 0 || d[7] != 6)
175 o = d[8] << 24 | d[9] << 16 | d[10] << 8 | d[11];
176 return (char *)h->dp + o;
180 headstringarray(struct rpmhead *h, int tag, int *cnt)
183 unsigned char *d, taga[4];
191 for (i = 0; i < h->cnt; i++, d += 16)
192 if (d[3] == taga[3] && d[2] == taga[2] && d[1] == taga[1] && d[0] == taga[0])
196 if (d[4] != 0 || d[5] != 0 || d[6] != 0 || d[7] != 8)
198 o = d[8] << 24 | d[9] << 16 | d[10] << 8 | d[11];
199 i = d[12] << 24 | d[13] << 16 | d[14] << 8 | d[15];
200 r = xmalloc2(i ? i : 1, sizeof(char *));
204 for (o = 0; o < i; o++)
208 d += strlen((char *)d) + 1;
209 if (d >= h->dp + h->dcnt)
219 headbin(struct rpmhead *h, int tag, int len)
222 unsigned char *d, taga[4];
228 for (i = 0; i < h->cnt; i++, d += 16)
229 if (d[3] == taga[3] && d[2] == taga[2] && d[1] == taga[1] && d[0] == taga[0])
233 if (d[4] != 0 || d[5] != 0 || d[6] != 0 || d[7] != 7)
235 i = d[12] << 24 | d[13] << 16 | d[14] << 8 | d[15];
238 o = d[8] << 24 | d[9] << 16 | d[10] << 8 | d[11];
239 return (unsigned char *)h->dp + o;
243 headtagtype(struct rpmhead *h, int tag)
246 unsigned char *d, taga[4];
252 for (i = 0; i < h->cnt; i++, d += 16)
253 if (d[3] == taga[3] && d[2] == taga[2] && d[1] == taga[1] && d[0] == taga[0])
254 return d[4] << 24 | d[5] << 16 | d[6] << 8 | d[7];
259 headexpandfilelist(struct rpmhead *h, int *cnt)
262 char **basenames, **dirnames;
264 unsigned int *diridx;
267 filenames = headstringarray(h, TAG_FILENAMES, cnt);
270 basenames = headstringarray(h, TAG_BASENAMES, cnt);
271 dirnames = headstringarray(h, TAG_DIRNAMES, (int *)0);
272 diridx = headint32(h, TAG_DIRINDEXES, (int *)0);
273 if (!basenames || !dirnames || !diridx)
279 for (i = 0; i < *cnt; i++)
280 l += strlen(dirnames[diridx[i]]) + strlen(basenames[i]) + 1;
281 filenames = xmalloc(*cnt * sizeof(char *) + l);
282 cp = (char *)(filenames + *cnt);
283 for (i = 0; i < *cnt; i++)
285 sprintf(cp, "%s%s", dirnames[diridx[i]], basenames[i]);
287 cp += strlen(cp) + 1;
295 char *headtonevr(struct rpmhead *h)
304 name = headstring(h, TAG_NAME);
305 version = headstring(h, TAG_VERSION);
306 release = headstring(h, TAG_RELEASE);
307 epoch = headint32(h, TAG_EPOCH, &epochcnt);
308 if (!name || !version || !release)
310 fprintf(stderr, "headtonevr: bad rpm header\n");
313 if (epoch && epochcnt)
315 char epochbuf[11]; /* 32bit decimal will fit in */
316 sprintf(epochbuf, "%u", *epoch);
317 nevr = xmalloc(strlen(name) + 1 + strlen(epochbuf) + 1 + strlen(version) + 1 + strlen(release) + 1);
318 sprintf(nevr, "%s-%s:%s-%s", name, epochbuf, version, release);
322 nevr = xmalloc(strlen(name) + 1 + strlen(version) + 1 + strlen(release) + 1);
323 sprintf(nevr, "%s-%s-%s", name, version, release);