fwknop: init script improvements
[feed/packages.git] / admin / debootstrap / files / pkgdetails.c
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
11 char *checksum_field=NULL;
12
13 static void oom_die(void)
14 {
15 fputs("Out of memory!\n", stderr);
16 exit(1);
17 }
18
19 static 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
30 static 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
40 static 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
49 static 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
66 static 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
128 static 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
215 static 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
270 static 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
296 int 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 }