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.

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