- int fdin;
- int fdout;
- FILE *in;
- FILE *out = stdout;
- int rc;
-
- if (argc > 3 || argc < 2) {
- fprintf(stderr, "usage: %s <input> [output]\n", argv[0]);
- return 0;
- }
-
- fdin = open(argv[1], O_RDONLY | O_LARGEFILE);
- if (fdin == -1) {
- fprintf(stderr, "open(%s) failed: %s\n", argv[1],
- strerror(errno));
- return 1;
- }
- in = fdopen(fdin, "r");
- if (in == NULL) {
- fprintf(stderr, "fopen(%s) failed: %s\n", argv[1],
- strerror(errno));
- close(fdin);
- return 1;
- }
- if (argc > 2) {
- fdout = open(argv[2],
- O_CREAT | O_TRUNC | O_WRONLY | O_LARGEFILE,
- 0600);
- if (fdout == -1) {
- fprintf(stderr, "open(%s) failed: %s\n", argv[2],
- strerror(errno));
- fclose(in);
- return 1;
- }
- out = fdopen(fdout, "w");
- if (out == NULL) {
- fprintf(stderr, "fopen(%s) failed: %s\n", argv[2],
- strerror(errno));
- fclose(in);
- close(fdout);
- return 1;
- }
- }
-
- rc = parse_buffer(in, out);
-
- fclose(in);
- if (out != stdout)
- fclose(out);
-
- return rc;
+ struct dbg_line *line;
+ struct ptldebug_header *hdr;
+ char buf[4097];
+ char *ptr;
+ unsigned long dropped = 0;
+ unsigned long kept = 0;
+ unsigned long bad = 0;
+ struct dbg_line **linev = NULL;
+ int linev_len = 0;
+ int rc;
+
+ hdr = (void *)buf;
+
+ while (1) {
+ int first_bad = 1;
+ int count;
+
+ count = HDR_SIZE;
+ ptr = buf;
+readhdr:
+ rc = read(fdin, ptr, count);
+ if (rc <= 0)
+ goto print;
+
+ ptr += rc;
+ count -= rc;
+ if (count > 0)
+ goto readhdr;
+
+ if (hdr->ph_len > 4094 || /* is this header bogus? */
+ hdr->ph_stack > 65536 ||
+ hdr->ph_sec < (1 << 30) ||
+ hdr->ph_usec > 1000000000 ||
+ hdr->ph_line_num > 65536) {
+ if (first_bad)
+ dump_hdr(lseek(fdin, 0, SEEK_CUR), hdr);
+ bad += first_bad;
+ first_bad = 0;
+
+ /* try to restart on next line */
+ while (count < HDR_SIZE && buf[count] != '\n')
+ count++;
+ if (buf[count] == '\n')
+ count++; /* move past '\n' */
+ if (HDR_SIZE - count > 0) {
+ int left = HDR_SIZE - count;
+
+ memmove(buf, buf + count, left);
+ ptr = buf + left;
+
+ goto readhdr;
+ }
+
+ continue;
+ }
+
+ if (hdr->ph_len == 0)
+ continue;
+
+ count = hdr->ph_len - HDR_SIZE;
+readmore:
+ rc = read(fdin, ptr, count);
+ if (rc <= 0)
+ break;
+
+ ptr += rc;
+ count -= rc;
+ if (count > 0)
+ goto readmore;
+
+ first_bad = 1;
+
+ if ((hdr->ph_subsys && !(subsystem_mask & hdr->ph_subsys)) ||
+ (hdr->ph_mask && !(debug_mask & hdr->ph_mask))) {
+ dropped++;
+ continue;
+ }
+
+retry_alloc:
+ line = malloc(sizeof(*line));
+ if (line == NULL) {
+ if (linev) {
+ fprintf(stderr, "error: line malloc(%u): "
+ "printing accumulated records\n",
+ (unsigned int)sizeof(*line));
+ print_rec(&linev, kept, fdout);
+
+ goto retry_alloc;
+ }
+ fprintf(stderr, "error: line malloc(%u): exiting\n",
+ (unsigned int)sizeof(*line));
+ break;
+ }
+
+ line->hdr = malloc(hdr->ph_len + 1);
+ if (line->hdr == NULL) {
+ free(line);
+ if (linev) {
+ fprintf(stderr, "error: hdr malloc(%u): "
+ "printing accumulated records\n",
+ hdr->ph_len + 1);
+ print_rec(&linev, kept, fdout);
+
+ goto retry_alloc;
+ }
+ fprintf(stderr, "error: hdr malloc(%u): exiting\n",
+ hdr->ph_len + 1);
+ break;
+ }
+
+ ptr = (void *)line->hdr;
+ memcpy(line->hdr, buf, hdr->ph_len);
+ ptr[hdr->ph_len] = '\0';
+
+ ptr += sizeof(*hdr);
+ line->file = ptr;
+ ptr += strlen(line->file) + 1;
+ line->fn = ptr;
+ ptr += strlen(line->fn) + 1;
+ line->text = ptr;
+
+retry_add:
+ if (add_rec(line, &linev, &linev_len, kept) < 0) {
+ if (linev) {
+ fprintf(stderr, "error: add_rec[%u] failed; "
+ "print accumulated records\n",
+ linev_len);
+ print_rec(&linev, kept, fdout);
+
+ goto retry_add;
+ }
+ fprintf(stderr, "error: add_rec[0] failed; exiting\n");
+ break;
+ }
+ kept++;
+ }
+
+print:
+ if (linev)
+ print_rec(&linev, kept, fdout);
+
+ printf("Debug log: %lu lines, %lu kept, %lu dropped, %lu bad.\n",
+ dropped + kept + bad, kept, dropped, bad);
+
+ return 0;