Newer
Older

rswindell
committed
/* ident.c */
/* Synchronet Indentification (RFC1413) functions */
/* $Id$ */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html *

rswindell
committed
* *
* 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. *
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* Anonymous FTP access to the most recent released source is available at *
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
* *
* Anonymous CVS access to the development source and modification history *
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
* (just hit return, no password is necessary) *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* You are encouraged to submit any modifications (preferably in Unix diff *
* format) via e-mail to mods@synchro.net *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
#include "sbbs.h"
#include "ident.h"
BOOL identify(union xp_sockaddr *client_addr, u_short local_port, char* buf
,size_t maxlen, int timeout)

rswindell
committed
{
char req[128];
int result;

rswindell
committed
SOCKET sock=INVALID_SOCKET;
struct timeval tv;
fd_set socket_set;
BOOL success=FALSE;
if(client_addr->addr.sa_family != AF_INET && client_addr->addr.sa_family != AF_INET6)
return FALSE;
if(timeout<=0)
timeout=IDENT_DEFAULT_TIMEOUT;

rswindell
committed
do {
if((sock = open_socket(SOCK_STREAM, "ident")) == INVALID_SOCKET) {

rswindell
committed
sprintf(buf,"ERROR %d creating socket",ERROR_VALUE);
break;
}
val=1;
ioctlsocket(sock,FIONBIO,&val);
memcpy(&addr, client_addr, xp_sockaddr_len(client_addr));
inet_setaddrport(&addr, IPPORT_IDENT);

rswindell
committed
if(result==SOCKET_ERROR
&& (ERROR_VALUE==EWOULDBLOCK || ERROR_VALUE==EINPROGRESS)) {
tv.tv_sec=timeout;
tv.tv_usec=0;
FD_ZERO(&socket_set);
FD_SET(sock,&socket_set);
if(select(sock+1,NULL,&socket_set,NULL,&tv)==1)
result=0; /* success */
}
if(result!=0) {

rswindell
committed
sprintf(buf,"ERROR %d connecting to server",ERROR_VALUE);
break;
}
val=0;
ioctlsocket(sock,FIONBIO,&val);
tv.tv_sec=10;
tv.tv_usec=0;
FD_ZERO(&socket_set);
FD_SET(sock,&socket_set);
i=select(sock+1,NULL,&socket_set,NULL,&tv);
if(i<1) {
sprintf(buf,"ERROR %d selecting socket for send",ERROR_VALUE);
break;
}
sprintf(req,"%u,%u\r\n", inet_addrport(client_addr), local_port);
if(sendsocket(sock,req,strlen(req))!=(int)strlen(req)) {

rswindell
committed
sprintf(buf,"ERROR %d sending request",ERROR_VALUE);
break;
}
tv.tv_sec=10;
tv.tv_usec=0;
FD_ZERO(&socket_set);
FD_SET(sock,&socket_set);
i=select(sock+1,&socket_set,NULL,NULL,&tv);
if(i<1) {
sprintf(buf,"ERROR %d detecting response",ERROR_VALUE);
break;
}
sprintf(buf,"ERROR %d receiving response",ERROR_VALUE);

rswindell
committed
break;
}

rswindell
committed
} while(0);
close_socket(sock);