[BACK]Return to ntservice.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / mpl / bind / dist / bin / named / win32

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>