/** @file Parser: SMTP sender impl. Copyright (c) 2001-2026 Art. Lebedev Studio (https://www.artlebedev.com) Authors: Konstantin Morshnev , Alexandr Petrosian */ #include "smtp.h" volatile const char * IDENT_COMMS_C="$Id: comms.C,v 1.16 2026/04/25 13:38:46 moko Exp $"; // --------------------------------------------------------------------------- int SMTP:: IsAddressARawIpaddress(const char* string) { while( *string ) { if( !isdigit((unsigned char)*string) ) { return 0; } string++; } return 1; } //--------------------------------------------------------------------------- ///@bug getservbyname is not reenterant int SMTP:: ResolveService(const char* service, u_short *our_port) { struct servent *serventry = NULL; if( IsAddressARawIpaddress(service) ) { char * tail; *our_port = (u_short)strtol(service, &tail, 10); if( tail == service ) { return WSAEPROTONOSUPPORT; } else { *our_port = htons(*our_port); } } else { serventry = getservbyname(service, "tcp"); if( serventry ) *our_port = serventry->s_port; else { #ifdef _MSC_VER int retval = WSAGetLastError(); if( (retval == WSANO_DATA) || (retval == WSANO_RECOVERY) ) { return WSAEPROTONOSUPPORT; } else { return (retval - 5000); } #else return WSAEPROTONOSUPPORT; #endif } } return 0; } //--------------------------------------------------------------------------- /// @bug gethostbyname is not reenterant int SMTP:: ResolveHostname(const char* hostname, struct sockaddr_in *sa_in) { struct hostent *hostentry = NULL; unsigned long ip_address; if( (ip_address = inet_addr(hostname)) != INADDR_NONE ) { sa_in->sin_addr.s_addr = ip_address; } else { if( (hostentry = gethostbyname(hostname)) == NULL ) { return WSAHOST_NOT_FOUND; } sa_in->sin_addr.s_addr = *(long *)hostentry->h_addr; } return 0; } //--------------------------------------------------------------------------- int SMTP:: GetAndSetTheSocket(SOCKET *the_socket) { if( INVALID_SOCKET == (*the_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP/*был 0, вложенно не работал*/)) ) { return WSAESOCKTNOSUPPORT; } // To enable SO_DONTLINGER (that is, disable SO_LINGER) // l_onoff should be set to zero and setsockopt should be called linger dont_linger={0,0}; setsockopt(*the_socket, SOL_SOCKET, SO_LINGER, (const char *)&dont_linger, sizeof(dont_linger)); return 0; } //--------------------------------------------------------------------------- int SMTP:: GetConnection(SOCKET the_socket, struct sockaddr_in *sa_in) { if( connect(the_socket, (struct sockaddr *)sa_in, sizeof(struct sockaddr_in))<0 ) { int retval = 0; switch( (retval = WSAGetLastError()) ) { case WSAEWOULDBLOCK: break; case WSAECONNREFUSED: return WSAECONNREFUSED; default: //wsprintf(message, "unexpected error %d from winsock\n", retval); //ShowError(message); return WSAHOST_NOT_FOUND; } } return 0; } //--------------------------------------------------------------------------- void SMTP:: MiscSocketSetup(SOCKET soc, fd_set *fds, struct timeval *timeout) { #ifdef _MSC_VER unsigned long ioctl_blocking = 1; ioctlsocket(soc, FIONBIO, &ioctl_blocking); #endif FD_ZERO(fds); FD_SET(soc, fds); timeout->tv_sec = 30; timeout->tv_usec = 0; } //---------------------------------------------------------------------------