1f08c3bdfSopenharmony_ci/*
2f08c3bdfSopenharmony_ci * Copyright (c) 2012 Cyril Hrubis <chrubis@suse.cz>
3f08c3bdfSopenharmony_ci *
4f08c3bdfSopenharmony_ci * This file is licensed under the GPL license.  For the full content
5f08c3bdfSopenharmony_ci * of this license, see the COPYING file at the top level of this
6f08c3bdfSopenharmony_ci * source tree.
7f08c3bdfSopenharmony_ci */
8f08c3bdfSopenharmony_ci
9f08c3bdfSopenharmony_ci#ifdef __linux__
10f08c3bdfSopenharmony_ci#include <mntent.h>
11f08c3bdfSopenharmony_ci#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
12f08c3bdfSopenharmony_ci#include <sys/param.h>
13f08c3bdfSopenharmony_ci#include <sys/mount.h>
14f08c3bdfSopenharmony_ci#include <errno.h>
15f08c3bdfSopenharmony_ci#include <string.h>
16f08c3bdfSopenharmony_ci#endif
17f08c3bdfSopenharmony_ci#include <stdio.h>
18f08c3bdfSopenharmony_ci#include "posixtest.h"
19f08c3bdfSopenharmony_ci
20f08c3bdfSopenharmony_ci#ifdef __linux__
21f08c3bdfSopenharmony_ci
22f08c3bdfSopenharmony_ci/*
23f08c3bdfSopenharmony_ci * Returns if prefix is prefix of a string and the length of prefix.
24f08c3bdfSopenharmony_ci */
25f08c3bdfSopenharmony_ciint strpref(const char *str, const char *pref)
26f08c3bdfSopenharmony_ci{
27f08c3bdfSopenharmony_ci	int i;
28f08c3bdfSopenharmony_ci
29f08c3bdfSopenharmony_ci	for (i = 0; pref[i] != '\0'; i++) {
30f08c3bdfSopenharmony_ci		/* string ended too soon */
31f08c3bdfSopenharmony_ci		if (str[i] == 0)
32f08c3bdfSopenharmony_ci			return -1;
33f08c3bdfSopenharmony_ci
34f08c3bdfSopenharmony_ci		/* string is diferent */
35f08c3bdfSopenharmony_ci		if (str[i] != pref[i])
36f08c3bdfSopenharmony_ci			return -1;
37f08c3bdfSopenharmony_ci	}
38f08c3bdfSopenharmony_ci
39f08c3bdfSopenharmony_ci	/* returns length of prefix */
40f08c3bdfSopenharmony_ci	return i;
41f08c3bdfSopenharmony_ci}
42f08c3bdfSopenharmony_ci
43f08c3bdfSopenharmony_ci/*
44f08c3bdfSopenharmony_ci * Scans through mounted filesystems and check for longest prefix
45f08c3bdfSopenharmony_ci * contained in path.
46f08c3bdfSopenharmony_ci */
47f08c3bdfSopenharmony_ciint mounted_noatime(const char *path)
48f08c3bdfSopenharmony_ci{
49f08c3bdfSopenharmony_ci	struct mntent *mnt;
50f08c3bdfSopenharmony_ci	int prefix_max = 0, prefix;
51f08c3bdfSopenharmony_ci	int has_noatime = 0;
52f08c3bdfSopenharmony_ci	FILE *f;
53f08c3bdfSopenharmony_ci
54f08c3bdfSopenharmony_ci	f = setmntent("/proc/mounts", "r");
55f08c3bdfSopenharmony_ci
56f08c3bdfSopenharmony_ci	if (f == NULL) {
57f08c3bdfSopenharmony_ci		printf("Couldn't mount /proc/mounts\n");
58f08c3bdfSopenharmony_ci		return -1;
59f08c3bdfSopenharmony_ci	}
60f08c3bdfSopenharmony_ci
61f08c3bdfSopenharmony_ci	while ((mnt = getmntent(f))) {
62f08c3bdfSopenharmony_ci		/* ignore duplicit record for root fs */
63f08c3bdfSopenharmony_ci		if (!strcmp(mnt->mnt_fsname, "rootfs"))
64f08c3bdfSopenharmony_ci			continue;
65f08c3bdfSopenharmony_ci
66f08c3bdfSopenharmony_ci		prefix = strpref(path, mnt->mnt_dir);
67f08c3bdfSopenharmony_ci
68f08c3bdfSopenharmony_ci		if (prefix > prefix_max) {
69f08c3bdfSopenharmony_ci			prefix_max = prefix;
70f08c3bdfSopenharmony_ci			has_noatime = hasmntopt(mnt, "noatime") != NULL;
71f08c3bdfSopenharmony_ci		}
72f08c3bdfSopenharmony_ci	}
73f08c3bdfSopenharmony_ci
74f08c3bdfSopenharmony_ci	return has_noatime;
75f08c3bdfSopenharmony_ci}
76f08c3bdfSopenharmony_ci#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
77f08c3bdfSopenharmony_ciint mounted_noatime(const char *path)
78f08c3bdfSopenharmony_ci{
79f08c3bdfSopenharmony_ci	struct statfs _statfs;
80f08c3bdfSopenharmony_ci
81f08c3bdfSopenharmony_ci	if (statfs(path, &_statfs) == -1) {
82f08c3bdfSopenharmony_ci		printf("statfs for %s failed: %s\n", path, strerror(errno));
83f08c3bdfSopenharmony_ci		return -1;
84f08c3bdfSopenharmony_ci	}
85f08c3bdfSopenharmony_ci
86f08c3bdfSopenharmony_ci	return (_statfs.f_flags & MNT_NOATIME);
87f08c3bdfSopenharmony_ci}
88f08c3bdfSopenharmony_ci#else
89f08c3bdfSopenharmony_ciint mounted_noatime(const char *path PTS_ATTRIBUTE_UNUSED)
90f08c3bdfSopenharmony_ci{
91f08c3bdfSopenharmony_ci	return 0;
92f08c3bdfSopenharmony_ci}
93f08c3bdfSopenharmony_ci#endif
94