(file) Return to server.c CVS log (file) (dir) Up to [OMI] / omi / server

   1 mike  1.1 /*
   2           **==============================================================================
   3           **
   4           ** Open Management Infrastructure (OMI)
   5           **
   6           ** Copyright (c) Microsoft Corporation
   7           ** 
   8           ** Licensed under the Apache License, Version 2.0 (the "License"); you may not 
   9           ** use this file except in compliance with the License. You may obtain a copy 
  10           ** of the License at 
  11           **
  12           **     http://www.apache.org/licenses/LICENSE-2.0 
  13           **
  14           ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15           ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
  16           ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
  17           ** MERCHANTABLITY OR NON-INFRINGEMENT. 
  18           **
  19           ** See the Apache 2 License for the specific language governing permissions 
  20           ** and limitations under the License.
  21           **
  22 mike  1.1 **==============================================================================
  23           */
  24           
  25           #include <limits.h>
  26           #include <protocol/protocol.h>
  27 krisbash 1.4 #include <pal/sleep.h>
  28 mike     1.2 #include <wsman/wsman.h>
  29 mike     1.1 #include <provreg/provreg.h>
  30              #include <provmgr/provmgr.h>
  31              #include <disp/disp.h>
  32 krisbash 1.4 #include <pal/strings.h>
  33              #include <pal/dir.h>
  34 mike     1.1 #include <base/log.h>
  35              #include <base/env.h>
  36              #include <base/process.h>
  37              #include <base/pidfile.h>
  38              #include <base/paths.h>
  39              #include <base/conf.h>
  40              #include <base/user.h>
  41 krisbash 1.4 #include <base/omigetopt.h>
  42              #include <base/multiplex.h>
  43              #include <base/Strand.h>
  44              #include <pal/format.h>
  45 krisbash 1.5 #include <pal/lock.h>
  46 mike     1.1 
  47              #if defined(CONFIG_POSIX)
  48              # include <signal.h>
  49              # include <sys/wait.h>
  50 krisbash 1.4 # include <pthread.h>
  51 mike     1.1 #endif
  52              
  53              typedef struct _ServerData ServerData;
  54              
  55              typedef enum _ServerTransportType
  56              {
  57                  SRV_PROTOCOL,
  58                  SRV_WSMAN
  59              }
  60              ServerTransportType;
  61              
  62              typedef struct _ServerCallbackData
  63              {
  64                  ServerData*         data;
  65                  ServerTransportType type;
  66              }
  67              ServerCallbackData;
  68              
  69              struct _ServerData
  70              {
  71 krisbash 1.4     Disp            disp;
  72                  MuxIn           mux;
  73                  ProtocolBase*   protocol;
  74 krisbash 1.5     WSMAN**         wsman;
  75                  int             wsman_size;
  76 krisbash 1.4     Selector        selector;
  77                  MI_Boolean      selectorInitialized;
  78 krisbash 1.5     MI_Boolean      reloadDispFlag;
  79 krisbash 1.4     MI_Boolean      terminated;
  80 mike     1.1 
  81                  /* pointers to self with different types - one per supported transport */
  82                  ServerCallbackData  protocolData;
  83                  ServerCallbackData  wsmanData;
  84              } ;
  85              
  86              typedef struct _Options
  87              {
  88                  MI_Boolean help;
  89 krisbash 1.4 #if !defined(CONFIG_FAVORSIZE)
  90 mike     1.1     MI_Boolean trace;
  91 krisbash 1.4 #endif
  92 mike     1.2     MI_Boolean httptrace;
  93 mike     1.1     MI_Boolean terminateByNoop;
  94              #if defined(CONFIG_POSIX)
  95                  MI_Boolean daemonize;
  96                  MI_Boolean stop;
  97                  MI_Boolean reloadConfig;
  98 krisbash 1.5     MI_Boolean reloadDispatcher;
  99 mike     1.1 #endif
 100                  /* mostly for unittesting in non-root env */
 101                  MI_Boolean ignoreAuthentication;
 102                  MI_Boolean locations;
 103                  MI_Boolean logstderr;
 104 krisbash 1.5     unsigned short *httpport;
 105                  int httpport_size;
 106                  unsigned short *httpsport;
 107                  int httpsport_size;
 108 krisbash 1.4     char* sslCipherSuite;
 109                  Server_SSL_Options sslOptions;
 110 mike     1.1     MI_Uint64 idletimeout;
 111                  MI_Uint64 livetime;
 112                  Log_Level logLevel;
 113              }
 114              Options;
 115              
 116 krisbash 1.5 static Lock s_disp_mutex = LOCK_INITIALIZER;
 117              
 118 mike     1.1 static Options s_opts;
 119              
 120              static ServerData s_data;
 121              
 122              static const char* arg0 = 0;
 123              
 124 krisbash 1.4 static const ZChar HELP[] = ZT("\
 125 mike     1.1 Usage: %s [OPTIONS]\n\
 126              \n\
 127              This program starts the server.\n\
 128              \n\
 129              OPTIONS:\n\
 130                  -h, --help                  Print this help message.\n\
 131                  -d                          Daemonize the server process (POSIX only).\n\
 132                  -s                          Stop the server process (POSIX only).\n\
 133                  -r                          Re-read configuration by the running server (POSIX only).\n\
 134 krisbash 1.5     --reload-dispatcher         Re-read configuration by the running server (POSIX only), but don't unload providers.\n\
 135 mike     1.1     --httpport PORT             HTTP protocol listener port.\n\
 136                  --httpsport PORT            HTTPS protocol listener port.\n\
 137                  --idletimeout TIMEOUT       Idle providers unload timeout (in seconds).\n\
 138                  -v, --version               Print version information.\n\
 139                  -l, --logstderr             Send log output to standard error.\n\
 140                  --loglevel LEVEL            Set logging level to one of the following\n\
 141                                              symbols/numbers: fatal/0, error/1, warning/2,\n\
 142 krisbash 1.4                                 info/3, debug/4, verbose/5 (default 2).\n\
 143 mike     1.2     --httptrace                 Enable logging of HTTP traffic.\n\
 144 krisbash 1.4     --timestamp                 Print timestamp server was built with.\n\
 145              \n");
 146              
 147              STRAND_DEBUGNAME( NoopRequest );
 148 mike     1.1 
 149 krisbash 1.4 static void FUNCTION_NEVER_RETURNS err(const ZChar* fmt, ...)
 150 mike     1.1 {
 151                  va_list ap;
 152                  memset(&ap, 0, sizeof(ap));
 153              
 154 krisbash 1.4     Ftprintf(stderr, ZT("%s: "), scs(arg0));
 155 mike     1.1 
 156                  va_start(ap, fmt);
 157 krisbash 1.4     Vftprintf(stderr, fmt, ap);
 158 mike     1.1     va_end(ap);
 159              
 160                  /* Write to log as well */
 161                  va_start(ap, fmt);
 162 krisbash 1.4     __LOGE((fmt, ap));
 163 mike     1.1     va_end(ap);
 164              
 165 krisbash 1.4     Ftprintf(stderr, ZT("\n"));
 166 mike     1.1     exit(1);
 167              }
 168              
 169 krisbash 1.4 static void FUNCTION_NEVER_RETURNS info_exit(const ZChar* fmt, ...)
 170 mike     1.1 {
 171 krisbash 1.4     va_list ap;
 172                  memset(&ap, 0, sizeof(ap));
 173              
 174                  Ftprintf(stderr, ZT("%s: "), scs(arg0));
 175              
 176                  va_start(ap, fmt);
 177                  Vftprintf(stderr, fmt, ap);
 178                  va_end(ap);
 179              
 180                  /* Write to log as well */
 181                  va_start(ap, fmt);
 182                  __LOGI((fmt, ap));
 183                  va_end(ap);
 184              
 185                  Ftprintf(stderr, ZT("\n"));
 186                  exit(0);
 187              }
 188 mike     1.1 
 189 krisbash 1.4 void PrintProviderMsg( _In_ Message* msg)
 190              {
 191              #if !defined(CONFIG_FAVORSIZE)
 192                  if (s_opts.trace)
 193 mike     1.1     {
 194 krisbash 1.4         switch ( msg->tag )
 195 mike     1.1         {
 196 krisbash 1.4             case PostResultMsgTag:
 197 mike     1.1             {
 198 krisbash 1.4                 const PostResultMsg* rsp = (const PostResultMsg*)msg;
 199 mike     1.1                 PostResultMsg_Print(rsp, stdout);
 200                          }
 201 krisbash 1.4             break;
 202 mike     1.1 
 203 krisbash 1.4             case PostInstanceMsgTag:
 204 mike     1.1             {
 205 krisbash 1.4                 const PostInstanceMsg* rsp = (const PostInstanceMsg*)msg;
 206 mike     1.1                 PostInstanceMsg_Print(rsp, stdout);
 207                          }
 208 krisbash 1.4             break;
 209 mike     1.1 
 210 krisbash 1.4             case PostSchemaMsgTag:
 211 mike     1.1             {
 212 krisbash 1.4                 const PostSchemaMsg* rsp = (const PostSchemaMsg*)msg;
 213                              PostSchemaMsg_Print(rsp, stdout);
 214 mike     1.1             }
 215 krisbash 1.4             break;
 216 mike     1.1 
 217 krisbash 1.4             case NoOpRspTag:
 218                              break;  // send noop confirmation to the client 
 219 mike     1.1 
 220 krisbash 1.4             default:
 221                          {
 222                              trace_UnknownMessageType(msg->tag);
 223                              exit(1);
 224                          }
 225 mike     1.1         }
 226                  }
 227 krisbash 1.4 #endif // !defined(CONFIG_FAVORSIZE)
 228              }
 229 mike     1.1 
 230 krisbash 1.4 /*
 231                  Simple interaction object to respond to the noop request.
 232                  It just sends a noop response and closes the interaction
 233                  (therefore shutting down)
 234              */
 235              void _NoopInteractionAck( _In_ Strand* self) 
 236              {
 237                  // do nothing
 238              }
 239 mike     1.1 
 240 krisbash 1.4 StrandFT _NoopInteractionUserFT = { 
 241                      NULL, 
 242                      NULL, 
 243                      _NoopInteractionAck, 
 244                      NULL, 
 245                      NULL, 
 246                      NULL,
 247                      NULL,
 248                      NULL, 
 249                      NULL, 
 250                      NULL, 
 251                      NULL, 
 252                      NULL };
 253 mike     1.1 
 254 krisbash 1.4 static void _ProcessNoopRequest(
 255                  _Inout_     InteractionOpenParams*  params )
 256 mike     1.1 {
 257 krisbash 1.4     Strand* strand;
 258                  NoOpReq* req = (NoOpReq*)params->msg;
 259                  NoOpRsp* rsp;
 260 mike     1.1 
 261 krisbash 1.4 #if !defined(CONFIG_FAVORSIZE)
 262                  if (s_opts.trace)
 263                  {
 264                      NoOpReq_Print(req, stdout);
 265                  }
 266              #endif
 267                          
 268                  strand = Strand_New( STRAND_DEBUG( NoopRequest ) &_NoopInteractionUserFT, 0, STRAND_FLAG_ENTERSTRAND, params );
 269 mike     1.1 
 270 krisbash 1.4     if( NULL == strand )
 271 mike     1.1     {
 272 krisbash 1.4         err(ZT("out of memory"));
 273                      trace_OutOfMemory();
 274                      Strand_FailOpen(params);
 275                      return;
 276                  }
 277 mike     1.1 
 278 krisbash 1.4     /* Send NoOp response back */
 279                  rsp = NoOpRsp_New(req->base.base.operationId);
 280 mike     1.1 
 281 krisbash 1.4     if (!rsp)
 282                  {
 283                      err(ZT("out of memory"));
 284                      trace_OutOfMemory();
 285                      Strand_FailOpen(params);
 286                      return;
 287                  }
 288 mike     1.1 
 289 krisbash 1.4 #if !defined(CONFIG_FAVORSIZE)
 290                  if (s_opts.trace)
 291                  {
 292                      NoOpRsp_Print(rsp, stdout);
 293                  }
 294              #endif
 295 mike     1.1 
 296 krisbash 1.4     Strand_Ack( strand );   // Ack open msg
 297                  Strand_Post( strand, &rsp->base );
 298                  Strand_Close( strand );   
 299                  Strand_Leave( strand);
 300                  
 301                  NoOpRsp_Release(rsp);
 302              
 303                  trace_ServerReceivedNoOpReqTag( (int)s_opts.terminateByNoop );
 304                  
 305                  if (s_opts.terminateByNoop)
 306                  {
 307                      s_data.terminated = MI_TRUE;
 308                      Selector_StopRunning(&s_data.selector);
 309                  }
 310              }
 311 mike     1.1 
 312 krisbash 1.4 /* Called by protocol stack to dispatch an incoming request message */
 313              static void _RequestCallback(
 314                  _Inout_ InteractionOpenParams* interactionParams )
 315              {
 316                  ServerCallbackData* self = (ServerCallbackData*)interactionParams->callbackData;
 317                  Message* msg = interactionParams->msg;
 318                  MI_Result result;
 319              
 320                  DEBUG_ASSERT( NULL != interactionParams );
 321                  DEBUG_ASSERT( NULL != msg );
 322                  
 323                  if (NoOpReqTag == msg->tag)
 324                  {
 325                      _ProcessNoopRequest( interactionParams );
 326                      return;
 327 mike     1.1     }
 328              
 329 krisbash 1.4 #if 1 // !defined(CONFIG_FAVORSIZE)
 330 mike     1.1     if (s_opts.trace)
 331                  {
 332                      MessagePrint(msg, stdout);
 333                  }
 334 krisbash 1.4 #endif
 335 krisbash 1.5     
 336                  Lock_Acquire(&s_disp_mutex);
 337 krisbash 1.4     result = Disp_HandleInteractionRequest(
 338                              &self->data->disp, 
 339                              interactionParams );
 340 krisbash 1.5     Lock_Release(&s_disp_mutex);
 341 krisbash 1.4     if( result != MI_RESULT_OK )
 342 mike     1.1     {
 343 krisbash 1.4         Strand_FailOpenWithResult(interactionParams, result, PostResultMsg_NewAndSerialize);
 344 mike     1.1     }
 345              }
 346 krisbash 1.4  
 347 mike     1.1 static void GetCommandLineDestDirOption(
 348                  int* argc_,
 349                  const char* argv[])
 350              {
 351                  int argc = *argc_;
 352                  int i;
 353                  const char* destdir = NULL;
 354              
 355                  for (i = 1; i < argc; )
 356                  {
 357                      if (strcmp(argv[i], "--destdir") == 0)
 358                      {
 359                          if (i + 1 == argc)
 360 krisbash 1.4                 err(ZT("missing argument for --destdir option"));
 361 mike     1.1 
 362                          destdir = argv[i+1];
 363                          memmove((char*)&argv[i], (char*)&argv[i+2], 
 364                              sizeof(char*) * (argc-i-1));
 365                          argc -= 2;
 366                      }
 367                      else if (strncmp(argv[i], "--destdir=", 10) == 0)
 368                      {
 369                          destdir = argv[i] + 10;
 370                          memmove((char*)&argv[i], (char*)&argv[i+1], 
 371                              sizeof(char*) * (argc-i));
 372              
 373                          argc -= 1;
 374                      }
 375                      else
 376                          i++;
 377                  }
 378              
 379                  if (destdir)
 380                  {
 381                      if (SetPath(ID_DESTDIR, destdir) != 0)
 382 krisbash 1.4             err(ZT("failed to set destdir"));
 383 mike     1.1     }
 384              
 385                  *argc_ = argc;
 386              }
 387              
 388 krisbash 1.5 /*
 389               * Parse an HTTP or HTTPS port specification:
 390               *
 391               *   "1270" would simply place 1270 in the list,
 392               *   "1270,5599" would place port 1270 and port 5599 to the list
 393               *
 394               * Returns 0 if parameter was good, non-zero if parameter was bad
 395               */
 396              static int ParseHttpPortSpecification(unsigned short **ports, int *size, const char *spec, unsigned short defport)
 397              {
 398                  // defport is unused (no longer support "+" to add default port
 399                  (void) defport;
 400              
 401                  // Ignore anything that is already stored
 402                  *size = 0;
 403              
 404                  // Skip leading spaces
 405                  char *saveptr;
 406                  char *ptr = (char *) spec;
 407                  while (*ptr == ' ')
 408                  {
 409 krisbash 1.5         ptr++;
 410                  }
 411              
 412                  while ( 1 )
 413                  {
 414                      unsigned long x;
 415                      char *end = NULL;
 416              
 417                      char *token = Strtok(ptr, ",", &saveptr);
 418                      ptr = NULL;
 419                      if (NULL == token)
 420                      {
 421                          break;
 422                      }
 423              
 424                      x = Strtoul(token, &end, 10);
 425                      if (*end != '\0' || x > USHRT_MAX)
 426                      {
 427                          return 1;
 428                      }
 429              
 430 krisbash 1.5         /* Don't add a port of '0' */
 431                      if ( x != 0 )
 432                      {
 433                          /* Don't add duplicate ports; just ignore second port */
 434                          int found = 0, i;
 435                          for (i = 0; i < (*size); ++i)
 436                          {
 437                              if ( (*ports)[i] == x )
 438                              {
 439                                  found = 1;
 440                                  break;
 441                              }
 442                          }
 443              
 444                          if ( ! found )
 445                          {
 446                              int bytes = ++(*size) * sizeof(unsigned int);
 447                              *ports = PAL_Realloc(*ports, bytes);
 448                              if ( (*ports) == 0 )
 449                              {
 450                                  err(ZT("memory allocation failure allocating %d bytes"), bytes);
 451 krisbash 1.5                 }
 452              
 453                              (*ports)[(*size) - 1] = x;
 454                          }
 455                      }
 456                  }
 457              
 458                  return 0;
 459              }
 460              
 461 mike     1.1 static void GetCommandLineOptions(
 462                  int* argc_,
 463                  const char* argv[])
 464              {
 465                  int argc = *argc_;
 466                  GetOptState state = GETOPTSTATE_INITIALIZER;
 467                  static const char* opts[] =
 468                  {
 469                      "-h",
 470                      "--help",
 471                      "-p",
 472                      "-t",
 473 mike     1.2         "--httptrace",
 474 krisbash 1.4         "--timestamp",
 475 mike     1.1         "--stopnoop",
 476                      "-v",
 477                      "--version",
 478                      "-d",
 479                      "-s",
 480                      "-r",
 481                      "--httpport:",
 482                      "--httpsport:",
 483                      "--idletimeout:",
 484                      "--livetime:",
 485                      "--ignoreAuthentication",
 486                      "-i",
 487                      "--prefix:",
 488                      "--libdir:",
 489                      "--bindir:",
 490                      "--localstatedir:",
 491                      "--sysconfdir:",
 492                      "--providerdir:",
 493 krisbash 1.4                 "--registerdir:",
 494 mike     1.1         "--certsdir:",
 495                      "--rundir:",
 496                      "--logdir:",
 497                      "--pidfile:",
 498                      "--logfile:",
 499 krisbash 1.4         "--configfile:",
 500 mike     1.1         "--socketfile:",
 501                      "--pemfile:",
 502                      "--keyfile:",
 503                      "--agentprogram:",
 504                      "--serverprogram:",
 505                      "--logstderr",
 506                      "--loglevel:",
 507                      "-l",
 508 krisbash 1.4         "--testopts",
 509 krisbash 1.5         "--reload-dispatcher",
 510 mike     1.1         NULL,
 511                  };
 512              
 513                  for (;;)
 514                  {
 515                      int r = GetOpt(&argc, argv, opts, &state);
 516              
 517                      if (r == 1)
 518                          break;
 519              
 520                      if (r == -1)
 521                      {
 522 krisbash 1.4             Ftprintf(stderr, ZT("error: %s\n"), scs(state.err));
 523 mike     1.1             exit(1);
 524                      }
 525              
 526                      if (strcmp(state.opt, "-h") == 0 ||
 527                          strcmp(state.opt, "--help") == 0)
 528                      {
 529                          s_opts.help = MI_TRUE;
 530                      }
 531                      else if (strcmp(state.opt, "-p") == 0)
 532                      {
 533                          s_opts.locations = MI_TRUE;
 534                      }
 535 krisbash 1.4 #if !defined(CONFIG_FAVORSIZE)
 536 mike     1.1         else if (strcmp(state.opt, "-t") == 0)
 537                      {
 538                          s_opts.trace = MI_TRUE;
 539                      }
 540 krisbash 1.4 #endif
 541 mike     1.2         else if (strcmp(state.opt, "--httptrace") == 0)
 542                      {
 543                          s_opts.httptrace = MI_TRUE;
 544                      }
 545 krisbash 1.4         else if (strcmp(state.opt, "--timestamp") == 0)
 546                      {
 547              #if defined(CONFIG_OS_WINDOWS)
 548                          Tprintf(PAL_T("%s: %T\n"), scs(arg0), tcs(CONFIG_TIMESTAMP));
 549              #else
 550                          Tprintf(ZT("%s: %s\n"), scs(arg0), scs(CONFIG_TIMESTAMP));
 551              #endif
 552                          exit(0);
 553                      }
 554 mike     1.1         else if (strcmp(state.opt, "--stopnoop") == 0)
 555                      {
 556                          s_opts.terminateByNoop = MI_TRUE;
 557                      }
 558                      else if (strcmp(state.opt, "-v") == 0 ||
 559                              strcmp(state.opt, "--version") == 0)
 560                      {
 561 krisbash 1.4 #if defined(CONFIG_OS_WINDOWS)
 562                          Tprintf(PAL_T("%s: %T\n"), scs(arg0),
 563                              tcs(CONFIG_PRODUCT PAL_T("-") CONFIG_VERSION PAL_T(" - ") CONFIG_DATE));
 564              #else
 565                          Tprintf(ZT("%s: %s\n"), scs(arg0),
 566                              scs(CONFIG_PRODUCT "-" CONFIG_VERSION " - " CONFIG_DATE));
 567              #endif
 568 mike     1.1             exit(0);
 569                      }
 570              #if defined(CONFIG_POSIX)
 571                      else if (strcmp(state.opt, "-d") == 0)
 572                      {
 573                          s_opts.daemonize = MI_TRUE;
 574                      }
 575                      else if (strcmp(state.opt, "-s") == 0)
 576                      {
 577                          s_opts.stop = MI_TRUE;
 578                      }
 579                      else if (strcmp(state.opt, "-r") == 0)
 580                      {
 581                          s_opts.reloadConfig = MI_TRUE;
 582                      }
 583 krisbash 1.5         else if (strcmp(state.opt, "--reload-dispatcher") == 0)
 584                      {
 585                          s_opts.reloadDispatcher = MI_TRUE;
 586                      }
 587 mike     1.1 #endif
 588                      else if (strcmp(state.opt, "--httpport") == 0)
 589                      {
 590 krisbash 1.5             if ( ParseHttpPortSpecification(&s_opts.httpport, &s_opts.httpport_size, state.arg, CONFIG_HTTPPORT) )
 591 krisbash 1.4             {
 592                              err(ZT("bad option argument for --httpport: %s"), 
 593                                  scs(state.arg));
 594                          }
 595 mike     1.1         }
 596                      else if (strcmp(state.opt, "--httpsport") == 0)
 597                      {
 598 krisbash 1.5             if ( ParseHttpPortSpecification(&s_opts.httpsport, &s_opts.httpsport_size, state.arg, CONFIG_HTTPSPORT) )
 599 krisbash 1.4             {
 600                              err(ZT("bad option argument for --httpsport: %s"), 
 601                                  scs(state.arg));
 602                          }
 603 mike     1.1         }
 604                      else if (strcmp(state.opt, "--idletimeout") == 0)
 605                      {
 606                          char* end;
 607                          MI_Uint64 x = Strtoull(state.arg, &end, 10);
 608              
 609                          if (*end != '\0')
 610 krisbash 1.4             {
 611                              err(ZT("bad option argument for --idletimeout: %s"), 
 612                                  scs(state.arg));
 613                          }
 614 mike     1.1 
 615                          s_opts.idletimeout = x;
 616                      }
 617                      else if (strcmp(state.opt, "--livetime") == 0)
 618                      {
 619                          char* end;
 620                          MI_Uint64 x = Strtoull(state.arg, &end, 10);
 621              
 622                          if (*end != '\0')
 623 krisbash 1.4             {
 624                              err(ZT("bad option argument for --livetime: %s"), 
 625                                  scs(state.arg));
 626                          }
 627 mike     1.1 
 628                          s_opts.livetime = x;
 629                      }
 630                      else if (strcmp(state.opt, "--ignoreAuthentication") == 0 ||
 631                           strcmp(state.opt, "-i") == 0)
 632                      {
 633                          s_opts.ignoreAuthentication = MI_TRUE;
 634                      }
 635                      else if (strcmp(state.opt, "--logstderr") == 0 ||
 636                           strcmp(state.opt, "-l") == 0)
 637                      {
 638                          s_opts.logstderr = MI_TRUE;
 639                      }
 640                      else if (strcmp(state.opt, "--loglevel") == 0)
 641                      {
 642                          if (Log_SetLevelFromString(state.arg) != 0)
 643                          {
 644 krisbash 1.4                 err(ZT("bad option argument for %s: %s"), 
 645                                  scs(state.opt), scs(state.arg));
 646                          }
 647                      }
 648                      else if (strcmp(state.opt, "--testopts") == 0)
 649                      {
 650                          s_opts.httptrace = MI_TRUE;
 651              
 652                          if (Log_SetLevelFromString("DEBUG") != 0)
 653                          {
 654                              err(ZT("bad argument for Log_SetLevelFromString()"));
 655 mike     1.1             }
 656                      }
 657                      else if (strncmp(state.opt, "--", 2) == 0 && IsNickname(state.opt+2))
 658                      {
 659                          if (SetPathFromNickname(state.opt+2, state.arg) != 0)
 660 krisbash 1.4                 err(ZT("SetPathFromNickname() failed"));
 661 mike     1.1         }
 662                  }
 663              
 664                  *argc_ = argc;
 665              }
 666              
 667              static void OpenLogFile()
 668              {
 669                  if (s_opts.logstderr)
 670                  {
 671                      if (Log_OpenStdErr() != MI_RESULT_OK)
 672 krisbash 1.4             err(ZT("failed to open log file to stderr"));
 673 mike     1.1     }
 674                  else
 675                  {
 676 krisbash 1.4         TChar path[PAL_MAX_PATH_SIZE];
 677                      TcsStrlcpy(path, OMI_GetPath(ID_LOGFILE), MI_COUNT(path));
 678 mike     1.1 
 679                      /* Open the log file */
 680                      if (Log_Open(path) != MI_RESULT_OK)
 681 krisbash 1.4             err(PAL_T("failed to open log file: %T"), tcs(path));
 682 mike     1.1     }
 683              }
 684              
 685              #if defined(CONFIG_POSIX)
 686 krisbash 1.4 
 687 mike     1.1 static void _HandleSIGTERM(int sig)
 688              {
 689                  if (sig == SIGTERM && s_data.selectorInitialized)
 690                  {
 691 krisbash 1.4         const char* socketFile = OMI_GetPath(ID_SOCKETFILE);
 692 mike     1.1         s_data.terminated = MI_TRUE;
 693                      Selector_StopRunning(&s_data.selector);
 694 krisbash 1.4         if (socketFile != NULL && *socketFile != '\0')
 695                          unlink(socketFile);
 696 mike     1.1     }
 697              }
 698              
 699              static void _HandleSIGHUP(int sig)
 700              {
 701                  if (sig == SIGHUP && s_data.selectorInitialized)
 702                  {
 703                      Selector_StopRunning(&s_data.selector);
 704                  }
 705              }
 706              
 707 krisbash 1.5 // We reload the ProvReg structure in the Dispatcher when this signal is received.
 708              // This gives us access to providers that are installed after the omiserver is running without terminating current providers that are running.
 709              static void _HandleSIGUSR1(int sig)
 710              {
 711                  if (sig == SIGUSR1)
 712                  {
 713                      s_data.reloadDispFlag = MI_TRUE;
 714                  }
 715              }
 716              
 717 krisbash 1.4 /* An array of PIDS that abnormally exited */
 718              #define NPIDS 16
 719              static pid_t _pids[NPIDS];
 720              static volatile size_t _npids;
 721              
 722 mike     1.1 static void _HandleSIGCHLD(int sig)
 723              {
 724                  if (sig == SIGCHLD)
 725                  {
 726 krisbash 1.4         for (;;)
 727                      {
 728                          int status = 0;
 729                          pid_t pid = waitpid(-1, &status, WNOHANG);
 730              
 731                          /* If abnormal exit, append to PIDs array */
 732                          if (pid > 0 && !WIFEXITED(status))
 733                          {
 734                              /* Save PID so error can be logged outside this function */
 735                              if (_npids < NPIDS)
 736                                  _pids[_npids++] = pid;
 737                          }
 738              
 739                          if (pid > 0 || (pid == -1 && errno == EINTR))
 740                              continue;
 741              
 742                          break;
 743                      }
 744 mike     1.1     }
 745              }
 746 krisbash 1.4 
 747              #endif /* defined(CONFIG_POSIX) */
 748 mike     1.1 
 749              static void _PrintPaths()
 750              {
 751                  PrintPaths();
 752              }
 753              
 754              static void GetConfigFileOptions()
 755              {
 756 krisbash 1.4     char path[PAL_MAX_PATH_SIZE];
 757 mike     1.1     Conf* conf;
 758              
 759                  /* Form the configuration file path */
 760 krisbash 1.4     Strlcpy(path, OMI_GetPath(ID_CONFIGFILE), sizeof(path));
 761 mike     1.1 
 762                  /* Open the configuration file */
 763                  conf = Conf_Open(path);
 764                  if (!conf)
 765 krisbash 1.4         err(ZT("failed to open configuration file: %s"), scs(path));
 766 mike     1.1 
 767                  /* For each key=value pair in configuration file */
 768                  for (;;)
 769                  {
 770                      const char* key;
 771                      const char* value;
 772                      int r = Conf_Read(conf, &key, &value);
 773              
 774                      if (r == -1)
 775 krisbash 1.4             err(ZT("%s: %s\n"), path, scs(Conf_Error(conf)));
 776 mike     1.1 
 777                      if (r == 1)
 778                          break;
 779              
 780                      if (strcmp(key, "httpport") == 0)
 781                      {
 782 krisbash 1.5             if ( ParseHttpPortSpecification(&s_opts.httpport, &s_opts.httpport_size, value, CONFIG_HTTPPORT) )
 783 mike     1.1             {
 784 krisbash 1.4                 err(ZT("%s(%u): invalid value for '%s': %s"), scs(path), 
 785                                  Conf_Line(conf), scs(key), scs(value));
 786 mike     1.1             }
 787                      }
 788                      else if (strcmp(key, "httpsport") == 0)
 789                      {
 790 krisbash 1.5             if ( ParseHttpPortSpecification(&s_opts.httpsport, &s_opts.httpsport_size, value, CONFIG_HTTPSPORT) )
 791 mike     1.1             {
 792 krisbash 1.4                 err(ZT("%s(%u): invalid value for '%s': %s"), scs(path), 
 793                                  Conf_Line(conf), scs(key), scs(value));
 794 mike     1.1             }
 795                      }
 796                      else if (strcmp(key, "idletimeout") == 0)
 797                      {
 798                          char* end;
 799                          MI_Uint64 x = Strtoull(value, &end, 10);
 800              
 801                          if (*end != '\0')
 802                          {
 803 krisbash 1.4                 err(ZT("%s(%u): invalid value for '%s': %s"), scs(path), 
 804                                  Conf_Line(conf), scs(key), scs(value));
 805 mike     1.1             }
 806              
 807                          s_opts.idletimeout = x;
 808                      }
 809                      else if (strcmp(key, "livetime") == 0)
 810                      {
 811                          char* end;
 812                          MI_Uint64 x = Strtoull(value, &end, 10);
 813              
 814                          if (*end != '\0')
 815                          {
 816 krisbash 1.4                 err(ZT("%s(%u): invalid value for '%s': %s"), scs(path), 
 817                                  Conf_Line(conf), scs(key), scs(value));
 818 mike     1.1             }
 819              
 820                          s_opts.livetime = x;
 821                      }
 822                      else if (strcmp(key, "trace") == 0)
 823                      {
 824                          if (Strcasecmp(value, "true") == 0)
 825                          {
 826 krisbash 1.4 #if !defined(CONFIG_FAVORSIZE)
 827 mike     1.1                 s_opts.trace = MI_TRUE;
 828 krisbash 1.4 #endif
 829 mike     1.1             }
 830                          else if (Strcasecmp(value, "false") == 0)
 831                          {
 832 krisbash 1.4 #if !defined(CONFIG_FAVORSIZE)
 833 mike     1.1                 s_opts.trace = MI_FALSE;
 834 krisbash 1.4 #endif
 835 mike     1.1             }
 836                          else
 837                          {
 838 krisbash 1.4                 err(ZT("%s(%u): invalid value for '%s': %s"), scs(path), 
 839                                  Conf_Line(conf), scs(key), scs(value));
 840 mike     1.1             }
 841                      }
 842 mike     1.2         else if (strcmp(key, "httptrace") == 0)
 843                      {
 844                          if (Strcasecmp(value, "true") == 0)
 845                          {
 846                              s_opts.httptrace = MI_TRUE;
 847                          }
 848                          else if (Strcasecmp(value, "false") == 0)
 849                          {
 850                              s_opts.httptrace = MI_FALSE;
 851                          }
 852                          else
 853                          {
 854 krisbash 1.4                 err(ZT("%s(%u): invalid value for '%s': %s"), scs(path), 
 855                                  Conf_Line(conf), scs(key), scs(value));
 856                          }
 857                      }
 858                      else if (strcmp(key, "loglevel") == 0)
 859                      {
 860                          if (Log_SetLevelFromString(value) != 0)
 861                          {
 862                              err(ZT("%s(%u): invalid value for '%s': %s"), scs(path), 
 863                                  Conf_Line(conf), scs(key), scs(value));
 864                          }
 865                      }
 866                      else if (strcmp(key, "sslciphersuite") == 0)
 867                      {
 868                          size_t valueLength = strlen(value);
 869                          s_opts.sslCipherSuite = PAL_Malloc(valueLength + 1);
 870                          if (s_opts.sslCipherSuite == NULL)
 871                              err(ZT("Out of memory"));
 872                          Strlcpy(s_opts.sslCipherSuite, value, valueLength+1);
 873                          s_opts.sslCipherSuite[valueLength] = '\0';
 874                      }
 875 krisbash 1.5         else if (strcmp(key, "NoSSLv2") == 0)
 876 krisbash 1.4         {
 877                          if (Strcasecmp(value, "true") == 0)
 878                          {
 879                              s_opts.sslOptions |= DISABLE_SSL_V2;
 880                          }
 881 krisbash 1.5             else if (Strcasecmp(value, "false") == 0)
 882                          {
 883                              s_opts.sslOptions &= ~DISABLE_SSL_V2;
 884                          }
 885                          else
 886 krisbash 1.4             {
 887                              err(ZT("%s(%u): invalid value for '%s': %s"), scs(path),
 888                                  Conf_Line(conf), scs(key), scs(value));
 889                          }
 890                      }
 891 krisbash 1.5         else if (strcmp(key, "NoSSLv3") == 0)
 892 krisbash 1.4         {
 893                          if (Strcasecmp(value, "true") == 0)
 894                          {
 895                              s_opts.sslOptions |= DISABLE_SSL_V3;
 896                          }
 897 krisbash 1.5             else if (Strcasecmp(value, "false") == 0)
 898                          {
 899                              s_opts.sslOptions &= ~DISABLE_SSL_V3;
 900                          }
 901                          else
 902 krisbash 1.4             {
 903                              err(ZT("%s(%u): invalid value for '%s': %s"), scs(path),
 904                                  Conf_Line(conf), scs(key), scs(value));
 905 mike     1.2             }
 906                      }
 907 mike     1.1         else if (IsNickname(key))
 908                      {
 909                          if (SetPathFromNickname(key, value) != 0)
 910 krisbash 1.4                 err(ZT("SetPathFromNickname() failed"));
 911 mike     1.1         }
 912                      else
 913                      {
 914 krisbash 1.4             err(ZT("%s(%u): unknown key: %s"), scs(path), Conf_Line(conf), 
 915                              scs(key));
 916 mike     1.1         }
 917                  }
 918              
 919                  /* Close configuration file */
 920                  Conf_Close(conf);
 921              
 922                  return;
 923              }
 924              
 925              int servermain(int argc, const char* argv[])
 926              {
 927                  MI_Result r;
 928              #if defined(CONFIG_POSIX)
 929                  int pidfile = -1;
 930              #endif
 931              
 932                  arg0 = argv[0];
 933              
 934                  memset(&s_data, 0, sizeof(s_data));
 935              
 936                  /* Set default options */
 937 krisbash 1.5     s_opts.httpport = PAL_Malloc(sizeof(unsigned short));
 938                  s_opts.httpport[0] = CONFIG_HTTPPORT;
 939                  s_opts.httpport_size = 1;
 940              
 941                  s_opts.httpsport = PAL_Malloc(sizeof(unsigned short));
 942                  s_opts.httpsport[0] = CONFIG_HTTPSPORT;
 943                  s_opts.httpsport_size = 1;
 944              
 945                  s_opts.sslOptions = DISABLE_SSL_V2;
 946 mike     1.1     s_opts.idletimeout = 0;
 947                  s_opts.livetime = 0;
 948              
 949                  /* Get --destdir command-line option */
 950                  GetCommandLineDestDirOption(&argc, argv);
 951              
 952                  /* Extract configuration file options */
 953                  GetConfigFileOptions();
 954              
 955                  /* Extract command-line options a second time (to override) */
 956                  GetCommandLineOptions(&argc, argv);
 957              
 958                  /* Open the log file */
 959                  OpenLogFile();
 960              
 961                  /* Print help */
 962                  if (s_opts.help)
 963                  {
 964 krisbash 1.4         Ftprintf(stderr, HELP, scs(arg0));
 965 mike     1.1         exit(1);
 966                  }
 967              
 968                  /* Print locations of files and directories */
 969                  if (s_opts.locations)
 970                  {
 971                      _PrintPaths();
 972 krisbash 1.4         Tprintf(ZT("\n"));
 973 mike     1.1         exit(0);
 974                  }
 975              
 976              #if defined(CONFIG_POSIX)
 977                  if (s_opts.stop || s_opts.reloadConfig)
 978                  {
 979                      if (PIDFile_IsRunning() != 0)
 980 krisbash 1.4             info_exit(ZT("server is not running\n"));
 981 mike     1.1 
 982                      if (PIDFile_Signal(s_opts.stop ? SIGTERM : SIGHUP) != 0)
 983 krisbash 1.4             err(ZT("failed to stop server\n"));
 984 mike     1.1 
 985                      if (s_opts.stop)
 986 krisbash 1.4             Tprintf(ZT("%s: stopped server\n"), scs(arg0));
 987 mike     1.1         else
 988 krisbash 1.4             Tprintf(ZT("%s: refreshed server\n"), scs(arg0));
 989 mike     1.1 
 990                      exit(0);
 991                  }
 992 krisbash 1.5     if (s_opts.reloadDispatcher)
 993                  {
 994                      if (PIDFile_IsRunning() != 0)
 995                          info_exit(ZT("server is not running\n"));
 996              
 997                      if (PIDFile_Signal(SIGUSR1) != 0)
 998                          err(ZT("failed to reload dispatcher on the server\n"));
 999              
1000                      Tprintf(ZT("%s: server has reloaded its dispatcher\n"), scs(arg0));
1001              
1002                      exit(0);        
1003                  }
1004 mike     1.1 #endif
1005              
1006              #if defined(CONFIG_POSIX)
1007              
1008                  if (PIDFile_IsRunning() == 0)
1009 krisbash 1.4         err(ZT("server is already running\n"));
1010 mike     1.1 
1011                  /* Verify that server is started as root */
1012                  if (0 != IsRoot() && !s_opts.ignoreAuthentication)
1013                  {
1014 krisbash 1.4         err(ZT("expected to run as root"));
1015 mike     1.1     }
1016              
1017                  /* ATTN: unit-test support; should be removed/ifdefed later */
1018                  if (s_opts.ignoreAuthentication)
1019                  {
1020                      IgnoreAuthCalls(1);
1021                  }
1022              
1023                  /* Watch for SIGTERM signals */
1024                  if (0 != SetSignalHandler(SIGTERM, _HandleSIGTERM) ||
1025 krisbash 1.5         0 != SetSignalHandler(SIGHUP, _HandleSIGHUP) ||
1026                      0 != SetSignalHandler(SIGUSR1, _HandleSIGUSR1))
1027                      err(ZT("cannot set sighandler, errno %d"), errno);
1028 mike     1.1 
1029              
1030                  /* Watch for SIGCHLD signals */
1031                  SetSignalHandler(SIGCHLD, _HandleSIGCHLD);
1032              
1033              #endif
1034              
1035                  /* Change directory to 'rundir' */
1036 krisbash 1.4     if (Chdir(OMI_GetPath(ID_RUNDIR)) != 0)
1037                  {
1038                      err(ZT("failed to change directory to: %s"), 
1039                          scs(OMI_GetPath(ID_RUNDIR)));
1040                  }
1041 mike     1.1 
1042              #if defined(CONFIG_POSIX)
1043                  /* Daemonize */
1044                  if (s_opts.daemonize && Process_Daemonize() != 0)
1045 krisbash 1.4         err(ZT("failed to daemonize server process"));
1046 mike     1.1 #endif
1047              
1048              #if defined(CONFIG_POSIX)
1049              
1050                  /* Create PID file */
1051                  if ((pidfile = PIDFile_OpenWrite()) == -1)
1052                  {
1053 krisbash 1.4         trace_CreatePIDFileFailed( scs(OMI_GetPath(ID_PIDFILE)) );
1054 mike     1.1         exit(1);
1055                  }
1056 krisbash 1.4 
1057 mike     1.1 #endif
1058              
1059                  /* Initialize calback parameters */
1060                  s_data.protocolData.data = &s_data;
1061                  s_data.protocolData.type = SRV_PROTOCOL;
1062                  s_data.wsmanData.data = &s_data;
1063                  s_data.wsmanData.type = SRV_WSMAN;
1064              
1065                  while (!s_data.terminated)
1066                  {
1067                      /* selector */
1068                      {
1069                          /* Initialize the network */
1070                          Sock_Start();
1071              
1072                          if(Selector_Init(&s_data.selector) != MI_RESULT_OK)
1073 krisbash 1.4                 err(ZT("Selector_Init() failed"));
1074 mike     1.1 
1075                          s_data.selectorInitialized = MI_TRUE;
1076 krisbash 1.4 
1077                          Timer_SetSelector(&s_data.selector);
1078 mike     1.1         }
1079              
1080                      /* Create the dispatcher object. */
1081                      {
1082                          r = Disp_Init(&s_data.disp, &s_data.selector);
1083              
1084                          if (r != MI_RESULT_OK)
1085                          {
1086 krisbash 1.4                 trace_DispatchInitFailed(r);
1087                              err(ZT("failed to initialize the dispatcher: %u"), r);
1088 mike     1.1             }
1089                      }
1090              
1091                      if (s_opts.idletimeout)
1092                      {
1093                          /* convert it to usec */
1094                          s_data.disp.agentmgr.provmgr.idleTimeoutUsec = s_opts.idletimeout * 1000000;
1095                      }
1096              
1097 krisbash 1.4         /* Set WSMAN options and create WSMAN server */
1098 krisbash 1.5         s_data.wsman_size = s_opts.httpport_size + s_opts.httpsport_size;
1099                      if ( s_data.wsman_size > 0 )
1100                      {
1101                          s_data.wsman = PAL_Calloc(s_data.wsman_size, sizeof(WSMAN*));
1102                          if ( s_data.wsman == NULL )
1103                          {
1104                              err(ZT("memory allocation failure allocating %d bytes"), s_data.wsman_size * sizeof(WSMAN*));
1105                          }
1106                      }
1107              
1108 mike     1.1         {
1109 krisbash 1.5             int wsman_count = 0;
1110 krisbash 1.4             WSMAN_Options options = DEFAULT_WSMAN_OPTIONS;
1111              #if !defined(CONFIG_FAVORSIZE)
1112                          options.enableTracing = s_opts.trace;
1113              #endif
1114                          options.enableHTTPTracing = s_opts.httptrace;
1115              
1116 krisbash 1.5             /* Start up the non-encrypted listeners */
1117                          int count;
1118                          for ( count = 0; count < s_opts.httpport_size; ++count )
1119                          {
1120                              r = WSMAN_New_Listener(
1121                                  &s_data.wsman[wsman_count++],
1122                                  &s_data.selector, 
1123                                  s_opts.httpport[count],
1124                                  0,
1125                                  s_opts.sslCipherSuite,
1126                                  s_opts.sslOptions,
1127                                  _RequestCallback,
1128                                  &s_data.wsmanData,
1129                                  &options);
1130              
1131                              if (r != MI_RESULT_OK)
1132                              {
1133                                  err(ZT("WSMAN_New_Listener() failed for port %u"), s_opts.httpport[count]);
1134                              }
1135              
1136                              /* Log start up message */
1137 krisbash 1.5                 trace_ListeningOnPort(s_opts.httpport[count]);
1138                          }
1139              
1140                          /* Start up the encrypted listeners */
1141                          for ( count = 0; count < s_opts.httpsport_size; ++count )
1142                          {
1143                              r = WSMAN_New_Listener(
1144                                  &s_data.wsman[wsman_count++],
1145                                  &s_data.selector, 
1146                                  0,
1147                                  s_opts.httpsport[count],
1148                                  s_opts.sslCipherSuite,
1149                                  s_opts.sslOptions,
1150                                  _RequestCallback,
1151                                  &s_data.wsmanData,
1152                                  &options);
1153              
1154                              if (r != MI_RESULT_OK)
1155                              {
1156                                  err(ZT("WSMAN_New_Listener() failed for encrypted port %u"), s_opts.httpsport[count]);
1157                              }
1158 mike     1.1 
1159 krisbash 1.5                 /* Log start up message */
1160                              trace_ListeningOnEncryptedPort(s_opts.httpsport[count]);
1161                          }
1162 mike     1.1         }
1163              
1164 krisbash 1.4         /* mux */
1165 mike     1.1         {
1166 krisbash 1.4             if(MuxIn_Init(&s_data.mux, _RequestCallback, &s_data.protocolData, NULL, PostResultMsg_NewAndSerialize) != MI_RESULT_OK)
1167                              err(ZT("MuxIn_Init() failed"));
1168 mike     1.1         }
1169 krisbash 1.4         
1170 mike     1.1         /* Create new protocol object */
1171                      {
1172 krisbash 1.4             r = ProtocolBase_New_Listener(
1173                              &s_data.protocol, 
1174                              &s_data.selector, 
1175                              OMI_GetPath(ID_SOCKETFILE), 
1176                              MuxIn_Open,
1177                              &s_data.mux);
1178 mike     1.1 
1179                          if (r != MI_RESULT_OK)
1180 krisbash 1.4                 err(ZT("Protocol_New_Listener() failed"));
1181 mike     1.1         }
1182              
1183                      /* Run the protocol object (waiting for new messages) */
1184 krisbash 1.4         {
1185                          const PAL_Uint64 ONE_SECOND_USEC = 1000 * 1000;
1186                          PAL_Uint64 start;
1187                          PAL_Uint64 finish;
1188 mike     1.1 
1189 krisbash 1.4             PAL_Time(&start);
1190              
1191                          if (s_opts.livetime)
1192                              finish = start + (s_opts.livetime * ONE_SECOND_USEC);
1193                          else
1194                              finish = 0;
1195              
1196                          for (;;)
1197                          {
1198                              PAL_Uint64 now;
1199 krisbash 1.5                 
1200                              if (s_data.reloadDispFlag)
1201                              {
1202                                  Lock_Acquire(&s_disp_mutex);
1203                                  Disp_Reload(&s_data.disp);
1204                                  s_data.reloadDispFlag = MI_FALSE;
1205                                  Lock_Release(&s_disp_mutex);
1206                              }
1207 krisbash 1.4 
1208                              r = Protocol_Run(s_data.protocol, ONE_SECOND_USEC);
1209              
1210                              if (r != MI_RESULT_TIME_OUT)
1211                                  break;
1212              
1213                              PAL_Time(&now);
1214              
1215                              /* Log abnormally terminated terminated process */
1216                              {
1217                                  size_t i;
1218              
1219                                  for (i = 0; i < _npids; i++)
1220                                      trace_ChildProcessTerminatedAbnormally(_pids[i]);
1221              
1222                                  _npids = 0;
1223                              }
1224              
1225                              if (finish && now > finish)
1226                                  break;
1227                          }
1228 krisbash 1.4         }
1229              
1230                      trace_Server_ProtocolRun(r);
1231 mike     1.1 
1232                      s_data.selectorInitialized = MI_FALSE;
1233              
1234                      if (MI_RESULT_TIME_OUT == r)
1235                      {
1236 krisbash 1.4             trace_Server_LiveTimeExpired();
1237 mike     1.1             s_data.terminated = MI_TRUE;
1238                      }
1239              
1240              #if defined(CONFIG_POSIX)
1241                      if (r == MI_RESULT_OK)
1242                      {
1243                          if (s_data.terminated)
1244 krisbash 1.4                 trace_ServerTerminated();
1245 mike     1.1             else
1246 krisbash 1.4                 trace_ServerReReadingConfig();
1247 mike     1.1         }
1248              #endif
1249              
1250                      // Destroy the dispatcher.
1251                      Selector_RemoveAllHandlers(&s_data.selector);
1252                      Disp_Destroy(&s_data.disp);
1253 krisbash 1.5 
1254                      {
1255                          int i;
1256                          for (i = 0; i < s_data.wsman_size; ++i)
1257                          {
1258                              WSMAN_Delete(s_data.wsman[i]);
1259                          }
1260                      }
1261              
1262 krisbash 1.4         ProtocolBase_Delete(s_data.protocol);
1263 mike     1.1         Selector_Destroy(&s_data.selector);
1264              
1265                      /* Shutdown the network */
1266                      Sock_Stop();
1267                  }
1268              
1269 krisbash 1.5     /* Done with WSMAN* array; free it */
1270                  PAL_Free(s_data.wsman);
1271                  s_data.wsman_size = 0;
1272              
1273                  /* Done with pointers to ports; free them now */
1274                  PAL_Free(s_opts.httpport);
1275                  PAL_Free(s_opts.httpsport);
1276                  s_opts.httpport_size = s_opts.httpsport_size = 0;
1277              
1278 mike     1.1 #if defined(CONFIG_POSIX)
1279                  /* Close PID file */
1280                  close(pidfile);
1281              
1282                  /* Remove PID file */
1283                  if (PIDFile_Delete() != 0)
1284 krisbash 1.4     {
1285                      trace_FailedRemovePIDFile(scs(OMI_GetPath(ID_PIDFILE)));
1286                  }
1287 mike     1.1 #endif
1288              
1289                  /* Log that we are exiting */
1290 krisbash 1.4     trace_ServerExiting();
1291 mike     1.1 
1292                  Log_Close();
1293 krisbash 1.4 
1294              #if defined(USE_ALLOCATOR)
1295              
1296              # if defined(USE_PAL_ATEXIT)
1297                  PAL_AtexitCall();
1298              # endif
1299              
1300                  PAL_DumpAllocStats();
1301              
1302                  if (PAL_GetBlocksAllocated())
1303                  {
1304                      printf("WARNING: %s: server has unfreed blocks on exit\n", arg0);
1305                      PAL_DumpAllocList();
1306                  }
1307              #endif
1308              
1309 mike     1.1     return 0;
1310              }

ViewCVS 0.9.2