/* ** sweep.c -- Sophos Anti-Virus binary RTLD wrapper */ #define CONFIG_OLD "/etc/sav.conf" #define CONFIG_NEW "@l_prefix@/etc/sav/sav.conf" #include #include #include #include #include #include #if defined(PATH_MAX) #define PATH_ADJUST_MAXLEN PATH_MAX #elif defined(MAXPATHLEN) #define PATH_ADJUST_MAXLEN MAXPATHLEN #else #define PATH_ADJUST_MAXLEN 1024 #endif static void path_adjust(char *buf, size_t buflen, const char *path) { size_t pathlen; /* special case first */ if (path == NULL) { buf[0] = '\0'; return; } /* take over path into buffer */ pathlen = strlen(path); if (pathlen > buflen) pathlen = buflen; strncpy(buf, path, pathlen); buf[pathlen] = '\0'; /* apply path adjustments */ if (strcmp(buf, CONFIG_OLD) == 0) strcpy(buf, CONFIG_NEW); return; } #if OPENPKG_FREEBSD #include #include int open(const char *path, int flags, ...) { static int (*func)(const char *, int, ...) = NULL; char path_adjusted[PATH_ADJUST_MAXLEN]; int rv; int mode; va_list ap; /* initially resolve original open(2) function */ if (func == NULL) func = dlsym(RTLD_NEXT, "open"); /* adjust path */ path_adjust(path_adjusted, sizeof(path_adjusted), path); /* execute original function */ if (flags & O_CREAT) { va_start(ap, flags); mode = (int)va_arg(ap, int); rv = func(path_adjusted, flags, mode); va_end(ap); } else rv = func(path_adjusted, flags); /* pass-through return value */ return rv; } /* ----------------------------------------------------------------- */ #elif OPENPKG_LINUX #include #define __USE_GNU #include #undef __USE_GNU #include static int myopen( const char *func_name, int (**func_ptr)(const char *, int, ...), char *buf, size_t buflen, const char *path, int flags, va_list ap) { int rv; int mode; /* initially resolve original open(2) like function */ if (*func_ptr == NULL) { if ((*func_ptr = dlsym(RTLD_NEXT, func_name)) == NULL) { fprintf(stderr, "sweep.so: unable to resolve function \"%s\"\n", func_name); abort(); } } /* adjust path */ path_adjust(buf, buflen, path); /* execute original function */ if (flags & O_CREAT) { mode = (int)va_arg(ap, int); rv = (*func_ptr)(buf, flags, mode); } else rv = (*func_ptr)(buf, flags); /* pass-through return value */ return rv; } #define genstub(name) \ int name(const char *path, int flags, ...) \ { \ static int (*func)(const char *, int, ...) = NULL; \ char path_adjusted[PATH_ADJUST_MAXLEN]; \ va_list ap; \ int rv; \ \ va_start(ap, flags); \ rv = myopen(#name, &func, path_adjusted, sizeof(path_adjusted), path, flags, ap); \ va_end(ap); \ return rv; \ } genstub(open) genstub(open64) genstub(__open) genstub(__open64) genstub(__libc_open) genstub(__libc_open64) #elif OPENPKG_SOLARIS #include #include #include #include int open(const char *path, int flags, ...) { static int (*func)(const char *, int, ...) = NULL; char path_adjusted[PATH_ADJUST_MAXLEN]; int rv; int mode; va_list ap; /* initially resolve original open(2) function */ if (func == NULL) func = dlsym(RTLD_NEXT, "open"); /* adjust path */ path_adjust(path_adjusted, sizeof(path_adjusted), path); /* execute original function */ if (flags & O_CREAT) { va_start(ap, flags); mode = (int)va_arg(ap, int); rv = func(path_adjusted, flags, mode); va_end(ap); } else rv = func(path_adjusted, flags); /* pass-through return value */ return rv; } #endif