/* DF-2756: read() on a directory fd -> raw on-disk directory blocks (UFS) */
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
int main(int argc, char **argv) {
    const char *path = argc > 1 ? argv[1] : "/boot";
    int fd = open(path, O_RDONLY);
    if (fd < 0) { perror("open"); return 1; }
    char buf[65536];
    ssize_t n = read(fd, buf, sizeof(buf));
    printf("read(%s) = %zd errno=%d\n", path, n, n < 0 ? errno : 0);
    if (n > 0) {
        /* dump first 2 dirent slots raw */
        unsigned char *p = (unsigned char*)buf;
        for (int i = 0; i < 4 && (i+1)*16 <= n; i++) {
            printf("dirent[%d] raw 16 bytes:", i);
            for (int j = 0; j < 16; j++) printf(" %02x", p[i*16+j]);
            printf("\n");
        }
        /* parse UFS dirents: u_char d_type; u_char d_namlen; u_short d_reclen; */
        long off = 0;
        int cnt = 0;
        while (off + 8 <= n && cnt < 12) {
            unsigned char *d = (unsigned char*)buf + off;
            unsigned short reclen = d[2] | (d[3] << 8);
            unsigned char namlen = d[1];
            if (reclen < 8 || off + reclen > n) { printf("bad reclen %u at %ld\n", reclen, off); break; }
            char name[256];
            int cp = namlen < 255 ? namlen : 255;
            memcpy(name, d+8, cp); name[cp] = 0;
            printf("dirent off=%ld reclen=%u namlen=%u name='%s'\n", off, reclen, namlen, name);
            /* slack bytes between name end and next entry */
            int used = 8 + ((cp + 1 + 3) & ~3);
            if (reclen > used && reclen - used >= 4) {
                printf("  slack (%d bytes):", reclen - used);
                for (int j = used; j < reclen && j < used + 24; j++) printf(" %02x", d[j]);
                printf("\n");
            }
            off += reclen; cnt++;
        }
    }
    close(fd);
    return 0;
}
