diff --git a/src/sexpots/sexpots.c b/src/sexpots/sexpots.c
index f92b4efd2e6a43094331b4bdc63d92eddbab4d1a..31aa58520b64a079097b653fb2bec6c2188b3328 100644
--- a/src/sexpots/sexpots.c
+++ b/src/sexpots/sexpots.c
@@ -189,6 +189,82 @@ static int syslog(int level, char *fmt, ...)
     return(retval);
 }
 
+#endif
+
+/****************************************************************************/
+/****************************************************************************/
+int lputs(int level, const char* str)
+{
+	time_t		t;
+	struct tm	tm;
+	char		tstr[32];
+#if defined(_WIN32)
+	char dbgmsg[1024];
+	_snprintf(dbgmsg,sizeof(dbgmsg),"%s %s", NAME, str);
+	if(log_level==LOG_DEBUG)
+		OutputDebugString(dbgmsg);
+#endif
+
+	if(level>log_level)
+		return 0;
+
+	if(daemonize)
+		return syslog(level,"%s", str);
+
+	t=time(NULL);
+	if(localtime_r(&t,&tm)==NULL)
+		tstr[0]=0;
+	else
+		sprintf(tstr,"%d/%d %02d:%02d:%02d "
+			,tm.tm_mon+1,tm.tm_mday
+			,tm.tm_hour,tm.tm_min,tm.tm_sec);
+
+	return fprintf(level>=LOG_NOTICE ? stdout:stderr, "%s %s\n", tstr, str);
+}
+
+/****************************************************************************/
+/****************************************************************************/
+int lprintf(int level, char *fmt, ...)
+{
+	va_list argptr;
+	char sbuf[1024];
+
+    va_start(argptr,fmt);
+    vsnprintf(sbuf,sizeof(sbuf),fmt,argptr);
+	sbuf[sizeof(sbuf)-1]=0;
+    va_end(argptr);
+    return(lputs(level,sbuf));
+}
+
+
+#if defined(_WIN32)
+
+#define NTSVC_TIMEOUT_STARTUP	30000	/* Milliseconds */
+#define NTSVC_TIMEOUT_SHUTDOWN	30000	/* Milliseconds */
+
+SERVICE_STATUS_HANDLE	svc_status_handle;
+SERVICE_STATUS			svc_status;
+
+void WINAPI ServiceControlHandler(DWORD dwCtrlCode)
+{
+	switch(dwCtrlCode) {
+		case SERVICE_CONTROL_STOP:
+		case SERVICE_CONTROL_SHUTDOWN:
+			lprintf(LOG_NOTICE,"Received termination control signal: %d", dwCtrlCode);
+			svc_status.dwWaitHint=NTSVC_TIMEOUT_SHUTDOWN;
+			svc_status.dwCurrentState=SERVICE_STOP_PENDING;
+			SetServiceStatus(svc_status_handle, &svc_status);
+			terminated=TRUE;
+//			SetEvent(service_event);
+			break;
+		case SERVICE_CONTROL_INTERROGATE:
+			lprintf(LOG_DEBUG,"Ignoring service control signal: SERVICE_CONTROL_INTERROGATE");
+			break;
+		default:
+			lprintf(LOG_WARNING,"Received unsupported service control signal: %d", dwCtrlCode);
+			break;
+	}
+}
 
 /* ChangeServiceConfig2 is a Win2K+ API function, must call dynamically */
 typedef WINADVAPI BOOL (WINAPI *ChangeServiceConfig2_t)(SC_HANDLE, DWORD, LPCVOID);
@@ -345,52 +421,6 @@ static int install(void)
 }
 #endif
 
-
-/****************************************************************************/
-/****************************************************************************/
-int lputs(int level, const char* str)
-{
-	time_t		t;
-	struct tm	tm;
-	char		tstr[32];
-#if defined(_WIN32)
-	char dbgmsg[1024];
-	_snprintf(dbgmsg,sizeof(dbgmsg),"%s %s", NAME, str);
-	if(log_level==LOG_DEBUG)
-		OutputDebugString(dbgmsg);
-#endif
-
-	if(level>log_level)
-		return 0;
-
-	if(daemonize)
-		return syslog(level,"%s", str);
-
-	t=time(NULL);
-	if(localtime_r(&t,&tm)==NULL)
-		tstr[0]=0;
-	else
-		sprintf(tstr,"%d/%d %02d:%02d:%02d "
-			,tm.tm_mon+1,tm.tm_mday
-			,tm.tm_hour,tm.tm_min,tm.tm_sec);
-
-	return fprintf(level>=LOG_NOTICE ? stdout:stderr, "%s %s\n", tstr, str);
-}
-
-/****************************************************************************/
-/****************************************************************************/
-int lprintf(int level, char *fmt, ...)
-{
-	va_list argptr;
-	char sbuf[1024];
-
-    va_start(argptr,fmt);
-    vsnprintf(sbuf,sizeof(sbuf),fmt,argptr);
-	sbuf[sizeof(sbuf)-1]=0;
-    va_end(argptr);
-    return(lputs(level,sbuf));
-}
-
 #ifdef _WINSOCKAPI_
 
 /* Note: Don't call WSACleanup() or TCP session will close! */
@@ -1152,30 +1182,9 @@ service_loop(int argc, char** argv)
 {
 	int		argn;
 	char*	arg;
-	char*	p;
 	char	str[128];
-	char	path[MAX_PATH+1];
-	char	fname[MAX_PATH+1];
-	char	ini_fname[MAX_PATH+1];
 	char	compiler[128];
 
-	/******************/
-	/* Read .ini file */
-	/******************/
-	/* Generate path/sexpots[.host].ini from path/sexpots[.exe] */
-	SAFECOPY(path,argv[0]);
-	p=getfname(path);
-	SAFECOPY(fname,p);
-	*p=0;
-	if((p=getfext(fname))!=NULL) 
-		*p=0;
-	SAFECOPY(termtype,fname);
-	strcat(fname,".ini");
-
-	iniFileName(ini_fname,sizeof(ini_fname),path,fname);
-	parse_ini_file(ini_fname);
-
-
 	for(argn=1; argn<(int)argc; argn++) {
 		arg=argv[argn];
 		if(*arg!='-') {	/* .ini file specified */
@@ -1221,8 +1230,6 @@ service_loop(int argc, char** argv)
 	}
 
 #if defined(_WIN32)
-	SetConsoleCtrlHandler(ControlHandler, TRUE /* Add */);
-
 	/* Convert "1" to "COM1" for Windows */
 	{
 		int i;
@@ -1230,6 +1237,22 @@ service_loop(int argc, char** argv)
 		if((i=atoi(com_dev)) != 0)
 			SAFEPRINTF(com_dev, "COM%d", i);
 	}
+
+	if(daemonize) {
+
+		if((svc_status_handle = RegisterServiceCtrlHandler(NAME, ServiceControlHandler))==0) {
+			lprintf(LOG_ERR,"!ERROR %d registering service control handler",GetLastError());
+			return;
+		}
+
+		svc_status.dwServiceType=SERVICE_WIN32_OWN_PROCESS;
+		svc_status.dwControlsAccepted=SERVICE_ACCEPT_SHUTDOWN;
+		svc_status.dwWaitHint=NTSVC_TIMEOUT_STARTUP;
+
+		svc_status.dwCurrentState=SERVICE_START_PENDING;
+		SetServiceStatus(svc_status_handle, &svc_status);
+	}
+
 #endif
 
 	lprintf(LOG_INFO,"%s", comVersion(str,sizeof(str)));
@@ -1268,6 +1291,14 @@ service_loop(int argc, char** argv)
 	if(ident)
 		_beginthread(ident_server_thread, 0, NULL);
 
+#if defined(_WIN32)
+	if(daemonize) {
+		svc_status.dwCurrentState=SERVICE_RUNNING;
+		svc_status.dwControlsAccepted|=SERVICE_ACCEPT_STOP;
+		SetServiceStatus(svc_status_handle, &svc_status);
+	}
+#endif
+
 	/***************************/
 	/* Initialization Complete */
 	/***************************/
@@ -1286,10 +1317,17 @@ service_loop(int argc, char** argv)
 			lprintf(LOG_INFO,"Call completed (%lu total)", total_calls);
 		}
 		if(com_hangup && !hangup_call(com_handle))
-			return;
+			break;
 		if(terminate_after_one_call)
 			break;
 	}
+
+#if defined(_WIN32)
+	if(daemonize) {
+		svc_status.dwCurrentState=SERVICE_STOPPED;
+		SetServiceStatus(svc_status_handle, &svc_status);
+	}
+#endif
 }
 
 
@@ -1299,6 +1337,10 @@ int main(int argc, char** argv)
 {
 	int		argn;
 	char*	arg;
+	char*	p;
+	char	path[MAX_PATH+1];
+	char	fname[MAX_PATH+1];
+	char	ini_fname[MAX_PATH+1];
 
 	/*******************************/
 	/* Generate and display banner */
@@ -1315,6 +1357,21 @@ int main(int argc, char** argv)
 
 	fprintf(stdout,"%s\n\n", banner);
 
+	/******************/
+	/* Read .ini file */
+	/******************/
+	/* Generate path/sexpots[.host].ini from path/sexpots[.exe] */
+	SAFECOPY(path,argv[0]);
+	p=getfname(path);
+	SAFECOPY(fname,p);
+	*p=0;
+	if((p=getfext(fname))!=NULL) 
+		*p=0;
+	SAFECOPY(termtype,fname);
+	strcat(fname,".ini");
+
+	iniFileName(ini_fname,sizeof(ini_fname),path,fname);
+	parse_ini_file(ini_fname);
 
 	/**********************/
 	/* Parse command-line */
@@ -1357,7 +1414,7 @@ int main(int argc, char** argv)
 		}
 		return 0;
 	}
-
+	SetConsoleCtrlHandler(ControlHandler, TRUE /* Add */);
 
 #endif