lol
1/*
2 * LD_PRELOAD trick to make c3pldrv handle the absolute path to /usr/{bin,lib,share)}.
3 * As c3pldrv is a 32 bit executable, /lib will be rewritten to /lib32.
4 *
5 * Usage:
6 * gcc -shared -fPIC -DOUT="$out" preload.c -o preload.so -ldl
7 * LD_PRELOAD=$PWD/preload.so ./c3pldrv
8 */
9
10#define _GNU_SOURCE
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <unistd.h>
15#include <fcntl.h>
16#include <dlfcn.h>
17#include <limits.h>
18
19#ifndef OUT
20#error Missing OUT define - path to the installation directory.
21#endif
22
23typedef void *(*dlopen_func_t)(const char *filename, int flag);
24typedef int (*open_func_t)(const char *pathname, int flags, ...);
25typedef int (*execv_func_t)(const char *path, char *const argv[]);
26
27
28void *dlopen(const char *filename, int flag)
29{
30 dlopen_func_t orig_dlopen;
31 const char *new_filename;
32 char buffer[PATH_MAX];
33
34 orig_dlopen = (dlopen_func_t)dlsym(RTLD_NEXT, "dlopen");
35
36 new_filename = filename;
37 if (strncmp("/usr/lib", filename, 8) == 0) {
38 snprintf(buffer, PATH_MAX, OUT "/lib32%s", filename+8);
39 buffer[PATH_MAX-1] = '\0';
40 new_filename = buffer;
41 }
42
43 return orig_dlopen(new_filename, flag);
44}
45
46int open(const char *pathname, int flags, ...)
47{
48 open_func_t orig_open;
49 const char *new_pathname;
50 char buffer[PATH_MAX];
51
52 orig_open = (open_func_t)dlsym(RTLD_NEXT, "open");
53
54 new_pathname = pathname;
55 if (strncmp("/usr/share", pathname, 10) == 0) {
56 snprintf(buffer, PATH_MAX, OUT "%s", pathname+4);
57 buffer[PATH_MAX-1] = '\0';
58 new_pathname = buffer;
59 }
60
61 return orig_open(new_pathname, flags);
62}
63
64int execv(const char *path, char *const argv[])
65{
66 execv_func_t orig_execv;
67 const char *new_path;
68 char buffer[PATH_MAX];
69
70 orig_execv = (execv_func_t)dlsym(RTLD_NEXT, "execv");
71
72 new_path = path;
73 if (strncmp("/usr/bin", path, 8) == 0) {
74 snprintf(buffer, PATH_MAX, OUT "%s", path+4);
75 buffer[PATH_MAX-1] = '\0';
76 new_path = buffer;
77 }
78
79 return orig_execv(new_path, argv);
80}
81