source: packages/admin/debootstrap/files/pkgdetails.c @ 31498

Last change on this file since 31498 was 31498, checked in by luka, 5 years ago

[packages] debootstrap: update to version 1.0.40

Signed-off-by: Daniel Golle <dgolle@…>

File size: 9.6 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <ctype.h>
5#include <stdarg.h>
6#include <errno.h>
7
8#define MAX_LINE 1000
9#define MAX_PKGS 100
10
11char *checksum_field=NULL;
12
13static void oom_die(void)
14{
15    fputs("Out of memory!\n", stderr);
16    exit(1);
17}
18
19static char *xvasprintf(const char *fmt, va_list ap) {
20    char *ret;
21
22    if (vasprintf (&ret, fmt, ap) < 0) {
23        if (errno == ENOMEM)
24            oom_die();
25        return NULL;
26    }
27    return ret;
28}
29
30static char *xasprintf(const char *fmt, ...) {
31    va_list ap;
32    char *ret;
33
34    va_start(ap, fmt);
35    ret = xvasprintf(fmt, ap);
36    va_end(ap);
37    return ret;
38}
39
40static char *fieldcpy(char *dst, char *fld) {
41    while (*fld && *fld != ':') 
42        fld++;
43    if (!*(fld++)) 
44        return NULL;
45    while (isspace(*fld)) fld++;
46    return strcpy(dst, fld);
47}
48
49static void outputdeps(char *deps) {
50    char *pch = deps;
51
52    while (1) {
53        while (isspace(*pch)) pch++;
54        if (!*pch) break;
55
56        while (*pch && *pch != '(' && *pch != '|' && *pch != ','
57               && !isspace(*pch))
58        {
59            fputc(*pch++, stdout);
60        }
61        fputc('\n', stdout);
62        while (*pch && *pch++ != ',') (void)NULL;
63    }
64}
65
66static void dogetdeps(char *pkgsfile, char **in_pkgs, int pkgc) {
67    char buf[MAX_LINE];
68    char cur_pkg[MAX_LINE];
69    char cur_deps[MAX_LINE];
70    char cur_predeps[MAX_LINE];
71    char prev_pkg[MAX_LINE];
72    char *pkgs[MAX_PKGS];
73    int i;
74    int skip;
75    FILE *f;
76    int output_pkg = -1;
77
78    cur_pkg[0] = cur_deps[0] = cur_predeps[0] = prev_pkg[0] = '\0';
79
80    for (i = 0; i < pkgc; i++) pkgs[i] = in_pkgs[i];
81
82    f = fopen(pkgsfile, "r");
83    if (f == NULL) {
84        perror(pkgsfile);
85        exit(1);
86    }
87
88    skip = 1;
89    while (fgets(buf, sizeof(buf), f)) {
90        if (*buf && buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0';
91        if (strncasecmp(buf, "Package:", 8) == 0) {
92            int any = 0;
93            skip = 1;
94            fieldcpy(cur_pkg, buf);
95            if (strcmp(cur_pkg, prev_pkg) != 0) {
96                if (output_pkg != -1)
97                    pkgs[output_pkg] = NULL;
98                if (cur_deps[0])
99                    outputdeps(cur_deps);
100                if (cur_predeps[0])
101                    outputdeps(cur_predeps);
102                strcpy(prev_pkg, cur_pkg);
103            }
104            cur_deps[0] = cur_predeps[0] = '\0';
105            output_pkg = -1;
106            for (i = 0; i < pkgc; i++) {
107                if (!pkgs[i]) continue;
108                any = 1;
109                if (strcmp(cur_pkg, pkgs[i]) == 0) {
110                    skip = 0;
111                    output_pkg = i;
112                    break;
113                }
114            }
115            if (!any) break;
116        } else if (!skip && strncasecmp(buf, "Depends:", 8) == 0)
117            fieldcpy(cur_deps, buf);
118        else if (!skip && strncasecmp(buf, "Pre-Depends:", 12) == 0)
119            fieldcpy(cur_predeps, buf);
120    }
121    if (cur_deps[0])
122        outputdeps(cur_deps);
123    if (cur_predeps[0])
124        outputdeps(cur_predeps);
125    fclose(f);
126}
127
128static void dopkgmirrorpkgs(int uniq, char *mirror, char *pkgsfile, 
129        char *fieldname, char **in_pkgs, int pkgc) 
130{
131    char buf[MAX_LINE];
132    char cur_field[MAX_LINE];
133    char cur_pkg[MAX_LINE];
134    char cur_ver[MAX_LINE];
135    char cur_arch[MAX_LINE];
136    char cur_size[MAX_LINE];
137    char cur_checksum[MAX_LINE];
138    char cur_filename[MAX_LINE];
139    char prev_pkg[MAX_LINE];
140    char *pkgs[MAX_PKGS];
141    int i;
142    FILE *f;
143    char *output = NULL;
144    int output_pkg = -1;
145
146    cur_field[0] = cur_pkg[0] = cur_ver[0] = cur_arch[0] = cur_filename[0] = prev_pkg[0] = '\0';
147
148    for (i = 0; i < pkgc; i++) pkgs[i] = in_pkgs[i];
149
150    f = fopen(pkgsfile, "r");
151    if (f == NULL) {
152        perror(pkgsfile);
153        exit(1);
154    }
155    while (fgets(buf, sizeof(buf), f)) {
156        if (*buf && buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0';
157        if (strncasecmp(buf, fieldname, strlen(fieldname)) == 0) {
158            fieldcpy(cur_field, buf);
159        }
160        if (strncasecmp(buf, "Package:", 8) == 0) {
161            fieldcpy(cur_pkg, buf);
162            if (strcmp(cur_pkg, prev_pkg) != 0) {
163                if (output)
164                    fputs(output, stdout);
165                if (uniq && output_pkg != -1)
166                    pkgs[output_pkg] = NULL;
167                strcpy(prev_pkg, cur_pkg);
168            }
169            free(output);
170            output = NULL;
171            output_pkg = -1;
172        } else if (strncasecmp(buf, "Version:", 8) == 0) {
173            fieldcpy(cur_ver, buf);
174        } else if (strncasecmp(buf, "Architecture:", 13) == 0) {
175            fieldcpy(cur_arch, buf);
176        } else if (strncasecmp(buf, "Size:", 5) == 0) {
177            fieldcpy(cur_size, buf);
178        } else if (strncasecmp(buf, checksum_field, strlen(checksum_field)) == 0
179                   && buf[strlen(checksum_field)] == ':') {
180            fieldcpy(cur_checksum, buf);
181        } else if (strncasecmp(buf, "Filename:", 9) == 0) {
182            fieldcpy(cur_filename, buf);
183        } else if (!*buf) {
184            int any = 0;
185            for (i = 0; i < pkgc; i++) {
186                if (!pkgs[i]) continue;
187                any = 1;
188                if (strcmp(cur_field, pkgs[i]) == 0) {
189                    free(output);
190                    output = xasprintf("%s %s %s %s %s %s %s\n", cur_pkg, cur_ver, cur_arch, mirror, cur_filename, cur_checksum, cur_size);
191                    output_pkg = i;
192                    break;
193                }
194            }
195            if (!any) break;
196            cur_field[0] = '\0';
197        }
198    }
199    if (output)
200        fputs(output, stdout);
201    if (uniq && output_pkg != -1)
202        pkgs[output_pkg] = NULL;
203    fclose(f);
204
205    /* any that weren't found are returned as "pkg -" */
206    if (uniq) {
207        for (i = 0; i < pkgc; i++) {
208            if (pkgs[i]) {
209                printf("%s -\n", pkgs[i]);
210            }
211        }
212    }
213}
214
215static void dopkgstanzas(char *pkgsfile, char **pkgs, int pkgc)
216{
217    char buf[MAX_LINE];
218    char *accum;
219    size_t accum_size = 0, accum_alloc = MAX_LINE * 2;
220    char cur_pkg[MAX_LINE];
221    FILE *f;
222
223    accum = malloc(accum_alloc);
224    if (!accum)
225        oom_die();
226
227    f = fopen(pkgsfile, "r");
228    if (f == NULL) {
229        perror(pkgsfile);
230        free(accum);
231        exit(1);
232    }
233    while (fgets(buf, sizeof(buf), f)) {
234        if (*buf) {
235            size_t len = strlen(buf);
236            if (accum_size + len + 1 > accum_alloc) {
237                accum_alloc = (accum_size + len + 1) * 2;
238                accum = realloc(accum, accum_alloc);
239                if (!accum)
240                    oom_die();
241            }
242            strcpy(accum + accum_size, buf);
243            accum_size += len;
244        }
245        if (*buf && buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0';
246        if (strncasecmp(buf, "Package:", 8) == 0) {
247            fieldcpy(cur_pkg, buf);
248        } else if (!*buf) {
249            int i;
250            for (i = 0; i < pkgc; i++) {
251                if (!pkgs[i]) continue;
252                if (strcmp(cur_pkg, pkgs[i]) == 0) {
253                    fputs(accum, stdout);
254                    if (accum[accum_size - 1] != '\n')
255                        fputs("\n\n", stdout);
256                    else if (accum[accum_size - 2] != '\n')
257                        fputc('\n', stdout);
258                    break;
259                }
260            }
261            *accum = '\0';
262            accum_size = 0;
263        }
264    }
265    fclose(f);
266
267    free(accum);
268}
269
270static int dotranslatewgetpercent(int low, int high, int end, char *str) {
271    int ch;
272    int val, lastval;
273
274    /* print out anything that looks like a % on its own line, appropriately
275     * scaled */
276
277    lastval = val = 0;
278    while ( (ch = getchar()) != EOF ) {
279        if (isdigit(ch)) {
280            val *= 10; val += ch - '0';
281        } else if (ch == '%') {
282            float f = (float) val / 100.0 * (high - low) + low;
283            if (str) {
284                printf("P: %d %d %s\n", (int) f, end, str);
285            } else {
286                printf("P: %d %d\n", (int) f, end);
287            }
288            lastval = val;
289        } else {
290            val = 0;
291        }
292    }
293    return lastval == 100;
294}
295
296int main(int argc, char *argv[]) {
297    checksum_field=getenv("DEBOOTSTRAP_CHECKSUM_FIELD");
298    if (checksum_field == NULL) {
299        checksum_field="MD5sum";
300    }
301
302    if ((argc == 6 || argc == 5) && strcmp(argv[1], "WGET%") == 0) {
303        if (dotranslatewgetpercent(atoi(argv[2]), atoi(argv[3]), 
304                                   atoi(argv[4]), argc == 6 ? argv[5] : NULL))
305        {
306            exit(0);
307        } else {
308            exit(1);
309        }
310    } else if (argc >= 4 && strcmp(argv[1], "GETDEPS") == 0) {
311        int i;
312        for (i = 3; argc - i > MAX_PKGS; i += MAX_PKGS) {
313            dogetdeps(argv[2], argv+i, MAX_PKGS);
314        }
315        dogetdeps(argv[2], argv+i, argc-i);
316        exit(0);
317    } else if (argc >= 5 && strcmp(argv[1], "PKGS") == 0) {
318        int i;
319        for (i = 4; argc - i > MAX_PKGS; i += MAX_PKGS) {
320            dopkgmirrorpkgs(1, argv[2], argv[3], "Package:", argv+i, MAX_PKGS);
321        }
322        dopkgmirrorpkgs(1, argv[2], argv[3], "Package:", argv+i, argc-i);
323        exit(0);
324    } else if (argc >= 6 && strcmp(argv[1], "FIELD") == 0) {
325        int i;
326        for (i = 5; argc - i > MAX_PKGS; i += MAX_PKGS) {
327            dopkgmirrorpkgs(0, argv[3], argv[4], argv[2], argv+i, MAX_PKGS);
328        }
329        dopkgmirrorpkgs(0, argv[3], argv[4], argv[2], argv+i, argc-i);
330        exit(0);
331    } else if (argc >= 4 && strcmp(argv[1], "STANZAS") == 0) {
332        int i;
333        for (i = 3; argc - i > MAX_PKGS; i += MAX_PKGS) {
334            dopkgstanzas(argv[2], argv+i, MAX_PKGS);
335        }
336        dopkgstanzas(argv[2], argv+i, argc-i);
337        exit(0);
338    } else {
339        fprintf(stderr, "usage: %s PKGS mirror packagesfile pkgs..\n", argv[0]);
340        fprintf(stderr, "   or: %s FIELD field mirror packagesfile pkgs..\n", 
341                argv[0]);
342        fprintf(stderr, "   or: %s GETDEPS packagesfile pkgs..\n", argv[0]);
343        fprintf(stderr, "   or: %s STANZAS packagesfile pkgs..\n", argv[0]);
344        fprintf(stderr, "   or: %s WGET%% low high end reason\n", argv[0]);
345        exit(1);
346    }
347}
Note: See TracBrowser for help on using the repository browser.