SuperServer.c++
上传用户:weiyuanprp
上传日期:2020-05-20
资源大小:1169k
文件大小:4k
源码类别:

传真(Fax)编程

开发平台:

C/C++

  1. /* $Id: SuperServer.c++,v 1.3 2009/05/25 20:20:09 faxguy Exp $ */
  2. /*
  3.  * Copyright (c) 1995-1996 Sam Leffler
  4.  * Copyright (c) 1995-1996 Silicon Graphics, Inc.
  5.  * HylaFAX is a trademark of Silicon Graphics
  6.  *
  7.  * Permission to use, copy, modify, distribute, and sell this software and 
  8.  * its documentation for any purpose is hereby granted without fee, provided
  9.  * that (i) the above copyright notices and this permission notice appear in
  10.  * all copies of the software and related documentation, and (ii) the names of
  11.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  12.  * publicity relating to the software without the specific, prior written
  13.  * permission of Sam Leffler and Silicon Graphics.
  14.  * 
  15.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  16.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  17.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  18.  * 
  19.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  20.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  21.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  22.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  23.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  24.  * OF THIS SOFTWARE.
  25.  */
  26. #include "Sys.h"
  27. #include "Dispatcher.h"
  28. #include "HylaFAXServer.h"
  29. #include "SuperServer.h"
  30. #include "Socket.h"
  31. #define MAXTRIES 10
  32. SuperServer::SuperServer(const char* k, int bl) : kind(k)
  33. {
  34.     backlog = bl;
  35.     ntries = 0;
  36.     Dispatcher::instance().startTimer(0,1,this); // schedule setup
  37. }
  38. SuperServer::~SuperServer() {}
  39. void
  40. SuperServer::timerExpired(long, long)
  41. {
  42.     if (!startServer()) {
  43. if (++ntries >= MAXTRIES) {
  44.     logError("HylaFAX %s: Unable to init server, "
  45. "giving up after %u tries.", (const char*) kind, ntries);
  46.     return;
  47. }
  48. logNotice("HylaFAX %s: Unable to init server, "
  49.     "trying again in %u seconds.", (const char*) kind, 5*ntries);
  50. Dispatcher::instance().startTimer(5*ntries,0, this);
  51.     } else
  52. logNotice("HylaFAX %s Protocol Server: restarted.", (const char*) kind);
  53. }
  54. int
  55. SuperServer::inputReady(int fd)
  56. {
  57.     Socket::Address addr;
  58.     socklen_t slen = sizeof(addr);
  59.     int c = Socket::accept(fd, &addr, &slen);
  60.     if (c < 0) {
  61. if (errno == EINTR || errno == ECONNABORTED)
  62.     return (0);
  63. logError("HylaFAX %s: accept: %m", (const char*) kind);
  64. _exit(-1);
  65.     }
  66. #ifdef IPV6_ADDRFORM
  67.     if (Socket::family(addr) == AF_INET6) {
  68. struct in6_addr& a = addr.in6.sin6_addr;
  69. if ( (a.s6_addr32[0] == 0 && a.s6_addr32[1] == 0 && a.s6_addr32[2] == htonl(0xFFFF))  ||
  70.      (a.s6_addr32[0] == 0 && a.s6_addr32[1] == 0 && a.s6_addr32[2] == 0 && ntohl(a.s6_addr32[3]) > 1) ) {
  71.     logDebug("IPv4 address in AF_INET6, forcing AF_INET");
  72.     int af = AF_INET;
  73.     setsockopt(c, IPPROTO_IPV6, IPV6_ADDRFORM, &af, sizeof(af));
  74. }
  75.     }
  76. #endif
  77.     pid_t pid = fork();
  78.     switch (pid) {
  79.     case 0: // child
  80. /*
  81.  * Child process, setup to process protocol requests.
  82.  * We unlink the dispatcher hook to this code and
  83.  * setup the link to the main handler that processes
  84.  * protocol requests.  This routine is dispatched
  85.  * when data is received on stdin (for compatibility
  86.  * with servers started via inetd).
  87.  */
  88. HylaFAXServer* app; app = newChild(); // XXX for __GNUC__
  89. Dispatcher::instance().unlink(fd);
  90. HylaFAXServer::closeLogging(); // close any open syslog fd
  91. HylaFAXServer::closeAllDispatched();
  92. Sys::close(STDERR_FILENO);
  93. if (dup2(c, STDIN_FILENO) < 0 || dup2(c, STDOUT_FILENO) < 0) {
  94.     logError("HylaFAX %s: dup2: %m", (const char*) kind);
  95.     _exit(-1);
  96. }
  97. if (c != STDIN_FILENO && c != STDOUT_FILENO)
  98.     Sys::close(c);
  99. HylaFAXServer::setupLogging(); // reopen syslog before chroot
  100. app->open(); // opening greeting
  101. break;
  102.     case -1: // fork failure
  103. logError("HylaFAX %s: Cannot fork: %m", (const char*) kind);
  104. break;
  105.     default: // parent
  106. Sys::close(c);
  107. Dispatcher::instance().startChild(pid, this);
  108. break;
  109.     }
  110.     return (0); // indicate data was consumed
  111. }
  112. void
  113. SuperServer::childStatus(pid_t, int)
  114. {
  115.     /*
  116.      * Nothing to do here - childStatus means it's already been reaped, and
  117.      * thus off the queue from the Dispatcher
  118.      */
  119. }