Advertisement
Aslai

Untitled

Dec 5th, 2012
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.72 KB | None | 0 0
  1. #include "IRC.h"
  2.  
  3. static void mysleep( unsigned long long d ){
  4. #ifdef __WIN32
  5.     Sleep( d );
  6. #else
  7.     usleep( d * 1000 );
  8. #endif
  9. }
  10.  
  11. static std::string str_lwr( std::string in ){
  12.     std::string out = "";
  13.     for( unsigned int i = 0; i < in.length(); ++i ){
  14.         out += tolower( in[i] );
  15.     }
  16.     return out;
  17. }
  18.  
  19. void IRC::senda( SOCKET sock, const char* str )
  20. {
  21.     #ifdef DEBUG
  22.     printf(">>%s\n", str);
  23.     #endif
  24.     send( sock, str, strlen( str ), 0 );
  25. }
  26.  
  27. void IRC::sendb( SOCKET sock, const char* str1, const char* str2 )
  28. {
  29.     char sendbuf[1000];
  30.     sprintf( sendbuf, "%s%s", str1, str2 );
  31.  
  32.     senda( sock, sendbuf );
  33. }
  34.  
  35. unsigned long IRC::resolveAddr( const char* addr, int ind)
  36. {
  37.     hostent* host = gethostbyname( addr );
  38.     if( host == 0 )
  39.     {
  40.         printf( "Failed to lookup %s.", addr );
  41.         return 0;
  42.     }
  43.     if( ind > host->h_length ) return -1;
  44.     unsigned long     myhost = *((unsigned long*) host->h_addr);//_list[host->h_length - ind];
  45.     //printf( "%Host: %i.%i.%i.%i\n", myhost & 0xFF, ( myhost >> 8 ) & 0xFF, ( myhost >> 16 ) & 0xFF, ( myhost >> 24 ) & 0xFF );
  46.     return myhost;
  47. }
  48.  
  49. char* IRC::getMessage( SOCKET recvOn, char* buffer, int len )
  50. {
  51.     char tmp = 0;
  52.     int pos = 0;
  53.     int val = 1;
  54.     //printf( "aloal" );
  55.     val = recv( recvOn, &tmp, 1, 0 );
  56.  
  57.     if( val == 0 )
  58.     {
  59.         buffer[0] = 0;
  60.         return (char*)0;
  61.     }
  62.     if( val < 0 )
  63.     {
  64.         buffer[0] = 0;
  65.         return 0;
  66.     }
  67.  
  68.     //printf( "aloal" );
  69.     while( tmp != '\n' && val > 0 )
  70.     {
  71.         if( pos >= len ){
  72.             buffer[pos] = 0;
  73.             if( buffer[pos-1] == '\r' )
  74.                 buffer[pos-1] = 0;
  75.             return buffer;
  76.         }
  77.         //printf( "aloal" );
  78.         //if( tmp > 28 )
  79.         buffer[pos++] = tmp;
  80.         val = recv( recvOn, &tmp, 1, 0 );
  81.         if( val <= 0 )
  82.         {
  83.             buffer[pos] = 0;
  84.             if( buffer[pos-1] == '\r' )
  85.                 buffer[pos-1] = 0;
  86.             return buffer;
  87.         }
  88.     }
  89.     if( buffer[pos-1] == '\r' )
  90.         buffer[pos-1] = 0;
  91.     buffer[pos++] = 0;
  92.     return buffer;
  93. }
  94.  
  95. SOCKET IRC::connectTCP( unsigned long ip, short int port )
  96. {
  97.     SOCKET ret;
  98.     ret = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  99.     if( ret < 0 ) return 0;
  100.     sockaddr_in clientService;
  101.     clientService.sin_family = AF_INET;
  102.     clientService.sin_addr.s_addr = ip;
  103.     clientService.sin_port = htons( port );
  104.     int result = connect( ret, (sockaddr*) &clientService, sizeof(clientService));
  105.     if( result < 0 ) return 0;
  106.     return ret;
  107. }
  108.  
  109.  
  110. void IRC::sendMsg(  SOCKET tosend, const char* format, ... )
  111. {
  112.  
  113.     char sendBuf[1000];
  114.     va_list strt;
  115.     va_start( strt, format );
  116.     vsprintf( sendBuf, format, strt );
  117.     va_end( strt );
  118.     sendb( tosend, sendBuf, (const char*) "\r\n" );
  119. }
  120.  
  121. void IRC::sendMsg( bool partial, const char* format, ... )
  122. {
  123.     char sendBuf[1000];
  124.     va_list strt;
  125.     va_start( strt, format );
  126.     vsprintf( sendBuf, format, strt );
  127.     va_end( strt );
  128.     senda( sock, sendBuf );
  129.     if( !partial )
  130.         senda( sock, "\r\n" );
  131. }
  132.  
  133.  
  134. void* IRC::thread::malloc( size_t len ){
  135.     void* t = ::malloc( len );
  136.     mallocs.push_back( t );
  137.     return t;
  138. }
  139. void IRC::thread::free( void* val ){
  140.     if( val == 0 ) return;
  141.     for( unsigned int i = 0; i < mallocs.size(); ++i )
  142.         if( mallocs[i] == val ){
  143.             ::free( mallocs[i] );
  144.             mallocs[i] = 0;
  145.             break;
  146.         }
  147. }
  148.  
  149. void IRC::thread::freeall(){
  150.     for( unsigned int i = 0; i < mallocs.size(); ++i )
  151.         if( mallocs[i] != 0 )
  152.             ::free( mallocs[i] );
  153.     mallocs.resize(0,0);
  154. }
  155. void IRC::callback_privmsg(SOCKET sock, std::string msg, IRC::user sender, void* d){
  156.     std::string v = msg.substr( 0, msg.find_first_of( ' ' ) );
  157.     IRC::destination dst;
  158.     dst.v = v;
  159.     dst.type = 0;
  160.     if( v[0] == '#' )
  161.         dst.type = 1;
  162.     else
  163.         dst.v = sender.nick;
  164.     IRC* irc = (IRC*) d;
  165.     std::string tmp = msg.substr(msg.find_first_of( ':' ) + 1);
  166.     std::string tmp2 = str_lwr( tmp );
  167.  
  168.     for( unsigned int i = 0; i < irc->ccb.size(); ++i ){
  169.         if( tmp2.find( irc->ccb[i].v ) == 0 ){
  170.             irc->ccb[i].call( sock, tmp, sender, dst, irc->ccb[i].d );
  171.         }
  172.     }
  173. }
  174. void IRC::callback_ping(SOCKET sock, std::string msg, IRC::user sender, void*){
  175.     msg[1] = 'O';
  176.     sendMsg( sock, "%s", msg.c_str() );
  177. }
  178. void IRC::pushcallback( std::string type, void* d, void (*call)( SOCKET sock, std::string msg, IRC::user sender, void* ) ){
  179.     callback a;
  180.     a.v = str_lwr(type);
  181.     a.d = d;
  182.     a.call = call;
  183.     cb.push_back( a );
  184. }
  185. void IRC::pushchatcallback( std::string type, void* d, void (*call)( SOCKET sock, std::string msg, IRC::user sender, IRC::destination dst, void* ) ){
  186.     chatcallback a;
  187.     a.v = str_lwr(type);
  188.     a.d = d;
  189.     a.call = call;
  190.     ccb.push_back( a );
  191. }
  192. void IRC::docallback( std::string raw ){
  193.     user a;
  194.     a.n = true;
  195.     a.nick = a.user = a.host = "";
  196.     int t = 0;
  197.     int t2 = 0;
  198.     if( raw[0] == ':' ){
  199.         t = 1;
  200.         t2 = raw.find_first_of( '!', t );
  201.         a.nick = raw.substr( 1, t2 - t );
  202.         t = t2 + 1;
  203.         t2 = raw.find_first_of( '@', t );
  204.         a.user = raw.substr( 1, t2 - t );
  205.         t = t2 + 1;
  206.         t2 = raw.find_first_of( ' ', t );
  207.         a.host = raw.substr( 1, t2 - t );
  208.         a.n = false;
  209.         t = t2 + 1;
  210.     }
  211.     t2 = raw.find_first_of( ' ', t );
  212.     std::string type = str_lwr(raw.substr( t, t2 - t ));
  213.  
  214.     for( unsigned int i = 0; i < cb.size(); ++i ){
  215.         if( type == cb[i].v)
  216.             cb[i].call( sock, raw.substr(t2+1), a, cb[i].d );
  217.     }
  218. }
  219. void IRC::main_loop(){
  220.     char buf[5001];
  221.     while(  time(0) < connecttime + 3  ){
  222.         mysleep( 100 );
  223.     }
  224.     docallback( "CONNECT" );
  225.     while( true ){
  226.         if( getMessage( sock, buf, 5000 ) == 0 ) break;
  227.         #ifdef DEBUG
  228.         printf("<<%s\n", buf);
  229.         #endif
  230.         std::string a = buf;
  231.         docallback( a );
  232.     }
  233. }
  234. IRC::IRC( std::string nick, std::string user, std::string realname, std::string server, int port ){
  235.     #ifdef __WIN32
  236.         WSADATA globalWSAData;
  237.         WSAStartup( MAKEWORD(2, 2), &globalWSAData );
  238.     #endif
  239.     valid = false;
  240.     sock = connectTCP( resolveAddr( server.c_str() ), port );
  241.     if( sock <= 0 ) { return; }
  242.     pushcallback( "PRIVMSG", (void*) this, callback_privmsg );
  243.     pushcallback( "PING", (void*) this, callback_ping );
  244.  
  245.     valid = true;
  246.     sendMsg( sock, "NICK %s", nick.c_str() );
  247.     sendMsg( sock, "USER %s %s %s :%s", user.c_str(), user.c_str(), user.c_str(), realname.c_str()  );
  248.     connecttime = time( 0 );
  249. }
  250. int IRC::isvalid(){
  251.     return valid;
  252. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement