You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

348 lines
9.6 KiB

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