void * vmalloc ( size_t size) { void * x; Memcontrol *M; verify_memory (size+2*sizeof (Memcontrol)); if ( size==0) return NULL; /*crash ("\n0 bytes in vmalloc\n");*/ else { x= malloc (size + 2*sizeof (Memcontrol)); //x=dlmalloc (size + 2*sizeof (Memcontrol)); if ( x==NULL) { printf_exit (EXIT_FAILURE,stderr, "\nFAILED TO ALLOCATE REQUIRED MEMORY (vmalloc)\n"); } else { M=x; M[0].size=size; M[0].size_element=0; sprintf ( M[0].check, "dy"); M+=2; x=M; return x; } } return NULL;}
long aln_stack (Alignment *A, int mode) { static long *list; static int size; static int max_size; if (A==NULL) return 0; else if ( mode==DECLARE_ALN) { if ( size==max_size) { max_size+=1000; list=vrealloc (list, max_size*sizeof (long)); } list[size++]=(long)A; return 0; } else if (mode==FREE_ALN) { int a, b; for (a=0; a<size; a++) { if (list[a]==(long)A) { for (b=a+1; b<size;b++) { list[b-1]=list[b]; } list[b-1]=0; size--; return 1; } } return 0; } else if ( mode==EXTRACT_ALN) { return list[size--]; } else { printf_exit (EXIT_FAILURE, stderr, "ERROR: Unknown mode for aln_stack"); return 0; } }
main(int argc, char *argv[]) { unsigned long int contador; char *charptr; int client; int first[2], second[2]; char hname[200]; struct hostent *he; int aux; fd_set infd, tinfd; struct timeval tv, *ptrtv; // SACAR TODOS LOS PARAMETROS init_params(argc, argv); ///////////////////////// SACAR NOMBRE HOST LOCAL ///////////////////////////// // SI ESTAMOS EN MODO CLIENTE Y (1 SOLO PARAMETRO O -v) gethostname(hname, 200); IFV(printf("Local host: %s\n\n", hname)); if(!params.S) { // SI ESTAMOS EN MODO CLIENTE SACAR ESTADISTICAS DEL HOST REMOTO /*in_addr i; he=gethostbyaddres(&i, SIZEOF(i), AF_INET);*/ he=gethostbyname(params.host); if(!he) perror_exit("Host not found"); IFV(print_host_stats(he)); } ////////// A PARTIR DE AQUI SOLO SE CONECTA SI SE PASO PUERTO OMO ULTIMO PARAMETRO if(NPARAMS==1) return 0; // SI SOLO HUBO UN PARAMETRO, SOLO QUERIAMOS COMPROBAR EL HOST, ADIOS // SI LLEGAMOS AQUI, EL Nº DE PUERTO ES EL ULTIMO PARAMETRO //PRINTV(NPARAMS); /////////////////////////////////////////////////////////////////////////////////// // AQUI SE DECIDE EL COMPORTAMIENTO PRINCIPAL DEL PROGRAMA CLIENTE/SERVIDOR if(!params.S) // CLIENTE { charptr=he_addr(he, 0); // LO INTENTAMOS CON LA 1A DIRECCION IFV( printf("\nTrying to connect to %s on port %d... ", charptr, params.port) ); client=socket_connect(charptr, params.port); if(client==-1) perror_exit("Error connecting to server"); IFV(printf("connected.\n")); // CONFIGURACION DE ORDEN DE LECTURA DE CANALES EN MODO CLIENTE first[0]=0; first[1]=client; second[0]=client; second[1]=1; } else //SERVIDOR // { IFV(printf("Listening on local port %d... ", params.port)); client=quick_accept(params.port); if(client==-1) perror_exit("Cannot bind to specified port"); IFV(printf("connected.\n")); close(aux); IFV(printf("Reverse host lookup\n")); IFV(print_host_stats(host_lookup(client))); if(params.e) execute_command(client, argc, argv); // ESTA ES LA MEJOR OPCION... // CONFIGURACION DE ORDEN DE LECTURA DE CANALES EN MODO SERVIDOR first[0]=client; first[1]=1; // PRIMERO LEER DE SOCKET Y ESCRIBIR A STDOUT second[0]=0; second[1]=client; // LUEGO "RESPONDER", LEYENDO DE STDIN Y ESCRIBIENDO A SOCKET // DAR TIEMPO AL CLIENTE A QUE NOS MANDE ALGO uwait(100); // ESPERAR 100 milisegundos } // INICIALIZAR LA ESTRUCTURA PARA select() if(params.t==-1) ptrtv=NULL; // LE PASAREMOS NULL A select else { BZERO(&tv); tv.tv_sec=params.t; ptrtv=&tv; } // INICIALIZAR VBLES DE CONTROL DEL BUCLE PRINCIPAL FD_ZERO(&infd); FD_ZERO(&tinfd); FD_SET(first[0], &infd); // ANYADIR fd AL CONJUNTO DE DESCRIPTORES FD_SET(second[0], &infd); // DESCARTAR CANALES QUE NO NOS INTERESEN // LEER SOLO DE SOCKET if(params.r) if(params.S) FD_CLR(second[0], &infd); else FD_CLR(first[0], &infd); // SOLO ESCRIBIR EN SOCKET if(params.w) if(params.S) FD_CLR(first[0], &infd); else FD_CLR(second[0], &infd); //////////////////////////////////////////////////////////////////////////////// ////////////// BUCLE PRINCIPAL DE LECTURA/ESCRITURA //////////////////////////// //////////////////////////////////////////////////////////////////////////////// // SERVIDOR: SOCKET->STDOUT; // STDIN->SOCKET; // // CLIENTE: STDIN->SOCKET; // SOCKET->STDOUT; // // USO MUY IMPORTANTE DE tinfd E infd PARA EL CONTROL DE FLUJO DE DATOS //////////////////////////////////////////////////////////////////////////////// tinfd=infd; while(FD_ISSET(first[0], &infd) || FD_ISSET(second[0], &infd)) // MIENTRAS HAY CONEXION EN ALGUN SENTIDO { // PRIMERO UN SELECT DE TANTEO if(select(MAX(first[0], second[0])+1, &tinfd, NULL, NULL, ptrtv)==-1) perror_exit("Fatal error"); // SI NO OCURRIO NADA DE INTERES, SALIR A LO BURRO if(!FD_ISSET(first[0], &tinfd) && !FD_ISSET(second[0], &tinfd)) { IFV(printf_exit("\nTimeout!!!")); exit(0); } //if(FD_ISSET(first[0], &tinfd)) printf("\nhay algo en first[0]=%d\n", first[0]); //if(FD_ISSET(second[0], &tinfd)) printf("\nhay algo en second[0]=%d\n", second[0]); read_write(first, &tinfd, &infd); // MODIFICAN infd PARA SABER CUANDO LLEGAMOS A EOF fflush(NULL); read_write(second, &tinfd, &infd); // SACANDO EL DESCRIPTOR CORRESPONDIENTE DE ENTRADA fflush(NULL); tinfd=infd; }// DEL WHILE IFV(printf("\nnk finished gracefully.\n")); close(client); return 0; }