projects/aports·blob 3.7.0_rc1 · refs

106 lines · 2.1 KiB

1#include <stdio.h>
2#include <err.h>
3#include <fcntl.h>
4#include <string.h>
5#include <unistd.h>
6
7#include <zlib.h>
8
9static int find_section(const char *buf, size_t bufsize, const char *str) {
10 int len = strlen(str);
11 const char *p;
12
13 if (len >= bufsize) return 0;
14
15 p = strrchr(buf, '/');
16 if (p++ == NULL) p = buf;
17 return strncmp(p, str, len) == 0;
18}
19
20int main(void)
21{
22 char obuf[8*1024], ibuf[8*1024];
23 z_stream zs;
24 int r = Z_OK, rc = 1, fd = -1;
25 size_t len;
26
27 if (inflateInit2(&zs, 15+32) != Z_OK)
28 goto err;
29
30 zs.avail_out = sizeof obuf;
31 zs.next_out = (Bytef *)obuf;
32
33 while (1) {
34 const char *fn = NULL;
35
36 if (zs.avail_in == 0) {
37 zs.avail_in = read(STDIN_FILENO, ibuf, sizeof ibuf);
38 zs.next_in = (Bytef *)ibuf;
39 if (zs.avail_in < 0) {
40 warn("Failed to read input");
41 goto err;
42 }
43 if (zs.avail_in == 0 && r == Z_STREAM_END) goto ok;
44 }
45
46 r = inflate(&zs, Z_NO_FLUSH);
47 if (r != Z_OK && r != Z_STREAM_END) {
48 warnx("Failed to inflate input");
49 goto err;
50 }
51
52 len = sizeof obuf - zs.avail_out;
53 if (len) {
54 if (fd < 0) {
55 const char *fn;
56
57 if (find_section(obuf, len, ".SIGN."))
58 fn = "signatures.tar.gz";
59 else if (find_section(obuf, len, ".PKGINFO"))
60 fn = "control.tar.gz";
61 else if (rc == 1)
62 fn = "data.tar.gz", rc = 2;
63 else {
64 warnx("Failed to find .PKGINFO section");
65 goto err;
66 }
67 fd = open(fn, O_CREAT|O_TRUNC|O_WRONLY, 0777);
68 if (fd < 0) {
69 warn("Failed to open %s", fn);
70 goto err;
71 }
72 }
73 zs.next_out = (Bytef *)obuf;
74 zs.avail_out = sizeof obuf;
75 }
76
77 if (zs.avail_in == 0 || r == Z_STREAM_END) {
78 len = (void *)zs.next_in - (void *)ibuf;
79 if (write(fd, ibuf, len) != len) {
80 warn("Failed to write to %s", fn);
81 goto err;
82 }
83 memmove(ibuf, zs.next_in, zs.avail_in);
84 zs.next_in = (Bytef *)ibuf;
85 }
86
87 if (r == Z_STREAM_END) {
88 if (fd >= 0) {
89 close(fd);
90 fd = -1;
91 }
92 inflateEnd(&zs);
93 if (inflateInit2(&zs, 15+32) != Z_OK) {
94 warnx("inflateInit2 failed");
95 goto err;
96 }
97 }
98 }
99ok:
100 rc = 0;
101err:
102 if (fd >= 0) close(fd);
103 inflateEnd(&zs);
104 return rc;
105}
106