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.

934 lines
22 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. static 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. static void handle_file_access_before(const char *, const char *, struct status_t *);
  64. static void handle_file_access_after(const char *, const char *, struct status_t *);
  65. char *wlog = 0, *rlog = 0, *cmdname = "unkown";
  66. /* Wrapper Functions */
  67. extern int open(const char* f, int a, int b);
  68. int (*orig_open)(const char* f, int a, int b) = 0;
  69. int open(const char* f, int a, int b)
  70. {
  71. struct status_t status;
  72. int old_errno=errno;
  73. int rc;
  74. handle_file_access_before("open", f, &status);
  75. if (!orig_open) orig_open = get_dl_symbol("open");
  76. errno=old_errno;
  77. #if DEBUG == 1
  78. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original open() at %p (wrapper is at %p).\n",
  79. getpid(), orig_open, open);
  80. #endif
  81. rc = orig_open(f, a, b);
  82. old_errno=errno;
  83. handle_file_access_after("open", f, &status);
  84. errno=old_errno;
  85. return rc;
  86. }
  87. extern int open64(const char* f, int a, int b);
  88. int (*orig_open64)(const char* f, int a, int b) = 0;
  89. int open64(const char* f, int a, int b)
  90. {
  91. struct status_t status;
  92. int old_errno=errno;
  93. int rc;
  94. handle_file_access_before("open64", f, &status);
  95. if (!orig_open64) orig_open64 = get_dl_symbol("open64");
  96. errno=old_errno;
  97. #if DEBUG == 1
  98. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original open64() at %p (wrapper is at %p).\n",
  99. getpid(), orig_open64, open64);
  100. #endif
  101. rc = orig_open64(f, a, b);
  102. old_errno=errno;
  103. handle_file_access_after("open64", f, &status);
  104. errno=old_errno;
  105. return rc;
  106. }
  107. extern FILE* fopen(const char* f, const char* g);
  108. FILE* (*orig_fopen)(const char* f, const char* g) = 0;
  109. FILE* fopen(const char* f, const char* g)
  110. {
  111. struct status_t status;
  112. int old_errno=errno;
  113. FILE* rc;
  114. handle_file_access_before("fopen", f, &status);
  115. if (!orig_fopen) orig_fopen = get_dl_symbol("fopen");
  116. errno=old_errno;
  117. #if DEBUG == 1
  118. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original fopen() at %p (wrapper is at %p).\n",
  119. getpid(), orig_fopen, fopen);
  120. #endif
  121. rc = orig_fopen(f, g);
  122. old_errno=errno;
  123. handle_file_access_after("fopen", f, &status);
  124. errno=old_errno;
  125. return rc;
  126. }
  127. extern FILE* fopen64(const char* f, const char* g);
  128. FILE* (*orig_fopen64)(const char* f, const char* g) = 0;
  129. FILE* fopen64(const char* f, const char* g)
  130. {
  131. struct status_t status;
  132. int old_errno=errno;
  133. FILE* rc;
  134. handle_file_access_before("fopen64", f, &status);
  135. if (!orig_fopen64) orig_fopen64 = get_dl_symbol("fopen64");
  136. errno=old_errno;
  137. #if DEBUG == 1
  138. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original fopen64() at %p (wrapper is at %p).\n",
  139. getpid(), orig_fopen64, fopen64);
  140. #endif
  141. rc = orig_fopen64(f, g);
  142. old_errno=errno;
  143. handle_file_access_after("fopen64", f, &status);
  144. errno=old_errno;
  145. return rc;
  146. }
  147. extern int creat(const char* f, mode_t m);
  148. int (*orig_creat)(const char* f, mode_t m) = 0;
  149. int creat(const char* f, mode_t m)
  150. {
  151. struct status_t status;
  152. int old_errno=errno;
  153. int rc;
  154. handle_file_access_before("creat", f, &status);
  155. if (!orig_creat) orig_creat = get_dl_symbol("creat");
  156. errno=old_errno;
  157. #if DEBUG == 1
  158. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original creat() at %p (wrapper is at %p).\n",
  159. getpid(), orig_creat, creat);
  160. #endif
  161. rc = orig_creat(f, m);
  162. old_errno=errno;
  163. handle_file_access_after("creat", f, &status);
  164. errno=old_errno;
  165. return rc;
  166. }
  167. extern int creat64(const char* f, mode_t m);
  168. int (*orig_creat64)(const char* f, mode_t m) = 0;
  169. int creat64(const char* f, mode_t m)
  170. {
  171. struct status_t status;
  172. int old_errno=errno;
  173. int rc;
  174. handle_file_access_before("creat64", f, &status);
  175. if (!orig_creat64) orig_creat64 = get_dl_symbol("creat64");
  176. errno=old_errno;
  177. #if DEBUG == 1
  178. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original creat64() at %p (wrapper is at %p).\n",
  179. getpid(), orig_creat64, creat64);
  180. #endif
  181. rc = orig_creat64(f, m);
  182. old_errno=errno;
  183. handle_file_access_after("creat64", f, &status);
  184. errno=old_errno;
  185. return rc;
  186. }
  187. extern int mkdir(const char* f, mode_t m);
  188. int (*orig_mkdir)(const char* f, mode_t m) = 0;
  189. int mkdir(const char* f, mode_t m)
  190. {
  191. struct status_t status;
  192. int old_errno=errno;
  193. int rc;
  194. handle_file_access_before("mkdir", f, &status);
  195. if (!orig_mkdir) orig_mkdir = get_dl_symbol("mkdir");
  196. errno=old_errno;
  197. #if DEBUG == 1
  198. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original mkdir() at %p (wrapper is at %p).\n",
  199. getpid(), orig_mkdir, mkdir);
  200. #endif
  201. rc = orig_mkdir(f, m);
  202. old_errno=errno;
  203. handle_file_access_after("mkdir", f, &status);
  204. errno=old_errno;
  205. return rc;
  206. }
  207. extern int mknod(const char* f, mode_t m, dev_t d);
  208. int (*orig_mknod)(const char* f, mode_t m, dev_t d) = 0;
  209. int mknod(const char* f, mode_t m, dev_t d)
  210. {
  211. struct status_t status;
  212. int old_errno=errno;
  213. int rc;
  214. handle_file_access_before("mknod", f, &status);
  215. if (!orig_mknod) orig_mknod = get_dl_symbol("mknod");
  216. errno=old_errno;
  217. #if DEBUG == 1
  218. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original mknod() at %p (wrapper is at %p).\n",
  219. getpid(), orig_mknod, mknod);
  220. #endif
  221. rc = orig_mknod(f, m, d);
  222. old_errno=errno;
  223. handle_file_access_after("mknod", f, &status);
  224. errno=old_errno;
  225. return rc;
  226. }
  227. extern int link(const char* s, const char* f);
  228. int (*orig_link)(const char* s, const char* f) = 0;
  229. int link(const char* s, const char* f)
  230. {
  231. struct status_t status;
  232. int old_errno=errno;
  233. int rc;
  234. handle_file_access_before("link", f, &status);
  235. if (!orig_link) orig_link = get_dl_symbol("link");
  236. errno=old_errno;
  237. #if DEBUG == 1
  238. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original link() at %p (wrapper is at %p).\n",
  239. getpid(), orig_link, link);
  240. #endif
  241. rc = orig_link(s, f);
  242. old_errno=errno;
  243. handle_file_access_after("link", f, &status);
  244. errno=old_errno;
  245. return rc;
  246. }
  247. extern int symlink(const char* s, const char* f);
  248. int (*orig_symlink)(const char* s, const char* f) = 0;
  249. int symlink(const char* s, const char* f)
  250. {
  251. struct status_t status;
  252. int old_errno=errno;
  253. int rc;
  254. handle_file_access_before("symlink", f, &status);
  255. if (!orig_symlink) orig_symlink = get_dl_symbol("symlink");
  256. errno=old_errno;
  257. #if DEBUG == 1
  258. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original symlink() at %p (wrapper is at %p).\n",
  259. getpid(), orig_symlink, symlink);
  260. #endif
  261. rc = orig_symlink(s, f);
  262. old_errno=errno;
  263. handle_file_access_after("symlink", f, &status);
  264. errno=old_errno;
  265. return rc;
  266. }
  267. extern int rename(const char* s, const char* f);
  268. int (*orig_rename)(const char* s, const char* f) = 0;
  269. int rename(const char* s, const char* f)
  270. {
  271. struct status_t status;
  272. int old_errno=errno;
  273. int rc;
  274. handle_file_access_before("rename", f, &status);
  275. if (!orig_rename) orig_rename = get_dl_symbol("rename");
  276. errno=old_errno;
  277. #if DEBUG == 1
  278. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original rename() at %p (wrapper is at %p).\n",
  279. getpid(), orig_rename, rename);
  280. #endif
  281. rc = orig_rename(s, f);
  282. old_errno=errno;
  283. handle_file_access_after("rename", f, &status);
  284. errno=old_errno;
  285. return rc;
  286. }
  287. extern int utime(const char* f, const struct utimbuf* t);
  288. int (*orig_utime)(const char* f, const struct utimbuf* t) = 0;
  289. int utime(const char* f, const struct utimbuf* t)
  290. {
  291. struct status_t status;
  292. int old_errno=errno;
  293. int rc;
  294. handle_file_access_before("utime", f, &status);
  295. if (!orig_utime) orig_utime = get_dl_symbol("utime");
  296. errno=old_errno;
  297. #if DEBUG == 1
  298. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original utime() at %p (wrapper is at %p).\n",
  299. getpid(), orig_utime, utime);
  300. #endif
  301. rc = orig_utime(f, t);
  302. old_errno=errno;
  303. handle_file_access_after("utime", f, &status);
  304. errno=old_errno;
  305. return rc;
  306. }
  307. extern int utimes(const char* f, struct timeval* t);
  308. int (*orig_utimes)(const char* f, struct timeval* t) = 0;
  309. int utimes(const char* f, struct timeval* t)
  310. {
  311. struct status_t status;
  312. int old_errno=errno;
  313. int rc;
  314. handle_file_access_before("utimes", f, &status);
  315. if (!orig_utimes) orig_utimes = get_dl_symbol("utimes");
  316. errno=old_errno;
  317. #if DEBUG == 1
  318. fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original utimes() at %p (wrapper is at %p).\n",
  319. getpid(), orig_utimes, utimes);
  320. #endif
  321. rc = orig_utimes(f, t);
  322. old_errno=errno;
  323. handle_file_access_after("utimes", f, &status);
  324. errno=old_errno;
  325. return rc;
  326. }
  327. extern int execv(const char* f, char* const a[]);
  328. int (*orig_execv)(const char* f, char* const a[]) = 0;
  329. int execv(const char* f, char* const a[])
  330. {
  331. int old_errno=errno;
  332. handle_file_access_after("execv", f, 0);
  333. if (!orig_execv) orig_execv = get_dl_symbol("execv");
  334. errno=old_errno;
  335. return orig_execv(f, a);
  336. }
  337. extern int execve(const char* f, char* const a[], char* const e[]);
  338. int (*orig_execve)(const char* f, char* const a[], char* const e[]) = 0;
  339. int execve(const char* f, char* const a[], char* const e[])
  340. {
  341. int old_errno=errno;
  342. handle_file_access_after("execve", f, 0);
  343. if (!orig_execve) orig_execve = get_dl_symbol("execve");
  344. errno=old_errno;
  345. return orig_execve(f, a, e);
  346. }
  347. /*
  348. * Copyright (C) 1991, 92, 94, 97, 98, 99 Free Software Foundation, Inc.
  349. * This file is part of the GNU C Library.
  350. *
  351. * --- NO-ROCK-COPYRIGHT-NOTE ---
  352. *
  353. * glibc-2.2.5/posix/execl.c
  354. */
  355. /* Execute PATH with all arguments after PATH until
  356. a NULL pointer and environment from `environ'. */
  357. int
  358. execl (const char *path, const char *arg, ...)
  359. {
  360. size_t argv_max = 1024;
  361. const char **argv = alloca (argv_max * sizeof (const char *));
  362. unsigned int i;
  363. va_list args;
  364. argv[0] = arg;
  365. va_start (args, arg);
  366. i = 0;
  367. while (argv[i++] != NULL)
  368. {
  369. if (i == argv_max)
  370. {
  371. const char **nptr = alloca ((argv_max *= 2) * sizeof (const char *));
  372. #ifndef _STACK_GROWS_UP
  373. if ((char *) nptr + argv_max == (char *) argv)
  374. {
  375. /* Stack grows down. */
  376. argv = (const char **) memcpy (nptr, argv,
  377. i * sizeof (const char *));
  378. argv_max += i;
  379. }
  380. else
  381. #endif
  382. #ifndef _STACK_GROWS_DOWN
  383. if ((char *) argv + i == (char *) nptr)
  384. /* Stack grows up. */
  385. argv_max += i;
  386. else
  387. #endif
  388. /* We have a hole in the stack. */
  389. argv = (const char **) memcpy (nptr, argv,
  390. i * sizeof (const char *));
  391. }
  392. argv[i] = va_arg (args, const char *);
  393. }
  394. va_end (args);
  395. return execve (path, (char *const *) argv, __environ);
  396. }
  397. /*
  398. * Copyright (C) 1991, 92, 94, 97, 98, 99 Free Software Foundation, Inc.
  399. * This file is part of the GNU C Library.
  400. *
  401. * glibc-2.2.5/posix/execle.c
  402. */
  403. /* Execute PATH with all arguments after PATH until a NULL pointer,
  404. and the argument after that for environment. */
  405. int
  406. execle (const char *path, const char *arg, ...)
  407. {
  408. size_t argv_max = 1024;
  409. const char **argv = alloca (argv_max * sizeof (const char *));
  410. const char *const *envp;
  411. unsigned int i;
  412. va_list args;
  413. argv[0] = arg;
  414. va_start (args, arg);
  415. i = 0;
  416. while (argv[i++] != NULL)
  417. {
  418. if (i == argv_max)
  419. {
  420. const char **nptr = alloca ((argv_max *= 2) * sizeof (const char *));
  421. #ifndef _STACK_GROWS_UP
  422. if ((char *) nptr + argv_max == (char *) argv)
  423. {
  424. /* Stack grows down. */
  425. argv = (const char **) memcpy (nptr, argv,
  426. i * sizeof (const char *));
  427. argv_max += i;
  428. }
  429. else
  430. #endif
  431. #ifndef _STACK_GROWS_DOWN
  432. if ((char *) argv + i == (char *) nptr)
  433. /* Stack grows up. */
  434. argv_max += i;
  435. else
  436. #endif
  437. /* We have a hole in the stack. */
  438. argv = (const char **) memcpy (nptr, argv,
  439. i * sizeof (const char *));
  440. }
  441. argv[i] = va_arg (args, const char *);
  442. }
  443. envp = va_arg (args, const char *const *);
  444. va_end (args);
  445. return execve (path, (char *const *) argv, (char *const *) envp);
  446. }
  447. /*
  448. * Copyright (C) 1991, 92, 94, 97, 98, 99 Free Software Foundation, Inc.
  449. * This file is part of the GNU C Library.
  450. *
  451. * glibc-2.2.5/posix/execlp.c
  452. */
  453. /* Execute FILE, searching in the `PATH' environment variable if
  454. it contains no slashes, with all arguments after FILE until a
  455. NULL pointer and environment from `environ'. */
  456. int
  457. execlp (const char *file, const char *arg, ...)
  458. {
  459. size_t argv_max = 1024;
  460. const char **argv = alloca (argv_max * sizeof (const char *));
  461. unsigned int i;
  462. va_list args;
  463. argv[0] = arg;
  464. va_start (args, arg);
  465. i = 0;
  466. while (argv[i++] != NULL)
  467. {
  468. if (i == argv_max)
  469. {
  470. const char **nptr = alloca ((argv_max *= 2) * sizeof (const char *));
  471. #ifndef _STACK_GROWS_UP
  472. if ((char *) nptr + argv_max == (char *) argv)
  473. {
  474. /* Stack grows down. */
  475. argv = (const char **) memcpy (nptr, argv,
  476. i * sizeof (const char *));
  477. argv_max += i;
  478. }
  479. else
  480. #endif
  481. #ifndef _STACK_GROWS_DOWN
  482. if ((char *) argv + i == (char *) nptr)
  483. /* Stack grows up. */
  484. argv_max += i;
  485. else
  486. #endif
  487. /* We have a hole in the stack. */
  488. argv = (const char **) memcpy (nptr, argv,
  489. i * sizeof (const char *));
  490. }
  491. argv[i] = va_arg (args, const char *);
  492. }
  493. va_end (args);
  494. return execvp (file, (char *const *) argv);
  495. }
  496. /*
  497. * Copyright (C) 1991, 92, 94, 97, 98, 99 Free Software Foundation, Inc.
  498. * This file is part of the GNU C Library.
  499. *
  500. * glibc-2.2.5/posix/execvp.c
  501. */
  502. /* The file is accessible but it is not an executable file. Invoke
  503. the shell to interpret it as a script. */
  504. static void
  505. script_execute (const char *file, char *const argv[])
  506. {
  507. /* Count the arguments. */
  508. int argc = 0;
  509. while (argv[argc++])
  510. ;
  511. /* Construct an argument list for the shell. */
  512. {
  513. char *new_argv[argc + 1];
  514. new_argv[0] = (char *) "/bin/sh";
  515. new_argv[1] = (char *) file;
  516. while (argc > 1)
  517. {
  518. new_argv[argc] = argv[argc - 1];
  519. --argc;
  520. }
  521. /* Execute the shell. */
  522. execve (new_argv[0], new_argv, __environ);
  523. }
  524. }
  525. /* Execute FILE, searching in the `PATH' environment variable if it contains
  526. no slashes, with arguments ARGV and environment from `environ'. */
  527. int
  528. execvp (file, argv)
  529. const char *file;
  530. char *const argv[];
  531. {
  532. if (*file == '\0')
  533. {
  534. /* We check the simple case first. */
  535. errno = ENOENT;
  536. return -1;
  537. }
  538. if (strchr (file, '/') != NULL)
  539. {
  540. /* Don't search when it contains a slash. */
  541. execve (file, argv, __environ);
  542. if (errno == ENOEXEC)
  543. script_execute (file, argv);
  544. }
  545. else
  546. {
  547. int got_eacces = 0;
  548. char *path, *p, *name;
  549. size_t len;
  550. size_t pathlen;
  551. path = getenv ("PATH");
  552. if (path == NULL)
  553. {
  554. /* There is no `PATH' in the environment.
  555. The default search path is the current directory
  556. followed by the path `confstr' returns for `_CS_PATH'. */
  557. len = confstr (_CS_PATH, (char *) NULL, 0);
  558. path = (char *) alloca (1 + len);
  559. path[0] = ':';
  560. (void) confstr (_CS_PATH, path + 1, len);
  561. }
  562. len = strlen (file) + 1;
  563. pathlen = strlen (path);
  564. name = alloca (pathlen + len + 1);
  565. /* Copy the file name at the top. */
  566. name = (char *) memcpy (name + pathlen + 1, file, len);
  567. /* And add the slash. */
  568. *--name = '/';
  569. p = path;
  570. do
  571. {
  572. char *startp;
  573. path = p;
  574. p = strchrnul (path, ':');
  575. if (p == path)
  576. /* Two adjacent colons, or a colon at the beginning or the end
  577. of `PATH' means to search the current directory. */
  578. startp = name + 1;
  579. else
  580. startp = (char *) memcpy (name - (p - path), path, p - path);
  581. /* Try to execute this name. If it works, execv will not return. */
  582. execve (startp, argv, __environ);
  583. if (errno == ENOEXEC)
  584. script_execute (startp, argv);
  585. switch (errno)
  586. {
  587. case EACCES:
  588. /* Record the we got a `Permission denied' error. If we end
  589. up finding no executable we can use, we want to diagnose
  590. that we did find one but were denied access. */
  591. got_eacces = 1;
  592. case ENOENT:
  593. case ESTALE:
  594. case ENOTDIR:
  595. /* Those errors indicate the file is missing or not executable
  596. by us, in which case we want to just try the next path
  597. directory. */
  598. break;
  599. default:
  600. /* Some other error means we found an executable file, but
  601. something went wrong executing it; return the error to our
  602. caller. */
  603. return -1;
  604. }
  605. }
  606. while (*p++ != '\0');
  607. /* We tried every element and none of them worked. */
  608. if (got_eacces)
  609. /* At least one failure was due to permissions, so report that
  610. error. */
  611. errno = EACCES;
  612. }
  613. /* Return the error from the last attempt (probably ENOENT). */
  614. return -1;
  615. }
  616. /* Internal Functions */
  617. static void * get_dl_symbol(char * symname)
  618. {
  619. void * rc;
  620. #if DLOPEN_LIBC
  621. static void * libc_handle = 0;
  622. if (!libc_handle) libc_handle=dlopen("libc.so.6", RTLD_LAZY);
  623. if (!libc_handle) {
  624. printf("fl_wrapper.so: Can't dlopen libc: %s\n", dlerror());
  625. abort();
  626. }
  627. rc = dlsym(libc_handle, symname);
  628. # if DEBUG == 1
  629. fprintf(stderr, "fl_wrapper.so debug [%d]: Symbol '%s' in libc (%p) has been resolved to %p.\n",
  630. getpid(), symname, libc_handle, rc);
  631. # endif
  632. dlclose(libc_handle);
  633. #else
  634. rc = dlsym(RTLD_NEXT, symname);
  635. # if DEBUG == 1
  636. fprintf(stderr, "fl_wrapper.so debug [%d]: Symbol '%s' (RTLD_NEXT) has been resolved to %p.\n",
  637. getpid(), symname, rc);
  638. # endif
  639. #endif
  640. if (!rc) {
  641. printf("fl_wrapper.so: Can't resolve %s: %s\n",
  642. symname, dlerror());
  643. abort();
  644. }
  645. return rc;
  646. }
  647. static int pid2ppid(int pid)
  648. {
  649. char buffer[100];
  650. int fd, rc, ppid = 0;
  651. sprintf(buffer, "/proc/%d/stat", pid);
  652. if ( (fd = open(buffer, O_RDONLY, 0)) < 0 ) return 0;
  653. if ( (rc = read(fd, buffer, 99)) > 0) {
  654. buffer[rc] = 0;
  655. /* format: 27910 (bash) S 27315 ... */
  656. sscanf(buffer, "%*[^ ] %*[^ ] %*[^ ] %d", &ppid);
  657. }
  658. close(fd);
  659. return ppid;
  660. }
  661. /* this is only called from fl_wrapper_init(). so it doesn't need to be
  662. * reentrant. */
  663. static char *getpname(int pid)
  664. {
  665. static char p[512];
  666. char buffer[100]="";
  667. char *arg=0, *b;
  668. int i, fd, rc;
  669. sprintf(buffer, "/proc/%d/cmdline", pid);
  670. if ( (fd = open(buffer, O_RDONLY, 0)) < 0 ) return "unkown";
  671. if ( (rc = read(fd, buffer, 99)) > 0) {
  672. buffer[rc--] = 0;
  673. for (i=0; i<rc; i++)
  674. if (!buffer[i]) { arg = buffer+i+1; break; }
  675. }
  676. close(fd);
  677. b = basename(buffer);
  678. snprintf(p, 512, "%s", b);
  679. if ( !strcmp(b, "bash") || !strcmp(b, "sh") || !strcmp(b, "perl") )
  680. if (arg && *arg && *arg != '-')
  681. snprintf(p, 512, "%s(%s)", b, basename(arg));
  682. return p;
  683. }
  684. /* invert the order by recursion. there will be only one recursion tree
  685. * so we can use a static var for managing the last ent */
  686. static void addptree(int *txtpos, char *cmdtxt, int pid, int basepid)
  687. {
  688. static char l[512] = "";
  689. char *p;
  690. if (!pid || pid == basepid) return;
  691. addptree(txtpos, cmdtxt, pid2ppid(pid), basepid);
  692. p = getpname(pid);
  693. if ( strcmp(l, p) )
  694. *txtpos += snprintf(cmdtxt+*txtpos, 4096-*txtpos, "%s%s",
  695. *txtpos ? "." : "", getpname(pid));
  696. else
  697. *txtpos += snprintf(cmdtxt+*txtpos, 4096-*txtpos, "*");
  698. strcpy(l, p);
  699. }
  700. void __attribute__ ((constructor)) fl_wrapper_init()
  701. {
  702. char cmdtxt[4096] = "";
  703. char *basepid_txt = getenv("FLWRAPPER_BASEPID");
  704. int basepid = 0, txtpos=0;
  705. if (basepid_txt)
  706. basepid = atoi(basepid_txt);
  707. addptree(&txtpos, cmdtxt, getpid(), basepid);
  708. cmdname = strdup(cmdtxt);
  709. wlog = getenv("FLWRAPPER_WLOG");
  710. rlog = getenv("FLWRAPPER_RLOG");
  711. }
  712. static void handle_file_access_before(const char * func, const char * file,
  713. struct status_t * status)
  714. {
  715. struct stat st;
  716. #if DEBUG == 1
  717. fprintf(stderr, "fl_wrapper.so debug [%d]: begin of handle_file_access_before(\"%s\", \"%s\", xxx)\n",
  718. getpid(), func, file);
  719. #endif
  720. if ( lstat(file,&st) ) {
  721. status->inode=0; status->size=0;
  722. status->mtime=0; status->ctime=0;
  723. } else {
  724. status->inode=st.st_ino; status->size=st.st_size;
  725. status->mtime=st.st_mtime; status->ctime=st.st_ctime;
  726. }
  727. #if DEBUG == 1
  728. fprintf(stderr, "fl_wrapper.so debug [%d]: end of handle_file_access_before(\"%s\", \"%s\", xxx)\n",
  729. getpid(), func, file);
  730. #endif
  731. }
  732. static void handle_file_access_after(const char * func, const char * file,
  733. struct status_t * status)
  734. {
  735. char buf[512], *buf2, *logfile;
  736. int fd; struct stat st;
  737. #if DEBUG == 1
  738. fprintf(stderr, "fl_wrapper.so debug [%d]: begin of handle_file_access_after(\"%s\", \"%s\", xxx)\n",
  739. getpid(), func, file);
  740. #endif
  741. if ( wlog != 0 && !strcmp(file, wlog) ) return;
  742. if ( rlog != 0 && !strcmp(file, rlog) ) return;
  743. if ( lstat(file, &st) ) return;
  744. if ( (status != 0) && (status->inode != st.st_ino ||
  745. status->size != st.st_size || status->mtime != st.st_mtime ||
  746. status->ctime != st.st_ctime) ) { logfile = wlog; }
  747. else { logfile = rlog; }
  748. if ( logfile == 0 ) return;
  749. fd=open(logfile,O_APPEND|O_WRONLY,0);
  750. if (fd == -1) return;
  751. if (file[0] == '/') {
  752. sprintf(buf,"%s.%s:\t%s\n",
  753. cmdname, func, file);
  754. } else {
  755. buf2=get_current_dir_name();
  756. sprintf(buf,"%s.%s:\t%s%s%s\n",
  757. cmdname, func, buf2,
  758. strcmp(buf2,"/") ? "/" : "", file);
  759. free(buf2);
  760. }
  761. write(fd,buf,strlen(buf));
  762. close(fd);
  763. #if DEBUG == 1
  764. fprintf(stderr, "fl_wrapper.so debug [%d]: end of handle_file_access_after(\"%s\", \"%s\", xxx)\n",
  765. getpid(), func, file);
  766. #endif
  767. }