⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cwinsock.cpp

📁 能够通过输入IP地址扫描端口
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
	CWinsock.cpp
	Classe base per interfaccia Winsock (SRT/SDK).
	Luca Piergentili, 15/07/96
	lpiergentili@yahoo.com
	http://www.geocities.com/lpiergentili/

	La classe viene usata come wrapper per gestire in locale i servizi implementati.
	Rimappa l'API Winsock a seconda della definizione della macro _DEBUGSOCKET:
	- se non viene definita la macro _DEBUGSOCKET le chiamate Winsock vengono rimappate sull'API originale
	- se viene definita la macro _DEBUGSOCKET vengono rimappate le chiamate winsock implementando unicamente i servizi SMTP/POP3
	  (non viene effettuato nessun controllo sull'esistenza delle directory utilizzate, da create a parte)
*/
#include "CWinsock.h"

#ifdef _DEBUGSOCKET

#include "env.h"
#include "pragma.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "strcpyn.h"
#if defined(_WINDOWS)
  #include "window.h"
#else
  #include "typedef.h"
#endif
#include <winsock.h>
#include "lmhosts.h"
#include "CDateTime.h"

#define WSA_MAX_SOCKETS	1								// numero max di socket gestiti (1-255)
#define WSA_MAX_MTU		4096								// valore MTU (512-8192)
#define POP3_PORT		110								// porta POP3
#define SMTP_PORT		25								// porta SMTP
#define BUF_SIZE		1048576							// dimensione del buffer per la lettura dal file (POP3)
#define MAX_DELE_MARK	512								// numero max di mark per il comando DELE
#ifdef _WINNT
  #define MAIL_DIRECTORY	"c:\\inetpub\\mail\\"				// directory per le mailbox
#else
  #define MAIL_DIRECTORY	"c:\\webshare\\mail\\"
#endif
#define SOCKET_FILE		MAIL_DIRECTORY"log\\socket.txt"		// file per il socket
#define COUNT_FILE		"tot.txt"							// file per i totali
#define USERS_FILE		"users.txt"						// file utenti
#define MAX_USR_LEN		20								// lunghezza max nome utente
#define MAX_EMAIL_LEN	35								// lunghezza max email
#define CRLF_LEN		2								// CR+LF
#define USR_ENTRY_LEN	(MAX_USR_LEN+MAX_EMAIL_LEN+CRLF_LEN)	// dimensione del record

/*
	CWinsock()
*/
CWinsock::CWinsock()
{
	iWSALastError = 0;
	iWSAFlag = 0;
	hFile = HFILE_ERROR;
	hSocket = INVALID_SOCKET;
	pHostName = LOCAL_HOST_NAME;
	pHostIp = LOCAL_HOST;
	iService = -1;
	iCommand = 0;
	pHostLastSend = new char[WSA_MAX_MTU + 1];
	memset(pHostLastSend,'\0',WSA_MAX_MTU + 1);
	pHostLastRecv = new char[WSA_MAX_MTU + 1];
	memset(pHostLastRecv,'\0',WSA_MAX_MTU + 1);
	pPop3Buffer = new char[BUF_SIZE + 1];
	memset(pPop3Buffer,'\0',BUF_SIZE + 1);
	bRetr = FALSE;
	hMailBox = HFILE_ERROR;
	pMailBox = new char[MAX_EMAIL_LEN + 1];
	memset(pMailBox,'\0',MAX_EMAIL_LEN + 1);
	iTotMail = 0;
	iDelArray = new int[MAX_DELE_MARK + 1];
	memset(iDelArray,'\0',MAX_DELE_MARK + 1);
	iDelIndex = -1;
	date.Reset();
}

/*
	~CWinsock()
*/
CWinsock::~CWinsock()
{
	if(pHostLastSend)
		delete [] pHostLastSend,pHostLastSend = NULL;
	if(pHostLastRecv)
		delete [] pHostLastRecv,pHostLastRecv = NULL;
	if(pPop3Buffer)
		delete [] pPop3Buffer,pPop3Buffer = NULL;
	if(pMailBox)
		delete [] pMailBox,pMailBox = NULL;
	if(iDelArray)
		delete [] iDelArray,iDelArray = NULL;
}

/*
	WSAStartup()
*/
int PASCAL FAR CWinsock::WSAStartup(WORD wVersionRequired,LPWSADATA lpWSAData)
{
	lpWSAData->wVersion		=	MAKEWORD(1,1);					// versione
	lpWSAData->wHighVersion	=	MAKEWORD(1,1);					// versione
	lstrcpy(lpWSAData->szDescription,"Dummy Winsock library v.1.0");	// vendor info
	lstrcpy(lpWSAData->szSystemStatus,"Written by Luca Piergentili");// more info
	lpWSAData->iMaxSockets	=	WSA_MAX_SOCKETS;				// numero massimo di socket supportati
	lpWSAData->iMaxUdpDg	=	WSA_MAX_MTU;					// valore MTU
	lpWSAData->lpVendorInfo	=	NULL;						// struttura fornita dal vendor
	iWSAFlag = 1;
	return(0);
}

/*
	WSACleanup()
*/
int PASCAL FAR CWinsock::WSACleanup(void)
{
	if(!iWSAFlag)
	{
		WSASetLastError(WSANOTINITIALISED);
		return(SOCKET_ERROR);
	}
	else
		return(0);
}

/*
	WSASetLastError()
*/
void PASCAL FAR CWinsock::WSASetLastError(int iError)
{
	iWSALastError = iError;
}

/*
	WSAGetLastError()
*/
int PASCAL FAR CWinsock::WSAGetLastError(void)
{
	return(iWSALastError);
}

/*
	setsockopt()
*/
int CWinsock::setsockopt(SOCKET s,int level,int optname,const char FAR *optval,int optlen)
{
	if(!iWSAFlag)
	{
		WSASetLastError(WSANOTINITIALISED);
		return(SOCKET_ERROR);
	}
	else
		return(0);
}

/*
	socket()

	Creazione del socket.
*/
SOCKET PASCAL FAR CWinsock::socket(int af,int type,int protocol)
{
	if(!iWSAFlag)
	{
		WSASetLastError(WSANOTINITIALISED);
		return(INVALID_SOCKET);
	}
		
	// controlla gli specificatori del socket
	if(af!=PF_INET)
	{
		WSASetLastError(WSAEAFNOSUPPORT);
		return(INVALID_SOCKET);
	}
	if(type!=SOCK_STREAM && type!=SOCK_DGRAM)
	{
		WSASetLastError(WSAESOCKTNOSUPPORT);
		return(INVALID_SOCKET);
	}
		
	// implementa il socket su file
	if((hFile = _lcreat(SOCKET_FILE,0))==HFILE_ERROR)
	{
		WSASetLastError(WSAEBADF);
		hSocket = INVALID_SOCKET;
	}
	else
		hSocket = WSA_MAX_SOCKETS;

	return(hSocket);
}

/*
	getsockname()
*/
int CWinsock::getsockname(SOCKET s,struct sockaddr FAR *name,int FAR *namelen)
{
	return(SOCKET_ERROR);
}

/*
	connect()
*/
int PASCAL FAR CWinsock::connect(SOCKET s,const struct sockaddr FAR *name,int namelen)
{
	if(!iWSAFlag)
	{
		WSASetLastError(WSANOTINITIALISED);
		return(SOCKET_ERROR);
	}
          
	// controlla che il socket (ossia il file) sia stato aperto
	if(hFile==HFILE_ERROR)
	{
		WSASetLastError(WSAENOTSOCK);
		return(SOCKET_ERROR);
	}
    
	// errore sul socket
	if(s==INVALID_SOCKET)
	{
		WSASetLastError(WSAENOTSOCK);
		return(SOCKET_ERROR);
	}
	else if(s==WSA_MAX_SOCKETS)
	{
		// implementa solo i servizi SMTP/POP3
		if(iService!=SMTP_PORT && iService!=POP3_PORT)
		{
			WSASetLastError(WSAEPROTONOSUPPORT);
			return(SOCKET_ERROR);
		}
		else
		{
			// imposta per il comando successivo
			strcpy(pHostLastSend,"CONNECT");
			return(0);
		}
	}
	else
	{
		WSASetLastError(WSAEISCONN);
		return(SOCKET_ERROR);
	}
}

/*
	shutdown()
*/
int CWinsock::shutdown(SOCKET s,int how)
{
	if(!iWSAFlag)
	{
		WSASetLastError(WSANOTINITIALISED);
		return(SOCKET_ERROR);
	}
	else
		return(0);
}

/*
	closesocket()
*/
int FAR PASCAL CWinsock::closesocket(SOCKET s)
{
	if(!iWSAFlag)
	{
		WSASetLastError(WSANOTINITIALISED);
		return(SOCKET_ERROR);
	}
          
	// controlla che il socket (ossia il file) sia stato aperto
	if(hFile==HFILE_ERROR)
	{
		WSASetLastError(WSAENOTSOCK);
		return(SOCKET_ERROR);
	}
          
	// errore sul socket
	if(s==INVALID_SOCKET)
	{
		WSASetLastError(WSAENOTSOCK);
		return(SOCKET_ERROR);
	}
	else if(s==WSA_MAX_SOCKETS)
	{
		_lclose(hFile);
		hFile = HFILE_ERROR;
		hSocket = INVALID_SOCKET;
		return(0);
	}
	else
	{
		WSASetLastError(WSAENOTSOCK);
		return(SOCKET_ERROR);
	}
}

/*
	send()
*/
int PASCAL FAR CWinsock::send(SOCKET s,const char FAR *buf,int len,int flags)
{
	if(!iWSAFlag)
	{
		WSASetLastError(WSANOTINITIALISED);
		return(SOCKET_ERROR);
	}
          
	// controlla che il socket (ossia il file) sia stato aperto
	if(hFile==HFILE_ERROR)
	{
		WSASetLastError(WSAENOTSOCK);
		return(SOCKET_ERROR);
	}
          
	// errore sul socket
	if(s==INVALID_SOCKET)
	{
		WSASetLastError(WSAENOTSOCK);
		return(SOCKET_ERROR);
	}
	else if(s==WSA_MAX_SOCKETS)
	{
		// invia i dati all'host tracciando il socket su file
		if(send_to_host(buf,len)!=0)
		{
			WSASetLastError(WSANO_DATA);
			return(SOCKET_ERROR);
		}
		else
			return(_lwrite(hFile,buf,len));
	}
	else
	{
		WSASetLastError(WSAENOTCONN);
		return(SOCKET_ERROR);
	}
}

/*
	recv()
*/
int PASCAL FAR CWinsock::recv(SOCKET s,char FAR *buf,int len,int flags)
{
	if(!iWSAFlag)
	{
		WSASetLastError(WSANOTINITIALISED);
		return(SOCKET_ERROR);
	}
          
	// controlla che il socket (ossia il file) sia stato aperto
	if(hFile==HFILE_ERROR)
	{
		WSASetLastError(WSAENOTSOCK);
		return(SOCKET_ERROR);
	}
          
	// errore sul socket
	if(s==INVALID_SOCKET)
	{
		WSASetLastError(WSAENOTSOCK);
		return(SOCKET_ERROR);
	}
	else if(s==WSA_MAX_SOCKETS)
	{
		// riceve i dati dall'host tracciando il socket su file
		if(recv_from_host(buf,len)!=0)
		{
			WSASetLastError(WSANO_DATA);
			return(SOCKET_ERROR);
		}
		else
			return(_lwrite(hFile,(const char FAR *)buf,strlen(buf)));
	}
	else
	{
		WSASetLastError(WSAENOTCONN);
		return(SOCKET_ERROR);
	}
}

/*
	gethostbyname()
*/	
struct hostent FAR * PASCAL FAR CWinsock::gethostbyname(const char FAR *name)
{
	static char* host_alias[] = {NULL,NULL};
	static struct in_addr st_addr;
	st_addr.S_un.S_addr = LOCAL_HOST_NUM;
	static char* host_names[] = {(char FAR *)&st_addr,NULL};
	static struct hostent host_ent_struct = {0};

	if(!iWSAFlag)
	{
		WSASetLastError(WSANOTINITIALISED);
		return((struct hostent FAR *)NULL);
	}
	else
	{
		// imposta la struttura
		host_ent_struct.h_name      = pHostName;
		host_ent_struct.h_aliases   = host_alias;
		host_ent_struct.h_addrtype  = PF_INET;
		host_ent_struct.h_length    = 4;
		host_ent_struct.h_addr_list = host_names;
		
		return((struct hostent FAR *)&host_ent_struct);
	}
}

/*
	gethostbyaddr()
*/	
struct hostent FAR * CWinsock::gethostbyaddr(const char FAR *addr,int len,int type)
{
	return(gethostbyname(NULL));
}

/*
	gethostname()
*/
int PASCAL FAR CWinsock::gethostname(char FAR *name,int namelen)
{
	if(!iWSAFlag)
	{
		WSASetLastError(WSANOTINITIALISED);
		return(SOCKET_ERROR);
	}
	else
	{
		strcpyn(name,pHostName,namelen);
		return(0);
	}
}

/*
	getservbyname()
*/
struct servent FAR * CWinsock::getservbyname(const char FAR *name,const char FAR *proto)
{
	static struct servent se;
	se.s_port = -1;
	return(&se);
}

/*
	getservbyport()
*/
struct servent FAR * CWinsock::getservbyport(int port,const char FAR *proto)
{
	static struct servent se;
	se.s_name = "???";
	return(&se);
}

/*
	htons()
*/
u_short PASCAL FAR CWinsock::htons(u_short hostshort)
{
	// imposta il servizio
	iService = hostshort;

	return(hostshort);
}

/*
	inet_addr()
*/
unsigned long PASCAL FAR CWinsock::inet_addr(const char FAR *cp)
{
	if(!iWSAFlag)
	{
		WSASetLastError(WSANOTINITIALISED);
		return(INADDR_NONE);
	}
	else
		return(LOCAL_HOST_NUM);
}

/*
	inet_ntoa()
*/
char FAR * CWinsock::inet_ntoa(struct in_addr in)
{
	if(!iWSAFlag)
	{
		WSASetLastError(WSANOTINITIALISED);
		return((char FAR *)NULL);
	}
	else
		return(pHostIp);
}

/*
	send_to_host()

	Utilizzata per inviare i dati all'host.
	I dati vengono registrati nella directory relativa alla casella email.
	Che l'handle del file per la mailbox sia chiuso (HFILE_ERROR) non viene considerato un 
	errore, dato che la funzione viene utilizzata anche per inviare i comandi al server.
*/
int CWinsock::send_to_host(const char FAR *buf,int len)
{
	// controlla il servizio
	if(iService < 0)
	{
		WSASetLastError(WSAEPROTONOSUPPORT);
		return(1);
	}
	
	// imposta per il comando successivo
	if(strstr(buf,"\r\n.\r\n")!=NULL)	
		strcpy(pHostLastSend,"END");
	else
		strcpyn(pHostLastSend,buf,WSA_MAX_MTU + 1);
	
	// registra i dati nella mailbox
	// il file viene aperto alla ricezione del comando DATA e chiuso con il comando END
	if(hMailBox!=HFILE_ERROR)
		_lwrite(hMailBox,buf,len);
	
	return(0);
}

/*
	recv_from_host()

	Utilizzata per ricevere i dati dall'host.
	I dati vengono prelevati dalla directory relativa alla casella email.
*/
int CWinsock::recv_from_host(char FAR * buf,int len)
{
	int ret = 0;
	static int tot = 0;
	
	// controlla che il servizio sia tra quelli gestiti, rispondendo al comando
	switch(iService)
	{
		/*
			SMTP

			- il messaggio non puo' eccedere i BUF_SIZE caratteri (per POP3)
			- supporta un solo destinatario per volta (non supporta ne' Cc: ne' Bcc:)
			- il comando RCPT TO non controlla l'esistenza dell'email

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -