(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           #include <base/time.h>
 28           #include <protocol/wsman.h>
 29           #include <provreg/provreg.h>
 30           #include <provmgr/provmgr.h>
 31           #include <disp/disp.h>
 32           #include <base/strings.h>
 33           #include <base/args.h>
 34           #include <base/dir.h>
 35           #include <base/log.h>
 36           #include <base/env.h>
 37           #include <base/process.h>
 38           #include <base/pidfile.h>
 39           #include <base/paths.h>
 40           #include <base/conf.h>
 41           #include <base/user.h>
 42           #include <base/getopt.h>
 43 mike  1.1 
 44           #if defined(CONFIG_POSIX)
 45           # include <signal.h>
 46           # include <sys/wait.h>
 47           #endif
 48           
 49           #define T MI_T
 50           
 51           typedef struct _ServerData ServerData;
 52           
 53           typedef enum _ServerTransportType
 54           {
 55               SRV_PROTOCOL,
 56               SRV_WSMAN
 57           }
 58           ServerTransportType;
 59           
 60           typedef struct _ServerCallbackData
 61           {
 62               ServerData*         data;
 63               ServerTransportType type;
 64 mike  1.1 }
 65           ServerCallbackData;
 66           
 67           struct _ServerData
 68           {
 69               Disp        disp;
 70               Protocol*   protocol;
 71               WSMAN*      wsman;
 72               Selector    selector;
 73               MI_Boolean  selectorInitialized;
 74               MI_Boolean  terminated;
 75           
 76               /* pointers to self with different types - one per supported transport */
 77               ServerCallbackData  protocolData;
 78               ServerCallbackData  wsmanData;
 79           } ;
 80           
 81           typedef struct _Options
 82           {
 83               MI_Boolean help;
 84               MI_Boolean trace;
 85 mike  1.1     MI_Boolean terminateByNoop;
 86           #if defined(CONFIG_POSIX)
 87               MI_Boolean daemonize;
 88               MI_Boolean stop;
 89               MI_Boolean reloadConfig;
 90           #endif
 91               /* mostly for unittesting in non-root env */
 92               MI_Boolean ignoreAuthentication;
 93               MI_Boolean locations;
 94               MI_Boolean logstderr;
 95               unsigned short httpport;
 96               unsigned short httpsport;
 97               MI_Uint64 idletimeout;
 98               MI_Uint64 livetime;
 99               Log_Level logLevel;
100           }
101           Options;
102           
103           static Options s_opts;
104           
105           static ServerData s_data;
106 mike  1.1 
107           static const char* arg0 = 0;
108           
109           static const char HELP[] = "\
110           Usage: %s [OPTIONS]\n\
111           \n\
112           This program starts the server.\n\
113           \n\
114           OPTIONS:\n\
115               -h, --help                  Print this help message.\n\
116               -d                          Daemonize the server process (POSIX only).\n\
117               -s                          Stop the server process (POSIX only).\n\
118               -r                          Re-read configuration by the running server (POSIX only).\n\
119               --httpport PORT             HTTP protocol listener port.\n\
120               --httpsport PORT            HTTPS protocol listener port.\n\
121               --idletimeout TIMEOUT       Idle providers unload timeout (in seconds).\n\
122               -v, --version               Print version information.\n\
123               -l, --logstderr             Send log output to standard error.\n\
124               --loglevel LEVEL            Set logging level to one of the following\n\
125                                           symbols/numbers: fatal/0, error/1, warning/2,\n\
126                                           info/3, debug/4 (default 2).\n\
127 mike  1.1 \n";
128           
129           PRINTF_FORMAT(1, 2)
130           void FUNCTION_NEVER_RETURNS err(const char* fmt, ...)
131           {
132               va_list ap;
133               memset(&ap, 0, sizeof(ap));
134           
135               fprintf(stderr, "%s: ", arg0);
136           
137               va_start(ap, fmt);
138               vfprintf(stderr, fmt, ap);
139               va_end(ap);
140           
141               /* Write to log as well */
142               va_start(ap, fmt);
143               va_end(ap);
144           
145               fputc('\n', stderr);
146               exit(1);
147           }
148 mike  1.1 
149           static void _ProviderCallback(Message* msg, void* callbackData)
150           {
151               ServerCallbackData* self = (ServerCallbackData* )callbackData;
152           
153               switch ( msg->tag )
154               {
155                   case PostResultMsgTag:
156                   {
157                       const PostResultMsg* rsp = (const PostResultMsg*)msg;
158           
159                       if (s_opts.trace)
160                       {
161                           PostResultMsg_Print(rsp, stdout);
162                       }
163                   }
164                   break;
165           
166                   case PostInstanceMsgTag:
167                   {
168                       const PostInstanceMsg* rsp = (const PostInstanceMsg*)msg;
169 mike  1.1 
170                       if (s_opts.trace)
171                       {
172                           PostInstanceMsg_Print(rsp, stdout);
173                       }
174                   }
175                   break;
176           
177                   case SubscribeResTag:
178                   {
179                       const SubscribeRes* rsp = (const SubscribeRes*)msg;
180           
181                       if (s_opts.trace)
182                       {
183                           SubscribeRes_Print(rsp, stdout);
184                       }
185                   }
186                   break;
187           
188                   case NoOpRspTag:
189                       break;  /* send noop confirmation to the client */
190 mike  1.1 
191                   default:
192                   {
193                       LOGF((T("unknown message type: %u"), msg->tag));
194                       exit(1);
195                   }
196               }
197           
198               /* forward message to the other side */
199               if (msg->request)
200                   msg->clientID = msg->request->clientID;
201           
202               switch (self->type)
203               {
204               case SRV_PROTOCOL:
205                   Protocol_Send(self->data->protocol, msg);
206                   break;
207           
208               case SRV_WSMAN:
209                   WSMAN_Send(self->data->wsman, msg);
210                   break;
211 mike  1.1 
212               default:
213                   LOGF((T("unknown transport type: %u"), (int)self->type));
214                   exit(1);
215               }
216           }
217           
218           /* Called by protocol stack to dispatch an incoming request message */
219           static MI_Boolean _RequestCallback(
220               Protocol* protocol_,
221               Message* msg,
222               void* data)
223           {
224               ServerCallbackData* self = (ServerCallbackData*)data;
225               MI_Result r;
226           
227               MI_UNUSED(protocol_);
228           
229               if (NoOpReqTag == msg->tag)
230               {
231                   NoOpReq* req = (NoOpReq*)msg;
232 mike  1.1         NoOpRsp* rsp;
233           
234                   if (s_opts.trace)
235                   {
236                       NoOpReq_Print(req, stdout);
237                   }
238           
239                   /* Send NoOp response back */
240                   rsp = NoOpRsp_New(req->base.msgID);
241           
242                   if (!rsp)
243                       err("out of memory");
244           
245                   rsp->base.clientID = req->base.clientID;
246           
247                   if (s_opts.trace)
248                   {
249                       NoOpRsp_Print(rsp, stdout);
250                   }
251           
252                   _ProviderCallback(&rsp->base, self);
253 mike  1.1         NoOpRsp_Release(rsp);
254           
255                   if (s_opts.terminateByNoop)
256                   {
257                       s_data.terminated = MI_TRUE;
258                       Selector_StopRunning(&s_data.selector);
259                   }
260                   return MI_TRUE;
261               }
262           
263               if (s_opts.trace)
264               {
265                   MessagePrint(msg, stdout);
266               }
267           
268               msg->callback = _ProviderCallback;
269               msg->callbackData = self;
270           
271               r = Disp_HandleRequest(&self->data->disp, msg);
272           
273               if (MI_RESULT_OK != r)
274 mike  1.1     {
275                   PostResultMsg* resp;
276           
277                   resp = PostResultMsg_New( msg->msgID );
278           
279                   if (!resp)
280                       return MI_TRUE;
281           
282                   resp->result = r;
283                   Message_SetRequest(&resp->base,msg);
284                   (*msg->callback)(&resp->base, msg->callbackData);
285           
286                   PostResultMsg_Release(resp);
287               }
288           
289               return MI_TRUE;
290           }
291           
292           static void GetCommandLineDestDirOption(
293               int* argc_,
294               const char* argv[])
295 mike  1.1 {
296               int argc = *argc_;
297               int i;
298               const char* destdir = NULL;
299           
300               for (i = 1; i < argc; )
301               {
302                   if (strcmp(argv[i], "--destdir") == 0)
303                   {
304                       if (i + 1 == argc)
305                           err("missing argument for --destdir option");
306           
307                       destdir = argv[i+1];
308                       memmove((char*)&argv[i], (char*)&argv[i+2], 
309                           sizeof(char*) * (argc-i-1));
310                       argc -= 2;
311                   }
312                   else if (strncmp(argv[i], "--destdir=", 10) == 0)
313                   {
314                       destdir = argv[i] + 10;
315                       memmove((char*)&argv[i], (char*)&argv[i+1], 
316 mike  1.1                 sizeof(char*) * (argc-i));
317           
318                       argc -= 1;
319                   }
320                   else
321                       i++;
322               }
323           
324               if (destdir)
325               {
326                   if (SetPath(ID_DESTDIR, destdir) != 0)
327                       err("failed to set destdir");
328               }
329           
330               *argc_ = argc;
331           }
332           
333           static void GetCommandLineOptions(
334               int* argc_,
335               const char* argv[])
336           {
337 mike  1.1     int argc = *argc_;
338               GetOptState state = GETOPTSTATE_INITIALIZER;
339               static const char* opts[] =
340               {
341                   "-h",
342                   "--help",
343                   "-p",
344                   "-t",
345                   "--stopnoop",
346                   "-v",
347                   "--version",
348                   "-d",
349                   "-s",
350                   "-r",
351                   "--httpport:",
352                   "--httpsport:",
353                   "--idletimeout:",
354                   "--livetime:",
355                   "--ignoreAuthentication",
356                   "-i",
357                   "--prefix:",
358 mike  1.1         "--libdir:",
359                   "--bindir:",
360                   "--localstatedir:",
361                   "--sysconfdir:",
362                   "--providerdir:",
363                   "--certsdir:",
364                   "--rundir:",
365                   "--logdir:",
366                   "--pidfile:",
367                   "--logfile:",
368                   "--registerdir:",
369                   "--socketfile:",
370                   "--pemfile:",
371                   "--keyfile:",
372                   "--agentprogram:",
373                   "--serverprogram:",
374                   "--logstderr",
375                   "--loglevel:",
376                   "-l",
377                   NULL,
378               };
379 mike  1.1 
380               for (;;)
381               {
382                   int r = GetOpt(&argc, argv, opts, &state);
383           
384                   if (r == 1)
385                       break;
386           
387                   if (r == -1)
388                   {
389                       fprintf(stderr, "error: %s\n", state.err);
390                       exit(1);
391                   }
392           
393                   if (strcmp(state.opt, "-h") == 0 ||
394                       strcmp(state.opt, "--help") == 0)
395                   {
396                       s_opts.help = MI_TRUE;
397                   }
398                   else if (strcmp(state.opt, "-p") == 0)
399                   {
400 mike  1.1             s_opts.locations = MI_TRUE;
401                   }
402                   else if (strcmp(state.opt, "-t") == 0)
403                   {
404                       s_opts.trace = MI_TRUE;
405                   }
406                   else if (strcmp(state.opt, "--stopnoop") == 0)
407                   {
408                       s_opts.terminateByNoop = MI_TRUE;
409                   }
410                   else if (strcmp(state.opt, "-v") == 0 ||
411                           strcmp(state.opt, "--version") == 0)
412                   {
413                       printf("%s: %s\n", arg0,
414                           CONFIG_PRODUCT "-" CONFIG_VERSION " - " CONFIG_DATE);
415                       exit(0);
416                   }
417           #if defined(CONFIG_POSIX)
418                   else if (strcmp(state.opt, "-d") == 0)
419                   {
420                       s_opts.daemonize = MI_TRUE;
421 mike  1.1         }
422                   else if (strcmp(state.opt, "-s") == 0)
423                   {
424                       s_opts.stop = MI_TRUE;
425                   }
426                   else if (strcmp(state.opt, "-r") == 0)
427                   {
428                       s_opts.reloadConfig = MI_TRUE;
429                   }
430           #endif
431                   else if (strcmp(state.opt, "--httpport") == 0)
432                   {
433                       unsigned long x;
434                       char* end;
435           
436                       x = Strtoul(state.arg, &end, 10);
437           
438                       if (*end != '\0' || x > USHRT_MAX)
439                           err("bad option argument for --httpport: %s", state.arg);
440           
441                       s_opts.httpport = (unsigned short)x;
442 mike  1.1         }
443                   else if (strcmp(state.opt, "--httpsport") == 0)
444                   {
445                       unsigned long x;
446                       char* end;
447           
448                       x = Strtoul(state.arg, &end, 10);
449           
450                       if (*end != '\0' || x > USHRT_MAX)
451                           err("bad option argument for --httpsport: %s", state.arg);
452           
453                       s_opts.httpsport = (unsigned short)x;
454                   }
455                   else if (strcmp(state.opt, "--idletimeout") == 0)
456                   {
457                       char* end;
458                       MI_Uint64 x = Strtoull(state.arg, &end, 10);
459           
460                       if (*end != '\0')
461                           err("bad option argument for --idletimeout: %s", state.arg);
462           
463 mike  1.1             s_opts.idletimeout = x;
464                   }
465                   else if (strcmp(state.opt, "--livetime") == 0)
466                   {
467                       char* end;
468                       MI_Uint64 x = Strtoull(state.arg, &end, 10);
469           
470                       if (*end != '\0')
471                           err("bad option argument for --livetime: %s", state.arg);
472           
473                       s_opts.livetime = x;
474                   }
475                   else if (strcmp(state.opt, "--ignoreAuthentication") == 0 ||
476                        strcmp(state.opt, "-i") == 0)
477                   {
478                       s_opts.ignoreAuthentication = MI_TRUE;
479                   }
480                   else if (strcmp(state.opt, "--logstderr") == 0 ||
481                        strcmp(state.opt, "-l") == 0)
482                   {
483                       s_opts.logstderr = MI_TRUE;
484 mike  1.1         }
485                   else if (strcmp(state.opt, "--loglevel") == 0)
486                   {
487                       if (Log_SetLevelFromString(state.arg) != 0)
488                       {
489                           err("bad option argument for %s: %s", state.opt, state.arg);
490                       }
491                   }
492                   else if (strncmp(state.opt, "--", 2) == 0 && IsNickname(state.opt+2))
493                   {
494                       if (SetPathFromNickname(state.opt+2, state.arg) != 0)
495                           err("SetPathFromNickname() failed");
496                   }
497               }
498           
499               *argc_ = argc;
500           }
501           
502           static void OpenLogFile()
503           {
504               if (s_opts.logstderr)
505 mike  1.1     {
506                   if (Log_OpenStdErr() != MI_RESULT_OK)
507                       err("failed to open log file to stderr");
508               }
509               else
510               {
511                   MI_Char path[MAX_PATH_SIZE];
512                   ZStrlcpy(path, GetPath(ID_LOGFILE), MI_COUNT(path));
513           
514                   /* Open the log file */
515                   if (Log_Open(path) != MI_RESULT_OK)
516                       err("failed to open log file: %s", path);
517               }
518           }
519           
520           #if defined(CONFIG_POSIX)
521           static void _HandleSIGTERM(int sig)
522           {
523               if (sig == SIGTERM && s_data.selectorInitialized)
524               {
525                   s_data.terminated = MI_TRUE;
526 mike  1.1         Selector_StopRunning(&s_data.selector);
527               }
528           }
529           
530           static void _HandleSIGHUP(int sig)
531           {
532               if (sig == SIGHUP && s_data.selectorInitialized)
533               {
534                   Selector_StopRunning(&s_data.selector);
535               }
536           }
537           
538           static void _HandleSIGCHLD(int sig)
539           {
540               if (sig == SIGCHLD)
541               {
542                   int status = 0;
543                   wait(&status);
544               }
545           }
546           #endif
547 mike  1.1 
548           static void _PrintPaths()
549           {
550               PrintPaths();
551           }
552           
553           static void GetConfigFileOptions()
554           {
555               char path[MAX_PATH_SIZE];
556               Conf* conf;
557           
558               /* Form the configuration file path */
559               Strlcpy(path, GetPath(ID_CONFIGFILE), sizeof(path));
560           
561               /* Open the configuration file */
562               conf = Conf_Open(path);
563               if (!conf)
564                   err("failed to open configuration file: %s", path);
565           
566               /* For each key=value pair in configuration file */
567               for (;;)
568 mike  1.1     {
569                   const char* key;
570                   const char* value;
571                   int r = Conf_Read(conf, &key, &value);
572           
573                   if (r == -1)
574                       err("%s: %s\n", path, Conf_Error(conf));
575           
576                   if (r == 1)
577                       break;
578           
579                   if (strcmp(key, "httpport") == 0)
580                   {
581                       char* end;
582                       unsigned long x = Strtoul(value, &end, 10);
583           
584                       if (*end != '\0' || x > USHRT_MAX)
585                       {
586                           err("%s(%u): invalid value for '%s': %s", path, 
587                               Conf_Line(conf), key, value);
588                       }
589 mike  1.1 
590                       s_opts.httpport = (unsigned short)x;
591                   }
592                   else if (strcmp(key, "httpsport") == 0)
593                   {
594                       char* end;
595                       unsigned long x = Strtoul(value, &end, 10);
596           
597                       if (*end != '\0' || x > USHRT_MAX)
598                       {
599                           err("%s(%u): invalid value for '%s': %s", path, 
600                               Conf_Line(conf), key, value);
601                       }
602           
603                       s_opts.httpsport = (unsigned short)x;
604                   }
605                   else if (strcmp(key, "idletimeout") == 0)
606                   {
607                       char* end;
608                       MI_Uint64 x = Strtoull(value, &end, 10);
609           
610 mike  1.1             if (*end != '\0')
611                       {
612                           err("%s(%u): invalid value for '%s': %s", path, 
613                               Conf_Line(conf), key, value);
614                       }
615           
616                       s_opts.idletimeout = x;
617                   }
618                   else if (strcmp(key, "livetime") == 0)
619                   {
620                       char* end;
621                       MI_Uint64 x = Strtoull(value, &end, 10);
622           
623                       if (*end != '\0')
624                       {
625                           err("%s(%u): invalid value for '%s': %s", path, 
626                               Conf_Line(conf), key, value);
627                       }
628           
629                       s_opts.livetime = x;
630                   }
631 mike  1.1         else if (strcmp(key, "trace") == 0)
632                   {
633                       if (Strcasecmp(value, "true") == 0)
634                       {
635                           s_opts.trace = MI_TRUE;
636                       }
637                       else if (Strcasecmp(value, "false") == 0)
638                       {
639                           s_opts.trace = MI_FALSE;
640                       }
641                       else
642                       {
643                           err("%s(%u): invalid value for '%s': %s", path, 
644                               Conf_Line(conf), key, value);
645                       }
646                   }
647                   else if (IsNickname(key))
648                   {
649                       if (SetPathFromNickname(key, value) != 0)
650                           err("SetPathFromNickname() failed");
651                   }
652 mike  1.1         else
653                   {
654                       err("%s(%u): unknown key: %s", path, Conf_Line(conf), key);
655                   }
656               }
657           
658               /* Close configuration file */
659               Conf_Close(conf);
660           
661               return;
662           }
663           
664           int servermain(int argc, const char* argv[])
665           {
666               MI_Result r;
667           #if defined(CONFIG_POSIX)
668               int pidfile = -1;
669           #endif
670           
671               arg0 = argv[0];
672           
673 mike  1.1     memset(&s_data, 0, sizeof(s_data));
674           
675               /* Set default options */
676               s_opts.httpport = CONFIG_HTTPPORT;
677               s_opts.httpsport = CONFIG_HTTPSPORT;
678               s_opts.idletimeout = 0;
679               s_opts.livetime = 0;
680           
681               /* Get --destdir command-line option */
682               GetCommandLineDestDirOption(&argc, argv);
683           
684               /* Extract configuration file options */
685               GetConfigFileOptions();
686           
687               /* Extract command-line options a second time (to override) */
688               GetCommandLineOptions(&argc, argv);
689           
690               /* Open the log file */
691               OpenLogFile();
692           
693               /* Print help */
694 mike  1.1     if (s_opts.help)
695               {
696                   fprintf(stderr, HELP, arg0);
697                   exit(1);
698               }
699           
700               /* Print locations of files and directories */
701               if (s_opts.locations)
702               {
703                   _PrintPaths();
704                   printf("\n");
705                   exit(0);
706               }
707           
708           #if defined(CONFIG_POSIX)
709               if (s_opts.stop || s_opts.reloadConfig)
710               {
711                   if (PIDFile_IsRunning() != 0)
712                       err("server is not running\n");
713           
714                   if (PIDFile_Signal(s_opts.stop ? SIGTERM : SIGHUP) != 0)
715 mike  1.1             err("failed to stop server\n");
716           
717                   if (s_opts.stop)
718                       printf("%s: stopped server\n", arg0);
719                   else
720                       printf("%s: refreshed server\n", arg0);
721           
722                   exit(0);
723               }
724           #endif
725           
726           #if defined(CONFIG_POSIX)
727           
728               if (PIDFile_IsRunning() == 0)
729                   err("server is already running\n");
730           
731               /* Verify that server is started as root */
732               if (0 != IsRoot() && !s_opts.ignoreAuthentication)
733               {
734                   err("expected to run as root");
735               }
736 mike  1.1 
737               /* ATTN: unit-test support; should be removed/ifdefed later */
738               if (s_opts.ignoreAuthentication)
739               {
740                   IgnoreAuthCalls(1);
741               }
742           
743               /* Watch for SIGTERM signals */
744               if (0 != SetSignalHandler(SIGTERM, _HandleSIGTERM) ||
745                   0 != SetSignalHandler(SIGHUP, _HandleSIGHUP))
746                   err("cannot set sighanlder, erron %d", errno);
747           
748           
749               /* Watch for SIGCHLD signals */
750               SetSignalHandler(SIGCHLD, _HandleSIGCHLD);
751           
752           #endif
753           
754               /* Change directory to 'rundir' */
755               if (Chdir(GetPath(ID_RUNDIR)) != 0)
756                   err("failed to change directory to: %s", GetPath(ID_RUNDIR));
757 mike  1.1 
758           #if defined(CONFIG_POSIX)
759               /* Daemonize */
760               if (s_opts.daemonize && Process_Daemonize() != 0)
761                   err("failed to daemonize server process");
762           #endif
763           
764           #if defined(CONFIG_POSIX)
765           
766               /* Create PID file */
767               if ((pidfile = PIDFile_OpenWrite()) == -1)
768               {
769                   LOGF(("failed to create PID file: %s", GetPath(ID_PIDFILE)));
770                   exit(1);
771               }
772           #endif
773           
774               /* Initialize calback parameters */
775               s_data.protocolData.data = &s_data;
776               s_data.protocolData.type = SRV_PROTOCOL;
777               s_data.wsmanData.data = &s_data;
778 mike  1.1     s_data.wsmanData.type = SRV_WSMAN;
779           
780               while (!s_data.terminated)
781               {
782                   /* selector */
783                   {
784                       /* Initialize the network */
785                       Sock_Start();
786           
787                       if(Selector_Init(&s_data.selector) != MI_RESULT_OK)
788                           err("Selector_Init() failed");
789           
790                       s_data.selectorInitialized = MI_TRUE;
791                   }
792           
793                   /* Create the dispatcher object. */
794                   {
795                       r = Disp_Init(&s_data.disp, &s_data.selector);
796           
797                       if (r != MI_RESULT_OK)
798                       {
799 mike  1.1                 LOGF((T("failed to initialize the dispatcher: %u"), r));
800                           err("failed to initialize the dispatcher: %u", r);
801                       }
802                   }
803           
804                   if (s_opts.idletimeout)
805                   {
806                       /* convert it to usec */
807                       s_data.disp.agentmgr.provmgr.idleTimeoutUsec = s_opts.idletimeout * 1000000;
808                   }
809           
810                   /* wsman server */
811                   {
812                       r = WSMAN_New_Listener(
813                           &s_data.wsman, 
814                           &s_data.selector, 
815                           s_opts.httpport, 
816                           s_opts.httpsport,
817                           (WSMANCallback)_RequestCallback, /* ATTN! address callback types! */
818                           &s_data.wsmanData);
819           
820 mike  1.1             if (r != MI_RESULT_OK)
821                           err("WSMAN_New_Listener() failed");
822                   }
823           
824                   /* Set WSMAN options */
825                   {
826                       WSMAN_Options options = DEFAULT_WSMAN_OPTIONS;
827                       options.enableTracing = s_opts.trace;
828                       WSMAN_SetOptions(s_data.wsman, &options);
829                   }
830           
831                   /* Create new protocol object */
832                   {
833                       r = Protocol_New_Listener(&s_data.protocol, &s_data.selector, 
834                           GetPath(ID_SOCKETFILE), _RequestCallback, &s_data.protocolData);
835           
836                       if (r != MI_RESULT_OK)
837                           err("Protocol_New_Listener() failed");
838                   }
839           
840                   /* Log start up message */
841 mike  1.1         LOGI((T("listening on ports: http %u, https %u"), s_opts.httpport, s_opts.httpsport));
842           
843                   /* Run the protocol object (waiting for new messages) */
844                   r = Protocol_Run(s_data.protocol, 
845                       (s_opts.livetime ? s_opts.livetime * 1000000 : TIME_NEVER));
846           
847                   LOGI((T("after run, r %d"), r));
848           
849                   s_data.selectorInitialized = MI_FALSE;
850           
851                   if (MI_RESULT_TIME_OUT == r)
852                   {
853                       LOGI((T("livetime expired; server stopped")));
854                       s_data.terminated = MI_TRUE;
855                   }
856           
857           #if defined(CONFIG_POSIX)
858                   if (r == MI_RESULT_OK)
859                   {
860                       if (s_data.terminated)
861                           LOGI((T("server terminated")));
862 mike  1.1             else
863                           LOGI((T("re-reading configuration")));
864                   }
865           #endif
866           
867                   // Destroy the dispatcher.
868                   Selector_RemoveAllHandlers(&s_data.selector);
869                   Disp_Destroy(&s_data.disp);
870                   WSMAN_Delete(s_data.wsman);
871                   Protocol_Delete(s_data.protocol);
872                   Selector_Destroy(&s_data.selector);
873           
874                   /* Shutdown the network */
875                   Sock_Stop();
876               }
877           
878           #if defined(CONFIG_POSIX)
879               /* Close PID file */
880               close(pidfile);
881           
882               /* Remove PID file */
883 mike  1.1     if (PIDFile_Delete() != 0)
884                   LOGW(("failed to remove PID file: %s", GetPath(ID_PIDFILE)));
885           #endif
886           
887               /* Log that we are exiting */
888               LOGI((T("server exiting")));
889           
890               Log_Close();
891               return 0;
892           }

ViewCVS 0.9.2