Merge branch 'collectd-5.8'
[collectd.git] / contrib / docker / rootfs_prefix / rootfs_prefix.c
1 /**
2  * collectd - contrib/docker/rootfs_prefix/rootfs_prefix.c
3  * Copyright (C) 2016-2018  Marc Fournier
4  * Copyright (C) 2016-2018  Ruben Kerkhof
5  *
6  * MIT License:
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24  * DEALINGS IN THE SOFTWARE.
25  *
26  * Authors:
27  *   Marc Fournier <marc.fournier at camptocamp.com>
28  *   Ruben Kerkhof <ruben at rubenkerkhof.com>
29  **/
30
31 #define _GNU_SOURCE
32
33 #include <dirent.h>
34 #include <dlfcn.h>
35 #include <errno.h>
36 #include <error.h>
37 #include <stdio.h>
38 #include <string.h>
39
40 #define PREFIX "/rootfs"
41 #define BUFSIZE 256
42
43 const char *add_prefix(const char *orig, char *prefixed) {
44   if ((strncmp(orig, "/proc", strlen("/proc")) != 0) &&
45       (strncmp(orig, "/sys", strlen("/sys")) != 0))
46     return orig;
47
48   int status = snprintf(prefixed, BUFSIZE, "%s%s", PREFIX, orig);
49   if (status < 1) {
50     error(status, errno, "adding '%s' prefix to file path failed: '%s' -> '%s'",
51           PREFIX, orig, prefixed);
52     return orig;
53   } else if ((unsigned int)status >= BUFSIZE) {
54     error(status, ENAMETOOLONG,
55           "'%s' got truncated when adding '%s' prefix: '%s'", orig, PREFIX,
56           prefixed);
57     return orig;
58   } else {
59     return (const char *)prefixed;
60   }
61 }
62
63 FILE *fopen(const char *path, const char *mode) {
64   char filename[BUFSIZE] = "\0";
65
66   FILE *(*original_fopen)(const char *, const char *);
67   original_fopen = dlsym(RTLD_NEXT, "fopen");
68
69   return (*original_fopen)(add_prefix(path, filename), mode);
70 }
71
72 DIR *opendir(const char *name) {
73   char filename[BUFSIZE] = "\0";
74
75   DIR *(*original_opendir)(const char *);
76   original_opendir = dlsym(RTLD_NEXT, "opendir");
77
78   return (*original_opendir)(add_prefix(name, filename));
79 }
80
81 int *open(const char *pathname, int flags) {
82   char filename[BUFSIZE] = "\0";
83
84   int *(*original_open)(const char *, int);
85   original_open = dlsym(RTLD_NEXT, "open");
86
87   return (*original_open)(add_prefix(pathname, filename), flags);
88 }