Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // THIS IS FILE : server20k.cpp
- //////////////////////////////////////////////////////////////////////////////
- // To linker:
- //
- //Maybe you need threads and mutex/semaphores?
- // -pthread
- //
- //It is more simple than search libraries on server...
- // -static
- //
- //For MySQL:
- // -lmysqlclient
- // -lz
- //
- #include "mysql/mysql.h"
- #include "mysql/mysqld_error.h"
- // libevent
- #include <event.h>
- // socket, bind, accept
- #include <sys/types.h>
- #include <sys/socket.h>
- // unix socket
- #include <sys/un.h>
- // inet_ntop
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- // errno
- #include <errno.h>
- // fcntl
- #include <fcntl.h>
- // memset
- #include <string.h>
- // getrlimit
- #include <sys/time.h>
- #include <sys/resource.h>
- #include <unistd.h>
- // exit
- #include <unistd.h>
- #include <stdlib.h>
- // signal
- #include <signal.h>
- // poll
- #include <sys/poll.h>
- #include <iostream>
- #include <iomanip>
- #include <list>
- using namespace std;
- void daemon_init();
- void discriptors_setuping();
- #define _SOCKETS_ERRORS_RUS_TEXT_ 1
- //#define _SOCKETS_ERRORS_ENG_TEXT_ 1
- void PrintDetailedSocketError( int err );
- void PrintDetailedBindError( int err );
- void PrintDetailedGSAError( int err );
- void PrintDetailedNonblockingError( int err );
- void PrintDetailedListenError( int err );
- int CreateSocket( int domain = AF_INET, int type = SOCK_STREAM, int protocol = 0 );
- void BindSocket( int sockfd, const struct sockaddr * addr, socklen_t addrlen );
- socklen_t GetSocketAddr( int sockfd, struct sockaddr * addr, socklen_t namelen );
- void SetSocketAsNoblocking( int sockfd );
- bool SetSocketAsNoblocking_once( int sockfd );
- void ListenSocket( int sockfd, int backlog );
- void MakeServer_IPv4( const char * addr_cstr_, unsigned short port_, int backlog_ );
- void MakeServer_IPv6( const char * addr_cstr_, unsigned short port_, int backlog_ );
- void MySQL_Works();
- int
- main( int argc, char ** argv)
- {
- //daemon_init();
- discriptors_setuping();
- MySQL_Works();
- //MakeServer_IPv6( "::1" /*=localhost*/, 5433 /*some port*/, 512 /*normal backlog*/ );
- //MakeServer_IPv6( "::" /*=INADDR_ANY*/, 5433 /*some port*/, 512 /*normal backlog*/ );
- //MakeServer_IPv4( "127.0.0.1" /*=localhost*/, 5433 /*some port*/, 512 /*normal backlog*/ );
- MakeServer_IPv4( "0.0.0.0" /*=INADDR_ANY*/, 5433 /*some port*/, 512 /*normal backlog*/ );
- exit(EXIT_SUCCESS);
- }
- void MySQL_Works()
- {
- char *server = "localhost";
- char *user = "sec-piler";
- char *database = "databasename";
- char *password = "psecpiler";
- MYSQL mysql;
- mysql_init( &mysql );
- //mysql_options( &mysql, MYSQL_READ_DEFAULT_GROUP, "your_prog_name" );
- cout << endl << "Try to connect." << endl;
- int attempt = 0;
- while( false == mysql_real_connect( &mysql,
- server, // IP or domain name of server.
- user,
- password,
- database,
- 3306, // Port for network connections (localhost or other server in INET).
- NULL, // Local unix socket, up performance to 8%. (unused only if param = NULL, used even if param is string like "" - Print error.)
- 0 // Flags, something about SSL, etc...
- )
- )
- {
- cerr << " (" << ++attempt << ") Erorr (#" << mysql_errno(&mysql) << "): " << mysql_error(&mysql) << '\r';
- usleep( 1000 * 1000 - 1 );
- }
- cout << endl << "Successful done." << endl;
- if( 0 != mysql_query( &mysql, "INSERT DELAYED INTO reports (username, repln) VALUES (\"\\\"The bob!\\\"\", \"\\\"23344122\\\"\")" ) )
- {
- cout << endl << "Error: Can't make query. Error(" << mysql_errno( &mysql ) << "): " << mysql_error( &mysql ) << endl;
- }
- }
- struct GrowBuff
- {
- char * buff;
- size_t buffSize;
- size_t buffUsed;
- static const size_t STD_BUFF_SIZE = 4096;
- GrowBuff()
- {
- buff = new char [STD_BUFF_SIZE];
- buffSize = STD_BUFF_SIZE;
- buffUsed = 0;
- }
- ~GrowBuff()
- {
- if( NULL != buff ) delete [] buff;
- }
- void AddSize( size_t add_size_ )
- {
- char * temp = new char [buffSize + add_size_];
- memcpy( temp, buff, buffUsed );
- delete [] buff;
- buff = temp;
- buffSize += add_size_;
- }
- void SureGotFreeSpace()
- {
- if( buffSize - buffUsed < STD_BUFF_SIZE )
- {
- AddSize( buffSize );
- }
- }
- void AddData( const char * data_, size_t data_size_ )
- {
- if( buffSize - buffUsed < data_size_ ) AddSize( buffUsed + data_size_ ); // I need mnogo i srazu! )
- memcpy( buff + buffUsed, data_, data_size_ );
- buffUsed += data_size_;
- }
- };
- struct ConnectionData
- {
- int sock;
- int number;
- GrowBuff buff_in;
- GrowBuff buff_out;
- pollfd mypoll;
- size_t writed;
- ConnectionData()
- {
- mypoll.revents = 0;
- writed = 0;
- }
- void OnWrite_WithTest()
- {
- if( mypoll.revents & (POLLOUT) )
- {
- size_t snd = 0;
- //cout << "OnWrite in connection #" << number << endl;
- if( writed < buff_out.buffUsed )
- {
- snd = send( sock,
- buff_out.buff + writed,
- buff_out.buffUsed - writed,
- 0 );
- cout << "snd = " << snd << endl;
- if( snd > 0 ) writed += snd;
- if( writed == buff_out.buffUsed )
- {
- cout << "writed = " << writed << "; buff used = " << buff_out.buffUsed << endl;
- writed = 0;
- buff_out.buffUsed = 0;
- mypoll.events = mypoll.events & (~POLLOUT);
- }
- }
- }
- }
- void OnRead()
- {
- size_t rcv = 1;
- while( -1 != rcv )
- {
- buff_in.SureGotFreeSpace();
- rcv = recv( sock,
- buff_in.buff,
- buff_in.buffSize - buff_in.buffUsed,
- 0 );
- if( 0 == rcv ) // If connection was closed.
- {
- mypoll.revents = POLLHUP;
- break;
- // We have close connection when will test it for errors <if( (...revent) & (POLLHUP|...) )>
- }
- // If we read something.
- if( -1 != rcv ) buff_in.buffUsed += rcv;
- else
- {
- if( EAGAIN != errno ) mypoll.revents = POLLHUP;
- break;
- }
- }
- }
- };
- void MakeServer_IPv4( const char * addr_cstr_, unsigned short port_, int backlog_ )
- {
- int srv_sock; // listening socket
- char saddr[sizeof(sockaddr_un)]; // buffer for address of listening socket (very big buffer))
- socklen_t saddr_len = sizeof(saddr); // size of address
- sockaddr * psaddr = (sockaddr *)&saddr; // pointer for standart functions
- sockaddr_in * psaddr4 = (sockaddr_in *)&saddr; // poinetr for hand-filling of address
- memset( &saddr, 0, saddr_len );
- psaddr4->sin_family = AF_INET;
- psaddr4->sin_port = htons( port_ ); // convertion <Host TO Network> byte order in <Short> variable
- if( 0 >= inet_pton( AF_INET, addr_cstr_, &(psaddr4->sin_addr) ) )
- {
- cerr << endl << " Error. Can't convert the character string \""<< addr_cstr_ <<"\" into a network address structure" << endl;
- exit(EXIT_FAILURE);
- }
- srv_sock = CreateSocket( AF_INET, SOCK_STREAM, 0 );
- BindSocket( srv_sock, psaddr, saddr_len );
- if( 0 == port_ )
- {
- saddr_len = GetSocketAddr( srv_sock, psaddr, saddr_len );
- port_ = ntohs( psaddr4->sin_port );
- cout << "System give me port #" << port_ << endl;
- }
- SetSocketAsNoblocking( srv_sock );
- ListenSocket( srv_sock, backlog_ );
- // Server socket done.
- // Poll.
- ConnectionData * cd;
- std::list<ConnectionData*> ConnectionsList;
- std::list<ConnectionData*>::iterator iList;
- size_t fdArrSize = 32;
- size_t fdArrUsed = 1;
- pollfd * fdArr = new pollfd[fdArrSize];
- fdArr[0].fd = srv_sock; // There always will be a server listening socket.
- fdArr[0].events = POLLIN;
- int conn = -1;
- sockaddr aconn;
- socklen_t slen = sizeof(aconn);
- const static size_t BUFF_SIZE = 1024;
- char buff[BUFF_SIZE];
- int res = 0;
- int number = 0;
- while( true )
- {
- cout << " > > > Poll go! " << endl;
- res = poll( fdArr, fdArrUsed, -1 /* timout off, wait forever event */ );
- if( -1 == res ) // Some error on poll()
- {
- // Oh man... In fact, i don't know what to do...
- // But it seems it never happens with Collector.
- continue;
- }
- // Copy poll results to lists elements, before we (maybe) accept new connections and list grown up.
- res = 1;
- for( iList = ConnectionsList.begin(); iList != ConnectionsList.end(); iList++)
- {
- (*iList)->mypoll = fdArr[res++];
- }
- //////////////////////////////////////////////////////////////////////////////
- // Accepting connections.
- if( fdArr[0].revents & (POLLIN) ) // We have new connection on listening socket.
- {
- conn = 0;
- while( -1 != conn )
- {
- conn = accept( srv_sock, &aconn, &slen );
- if( -1 != conn )
- {
- cout << "New connection socket discriptor = " << conn << endl;
- if( false == SetSocketAsNoblocking_once( conn ) )
- {
- cerr << endl << " Error. Can't set connected socket as nonblocking." << endl;
- close( conn );
- continue;
- }
- cd = new ConnectionData;
- cd->sock = conn;
- cd->mypoll.fd = conn;
- cd->mypoll.events = POLLIN; // POLLIN|POLLOUT
- cd->number = ++number;
- ConnectionsList.push_back( cd );
- }
- else cout << "Have no more connections." << endl;
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- if(fdArrSize+1 < ConnectionsList.size() )
- {
- delete [] fdArr;
- fdArrSize += fdArrSize/2;
- fdArr = new pollfd[fdArrSize];
- fdArr[0].fd = srv_sock;
- fdArr[0].events = POLLIN;
- }
- fdArrUsed = 1;
- //////////////////////////////////////////////////////////////////////////////
- // Look for data and errors on every socket.
- for( iList = ConnectionsList.begin(); iList != ConnectionsList.end(); )
- {
- cd = *(iList);
- cout << "Look at connection #" << fdArrUsed << ", disriptor " << cd->sock << "; revents = " << cd->mypoll.revents << endl;
- // Look for data...
- if( cd->mypoll.revents & (POLLIN) ) // If we have new data on this socket.
- {
- cout << "Got data on socket: " << cd->sock << "; conn#" << cd->number << ") Buff used = " << cd->buff_in.buffUsed << endl;
- cd->OnRead();
- cout << "Now buff used = " << cd->buff_in.buffUsed << endl;
- }
- // Look for errors...
- if( cd->mypoll.revents & (POLLERR|POLLHUP|POLLNVAL) ) // If we have some error on this socket.
- {
- close( cd->sock );
- delete cd;
- cd = NULL;
- iList = ConnectionsList.erase( iList );
- }
- else
- {
- iList++;
- }
- //////////////////////////////////////////////////////////////////////////////
- // Work may be here, or in other thread.
- if( NULL != cd )
- if( cd->buff_in.buffUsed > 100 )
- {
- cd->buff_out.AddSize( 1231232 );
- char test_text[] = "[Test text] ";
- size_t ttsize = strlen(test_text)+1;
- for( size_t i = 0; i < cd->buff_out.buffSize; i++)
- {
- cd->buff_out.buff[i] = test_text[i%ttsize];
- }
- cd->buff_out.buffUsed = cd->buff_out.buffSize;
- cd->mypoll.events |= POLLOUT;
- cd->buff_in.buffUsed = 0;
- }
- //////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- // Work may be here, or in other thread.
- if( NULL != cd )
- if( cd->buff_in.buffUsed > 10 )
- {
- memcpy( cd->buff_out.buff,
- "Ok, we have more than 10 bytes, and i answer you...\n",
- strlen("Ok, we have more than 10 bytes, and i answer you...\n")
- );
- cd->buff_out.buffUsed = strlen("Ok, we have more than 10 bytes, and i answer you...\n");
- cd->mypoll.events |= POLLOUT;
- //cd->buff_in.buffUsed = 0;
- }
- //////////////////////////////////////////////////////////////////////////////
- // If we can write something into socket, and have data to write
- if( NULL != cd )
- {
- cd->OnWrite_WithTest();
- fdArr[fdArrUsed++] = cd->mypoll;
- }
- }//for( iList = ConnectionsList.begin(); iList != ConnectionsList.end(); )
- //////////////////////////////////////////////////////////////////////////////
- // ^ Next loop of server work.
- // | |
- // +------+
- }//while( true )
- }
- // Simple echo server.
- void MakeServer_IPv6( const char * addr_cstr_, unsigned short port_, int backlog_ )
- {
- int sock; // listening socket
- char saddr[sizeof(sockaddr_un)]; // buffer for address of listening socket (very big buffer))
- socklen_t saddr_len = sizeof(saddr); // size of address
- sockaddr * psaddr = (sockaddr *)&saddr; // pointer for standart functions
- sockaddr_in6 * psaddr6 = (sockaddr_in6*)&saddr; // poinetr for hand-filling of address
- memset( &saddr, 0, saddr_len );
- psaddr6->sin6_family = AF_INET6;
- psaddr6->sin6_port = htons( port_ ); // convertion <Host TO Network> byte order in <Short> variable
- if( 0 >= inet_pton( AF_INET6, addr_cstr_, &(psaddr6->sin6_addr) ) )
- {
- cerr << endl << " Error. Can't convert the character string \""<< addr_cstr_ <<"\" into a network address structure" << endl;
- exit(EXIT_FAILURE);
- }
- sock = CreateSocket( AF_INET6, SOCK_STREAM, 0 );
- BindSocket( sock, psaddr, saddr_len );
- if( 0 == port_ )
- {
- saddr_len = GetSocketAddr( sock, psaddr, saddr_len );
- port_ = ntohs( psaddr6->sin6_port );
- cout << "System give me port #" << port_ << endl;
- }
- //SetSocketAsNoblocking( sock );
- ListenSocket( sock, backlog_ );
- int conn = -1;
- sockaddr_in6 aconn;
- sockaddr * paconn = (sockaddr*)&aconn;
- socklen_t slen = sizeof(aconn);
- while( true )
- {
- conn = accept( sock, paconn, &slen );
- cout << "New connection socket discriptor = " << conn << endl;
- if( -1 != conn )
- {
- if( false == SetSocketAsNoblocking_once( conn ) )
- {
- cerr << endl << " Error. Can't set connected socket as nonblocking." << endl;
- close( conn );
- continue;
- }
- char buff[4096];
- size_t rcv = 1;
- while( (-1 != rcv) && (0 != rcv) )
- {
- rcv = recv( conn, buff, 4096, 0 );
- cout << "Received " << rcv << " bytes: ";
- cout.write( buff, rcv );
- cout << endl;
- send( conn, buff, rcv, 0 );
- }
- close( conn );
- }
- }//while( true )
- }
- void daemon_init()
- {
- pid_t pid;
- if( 0 != (pid = fork()) )
- // Parent exit.
- exit(0);
- // Child now work...
- // Create new session without binded terminal
- // and become a main process in session.
- setsid();
- // Ignore signal of terminating main session process (i.e. me)
- // on next <fork() exit(0)> for new child.
- signal(SIGHUP, SIG_IGN);
- if( 0 != (pid = fork()) )
- // First child exit (main session process).
- exit(0);
- // second child now work...
- // Change work directory path for unbinding from
- // device (~directory) where from was started application.
- chdir( "/" );
- // Mask of file creation mode.
- // (Premission of created files, ...)
- umask( 0 );
- // Closing default file discriptors.
- // stdin
- close(0);
- open("/dev/null", O_RDONLY);
- // stdout
- close(1);
- open("/dev/null", O_RDWR);
- // stderr
- close(2);
- open("/dev/null", O_RDWR);
- // Done! We are full daemon now.
- }
- #define FILE_LIMIT_CUR 100000
- #define FILE_LIMIT_MAX 100000
- void discriptors_setuping()
- {
- rlimit ret; ret.rlim_max = 0; ret.rlim_cur = 0;
- rlimit ret_bu; // ret back up.
- //getrlimit( RLIMIT_LOCKS, &ret );
- getrlimit( RLIMIT_NOFILE, &ret );
- ret_bu = ret;
- if( ret.rlim_cur < FILE_LIMIT_CUR || ret.rlim_max < FILE_LIMIT_MAX )
- {
- cout << endl
- << "File(=socket) discriptors limits: current = " << setw(7) << ret.rlim_cur << "; max = " << setw(7) << ret.rlim_max << endl;
- cout << " Try to set: ";
- }
- if( ret.rlim_cur < FILE_LIMIT_CUR )
- {
- cout << "current = " << setw(7) << FILE_LIMIT_CUR << "; ";
- ret.rlim_cur = FILE_LIMIT_CUR;
- }
- else cout<< "current = ok; ";
- if( ret.rlim_max < FILE_LIMIT_MAX )
- {
- cout << "max = " << setw(7) << FILE_LIMIT_MAX << endl;
- ret.rlim_max = FILE_LIMIT_MAX;
- }
- else cout << "max = ok" << endl;
- setrlimit( RLIMIT_NOFILE, &ret );
- getrlimit( RLIMIT_NOFILE, &ret );
- cout << " * * * New limits: current = " << setw(7) << ret.rlim_cur << "; max = " << setw(7) << ret.rlim_max << endl;
- if( ret.rlim_cur == ret_bu.rlim_cur &&
- ret.rlim_max == ret_bu.rlim_cur ) cout << "WARNING: Hm. It's seems you are not root. It's better to run application as root to change this limits, if you have big workload there." << endl;
- }
- // socket
- //#include <sys/types.h>
- //#include <sys/socket.h>
- int CreateSocket( int domain, int type, int protocol)
- {
- int sock;
- int attempt = 0;
- sock = socket( domain, type, protocol );
- while( -1 == sock )
- {
- if( 0 == attempt ) cerr << " ERROR. Can't create socket." << endl;
- cerr << " (" << ++attempt << ") errno = " << errno << " = ";
- PrintDetailedSocketError( errno );
- cerr << "\r";
- sleep(1);
- sock = socket( domain, type, protocol );
- }
- cout << endl << "Socket successful created (discriptor = " << sock << ")" << endl;
- return sock;
- }
- // bind
- //#include <sys/types.h>
- //#include <sys/socket.h>
- // inet_ntop
- //#include <arpa/inet.h>
- void BindSocket( int sockfd, const struct sockaddr * addr, socklen_t addrlen )
- {
- int attempt = 0;
- char addr_cstr[INET6_ADDRSTRLEN+1];
- //addr_cstr[0] = '\0';
- if( AF_INET == addr->sa_family )
- {
- if( NULL == inet_ntop( AF_INET , (void*)&(((sockaddr_in*)addr)->sin_addr), addr_cstr, INET6_ADDRSTRLEN+1 ) )
- addr_cstr[0] = '\0';
- }
- if( AF_INET6 == addr->sa_family )
- {
- if( NULL == inet_ntop( AF_INET6, (void*)&(((sockaddr_in6*)addr)->sin6_addr), addr_cstr, INET6_ADDRSTRLEN+1 ) )
- addr_cstr[0] = '\0';
- }
- while( -1 == bind( sockfd, addr, addrlen ) )
- {
- if( 0 == attempt )
- {
- cerr << " ERROR. Can't bind socket(" << sockfd << ")";
- if( NULL != addr_cstr )
- {
- cerr << " to address [" << addr_cstr << "]:";
- if( AF_INET == addr->sa_family ) cerr << ntohs(((sockaddr_in*) addr)->sin_port );
- if( AF_INET6 == addr->sa_family ) cerr << ntohs(((sockaddr_in6*)addr)->sin6_port);
- }
- cerr << "." << endl;
- }
- cerr << " (" << ++attempt << ") errno = " << errno << " = ";
- PrintDetailedBindError( errno );
- cerr << "\r";
- sleep(1);
- }
- cout << endl << "Socket(" << sockfd << ") successful binded";
- if( NULL != addr_cstr )
- {
- cout << " to address [" << addr_cstr << "]:";
- if( AF_INET == addr->sa_family ) cout << ntohs(((sockaddr_in*) addr)->sin_port );
- if( AF_INET6 == addr->sa_family ) cout << ntohs(((sockaddr_in6*)addr)->sin6_port);
- }
- cout << "." << endl;
- }
- // #include <sys/socket.h>
- socklen_t GetSocketAddr( int sockfd, struct sockaddr * addr, socklen_t namelen )
- {
- int attempt = 0;
- //cout << endl << "namelen = " << namelen;
- socklen_t socklen = namelen;
- while( -1 == getsockname( sockfd, addr, &socklen ) )
- {
- if( 0 == attempt ) cerr << " Error. Can't get socket(" << sockfd << ") address." << endl;
- cerr << " (" << ++attempt << ") errno = " << errno << " = ";
- PrintDetailedGSAError( errno );
- cerr << "\r";
- sleep(1);
- }
- //cout << "new namelen = " << socklen;
- return socklen;
- }
- //#include <fcntl.h>
- bool SetSocketAsNoblocking_once( int sockfd )
- {
- return (-1 != fcntl( sockfd, F_SETFL, O_NONBLOCK ) );
- }
- //#include <fcntl.h>
- void SetSocketAsNoblocking( int sockfd )
- {
- int attempt = 0;
- while( -1 == fcntl( sockfd, F_SETFL, O_NONBLOCK ) )
- {
- if( 0 == attempt ) cerr << " Error. Can't set socket(" << sockfd <<") as nonblocking." << endl;
- cerr << " (" << ++attempt << ") errno = " << errno << " = ";
- PrintDetailedNonblockingError( errno );
- cerr << "\r" << endl;
- sleep(1);
- }
- cout << endl << "Socket(" << sockfd << ") set as nonblocking successful" << endl;
- }
- void ListenSocket( int sockfd, int backlog )
- {
- int attempt = 0;
- while( -1 == listen( sockfd, backlog ) )
- {
- if( 0 == attempt ) cerr << " ERROR. Can't set socket as listening." << endl;
- cerr << " (" << ++attempt << ") errno = " << errno << " = ";
- PrintDetailedListenError( errno );
- cerr << "\r";
- sleep(1);
- }
- cout << endl << "Socket(" << sockfd << ") set as listening successful." << endl;
- }
- void PrintDetailedSocketError( int err )
- {
- #ifdef _SOCKETS_ERRORS_RUS_TEXT_
- switch( err )
- {
- case EPROTONOSUPPORT : cerr << "EPROTONOSUPPORT = Тип протокола или указанный протокол не поддерживаются в этом домене."; break;
- case EAFNOSUPPORT : cerr << "EAFNOSUPPORT = Реализация не поддерживает указанное семейства адресов. "; break;
- case ENFILE : cerr << "ENFILE = Недостаточно памяти, чтобы создать новый сокет. "; break;
- case EMFILE : cerr << "EMFILE = Переполнение таблицы с файлами процесса."; break;
- case EACCES : cerr << "EACCES = Нет доступа к созданию сокета указанного типа и/или протокола."; break;
- case ENOBUFS : cerr << "ENOBUFS = ENOMEM = Недостаточно памяти для создания сокета."; break;
- case EINVAL : cerr << "EINVAL = Неизвестный протокол или недоступный набор протоколов."; break;
- default : cerr << "<UNKNOWN ERROR> = Неизвестная ошибка создания сокета."; break;
- }
- #else
- #ifdef _SOCKETS_ERRORS_ENG_TEXT_
- switch( err )
- {
- case EACCES : cerr << "EACCES = Permission to create a socket of the specified type and/or protocol is denied."; break;
- case EAFNOSUPPORT : cerr << "EAFNOSUPPORT = The implementation does not support the specified address family."; break;
- case EINVAL : cerr << "EINVAL = Unknown protocol, or protocol family not available. (OR) Invalid flags in type."; break;
- case EMFILE : cerr << "EMFILE = Process file table overflow."; break;
- case ENFILE : cerr << "ENFILE = The system limit on the total number of open files has been reached."; break;
- case ENOBUFS : cerr << "ENOBUFS = ENOMEM = Insufficient memory is available. The socket cannot be created until sufficient resources are freed."; break;
- case EPROTONOSUPPORT : cerr << "EPROTONOSUPPORT = The protocol type or the specified protocol is not supported within this domain."; break;
- default : cerr << "<UNKNOWN ERROR> = Unknown error while socket creating."; break;
- }
- #endif // #ifdef _SOCKETS_ERRORS_ENG_TEXT_
- #endif // #ifdef _SOCKETS_ERRORS_RUS_TEXT_
- }
- void PrintDetailedBindError( int err )
- {
- #ifdef _SOCKETS_ERRORS_RUS_TEXT_
- switch( err )
- {
- case EBADF : cerr << "EBADF = sockfd не является правильным дескриптором."; break;
- case EINVAL : cerr << "EINVAL = Сокет уже привязан к какому-то адресу. Эта ошибка в будущем может не выдаваться, смотри linux/unix/sock.c, где описаны детали."; break;
- case EACCES : cerr << "EACCES = Адрес защищен, или пользователь не является суперпользователем."; break;
- case ENOTSOCK : cerr << "ENOTSOCK = Аргумент системного вызова является дескриптором файла, а не сокета."; break;
- case EADDRINUSE : cerr << "EADDRINUSE = Адрес уже используется."; break;
- default : cerr << "<UNKNOWN ERROR> = Неизвестная ошибка привязки сокета к адресу."; break;
- /*
- Нижеследующие ошибки специфичны для сокетов домена UNIX (AF_UNIX):
- EINVAL
- Параметр addrlen неверен, или сокет не был найден в семействе адресов AF_UNIX.
- EROFS
- Попытка создания inode сокета на файловой системе "только для чтения".
- EFAULT
- my_addr указывает за пределы доступного адресного пространства.
- ENAMETOOLONG
- my_addr слишком длинно.
- ENOENT
- Файл не существует.
- ENOMEM
- Ядру не хватило памяти.
- ENOTDIR
- Компонент пути, использованный как каталог, в действительности таковым не является.
- EACCES
- Не разрешен поиск в одном из компонентов пути.
- ELOOP
- my_addr является зацикленной символической ссылкой, то есть при подстановке возникает ссылка на неё саму.
- */
- }
- #else
- #ifdef _SOCKETS_ERRORS_ENG_TEXT_
- switch( err )
- {
- case EACCES : cerr << "EACCES = The address is protected, and the user is not the superuser."; break;
- case EADDRINUSE : cerr << "EADDRINUSE = The given address is already in use."; break;
- case EBADF : cerr << "EBADF = sockfd is not a valid descriptor."; break;
- case EINVAL : cerr << "EINVAL = The socket is already bound to an address."; break;
- case ENOTSOCK : cerr << "ENOTSOCK = sockfd is a descriptor for a file, not a socket."; break;
- default : cerr << "<UNKNOWN ERROR> = Unknown error while socket binding to address."; break;
- /*
- The following errors are specific to Unix domain (AF_UNIX) sockets:
- EACCES
- Search permission is denied on a component of the path prefix. (See also path_resolution(7).)
- EADDRNOTAVAIL
- A nonexistent interface was requested or the requested address was not local.
- EFAULT
- addr points outside the user's accessible address space.
- EINVAL
- The addrlen is wrong, or the socket was not in the AF_UNIX family.
- ELOOP
- Too many symbolic links were encountered in resolving addr.
- ENAMETOOLONG
- addr is too long.
- ENOENT
- The file does not exist.
- ENOMEM
- Insufficient kernel memory was available.
- ENOTDIR
- A component of the path prefix is not a directory.
- EROFS
- The socket inode would reside on a read-only file system.
- */
- }
- #endif // #ifdef _SOCKETS_ERRORS_ENG_TEXT_
- #endif // #ifdef _SOCKETS_ERRORS_RUS_TEXT_
- }
- void PrintDetailedGSAError( int err )
- {
- #ifdef _SOCKETS_ERRORS_RUS_TEXT_
- switch( err )
- {
- case EBADF : cerr << "EBADF = Неверный файловый дескриптор s."; break;
- case ENOTSOCK : cerr << "ENOTSOCK = Аргумент -- это файл, а не сокет."; break;
- case EINVAL : cerr << "EINVAL = Неверное значение namelen (возможно отрицательное)."; break;
- case ENOBUFS : cerr << "ENOBUFS = В системе недостаточно ресурсов для выполнения операции."; break;
- case EFAULT : cerr << "EFAULT = name указывает за пределы доступного адресного пространства."; break;
- default : cerr << "<UNKNOWN ERROR> = Неизвестная ошибка взятия адреса сокета."; break;
- }
- #else
- #ifdef _SOCKETS_ERRORS_ENG_TEXT_
- switch( err )
- {
- case EBADF : cerr << "EBADF = The argument sockfd is not a valid descriptor."; break;
- case EFAULT : cerr << "EFAULT = The name argument points to memory not in a valid part of the process address space."; break;
- case EINVAL : cerr << "EINVAL = namelen is invalid (e.g., is negative)."; break;
- case ENOBUFS : cerr << "ENOBUFS = Insufficient resources were available in the system to perform the operation."; break;
- case ENOTSOCK : cerr << "ENOTSOCK = The argument s is a file, not a socket."; break;
- default : cerr << "<UNKNOWN ERROR> = Unknown error while getting socket address."; break;
- }
- #endif // #ifdef _SOCKETS_ERRORS_ENG_TEXT_
- #endif // #ifdef _SOCKETS_ERRORS_RUS_TEXT_
- }
- void PrintDetailedNonblockingError( int err )
- {
- #ifdef _SOCKETS_ERRORS_RUS_TEXT_
- switch( err )
- {
- case EACCES : cout << "EACCES = "; // not break
- case EAGAIN : cout << "EAGAIN = Операция запрещена блокировками, которые удерживаются другими процессами. (ИЛИ) Операция запрещена, потому что для этого файла другой процесс использует механизм отображения в память (memory-map). " << endl; break;
- case EBADF : cout << "EBADF = fd не является открытым файловым дескриптором или команда была F_SETLK или F_SETLKW и режим открытия файлового дескриптора не совпадает с типом запрошенной блокировки." << endl; break;
- case EDEADLK : cout << "EDEADLK = Было обнаружено, что указанная команда F_SETLKW должна вызывать мёртвую блокировку (deadlock)." << endl; break;
- case EFAULT : cout << "EFAULT = lock находится за пределами доступного адресного пространства." << endl; break;
- case EINTR : cout << "EINTR = Выполнение команды F_SETLKW, было прервана сигналом. Или выполнение команд F_GETLK и F_SETLK, было прервано сигналом перед тем как была блокировка была проверка или установлена. Большинство таких ошибок случается при блокировке удалённого файла (например, блокировка через NFS), но иногда такое может случаться и на локальных файлах." << endl; break;
- case EINVAL : cout << "EINVAL = Для F_DUPFD,значение arg отрицательное или же больше, чем максимально возможное значение. Для F_SETSIG,значение arg не содержит допустимый номер сигнала." << endl; break;
- case EMFILE : cout << "EMFILE = Для F_DUPFD, процесс достиг максимального количества открытых файловых дескрипторов." << endl; break;
- case ENOLCK : cout << "ENOLCK = Открыто слишком много блокировок сегментов, таблица блокировок заполнена или ошибка протокола удалённой блокировки (например, при блокировке через NFS)." << endl; break;
- case EPERM : cout << "EPERM = Попытка сбросить флаг O_APPEND на файле, который открыт с атрибутом только для добавления." << endl; break;
- default : cout << "<UNKNOWN ERROR> = Неизвестная ошибка при установлении сокета неблокирующим." << endl;
- }
- #else
- #ifdef _SOCKETS_ERRORS_ENG_TEXT_
- switch( err )
- {
- case EACCES : cout << "EACCES = "; // not break
- case EAGAIN : cout << "EAGAIN = Operation is prohibited by locks held by other processes. (OR) The operation is prohibited because the file has been memory-mapped by another process." << endl; break;
- case EBADF : cout << "EBADF = fd is not an open file descriptor, or the command was F_SETLK or F_SETLKW and the file descriptor open mode doesn't match with the type of lock requested." << endl; break;
- case EDEADLK : cout << "EDEADLK = It was detected that the specified F_SETLKW command would cause a deadlock." << endl; break;
- case EFAULT : cout << "EFAULT = lock is outside your accessible address space." << endl; break;
- case EINTR : cout << "EINTR = For F_SETLKW, the command was interrupted by a signal; see signal(7). For F_GETLK and F_SETLK, the command was interrupted by a signal before the lock was checked or acquired. Most likely when locking a remote file (e.g., locking over NFS), but can sometimes happen locally." << endl; break;
- case EINVAL : cout << "EINVAL = For F_DUPFD, arg is negative or is greater than the maximum allowable value. For F_SETSIG, arg is not an allowable signal number." << endl; break;
- case EMFILE : cout << "EMFILE = For F_DUPFD, the process already has the maximum number of file descriptors open." << endl; break;
- case ENOLCK : cout << "ENOLCK = Too many segment locks open, lock table is full, or a remote locking protocol failed (e.g., locking over NFS)." << endl; break;
- case EPERM : cout << "EPERM = Attempted to clear the O_APPEND flag on a file that has the append-only attribute set." << endl; break;
- default : cerr << "<UNKNOWN ERROR> = Unknown error while setup socket as nonblocking."; break;
- }
- #endif // #ifdef _SOCKETS_ERRORS_ENG_TEXT_
- #endif // #ifdef _SOCKETS_ERRORS_RUS_TEXT_
- }
- void PrintDetailedListenError( int err )
- {
- #ifdef _SOCKETS_ERRORS_RUS_TEXT_
- switch( err )
- {
- case EADDRINUSE : cerr << "EADDRINUSE = Другой сокет уже слушает на этом же порту."; break;
- case EBADF : cerr << "EBADF = Аргумент sockfd не является правильным дескриптором."; break;
- case ENOTSOCK : cerr << "ENOTSOCK = Аргумент sockfd не является сокетом."; break;
- case EOPNOTSUPP : cerr << "EOPNOTSUPP = Тип сокета не поддерживает операцию listen."; break;
- default : cerr << "<UNKNOWN ERROR> = Неизвестная ошибка при установлении сокета слушающим."; break;
- }
- #else
- #ifdef _SOCKETS_ERRORS_ENG_TEXT_
- switch( err )
- {
- case EADDRINUSE : cerr << "EADDRINUSE = Another socket is already listening on the same port."; break;
- case EBADF : cerr << "EBADF = The argument sockfd is not a valid descriptor."; break;
- case ENOTSOCK : cerr << "ENOTSOCK = The argument sockfd is not a socket."; break;
- case EOPNOTSUPP : cerr << "EOPNOTSUPP = The socket is not of a type that supports the listen() operation."; break;
- default : cerr << "<UNKNOWN ERROR> = Unknown error while setting socket as listening."; break;
- }
- #endif // #ifdef _SOCKETS_ERRORS_ENG_TEXT_
- #endif // #ifdef _SOCKETS_ERRORS_RUS_TEXT_
- }
- // F O R M Y S Q L
- // Useful for inserting binary data into blob field in table.
- /*
- unsigned long temp = 0;
- for( unsigned long i = 0; i < dataSize; i++ )
- {
- if( '\0' == data[i] || '\\' == data[i] || '\'' == data[i] || '\"' == data[i] )
- temp++;
- }
- char * slashed_data = new char [dataSize + temp];
- dataToBlobQuery( data, dataSize, slashed_data, dataSize + temp );
- */
- // Экранизация символов.
- unsigned int dataToBlobQuery(const char * data, unsigned int data_size, char * res, unsigned int res_size)
- {
- unsigned int data_new_len = 0;
- while( data_size > 0 && res_size > 0 )
- {
- switch( *data )
- {
- // 0x00 -> \0
- case '\0' :
- if( res_size < 2 ) break;
- *res++ = '\\'; res_size--; // '\'
- *res++ = '0' ; res_size--; // '0'
- data_new_len++;
- break;
- // \ -> \\ ( without this text -- next `case' would be in this commentary ... my sweet, sweet bug)) )
- case '\\' :
- if( res_size < 2 ) break;
- *res++ = '\\'; res_size--; // '\'
- *res++ = '\\'; res_size--; // '\'
- data_new_len++;
- break;
- // ' -> \'
- case '\'' :
- if( res_size < 2 ) break;
- *res++ = '\\'; res_size--; // '\'
- *res++ = '\''; res_size--; // "'"
- data_new_len++;
- break;
- // " -> \"
- case '\"' :
- if( res_size < 2 ) break;
- *res++ = '\\'; res_size--; // '\'
- *res++ = '\"'; res_size--; // '"'
- data_new_len++;
- break;
- // alpha -> alpha
- default:
- *res++ = *data; res_size--;
- }
- *data ++;
- data_size --;
- data_new_len++;
- }
- return data_new_len;
- }
- struct PilerData
- {
- MYSQL *pMySql;
- };
- void connectToMySql(PilerData * pPD)
- {
- return;
- }
- int getHostBanList(PilerData * pPD)
- {
- const unsigned int query_max_size = 512;
- char query[query_max_size];
- unsigned int q_size = strlen("SELECT * FROM `");
- memcpy( query, "SELECT * FROM `" , q_size );
- memcpy( query + q_size, "hostban", strlen("hostban") );
- q_size += strlen("hostban");
- query[q_size++] = '`';
- int attempt = 1;
- while( 0 != mysql_real_query(pPD->pMySql, query, q_size) )
- {
- cout << " ERROR. > writeToMySql function > mysql_query > getTablesFields ->- Can't process query: " << endl;
- cout << query << endl;
- cout << "MySQL (#" << mysql_errno(pPD->pMySql) << "): " << mysql_error( pPD->pMySql ) << endl;
- int i_mysql_errno = mysql_errno( pPD->pMySql );
- cout << "MySQL error code = " << i_mysql_errno << endl;
- // ER_NO_SUCH_TABLE 1146
- if( ER_NO_SUCH_TABLE == i_mysql_errno ) return 1;
- if( 2006 == i_mysql_errno ) // Server lost.
- {
- connectToMySql( pPD ); // Reconnect to MySQL server.
- }
- else if( attempt++ > 5 ) return 2;
- }
- MYSQL_RES * pMySqlRes = mysql_store_result( pPD->pMySql );
- if( NULL != pMySqlRes )
- {
- // // // // // // // // // // // // // // // //
- // Обрабатываем результаты запроса.
- unsigned int fields = mysql_num_fields( pMySqlRes );
- if( fields < 2 )
- {
- mysql_free_result( pMySqlRes );
- return 1;
- }
- my_ulonglong rows_count = mysql_num_rows( pMySqlRes );
- MYSQL_ROW row;
- // // // // // // //
- int options = 0;
- const char *error;
- int erroffset;
- // // // // // // //
- //cout << " : rows_count = " << rows_count << endl;
- for( my_ulonglong i = 0; i < rows_count; i++ )
- {
- row = mysql_fetch_row(pMySqlRes);
- if( NULL != row )
- {
- cout << (char *) row[1] << endl;
- }
- }
- mysql_free_result( pMySqlRes );
- } // if( NULL != pMySqlRes )
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement