Skip to content
Snippets Groups Projects
ntsvcs.c 39.3 KiB
Newer Older
/****************************************************************************/
/* Uninstall one or all services											*/
/****************************************************************************/
static int uninstall(const char* svc_name)
    SC_HANDLE   hSCManager;

    hSCManager = OpenSCManager(
                        NULL,                   /* machine (NULL == local) */
                        NULL,                   /* database (NULL == default) */
                        SC_MANAGER_ALL_ACCESS   /* access required */
                        );
    if(hSCManager==NULL) {
		fprintf(stderr,"!ERROR %d opening SC manager\n",GetLastError());
		return(-1);
	}

		if(svc_name==NULL	/* All? */
			|| !stricmp(ntsvc_list[i]->name, svc_name)
			|| !stricmp(ntsvc_list[i]->name+STRLEN_SYNCHRONET, svc_name))
			remove_service(hSCManager
				,ntsvc_list[i]->name
				,ntsvc_list[i]->display_name);

	CloseServiceHandle(hSCManager);

	return(0);
}

/****************************************************************************/
/* Utility function to disable a service									*/
/****************************************************************************/
static void set_service_start_type(SC_HANDLE hSCManager, char* name
								   ,char* disp_name, DWORD start_type)
{
    SC_HANDLE		hService;

	printf("%s service: %-*s ... "
		,start_type==SERVICE_DISABLED ? "Disabling" : "Enabling"
		,STRLEN_MAX_DISPLAY_NAME, disp_name);
    if((hService=open_service(hSCManager, name))==NULL)
		hService,				/* handle to service */
		SERVICE_NO_CHANGE,		/* type of service */
		start_type,				/* when to start service */
		SERVICE_NO_CHANGE,		/* severity if service fails to start */
		NULL,					/* pointer to service binary file name */
		NULL,					/* pointer to load ordering group name */
		NULL,					/* pointer to variable to get tag identifier */
		NULL,					/* pointer to array of dependency names */
		NULL,					/* pointer to account name of service */
		NULL,					/* pointer to password for service account */
		NULL					/* pointer to display name */
		printf("\n!ERROR %d changing service config for: %s\n",GetLastError(),name);
	else
		printf("%s\n", start_type_desc(start_type));

    CloseServiceHandle(hService);
}

/****************************************************************************/
/* Enable (set to auto-start) or disable one or all services				*/
/****************************************************************************/
static int enable(const char* svc_name, BOOL enabled)
{
	int			i;
    SC_HANDLE   hSCManager;

    hSCManager = OpenSCManager(
                        NULL,                   /* machine (NULL == local) */
                        NULL,                   /* database (NULL == default) */
                        SC_MANAGER_ALL_ACCESS   /* access required */
                        );
    if(hSCManager==NULL) {
		fprintf(stderr,"!ERROR %d opening SC manager\n",GetLastError());
		return(-1);
	}

	for(i=0;ntsvc_list[i]!=NULL;i++)
		if(svc_name==NULL	/* All? */
			|| !stricmp(ntsvc_list[i]->name, svc_name)
			|| !stricmp(ntsvc_list[i]->name+STRLEN_SYNCHRONET, svc_name))
			set_service_start_type(hSCManager
				,ntsvc_list[i]->name
				,ntsvc_list[i]->display_name
				,enabled ? (ntsvc_list[i]->autostart ? SERVICE_AUTO_START : SERVICE_DEMAND_START)
					: SERVICE_DISABLED);

	CloseServiceHandle(hSCManager);

	return(0);
}

/****************************************************************************/
/* List one or all services													*/
/****************************************************************************/
static int list(const char* svc_name)
{
	int			i;
    SC_HANDLE   hSCManager;
	DWORD		state;
	DWORD		start_type;

    hSCManager = OpenSCManager(
                        NULL,                   /* machine (NULL == local) */
                        NULL,                   /* database (NULL == default) */
                        SC_MANAGER_ALL_ACCESS   /* access required */
                        );
    if(hSCManager==NULL) {
		fprintf(stderr,"!ERROR %d opening SC manager\n",GetLastError());
		return(-1);
	}

	for(i=0;ntsvc_list[i]!=NULL;i++) {
		if(svc_name==NULL 
			|| !stricmp(ntsvc_list[i]->name, svc_name)
			|| !stricmp(ntsvc_list[i]->name+STRLEN_SYNCHRONET, svc_name)) {
			start_type = get_service_info(hSCManager, ntsvc_list[i]->name, &state);
			printf("%-*s ... %s, %s\n"
				,STRLEN_MAX_DISPLAY_NAME, ntsvc_list[i]->display_name
				,start_type_desc(start_type)
				,state_desc(state));
		}
	}

	CloseServiceHandle(hSCManager);

	return(0);
}

/****************************************************************************/
/* Start one or all services												*/
/****************************************************************************/
static int start(const char* svc_name, int argc, char** argv)
{
	int			i;
    SC_HANDLE   hSCManager;

    hSCManager = OpenSCManager(
                        NULL,                   /* machine (NULL == local) */
                        NULL,                   /* database (NULL == default) */
                        SC_MANAGER_ALL_ACCESS   /* access required */
                        );
    if(hSCManager==NULL) {
		fprintf(stderr,"!ERROR %d opening SC manager\n",GetLastError());
		return(-1);
	}

	for(i=0;ntsvc_list[i]!=NULL;i++) {
		if(svc_name==NULL 
			&& get_service_info(hSCManager, ntsvc_list[i]->name,NULL)==SERVICE_DISABLED)
		if(svc_name==NULL 
			|| !stricmp(ntsvc_list[i]->name, svc_name)
			|| !stricmp(ntsvc_list[i]->name+STRLEN_SYNCHRONET, svc_name))
			start_service(hSCManager,ntsvc_list[i]->name,ntsvc_list[i]->display_name

/****************************************************************************/
/* Main Entry Point															*/
/****************************************************************************/
int main(int argc, char** argv)
{
	char*	ctrl_dir;
	char*	arg;
	char	str[MAX_PATH+1];
	int		i;
	FILE*	fp=NULL;

	SERVICE_TABLE_ENTRY  ServiceDispatchTable[] = 
    { 
        { NTSVC_NAME_BBS,		bbs_start		}, 
		{ NTSVC_NAME_FTP,		ftp_start		},
		{ NTSVC_NAME_WEB,		web_start		},
		{ NTSVC_NAME_MAIL,		mail_start		},
		{ NTSVC_NAME_SERVICES,	services_start	},
        { NULL,					NULL			}	/* Terminator */
    }; 

	printf("\nSynchronet NT Services  Version %s%c  %s\n\n"
		,VERSION,REVISION,COPYRIGHT_NOTICE);

	loginAttemptListInit(&login_attempt_list);

Rob Swindell's avatar
Rob Swindell committed
	ctrl_dir = get_ctrl_dir(/* warn: */TRUE);
	sbbs_get_ini_fname(ini_file, ctrl_dir, NULL /* auto-host_name */);

	/* Initialize BBS startup structure */
    memset(&bbs_startup,0,sizeof(bbs_startup));
    bbs_startup.size=sizeof(bbs_startup);
	bbs_startup.cbdata=&bbs;
	bbs_startup.event_cbdata=&event;
	bbs_startup.event_lputs=svc_lputs;
    bbs_startup.terminated=svc_terminated;
	bbs_startup.login_attempt_list=&login_attempt_list;
    strcpy(bbs_startup.ctrl_dir,ctrl_dir);

	/* Initialize FTP startup structure */
    memset(&ftp_startup,0,sizeof(ftp_startup));
	ftp_startup.cbdata=&ftp;
    ftp_startup.size=sizeof(ftp_startup);
	ftp_startup.lputs=svc_lputs;
    ftp_startup.started=svc_started;
    ftp_startup.terminated=svc_terminated;
	ftp_startup.login_attempt_list=&login_attempt_list;
    strcpy(ftp_startup.ctrl_dir,ctrl_dir);

	/* Initialize Web Server startup structure */
    memset(&web_startup,0,sizeof(web_startup));
	web_startup.cbdata=&web;
    web_startup.size=sizeof(web_startup);
	web_startup.lputs=svc_lputs;
    web_startup.started=svc_started;
    web_startup.terminated=svc_terminated;
	web_startup.login_attempt_list=&login_attempt_list;
    strcpy(web_startup.ctrl_dir,ctrl_dir);

	/* Initialize Mail Server startup structure */
    memset(&mail_startup,0,sizeof(mail_startup));
	mail_startup.cbdata=&mail;
    mail_startup.size=sizeof(mail_startup);
	mail_startup.lputs=svc_lputs;
    mail_startup.started=svc_started;
    mail_startup.terminated=svc_terminated;
	mail_startup.login_attempt_list=&login_attempt_list;
    strcpy(mail_startup.ctrl_dir,ctrl_dir);

	/* Initialize Services startup structure */
    memset(&services_startup,0,sizeof(services_startup));
	services_startup.cbdata=&services;
    services_startup.size=sizeof(services_startup);
	services_startup.lputs=svc_lputs;
    services_startup.started=svc_started;
	services_startup.recycle=svc_recycle;
    services_startup.terminated=svc_terminated;
	services_startup.clients=svc_clients;
	services_startup.login_attempt_list=&login_attempt_list;
    strcpy(services_startup.ctrl_dir,ctrl_dir);

	/* Read .ini file here */
	if((fp=fopen(ini_file,"r"))!=NULL) {
		sprintf(str,"Reading %s",ini_file);
	}

	/* We call this function to set defaults, even if there's no .ini file */
		,&bbs.autostart			,NULL
		,&ftp.autostart			,NULL
		,&web.autostart			,NULL
		,&mail.autostart		,NULL
		,&services.autostart	,NULL

	/* close .ini file here */
	if(fp!=NULL)
		fclose(fp);

	if(chdir(ctrl_dir)!=0) {
rswindell's avatar
rswindell committed
		sprintf(str,"!ERROR %d (%s) changing directory to: %s", errno, strerror(errno), ctrl_dir);
	for(i=1;i<argc;i++) {
		arg=argv[i];
		if(!stricmp(arg,"help") || *arg=='?')
			start_services=FALSE;

		if(!stricmp(arg,"list"))
			return list(argv[i+1]);

		if(!stricmp(arg,"install"))
			return install(argv[i+1]);

		if(!stricmp(arg,"remove"))
			return uninstall(argv[i+1]);
			return control(argv[i+1],SERVICE_CONTROL_STOP);

		if(!stricmp(arg,"start"))
			return start(argv[i+1],argc,argv);

		if(!stricmp(arg,"recycle"))
			return control(argv[i+1],SERVICE_CONTROL_RECYCLE);

		if(!stricmp(arg,"mute"))
			return control(argv[i+1],SERVICE_CONTROL_MUTE);

		if(!stricmp(arg,"unmute"))
			return control(argv[i+1],SERVICE_CONTROL_UNMUTE);
	if(start_services) {
		printf("Starting service control dispatcher.\n" );
		printf("This may take several seconds.  Please wait.\n" );

		if(StartServiceCtrlDispatcher(ServiceDispatchTable))
			return(0);

		sprintf(str,"!ERROR %u starting service control dispatcher",GetLastError());
		printf("%s\n\n",str);
		OutputDebugString(str); 
	}

	SAFECOPY(str,getfname(argv[0]));
	printf("Usage: %s [command] [service]\n", str);
	printf("\nIf service name not specified, default is ALL services.\n");
	printf("\nAvailable Commands:\n\n");
	printf("%-20s %s\n","list","to list services");
    printf("%-20s %s\n","install","to install services");
rswindell's avatar
rswindell committed
    printf("%-20s %s\n","remove","to remove services");
    printf("%-20s %s\n","disable","to disable services");
    printf("%-20s %s\n","enable","to re-enable disabled services");
    printf("%-20s %s\n","start","to start services");
    printf("%-20s %s\n","stop","to stop services");
	printf("%-20s %s\n","recycle","to recycle services");
	printf("%-20s %s\n","mute","to mute (sounds of) services");
	printf("%-20s %s\n","unmute","to unmute (sounds of) services");
	printf("\nAvailable Services:\n\n");
	printf("%-20s %s\n","Name","Description");
	printf("%-20s %s\n","----","-----------");
	for(i=0;ntsvc_list[i]!=NULL;i++)
		printf("%-20s %s\n",ntsvc_list[i]->name+STRLEN_SYNCHRONET,ntsvc_list[i]->display_name);