DF-2619 / getdents_dump.c
/* DF-2619: getdents dumper with hexdump of every d_name (leak capture). * DragonFly dirent: d_ino(8) d_namlen(u16@8) d_type(u8@10) .. d_name@16; * advance by _DIRENT_DIRSIZ = (16 + namlen + 1 + 7) & ~7. */ #include <sys/types.h> #include <sys/dirent.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> ssize_t getdents(int, char *, size_t); #define DOFF __offsetof(struct dirent, d_name) int main(int argc, char **argv) { char buf[65536]; int fd; int n; int i; int off; int rec; if (argc != 2) { fprintf(stderr, "usage: getdents_dump <dir>\n"); return 2; } fd = open(argv[1], O_RDONLY); if (fd < 0) { perror("open"); return 1; } for (;;) { n = getdents(fd, buf, sizeof(buf)); if (n <= 0) { printf("getdents rc=%d\n", n); break; } for (off = 0; off < n; off += rec) { struct dirent *de = (struct dirent *)(buf + off); printf("ino=%llu namlen=%u type=%u name=", (unsigned long long)de->d_ino, de->d_namlen, de->d_type); for (i = 0; i < de->d_namlen; ++i) { unsigned char c = (unsigned char)de->d_name[i]; if (c >= 0x20 && c < 0x7f && c != '\\') putchar(c); else if (c == '\\') printf("\\\\"); else printf("\\x%02x", c); } putchar('\n'); if (de->d_namlen > 64) { printf(" hexdump[0..%u]: ", de->d_namlen); for (i = 0; i < de->d_namlen; ++i) printf("%02x", (unsigned char)de->d_name[i]); putchar('\n'); } rec = (DOFF + de->d_namlen + 1 + 7) & ~7; if (rec < 24) rec = 24; } } close(fd); return 0; } |