/* * xstamp - read file names on stdin; for every 32/64-bit XCOFF file (or * XCOFF member of a big archive) print "timdat path[(member)]". */ #include #include #include static unsigned long be32(unsigned char *q) { return ((unsigned long)q[0] << 24) | ((unsigned long)q[1] << 16) | ((unsigned long)q[2] << 8) | q[3]; } static void xcoff(unsigned char *h, char *path, char *mem) { unsigned int magic = (h[0] << 8) | h[1]; if (magic != 0x01DF && magic != 0x01EF && magic != 0x01F7) return; if (mem) printf("%ld %s(%s)\n", (long)be32(h + 4), path, mem); else printf("%ld %s\n", (long)be32(h + 4), path); } static long dec(char *s, int n) { char tmp[32]; memcpy(tmp, s, n); tmp[n] = '\0'; return atol(tmp); } int main(void) { char path[2048], hdr[128], mem[256]; unsigned char x[20]; FILE *fp; long off, namlen; while (fgets(path, sizeof path, stdin)) { path[strcspn(path, "\n")] = '\0'; if ((fp = fopen(path, "r")) == NULL) continue; if (fread(hdr, 1, 128, fp) >= 20) { if (memcmp(hdr, "\n", 8) == 0) { off = dec(hdr + 68, 20); while (off > 0 && fseek(fp, off, SEEK_SET) == 0 && fread(hdr, 1, 112, fp) == 112) { namlen = dec(hdr + 108, 4); if (namlen <= 0 || namlen >= (long)sizeof mem) break; if (fread(mem, 1, namlen, fp) != (size_t)namlen) break; mem[namlen] = '\0'; fseek(fp, off + 112 + namlen + (namlen & 1) + 2, SEEK_SET); if (fread(x, 1, 20, fp) == 20) xcoff(x, path, mem); off = dec(hdr + 20, 20); } } else xcoff((unsigned char *)hdr, path, NULL); } fclose(fp); } return 0; }