#include "common.h"

// диагностика ошибки ...
void errx( const char *msg, int err ) {
    perror( msg );
    if( err != EOK ) errno = err;
    exit( EXIT_FAILURE );
};

// ретранслятор тестовых пакетов TCP
static char data[ MAXLINE ];
void retrans( int sc ) {
   int rc = read( sc, data, MAXLINE );
   if( rc > 0 ) {
      rc = write( sc, data, strlen( data ) + 1 );
      if ( rc < 0 ) perror( "write data failed" );
   }
   else if( rc < 0 ) { perror( "read data failed" ); return; }
   else if( rc == 0 ) { cout << "client closed connection" << endl; return; };
   return;
};

// создание и подготовка прослушивающего сокета
static struct sockaddr_in addr;
int getsocket(  in_port_t p ) {
   int rc = 1, ls;
   if( -1 == ( ls = socket( AF_INET, SOCK_STREAM, 0 ) ) ) errx( "create stream socket failed" );
   if( setsockopt( ls, SOL_SOCKET, SO_REUSEADDR, &rc, sizeof( rc ) ) != 0 ) errx( "set socket option failed" );
   memset( &addr, 0, sizeof( addr ) );
   addr.sin_family = AF_INET;
   addr.sin_port = htons( p );
   addr.sin_addr.s_addr = htonl( INADDR_ANY );
   if( bind( ls, (struct sockaddr*)&addr, sizeof( sockaddr ) ) != 0 ) errx( "bind socket address failed" );
   if( listen( ls, 25 ) != 0 ) errx( "put socket in listen state failed" );
   cout << "waiting on port " << p << " ..." << endl;
   return ls;
};

// уровень отладочного вывода сервера
int debug = 0;
void setv( int argc, char *argv[] ) {
   debug = ( argc > 1 && 0 == strcmp( argv[ 1 ], "-v" ) ) ? 1 : 0;
   if( debug ) cout << "verbose mode" << endl;
}

