72 lines
1.8 KiB
C
72 lines
1.8 KiB
C
#include <sys/types.h>
|
|
#include <sys/dirent.h>
|
|
|
|
#include <dirent.h>
|
|
#include <err.h>
|
|
#include <fcntl.h>
|
|
#include <inttypes.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
struct dirent *entry;
|
|
off_t base, before, start;
|
|
char *buffer;
|
|
char *end;
|
|
size_t buffer_size;
|
|
ssize_t bytes;
|
|
int calls, fd;
|
|
|
|
if (argc < 2 || argc > 5)
|
|
errx(2, "usage: %s directory [offset [buffer-size [calls]]]",
|
|
argv[0]);
|
|
start = argc >= 3 ? strtoll(argv[2], NULL, 0) : 0;
|
|
buffer_size = argc >= 4 ? strtoul(argv[3], NULL, 0) : 128;
|
|
calls = argc >= 5 ? strtol(argv[4], NULL, 0) : 32;
|
|
if (buffer_size < 32 || calls < 1)
|
|
errx(2, "invalid buffer size or call count");
|
|
|
|
fd = open(argv[1], O_RDONLY | O_DIRECTORY);
|
|
if (fd < 0)
|
|
err(1, "open %s", argv[1]);
|
|
if (lseek(fd, start, SEEK_SET) < 0)
|
|
err(1, "lseek %jd", (intmax_t)start);
|
|
buffer = malloc(buffer_size);
|
|
if (buffer == NULL)
|
|
err(1, "malloc");
|
|
|
|
for (int call = 0; call < calls; call++) {
|
|
before = lseek(fd, 0, SEEK_CUR);
|
|
if (before < 0)
|
|
err(1, "lseek current");
|
|
base = -1;
|
|
bytes = getdirentries(fd, buffer, buffer_size, &base);
|
|
if (bytes < 0)
|
|
err(1, "getdirentries");
|
|
printf("call=%d before=%jd after=%jd base=%jd bytes=%zd\n",
|
|
call, (intmax_t)before,
|
|
(intmax_t)lseek(fd, 0, SEEK_CUR), (intmax_t)base, bytes);
|
|
if (bytes == 0)
|
|
break;
|
|
end = buffer + bytes;
|
|
for (entry = (struct dirent *)buffer;
|
|
(char *)entry < end;
|
|
entry = (struct dirent *)((char *)entry + entry->d_reclen)) {
|
|
if (entry->d_reclen == 0 ||
|
|
(char *)entry + entry->d_reclen > end)
|
|
errx(1, "invalid dirent record");
|
|
printf(" off=%jd ino=%ju reclen=%u type=%u name=%.*s\n",
|
|
(intmax_t)entry->d_off, (uintmax_t)entry->d_fileno,
|
|
entry->d_reclen, entry->d_type, entry->d_namlen,
|
|
entry->d_name);
|
|
}
|
|
}
|
|
|
|
free(buffer);
|
|
close(fd);
|
|
return (0);
|
|
}
|