-- SB2 preload library interface definition file -- ============================================= -- -- This file defines all symbols that are exported from the SB2 preload -- library. For most symbols, it alse specifies how that symbol (wrapper -- function, typically) should be generated by the interface generator script. -- see gen-interface.pl for details. -- -- Copyright (C) 2007 Lauri T. Aarnio LOGLEVEL: SB_LOGLEVEL_NOISE -- 1. historical constructors/destructors. -- ----------------------------------- -- these seem to be created by ld, and should be exported, although -- most sources now say that these should not be used (instead use -- the __atribute__ things that *are* used by this library) EXPORT: void _init(void) EXPORT: void _fini(void) -- -- 2. exported functions. -- ------------------- -- Functions used by the "sb2show" command: EXPORT: char *sb2show__binary_type__(const char *filename) EXPORT: char *sb2show__map_path2__(const char *binary_name, \ const char *mapping_mode, const char *fn_name, const char *pathname, \ int *readonly) EXPORT: char * sb2show__get_real_cwd__(const char *binary_name, \ const char *fn_name) EXPORT: int sb2show__execve_mods__( \ char *file, \ char *const *orig_argv, char *const *orig_envp, \ char **new_file, char ***new_argv, char ***new_envp) EXPORT: char *sb2__read_string_variable_from_lua__(const char *name) EXPORT: void sb2__load_and_execute_lua_file__(const char *filename) EXPORT: const char *sb2__lua_c_interface_version__(void) EXPORT: void sb2__set_active_exec_policy_name__(const char *name) -- FIXME: The following two functions do not have anything to do with path -- remapping. Instead the implementations in libsb2.c prevent locking of -- the shadow file, which I find really hard to understand. Please explain -- why we should have these wrappers, or should these be removed completely? EXPORT: int lckpwdf (void) EXPORT: int ulckpwdf (void) -- 3. "gates" -- ------- -- Interfaces to functions that are too complex to be generated -- completely by the interface generator. GATE: int execl (const char *path, const char *arg, ...) : pass_va_list GATE: int execle (const char *path, const char *arg, ...) : pass_va_list GATE: int execlp (const char *file, const char *arg, ...) : pass_va_list GATE: int execv (const char *path, char *const argv []) GATE: int execve (const char *filename, char *const argv [], char *const envp[]) GATE: int execvp (const char *file, char *const argv []) GATE: char * getcwd (char *buf, size_t size) : returns_string create_nomap_nolog_version GATE: char * get_current_dir_name (void) : returns_string GATE: char * getwd (char *buf) : returns_string GATE: char *realpath(const char *name, char *resolved) : \ map(name) returns_string GATE: char *__realpath_chk(__const char *__restrict __name, \ char *__restrict __resolved, size_t __resolvedlen) : \ map(__name) returns_string GATE: int uname(struct utsname *buf) #ifdef HAVE_FTS_H GATE: FTS * fts_open (char * const *path_argv, int options, \ int (*compar)(const FTSENT **, const FTSENT **)) #endif GATE: int glob (const char *pattern, int flags, \ int (*errfunc) (const char *, int), glob_t *pglob) : #ifdef HAVE_GLOB64 GATE: int glob64 (const char *pattern, int flags, \ int (*errfunc) (const char *, int), glob64_t *pglob) : #endif -- These gates just log what happened: GATE: void _exit(int status) GATE: void _Exit(int status) -- -- 4. Wrappers where the path is not mapped -- ------------------------------------- -- -- (none currently) -- -- 5. "open()-class": -- --------------- -- These are auto-generated wrappers with varargs: an optional "int mode" -- parameter may be specified in the call. These can be completely handled -- by the generated wrappers. -- #define OPEN_FLAGS_RW_MODE (O_WRONLY|O_RDWR|O_APPEND|O_CREAT|O_TRUNC) WRAP: int __open(const char *pathname, int flags, ...) : \ map(pathname) optional_arg_is_create_mode(flags&O_CREAT) \ postprocess(pathname) \ check_and_fail_if_readonly(flags&OPEN_FLAGS_RW_MODE,pathname,-1,EROFS) WRAP: int __open64(const char *pathname, int flags, ...) : \ map(pathname) optional_arg_is_create_mode(flags&O_CREAT) \ postprocess(pathname) \ check_and_fail_if_readonly(flags&OPEN_FLAGS_RW_MODE,pathname,-1,EROFS) WRAP: int open(const char *pathname, int flags, ...) : \ map(pathname) optional_arg_is_create_mode(flags&O_CREAT) \ postprocess(pathname) \ create_nomap_nolog_version \ check_and_fail_if_readonly(flags&OPEN_FLAGS_RW_MODE,pathname,-1,EROFS) WRAP: int open64(const char *pathname, int flags, ...) : \ map(pathname) optional_arg_is_create_mode(flags&O_CREAT) \ postprocess(pathname) \ check_and_fail_if_readonly(flags&OPEN_FLAGS_RW_MODE,pathname,-1,EROFS) WRAP: int openat(int dirfd, const char *pathname, int flags, ...) : \ map_at(dirfd,pathname) optional_arg_is_create_mode(flags&O_CREAT) \ postprocess(pathname) \ check_and_fail_if_readonly(flags&OPEN_FLAGS_RW_MODE,pathname,-1,EROFS) WRAP: int __openat_2(int dirfd, const char *pathname, int flags) : \ map_at(dirfd,pathname) \ postprocess(pathname) \ check_and_fail_if_readonly(flags&OPEN_FLAGS_RW_MODE,pathname,-1,EROFS) WRAP: int openat64(int dirfd, const char *pathname, int flags, ...) : \ map_at(dirfd,pathname) optional_arg_is_create_mode(flags&O_CREAT) \ postprocess(pathname) \ check_and_fail_if_readonly(flags&OPEN_FLAGS_RW_MODE,pathname,-1,EROFS) WRAP: int close(int fd) : \ postprocess() \ create_nomap_nolog_version -- 5b. other ways to create new filedescriptors: -- we'll wrap these to be able to update fdpathdb WRAP: int dup(int fd) : \ postprocess() WRAP: int dup2(int fd, int fd2) : \ postprocess() -- 3rd parameter of fcntl() and fcntl64() is either a "long" or a -- "struct flock *". However, treat it as "void*"; it is not needed -- by the postprocessor. WRAP: int fcntl(int fd, int cmd, ...) : \ optional_arg_is_void_ptr \ postprocess() WRAP: int fcntl64(int fd, int cmd, ...) : \ optional_arg_is_void_ptr \ postprocess() -- -- 6. Simple wrappers -- --------------- -- WRAP: int __lxstat(int ver, const char *filename, struct stat *buf) : \ dont_resolve_final_symlink map(filename) #ifdef HAVE___LXSTAT64 WRAP: int __lxstat64(int ver, const char *filename, struct stat64 *buf) : \ dont_resolve_final_symlink map(filename) #endif -- N.B. 2nd parameter of '__opendir2' is bufsize, at least on -- some implementations WRAP: DIR *__opendir2(const char *name, int flags) : map(name) WRAP: int __xmknod(int ver, const char *path, mode_t mode, dev_t *dev) : \ dont_resolve_final_symlink map(path) fail_if_readonly(path,-1,EROFS) WRAP: int __xmknodat(int ver, int dirfd, const char *pathname, mode_t mode, dev_t *dev) : \ dont_resolve_final_symlink map_at(dirfd,pathname) fail_if_readonly(pathname,-1,EROFS) WRAP: int __xstat(int ver, const char *filename, struct stat *buf) : map(filename) #ifdef HAVE___XSTAT64 WRAP: int __xstat64(int ver, const char *filename, struct stat64 *buf) : map(filename) #endif #ifdef AT_SYMLINK_NOFOLLOW WRAP: int __fxstatat(int ver, int dirfd, const char *pathname, struct stat *buf, int flags) : \ dont_resolve_final_symlink_if(flags&AT_SYMLINK_NOFOLLOW) \ map_at(dirfd,pathname) WRAP: int __fxstatat64(int ver, int dirfd, const char *pathname, struct stat64 *buf, int flags) : \ dont_resolve_final_symlink_if(flags&AT_SYMLINK_NOFOLLOW) \ map_at(dirfd,pathname) #endif WRAP: int _xftw(int mode, const char *dir, int (*fn)(const char *file, const struct stat *sb, int flag), int nopenfd) : map(dir) #ifdef HAVE__XFTW64 WRAP: int _xftw64(int mode, const char *dir, int (*fn)(const char *file, const struct stat64 *sb, int flag), int nopenfd) : map(dir) #endif WRAP: int access(const char *pathname, int mode) : map(pathname) \ create_nomap_nolog_version \ check_and_fail_if_readonly(mode&W_OK,pathname,-1,EROFS) WRAP: int acct(const char *filename) : \ map(filename) fail_if_readonly(filename,-1,EROFS) WRAP: char *canonicalize_file_name(const char *name) : map(name) returns_string WRAP: int chdir(const char *path) : map(path) #ifdef HAVE_OSX_XATTRS -- chflags is from 4.4BSD, actually. WRAP: int chflags(const char *path, u_int flags) : \ map(path) fail_if_readonly(path,-1,EROFS) #endif WRAP: int chmod(const char *path, mode_t mode) : \ map(path) fail_if_readonly(path,-1,EROFS) WRAP: int chown(const char *path, uid_t owner, gid_t group) : \ map(path) fail_if_readonly(path,-1,EROFS) WRAP: int creat(const char *pathname, mode_t mode) : \ map(pathname) fail_if_readonly(pathname,-1,EROFS) WRAP: int creat64(const char *pathname, mode_t mode) : \ map(pathname) fail_if_readonly(pathname,-1,EROFS) -- dlmopen was introduced in glibc 2.3.4 and not present before that #if __GLIBC__ > 2 || (__GLIBC__ == 2 && (__GLIBC_MINOR__ > 3 || (__GLIBC_MINOR__ == 3 && __GLIBC_PATCHLEVEL__ > 3))) WRAP: void *dlmopen(Lmid_t nsid, const char *filename, int flag) : map(filename) #endif WRAP: void *dlopen(const char *filename, int flag) : map(filename) WRAP: int euidaccess(const char *pathname, int mode) : \ map(pathname) \ check_and_fail_if_readonly(mode&W_OK,pathname,-1,EROFS) -- eaccess() is same as euidaccess(), provided for compatibility WRAP: int eaccess(const char *pathname, int mode) : \ map(pathname) \ check_and_fail_if_readonly(mode&W_OK,pathname,-1,EROFS) #ifdef AT_SYMLINK_NOFOLLOW WRAP: int faccessat(int dirfd, const char *pathname, int mode, int flags) : \ dont_resolve_final_symlink_if(flags&AT_SYMLINK_NOFOLLOW) \ map_at(dirfd,pathname) \ check_and_fail_if_readonly(mode&W_OK,pathname,-1,EROFS) #endif -- FIXME: fchmod() should be handled when -at-functions can be handled -- properly, now just introduce the wrapper (we'll get the calls to logger!) WRAP: int fchmod(int fildes, mode_t mode) #ifdef AT_SYMLINK_NOFOLLOW WRAP: int fchmodat(int dirfd, const char *pathname, mode_t mode, int flags) : \ dont_resolve_final_symlink_if(flags&AT_SYMLINK_NOFOLLOW) \ map_at(dirfd,pathname) \ fail_if_readonly(pathname,-1,EROFS) WRAP: int fchownat(int dirfd, const char *pathname, uid_t owner, gid_t group, \ int flags) : \ dont_resolve_final_symlink_if(flags&AT_SYMLINK_NOFOLLOW) \ map_at(dirfd,pathname) \ fail_if_readonly(pathname,-1,EROFS) #endif WRAP: FILE *fopen(const char *path, const char *mode) : \ map(path) \ check_and_fail_if_readonly(fopen_mode_w_perm(mode),path,NULL,EROFS) WRAP: FILE *fopen64(const char *path, const char *mode) : \ map(path) \ check_and_fail_if_readonly(fopen_mode_w_perm(mode),path,NULL,EROFS) WRAP: FILE *freopen(const char *path, const char *mode, FILE *stream) : \ map(path) \ check_and_fail_if_readonly(fopen_mode_w_perm(mode),path,NULL,freopen_errno(stream)) WRAP: FILE *freopen64(const char *path, const char *mode, FILE *stream) : \ map(path) \ check_and_fail_if_readonly(fopen_mode_w_perm(mode),path,NULL,freopen_errno(stream)) #ifdef AT_SYMLINK_NOFOLLOW WRAP: int fstatat(int dirfd, const char *pathname, struct stat *buf, int flags) : \ dont_resolve_final_symlink_if(flags&AT_SYMLINK_NOFOLLOW) \ map_at(dirfd,pathname) WRAP: int fstatat64(int dirfd, const char *pathname, struct stat64 *buf, int flags) : \ dont_resolve_final_symlink_if(flags&AT_SYMLINK_NOFOLLOW) \ map_at(dirfd,pathname) #endif WRAP: int ftw(const char *dir, int (*fn)(const char *file, const struct stat *sb, int flag), int nopenfd) : map(dir) #ifdef HAVE_FTW64 WRAP: int ftw64(const char *dir, int (*fn)(const char *file, const struct stat64 *sb, int flag), int nopenfd) : map(dir) #endif WRAP: int futimesat(int dirfd, const char *pathname, const struct timeval times[2]) : \ map_at(dirfd,pathname) \ fail_if_readonly(pathname,-1,EROFS) #ifdef HAVE_LINUX_XATTRS WRAP: ssize_t getxattr(const char *path, const char *name, void *value, size_t size) : map(path) #endif #ifdef HAVE_OSX_XATTRS WRAP: int getattrlist(const char* path, void * attrList, \ void * attrBuf, size_t attrBufSize, unsigned long options) : \ map(path) WRAP: ssize_t getxattr(const char *path, const char *name, void *value, size_t size, u_int32_t position, int options) : map(path) #endif EXPORT: int glob_pattern_p(const char *pattern, int quote) WRAP: int lchmod(const char *path, mode_t mode) : \ dont_resolve_final_symlink map(path) fail_if_readonly(path,-1,EROFS) WRAP: int lchown(const char *path, uid_t owner, gid_t group) : \ dont_resolve_final_symlink map(path) fail_if_readonly(path,-1,EROFS) #ifdef HAVE_LGETXATTR WRAP: ssize_t lgetxattr(const char *path, const char *name, void *value, size_t size) : \ dont_resolve_final_symlink map(path) #endif WRAP: int link(const char *oldpath, const char *newpath) : \ map(oldpath) map(newpath) \ fail_if_readonly(oldpath,-1,EROFS) \ fail_if_readonly(newpath,-1,EROFS) WRAP: int linkat(int olddirfd, const char *oldpath, \ int newdirfd, const char *newpath, int flags) : \ map_at(olddirfd,oldpath) map_at(newdirfd,newpath) \ fail_if_readonly(oldpath,-1,EROFS) \ fail_if_readonly(newpath,-1,EROFS) #ifdef HAVE_LISTXATTR #ifdef HAVE_LINUX_XATTRS WRAP: ssize_t listxattr(const char *path, char *list, size_t size) : map(path) #endif #ifdef HAVE_OSX_XATTRS WRAP: ssize_t listxattr(const char *path, char *list, size_t size, int options) : map(path) #endif #endif #ifdef HAVE_LLISTXATTR WRAP: ssize_t llistxattr(const char *path, char *list, size_t size) : \ dont_resolve_final_symlink map(path) #endif #ifdef HAVE_LREMOVEXATTR WRAP: int lremovexattr(const char *path, const char *name) : \ dont_resolve_final_symlink map(path) fail_if_readonly(path,-1,EROFS) #endif #ifdef HAVE_LSETXATTR WRAP: int lsetxattr(const char *path, const char *name, const void *value, size_t size, int flags) : \ dont_resolve_final_symlink map(path) fail_if_readonly(path,-1,EROFS) #endif WRAP: int lstat(const char *file_name, struct stat *buf) : \ dont_resolve_final_symlink map(file_name) #ifdef HAVE_LSTAT64 WRAP: int lstat64(const char *file_name, struct stat64 *buf) : \ dont_resolve_final_symlink map(file_name) #endif WRAP: int lutimes(const char *filename, const struct timeval tv[2]) : \ dont_resolve_final_symlink map(filename) \ fail_if_readonly(filename,-1,EROFS) WRAP: int mkdir(const char *pathname, mode_t mode) : \ map(pathname) fail_if_readonly(pathname,-1,EROFS) \ create_nomap_nolog_version WRAP: int mkdirat(int dirfd, const char *pathname, mode_t mode) : \ map_at(dirfd,pathname) fail_if_readonly(pathname,-1,EROFS) WRAP: int mkfifo(const char *pathname, mode_t mode) : \ map(pathname) fail_if_readonly(pathname,-1,EROFS) WRAP: int mkfifoat(int dirfd, const char *pathname, mode_t mode) : \ map_at(dirfd,pathname) fail_if_readonly(pathname,-1,EROFS) WRAP: int mknod(const char *pathname, mode_t mode, dev_t dev) : \ map(pathname) fail_if_readonly(pathname,-1,EROFS) WRAP: int mknodat(int dirfd, const char *pathname, mode_t mode, dev_t dev) : \ map_at(dirfd,pathname) fail_if_readonly(pathname,-1,EROFS) WRAP: int nftw(const char *dir, int (*fn)(const char *file, const struct stat *sb, int flag, struct FTW *s), int nopenfd, int flags) : map(dir) #ifdef HAVE_NFTW64 WRAP: int nftw64(const char *dir, int (*fn)(const char *file, const struct stat64 *sb, int flag, struct FTW *s), int nopenfd, int flags) : map(dir) #endif WRAP: DIR *opendir(const char *name) : map(name) WRAP: long pathconf(const char *path, int name) : map(path) WRAP: READLINK_TYPE readlink(const char *path, char *buf, size_t bufsize) : \ dont_resolve_final_symlink map(path) WRAP: READLINK_TYPE readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsize) : \ dont_resolve_final_symlink map_at(dirfd,pathname) WRAP: int remove(const char *pathname) : \ map(pathname) fail_if_readonly(pathname,-1,EROFS) #ifdef HAVE_REMOVEXATTR #ifdef HAVE_LINUX_XATTRS WRAP: int removexattr(const char *path, const char *name) : \ map(path) fail_if_readonly(path,-1,EROFS) #endif #ifdef HAVE_OSX_XATTRS WRAP: int removexattr(const char *path, const char *name, int options) : \ map(path) fail_if_readonly(path,-1,EROFS) #endif #endif WRAP: int rename(const char *oldpath, const char *newpath) : \ dont_resolve_final_symlink map(oldpath) \ dont_resolve_final_symlink map(newpath) \ fail_if_readonly(oldpath,-1,EROFS) \ fail_if_readonly(newpath,-1,EROFS) WRAP: int renameat(int olddirfd, const char *oldpath, int newdirfd, \ const char *newpath) : \ dont_resolve_final_symlink map_at(olddirfd,oldpath) \ dont_resolve_final_symlink map_at(newdirfd,newpath) \ fail_if_readonly(oldpath,-1,EROFS) \ fail_if_readonly(newpath,-1,EROFS) WRAP: int revoke(const char *file) : map(file) WRAP: int rmdir(const char *pathname) : \ map(pathname) fail_if_readonly(pathname,-1,EROFS) #ifdef HAVE_SCANDIR #ifdef HAVE_LINUX_SCANDIR WRAP: int scandir(const char *dir, struct dirent ***namelist, \ SCANDIR_TYPE_ARG3, int(*compar)(const void *, const void *)) : \ map(dir) hardcode_param(3,filter) #endif #ifdef HAVE_OSX_SCANDIR WRAP: int scandir(const char *dirname, struct dirent ***namelist, int (*select)(struct dirent *), int (*compar)(const void *, const void *)): map(dirname) #endif #endif #ifdef HAVE_SCANDIR64 WRAP: int scandir64(const char *dir, struct dirent64 ***namelist, \ int(*filter)(const struct dirent64 *), \ int(*compar)(const void *, const void *)) : \ map(dir) #endif #ifdef HAVE_SETXATTR #ifdef HAVE_LINUX_XATTRS WRAP: int setxattr(const char *path, const char *name, const void *value, \ size_t size, int flags) : \ map(path) fail_if_readonly(path,-1,EROFS) #endif #ifdef HAVE_OSX_XATTRS WRAP: int setattrlist(const char* path, void * attrList, \ void * attrBuf, size_t attrBufSize, unsigned long options) : \ map(path) fail_if_readonly(path,-1,EROFS) WRAP: int setxattr(const char *path, const char *name, const void *value, \ size_t size, u_int32_t position, int options) : \ map(path) fail_if_readonly(path,-1,EROFS) #endif #endif WRAP: int stat(const char *file_name, struct stat *buf) : map(file_name) #ifdef HAVE_STAT64 WRAP: int stat64(const char *file_name, struct stat64 *buf) : map(file_name) #endif -- symlink and symlinkat: -- * "oldpath" is the string that will be contents of the symlink, and -- it must not mapped now when SB2 resolves symlinks -- * "newpath" is location where the symlink will be created. WRAP: int symlink(const char *oldpath, const char *newpath) : \ dont_resolve_final_symlink map(newpath) \ fail_if_readonly(newpath,-1,EROFS) \ create_nomap_nolog_version WRAP: int symlinkat(const char *oldpath, int newdirfd, const char *newpath) : \ dont_resolve_final_symlink map_at(newdirfd,newpath) \ fail_if_readonly(newpath,-1,EROFS) WRAP: int truncate(const char *path, off_t length) : \ map(path) fail_if_readonly(path,-1,EROFS) #ifdef HAVE_TRUNCATE64 WRAP: int truncate64(const char *path, off64_t length) : \ map(path) fail_if_readonly(path,-1,EROFS) #endif WRAP: int unlink(const char *pathname) : \ dont_resolve_final_symlink map(pathname) \ fail_if_readonly(pathname,-1,EROFS) WRAP: int unlinkat(int dirfd, const char *pathname, int flags) : \ dont_resolve_final_symlink map_at(dirfd,pathname) \ fail_if_readonly(pathname,-1,EROFS) WRAP: int utime(const char *filename, const struct utimbuf *buf) : \ map(filename) fail_if_readonly(filename,-1,EROFS) WRAP: int utimes(const char *filename, const struct timeval tv[2]) : \ map(filename) fail_if_readonly(filename,-1,EROFS) -- -- 7. Socket API -- ---------- -- Unix domain socket addresses need to be mapped. GATE: int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen) GATE: int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen) -- -- 8. Wrappers, where argument buffer is modified -- ------------------------------------------- -- -- mkdtemp() & mkstemp() return name of the generated filename in "template" WRAP: char *mkdtemp(char *template) : \ map(template) \ postprocess(template) \ fail_if_readonly(template,NULL,EROFS) \ returns_string \ return(ret?template:NULL) WRAP: int mkstemp(char *template) : \ map(template) \ postprocess(template) \ fail_if_readonly(template,-1,EROFS) WRAP: int mkstemp64(char *template) : \ map(template) \ postprocess(template) \ fail_if_readonly(template,-1,EROFS) -- tmpnam(), tempnam() and mktemp() do not create files, they create file names -- that did not exist when the function was called. These need to do path -- mapping when performing the tests.. because of that we need to replace -- these functions completely. GATE: char *tmpnam(char *s) : returns_string GATE: char *tempnam(const char *tmpdir, const char *prefix) : returns_string WRAP: char *mktemp(char *template) : \ map(template) \ postprocess(template) \ returns_string \ return(ret?template:NULL) -- -- 9. Other wrappers (not directly related to path or exec mapping) -- ------------------------------------------------------------- -- -- setrlimit() and setrlimit64(): -- There is a bug in Linux/glibc's ld.so interaction: ld.so segfaults -- when it tries to execute programs "manually" when stack limit -- has been set to infinity. We need to observe setrlimit() and change -- the stack limit back before exec... -- -- [someone who wrote the glibc versions of setrlimit() didn't care -- about X/Open compatibility, first argument of setrmit() is not an "int" -- even if X/Open standard defines so!] #if defined __USE_GNU && !defined __cplusplus #define SETRLIMIT_ARG1_TYPE __rlimit_resource_t #else #define SETRLIMIT_ARG1_TYPE int #endif GATE: int setrlimit(SETRLIMIT_ARG1_TYPE resource, const struct rlimit *rlp) #ifndef __APPLE__ GATE: int setrlimit64(SETRLIMIT_ARG1_TYPE resource, const struct rlimit64 *rlp) #endif -- -- gettext(3) and related message translation functions. -- -- We need to wrap all functions that accept 'domainname' as -- parameter. Normal way of using gettext(3) is -- bindtextdomain("mydomain", "/path/to/locales"); -- textdomain("mydomain"); -- gettext(...); -- -- But we have seen in several applications that bindtextdomain(3) -- and textdomain(3) can be skipped and dcgettext(3) and the like -- functions are used: -- dcgettext("mydomain", ...); -- -- We solve this by wrapping all gettext functions that take domainname -- and call explicitly bindtextdomain(3). This way message catalog -- directories will get mapped to correct place. Are then mapped normally -- using mapping engine and conditional rules based on active exec policy. -- specified in exec_policy as follows: -- -- TODO: should we wrap also plain gettext() and ngettext()? -- GATE: char *bindtextdomain(const char *domainname, const char *dirname) GATE: char *textdomain(const char *domainname) GATE: char *dgettext(const char *domainname, const char *msgid) GATE: char *dcgettext(const char *domainname, const char *msgid, int category) GATE: char *dngettext(const char *domainname, const char *msgid, \ const char *msgid_plural, unsigned long int n) GATE: char *dcngettext(const char *domainname, const char *msgid, \ const char *msgid_plural, unsigned long int n, int category)