pkgdetails.c (9849B)
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 }