/*****************************************************************************/

/*
 *      serv.c  --  Win32 bayusb service starter.
 *
 *      Copyright (C) 2000-2001
 *          Thomas Sailer (t.sailer@alumni.ethz.ch)
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Please note that the GPL allows you to use the driver, NOT the radio.
 *  In order to use the radio, you need a license from the communications
 *  authority of your country.
 *
 *  History:
 *   0.1  19.09.2000  Created
 */

/*****************************************************************************/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#define _REENTRANT

#include "trx.h"

#include <windows.h>
#include <winsock.h>
#include <wincon.h>
#include <process.h>
#include <errno.h>
#include <getopt.h>
#include <malloc.h>

/* --------------------------------------------------------------------- */

static unsigned int verboselevel = 10;
static unsigned int syslogmsg = 1;

/* --------------------------------------------------------------------- */

int lprintf(unsigned vl, const char *format, ...)
{
        va_list ap;
        int r;

        if (vl > verboselevel)
                return 0;
        va_start(ap, format);
        if (syslogmsg) {
		char buf[512];
		r = vsnprintf(buf, sizeof(buf), format, ap);
		OutputDebugString(buf);
        } else {
                r = vfprintf(stderr, format, ap);
		fflush(stderr);
	}
        va_end(ap);
        return r;
}

/* --------------------------------------------------------------------- */

static SERVICE_STATUS          MyServiceStatus; 
static SERVICE_STATUS_HANDLE   MyServiceStatusHandle; 

static void BaycomUsbServiceCtrlHandler(DWORD Opcode) 
{ 
        DWORD status; 
 
        switch(Opcode) { 
        case SERVICE_CONTROL_STOP: 
		server_entry_quit();
                MyServiceStatus.dwWin32ExitCode = 0; 
                MyServiceStatus.dwCurrentState  = SERVICE_STOP_PENDING; 
                MyServiceStatus.dwCheckPoint    = 0; 
                MyServiceStatus.dwWaitHint      = 0;
                if (!SetServiceStatus(MyServiceStatusHandle, &MyServiceStatus)) { 
                        status = GetLastError(); 
                        lprintf(1, "SetServiceStatus error %ld\n",status); 
                }
                lprintf(1, "Stopping baycomusbserv\n");
                return; 
 
        case SERVICE_CONTROL_INTERROGATE: 
                /* Fall through to send current status. */
                break;
 
        default:
                lprintf(1, "BaycomUsbServiceCtrlHandler: Unrecognized opcode %ld\n", Opcode); 
        }
        /* Send current status. */
        if (!SetServiceStatus(MyServiceStatusHandle, &MyServiceStatus)) { 
                status = GetLastError();
                lprintf(1, "SetServiceStatus error %ld\n",status); 
        }
}

static void BaycomUsbServiceStart(DWORD argc, LPTSTR *argv)
{ 
        DWORD status;
	char *args[8];

        MyServiceStatus.dwServiceType        = SERVICE_WIN32; 
        MyServiceStatus.dwCurrentState       = SERVICE_START_PENDING; 
        MyServiceStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP; 
        MyServiceStatus.dwWin32ExitCode      = 0; 
        MyServiceStatus.dwServiceSpecificExitCode = 0; 
        MyServiceStatus.dwCheckPoint         = 0; 
        MyServiceStatus.dwWaitHint           = 0; 
 
        MyServiceStatusHandle = RegisterServiceCtrlHandler(SERVICENAME, BaycomUsbServiceCtrlHandler);
        if (MyServiceStatusHandle == (SERVICE_STATUS_HANDLE)0) {
                lprintf(1, "RegisterServiceCtrlHandler failed %ld\n", GetLastError());
                return;
        }

	args[0] = "baycomusbserv";
	args[1] = "-s";
	args[2] = "-v";
	args[3] = "10";
	if (!argc){
		argc = 4;
		argv = args;
	}

        if (server_entry_parse_argv(argc, argv)) {
                MyServiceStatus.dwCurrentState       = SERVICE_STOPPED; 
                MyServiceStatus.dwCheckPoint         = 0; 
                MyServiceStatus.dwWaitHint           = 0; 
                MyServiceStatus.dwWin32ExitCode      = ERROR_ACCESS_DENIED; 
                MyServiceStatus.dwServiceSpecificExitCode = ERROR_INVALID_DATA;
                SetServiceStatus(MyServiceStatusHandle, &MyServiceStatus); 
                return; 
        }
        /* Initialization complete - report running status. */
        MyServiceStatus.dwCurrentState       = SERVICE_RUNNING; 
        MyServiceStatus.dwCheckPoint         = 0; 
        MyServiceStatus.dwWaitHint           = 0;
        if (!SetServiceStatus(MyServiceStatusHandle, &MyServiceStatus)) { 
                status = GetLastError(); 
                lprintf(1, "SetServiceStatus error %ld\n",status); 
        } 

        MyServiceStatus.dwWin32ExitCode = 0;
	MyServiceStatus.dwServiceSpecificExitCode = 0;
	if (server_entry_run()) {
                MyServiceStatus.dwWin32ExitCode      = ERROR_ACCESS_DENIED; 
                MyServiceStatus.dwServiceSpecificExitCode = ERROR_INVALID_DATA;
	}
        MyServiceStatus.dwCurrentState  = SERVICE_STOPPED; 
        MyServiceStatus.dwCheckPoint    = 0; 
        MyServiceStatus.dwWaitHint      = 0;
        if (!SetServiceStatus(MyServiceStatusHandle, &MyServiceStatus)) { 
                status = GetLastError(); 
                lprintf(1, "SetServiceStatus error %ld\n",status); 
        } 
        lprintf(1, "baycomusbserv stopped\n");
}

/* --------------------------------------------------------------------- */

int main(int argc, char *argv[])
{
        SERVICE_TABLE_ENTRY DispatchTable[] = { 
                { SERVICENAME, BaycomUsbServiceStart },
                { NULL, NULL } 
        };
        
        printf("baycomusbserv v" VERSION " (c) 1999-2001 by Thomas Sailer, HB9JNX/AE4WA\n");
        if (argc >= 2 && !strcmp(argv[1], "-S")) {
                if (!StartServiceCtrlDispatcher(DispatchTable)) {
                        lprintf(0, "Error starting service: %lu\n", GetLastError());
                        exit(1);
                }
                lprintf(0, "Starting Service\n");
                return 0;
        }
	if (server_entry_parse_argv(argc, argv))
		return 1;
	return server_entry_run();
}
