// Transport parser static int parse_transport( const char* s ) { const char *c; static TRANSPORT_SER tser; if( strstr( s, "ser:" ) == s ) { s += strlen( "ser:" ); if( ( c = strchr( s, ',' ) ) == NULL ) { fprintf( stderr, "Invalid serial transport syntax\n" ); return 0; } if( secure_atoi( c + 1, &tser.speed ) == 0 ) { fprintf( stderr, "Invalid port speed\n" ); return 0; } tser.pname = strndup( s, c - s ); transport_data = &tser; transport_send = transport_ser_send; transport_recv = transport_ser_recv; transport_init = transport_ser_init; transport_type = TRANSPORT_TYPE_SER; return 1; } fprintf( stderr, "Error: unsupported transport\n" ); return 0; }
int main( int argc, const char **argv ) { long serspeed; if( argc < 4 ) { fprintf( stderr, "Usage: %s <port> <speed> <dirname> [-v]\n", argv[ 0 ] ); fprintf( stderr, "(use -v for verbose output).\n"); return 1; } if( secure_atoi( argv[ SPEED_ARG_IDX ], &serspeed ) == 0 ) { fprintf( stderr, "Invalid speed\n" ); return 1; } if( !os_isdir( argv[ DIRNAME_ARG_IDX ] ) ) { fprintf( stderr, "Invalid directory %s\n", argv[ DIRNAME_ARG_IDX ] ); return 1; } if( ( argc >= 5 ) && !strcmp( argv[ VERBOSE_ARG_IDX ], "-v" ) ) log_init( LOG_ALL ); else log_init( LOG_NONE ); // Setup RFS server server_setup( argv[ DIRNAME_ARG_IDX ] ); // Setup serial port if( ( ser = ser_open( argv[ PORT_ARG_IDX ] ) ) == ( ser_handler )-1 ) { fprintf( stderr, "Cannot open port %s\n", argv[ PORT_ARG_IDX ] ); return 1; } if( ser_setup( ser, ( u32 )serspeed, SER_DATABITS_8, SER_PARITY_NONE, SER_STOPBITS_1 ) != SER_OK ) { fprintf( stderr, "Unable to initialize serial port\n" ); return 1; } flush_serial(); // User report printf( "Running RFS server on port %s (%u baud) in directory %s\n", argv[ PORT_ARG_IDX ], ( unsigned )serspeed, argv[ DIRNAME_ARG_IDX ] ); // Enter the server endless loop while( 1 ) { read_request_packet(); server_execute_request( rfs_buffer ); send_response_packet(); } ser_close( ser ); return 0; }
int main( int argc, char **argv ) { unsigned i; THREAD_DATA *tdata; int c; int temp, sdata; int got_esc = 0; DATA data; // Interpret arguments if( argc < 4 ) { fprintf( stderr, "Usage: %s <transport> <baud> <vcom1> [<vcom2>] ... [<vcomn>] [-v]\n", argv[ 0 ] ); return 1; } i = argc - 1; if( !strcasecmp( argv[ i ], "-v" ) ) { i --; log_init( LOG_ALL ); } else log_init( LOG_NONE ); if( ( vport_num = i - 2 ) > SERVICE_MAX ) { fprintf( stderr, "Too many service ports, maximum is %d\n", SERVICE_MAX ); return 1; } if( parse_transport( argv[ MAIN_TRANSPORT_IDX ] ) == 0 ) return 1; if( secure_atoi( argv[ SERVICE_BAUD_IDX ], &service_baud ) == 0 ) { fprintf( stderr, "Invalid service baud\n" ); return 1; } if( transport_init() == 0 ) return 1; // Create global sync objects sem_init( &mux_w_sem, 0, 1 ); sem_init( &mux_r_sem, 0, 0 ); // Open all the service ports and create their corresponding threads if( ( threads = ( THREAD_DATA* )malloc( sizeof( THREAD_DATA ) * ( vport_num + 1 ) ) ) == NULL ) { fprintf( stderr, "Not enough memory\n" ); return 1; } for( i = 0; i <= vport_num; i ++ ) { tdata = threads + i; if( i < vport_num ) { if( ( tdata->fd = ser_open( argv[ i + FIRST_SERVICE_IDX ] ) ) == ( ser_handler )-1 ) { fprintf( stderr, "Unable to open port %s\n", argv[ i + FIRST_SERVICE_IDX ] ); return 1; } if( ser_setup( tdata->fd, service_baud, SER_DATABITS_8, SER_PARITY_NONE, SER_STOPBITS_1 ) != SER_OK ) { fprintf( stderr, "Unable to setup serial port %s\n", argv[ i + FIRST_SERVICE_IDX ] ); return 1; } tdata->pname = argv[ i + FIRST_SERVICE_IDX ]; tdata->service_id = i + SERVICE_ID_FIRST; } if( pthread_create( &tdata->tid, NULL, i == vport_num ? transport_thread : service_thread, ( void* )tdata ) ) { fprintf( stderr, "Unable to create thread\n" ); return 1; } } printf( "Starting service multiplexer on %u port(s)\n", vport_num ); // Main service thread while( 1 ) { sem_wait( &mux_r_sem ); data = mux_data; sem_post( &mux_w_sem ); if( data.id == TRANSPORT_SERVICE_ID ) { // Read one byte, interpret it c = data.data; if( c != ESCAPE_CHAR ) { if( c >= SERVICE_ID_FIRST && c <= SERVICE_ID_LAST ) service_id_in = c; else { if( got_esc ) { // Got an escape last time, check the char now (with the 5th bit flipped) c ^= ESCAPE_XOR_MASK; if( c != ESCAPE_CHAR && c < SERVICE_ID_FIRST && c > SERVICE_ID_LAST ) { fprintf( stderr, "Protocol error: invalid escape sequence\n" ); return 1; } got_esc = 0; } if( service_id_in == -1 ) { fprintf( stderr, "Protocol error: service ID not specified\n" ); return 1; } ser_write_byte( threads[ service_id_in - SERVICE_ID_FIRST ].fd, c ); } } else got_esc = 1; } else { temp = data.id; sdata = data.data; if( temp != service_id_out ) transport_send_byte( temp ); // Then send the actual data byte, escaping it if needed if( sdata == ESCAPE_CHAR || ( sdata >= SERVICE_ID_FIRST && sdata <= SERVICE_ID_LAST ) ) { transport_send_byte( ESCAPE_CHAR ); transport_send_byte( ( u8 )sdata ^ ESCAPE_XOR_MASK ); } else transport_send_byte( sdata ); service_id_out = temp; } } return 0; }
static void app(void) { SOCKET sock = init_connection(); char buffer[BUF_SIZE]; int max = sock; /* tableau des clients */ Client clients[MAX_CLIENTS]; fd_set rdfs; /* Topologie */ struct graph * graph = initialiser_Graph(); while(1) { int i = 0; FD_ZERO(&rdfs); /* ajouter STDIN_FILENO */ FD_SET(STDIN_FILENO, &rdfs); /* ajouter le socket de connexion */ FD_SET(sock, &rdfs); /* ajouter un socket pour chaque client */ for(i = 0; i < actual; i++) { FD_SET(clients[i].sock, &rdfs); } if(select(max + 1, &rdfs, NULL, NULL, NULL) == -1) { perror("select()"); exit(errno); } /* quelque chose qui rentre depuis le clavier */ if(FD_ISSET(STDIN_FILENO, &rdfs)) { /* char message[BUF_SIZE]; */ fgets(buffer, BUF_SIZE - 1, stdin); { char *p = NULL; p = strstr(buffer, "\n"); if(p != NULL) { *p = 0; } else { /* fclean */ buffer[BUF_SIZE - 1] = 0; } } /* ===Pour écrire à tous les clients=== message[0] = 0; strncpy(message, "serveur : ", 0); strncat(message, buffer, 10); for(i = 0; i < actual; i++) { write_client(clients[i].sock, message); } */ /* On analyse ce que l'utilisateur tape et on agit en conséquence */ if(analyse_cmd(graph, buffer) == 0) break; /* L'utilisateur veut quitter */ } else if(FD_ISSET(sock, &rdfs)) { /* nouveau client */ SOCKADDR_IN csin = { 0 }; socklen_t sinsize = sizeof(csin); int csock = accept(sock, (SOCKADDR *)&csin, &sinsize); if(csock == SOCKET_ERROR) { perror("accept()"); continue; } /* après s'être connecté le client envoie son nom */ if(read_client(csock, buffer) == -1) { /* déconnecté */ continue; } /* quel est le nouveau fd maximum ? */ max = csock > max ? csock : max; FD_SET(csock, &rdfs); /* On ajoute le socket à la liste d'écoute */ int nbTokens; char **tokens = malloc(MAX_NB_TOKENS*sizeof(char*)); nbTokens = strsplit(buffer, tokens, MAX_LEN_LINE, " "); printf("ENVOYE : %s, NB TOKENS : %d\n", buffer, nbTokens); if (nbTokens == 6 && strcmp(tokens[0], "log") == 0 && strcmp(tokens[1], "in") == 0 && strcmp(tokens[2], "as") == 0 && strcmp(tokens[4], "port") == 0) { printf("nbTokens == 6\n"); int port; tokens[5][strlen(tokens[5])-1] = '\0'; port = secure_atoi(tokens[5]); /* On cherche si un client utilise déjà le nom demandé * si le nom existe * et si le port est bon*/ if (port <= 65535 && port >= 0) { printf("port OK\n"); int indice_noeud, indice_noeud_gen; Client c; c.sock = csock; c.port_number = port; c.address = inet_ntoa(csin.sin_addr); indice_noeud = exist_Noeud(graph, tokens[3]); indice_noeud_gen = obtenir_Indice_Noeud_Non_Actif(graph); if (indice_noeud < actual && indice_noeud >= 0 && est_actif_noeud(graph, indice_noeud)== 0) { printf("indice noeud OK, %s\n", tokens[3]); strcpy(c.name, tokens[3]); activer_Noeud(graph, indice_noeud); clients[actual] = c; actual = actual + 1; char bufG[BUF_SIZE] = ""; sprintf(bufG, "greeting %s*\n", c.name); write_client(c.sock, bufG, clients); } else if(indice_noeud_gen != -1) { printf("indice noeud gen OK\n"); strcpy(c.name, obtenir_Nom_Noeud(graph, indice_noeud_gen)); activer_Noeud(graph, indice_noeud_gen); clients[actual] = c; actual = actual + 1; char bufG[BUF_SIZE] = ""; sprintf(bufG, "greeting %s*\n", c.name); printf("bufG : %s\n", bufG); write_client(c.sock, bufG, clients); printf("écrit\n"); } else { printf("Tous les noeuds sont déjà occupés !\n"); } } else printf("Erreur de port : %s\n", tokens[5]); } else if (nbTokens == 4 && strcmp(tokens[0], "log") == 0 && strcmp(tokens[1], "in") == 0 && strcmp(tokens[2], "port") == 0) { int port; tokens[5][strlen(tokens[5])-1] = '\0'; port = secure_atoi(tokens[5]); /* On cherche si un client utilise déjà le nom demandé * si le nom existe * et si le port est bon*/ if (port <= 65535 && port >= 0) { int indice_noeud_gen; Client c; c.sock = csock; c.port_number = port; c.address = inet_ntoa(csin.sin_addr); indice_noeud_gen = obtenir_Indice_Noeud_Non_Actif(graph); if(indice_noeud_gen != -1) { strcpy(c.name, obtenir_Nom_Noeud(graph, indice_noeud_gen)); activer_Noeud(graph, indice_noeud_gen); clients[actual] = c; actual = actual + 1; char bufG[BUF_SIZE] = ""; sprintf(bufG, "greeting %s*\n", c.name); /* printf("bufG : %s\n", bufG); */ write_client(c.sock, bufG, clients); /* printf("écrit\n"); */ } else { printf("Tous les noeuds sont déjà occupés !\n"); } } else printf("Erreur de port : %s\n", tokens[5]); } /* for(i=0; i < nbTokens; i++) { free(tokens[i]); } free(tokens); */ } else { int i; for(i = 0; i < actual; i++) { /* un client parle */ if(FD_ISSET(clients[i].sock, &rdfs)) { Client client = clients[i]; int c = read_client(clients[i].sock, buffer); /* client déconnecté */ if(c == 0) { closesocket(clients[i].sock); remove_client(clients, i, &actual); strncpy(buffer, client.name, BUF_SIZE - 1); strncat(buffer, " déconnecté !", BUF_SIZE - strlen(buffer) - 1); send_message_to_all_clients(clients, client, actual, buffer, 1); } else { /* On analyse la requête du client stockée dans buffer et on lui répond */ printf("router_poll : %s\n", buffer); if(router_poll(graph, &clients[i], buffer, clients) == 0) { /* Si le routeur veut être déconnecté */ closesocket(clients[i].sock); remove_client(clients, i, &actual); } /* ====Pour envoyer un message à tous les routeurs==== send_message_to_all_clients(clients, client, actual, buffer, 0); */ } break; } } } } /* libération des données */ free_graph(graph); clear_clients(clients, actual); end_connection(sock); }