MainLinux.cpp
上传用户:woshihumen
上传日期:2013-07-18
资源大小:484k
文件大小:8k
源码类别:

Email服务器

开发平台:

Visual C++

  1. /*
  2.  *  XMail by Davide Libenzi ( Intranet and Internet mail server )
  3.  *  Copyright (C) 1999,..,2004  Davide Libenzi
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  *
  19.  *  Davide Libenzi <davidel@xmailserver.org>
  20.  *
  21.  */
  22. #include "SysInclude.h"
  23. #include "SysDep.h"
  24. #include "SvrDefines.h"
  25. #include "SList.h"
  26. #include "ShBlocks.h"
  27. #include "UsrUtils.h"
  28. #include "SvrUtils.h"
  29. #include "MessQueue.h"
  30. #include "SMAILUtils.h"
  31. #include "QueueUtils.h"
  32. #include "AppDefines.h"
  33. #include "MailSvr.h"
  34. #define RUNNING_PIDS_DIR            "/var/run"
  35. #define DEVNULL                     "/dev/null"
  36. #define NOFILE                      64
  37. #define XMAIL_DEBUG_OPTION          "-Md"
  38. #define XMAIL_PIDDIR_ENV            "XMAIL_PID_DIR"
  39. static int MnEventLog(char const *pszFormat, ...);
  40. static char const *MnGetPIDDir(void);
  41. static int MnSavePID(char const *pszPidFile);
  42. static int MnRemovePID(char const *pszPidFile);
  43. static void MnSetupStdHandles(void);
  44. static int MnDaemonBootStrap(void);
  45. static int MnIsDebugStartup(int iArgCount, char *pszArgs[]);
  46. static int MnDaemonStartup(int iArgCount, char *pszArgs[]);
  47. static int MnEventLog(char const *pszFormat, ...)
  48. {
  49. openlog(APP_NAME_STR, LOG_PID, LOG_DAEMON);
  50. va_list Args;
  51. va_start(Args, pszFormat);
  52. char szBuffer[2048] = "";
  53. vsnprintf(szBuffer, sizeof(szBuffer) - 1, pszFormat, Args);
  54. syslog(LOG_ERR, "%s", szBuffer);
  55. va_end(Args);
  56. closelog();
  57. return (0);
  58. }
  59. static char const *MnGetPIDDir(void)
  60. {
  61. char const *pszPIDDir = getenv(XMAIL_PIDDIR_ENV);
  62. return ((pszPIDDir != NULL) ? pszPIDDir: RUNNING_PIDS_DIR);
  63. }
  64. static int MnSavePID(char const *pszPidFile)
  65. {
  66. char szPidFile[SYS_MAX_PATH] = "";
  67. snprintf(szPidFile, sizeof(szPidFile) - 1, "%s/%s.pid", MnGetPIDDir(), pszPidFile);
  68. FILE *pFile = fopen(szPidFile, "w");
  69. if (pFile == NULL) {
  70. perror(szPidFile);
  71. return (-errno);
  72. }
  73. fprintf(pFile, "%u", (unsigned int) getpid());
  74. fclose(pFile);
  75. return (0);
  76. }
  77. static int MnRemovePID(char const *pszPidFile)
  78. {
  79. char szPidFile[SYS_MAX_PATH] = "";
  80. snprintf(szPidFile, sizeof(szPidFile) - 1, "%s/%s.pid", MnGetPIDDir(), pszPidFile);
  81. if (unlink(szPidFile) != 0) {
  82. perror(szPidFile);
  83. return (-errno);
  84. }
  85. return (0);
  86. }
  87. static void MnSetupStdHandles(void)
  88. {
  89. int iFD = open(DEVNULL, O_RDWR, 0);
  90. if (iFD == -1) {
  91. MnEventLog("Cannot open file %s : %s", DEVNULL, strerror(errno));
  92. exit(errno);
  93. }
  94. if ((dup2(iFD, 0) == -1) || (dup2(iFD, 1) == -1) || (dup2(iFD, 2) == -1)) {
  95. MnEventLog("File descriptor duplication error : %s", strerror(errno));
  96. exit(errno);
  97. }
  98. close(iFD);
  99. }
  100. static int MnDaemonBootStrap(void)
  101. {
  102. ///////////////////////////////////////////////////////////////////////////////
  103. //  This code is inspired from the code of the great Richard Stevens books.
  104. //  May You RIP in programmers paradise great Richard.
  105. //  I suggest You to buy all his collection, soon !
  106. ///////////////////////////////////////////////////////////////////////////////
  107. ///////////////////////////////////////////////////////////////////////////////
  108. //  For BSD
  109. ///////////////////////////////////////////////////////////////////////////////
  110. #ifdef SIGTTOU
  111. signal(SIGTTOU, SIG_IGN);
  112. #endif
  113. #ifdef SIGTTIN
  114. signal(SIGTTIN, SIG_IGN);
  115. #endif
  116. #ifdef SIGTSTP
  117. signal(SIGTSTP, SIG_IGN);
  118. #endif
  119. ///////////////////////////////////////////////////////////////////////////////
  120. //  1st fork
  121. ///////////////////////////////////////////////////////////////////////////////
  122. int iChildPID = fork();
  123. if (iChildPID < 0) {
  124. MnEventLog("Cannot fork : %s", strerror(errno));
  125. exit(errno);
  126. } else if (iChildPID > 0)
  127. exit(0);
  128. ///////////////////////////////////////////////////////////////////////////////
  129. //  Disassociate from controlling terminal and process group. Ensure the process
  130. //  can't reacquire a new controlling terminal.
  131. ///////////////////////////////////////////////////////////////////////////////
  132. if (setpgrp() == -1) {
  133. MnEventLog("Can't change process group : %s", strerror(errno));
  134. exit(errno);
  135. }
  136. signal(SIGHUP, SIG_IGN);
  137. ///////////////////////////////////////////////////////////////////////////////
  138. //  2nd fork
  139. ///////////////////////////////////////////////////////////////////////////////
  140. iChildPID = fork();
  141. if (iChildPID < 0) {
  142. MnEventLog("Cannot fork : %s", strerror(errno));
  143. exit(errno);
  144. } else if (iChildPID > 0)
  145. exit(0);
  146. ///////////////////////////////////////////////////////////////////////////////
  147. //  Close open file descriptors
  148. ///////////////////////////////////////////////////////////////////////////////
  149. for (int fd = 0; fd < NOFILE; fd++)
  150. close(fd);
  151. ///////////////////////////////////////////////////////////////////////////////
  152. //  Set std handles
  153. ///////////////////////////////////////////////////////////////////////////////
  154. MnSetupStdHandles();
  155. ///////////////////////////////////////////////////////////////////////////////
  156. //  Probably got set to EBADF from a close
  157. ///////////////////////////////////////////////////////////////////////////////
  158. errno = 0;
  159. ///////////////////////////////////////////////////////////////////////////////
  160. //  Move the current directory to root, to make sure we aren't on a mounted
  161. //  filesystem.
  162. ///////////////////////////////////////////////////////////////////////////////
  163. chdir("/");
  164. ///////////////////////////////////////////////////////////////////////////////
  165. //  Clear any inherited file mode creation mask.
  166. ///////////////////////////////////////////////////////////////////////////////
  167. umask(0);
  168. ///////////////////////////////////////////////////////////////////////////////
  169. //  Ignore childs dead.
  170. ///////////////////////////////////////////////////////////////////////////////
  171. ///////////////////////////////////////////////////////////////////////////////
  172. //  System V
  173. ///////////////////////////////////////////////////////////////////////////////
  174. signal(SIGCLD, SIG_IGN);
  175. return (0);
  176. }
  177. static int MnIsDebugStartup(int iArgCount, char *pszArgs[])
  178. {
  179. for (int ii = 0; ii < iArgCount; ii++)
  180. if (strcmp(pszArgs[ii], XMAIL_DEBUG_OPTION) == 0)
  181. return (1);
  182. return (0);
  183. }
  184. static int MnDaemonStartup(int iArgCount, char *pszArgs[])
  185. {
  186. ///////////////////////////////////////////////////////////////////////////////
  187. //  Daemon bootstrap code if We're not in debug mode
  188. ///////////////////////////////////////////////////////////////////////////////
  189. if (!MnIsDebugStartup(iArgCount, pszArgs))
  190. MnDaemonBootStrap();
  191. ///////////////////////////////////////////////////////////////////////////////
  192. //  Extract PID file name
  193. ///////////////////////////////////////////////////////////////////////////////
  194. char const *pszPidFile = strrchr(pszArgs[0], '/');
  195. pszPidFile = (pszPidFile != NULL) ? (pszPidFile + 1): pszArgs[0];
  196. ///////////////////////////////////////////////////////////////////////////////
  197. //  Create PID file
  198. ///////////////////////////////////////////////////////////////////////////////
  199. MnSavePID(pszPidFile);
  200. int iServerResult = SvrMain(iArgCount, pszArgs);
  201. ///////////////////////////////////////////////////////////////////////////////
  202. //  Remove PID file
  203. ///////////////////////////////////////////////////////////////////////////////
  204. MnRemovePID(pszPidFile);
  205. return (iServerResult);
  206. }
  207. int main(int iArgCount, char *pszArgs[])
  208. {
  209. return (MnDaemonStartup(iArgCount, pszArgs));
  210. }