2 * Copyright (c) 2009, Novell Inc.
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
22 static unsigned char *
23 decompress(unsigned char *in, int inl, int *outlp)
29 memset(&strm, 0, sizeof(strm));
32 out = sat_malloc(4096);
34 strm.avail_out = 4096;
36 ret = inflateInit2(&strm, -MAX_WBITS);
44 if (strm.avail_out == 0)
47 out = sat_realloc(out, outl + 4096);
48 strm.next_out = out + outl;
49 strm.avail_out = 4096;
51 ret = inflate(&strm, Z_NO_FLUSH);
52 if (ret == Z_STREAM_END)
60 outl += 4096 - strm.avail_out;
67 control2solvable(Solvable *s, char *control)
72 repo_add_debs(Repo *repo, const char **debs, int ndebs, int flags)
74 Pool *pool = repo->pool;
76 unsigned char buf[4096], *bp;
77 int i, l, l2, vlen, clen, ctarlen;
79 unsigned char pkgid[16];
86 if (!(flags & REPO_REUSE_REPODATA))
87 data = repo_add_repodata(repo, 0);
89 data = repo_last_repodata(repo);
90 for (i = 0; i < ndebs; i++)
92 if ((fp = fopen(debs[i], "r")) == 0)
97 if (fstat(fileno(fp), &stb))
102 l = fread(buf, 1, sizeof(buf), fp);
103 if (l < 8 + 60 || strncmp(buf, "!<arch>\ndebian-binary ", 8 + 16) != 0)
105 fprintf(stderr, "%s: not a deb package\n", debs[i]);
109 vlen = atoi(buf + 8 + 48);
110 if (vlen < 0 || vlen > l)
112 fprintf(stderr, "%s: not a deb package\n", debs[i]);
117 if (l < 8 + 60 + vlen + 60)
119 fprintf(stderr, "%s: unhandled deb package\n", debs[i]);
123 if (strncmp(buf + 8 + 60 + vlen, "control.tar.gz ", 16) != 0)
125 fprintf(stderr, "%s: control.tar.gz is not second entry\n", debs[i]);
129 clen = atoi(buf + 8 + 60 + vlen + 48);
132 fprintf(stderr, "%s: control.tar.gz has illegal size\n", debs[i]);
136 ctgz = sat_calloc(1, clen + 4);
137 bp = buf + 8 + 60 + vlen + 60;
138 l -= 8 + 60 + vlen + 60;
145 if (fread(ctgz + l, clen - l, 1, fp) != 1)
147 fprintf(stderr, "%s: unexpected EOF\n", debs[i]);
155 if (flags & DEBS_ADD_WITH_PKGID)
157 void *handle = sat_chksum_create(REPOKEY_TYPE_MD5);
158 sat_chksum_add(handle, ctgz, clen);
159 sat_chksum_free(handle, pkgid);
162 if (ctgz[0] != 0x1f || ctgz[1] != 0x8b)
164 fprintf(stderr, "%s: control.tar.gz is not gzipped\n", debs[i]);
168 if (ctgz[2] != 8 || (ctgz[3] & 0xe0) != 0)
170 fprintf(stderr, "%s: control.tar.gz is compressed in a strange way\n", debs[i]);
175 bp += 6; /* skip time, xflags and OS code */
178 /* skip extra field */
179 l = bp[0] | bp[1] << 8;
181 if (bp >= ctgz + clen)
183 fprintf(stderr, "%s: corrupt gzip\n", debs[i]);
188 if (ctgz[3] & 0x08) /* orig filename */
191 if (ctgz[3] & 0x10) /* file comment */
194 if (ctgz[3] & 0x02) /* header crc */
196 if (bp >= ctgz + clen)
198 fprintf(stderr, "%s: corrupt control.tar.gz\n", debs[i]);
202 ctar = decompress(bp, ctgz + clen - bp, &ctarlen);
206 fprintf(stderr, "%s: corrupt control.tar.gz\n", debs[i]);
215 for (j = 124; j < 124 + 12; j++)
216 if (bp[j] >= '0' && bp[j] <= '7')
217 l2 = l2 * 8 + (bp[j] - '0');
218 if (!strcmp(bp, "./control"))
220 l2 = 512 + ((l2 + 511) & ~511);
224 if (l <= 512 || l - 512 - l2 <= 0 || l2 <= 0)
226 fprintf(stderr, "%s: control.tar.gz contains no ./control file\n", debs[i]);
230 memmove(ctar, bp + 512, l2);
231 ctar = sat_realloc(ctar, l2 + 1);
233 s = pool_id2solvable(pool, repo_add_solvable(repo));
234 control2solvable(s, (char *)ctar);
235 repodata_set_location(data, s - pool->solvables, 0, 0, debs[i]);
236 repodata_set_num(data, s - pool->solvables, SOLVABLE_DOWNLOADSIZE, (unsigned int)((stb.st_size + 1023) / 1024));
238 repodata_set_bin_checksum(data, s - pool->solvables, SOLVABLE_PKGID, REPOKEY_TYPE_MD5, pkgid);
241 if (!(flags & REPO_NO_INTERNALIZE))
242 repodata_internalize(data);
246 main(int argc, const char **argv)
248 Pool *pool = pool_create();
249 Repo *repo = repo_create(pool, "debs2solv");
250 repo_add_debs(repo, argv + 1, argc - 1, DEBS_ADD_WITH_PKGID);
251 repo_write(repo, stdout, 0, 0, 0);