nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at python-updates 170 lines 4.8 kB view raw
1/* Brgen4 search for configuration under `/etc/opt/brother/scanner/brscan4`. This 2 LD_PRELOAD library intercepts execvp(), open and open64 calls to redirect them to 3 the corresponding location in $out. Also support specifying an alternate 4 file name for `brsanenetdevice4.cfg` which otherwise is invariable 5 created at `/etc/opt/brother/scanner/brscan4`*/ 6 7#define _GNU_SOURCE 8#include <stdio.h> 9#include <stdarg.h> 10#include <stdlib.h> 11#include <dlfcn.h> 12#include <sys/types.h> 13#include <sys/stat.h> 14#include <fcntl.h> 15#include <limits.h> 16#include <string.h> 17#include <dirent.h> 18 19char origDir [] = "/etc/opt/brother/scanner/brscan4"; 20char realDir [] = OUT "/opt/brother/scanner/brscan4"; 21 22char devCfgFileNameEnvVar [] = "BRSANENETDEVICE4_CFG_FILENAME"; 23char devCfgFileName [] = "/etc/opt/brother/scanner/brscan4//brsanenetdevice4.cfg"; 24 25const char * rewrite(const char * path, char * buf) 26{ 27 if (strncmp(path, devCfgFileName, sizeof(devCfgFileName)) == 0) { 28 29 const char* newCfgFileName = getenv(devCfgFileNameEnvVar); 30 if (!newCfgFileName) return path; 31 32 if (snprintf(buf, PATH_MAX, "%s", newCfgFileName) >= PATH_MAX) 33 abort(); 34 return buf; 35 } 36 37 if (strncmp(path, origDir, sizeof(origDir) - 1) != 0) return path; 38 if (snprintf(buf, PATH_MAX, "%s%s", realDir, path + sizeof(origDir) - 1) >= PATH_MAX) 39 abort(); 40 return buf; 41} 42 43const char* findAndReplaceFirstOccurence(const char* inStr, const char* subStr, 44 const char* replaceStr, 45 char* buf, unsigned maxBuf) 46{ 47 const char* foundStr = strstr(inStr, subStr); 48 if (!foundStr) 49 return inStr; 50 51 const unsigned inStrLen = strlen(inStr); 52 const unsigned subStrLen = strlen(subStr); 53 const unsigned replaceStrLen = strlen(replaceStr); 54 55 const unsigned precedingStrLen = foundStr - inStr; 56 if (precedingStrLen + 1 > maxBuf) 57 return NULL; 58 59 const unsigned followingStrPos = precedingStrLen + subStrLen; 60 const unsigned followingStrLen = inStrLen - followingStrPos; 61 62 strncpy(buf, inStr, precedingStrLen); 63 unsigned outLength = precedingStrLen; 64 65 if (outLength + replaceStrLen + 1 > maxBuf) 66 return NULL; 67 68 strncpy(buf + outLength, replaceStr, replaceStrLen); 69 outLength += replaceStrLen; 70 71 if (outLength + followingStrLen + 1 > maxBuf) 72 return NULL; 73 74 strncpy(buf + outLength, inStr + followingStrPos, followingStrLen); 75 outLength += followingStrLen; 76 77 buf[outLength] = '\0'; 78 79 return buf; 80} 81 82const char* rewriteSystemCall(const char* command, char* buf, unsigned maxBuf) 83{ 84 85 const char* foundStr = strstr(command, devCfgFileName); 86 if (!foundStr) 87 return command; 88 89 const char* replaceStr = getenv(devCfgFileNameEnvVar); 90 if (!replaceStr) return command; 91 92 const char* result = 93 findAndReplaceFirstOccurence(command, devCfgFileName, replaceStr, buf, maxBuf); 94 95 if (!result) 96 abort(); 97 98 return result; 99} 100 101int execvp(const char * path, char * const argv[]) 102{ 103 int (*_execvp) (const char *, char * const argv[]) = dlsym(RTLD_NEXT, "execvp"); 104 char buf[PATH_MAX]; 105 return _execvp(rewrite(path, buf), argv); 106} 107 108 109int open(const char *path, int flags, ...) 110{ 111 char buf[PATH_MAX]; 112 int (*_open) (const char *, int, mode_t) = dlsym(RTLD_NEXT, "open"); 113 mode_t mode = 0; 114 if (flags & O_CREAT) { 115 va_list ap; 116 va_start(ap, flags); 117 mode = va_arg(ap, mode_t); 118 va_end(ap); 119 } 120 return _open(rewrite(path, buf), flags, mode); 121} 122 123int open64(const char *path, int flags, ...) 124{ 125 char buf[PATH_MAX]; 126 int (*_open64) (const char *, int, mode_t) = dlsym(RTLD_NEXT, "open64"); 127 mode_t mode = 0; 128 if (flags & O_CREAT) { 129 va_list ap; 130 va_start(ap, flags); 131 mode = va_arg(ap, mode_t); 132 va_end(ap); 133 } 134 return _open64(rewrite(path, buf), flags, mode); 135} 136 137FILE* fopen(const char* path, const char* mode) 138{ 139 char buf[PATH_MAX]; 140 FILE* (*_fopen) (const char*, const char*) = dlsym(RTLD_NEXT, "fopen"); 141 142 return _fopen(rewrite(path, buf), mode); 143} 144 145FILE *fopen64(const char *path, const char *mode) 146{ 147 char buf[PATH_MAX]; 148 FILE* (*_fopen64) (const char*, const char*) = dlsym(RTLD_NEXT, "fopen64"); 149 150 return _fopen64(rewrite(path, buf), mode); 151} 152 153DIR* opendir(const char* path) 154{ 155 char buf[PATH_MAX]; 156 DIR* (*_opendir) (const char*) = dlsym(RTLD_NEXT, "opendir"); 157 158 return _opendir(rewrite(path, buf)); 159} 160 161#define SYSTEM_CMD_MAX 512 162 163int system(const char *command) 164{ 165 char buf[SYSTEM_CMD_MAX]; 166 int (*_system) (const char*) = dlsym(RTLD_NEXT, "system"); 167 168 const char* newCommand = rewriteSystemCall(command, buf, SYSTEM_CMD_MAX); 169 return _system(newCommand); 170}