mirror of the now-defunct rocklinux.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

274 lines
7.5 KiB

  1. #!/bin/bash
  2. #
  3. # This shell-script genereates the fl_wrapper.c source file.
  4. cat << EOT
  5. /* ROCK Linux Wrapper for getting a list of created files
  6. *
  7. * --- ROCK-COPYRIGHT-NOTE-BEGIN ---
  8. *
  9. * This copyright note is auto-generated by ./scripts/Create-CopyPatch.
  10. * Please add additional copyright information _after_ the line containing
  11. * the ROCK-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by
  12. * the ./scripts/Create-CopyPatch script. Do not edit this copyright text!
  13. *
  14. * ROCK Linux: rock-src/misc/tools-source/fl_wrapper.c.sh
  15. * ROCK Linux is Copyright (C) 1998 - 2003 Clifford Wolf
  16. *
  17. * This program is free software; you can redistribute it and/or modify
  18. * it under the terms of the GNU General Public License as published by
  19. * the Free Software Foundation; either version 2 of the License, or
  20. * (at your option) any later version. A copy of the GNU General Public
  21. * License can be found at Documentation/COPYING.
  22. *
  23. * Many people helped and are helping developing ROCK Linux. Please
  24. * have a look at http://www.rocklinux.org/ and the Documentation/TEAM
  25. * file for details.
  26. *
  27. * --- ROCK-COPYRIGHT-NOTE-END ---
  28. *
  29. * gcc -Wall -O2 -ldl -shared -o fl_wrapper.so fl_wrapper.c
  30. *
  31. * !!! THIS FILE IS AUTO-GENERATED BY $0 !!!
  32. *
  33. * ELF Dynamic Loading Documentation:
  34. * - http://www.linuxdoc.org/HOWTO/GCC-HOWTO-7.html
  35. * - http://www.educ.umu.se/~bjorn/mhonarc-files/linux-gcc/msg00576.html
  36. * - /usr/include/dlfcn.h
  37. */
  38. /* Headers and prototypes */
  39. #define DEBUG 0
  40. #define DLOPEN_LIBC 1
  41. #define _GNU_SOURCE
  42. #define _REENTRANT
  43. #define open xxx_open
  44. #define open64 xxx_open64
  45. #define mknod xxx_mknod
  46. # include <dlfcn.h>
  47. # include <errno.h>
  48. # include <fcntl.h>
  49. # include <stdio.h>
  50. # include <stdlib.h>
  51. # include <string.h>
  52. # include <sys/stat.h>
  53. # include <sys/types.h>
  54. # include <unistd.h>
  55. # include <utime.h>
  56. # include <stdarg.h>
  57. #undef mknod
  58. #undef open
  59. #undef open64
  60. void * get_dl_symbol(char *);
  61. struct status_t {
  62. ino_t inode;
  63. off_t size;
  64. time_t mtime;
  65. time_t ctime;
  66. };
  67. void handle_file_access_before(const char *, const char *, struct status_t *);
  68. void handle_file_access_after(const char *, const char *, struct status_t *);
  69. /* Wrapper Functions */
  70. EOT
  71. # This has been made with cpp-macros before until they turned to be absolutely
  72. # unreadable ...
  73. #
  74. add_wrapper()
  75. {
  76. line="$( echo "$*" | sed 's/ *, */,/g' )"
  77. old_ifs="$IFS" ; IFS="," ; set $line ; IFS="$old_ifs"
  78. ret_type=$1 ; shift ; function=$1 ; shift
  79. p1="" ; p2="" ; for x ; do p1="$p1$x, " ; done
  80. for x ; do x="${x%%\[\]}" ; p2="$p2${x##* }, " ; done
  81. p1="${p1%, }" ; p2="${p2%, }"
  82. if [ "${function#exec}" = "${function}" ]
  83. then
  84. echo ; cat << EOT
  85. extern $ret_type $function($p1);
  86. $ret_type (*orig_$function)($p1) = NULL;
  87. extern $ret_type $function($p1) {
  88. struct status_t status;
  89. int old_errno=errno;
  90. $ret_type rc;
  91. handle_file_access_before("$function", f, &status);
  92. if (!orig_$function) orig_$function = get_dl_symbol("$function");
  93. errno=old_errno;
  94. #if DEBUG == 1
  95. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original $function() at %p (wrapper is at %p).\n",
  96. getpid(), orig_$function, $function);
  97. #endif
  98. rc = orig_$function($p2);
  99. old_errno=errno;
  100. handle_file_access_after("$function", f, &status);
  101. errno=old_errno;
  102. return rc;
  103. }
  104. EOT
  105. else
  106. echo ; cat << EOT
  107. extern $ret_type $function($p1);
  108. $ret_type (*orig_$function)($p1) = NULL;
  109. extern $ret_type $function($p1) {
  110. int old_errno=errno;
  111. handle_file_access_after("$function", f, NULL);
  112. if (!orig_$function) orig_$function = get_dl_symbol("$function");
  113. errno=old_errno;
  114. return orig_$function($p2);
  115. }
  116. EOT
  117. fi
  118. }
  119. add_wrapper 'int, open, const char* f, int a, int b'
  120. add_wrapper 'int, open64, const char* f, int a, int b'
  121. add_wrapper 'FILE*, fopen, const char* f, const char* g'
  122. add_wrapper 'FILE*, fopen64, const char* f, const char* g'
  123. add_wrapper 'int, creat, const char* f, mode_t m'
  124. add_wrapper 'int, creat64, const char* f, mode_t m'
  125. add_wrapper 'int, mkdir, const char* f, mode_t m'
  126. add_wrapper 'int, mknod, const char* f, mode_t m, dev_t d'
  127. add_wrapper 'int, link, const char* s, const char* f'
  128. add_wrapper 'int, symlink, const char* s, const char* f'
  129. add_wrapper 'int, rename, const char* s, const char* f'
  130. add_wrapper 'int, utime, const char* f, const struct utimbuf* t'
  131. add_wrapper 'int, utimes, const char* f, struct timeval* t'
  132. add_wrapper 'int, execv, const char* f, char* const a[]'
  133. add_wrapper 'int, execve, const char* f, char* const a[], char* const e[]'
  134. echo
  135. cat fl_wrapper_execl.c
  136. echo ; cat << "EOT"
  137. /* Internal Functions */
  138. void * get_dl_symbol(char * symname) {
  139. void * rc;
  140. #if DLOPEN_LIBC
  141. static void * libc_handle = NULL;
  142. if (!libc_handle) libc_handle=dlopen("libc.so.6", RTLD_LAZY);
  143. if (!libc_handle) {
  144. printf("fl_wrapper.so: Can't dlopen libc: %s\n", dlerror());
  145. abort();
  146. }
  147. rc = dlsym(libc_handle, symname);
  148. # if DEBUG == 1
  149. fprintf(stderr, "fl_wrapper.so debug [%d]: Symbol '%s' in libc (%p) has been resolved to %p.\n",
  150. getpid(), symname, libc_handle, rc);
  151. # endif
  152. dlclose(libc_handle);
  153. #else
  154. rc = dlsym(RTLD_NEXT, symname);
  155. # if DEBUG == 1
  156. fprintf(stderr, "fl_wrapper.so debug [%d]: Symbol '%s' (RTLD_NEXT) has been resolved to %p.\n",
  157. getpid(), symname, rc);
  158. # endif
  159. #endif
  160. if (!rc) {
  161. printf("fl_wrapper.so: Can't resolve %s: %s\n",
  162. symname, dlerror());
  163. abort();
  164. }
  165. return rc;
  166. }
  167. void handle_file_access_before(const char * func, const char * file,
  168. struct status_t * status) {
  169. struct stat st;
  170. #if DEBUG == 1
  171. fprintf(stderr, "fl_wrapper.so debug [%d]: begin of handle_file_access_before(\"%s\", \"%s\", xxx)\n",
  172. getpid(), func, file);
  173. #endif
  174. if ( lstat(file,&st) ) {
  175. status->inode=0; status->size=0;
  176. status->mtime=0; status->ctime=0;
  177. } else {
  178. status->inode=st.st_ino; status->size=st.st_size;
  179. status->mtime=st.st_mtime; status->ctime=st.st_ctime;
  180. }
  181. #if DEBUG == 1
  182. fprintf(stderr, "fl_wrapper.so debug [%d]: end of handle_file_access_before(\"%s\", \"%s\", xxx)\n",
  183. getpid(), func, file);
  184. #endif
  185. }
  186. char *wlog = NULL, *rlog = NULL;
  187. void handle_file_access_after(const char * func, const char * file,
  188. struct status_t * status) {
  189. char buf[512], *buf2, *logfile;
  190. char cmdname[512] = "unknown";
  191. int fd; struct stat st;
  192. #if DEBUG == 1
  193. fprintf(stderr, "fl_wrapper.so debug [%d]: begin of handle_file_access_after(\"%s\", \"%s\", xxx)\n",
  194. getpid(), func, file);
  195. #endif
  196. fd=readlink("/proc/self/exe", cmdname, 512);
  197. if (fd < 1) strcpy(cmdname, "unknown");
  198. else cmdname[fd] = 0;
  199. if ( wlog == NULL ) wlog = getenv("FLWRAPPER_WLOG");
  200. if ( rlog == NULL ) rlog = getenv("FLWRAPPER_RLOG");
  201. if ( wlog != NULL && !strcmp(file, wlog) ) return;
  202. if ( rlog != NULL && !strcmp(file, rlog) ) return;
  203. if ( lstat(file, &st) ) return;
  204. if ( (status != NULL) && (status->inode != st.st_ino ||
  205. status->size != st.st_size || status->mtime != st.st_mtime ||
  206. status->ctime != st.st_ctime) ) { logfile = wlog; }
  207. else { logfile = rlog; }
  208. if ( logfile == NULL ) return;
  209. fd=open(logfile,O_APPEND|O_WRONLY,0);
  210. if (fd == -1) return;
  211. if (file[0] == '/') {
  212. sprintf(buf,"%s.%s:\t%s\n",
  213. basename(cmdname), func, file);
  214. } else {
  215. buf2=get_current_dir_name();
  216. sprintf(buf,"%s.%s:\t%s%s%s\n",
  217. basename(cmdname), func, buf2,
  218. strcmp(buf2,"/") ? "/" : "", file);
  219. free(buf2);
  220. }
  221. write(fd,buf,strlen(buf));
  222. close(fd);
  223. #if DEBUG == 1
  224. fprintf(stderr, "fl_wrapper.so debug [%d]: end of handle_file_access_after(\"%s\", \"%s\", xxx)\n",
  225. getpid(), func, file);
  226. #endif
  227. }
  228. EOT