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

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 DEVNULL                     "/dev/null"
  35. #define RUNNING_PIDS_DIR            "/var/run"
  36. #if !defined(NOFILE)
  37. #define NOFILE                      64
  38. #endif
  39. #define XMAIL_DEBUG_OPTION          "-Md"
  40. #define XMAIL_PIDDIR_ENV            "XMAIL_PID_DIR"
  41. static int MnEventLog(char const *pszFormat, ...);
  42. static char const *MnGetPIDDir(void);
  43. static int MnSavePID(char const *pszPidFile);
  44. static int MnRemovePID(char const *pszPidFile);
  45. static void MnSIGCLD(int iSignal);
  46. static int MnDaemonBootStrap(void);
  47. static int MnIsDebugStartup(int iArgCount, char *pszArgs[]);
  48. static int MnDaemonStartup(int iArgCount, char *pszArgs[]);
  49. static int MnEventLog(char const *pszFormat, ...)
  50. {
  51. openlog(APP_NAME_STR, LOG_PID, LOG_DAEMON);
  52. va_list Args;
  53. va_start(Args, pszFormat);
  54. char szBuffer[2048] = "";
  55. vsnprintf(szBuffer, sizeof(szBuffer) - 1, pszFormat, Args);
  56. syslog(LOG_ERR, "%s", szBuffer);
  57. va_end(Args);
  58. closelog();
  59. return (0);
  60. }
  61. static char const *MnGetPIDDir(void)
  62. {
  63. char const *pszPIDDir = getenv(XMAIL_PIDDIR_ENV);
  64. return ((pszPIDDir != NULL) ? pszPIDDir: RUNNING_PIDS_DIR);
  65. }
  66. static int MnSavePID(char const *pszPidFile)
  67. {
  68. char szPidFile[SYS_MAX_PATH] = "";
  69. snprintf(szPidFile, sizeof(szPidFile) - 1, "%s/%s.pid", MnGetPIDDir(), pszPidFile);
  70. FILE *pFile = fopen(szPidFile, "w");
  71. if (pFile == NULL) {
  72. perror(szPidFile);
  73. return (-errno);
  74. }
  75. fprintf(pFile, "%u", (unsigned int) getpid());
  76. fclose(pFile);
  77. return (0);
  78. }
  79. static int MnRemovePID(char const *pszPidFile)
  80. {
  81. char szPidFile[SYS_MAX_PATH] = "";
  82. snprintf(szPidFile, sizeof(szPidFile) - 1, "%s/%s.pid", MnGetPIDDir(), pszPidFile);
  83. if (unlink(szPidFile) != 0) {
  84. perror(szPidFile);
  85. return (-errno);
  86. }
  87. return (0);
  88. }
  89. static void MnSIGCLD(int iSignal)
  90. {
  91. ///////////////////////////////////////////////////////////////////////////////
  92. //  For BSD
  93. ///////////////////////////////////////////////////////////////////////////////
  94. #ifdef __BSD__
  95. int iDeadPID;
  96. union wait ExitStatus;
  97. while ((iDeadPID = wait3(&ExitStatus, WNOHANG, (struct rusage *) NULL)) > 0);
  98. #endif
  99. }
  100. static void MnSetupStdHandles(void)
  101. {
  102. int iFD = open(DEVNULL, O_RDWR, 0);
  103. if (iFD == -1) {
  104. MnEventLog("Cannot open file %s : %s", DEVNULL, strerror(errno));
  105. exit(errno);
  106. }
  107. if ((dup2(iFD, 0) == -1) || (dup2(iFD, 1) == -1) || (dup2(iFD, 2) == -1)) {
  108. MnEventLog("File descriptor duplication error : %s", strerror(errno));
  109. exit(errno);
  110. }
  111. close(iFD);
  112. }
  113. static int MnDaemonBootStrap(void)
  114. {
  115. ///////////////////////////////////////////////////////////////////////////////
  116. //  This code is inspired from the code of the great Richard Stevens books.
  117. //  May You RIP in programmers paradise great Richard.
  118. //  I suggest You to buy all his collection, soon !
  119. ///////////////////////////////////////////////////////////////////////////////
  120. ///////////////////////////////////////////////////////////////////////////////
  121. //  For BSD
  122. ///////////////////////////////////////////////////////////////////////////////
  123. #ifdef SIGTTOU
  124. signal(SIGTTOU, SIG_IGN);
  125. #endif
  126. #ifdef SIGTTIN
  127. signal(SIGTTIN, SIG_IGN);
  128. #endif
  129. #ifdef SIGTSTP
  130. signal(SIGTSTP, SIG_IGN);
  131. #endif
  132. ///////////////////////////////////////////////////////////////////////////////
  133. //  1st fork
  134. ///////////////////////////////////////////////////////////////////////////////
  135. int iChildPID = fork();
  136. if (iChildPID < 0) {
  137. MnEventLog("Cannot fork : %s", strerror(errno));
  138. exit(errno);
  139. } else if (iChildPID > 0)
  140. exit(0);
  141. ///////////////////////////////////////////////////////////////////////////////
  142. //  Disassociate from controlling terminal and process group. Ensure the process
  143. //  can't reacquire a new controlling terminal.
  144. ///////////////////////////////////////////////////////////////////////////////
  145. #ifdef __BSD__
  146. ///////////////////////////////////////////////////////////////////////////////
  147. //  BSD
  148. ///////////////////////////////////////////////////////////////////////////////
  149. if (setpgrp(0, getpid()) == -1) {
  150. MnEventLog("Can't change process group : %s", strerror(errno));
  151. exit(errno);
  152. }
  153. ///////////////////////////////////////////////////////////////////////////////
  154. //  Lose controlling tty
  155. ///////////////////////////////////////////////////////////////////////////////
  156. int iFdTty = open("/dev/tty", O_RDWR);
  157. if (iFdTty >= 0) {
  158. ioctl(iFdTty, TIOCNOTTY, (char *) NULL);
  159. close(iFdTty);
  160. }
  161. #else
  162. ///////////////////////////////////////////////////////////////////////////////
  163. //  System V
  164. ///////////////////////////////////////////////////////////////////////////////
  165. if (setpgrp() == -1) {
  166. MnEventLog("Can't change process group : %s", strerror(errno));
  167. exit(errno);
  168. }
  169. signal(SIGHUP, SIG_IGN);
  170. ///////////////////////////////////////////////////////////////////////////////
  171. //  2nd fork
  172. ///////////////////////////////////////////////////////////////////////////////
  173. iChildPID = fork();
  174. if (iChildPID < 0) {
  175. MnEventLog("Cannot fork : %s", strerror(errno));
  176. exit(errno);
  177. } else if (iChildPID > 0)
  178. exit(0);
  179. #endif
  180. ///////////////////////////////////////////////////////////////////////////////
  181. //  Close open file descriptors
  182. ///////////////////////////////////////////////////////////////////////////////
  183. for (int fd = 0; fd < NOFILE; fd++)
  184. close(fd);
  185. ///////////////////////////////////////////////////////////////////////////////
  186. //  Set std handles
  187. ///////////////////////////////////////////////////////////////////////////////
  188. MnSetupStdHandles();
  189. ///////////////////////////////////////////////////////////////////////////////
  190. //  Probably got set to EBADF from a close
  191. ///////////////////////////////////////////////////////////////////////////////
  192. errno = 0;
  193. ///////////////////////////////////////////////////////////////////////////////
  194. //  Move the current directory to root, to make sure we aren't on a mounted
  195. //  filesystem.
  196. ///////////////////////////////////////////////////////////////////////////////
  197. chdir("/");
  198. ///////////////////////////////////////////////////////////////////////////////
  199. //  Clear any inherited file mode creation mask.
  200. ///////////////////////////////////////////////////////////////////////////////
  201. umask(0);
  202. ///////////////////////////////////////////////////////////////////////////////
  203. //  Ignore childs dead.
  204. ///////////////////////////////////////////////////////////////////////////////
  205. #ifdef __BSD__
  206. ///////////////////////////////////////////////////////////////////////////////
  207. //  BSD
  208. ///////////////////////////////////////////////////////////////////////////////
  209. signal(SIGCLD, MnSIGCLD);
  210. #else
  211. ///////////////////////////////////////////////////////////////////////////////
  212. //  System V
  213. ///////////////////////////////////////////////////////////////////////////////
  214. signal(SIGCLD, SIG_IGN);
  215. #endif
  216. return (0);
  217. }
  218. static int MnIsDebugStartup(int iArgCount, char *pszArgs[])
  219. {
  220. for (int ii = 0; ii < iArgCount; ii++)
  221. if (strcmp(pszArgs[ii], XMAIL_DEBUG_OPTION) == 0)
  222. return (1);
  223. return (0);
  224. }
  225. static int MnDaemonStartup(int iArgCount, char *pszArgs[])
  226. {
  227. ///////////////////////////////////////////////////////////////////////////////
  228. //  Daemon bootstrap code if We're not in debug mode
  229. ///////////////////////////////////////////////////////////////////////////////
  230. if (!MnIsDebugStartup(iArgCount, pszArgs))
  231. MnDaemonBootStrap();
  232. ///////////////////////////////////////////////////////////////////////////////
  233. //  Extract PID file name
  234. ///////////////////////////////////////////////////////////////////////////////
  235. char const *pszPidFile = strrchr(pszArgs[0], '/');
  236. pszPidFile = (pszPidFile != NULL) ? (pszPidFile + 1): pszArgs[0];
  237. ///////////////////////////////////////////////////////////////////////////////
  238. //  Create PID file
  239. ///////////////////////////////////////////////////////////////////////////////
  240. MnSavePID(pszPidFile);
  241. int iServerResult = SvrMain(iArgCount, pszArgs);
  242. ///////////////////////////////////////////////////////////////////////////////
  243. //  Remove PID file
  244. ///////////////////////////////////////////////////////////////////////////////
  245. MnRemovePID(pszPidFile);
  246. return (iServerResult);
  247. }
  248. int main(int iArgCount, char *pszArgs[])
  249. {
  250. return (MnDaemonStartup(iArgCount, pszArgs));
  251. }