#include #include #include #include #include #include #include #include #include #include #include #include "task_queue.h" #include "pthread_pool.h" #define PORT 2488 #define HOST "127.0.0.1" #define BUFSIZE 4098 #define MAX_CONN 200 #define mass( _eq, _msg ) \ if( _eq ) { \ perror( _msg ); \ exit(-1); \ } static void* saved; int send_direntry( int sock, char* name ) { DIR *dir; struct dirent *entry; char buf[4096] = { 0 }; int off = 0, i; if( (dir = opendir( name )) == NULL ) { sprintf( buf, "server: Cannot open a directory: %s.\r\n", name ); write( sock, buf, strlen( buf ) ); return -1; } for( i = 0; ( entry = readdir( dir )); i++ ) { /* if( !strcmp( entry->d_name, ".") || !strcmp( entry->d_name, "..")) continue; */ sprintf( buf+off, "%s\r\n", entry->d_name ); off = strlen( entry->d_name ); if( i = 7 ) { write( sock, buf, strlen( buf )); i = off = 0; } } closedir( dir ); return 0; } void* socket_handler( void* args ) { char buf[BUFSIZE], name[256]; int input_size, sock = (int)args, i, word = 0; #ifdef debug fprintf( stderr, "Thread: %d. Socket: %d.\n", pthread_self(), sock); #endif while(( input_size = read( sock, buf, BUFSIZE)) > 0 ) { word = 0; for( i = 0; i < input_size; i++ ) { if( buf[i] == 0 || i == input_size-1) { if( buf[i-1] == 13) { buf[i-1] = 0; } strcpy( name, buf+word ); #ifdef debug /* puts( name ); */ #endif send_direntry( sock, name ); write( sock, "\0", 1); word = i+1; } } } fprintf( stderr, "Thread %d ended. Socket %d.\n", pthread_self(), sock ); close(sock); return NULL; } void handle_sigint( int sig ) { pthread_pool_destroy( (pthread_pool_t*)saved ); exit(0); } int main( int argc, char* argv[] ) { int s_sock, c_sock, val = 1; struct sockaddr_in saddr; socklen_t slen = sizeof( struct sockaddr_in); pthread_pool_t *pool; pthread_pool_attr_t *attr; task_t *task; struct sigaction act; sigset_t mask; sigemptyset( &mask ); sigaddset( &mask, SIGPIPE ); memset( &act, 0, sizeof( struct sigaction)); act.sa_handler = SIG_IGN; act.sa_mask = mask; sigaction( SIGPIPE, &act, 0); signal( SIGINT, handle_sigint ); mass( (s_sock = socket( AF_INET, SOCK_STREAM, 0 )) < 0, "socket" ); memset( &saddr, 0, sizeof( struct sockaddr_in ) ); saddr.sin_family = AF_INET; saddr.sin_port = htons( PORT ); mass( inet_aton( HOST, &saddr.sin_addr ) < 0, "inet_addr" ); mass( setsockopt( s_sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(int) ) < 0, "setsockopt"); mass( bind(s_sock, (struct sockaddr*)&saddr, sizeof(saddr))<0, "bind"); attr = pthread_pool_attr_init( NULL, 8, 2, 6, 2 ); mass( pthread_pool_init( &pool, attr ) < 0, "pool_init" ); saved = (void*)pool; listen( s_sock, MAX_CONN ); #ifdef debug fputs( "Server inited.\n", stderr); #endif while( 1 ) { c_sock = accept( s_sock, (struct sockaddr*)&saddr, &slen); if( c_sock < 0 ) { usleep( 1000 ); continue; } task = create_task( socket_handler, (void*)c_sock ); #ifdef debug fprintf( stderr, "Accepted: %d.\n", c_sock ); #endif pthread_pool_add_task( pool, task ); } return 0; }