16de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis/*
26de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis * Copyright (c) 2012 Cyril Hrubis <chrubis@suse.cz>
36de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis *
46de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis * This file is licensed under the GPL license.  For the full content
56de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis * of this license, see the COPYING file at the top level of this
66de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis * source tree.
76de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis */
86de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis
96de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis#ifdef __linux__
106de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis#include <mntent.h>
114d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
124d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper#include <sys/param.h>
134d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper#include <sys/mount.h>
144d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper#include <errno.h>
154d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper#include <string.h>
164d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper#endif
174d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper#include <stdio.h>
184d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper
194d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper#ifdef __linux__
206de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis
216de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis/*
224d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper * Returns if prefix is prefix of a string and the length of prefix.
236de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis */
246de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubisint strpref(const char *str, const char *pref)
256de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis{
266de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis	int i;
276de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis
286de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis	for (i = 0; pref[i] != '\0'; i++) {
296de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis		/* string ended too soon */
306de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis		if (str[i] == 0)
316de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis			return -1;
321c84cdb09319a8ca80ee59fb886cc3532846a0e6Cyril Hrubis
336de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis		/* string is diferent */
346de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis		if (str[i] != pref[i])
356de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis			return -1;
366de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis	}
376de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis
384d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper	/* returns length of prefix */
396de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis	return i;
406de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis}
416de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis
426de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis/*
436de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis * Scans through mounted filesystems and check for longest prefix
446de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis * contained in path.
456de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis */
466de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubisint mounted_noatime(const char *path)
476de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis{
486de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis	struct mntent *mnt;
494ba1c46742f4b272d14b042a8e286a1a518f539fCyril Hrubis	int prefix_max = 0, prefix;
506de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis	int has_noatime;
516de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis	FILE *f;
521c84cdb09319a8ca80ee59fb886cc3532846a0e6Cyril Hrubis
531c84cdb09319a8ca80ee59fb886cc3532846a0e6Cyril Hrubis	f = setmntent("/proc/mounts", "r");
546de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis
556de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis	if (f == NULL) {
566de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis		printf("Couldn't mount /proc/mounts\n");
576de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis		return -1;
586de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis	}
596de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis
604ba1c46742f4b272d14b042a8e286a1a518f539fCyril Hrubis	while ((mnt = getmntent(f))) {
611c84cdb09319a8ca80ee59fb886cc3532846a0e6Cyril Hrubis		/* ignore duplicit record for root fs */
621c84cdb09319a8ca80ee59fb886cc3532846a0e6Cyril Hrubis		if (!strcmp(mnt->mnt_fsname, "rootfs"))
636de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis			continue;
641c84cdb09319a8ca80ee59fb886cc3532846a0e6Cyril Hrubis
656de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis		prefix = strpref(path, mnt->mnt_dir);
666de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis
676de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis		if (prefix > prefix_max) {
686de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis			prefix_max = prefix;
696de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis			has_noatime = hasmntopt(mnt, "noatime") != NULL;
706de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis		}
716de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis	}
726de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis
736de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis	return has_noatime;
744d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper}
754d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
764d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooperint mounted_noatime(const char *path)
774d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper{
784d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper	struct statfs _statfs;
794d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper
804d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper	if (statfs(path, &_statfs) == -1) {
814d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper		printf("statfs for %s failed: %s", strerror(errno));
824d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper		return -1;
834d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper	}
844d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper
854d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper	return (_statfs.f_flags & MNT_NOATIME);
864d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper}
876de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis#else
884d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooperint mounted_noatime(const char *path)
894d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper{
906de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis	return 0;
916de744ecba6043f5fb79f618bdea3592d006f31dCyril Hrubis}
924d1552df78b4a6d69b77e97d0f3ef7371c80c7f8Garrett Cooper#endif
93