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.

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