आप इसे LD_PRELOAD ट्रिक का उपयोग करके कर सकते हैं । यहाँ एक कार्यान्वयन है जो मानचित्रों को एक विशिष्ट उपसर्ग के साथ दूसरे स्थान पर शुरू करता है। कोड भी जीथब पर है ।
उदाहरण के लिए, आप /etc/
रूट किए बिना किसी फ़ाइल के अस्तित्व को नकली बना सकते हैं । यह स्वयं उस क्लाक क्लाइंट के लिए आवश्यक था जो फ़ाइल के /etc/ownCloud/sync-exclude.list
मौजूद न होने पर काम करने से मना कर देता है।
यह ओवरराइडिंग के द्वारा काम करता है open()
और open64()
एक डायरेक्टरी को दूसरे में मैप करने के लिए कार्य करता है , उदाहरण के लिए सभी open()
कॉल्स को /etc/ownCloud/...
रीडायरेक्ट किया जा सकता है /home/user1/.etc/ownCloud/...
।
बस समायोजित करें path_map
, फिर संकलित करें और अपने कार्यक्रम को पहले से लोड किए गए परिवाद के साथ चलाएं:
gcc -std=c99 -Wall -shared -fPIC path-mapping.c -o path-mapping.so -ldl
LD_PRELOAD=/path/to/my/path-mapping.so someprogram
का स्रोत कोड path-mapping.c
:
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <dlfcn.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdarg.h>
#include <malloc.h>
// List of path pairs. Paths beginning with the first item will be
// translated by replacing the matching part with the second item.
static const char *path_map[][2] = {
{ "/etc/ownCloud/", "/home/user1/.etc/ownCloud/" },
};
__thread char *buffer = NULL;
__thread int buffer_size = -1;
typedef FILE* (*orig_fopen_func_type)(const char *path, const char *mode);
typedef int (*orig_open_func_type)(const char *pathname, int flags, ...);
static int starts_with(const char *str, const char *prefix) {
return (strncmp(prefix, str, strlen(prefix)) == 0);
}
static char *get_buffer(int min_size) {
int step = 63;
if (min_size < 1) {
min_size = 1;
}
if (min_size > buffer_size) {
if (buffer != NULL) {
free(buffer);
buffer = NULL;
buffer_size = -1;
}
buffer = malloc(min_size + step);
if (buffer != NULL) {
buffer_size = min_size + step;
}
}
return buffer;
}
static const char *fix_path(const char *path)
{
int count = (sizeof path_map) / (sizeof *path_map); // Array length
for (int i = 0; i < count; i++) {
const char *prefix = path_map[i][0];
const char *replace = path_map[i][1];
if (starts_with(path, prefix)) {
const char *rest = path + strlen(prefix);
char *new_path = get_buffer(strlen(path) + strlen(replace) - strlen(prefix));
strcpy(new_path, replace);
strcat(new_path, rest);
printf("Mapped Path: %s ==> %s\n", path, new_path);
return new_path;
}
}
return path;
}
int open(const char *pathname, int flags, ...)
{
const char *new_path = fix_path(pathname);
orig_open_func_type orig_func;
orig_func = (orig_open_func_type)dlsym(RTLD_NEXT, "open");
// If O_CREAT is used to create a file, the file access mode must be given.
if (flags & O_CREAT) {
va_list args;
va_start(args, flags);
int mode = va_arg(args, int);
va_end(args);
return orig_func(new_path, flags, mode);
} else {
return orig_func(new_path, flags);
}
}
int open64(const char *pathname, int flags, ...)
{
const char *new_path = fix_path(pathname);
orig_open_func_type orig_func;
orig_func = (orig_open_func_type)dlsym(RTLD_NEXT, "open64");
// If O_CREAT is used to create a file, the file access mode must be given.
if (flags & O_CREAT) {
va_list args;
va_start(args, flags);
int mode = va_arg(args, int);
va_end(args);
return orig_func(new_path, flags, mode);
} else {
return orig_func(new_path, flags);
}
}
LD_PRELOAD
साथ या FUSE के माध्यम से किया जा सकता है , लेकिन मुझे कोई मौजूदा कार्यान्वयन नहीं पता है।