1 /* $NetBSD: ntservice.c,v 1.6 2014/12/10 04:37:52 christos Exp $ */
4 * Copyright (C) 2004, 2006, 2007, 2009, 2011, 2013, 2014 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1999-2002 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: ntservice.c,v 1.16 2011/01/13 08:50:29 tbox Exp */
26 #include <isc/commandline.h>
29 #include <named/globals.h>
30 #include <named/ntservice.h>
31 #include <named/main.h>
32 #include <named/server.h>
34 /* Handle to SCM for updating service status */
35 static SERVICE_STATUS_HANDLE hServiceStatus
= 0;
36 static BOOL foreground
= FALSE
;
37 static char ConsoleTitle
[128];
40 * Forward declarations
42 void ServiceControl(DWORD dwCtrlCode
);
43 int bindmain(int, char *[]); /* From main.c */
46 * Initialize the Service by registering it.
49 ntservice_init(void) {
51 /* Register handler with the SCM */
52 hServiceStatus
= RegisterServiceCtrlHandler(BIND_SERVICE_NAME
,
53 (LPHANDLER_FUNCTION
)ServiceControl
);
54 if (!hServiceStatus
) {
56 "could not register service control handler");
57 UpdateSCM(SERVICE_STOPPED
);
60 UpdateSCM(SERVICE_RUNNING
);
62 strcpy(ConsoleTitle
, "BIND Version ");
63 strcat(ConsoleTitle
, VERSION
);
64 SetConsoleTitle(ConsoleTitle
);
69 ntservice_shutdown(void) {
70 UpdateSCM(SERVICE_STOPPED
);
73 * Routine to check if this is a service or a foreground program
76 ntservice_isservice(void) {
80 * ServiceControl(): Handles requests from the SCM and passes them on
84 ServiceControl(DWORD dwCtrlCode
) {
85 /* Handle the requested control code */
87 case SERVICE_CONTROL_INTERROGATE
:
91 case SERVICE_CONTROL_SHUTDOWN
:
92 case SERVICE_CONTROL_STOP
:
93 ns_server_flushonshutdown(ns_g_server
, ISC_TRUE
);
95 UpdateSCM(SERVICE_STOPPED
);
103 * Tell the Service Control Manager the state of the service.
105 void UpdateSCM(DWORD state
) {
107 static DWORD dwState
= SERVICE_STOPPED
;
109 if (hServiceStatus
) {
113 memset(&ss
, 0, sizeof(SERVICE_STATUS
));
114 ss
.dwServiceType
|= SERVICE_WIN32_OWN_PROCESS
;
115 ss
.dwCurrentState
= dwState
;
116 ss
.dwControlsAccepted
= SERVICE_ACCEPT_STOP
|
117 SERVICE_ACCEPT_SHUTDOWN
;
119 ss
.dwServiceSpecificExitCode
= 0;
120 ss
.dwWin32ExitCode
= NO_ERROR
;
121 ss
.dwWaitHint
= dwState
== SERVICE_STOP_PENDING
? 10000 : 1000;
123 if (!SetServiceStatus(hServiceStatus
, &ss
)) {
124 ss
.dwCurrentState
= SERVICE_STOPPED
;
125 SetServiceStatus(hServiceStatus
, &ss
);
135 * This is the entry point for the executable
136 * We can now call bindmain() explicitly or via StartServiceCtrlDispatcher()
139 int main(int argc
, char *argv
[])
143 /* Command line users should put -f in the options. */
144 isc_commandline_errprint
= ISC_FALSE
;
145 while ((ch
= isc_commandline_parse(argc
, argv
,
146 "46c:C:d:D:E:fFgi:lm:n:N:p:P:"
147 "sS:t:T:U:u:vVx:")) != -1) {
159 isc_commandline_reset
= ISC_TRUE
;
162 /* run in console window */
163 exit(bindmain(argc
, argv
));
165 /* Start up as service */
166 char *SERVICE_NAME
= BIND_SERVICE_NAME
;
168 SERVICE_TABLE_ENTRY dispatchTable
[] = {
169 { TEXT(SERVICE_NAME
),
170 (LPSERVICE_MAIN_FUNCTION
)bindmain
},
174 rc
= StartServiceCtrlDispatcher(dispatchTable
);
177 "Use -f to run from the command line.\n");
178 /* will be 1063 when launched as a console app */
179 exit(GetLastError());