new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / shared / fs_op.c
diff --git a/src/shared/fs_op.c b/src/shared/fs_op.c
new file mode 100755 (executable)
index 0000000..f9c3595
--- /dev/null
@@ -0,0 +1,113 @@
+/* Copyright (C) 2014 Trend Micro Inc.
+ * All rights reserved.
+ *
+ * This program is a free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public
+ * License (version 2) as published by the FSF - Free Software
+ * Foundation
+ */
+
+
+/* Functions to retrieve information about the filesystem
+ */
+
+
+#include "shared.h"
+#ifndef ARGV0
+#define ARGV0 "fs_op"
+#endif
+
+const struct file_system_type network_file_systems[] = {
+    {.name="NFS",  .f_type=0x6969,     .flag=1},
+    {.name="CIFS", .f_type=0xFF534D42, .flag=1},
+
+    /*  The last entry must be name=NULL */
+    {.name=NULL, .f_type=0, .flag=0}
+};
+
+/* List of filesystem to skip the link count test */
+const struct file_system_type skip_file_systems[] = {
+    {.name="BTRFS", .f_type=0x9123683E, .flag=1},
+
+    /*  The last entry must be name=NULL */
+    {.name=NULL, .f_type=0, .flag=0}
+};
+
+short IsNFS(const char *dir_name)
+{
+#if !defined(WIN32) && (defined(Linux) || defined(FreeBSD) || defined(OpenBSD))
+    struct statfs stfs;
+
+    /* ignore NFS (0x6969) or CIFS (0xFF534D42) mounts */
+    if ( ! statfs(dir_name, &stfs) )
+    {
+        int i;
+        for ( i=0; network_file_systems[i].name != NULL; i++ ) {
+#if __OpenBSD__
+            if(strcasecmp(network_file_systems[i].name, stfs.f_fstypename) == 0) {
+#else
+            if(network_file_systems[i].f_type == stfs.f_type ) {
+#endif  // __OpenBSD
+                return network_file_systems[i].flag;
+            }
+        }
+        return(0);
+    }
+    else
+    {
+        /* If the file exists, throw an error and retreat! If the file does not exist, there
+        * is no reason to spam the log with these errors. */
+       if(errno != ENOENT) {
+            merror("ERROR: statfs('%s') produced error: %s", dir_name, strerror(errno));
+       }
+        return(-1);
+    }
+#else
+    verbose(
+        "INFO: Attempted to check NFS status for '%s', but we don't know how on this OS.",
+        dir_name
+    );
+#endif
+    return(0);
+}
+
+short skipFS(const char *dir_name)
+{
+#if !defined(WIN32) && (defined(Linux) || defined(FreeBSD) || defined(OpenBSD))
+    struct statfs stfs;
+
+    if ( ! statfs(dir_name, &stfs) )
+    {
+        int i;
+        for ( i=0; skip_file_systems[i].name != NULL; i++ ) {
+#if __OpenBSD__
+            if(strcasecmp(skip_file_systems[i].name, stfs.f_fstypename) == 0) {
+#else
+            if(skip_file_systems[i].f_type == stfs.f_type ) {
+#endif  // __OpenBSD__
+                debug1("%s: Skipping dir (FS %s): %s ", ARGV0, skip_file_systems[i].name, dir_name);
+                return skip_file_systems[i].flag;
+            }
+        }
+        return(0);
+    }
+    else
+    {
+        /* If the file exists, throw an error and retreat! If the file does not exist, there
+         * is no reason to spam the log with these errors. */
+        if(errno != ENOENT) {
+            merror("ERROR: statfs('%s') produced error: %s", dir_name, strerror(errno));
+        }
+        return(-1);
+    }
+#else
+    verbose(
+        "INFO: Attempted to check FS status for '%s', but we don't know how on this OS.",
+        dir_name
+    );
+#endif
+    return(0);
+}
+
+
+/* EOF */