File: testsync.c

package info (click to toggle)
librecast 0.11.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,760 kB
  • sloc: ansic: 31,144; asm: 28,570; sh: 3,164; makefile: 713; python: 70
file content (86 lines) | stat: -rw-r--r-- 2,704 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* Copyright (c) 2023-2024 Brett Sheffield <bacs@librecast.net> */

#include "../src/config.h"
#define _XOPEN_SOURCE 700 /* for nftw() */
#include <ftw.h>
#include "test.h"
#include "testdata.h"
#include <assert.h>
#include <sys/types.h>
#include <unistd.h>

static char *rsrc, *rdst, *owd;

/* check mode, owner, group, times */
int statcmp_sb(const struct stat *ssb, const struct stat *dsb, const char *dst)
{
	if ((ssb->st_mode & S_IFMT) == S_IFLNK) return 0; /* don't bother with symlinks */
	test_assert(ssb->st_mode == dsb->st_mode, "st_mode: '%s' %o %o", dst, ssb->st_mode, dsb->st_mode);
	test_assert(ssb->st_uid == dsb->st_uid, "st_uid:  '%s'", dst);
	test_assert(ssb->st_gid == dsb->st_gid, "st_gid:  '%s'", dst);
	if ((ssb->st_mode & S_IFMT) != S_IFDIR) {
		/* check size, but not for directories */
		test_assert(ssb->st_size == dsb->st_size, "st_size: '%s'", dst);
	}
#ifndef HAVE_UTIMENSAT
	/* without utimensat(), we only have microsecond precision */
	ssb->st_mtim.tv_nsec /= 1000; ssb->st_mtim.tv_nsec *= 1000;
	ssb->st_atim.tv_nsec /= 1000; ssb->st_atim.tv_nsec *= 1000;
#endif
	/* No point testing atime unless the filesystem is mounted noatime */
	/* test_assert(ssb.st_atim.tv_nsec == dsb.st_atim.tv_nsec, "st_atim: '%s'", dst); */
	test_assert(ssb->st_mtim.tv_nsec == dsb->st_mtim.tv_nsec, "st_mtim: '%s'", dst);
	return 0;
}

/* check mode, owner, group, times */
int statcmp(const char *src, const char *dst)
{
	struct stat ssb, dsb;
	int rc;
	rc = stat(src, &ssb);
	if (!test_assert(rc == 0, "stat '%s'", src)) return -1;
	rc = stat(dst, &dsb);
	if (!test_assert(rc == 0, "stat '%s'", dst)) return -1;
	return statcmp_sb(&ssb, &dsb, dst);
}

static int verify_dst(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
{
	(void) typeflag, (void) ftwbuf;
	struct stat dsb;
	int rc;
	if (chdir(rdst) == -1) return -1;
	rc = stat(fpath, &dsb);
	if (!rc) rc = statcmp_sb(sb, &dsb, fpath);
	if (chdir(rsrc) == -1) return -1;
	return rc;
}

void test_verify_dirs(const char *src, const char *dst)
{
	int n = 0, rc;

	statcmp(src, dst);
	owd = getcwd(NULL, 0);
	assert(owd);
	rsrc = realpath(src, NULL);
	rdst = realpath(dst, NULL);

	test_log("src: %s\n", src);
	test_log("dst: %s\n", dst);
	test_log("rsrc: %s\n", rsrc);
	test_log("rdst: %s\n", rdst);

	if (chdir(rsrc) == -1) goto err_free;
	rc = nftw(".", &verify_dst, 32, 0);
	if (!test_assert(rc == 0, "nftw() returned %i", rc)) goto err_free;
	test_log("%i entries verified\n", n);
	test_assert(test_status == TEST_OK, "source and destination trees match");
	if (chdir(owd) == -1) perror("chdir");

err_free:
	free(rsrc); free(rdst);
	free(owd);
}