common.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /* common.c
  2. *
  3. * Functions for debugging and logging as well as some other
  4. * simple helper functions.
  5. *
  6. * Russ Dill <Russ.Dill@asu.edu> 2001-2003
  7. * Rewritten by Vladimir Oleynik <dzo@simtreas.ru> (C) 2003
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22. */
  23. #include <fcntl.h>
  24. #include <unistd.h>
  25. #include <errno.h>
  26. #include <string.h>
  27. #include <stdlib.h>
  28. #include <signal.h>
  29. #include <paths.h>
  30. #include <sys/socket.h>
  31. #include <stdarg.h>
  32. #include "common.h"
  33. #include "pidfile.h"
  34. static int daemonized;
  35. long uptime(void)
  36. {
  37. struct sysinfo info;
  38. sysinfo(&info);
  39. return info.uptime;
  40. }
  41. /*
  42. * This function makes sure our first socket calls
  43. * aren't going to fd 1 (printf badness...) and are
  44. * not later closed by daemon()
  45. */
  46. static inline void sanitize_fds(void)
  47. {
  48. int zero;
  49. if ((zero = open(_PATH_DEVNULL, O_RDWR, 0)) < 0) return;
  50. while (zero < 3) zero = dup(zero);
  51. close(zero);
  52. }
  53. void background(const char *pidfile)
  54. {
  55. #ifdef __uClinux__
  56. LOG(LOG_ERR, "Cannot background in uclinux (yet)");
  57. #else /* __uClinux__ */
  58. int pid_fd;
  59. /* hold lock during fork. */
  60. pid_fd = pidfile_acquire(pidfile);
  61. if (daemon(0, 0) == -1) {
  62. perror("fork");
  63. exit(1);
  64. }
  65. daemonized++;
  66. pidfile_write_release(pid_fd);
  67. #endif /* __uClinux__ */
  68. }
  69. #ifdef UDHCP_SYSLOG
  70. void udhcp_logging(int level, const char *fmt, ...)
  71. {
  72. va_list p;
  73. va_list p2;
  74. va_start(p, fmt);
  75. __va_copy(p2, p);
  76. if(!daemonized) {
  77. vprintf(fmt, p);
  78. putchar('\n');
  79. }
  80. vsyslog(level, fmt, p2);
  81. va_end(p);
  82. }
  83. void start_log_and_pid(const char *client_server, const char *pidfile)
  84. {
  85. int pid_fd;
  86. /* Make sure our syslog fd isn't overwritten */
  87. sanitize_fds();
  88. /* do some other misc startup stuff while we are here to save bytes */
  89. pid_fd = pidfile_acquire(pidfile);
  90. pidfile_write_release(pid_fd);
  91. /* equivelent of doing a fflush after every \n */
  92. setlinebuf(stdout);
  93. openlog(client_server, LOG_PID | LOG_CONS, LOG_LOCAL0);
  94. udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION);
  95. }
  96. #else
  97. static char *syslog_level_msg[] = {
  98. [LOG_EMERG] = "EMERGENCY!",
  99. [LOG_ALERT] = "ALERT!",
  100. [LOG_CRIT] = "critical!",
  101. [LOG_WARNING] = "warning",
  102. [LOG_ERR] = "error",
  103. [LOG_INFO] = "info",
  104. [LOG_DEBUG] = "debug"
  105. };
  106. void udhcp_logging(int level, const char *fmt, ...)
  107. {
  108. va_list p;
  109. va_start(p, fmt);
  110. if(!daemonized) {
  111. printf("%s, ", syslog_level_msg[level]);
  112. vprintf(fmt, p);
  113. putchar('\n');
  114. }
  115. va_end(p);
  116. }
  117. void start_log_and_pid(const char *client_server, const char *pidfile)
  118. {
  119. int pid_fd;
  120. /* Make sure our syslog fd isn't overwritten */
  121. sanitize_fds();
  122. /* do some other misc startup stuff while we are here to save bytes */
  123. pid_fd = pidfile_acquire(pidfile);
  124. pidfile_write_release(pid_fd);
  125. /* equivelent of doing a fflush after every \n */
  126. setlinebuf(stdout);
  127. udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION);
  128. }
  129. #endif