home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / wpbif094.zip / TCPSOCK.CPP < prev    next >
C/C++ Source or Header  |  2012-10-22  |  8KB  |  217 lines

  1. /*
  2.    Class TCPSock implementation
  3.  
  4.     Copyright VOS 1995
  5.     Author: Vitaly S. Gumirov
  6.  
  7.     email: vos@ifshop.ict.nsk.su
  8.  
  9. */
  10.  
  11. #include <tcpsock.hpp>
  12.  
  13. const char *empty_string="";
  14.  
  15. const char *ErrorMessages[]={
  16.       "Invalid arguments",
  17.       "Socket isn't initialized",
  18.       "Error greeting from the server",
  19.       "Invalid user name",
  20.       "Invalid password",
  21.       "STAT error",
  22.       0
  23. };
  24.  
  25. static const char OK_string[]="+OK";
  26. static const long OK_len=sizeof(OK_string)-1;
  27.  
  28. void TCPSock::TCPSock_Init(struct hostent *hostnm_server, unsigned short server_port) throw(TCPSockError) {
  29.      hostnm = hostnm_server;
  30.      if (hostnm == (struct hostent *) 0)   {
  31.         throw TCPSockError("Gethostbyname failed");
  32.      } else {
  33.         port=server_port;
  34.         server.sin_family      = AF_INET;
  35.         server.sin_port        = htons(port);
  36.         server.sin_addr.s_addr = *((unsigned long *)hostnm->h_addr);
  37.         if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)   {
  38.            throw TCPSockError("Socket()");
  39.         }
  40.      }
  41. }
  42.  
  43. int TCPSock::connect() throw(TCPSockError) {
  44.       int retVal=(::connect(s, (struct sockaddr *)&server, sizeof(server)));
  45.       if(retVal<0) throw TCPSockError("connect");
  46.       else return retVal;
  47. }
  48.  
  49. int TCPSock::send(char * buf, int len, int flags) throw(TCPSockError) {
  50.       int ret=(::send(s, buf, (!len)?strlen(buf):len , flags ));
  51.       if(ret<0) throw TCPSockError("send");
  52.       return ret;
  53. }
  54.  
  55. int TCPSock::recv(char *buf, int buf_size, int flags) throw(TCPSockError) {
  56.       int ret= (::recv(s, buf, buf_size, flags));
  57.       if(ret<0) throw TCPSockError("recv");
  58.       return ret;
  59. }
  60.  
  61.  
  62. const char * TCPSockError::sock_errmsg() {
  63.    char *msg;
  64.    switch(this->sock_errno()) {
  65.      case  SOCEPERM           : msg="(SOCBASEERR+1)   /*Not owner*/";break;
  66.      case  SOCESRCH           : msg="(SOCBASEERR+3)   /*No such process*/";break;
  67.      case  SOCEINTR           : msg="(SOCBASEERR+4)   /*Interrupted system call*/";break;
  68.      case  SOCENXIO           : msg="(SOCBASEERR+6)   /*No such device or address*/";break;
  69.      case  SOCEBADF           : msg="(SOCBASEERR+9)   /*Bad file number*/";break;
  70.      case  SOCEACCES          : msg="(SOCBASEERR+13)  /*Permission denied*/";break;
  71.      case  SOCEFAULT          : msg="(SOCBASEERR+14)  /*Bad address*/";break;
  72.      case  SOCEINVAL          : msg="(SOCBASEERR+22)  /*Invalid argument*/";break;
  73.      case  SOCEMFILE          : msg="(SOCBASEERR+24)  /*Too many open files*/";break;
  74.      case  SOCEPIPE           : msg="(SOCBASEERR+32)  /*Broken pipe*/";break;
  75.      case  SOCEOS2ERR         : msg="(SOCBASEERR+100) /*OS/2 Error*/";break;
  76.      case SOCEWOULDBLOCK     : msg="(SOCBASEERR+35)  /*Operation would block*/";break;
  77.      case SOCEINPROGRESS     : msg="(SOCBASEERR+36)  /*Operation now in progress*/";break;
  78.      case SOCEALREADY        : msg="(SOCBASEERR+37)  /*Operation already in progress*/";break;
  79.      case SOCENOTSOCK        : msg="(SOCBASEERR+38)  /*Socket operation on non-socket*/";break;
  80.      case SOCEDESTADDRREQ    : msg="(SOCBASEERR+39)  /*Destination address required*/";break;
  81.      case SOCEMSGSIZE        : msg="(SOCBASEERR+40)  /*Message too long*/";break;
  82.      case SOCEPROTOTYPE      : msg="(SOCBASEERR+41)  /*Protocol wrong type for socket*/";break;
  83.      case SOCENOPROTOOPT     : msg="(SOCBASEERR+42)  /*Protocol not available*/";break;
  84.      case SOCEPROTONOSUPPORT : msg="(SOCBASEERR+43)  /*Protocol not supported*/";break;
  85.      case SOCESOCKTNOSUPPORT : msg="(SOCBASEERR+44)  /*Socket type not supported*/";break;
  86.      case SOCEOPNOTSUPP      : msg="(SOCBASEERR+45)  /*Operation not supported on socket*/";break;
  87.      case SOCEPFNOSUPPORT    : msg="(SOCBASEERR+46)  /*Protocol family not supported*/";break;
  88.      case SOCEAFNOSUPPORT    : msg="(SOCBASEERR+47)  /*Address family not supported by protocol family*/";break;
  89.      case SOCEADDRINUSE      : msg="(SOCBASEERR+48)  /*Address already in use*/";break;
  90.      case SOCEADDRNOTAVAIL   : msg="(SOCBASEERR+49)  /*Can't assign requested address*/";break;
  91.      case SOCENETDOWN        : msg="(SOCBASEERR+50)  /*Network is down*/";break;
  92.      case SOCENETUNREACH     : msg="(SOCBASEERR+51)  /*Network is unreachable*/";break;
  93.      case SOCENETRESET       : msg="(SOCBASEERR+52)  /*Network dropped connection on r";break;
  94.      case  SOCECONNABORTED   : msg="(SOCBASEERR+53)  /*Software caused connection abort*/";break;
  95.      case  SOCECONNRESET     : msg="(SOCBASEERR+54)  /*Connection reset by peer*/";break;
  96.      case  SOCENOBUFS        : msg="(SOCBASEERR+55)  /*No buffer space available*/";break;
  97.      case  SOCEISCONN        : msg="(SOCBASEERR+56)  /*Socket is already connected*/";break;
  98.      case  SOCENOTCONN       : msg="(SOCBASEERR+57)  /*Socket is not connected*/";break;
  99.      case  SOCESHUTDOWN      : msg="(SOCBASEERR+58)  /*Can't send after socket shutdown*/";break;
  100.      case  SOCETOOMANYREFS   : msg="(SOCBASEERR+59)  /*Too many references: can't splice*/";break;
  101.      case  SOCETIMEDOUT      : msg="(SOCBASEERR+60)  /*Connection timed out*/";break;
  102.      case  SOCECONNREFUSED   : msg="(SOCBASEERR+61)  /*Connection refused*/";break;
  103.      case  SOCELOOP          : msg="(SOCBASEERR+62)  /*Too many levels of symbolic links*/";break;
  104.      case  SOCENAMETOOLONG   : msg="(SOCBASEERR+63)  /*File name too long*/";break;
  105.      case  SOCEHOSTDOWN      : msg="(SOCBASEERR+64)  /*Host is down*/";break;
  106.      case  SOCEHOSTUNREACH   : msg="(SOCBASEERR+65)  /*No route to host*/";break;
  107.      case  SOCENOTEMPTY      : msg="(SOCBASEERR+66)  /*Directory not empty*/";break;
  108.      default: msg="Error not defined";break;
  109.    }
  110.    static char buf[100];
  111.    if(default_msg) {
  112.       sprintf(buf,"%s : %s", msg,default_msg);
  113.       return buf;
  114.    } return msg;
  115. }
  116.  
  117.  
  118. const char * POP3SockError::sock_errmsg()
  119. {
  120.   if(errcode==POP3SockError::ERR_NULL) return TCPSockError::sock_errmsg();
  121.   long ec=errcode-POP3SockError::MIN_ERRNO;
  122.   if(ec>=0 && ec<sizeof(ErrorMessages))
  123.       return ErrorMessages[ec];
  124.   else
  125.       return TCPSockError::sock_errmsg();
  126. }
  127.  
  128.  
  129. BOOL POP3Sock::logon()  throw(TCPSockError, POP3SockError)
  130. {
  131.   if(!IsInitialized()) {
  132.       POP3SockError err("POP3Sock::logon()", POP3SockError::NOT_INITIALIZED );
  133.       throw  err;
  134.       return FALSE;
  135.   }
  136.   if(connect()<0) return FALSE;
  137.   char buf[100];
  138.   if(recv(buf, sizeof(buf))<0) return FALSE;
  139.   if(!check_ok(buf) ) {
  140.      throw POP3SockError( "POP3Sock::logon", POP3SockError::ERR_GREETING);
  141.      return FALSE;
  142.    }
  143.   if(sock_printf("USER %s\r\n",user)<0) return FALSE;
  144.   if(recv(buf, sizeof(buf))<0) return FALSE;
  145.   if(!check_ok(buf) ) {
  146.      throw POP3SockError( "POP3Sock::logon",POP3SockError::ERR_USER);
  147.      return FALSE;
  148.    }
  149.   if(sock_printf("PASS %s\r\n",passwd)<0) return FALSE;
  150.   if(recv(buf, sizeof(buf))<0) return FALSE;
  151.   if(!check_ok(buf) ) {
  152.      throw POP3SockError( "POP3Sock::logon",POP3SockError::ERR_PASSWD);
  153.      return FALSE;
  154.    }
  155.    return TRUE;
  156. }
  157.  
  158.  
  159.  
  160. long POP3Sock::number_of_msgs()
  161. {
  162.   char buf[100];
  163.   if(sock_printf("STAT\r\n")<0) return FALSE;
  164.   if(recv(buf, sizeof(buf))<0) return FALSE;
  165.   if(!check_ok(buf) ) {
  166.      return FALSE;
  167.    }
  168.    long msgNum=0;
  169.     *(strchr(buf,'\r'))=0;
  170.     sscanf(buf+OK_len,"%d",  &msgNum);
  171.    return msgNum;
  172. }
  173.  
  174. BOOL POP3Sock::quit()
  175. {
  176.   char buf[100];
  177.   if(sock_printf("QUIT\r\n")<0) return FALSE;
  178.   if(recv(buf, sizeof(buf))<0) return FALSE;
  179.   if(!check_ok(buf) ) {
  180.      return FALSE;
  181.    }
  182.    soclose();
  183.    return TRUE;
  184.  
  185. }
  186.  
  187. BOOL POP3Sock::reset()
  188. {
  189.   char buf[100];
  190.   if(sock_printf("RSET\r\n")<0) return FALSE;
  191.   if(recv(buf, sizeof(buf))<0) return FALSE;
  192.   if(!check_ok(buf) ) {
  193.      return FALSE;
  194.    }
  195.    return TRUE;
  196. }
  197.  
  198.  
  199. BOOL POP3Sock::check_ok(char * buf) 
  200. BOOL retVal= (strnicmp(buf, OK_string, OK_len)==0);
  201. return retVal;
  202. }
  203.  
  204. int TCPSock::sock_printf(char *format,...) {
  205. va_list ap;
  206. va_start(ap, format);
  207.  
  208. static   char buf[100];
  209. vsprintf(buf,format,ap);
  210. va_end(ap);
  211.  
  212. return this->send(buf);
  213. }
  214.  
  215.  
  216.