Advertisement
Guest User

daemonize of z-connector

a guest
Dec 4th, 2012
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 9.25 KB | None | 0 0
  1. # HG changeset patch
  2. # Date 1354602095 -25200
  3. # Node ID 5b943f6164c5be8617e28b0b26aaf64de49621fa
  4. # Parent  076d182af50930013519233ea1a8ee067c6538f6
  5. daemonize && syslog
  6.  
  7. diff --git a/Unix/log.c b/Unix/log.c
  8. --- a/Unix/log.c
  9. +++ b/Unix/log.c
  10. @@ -1,38 +1,92 @@
  11.  #include "common.h"
  12. -#include "log.h"
  13. +#include "log.h"
  14. +#ifndef WIN32
  15. +#include <syslog.h>
  16. +#endif
  17.  
  18.  // global logging level
  19.  int LogLevel = 0;
  20.  
  21.  // log file object
  22. -FILE *logFile = NULL;
  23. +FILE *logFile;
  24. +int useSyslog;
  25.  
  26.  void OpenLog(const char *fileName)
  27. -{
  28. -   logFile = (strcmp(fileName, "-") == 0) ? stdout : fopen(fileName, "a");
  29. +{
  30. +    useSyslog = 0;
  31. +    logFile = NULL;
  32. +    if ( strcmp(fileName, "-")==0 )
  33. +    {
  34. +        logFile = stdout;
  35. +    }
  36. +    else if ( strcmp(fileName, "syslog")==0 )
  37. +    {
  38. +        useSyslog = 1;
  39. +#ifndef WIN32
  40. +        openlog ( "z-agent", LOG_PID, LOG_DAEMON );
  41. +#endif
  42. +    }
  43. +    else
  44. +    {
  45. +        logFile = fopen(fileName, "a");
  46. +    }
  47.  
  48. -   if (logFile == NULL)
  49. -   {
  50. -       printf("Failed to open log file (%s): %s\n", fileName, strerror(errno));
  51. +   if ( !logFile )
  52. +   {
  53. +        if ( !useSyslog )
  54. +            printf("Failed to open log file (%s): %s\n", fileName, strerror(errno));
  55. +#ifdef WIN32
  56. +        else
  57. +            printf("Logging ty syslog on Windows not supported. Sorry\n");
  58. +#endif
  59.     }
  60.  }
  61.  
  62.  void CloseLog()
  63.  {
  64. -   if (logFile != NULL && logFile != stdout)
  65. -       fclose(logFile);
  66. -   logFile = NULL;
  67. +   if (logFile != NULL && logFile != stdout && !useSyslog )
  68. +   {
  69. +        if (!useSyslog)
  70. +            fclose(logFile);
  71. +   }
  72. +
  73. +   logFile = NULL;
  74. +#ifndef WIN32
  75. +    if ( useSyslog )
  76. +        closelog();
  77. +#endif
  78.  }
  79.  
  80.  void Log(int level, const char *fmt, ...)
  81. -{
  82. +{
  83. +#ifndef WIN32
  84. +    const int levels[] = { LOG_EMERG, LOG_WARNING, LOG_INFO, LOG_DEBUG };
  85. +#endif
  86.     va_list ap;
  87.  
  88.     if (level > LogLevel) return;
  89. +
  90. +#ifndef WIN32
  91. +    if ( useSyslog )
  92. +    {
  93. +        vsyslog ( levels[level], fmt, ap );
  94. +        return;
  95. +    }
  96. +#endif
  97.  
  98.      va_start(ap, fmt);
  99. -   vfprintf((logFile != NULL) ? logFile : stdout, fmt, ap);
  100. -   va_end(ap);
  101. +    vfprintf((logFile != NULL) ? logFile : stdout, fmt, ap);
  102. +    va_end(ap);
  103.  
  104. -   fflush((logFile != NULL) ? logFile : stdout);
  105. +    fflush((logFile != NULL) ? logFile : stdout);
  106. +}
  107. +
  108. +void Error(const char *fmt, ...)
  109. +{
  110. +    va_list ap;
  111. +    va_start(ap, fmt);
  112. +    vfprintf( stderr, fmt, ap);
  113. +    va_end(ap);
  114. +    fflush(stderr);
  115. +    exit (1);
  116.  }
  117. diff --git a/Unix/log.h b/Unix/log.h
  118. --- a/Unix/log.h
  119. +++ b/Unix/log.h
  120. @@ -6,11 +6,13 @@
  121.  void OpenLog(const char *fileName);
  122.  void CloseLog();
  123.  
  124. -void Log(int level, const char *fmt, ...);
  125. +void Log(int level, const char *fmt, ...);
  126. +void Error(const char *fmt, ...);
  127.  
  128.  #define ERR(s, ...) Log(0, "[E] " s, ##__VA_ARGS__)
  129.  #define WARN(s, ...) Log(1, "[W] " s, ##__VA_ARGS__)
  130.  #define INFO(s, ...) Log(2, "[I] " s, ##__VA_ARGS__)
  131. -#define DBG(s, ...) Log(3, "[D] " s, ##__VA_ARGS__)
  132. +#define DBG(s, ...) Log(3, "[D] " s, ##__VA_ARGS__)
  133. +#define FATAL(s, ...) Error( "[FATAL] " s, ##__VA_ARGS__)
  134.  
  135.  #endif
  136. \ No newline at end of file
  137. diff --git a/Unix/main.c b/Unix/main.c
  138. --- a/Unix/main.c
  139. +++ b/Unix/main.c
  140. @@ -24,7 +24,7 @@
  141.  void DumpBuffer(const char *data, int length)
  142.  {
  143.     char line[49];
  144. -   int i, j;
  145. +   int i;
  146.  
  147.     line[48] = '\0';
  148.  
  149. @@ -119,7 +119,6 @@
  150.  {
  151.     struct hostent *srv;
  152.     int dev = -1;
  153. -   FILE* log = NULL;
  154.     SOCKET sock = SOCKET_ERROR;
  155.     struct sockaddr_in srvaddr;
  156.     int keepalive = 1, hasCert, retCode;
  157. @@ -186,11 +185,11 @@
  158.     {
  159.         WARN("Failed to enable keep-alives\n");
  160.     }
  161. -  
  162. +
  163.     srvaddr.sin_family = AF_INET;
  164.     srvaddr.sin_port = htons((u_short) port);
  165.     memcpy(&srvaddr.sin_addr, srv->h_addr_list[0], 4);
  166. -  
  167. +
  168.     INFO("Connecting to server...\n");
  169.  
  170.     if (0 != connect(sock, (const struct sockaddr *) &srvaddr, sizeof(srvaddr)))
  171. @@ -241,8 +240,8 @@
  172.             RETURN(3);
  173.         }
  174.     }
  175. -  
  176. -  
  177. +
  178. +
  179.     IsTerminating = 0;
  180.  
  181.     signal(SIGTERM, sig_handler);
  182. @@ -280,18 +279,22 @@
  183.     struct arg_file *cert = arg_file0(NULL, "cert", NULL, "personal certificate");
  184.     struct arg_file *key = arg_file0(NULL, "key", NULL, "personal certificate key");
  185.     struct arg_file *cacert = arg_file0(NULL, "cacert", NULL, "CA certificate");
  186. -   struct arg_file *log = arg_file0("lL", "log", NULL, "file to write log to (defaults to stdout)");
  187. +   struct arg_file *log = arg_file0("lL", "log", NULL, "file to write log to (defaults to stdout or syslog)");
  188.     struct arg_lit *debug = arg_lit0(NULL, "debug", "log debugging information");
  189. -    struct arg_lit *help = arg_lit0("h", "help", "print this help and exit");
  190. +#ifndef WIN32
  191. +    struct arg_file *daemon = arg_file0("bB", "pid", NULL, "daemonize and write the pid into given pidfile");
  192. +#endif
  193. +    struct arg_lit *help = arg_lit0("h", "help", "print this help and exit");
  194.      struct arg_end *end = arg_end(20);
  195.  
  196. -   void* argTable[] = {device, server, port, cert, key, cacert, log, debug, help, end};
  197. -
  198. -#ifdef WIN32
  199. +#ifdef WIN32
  200. +    void* argTable[] = {device, server, port, cert, key, cacert, log, debug, help, end};
  201.     WSADATA wsa;
  202.     WORD wsaVersion = MAKEWORD(2, 2);
  203.     int wsaError;
  204. -   DWORD win32err;
  205. +   DWORD win32err;
  206. +#else
  207. +    void* argTable[] = {device, server, port, cert, key, cacert, log, debug, daemon, help, end};
  208.  #endif
  209.  
  210.     int retCode, nErrors;
  211. @@ -316,7 +319,15 @@
  212.          CLEAN_RETURN(0);
  213.      }
  214.  
  215. -   LogLevel = (IS_ARG_SET(debug)) ? 3 : 2;
  216. +   LogLevel = (IS_ARG_SET(debug)) ? 3 : 2;
  217. +
  218. +#ifndef WIN32
  219. +   int IDaemon = 0;
  220. +   int iPid = -1;
  221. +   const char * sPidFN = SAFE_FILE (daemon, "");
  222. +   if ( HAS_STR(sPidFN) )
  223. +        IDaemon = 1;
  224. +#endif
  225.  
  226.      if (nErrors > 0)
  227.     {
  228. @@ -325,7 +336,8 @@
  229.  
  230.          CLEAN_RETURN(2);
  231.      }
  232. -
  233. +
  234. +    const char * defLog = "-";
  235.  #ifdef WIN32
  236.     hStoppingEvent = CreateEvent(NULL, TRUE, FALSE, "Local\\Z-Agent-Stop");
  237.     if (hStoppingEvent == NULL)
  238. @@ -361,17 +373,108 @@
  239.         CloseHandle(hStoppingEvent);
  240.         CLEAN_RETURN(3);
  241.     }
  242. +#else
  243. +    if (IDaemon)
  244. +    {
  245. +        // first, look if we can create and lock the PID
  246. +        iPid = open ( sPidFN, O_CREAT | O_WRONLY, S_IREAD | S_IWRITE );
  247. +        if ( iPid<0 )
  248. +            FATAL ( "failed to create pid file '%s': %s\n", sPidFN, strerror(errno) );
  249. +
  250. +        struct flock tLock;
  251. +        tLock.l_type = F_WRLCK;
  252. +        tLock.l_whence = SEEK_SET;
  253. +        tLock.l_start = 0;
  254. +        tLock.l_len = 0;
  255. +        if ( fcntl ( iPid, F_SETLK, &tLock )==-1 )
  256. +            FATAL ( "failed to lock pid file '%s': %s (daemon already running?)\n", sPidFN, strerror(errno) );
  257. +
  258. +        // prepare to detach
  259. +        int iDevNull = open ( "/dev/null", O_RDWR );
  260. +        close ( STDIN_FILENO );
  261. +       close ( STDOUT_FILENO );
  262. +       dup2 ( iDevNull, STDIN_FILENO );
  263. +       dup2 ( iDevNull, STDOUT_FILENO );
  264. +
  265. +       // unlock the pid (will relock again in child)
  266. +       tLock.l_type = F_UNLCK;
  267. +        fcntl ( iPid, F_SETLK, &tLock );
  268. +
  269. +        // Fork #1 - detach from controlling terminal
  270. +        switch ( fork() )
  271. +        {
  272. +            case -1:
  273. +                // error
  274. +                FATAL ( "fork() failed (reason: %s)\n", strerror ( errno ) );
  275. +            case 0:
  276. +                // daemonized child - or new and free watchdog :)
  277. +                break;
  278. +
  279. +            default:
  280. +               exit ( 0 );
  281. +        }
  282. +
  283. +        // became the session leader
  284. +        if ( setsid()==-1 )
  285. +        {
  286. +            FATAL ( "fork() failed (reason: %s)\n", strerror ( errno ) );
  287. +        }
  288. +
  289. +        // Fork #2 - detach from session leadership (may be not necessary, however)
  290. +        switch ( fork() )
  291. +        {
  292. +            case -1:
  293. +                // error
  294. +                FATAL ( "fork() failed (reason: %s)\n", strerror ( errno ) );
  295. +                exit ( 1 );
  296. +            case 0:
  297. +                // daemonized child - or new and free watchdog :)
  298. +                break;
  299. +
  300. +            default:
  301. +                // the parent
  302. +                exit ( 0 );
  303. +        }
  304. +
  305. +       // relock the pid
  306. +        tLock.l_type = F_WRLCK;
  307. +        if ( fcntl ( iPid, F_SETLK, &tLock )==-1 )
  308. +            FATAL ( "failed to re-lock pid file '%s': %s\n", sPidFN, strerror(errno) );
  309. +
  310. +        // write our pid into pidfile
  311. +       char sPid[16];
  312. +       snprintf ( sPid, sizeof(sPid), "%d\n", (int)getpid() );
  313. +       int iPidLen = strlen(sPid);
  314. +
  315. +       lseek(iPid, 0, SEEK_SET);
  316. +       if ( iPidLen!=write ( iPid, sPid, iPidLen ) )
  317. +            FATAL ( "failed to write to pid file '%s' (errno=%d, msg=%s)\n", sPidFN, errno, strerror(errno) );
  318. +
  319. +       if ( ftruncate ( iPid, iPidLen ) )
  320. +            FATAL ( "failed to truncate pid file '%s' (errno=%d, msg=%s)\n", sPidFN, errno, strerror(errno) );
  321. +
  322. +        close ( STDERR_FILENO );
  323. +       dup2 ( iDevNull, STDERR_FILENO );
  324. +       defLog = "syslog";
  325. +
  326. +    }
  327.  #endif
  328.  
  329. -   retCode = main_impl(device->filename[0],
  330. +   retCode = main_impl(device->filename[0],
  331.                         server->sval[0], SAFE_INT(port, 9087),
  332. -                       SAFE_FILE(cert, ""), SAFE_FILE(key, ""), SAFE_FILE(cacert, ""),
  333. -                       SAFE_FILE(log, "-"));
  334. +                       SAFE_FILE(cert, ""), SAFE_FILE(key, ""), SAFE_FILE(cacert, ""),
  335. +                       SAFE_FILE(log, defLog));
  336.  
  337.  #ifdef WIN32
  338.     WSACleanup();
  339.  
  340.     CloseHandle(hStoppingEvent);
  341. +#else
  342. +    if ( iPid>=0 )
  343. +    {
  344. +       close ( iPid );
  345. +       unlink ( sPidFN );
  346. +    }
  347.  #endif
  348.  
  349.     CLEAN_RETURN(retCode);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement