Annotation of src/external/mpl/bind/dist/bin/named/win32/ntservice.c, Revision 1.3.2.3
1.3.2.3 ! martin 1: /* $NetBSD$ */
1.3.2.2 christos 2:
3: /*
4: * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5: *
6: * This Source Code Form is subject to the terms of the Mozilla Public
7: * License, v. 2.0. If a copy of the MPL was not distributed with this
8: * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9: *
10: * See the COPYRIGHT file distributed with this work for additional
11: * information regarding copyright ownership.
12: */
13:
14: #include <config.h>
15: #include <stdio.h>
16:
17: #include <isc/app.h>
18: #include <isc/commandline.h>
19: #include <isc/log.h>
20: #include <isc/print.h>
21: #include <isc/string.h>
22:
23: #include <named/globals.h>
24: #include <named/ntservice.h>
25: #include <named/main.h>
26: #include <named/server.h>
27:
28: /* Handle to SCM for updating service status */
29: static SERVICE_STATUS_HANDLE hServiceStatus = 0;
30: static BOOL foreground = FALSE;
31: static char ConsoleTitle[128];
32:
33: /*
34: * Forward declarations
35: */
36: void ServiceControl(DWORD dwCtrlCode);
37: int bindmain(int, char *[]); /* From main.c */
38:
39: /*
40: * Initialize the Service by registering it.
41: */
42: void
43: ntservice_init(void) {
44: if (!foreground) {
45: /* Register handler with the SCM */
46: hServiceStatus = RegisterServiceCtrlHandler(BIND_SERVICE_NAME,
47: (LPHANDLER_FUNCTION)ServiceControl);
48: if (!hServiceStatus) {
49: named_main_earlyfatal(
50: "could not register service control handler");
51: }
52: UpdateSCM(SERVICE_RUNNING);
53: } else {
54: strlcpy(ConsoleTitle, "BIND Version ", sizeof(ConsoleTitle));
55: strlcat(ConsoleTitle, VERSION, sizeof(ConsoleTitle));
56: SetConsoleTitle(ConsoleTitle);
57: }
58: }
59:
60: void
61: ntservice_shutdown(void) {
62: UpdateSCM(SERVICE_STOPPED);
63: }
64: /*
65: * Routine to check if this is a service or a foreground program
66: */
67: BOOL
68: ntservice_isservice(void) {
69: return(!foreground);
70: }
71: /*
72: * ServiceControl(): Handles requests from the SCM and passes them on
73: * to named.
74: */
75: void
76: ServiceControl(DWORD dwCtrlCode) {
77: /* Handle the requested control code */
78: switch(dwCtrlCode) {
79: case SERVICE_CONTROL_INTERROGATE:
80: UpdateSCM(0);
81: break;
82:
83: case SERVICE_CONTROL_SHUTDOWN:
84: case SERVICE_CONTROL_STOP:
85: named_server_flushonshutdown(named_g_server, true);
86: isc_app_shutdown();
1.3.2.3 ! martin 87: UpdateSCM(SERVICE_STOP_PENDING);
1.3.2.2 christos 88: break;
89: default:
90: break;
91: }
92: }
93:
94: /*
95: * Tell the Service Control Manager the state of the service.
96: */
97: void UpdateSCM(DWORD state) {
98: SERVICE_STATUS ss;
99: static DWORD dwState = SERVICE_STOPPED;
100:
101: if (hServiceStatus) {
102: if (state)
103: dwState = state;
104:
105: memset(&ss, 0, sizeof(SERVICE_STATUS));
106: ss.dwServiceType |= SERVICE_WIN32_OWN_PROCESS;
107: ss.dwCurrentState = dwState;
108: ss.dwControlsAccepted = SERVICE_ACCEPT_STOP |
109: SERVICE_ACCEPT_SHUTDOWN;
110: ss.dwCheckPoint = 0;
111: ss.dwServiceSpecificExitCode = 0;
112: ss.dwWin32ExitCode = NO_ERROR;
113: ss.dwWaitHint = dwState == SERVICE_STOP_PENDING ? 10000 : 1000;
114:
115: if (!SetServiceStatus(hServiceStatus, &ss)) {
116: ss.dwCurrentState = SERVICE_STOPPED;
117: SetServiceStatus(hServiceStatus, &ss);
118: }
119: }
120: }
121:
122: /* unhook main */
123:
124: #undef main
125:
126: /*
127: * This is the entry point for the executable
128: * We can now call bindmain() explicitly or via StartServiceCtrlDispatcher()
129: * as we need to.
130: */
131: int main(int argc, char *argv[])
132: {
133: int rc, ch;
134:
135: /* Command line users should put -f in the options. */
136: isc_commandline_errprint = false;
137: while ((ch = isc_commandline_parse(argc, argv,
138: NAMED_MAIN_ARGS)) != -1)
139: {
140: switch (ch) {
141: case 'f':
142: case 'g':
143: case 'v':
144: case 'V':
145: foreground = TRUE;
146: break;
147: default:
148: break;
149: }
150: }
151: isc_commandline_reset = true;
152:
153: if (foreground) {
154: /* run in console window */
155: exit(bindmain(argc, argv));
156: } else {
157: /* Start up as service */
158: char *SERVICE_NAME = BIND_SERVICE_NAME;
159:
160: SERVICE_TABLE_ENTRY dispatchTable[] = {
161: { TEXT(SERVICE_NAME),
162: (LPSERVICE_MAIN_FUNCTION)bindmain },
163: { NULL, NULL }
164: };
165:
166: rc = StartServiceCtrlDispatcher(dispatchTable);
167: if (!rc) {
168: fprintf(stderr,
169: "Use -f to run from the command line.\n");
170: /* will be 1063 when launched as a console app */
171: exit(GetLastError());
172: }
173: }
174: exit(0);
175: }
CVSweb <webmaster@jp.NetBSD.org>