diff --git a/src/sexpots/sexpots.c b/src/sexpots/sexpots.c
index ecaf80bc17476db5ee40242306c56f11b12d1a2d..e34b10aeaf3eda38e66cb93b22619f642a88d168 100644
--- a/src/sexpots/sexpots.c
+++ b/src/sexpots/sexpots.c
@@ -73,6 +73,7 @@ BOOL	com_handle_passed=FALSE;
 BOOL	com_alreadyconnected=FALSE;
 BOOL	com_hangup=TRUE;
 ulong	com_baudrate=0;
+BOOL	dcd_ignore=FALSE;
 int		dcd_timeout=10;	/* seconds */
 ulong	dtr_delay=100;	/* milliseconds */
 
@@ -81,7 +82,7 @@ BOOL	terminate_after_one_call=FALSE;
 
 SOCKET	sock=INVALID_SOCKET;
 char	host[MAX_PATH+1];
-ushort	port;
+ushort	port=IPPORT_TELNET;
 
 /* stats */
 ulong	total_calls=0;
@@ -101,6 +102,17 @@ uchar	telnet_remote_option[0x100];
 BYTE	telnet_cmd[64];
 int		telnet_cmdlen;
 
+/* ident (RFC1416) server stuff */
+BOOL	ident=FALSE;
+ushort	ident_port=IPPORT_IDENT;
+ulong	ident_interface=INADDR_ANY;
+SOCKET	ident_sock=INVALID_SOCKET;
+char	ident_response[INI_MAX_VALUE_LEN];
+
+/* Caller-ID stuff */
+char	cid_name[64];
+char	cid_number[64];
+
 /****************************************************************************/
 /****************************************************************************/
 int usage(const char* fname)
@@ -275,6 +287,8 @@ void close_socket(SOCKET* sock)
 /****************************************************************************/
 void cleanup(void)
 {
+	terminated=TRUE;
+
 	lprintf(LOG_INFO,"Cleaning up ...");
 
 
@@ -286,6 +300,7 @@ void cleanup(void)
 	}
 
 	close_socket(&sock);
+	close_socket(&ident_sock);
 
 #ifdef _WINSOCKAPI_
 	WSACleanup();
@@ -308,6 +323,9 @@ BOOL wait_for_call(HANDLE com_handle)
 	BOOL		result=TRUE;
 	DWORD		events=0;
 
+	ZERO_VAR(cid_name);
+	ZERO_VAR(cid_number);
+
 	if(com_alreadyconnected)
 		return TRUE;
 
@@ -328,22 +346,30 @@ BOOL wait_for_call(HANDLE com_handle)
 	while(1) {
 		if(terminated)
 			return FALSE;
-		if(comGetModemStatus(com_handle)&COM_DCD)
-			break;
-		if((rd=comReadBuf(com_handle, str, sizeof(str)-1, 250)) > 0) {
+		if((rd=comReadBuf(com_handle, str, sizeof(str)-1, /* terminator: */'\n', 250)) > 0) {
 			str[rd]=0;
 			truncsp(str);
 			p=str;
 			SKIP_WHITESPACE(p);
-			lprintf(LOG_INFO, "Modem Message: %s", p);
-			if(strncmp(p,"CONNECT ",8)==0) {
-				long rate=atoi(p+8);
-				if(rate)
-					SAFEPRINTF2(termspeed,"%u,%u", rate, rate);
+			if(*p) {
+				lprintf(LOG_INFO, "Modem Message: %s", p);
+				if(strncmp(p,"CONNECT ",8)==0) {
+					long rate=atoi(p+8);
+					if(rate)
+						SAFEPRINTF2(termspeed,"%u,%u", rate, rate);
+				}
+				else if(strncmp(p,"NMBR = ",7)==0)
+					SAFECOPY(cid_number, p+7);
+				else if(strncmp(p,"NAME = ",7)==0)
+					SAFECOPY(cid_name, p+7);
 			}
+			continue;	/* don't check DCD until we've received all the modem msgs */
 		}
+		if(comGetModemStatus(com_handle)&COM_DCD)
+			break;
 	}
 
+	lprintf(LOG_INFO,"Carrier detected on %s", com_dev);
 	return TRUE;
 }
 
@@ -423,6 +449,99 @@ void input_thread(void* arg)
 	input_thread_terminated=TRUE;
 }
 
+void ident_server_thread(void* arg)
+{
+	int				result;
+	SOCKET			sock;
+	SOCKADDR_IN		server_addr={0};
+	fd_set			socket_set;
+	struct timeval tv;
+
+	lprintf(LOG_DEBUG,"Ident server thread started");
+
+	if((sock=socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) == INVALID_SOCKET) {
+		lprintf(LOG_ERR,"ERROR %u creating socket", ERROR_VALUE);
+		return;
+	}
+	
+    memset(&server_addr, 0, sizeof(server_addr));
+
+	server_addr.sin_addr.s_addr = htonl(ident_interface);
+    server_addr.sin_family = AF_INET;
+    server_addr.sin_port   = htons(ident_port);
+
+    if(bind(sock,(struct sockaddr *)&server_addr,sizeof(server_addr))!=0) {
+		lprintf(LOG_ERR,"ERROR %u binding ident server socket", ERROR_VALUE);
+		close_socket(&sock);
+		return;
+	}
+
+    if(listen(sock, 1)) {
+		lprintf(LOG_ERR,"!ERROR %u listening on ident server socket", ERROR_VALUE);
+		close_socket(&sock);
+		return;
+	}
+
+	while(!terminated) {
+		/* now wait for connection */
+
+		FD_ZERO(&socket_set);
+		FD_SET(sock,&socket_set);
+
+		tv.tv_sec=5;
+		tv.tv_usec=0;
+
+		if((result=select(sock+1,&socket_set,NULL,NULL,&tv))<1) {
+			if(result==0)
+				continue;
+			if(ERROR_VALUE==EINTR)
+				lprintf(LOG_DEBUG,"Ident Server listening interrupted");
+			else if(ERROR_VALUE == ENOTSOCK)
+            	lprintf(LOG_NOTICE,"Ident Server sockets closed");
+			else
+				lprintf(LOG_WARNING,"!ERROR %d selecting ident socket",ERROR_VALUE);
+			continue;
+		}
+
+		if(FD_ISSET(sock,&socket_set)) {
+			SOCKADDR_IN		client_addr;
+			socklen_t		client_addr_len;
+			SOCKET			client_socket=INVALID_SOCKET;
+			char			request[128];
+			char			response[256];
+			int				rd;
+
+			client_addr_len = sizeof(client_addr);
+			client_socket = accept(sock, (struct sockaddr *)&client_addr, &client_addr_len);
+			if(client_socket != INVALID_SOCKET) {
+				lprintf(LOG_INFO,"Ident request from %s : %u"
+					,inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
+				FD_ZERO(&socket_set);
+				FD_SET(client_socket,&socket_set);
+				tv.tv_sec=5;
+				tv.tv_usec=0;
+				if(select(client_socket+1,&socket_set,NULL,NULL,&tv)==1) {
+					lprintf(LOG_DEBUG,"Ident select");
+					if((rd=recv(client_socket, request, sizeof(request), 0)) > 0) {
+						request[rd]=0;
+						truncsp(request);
+						lprintf(LOG_INFO,"Ident request: %s", request);
+						/* example response: "40931,23:USERID:UNIX:cyan" */
+						SAFEPRINTF4(response,"%s:%s:%s %s\r\n"
+							,request, ident_response, cid_number, cid_name);
+						sendsocket(client_socket,response,strlen(response));
+					} else
+						lprintf(LOG_DEBUG,"ident recv=%d %d", rd, ERROR_VALUE);
+				}
+				close_socket(&client_socket);
+			}
+		}
+	}
+
+	close_socket(&sock);
+	lprintf(LOG_DEBUG,"Ident server thread terminated");
+}
+
 static void send_telnet_cmd(uchar cmd, uchar opt)
 {
 	char buf[16];
@@ -607,7 +726,7 @@ BOOL handle_call(void)
 
 	while(!terminated) {
 
-		if((comGetModemStatus(com_handle)&COM_DCD) == 0) {
+		if(!dcd_ignore && (comGetModemStatus(com_handle)&COM_DCD) == 0) {
 			lprintf(LOG_WARNING,"Loss of Carrier Detect (DCD) detected");
 			break;
 		}
@@ -706,6 +825,7 @@ BOOL WINAPI ControlHandler(DWORD CtrlType)
 void parse_ini_file(const char* ini_fname)
 {
 	FILE* fp;
+	char* section;
 
 	if((fp=fopen(ini_fname,"r"))!=NULL)
 		lprintf(LOG_INFO,"Reading %s",ini_fname);
@@ -718,25 +838,32 @@ void parse_ini_file(const char* ini_fname)
 		log_level=LOG_DEBUG;
 	
 	/* [COM] Section */
-	iniReadString(fp, "COM", "Device", "COM1", com_dev);
-	iniReadString(fp, "COM", "ModemInit", "AT&F", mdm_init);
-	iniReadString(fp, "COM", "ModemAutoAnswer", "ATS0=1", mdm_autoans);
-	iniReadString(fp, "COM", "ModemCleanup", "ATS0=0", mdm_cleanup);
-	com_hangup	    = iniReadBool(fp, "COM", "Hangup", com_hangup);
-	mdm_null	    = iniReadBool(fp, "COM", "NullModem", mdm_null);
-	mdm_timeout     = iniReadInteger(fp, "COM", "ModemTimeout", mdm_timeout);
-	dcd_timeout     = iniReadInteger(fp, "COM", "DCDTimeout", dcd_timeout);
-	dtr_delay		= iniReadLongInt(fp, "COM", "DTRDelay", dtr_delay);
-	com_baudrate    = iniReadLongInt(fp, "COM", "BaudRate", com_baudrate);
+	section="COM";
+	iniReadString(fp, section, "Device", "COM1", com_dev);
+	iniReadString(fp, section, "ModemInit", "AT&F", mdm_init);
+	iniReadString(fp, section, "ModemAutoAnswer", "ATS0=1", mdm_autoans);
+	iniReadString(fp, section, "ModemCleanup", "ATS0=0", mdm_cleanup);
+	com_hangup	    = iniReadBool(fp, section, "Hangup", com_hangup);
+	mdm_null	    = iniReadBool(fp, section, "NullModem", mdm_null);
+	mdm_timeout     = iniReadInteger(fp, section, "ModemTimeout", mdm_timeout);
+	dcd_timeout     = iniReadInteger(fp, section, "DCDTimeout", dcd_timeout);
+	dcd_ignore      = iniReadBool(fp, section, "IgnoreDCD", dcd_ignore);
+	dtr_delay		= iniReadLongInt(fp, section, "DTRDelay", dtr_delay);
+	com_baudrate    = iniReadLongInt(fp, section, "BaudRate", com_baudrate);
 
 	/* [TCP] Section */
-	iniReadString(fp, "TCP", "Host", "localhost", host);
-	iniReadString(fp, "TCP", "TelnetTermType", termtype, termtype);
-	iniReadString(fp, "TCP", "TelnetTermSpeed", "28800,28800", termspeed);
-	port					= iniReadShortInt(fp, "TCP", "Port", IPPORT_TELNET);
-	tcp_nodelay				= iniReadBool(fp,"TCP","NODELAY", tcp_nodelay);
-	telnet					= iniReadBool(fp,"TCP","Telnet", telnet);
-	debug_telnet			= iniReadBool(fp,"TCP","DebugTelnet", debug_telnet);
+	section="TCP";
+	iniReadString(fp, section, "Host", "localhost", host);
+	iniReadString(fp, section, "TelnetTermType", termtype, termtype);
+	iniReadString(fp, section, "TelnetTermSpeed", "28800,28800", termspeed);
+	port					= iniReadShortInt(fp, section, "Port", port);
+	tcp_nodelay				= iniReadBool(fp,section,"NODELAY", tcp_nodelay);
+	telnet					= iniReadBool(fp,section,"Telnet", telnet);
+	debug_telnet			= iniReadBool(fp,section,"DebugTelnet", debug_telnet);
+	ident					= iniReadBool(fp,section,"Ident", ident);
+	ident_port				= iniReadShortInt(fp, section, "IdentPort", ident_port);
+	ident_interface			= iniReadIpAddress(fp, section, "IdentInterface", ident_interface);
+	iniReadString(fp, section, "IdentResponse", "CALLERID:SEXPOTS", ident_response);
 
 	if(fp!=NULL)
 		fclose(fp);
@@ -879,6 +1006,9 @@ int main(int argc, char** argv)
 
 	lprintf(LOG_INFO,"%s set to %ld bps DTE rate", com_dev, comGetBaudRate(com_handle));
 
+	if(ident)
+		_beginthread(ident_server_thread, 0, NULL);
+
 	/***************************/
 	/* Initialization Complete */
 	/***************************/