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 }
|