আপনি এটি LD_PRELOAD কৌশল ব্যবহার করে করতে পারেন । এখানে এমন একটি বাস্তবায়ন রয়েছে যা কোনও নির্দিষ্ট উপসর্গের সাথে অন্য কোনও স্থানে যাত্রা শুরু করে maps কোডটি গিথুবেও রয়েছে ।
উদাহরণস্বরূপ, আপনি /etc/
রুট না হয়ে কোনও ফাইলের অস্তিত্ব নকল করতে পারেন । এটি নিজস্ব ক্লাউড ক্লায়েন্টের জন্য প্রয়োজনীয় ছিল যা ফাইল /etc/ownCloud/sync-exclude.list
উপস্থিত না থাকলে কাজ করতে অস্বীকার করে work
এটি একটি ডিরেক্টরিকে অন্য ডিরেক্টরিতে ম্যাপ করার জন্য 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 এর মাধ্যমে করা যেতে পারে তবে আমি কোনও বিদ্যমান বাস্তবায়ন জানি না।