DragonFlyBSD Kernel Audit
DF-2955 / fattime_poc.c
← back to finding ↓ download raw
/*
 * fattime_poc.c — set an explicit mtime on a file (utimes(2)) and read it
 * back with stat(2). Used against a mounted msdosfs filesystem to show
 * sys/kern/subr_fattime.c encode/decode defects end-to-end.
 *
 * usage: fattime_poc <path> <tv_sec>
 */
#include <sys/stat.h>
#include <sys/time.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

static void
fmt(long long sec, char *b, size_t l)
{
	time_t t = (time_t)sec;
	struct tm tm;

	gmtime_r(&t, &tm);
	strftime(b, l, "%Y-%m-%d %H:%M:%S", &tm);
}

int
main(int argc, char **argv)
{
	struct timeval tv[2];
	struct stat st;
	long long want;
	char b[64];

	if (argc != 3) {
		fprintf(stderr, "usage: %s path tv_sec\n", argv[0]);
		return (2);
	}
	want = strtoll(argv[2], NULL, 0);

	tv[0].tv_sec = (time_t)want;
	tv[0].tv_usec = 0;
	tv[1] = tv[0];
	if (utimes(argv[1], tv) < 0)
		err(1, "utimes(%s)", argv[1]);

	if (stat(argv[1], &st) < 0)
		err(1, "stat(%s)", argv[1]);

	fmt(want, b, sizeof(b));
	printf("requested : %lld (%s UTC)\n", want, b);
	fmt((long long)st.st_mtime, b, sizeof(b));
	printf("stat mtime: %lld (%s UTC)\n", (long long)st.st_mtime, b);
	if ((long long)st.st_mtime == want) {
		printf("MATCH\n");
		return (0);
	}
	printf("MISMATCH\n");
	return (1);
}