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.

841 lines
21 KiB

  1. /* ROCK Linux Wrapper for getting a list of created files
  2. *
  3. * --- ROCK-COPYRIGHT-NOTE-BEGIN ---
  4. *
  5. * This copyright note is auto-generated by ./scripts/Create-CopyPatch.
  6. * Please add additional copyright information _after_ the line containing
  7. * the ROCK-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by
  8. * the ./scripts/Create-CopyPatch script. Do not edit this copyright text!
  9. *
  10. * ROCK Linux: rock-src/misc/tools-source/fl_wrapper.c.sh
  11. * ROCK Linux is Copyright (C) 1998 - 2003 Clifford Wolf
  12. *
  13. * This program is free software; you can redistribute it and/or modify
  14. * it under the terms of the GNU General Public License as published by
  15. * the Free Software Foundation; either version 2 of the License, or
  16. * (at your option) any later version. A copy of the GNU General Public
  17. * License can be found at Documentation/COPYING.
  18. *
  19. * Many people helped and are helping developing ROCK Linux. Please
  20. * have a look at http://www.rocklinux.org/ and the Documentation/TEAM
  21. * file for details.
  22. *
  23. * --- ROCK-COPYRIGHT-NOTE-END ---
  24. *
  25. * gcc -Wall -O2 -ldl -shared -o fl_wrapper.so fl_wrapper.c
  26. *
  27. * !!! THIS FILE IS AUTO-GENERATED BY fl_wrapper.c.sh !!!
  28. *
  29. * ELF Dynamic Loading Documentation:
  30. * - http://www.linuxdoc.org/HOWTO/GCC-HOWTO-7.html
  31. * - http://www.educ.umu.se/~bjorn/mhonarc-files/linux-gcc/msg00576.html
  32. * - /usr/include/dlfcn.h
  33. */
  34. /* Headers and prototypes */
  35. #define DEBUG 0
  36. #define DLOPEN_LIBC 1
  37. #define _GNU_SOURCE
  38. #define _REENTRANT
  39. #define open xxx_open
  40. #define open64 xxx_open64
  41. #define mknod xxx_mknod
  42. # include <dlfcn.h>
  43. # include <errno.h>
  44. # include <fcntl.h>
  45. # include <stdio.h>
  46. # include <stdlib.h>
  47. # include <string.h>
  48. # include <sys/stat.h>
  49. # include <sys/types.h>
  50. # include <unistd.h>
  51. # include <utime.h>
  52. # include <stdarg.h>
  53. #undef mknod
  54. #undef open
  55. #undef open64
  56. void * get_dl_symbol(char *);
  57. struct status_t {
  58. ino_t inode;
  59. off_t size;
  60. time_t mtime;
  61. time_t ctime;
  62. };
  63. void handle_file_access_before(const char *, const char *, struct status_t *);
  64. void handle_file_access_after(const char *, const char *, struct status_t *);
  65. /* Wrapper Functions */
  66. extern int open(const char* f, int a, int b);
  67. int (*orig_open)(const char* f, int a, int b) = NULL;
  68. extern int open(const char* f, int a, int b) {
  69. struct status_t status;
  70. int old_errno=errno;
  71. int rc;
  72. handle_file_access_before("open", f, &status);
  73. if (!orig_open) orig_open = get_dl_symbol("open");
  74. errno=old_errno;
  75. #if DEBUG == 1
  76. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original open() at %p (wrapper is at %p).\n",
  77. getpid(), orig_open, open);
  78. #endif
  79. rc = orig_open(f, a, b);
  80. old_errno=errno;
  81. handle_file_access_after("open", f, &status);
  82. errno=old_errno;
  83. return rc;
  84. }
  85. extern int open64(const char* f, int a, int b);
  86. int (*orig_open64)(const char* f, int a, int b) = NULL;
  87. extern int open64(const char* f, int a, int b) {
  88. struct status_t status;
  89. int old_errno=errno;
  90. int rc;
  91. handle_file_access_before("open64", f, &status);
  92. if (!orig_open64) orig_open64 = get_dl_symbol("open64");
  93. errno=old_errno;
  94. #if DEBUG == 1
  95. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original open64() at %p (wrapper is at %p).\n",
  96. getpid(), orig_open64, open64);
  97. #endif
  98. rc = orig_open64(f, a, b);
  99. old_errno=errno;
  100. handle_file_access_after("open64", f, &status);
  101. errno=old_errno;
  102. return rc;
  103. }
  104. extern FILE* fopen(const char* f, const char* g);
  105. FILE* (*orig_fopen)(const char* f, const char* g) = NULL;
  106. extern FILE* fopen(const char* f, const char* g) {
  107. struct status_t status;
  108. int old_errno=errno;
  109. FILE* rc;
  110. handle_file_access_before("fopen", f, &status);
  111. if (!orig_fopen) orig_fopen = get_dl_symbol("fopen");
  112. errno=old_errno;
  113. #if DEBUG == 1
  114. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original fopen() at %p (wrapper is at %p).\n",
  115. getpid(), orig_fopen, fopen);
  116. #endif
  117. rc = orig_fopen(f, g);
  118. old_errno=errno;
  119. handle_file_access_after("fopen", f, &status);
  120. errno=old_errno;
  121. return rc;
  122. }
  123. extern FILE* fopen64(const char* f, const char* g);
  124. FILE* (*orig_fopen64)(const char* f, const char* g) = NULL;
  125. extern FILE* fopen64(const char* f, const char* g) {
  126. struct status_t status;
  127. int old_errno=errno;
  128. FILE* rc;
  129. handle_file_access_before("fopen64", f, &status);
  130. if (!orig_fopen64) orig_fopen64 = get_dl_symbol("fopen64");
  131. errno=old_errno;
  132. #if DEBUG == 1
  133. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original fopen64() at %p (wrapper is at %p).\n",
  134. getpid(), orig_fopen64, fopen64);
  135. #endif
  136. rc = orig_fopen64(f, g);
  137. old_errno=errno;
  138. handle_file_access_after("fopen64", f, &status);
  139. errno=old_errno;
  140. return rc;
  141. }
  142. extern int creat(const char* f, mode_t m);
  143. int (*orig_creat)(const char* f, mode_t m) = NULL;
  144. extern int creat(const char* f, mode_t m) {
  145. struct status_t status;
  146. int old_errno=errno;
  147. int rc;
  148. handle_file_access_before("creat", f, &status);
  149. if (!orig_creat) orig_creat = get_dl_symbol("creat");
  150. errno=old_errno;
  151. #if DEBUG == 1
  152. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original creat() at %p (wrapper is at %p).\n",
  153. getpid(), orig_creat, creat);
  154. #endif
  155. rc = orig_creat(f, m);
  156. old_errno=errno;
  157. handle_file_access_after("creat", f, &status);
  158. errno=old_errno;
  159. return rc;
  160. }
  161. extern int creat64(const char* f, mode_t m);
  162. int (*orig_creat64)(const char* f, mode_t m) = NULL;
  163. extern int creat64(const char* f, mode_t m) {
  164. struct status_t status;
  165. int old_errno=errno;
  166. int rc;
  167. handle_file_access_before("creat64", f, &status);
  168. if (!orig_creat64) orig_creat64 = get_dl_symbol("creat64");
  169. errno=old_errno;
  170. #if DEBUG == 1
  171. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original creat64() at %p (wrapper is at %p).\n",
  172. getpid(), orig_creat64, creat64);
  173. #endif
  174. rc = orig_creat64(f, m);
  175. old_errno=errno;
  176. handle_file_access_after("creat64", f, &status);
  177. errno=old_errno;
  178. return rc;
  179. }
  180. extern int mkdir(const char* f, mode_t m);
  181. int (*orig_mkdir)(const char* f, mode_t m) = NULL;
  182. extern int mkdir(const char* f, mode_t m) {
  183. struct status_t status;
  184. int old_errno=errno;
  185. int rc;
  186. handle_file_access_before("mkdir", f, &status);
  187. if (!orig_mkdir) orig_mkdir = get_dl_symbol("mkdir");
  188. errno=old_errno;
  189. #if DEBUG == 1
  190. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original mkdir() at %p (wrapper is at %p).\n",
  191. getpid(), orig_mkdir, mkdir);
  192. #endif
  193. rc = orig_mkdir(f, m);
  194. old_errno=errno;
  195. handle_file_access_after("mkdir", f, &status);
  196. errno=old_errno;
  197. return rc;
  198. }
  199. extern int mknod(const char* f, mode_t m, dev_t d);
  200. int (*orig_mknod)(const char* f, mode_t m, dev_t d) = NULL;
  201. extern int mknod(const char* f, mode_t m, dev_t d) {
  202. struct status_t status;
  203. int old_errno=errno;
  204. int rc;
  205. handle_file_access_before("mknod", f, &status);
  206. if (!orig_mknod) orig_mknod = get_dl_symbol("mknod");
  207. errno=old_errno;
  208. #if DEBUG == 1
  209. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original mknod() at %p (wrapper is at %p).\n",
  210. getpid(), orig_mknod, mknod);
  211. #endif
  212. rc = orig_mknod(f, m, d);
  213. old_errno=errno;
  214. handle_file_access_after("mknod", f, &status);
  215. errno=old_errno;
  216. return rc;
  217. }
  218. extern int link(const char* s, const char* f);
  219. int (*orig_link)(const char* s, const char* f) = NULL;
  220. extern int link(const char* s, const char* f) {
  221. struct status_t status;
  222. int old_errno=errno;
  223. int rc;
  224. handle_file_access_before("link", f, &status);
  225. if (!orig_link) orig_link = get_dl_symbol("link");
  226. errno=old_errno;
  227. #if DEBUG == 1
  228. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original link() at %p (wrapper is at %p).\n",
  229. getpid(), orig_link, link);
  230. #endif
  231. rc = orig_link(s, f);
  232. old_errno=errno;
  233. handle_file_access_after("link", f, &status);
  234. errno=old_errno;
  235. return rc;
  236. }
  237. extern int symlink(const char* s, const char* f);
  238. int (*orig_symlink)(const char* s, const char* f) = NULL;
  239. extern int symlink(const char* s, const char* f) {
  240. struct status_t status;
  241. int old_errno=errno;
  242. int rc;
  243. handle_file_access_before("symlink", f, &status);
  244. if (!orig_symlink) orig_symlink = get_dl_symbol("symlink");
  245. errno=old_errno;
  246. #if DEBUG == 1
  247. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original symlink() at %p (wrapper is at %p).\n",
  248. getpid(), orig_symlink, symlink);
  249. #endif
  250. rc = orig_symlink(s, f);
  251. old_errno=errno;
  252. handle_file_access_after("symlink", f, &status);
  253. errno=old_errno;
  254. return rc;
  255. }
  256. extern int rename(const char* s, const char* f);
  257. int (*orig_rename)(const char* s, const char* f) = NULL;
  258. extern int rename(const char* s, const char* f) {
  259. struct status_t status;
  260. int old_errno=errno;
  261. int rc;
  262. handle_file_access_before("rename", f, &status);
  263. if (!orig_rename) orig_rename = get_dl_symbol("rename");
  264. errno=old_errno;
  265. #if DEBUG == 1
  266. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original rename() at %p (wrapper is at %p).\n",
  267. getpid(), orig_rename, rename);
  268. #endif
  269. rc = orig_rename(s, f);
  270. old_errno=errno;
  271. handle_file_access_after("rename", f, &status);
  272. errno=old_errno;
  273. return rc;
  274. }
  275. extern int utime(const char* f, const struct utimbuf* t);
  276. int (*orig_utime)(const char* f, const struct utimbuf* t) = NULL;
  277. extern int utime(const char* f, const struct utimbuf* t) {
  278. struct status_t status;
  279. int old_errno=errno;
  280. int rc;
  281. handle_file_access_before("utime", f, &status);
  282. if (!orig_utime) orig_utime = get_dl_symbol("utime");
  283. errno=old_errno;
  284. #if DEBUG == 1
  285. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original utime() at %p (wrapper is at %p).\n",
  286. getpid(), orig_utime, utime);
  287. #endif
  288. rc = orig_utime(f, t);
  289. old_errno=errno;
  290. handle_file_access_after("utime", f, &status);
  291. errno=old_errno;
  292. return rc;
  293. }
  294. extern int utimes(const char* f, struct timeval* t);
  295. int (*orig_utimes)(const char* f, struct timeval* t) = NULL;
  296. extern int utimes(const char* f, struct timeval* t) {
  297. struct status_t status;
  298. int old_errno=errno;
  299. int rc;
  300. handle_file_access_before("utimes", f, &status);
  301. if (!orig_utimes) orig_utimes = get_dl_symbol("utimes");
  302. errno=old_errno;
  303. #if DEBUG == 1
  304. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original utimes() at %p (wrapper is at %p).\n",
  305. getpid(), orig_utimes, utimes);
  306. #endif
  307. rc = orig_utimes(f, t);
  308. old_errno=errno;
  309. handle_file_access_after("utimes", f, &status);
  310. errno=old_errno;
  311. return rc;
  312. }
  313. extern int execv(const char* f, char* const a[]);
  314. int (*orig_execv)(const char* f, char* const a[]) = NULL;
  315. extern int execv(const char* f, char* const a[]) {
  316. int old_errno=errno;
  317. handle_file_access_after("execv", f, NULL);
  318. if (!orig_execv) orig_execv = get_dl_symbol("execv");
  319. errno=old_errno;
  320. return orig_execv(f, a);
  321. }
  322. extern int execve(const char* f, char* const a[], char* const e[]);
  323. int (*orig_execve)(const char* f, char* const a[], char* const e[]) = NULL;
  324. extern int execve(const char* f, char* const a[], char* const e[]) {
  325. int old_errno=errno;
  326. handle_file_access_after("execve", f, NULL);
  327. if (!orig_execve) orig_execve = get_dl_symbol("execve");
  328. errno=old_errno;
  329. return orig_execve(f, a, e);
  330. }
  331. /*
  332. * Copyright (C) 1991, 92, 94, 97, 98, 99 Free Software Foundation, Inc.
  333. * This file is part of the GNU C Library.
  334. *
  335. * --- NO-ROCK-COPYRIGHT-NOTE ---
  336. *
  337. * glibc-2.2.5/posix/execl.c
  338. */
  339. /* Execute PATH with all arguments after PATH until
  340. a NULL pointer and environment from `environ'. */
  341. int
  342. execl (const char *path, const char *arg, ...)
  343. {
  344. size_t argv_max = 1024;
  345. const char **argv = alloca (argv_max * sizeof (const char *));
  346. unsigned int i;
  347. va_list args;
  348. argv[0] = arg;
  349. va_start (args, arg);
  350. i = 0;
  351. while (argv[i++] != NULL)
  352. {
  353. if (i == argv_max)
  354. {
  355. const char **nptr = alloca ((argv_max *= 2) * sizeof (const char *));
  356. #ifndef _STACK_GROWS_UP
  357. if ((char *) nptr + argv_max == (char *) argv)
  358. {
  359. /* Stack grows down. */
  360. argv = (const char **) memcpy (nptr, argv,
  361. i * sizeof (const char *));
  362. argv_max += i;
  363. }
  364. else
  365. #endif
  366. #ifndef _STACK_GROWS_DOWN
  367. if ((char *) argv + i == (char *) nptr)
  368. /* Stack grows up. */
  369. argv_max += i;
  370. else
  371. #endif
  372. /* We have a hole in the stack. */
  373. argv = (const char **) memcpy (nptr, argv,
  374. i * sizeof (const char *));
  375. }
  376. argv[i] = va_arg (args, const char *);
  377. }
  378. va_end (args);
  379. return execve (path, (char *const *) argv, __environ);
  380. }
  381. /*
  382. * Copyright (C) 1991, 92, 94, 97, 98, 99 Free Software Foundation, Inc.
  383. * This file is part of the GNU C Library.
  384. *
  385. * glibc-2.2.5/posix/execle.c
  386. */
  387. /* Execute PATH with all arguments after PATH until a NULL pointer,
  388. and the argument after that for environment. */
  389. int
  390. execle (const char *path, const char *arg, ...)
  391. {
  392. size_t argv_max = 1024;
  393. const char **argv = alloca (argv_max * sizeof (const char *));
  394. const char *const *envp;
  395. unsigned int i;
  396. va_list args;
  397. argv[0] = arg;
  398. va_start (args, arg);
  399. i = 0;
  400. while (argv[i++] != NULL)
  401. {
  402. if (i == argv_max)
  403. {
  404. const char **nptr = alloca ((argv_max *= 2) * sizeof (const char *));
  405. #ifndef _STACK_GROWS_UP
  406. if ((char *) nptr + argv_max == (char *) argv)
  407. {
  408. /* Stack grows down. */
  409. argv = (const char **) memcpy (nptr, argv,
  410. i * sizeof (const char *));
  411. argv_max += i;
  412. }
  413. else
  414. #endif
  415. #ifndef _STACK_GROWS_DOWN
  416. if ((char *) argv + i == (char *) nptr)
  417. /* Stack grows up. */
  418. argv_max += i;
  419. else
  420. #endif
  421. /* We have a hole in the stack. */
  422. argv = (const char **) memcpy (nptr, argv,
  423. i * sizeof (const char *));
  424. }
  425. argv[i] = va_arg (args, const char *);
  426. }
  427. envp = va_arg (args, const char *const *);
  428. va_end (args);
  429. return execve (path, (char *const *) argv, (char *const *) envp);
  430. }
  431. /*
  432. * Copyright (C) 1991, 92, 94, 97, 98, 99 Free Software Foundation, Inc.
  433. * This file is part of the GNU C Library.
  434. *
  435. * glibc-2.2.5/posix/execlp.c
  436. */
  437. /* Execute FILE, searching in the `PATH' environment variable if
  438. it contains no slashes, with all arguments after FILE until a
  439. NULL pointer and environment from `environ'. */
  440. int
  441. execlp (const char *file, const char *arg, ...)
  442. {
  443. size_t argv_max = 1024;
  444. const char **argv = alloca (argv_max * sizeof (const char *));
  445. unsigned int i;
  446. va_list args;
  447. argv[0] = arg;
  448. va_start (args, arg);
  449. i = 0;
  450. while (argv[i++] != NULL)
  451. {
  452. if (i == argv_max)
  453. {
  454. const char **nptr = alloca ((argv_max *= 2) * sizeof (const char *));
  455. #ifndef _STACK_GROWS_UP
  456. if ((char *) nptr + argv_max == (char *) argv)
  457. {
  458. /* Stack grows down. */
  459. argv = (const char **) memcpy (nptr, argv,
  460. i * sizeof (const char *));
  461. argv_max += i;
  462. }
  463. else
  464. #endif
  465. #ifndef _STACK_GROWS_DOWN
  466. if ((char *) argv + i == (char *) nptr)
  467. /* Stack grows up. */
  468. argv_max += i;
  469. else
  470. #endif
  471. /* We have a hole in the stack. */
  472. argv = (const char **) memcpy (nptr, argv,
  473. i * sizeof (const char *));
  474. }
  475. argv[i] = va_arg (args, const char *);
  476. }
  477. va_end (args);
  478. return execvp (file, (char *const *) argv);
  479. }
  480. /*
  481. * Copyright (C) 1991, 92, 94, 97, 98, 99 Free Software Foundation, Inc.
  482. * This file is part of the GNU C Library.
  483. *
  484. * glibc-2.2.5/posix/execvp.c
  485. */
  486. /* The file is accessible but it is not an executable file. Invoke
  487. the shell to interpret it as a script. */
  488. static void
  489. script_execute (const char *file, char *const argv[])
  490. {
  491. /* Count the arguments. */
  492. int argc = 0;
  493. while (argv[argc++])
  494. ;
  495. /* Construct an argument list for the shell. */
  496. {
  497. char *new_argv[argc + 1];
  498. new_argv[0] = (char *) "/bin/sh";
  499. new_argv[1] = (char *) file;
  500. while (argc > 1)
  501. {
  502. new_argv[argc] = argv[argc - 1];
  503. --argc;
  504. }
  505. /* Execute the shell. */
  506. execve (new_argv[0], new_argv, __environ);
  507. }
  508. }
  509. /* Execute FILE, searching in the `PATH' environment variable if it contains
  510. no slashes, with arguments ARGV and environment from `environ'. */
  511. int
  512. execvp (file, argv)
  513. const char *file;
  514. char *const argv[];
  515. {
  516. if (*file == '\0')
  517. {
  518. /* We check the simple case first. */
  519. errno = ENOENT;
  520. return -1;
  521. }
  522. if (strchr (file, '/') != NULL)
  523. {
  524. /* Don't search when it contains a slash. */
  525. execve (file, argv, __environ);
  526. if (errno == ENOEXEC)
  527. script_execute (file, argv);
  528. }
  529. else
  530. {
  531. int got_eacces = 0;
  532. char *path, *p, *name;
  533. size_t len;
  534. size_t pathlen;
  535. path = getenv ("PATH");
  536. if (path == NULL)
  537. {
  538. /* There is no `PATH' in the environment.
  539. The default search path is the current directory
  540. followed by the path `confstr' returns for `_CS_PATH'. */
  541. len = confstr (_CS_PATH, (char *) NULL, 0);
  542. path = (char *) alloca (1 + len);
  543. path[0] = ':';
  544. (void) confstr (_CS_PATH, path + 1, len);
  545. }
  546. len = strlen (file) + 1;
  547. pathlen = strlen (path);
  548. name = alloca (pathlen + len + 1);
  549. /* Copy the file name at the top. */
  550. name = (char *) memcpy (name + pathlen + 1, file, len);
  551. /* And add the slash. */
  552. *--name = '/';
  553. p = path;
  554. do
  555. {
  556. char *startp;
  557. path = p;
  558. p = strchrnul (path, ':');
  559. if (p == path)
  560. /* Two adjacent colons, or a colon at the beginning or the end
  561. of `PATH' means to search the current directory. */
  562. startp = name + 1;
  563. else
  564. startp = (char *) memcpy (name - (p - path), path, p - path);
  565. /* Try to execute this name. If it works, execv will not return. */
  566. execve (startp, argv, __environ);
  567. if (errno == ENOEXEC)
  568. script_execute (startp, argv);
  569. switch (errno)
  570. {
  571. case EACCES:
  572. /* Record the we got a `Permission denied' error. If we end
  573. up finding no executable we can use, we want to diagnose
  574. that we did find one but were denied access. */
  575. got_eacces = 1;
  576. case ENOENT:
  577. case ESTALE:
  578. case ENOTDIR:
  579. /* Those errors indicate the file is missing or not executable
  580. by us, in which case we want to just try the next path
  581. directory. */
  582. break;
  583. default:
  584. /* Some other error means we found an executable file, but
  585. something went wrong executing it; return the error to our
  586. caller. */
  587. return -1;
  588. }
  589. }
  590. while (*p++ != '\0');
  591. /* We tried every element and none of them worked. */
  592. if (got_eacces)
  593. /* At least one failure was due to permissions, so report that
  594. error. */
  595. errno = EACCES;
  596. }
  597. /* Return the error from the last attempt (probably ENOENT). */
  598. return -1;
  599. }
  600. /* Internal Functions */
  601. void * get_dl_symbol(char * symname) {
  602. void * rc;
  603. #if DLOPEN_LIBC
  604. static void * libc_handle = NULL;
  605. if (!libc_handle) libc_handle=dlopen("libc.so.6", RTLD_LAZY);
  606. if (!libc_handle) {
  607. printf("fl_wrapper.so: Can't dlopen libc: %s\n", dlerror());
  608. abort();
  609. }
  610. rc = dlsym(libc_handle, symname);
  611. # if DEBUG == 1
  612. fprintf(stderr, "fl_wrapper.so debug [%d]: Symbol '%s' in libc (%p) has been resolved to %p.\n",
  613. getpid(), symname, libc_handle, rc);
  614. # endif
  615. dlclose(libc_handle);
  616. #else
  617. rc = dlsym(RTLD_NEXT, symname);
  618. # if DEBUG == 1
  619. fprintf(stderr, "fl_wrapper.so debug [%d]: Symbol '%s' (RTLD_NEXT) has been resolved to %p.\n",
  620. getpid(), symname, rc);
  621. # endif
  622. #endif
  623. if (!rc) {
  624. printf("fl_wrapper.so: Can't resolve %s: %s\n",
  625. symname, dlerror());
  626. abort();
  627. }
  628. return rc;
  629. }
  630. void handle_file_access_before(const char * func, const char * file,
  631. struct status_t * status) {
  632. struct stat st;
  633. #if DEBUG == 1
  634. fprintf(stderr, "fl_wrapper.so debug [%d]: begin of handle_file_access_before(\"%s\", \"%s\", xxx)\n",
  635. getpid(), func, file);
  636. #endif
  637. if ( lstat(file,&st) ) {
  638. status->inode=0; status->size=0;
  639. status->mtime=0; status->ctime=0;
  640. } else {
  641. status->inode=st.st_ino; status->size=st.st_size;
  642. status->mtime=st.st_mtime; status->ctime=st.st_ctime;
  643. }
  644. #if DEBUG == 1
  645. fprintf(stderr, "fl_wrapper.so debug [%d]: end of handle_file_access_before(\"%s\", \"%s\", xxx)\n",
  646. getpid(), func, file);
  647. #endif
  648. }
  649. char *wlog = NULL, *rlog = NULL;
  650. void handle_file_access_after(const char * func, const char * file,
  651. struct status_t * status) {
  652. char buf[512], *buf2, *logfile;
  653. char cmdname[512] = "unknown";
  654. int fd; struct stat st;
  655. #if DEBUG == 1
  656. fprintf(stderr, "fl_wrapper.so debug [%d]: begin of handle_file_access_after(\"%s\", \"%s\", xxx)\n",
  657. getpid(), func, file);
  658. #endif
  659. fd=readlink("/proc/self/exe", cmdname, 512);
  660. if (fd < 1) strcpy(cmdname, "unknown");
  661. else cmdname[fd] = 0;
  662. if ( wlog == NULL ) wlog = getenv("FLWRAPPER_WLOG");
  663. if ( rlog == NULL ) rlog = getenv("FLWRAPPER_RLOG");
  664. if ( wlog != NULL && !strcmp(file, wlog) ) return;
  665. if ( rlog != NULL && !strcmp(file, rlog) ) return;
  666. if ( lstat(file, &st) ) return;
  667. if ( (status != NULL) && (status->inode != st.st_ino ||
  668. status->size != st.st_size || status->mtime != st.st_mtime ||
  669. status->ctime != st.st_ctime) ) { logfile = wlog; }
  670. else { logfile = rlog; }
  671. if ( logfile == NULL ) return;
  672. fd=open(logfile,O_APPEND|O_WRONLY,0);
  673. if (fd == -1) return;
  674. if (file[0] == '/') {
  675. sprintf(buf,"%s.%s:\t%s\n",
  676. basename(cmdname), func, file);
  677. } else {
  678. buf2=get_current_dir_name();
  679. sprintf(buf,"%s.%s:\t%s%s%s\n",
  680. basename(cmdname), func, buf2,
  681. strcmp(buf2,"/") ? "/" : "", file);
  682. free(buf2);
  683. }
  684. write(fd,buf,strlen(buf));
  685. close(fd);
  686. #if DEBUG == 1
  687. fprintf(stderr, "fl_wrapper.so debug [%d]: end of handle_file_access_after(\"%s\", \"%s\", xxx)\n",
  688. getpid(), func, file);
  689. #endif
  690. }