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

ViewCVS 0.9.2