Sync usage with man page.
[netbsd-mini2440.git] / external / bsd / bind / dist / bin / named / win32 / ntservice.c
blob08296428d66340d0fae065c3559965142445cb7b
1 /* $NetBSD$ */
3 /*
4 * Copyright (C) 2004, 2006, 2007, 2009 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.14 2009/06/23 23:47:44 tbox Exp */
22 #include <config.h>
23 #include <stdio.h>
25 #include <isc/app.h>
26 #include <isc/log.h>
28 #include <named/globals.h>
29 #include <named/ntservice.h>
30 #include <named/main.h>
31 #include <named/server.h>
33 /* Handle to SCM for updating service status */
34 static SERVICE_STATUS_HANDLE hServiceStatus = 0;
35 static BOOL foreground = FALSE;
36 static char ConsoleTitle[128];
39 * Forward declarations
41 void ServiceControl(DWORD dwCtrlCode);
42 void GetArgs(int *, char ***, char ***);
43 int main(int, char *[], char *[]); /* From ns_main.c */
46 * Here we change the entry point for the executable to bindmain() from main()
47 * This allows us to invoke as a service or from the command line easily.
49 #pragma comment(linker, "/entry:bindmain")
52 * This is the entry point for the executable
53 * We can now call main() explicitly or via StartServiceCtrlDispatcher()
54 * as we need to.
56 int bindmain()
58 int rc,
59 i = 1;
61 int argc;
62 char **envp, **argv;
65 * We changed the entry point function, so we must initialize argv,
66 * etc. ourselves. Ick.
68 GetArgs(&argc, &argv, &envp);
70 /* Command line users should put -f in the options. */
71 /* XXXMPA should use isc_commandline_parse() here. */
72 while (argv[i]) {
73 if (!strcmp(argv[i], "-f") ||
74 !strcmp(argv[i], "-g") ||
75 !strcmp(argv[i], "-v")) {
76 foreground = TRUE;
77 break;
79 i++;
82 if (foreground) {
83 /* run in console window */
84 exit(main(argc, argv, envp));
85 } else {
86 /* Start up as service */
87 char *SERVICE_NAME = BIND_SERVICE_NAME;
89 SERVICE_TABLE_ENTRY dispatchTable[] = {
90 { TEXT(SERVICE_NAME), (LPSERVICE_MAIN_FUNCTION)main },
91 { NULL, NULL }
94 rc = StartServiceCtrlDispatcher(dispatchTable);
95 if (!rc) {
96 fprintf(stderr, "Use -f to run from the command line.\n");
97 exit(GetLastError());
100 exit(0);
104 * Initialize the Service by registering it.
106 void
107 ntservice_init() {
108 if (!foreground) {
109 /* Register handler with the SCM */
110 hServiceStatus = RegisterServiceCtrlHandler(BIND_SERVICE_NAME,
111 (LPHANDLER_FUNCTION)ServiceControl);
112 if (!hServiceStatus) {
113 ns_main_earlyfatal(
114 "could not register service control handler");
115 UpdateSCM(SERVICE_STOPPED);
116 exit(1);
118 UpdateSCM(SERVICE_RUNNING);
119 } else {
120 strcpy(ConsoleTitle, "BIND Version ");
121 strcat(ConsoleTitle, VERSION);
122 SetConsoleTitle(ConsoleTitle);
126 void
127 ntservice_shutdown() {
128 UpdateSCM(SERVICE_STOPPED);
131 * Routine to check if this is a service or a foreground program
133 BOOL
134 ntservice_isservice() {
135 return(!foreground);
138 * ServiceControl(): Handles requests from the SCM and passes them on
139 * to named.
141 void
142 ServiceControl(DWORD dwCtrlCode) {
143 /* Handle the requested control code */
144 switch(dwCtrlCode) {
145 case SERVICE_CONTROL_INTERROGATE:
146 UpdateSCM(0);
147 break;
149 case SERVICE_CONTROL_SHUTDOWN:
150 case SERVICE_CONTROL_STOP:
151 ns_server_flushonshutdown(ns_g_server, ISC_TRUE);
152 isc_app_shutdown();
153 UpdateSCM(SERVICE_STOPPED);
154 break;
155 default:
156 break;
161 * Tell the Service Control Manager the state of the service.
163 void UpdateSCM(DWORD state) {
164 SERVICE_STATUS ss;
165 static DWORD dwState = SERVICE_STOPPED;
167 if (hServiceStatus) {
168 if (state)
169 dwState = state;
171 memset(&ss, 0, sizeof(SERVICE_STATUS));
172 ss.dwServiceType |= SERVICE_WIN32_OWN_PROCESS;
173 ss.dwCurrentState = dwState;
174 ss.dwControlsAccepted = SERVICE_ACCEPT_STOP |
175 SERVICE_ACCEPT_SHUTDOWN;
176 ss.dwCheckPoint = 0;
177 ss.dwServiceSpecificExitCode = 0;
178 ss.dwWin32ExitCode = NO_ERROR;
179 ss.dwWaitHint = dwState == SERVICE_STOP_PENDING ? 10000 : 1000;
181 if (!SetServiceStatus(hServiceStatus, &ss)) {
182 ss.dwCurrentState = SERVICE_STOPPED;
183 SetServiceStatus(hServiceStatus, &ss);
189 * C-runtime stuff used to initialize the app and
190 * get argv, argc, envp.
193 typedef struct
195 int newmode;
196 } _startupinfo;
198 _CRTIMP void __cdecl __set_app_type(int);
199 _CRTIMP void __cdecl __getmainargs(int *, char ***, char ***, int,
200 _startupinfo *);
201 void __cdecl _setargv(void);
203 #ifdef _M_IX86
204 /* Pentium FDIV adjustment */
205 extern int _adjust_fdiv;
206 extern int * _imp___adjust_fdiv;
207 /* Floating point precision */
208 extern void _setdefaultprecision();
209 #endif
211 extern int _newmode; /* malloc new() handler mode */
212 extern int _dowildcard; /* passed to __getmainargs() */
214 typedef void (__cdecl *_PVFV)(void);
215 extern void __cdecl _initterm(_PVFV *, _PVFV *);
216 extern _PVFV *__onexitbegin;
217 extern _PVFV *__onexitend;
218 extern _CRTIMP char **__initenv;
221 * Do the work that mainCRTStartup() would normally do
223 void GetArgs(int *argc, char ***argv, char ***envp)
225 _startupinfo startinfo;
228 * Set the app type to Console (check CRT/SRC/INTERNAL.H:
229 * \#define _CONSOLE_APP 1)
231 __set_app_type(1);
233 /* Mark this module as an EXE file */
234 __onexitbegin = __onexitend = (_PVFV *)(-1);
236 startinfo.newmode = _newmode;
237 __getmainargs(argc, argv, envp, _dowildcard, &startinfo);
238 __initenv = *envp;
240 #ifdef _M_IX86
241 _adjust_fdiv = * _imp___adjust_fdiv;
242 _setdefaultprecision();
243 #endif