static void test_string_substring_from_start() { char *original = "hola mundo!"; char *substring = string_substring_from(original, 0); CU_ASSERT_STRING_EQUAL(substring, original); CU_ASSERT_PTR_NOT_EQUAL(substring, original); free(substring); }
static void test_string_substring_from_middle() { char *original = "hola mundo!"; char *substring = string_substring_from(original, 5); CU_ASSERT_STRING_EQUAL(substring, "mundo!"); CU_ASSERT_PTR_NOT_EQUAL(substring, &(original[5])); free(substring); }
int lengthVecConfig(char * value){ int cont=1; int i; for (i=1;i< strlen(value);i++) { if (string_starts_with(string_substring_from(value,i),",")) cont++; } return cont; }
int conectarAFilesystemYSubirArchivo(char *nombreArchivo, char *pathArchivoEnMDFS) { ConfiguracionNodo *config = obtenerConfiguracionNodo(); SocketConecta *conexion = newSocketConecta(config->ip_fs, config->puerto_fs); conectarAServidor(conexion); if (! estaConectado(conexion)) return SUBIDA_FALLO; char pedidoSubidaArchivo = MENSAJE_PEDIDO_SUBIDA_ARCHIVO; enviarMensaje(conexion, &pedidoSubidaArchivo, 1); int contador = strlen(pathArchivoEnMDFS); while(pathArchivoEnMDFS[contador] != '/') contador--; char *pathDirectorio; if (contador == 0) pathDirectorio = "/"; else pathDirectorio = string_substring_until(pathArchivoEnMDFS, contador); char *nombre = string_substring_from(pathArchivoEnMDFS, contador + 1); int longitudMensaje = strlen(pathDirectorio); enviarMensaje(conexion, &longitudMensaje, sizeof(int)); enviarMensaje(conexion, pathDirectorio, longitudMensaje); longitudMensaje = strlen(nombre); enviarMensaje(conexion, &longitudMensaje, sizeof(int)); enviarMensaje(conexion, nombre, longitudMensaje); char *pathEspacioTemporal = obtenerPathEspacioTemporal(); char *rutaArchivo = malloc(strlen(pathEspacioTemporal) + strlen(nombreArchivo) + 2); strcpy(rutaArchivo, pathEspacioTemporal); strcat(rutaArchivo, "/"); strcat(rutaArchivo, nombreArchivo); loguearYMostrarEnPantalla(LOG_LEVEL_INFO, "Subiendo archivo %s al MDFS en %s", rutaArchivo, pathArchivoEnMDFS); FILE *contenidoArchivo = fopen(rutaArchivo, "r"); char buffer[SIZE_BLOQUE_DE_ENVIO + 1]; size_t bytesLeidos = fread(buffer, 1, SIZE_BLOQUE_DE_ENVIO, contenidoArchivo); while(bytesLeidos > 0) { enviarTodo(conexion, buffer, bytesLeidos); bytesLeidos = fread(buffer, 1, SIZE_BLOQUE_DE_ENVIO, contenidoArchivo); char siguiente; recibirMensaje(conexion, &siguiente, 1); } int cero = 0; enviarMensaje(conexion, &cero, sizeof(int)); char resultadoSubida; recibirMensaje(conexion, &resultadoSubida, 1); if (resultadoSubida == MENSAJE_SUBIDA_OK) { loguearYMostrarEnPantalla(LOG_LEVEL_INFO, "Subida de archivo %s al MDFS en %s finalizada", nombreArchivo, pathArchivoEnMDFS); return SUBIDA_OK; } loguearYMostrarEnPantalla(LOG_LEVEL_INFO, "Subida de archivo %s al MDFS en %s fallida", nombreArchivo, pathArchivoEnMDFS); return SUBIDA_FALLO; }
int main(int argc, char **argv) { char log_text[2000]; char* nombre = string_substring_from(argv[1], 2); char* nombre_log = string_duplicate(nombre); char* log = ".log"; string_append(&nombre_log, log); inicializar_log(nombre_log, "Programa"); habilitar_log_info(); sprintf(log_text, "Proceso Programa %s Iniciado", nombre); log_info_message(log_text); log_info_message("Chequeando el path del script..."); if (argv[1] == NULL ) { log_error_message("El path del script no puede ser vacio."); finalizar_log(); return EXIT_FAILURE; } // CONEXION CON KERNEL t_KER_PRO_CPU_UMV mensajeAEnviar = obtener_nueva_shared_str(); t_KER_PRO_CPU_UMV* mensajeARecibir; log_debug_message("Se inicia la conexion con el KERNEL"); int socket; // ACA VA LO DE LA VARIABLE DE ENTORNO char* rutaConfiguracion = getenv("ANSISOP_CONFIG"); t_config *config = config_create(rutaConfiguracion); int puerto = config_get_int_value(config, "Puerto"); char* ip = config_get_string_value(config, "IP"); sprintf(log_text, "LA IP ES: %s\n", ip); log_info_message(log_text); sprintf(log_text, "EL PUERTO ES: %i\n", puerto); log_info_message(log_text); socket = conectar_a_servidor(ip, puerto); if (socket == -1) { return EXIT_FAILURE; } log_debug_message("Conectado\n"); // SE LEVANTA EL SCRIPT sprintf(log_text, "Se levantan datos del script en el path:%s", argv[1]); log_info_message(log_text); int num = 0; log_debug_message("se abre el archivo"); FILE* script; script = fopen(argv[1], "r"); log_debug_message("se abrio el archivo"); int tamanio; fseek(script, 0, SEEK_END); tamanio = ftell(script) + 1; sprintf(log_text, "El tamanio del script es: (%d)", tamanio); log_info_message(log_text); char codigo[tamanio]; rewind(script); char aux; while (feof(script) == 0) { aux = fgetc(script); codigo[num] = aux; num++; } log_debug_message("se termino de leer"); // printf("num vale: (%d)\n", num); num = num - 1; // printf("ahora num vale: (%d)\n", num); sprintf(log_text, "LEO: ('nueva linea')y pongo en posicion (%d)", num); log_debug_message(log_text); codigo[num] = '\n'; num++; sprintf(log_text, "LEO: ('barra 0')y pongo en posicion (%d)", num); log_debug_message(log_text); codigo[num] = '\0'; sprintf(log_text, "El script es: \n%s", codigo); log_debug_message(log_text); sprintf(log_text, "La longitud del codigo es: %i\n", strlen(codigo)); log_info_message(log_text); fclose(script); mensajeAEnviar.codigo = codigo; mensajeAEnviar.mensaje = nombre; log_debug_message("se copia el codigo"); sprintf(log_text, "El codigo copiado en el mensaje es: (%s)", mensajeAEnviar.codigo); log_debug_message(log_text); // SE ENVIA EL HANDSHAKE log_info_message( "Se envia HANDSHAKE al PLP con el Codigo y el Nombre del programa\n"); enviar_mensaje_a_servidor(socket, HANDSHAKE_PROGRAMA_PLP, &mensajeAEnviar); void *msj = recibir_mensaje_de_servidor(socket); if (msj != NULL ) { mensajeARecibir = (t_KER_PRO_CPU_UMV*) msj; } else { log_debug_message("ERROR AL RECIBIR MENSAJE NULO"); return -1; } if (mensajeARecibir->gen_msg.id_MSJ != HANDSHAKE_PROGRAMA_PLP || mensajeARecibir->OK != 1) { sprintf(log_text, "%s\n", mensajeARecibir->mensaje); log_info_message(log_text); return -1; } else { log_info_message("Respuesta Handshake entre PROGRAMA-KERNEL recibida"); } while (1) { log_info_message( "\nEL PROGRAMA SE QUEDA ESPERANDO MENSAJES DE IMPRIMIR/ IMPRIMIR TEXTO O FINALIZAR EJECUCION\n"); msj = recibir_mensaje_de_servidor(socket); if (msj != NULL ) { mensajeARecibir = (t_KER_PRO_CPU_UMV*) msj; } else { log_debug_message("ERROR AL RECIBIR MENSAJE NULO"); return -1; } switch (mensajeARecibir->gen_msg.id_MSJ) { case IMPRIMIR: { log_info_message("LLEGO MENSAJE CON ID IMPRIMIR"); sprintf(log_text, "SE IMPRIME EL VALOR DE LA VARIABLE: %i\n", mensajeARecibir->valor); log_info_message(log_text); break; } case IMPRIMIR_TEXTO: { // SE HACE LO DE IMPRIMIR TEXTO log_info_message("LLEGO MENSAJE CON ID IMPRIMIR TEXTO"); sprintf(log_text, "SE IMPRIME EL TEXTO:\n\n %s\n", mensajeARecibir->texto); log_info_message(log_text); break; } case FINALIZACION_EJECUCION_PROGRAMA: { log_info_message( "\n---------------LLEGO UN MENSAJE DE FINALIZACION----------------\n"); log_info_message("\nLA EJECUCION DE ESTE PROGRAMA HA CONCLUIDO\n"); return EXIT_SUCCESS; break; } default: { log_info_message( "\n---------------LLEGO UN MENSAJE DESCONOCIDO A PROGRAMA----------------\n"); } } } return EXIT_SUCCESS; }
void consola() { //char eleccion[30]; char* eleccion; char* comando; char* parametro; char c = 0; int longComando = 0; int posInicioParametro = 0; int consola = 1; while (consola) { posInicioParametro = 0; eleccion = string_new(); comando = string_new(); puts( "____________________________________________________________________\n\n" "Comandos disponibles: \n" "- 1) correr PATH \n" "- 2) finalizar PID \n" "- 3) ps \n" "- 4) cpu \n" "Ingrese un comando: "); scanf("%c", &c); //printf("Escanee %c\n",c); longComando++; eleccion = (char*) malloc( sizeof(char) * longComando ); string_append(&eleccion, string_repeat(c,1)); while(c != '\n'){ scanf("%c", &c); //printf("Escanee %c\n",c); longComando++; eleccion = (char*) realloc(eleccion, sizeof(char) * longComando ); string_append(&eleccion, string_repeat(c,1)); } eleccion = (char*) realloc(eleccion, sizeof(char) * (longComando+1) ); eleccion[longComando] = '\0'; int i = 0; while(eleccion[i] != '\0'){ if(eleccion[i] == ' ') posInicioParametro = i+1; i++; } //printf("El parametro empieza en la posicion %d\n", posInicioParametro); if(posInicioParametro != 0){ parametro = string_new(); comando = (char*) malloc( sizeof(char) * strlen(string_substring(eleccion, 0, posInicioParametro-1))); comando = string_substring(eleccion, 0, posInicioParametro-1); parametro = (char*) malloc( sizeof(char) * strlen(string_substring_from(eleccion, posInicioParametro))); parametro = string_substring_from(eleccion, posInicioParametro); } else{ //printf("strlen %d \n", strlen(eleccion)); eleccion[strlen(eleccion)-1] = '\0'; //printf("strlen %d \n", strlen(eleccion)); comando = (char*) malloc( sizeof(char) * strlen(eleccion) ); comando = string_duplicate(eleccion); } if(posInicioParametro == 0){ if(strcmp(eleccion, "ps") == 0){ printf("3Comando a ejecutar: %s\n", comando); } else{ if(strcmp(eleccion, "cpu") == 0){ printf("4Comando a ejecutar: %s\n", comando); } else{ printf("El comando (%s) ingresado no es valido \n", comando); eleccion[0] = '\0'; comando[0] = '\0'; } } } if(posInicioParametro != 0){ if(strcmp(comando, "correr") == 0){ printf("1Comando a ejecutar: %s %s\n", comando, parametro); Enviar(socketCPU, comando); Enviar(socketCPU, parametro); } else{ if(strcmp(comando, "finalizar") == 0){ printf("2Comando a ejecutar: %s %s\n", comando, parametro); } else{ printf("El comando (%s %s) ingresado no es valido \n", comando, parametro); eleccion[0] = '\0'; comando[0] = '\0'; parametro[0] = '\0'; } } } free(eleccion); free(comando); if(posInicioParametro != 0){ free(parametro); } } }
void mensajesConPlataforma(int32_t socketEscucha) {//ATIENDE LA RECEPCION Y POSTERIOR RESPUESTA DE MENSAJES DEL ORQUESTADOR enum tipo_paquete unMensaje = PER_conexionNivel_ORQ; char* elMensaje=NULL; pthread_mutex_lock(&mutex_log); log_info(logger,"Voy a esperar recibir un mensaje de %d", socketEscucha); pthread_mutex_unlock(&mutex_log); pthread_mutex_lock(&mutex_mensajes); //(matyx) recibirMensaje(socketEscucha, &unMensaje,&elMensaje); pthread_mutex_unlock(&mutex_mensajes); sleep(1); pthread_mutex_lock(&mutex_log); log_info(logger, "Llego el tipo de paquete: %s .",obtenerNombreEnum(unMensaje)); log_info(logger, "Llego este mensaje: %s .",elMensaje); pthread_mutex_unlock(&mutex_log); switch (unMensaje) { case PLA_movimiento_NIV: {//graficar y actualizar la lista RECIBE "@,1,3" char ** mens = string_split(elMensaje,","); char idPers = mens[0][0]; if(huboCambios==true){ pthread_mutex_lock(&mutex_log); log_info(logger,"envio los cambios de configuracion"); pthread_mutex_unlock(&mutex_log); pthread_mutex_lock(&mutex_mensajes); enviarMensaje(socketDeEscucha, NIV_cambiosConfiguracion_PLA,buffer1); pthread_mutex_unlock(&mutex_mensajes); huboCambios=false; pthread_mutex_lock(&mutex_log); log_info(logger,"me preparo para recibir el ok"); pthread_mutex_unlock(&mutex_log); pthread_mutex_lock(&mutex_mensajes); recibirMensaje(socketEscucha, &unMensaje,&elMensaje); pthread_mutex_unlock(&mutex_mensajes); pthread_mutex_lock(&mutex_log); log_info(logger,"deberia haber recibido el OK1"); pthread_mutex_unlock(&mutex_log); if(unMensaje==OK1){ pthread_mutex_lock(&mutex_log); log_info(logger,"ya envie el cambio de configuracion, y me dieron el ok"); pthread_mutex_unlock(&mutex_log); if(existePersonajeEnListaItems(idPers)){ pthread_mutex_lock(&mutex_listas); MoverPersonaje(items, idPers,atoi(mens[1]), atoi(mens[2])); pthread_mutex_unlock(&mutex_listas); pthread_mutex_lock(&mutex_log); log_info(logger, "El personaje %s se movio a %s %s ",mens[0],mens[1],mens[2]); pthread_mutex_unlock(&mutex_log); if(graficar) nivel_gui_dibujar(items,nombre); } pthread_mutex_lock(&mutex_mensajes); enviarMensaje(socketEscucha,NIV_movimiento_PLA,"0"); //"0" SI ES VALIDO pthread_mutex_unlock(&mutex_mensajes); } else { pthread_mutex_lock(&mutex_log); log_info(logger,"no recibi OK1,recibi cualquiera"); pthread_mutex_unlock(&mutex_log); } } else { if(existePersonajeEnListaItems(idPers)){ pthread_mutex_lock(&mutex_listas); MoverPersonaje(items, elMensaje[0],atoi(mens[1]), atoi(mens[2])); pthread_mutex_unlock(&mutex_listas); pthread_mutex_lock(&mutex_log); log_info(logger, "El personaje %s se movio a %s %s ",mens[0],mens[1],mens[2]); pthread_mutex_unlock(&mutex_log); if(graficar) nivel_gui_dibujar(items,nombre); } pthread_mutex_lock(&mutex_log); log_info(logger, "Confirmo que el personaje %s puede moverse",mens[0]); pthread_mutex_unlock(&mutex_log); pthread_mutex_lock(&mutex_mensajes); enviarMensaje(socketEscucha,NIV_movimiento_PLA,"0"); //"0" SI ES VALIDO pthread_mutex_unlock(&mutex_mensajes); } break; } case PLA_personajeMuerto_NIV:{ //RECIBE "@" MUERTE POR ENEMIGOS char id=elMensaje[0]; t_personaje_niv1 * personaje = malloc(sizeof(t_personaje_niv1)); personaje = buscarPersonajeListaPersonajes(listaPersonajesRecursos,string_substring_until(elMensaje,1)); pthread_mutex_lock(&mutex_listas); // liberarRecursosDelPersonaje(personaje->recursosActuales); // tambien suma sus recursos a disponible borrarPersonajeListaPersonajes(listaPersonajesRecursos,elMensaje); pthread_mutex_unlock(&mutex_listas); pthread_mutex_lock(&mutex_log); log_info(logger, "El personaje %c ha muerto ",id); pthread_mutex_unlock(&mutex_log); break; } case PLA_nuevoPersonaje_NIV:{ //RECIBE "@" LA POSICION DE INICIO SERA SIEMPRE 0,0 POR LO QUE NO LA RECIBE char * simbolo = malloc(strlen(elMensaje)+1); strcpy(simbolo,elMensaje); pthread_mutex_lock(&mutex_listas); CrearPersonaje(items,elMensaje[0],0,0); pthread_mutex_unlock(&mutex_listas); //ACA CREO UNA LISTA DE PERSONAJES CON SUS RESPECTIVOS RECURSOS ASIGNADOS t_personaje_niv1 * personaje = malloc(sizeof(t_personaje_niv1)); personaje->simbolo = string_substring_until(elMensaje,1); personaje->recursosActuales = list_create(); personaje->recursoBloqueante = string_new(); personaje->posicion = posicion_create_pos(0,0); personaje->ingresoSistema = ingresoAlSistema; ingresoAlSistema++; pthread_mutex_lock(&mutex_listas); list_add(listaPersonajesRecursos,personaje); pthread_mutex_unlock(&mutex_listas); if(graficar) nivel_gui_dibujar(items,nombre); pthread_mutex_lock(&mutex_log); log_info(logger, "El nuevo personaje %c se dibujo en el mapa",elMensaje[0]); pthread_mutex_unlock(&mutex_log); break; } case PLA_posCaja_NIV:{ // RECIBE "F" SI ESTA SOLICITANDO UNA FLOR, POR EJEMPLO char * pos = string_new(); ITEM_NIVEL * caja = buscarRecursoEnLista(items, elMensaje); string_append(&pos, string_from_format("%d",caja->posx)); string_append(&pos, ","); string_append(&pos, string_from_format("%d",caja->posy)); pthread_mutex_lock(&mutex_log); log_info(logger,"enviare la posicion de la caja"); pthread_mutex_unlock(&mutex_log); pthread_mutex_lock(&mutex_mensajes); enviarMensaje(socketEscucha, NIV_posCaja_PLA,pos); //"X,Y" pthread_mutex_unlock(&mutex_mensajes); pthread_mutex_lock(&mutex_log); log_info(logger, "Envio posicion del recurso %s coordenadas %s ",elMensaje,pos); pthread_mutex_unlock(&mutex_log); free(pos); break; } case PLA_solicitudRecurso_NIV:{ // LE CONTESTO SI EL RECURSOS ESTA DISPONIBLE // El mensaje de ejemplo es : "@,H" char * rta; bool hayRecurso = determinarRecursoDisponible (string_substring_from(elMensaje, 2)); //SI ESTA EL RECURSO TMB LO RESTA t_personaje_niv1 * pers = buscarPersonajeListaPersonajes(listaPersonajesRecursos, string_substring_until(elMensaje,1)); if (hayRecurso){ rta = "0"; pthread_mutex_lock(&mutex_listas); list_add(pers->recursosActuales, string_substring_from(elMensaje, 2)); pers->recursoBloqueante = string_new(); pthread_mutex_unlock(&mutex_listas); }else{ pthread_mutex_lock(&mutex_listas); pers->recursoBloqueante = string_substring_from(elMensaje, 2); rta = "1"; pthread_mutex_unlock(&mutex_listas); } pthread_mutex_lock(&mutex_mensajes); enviarMensaje(socketEscucha, NIV_recursoConcedido_PLA,rta);//"0" CONCEDIDO, "1" NO CONCEDIDO pthread_mutex_unlock(&mutex_mensajes); break; } case PLA_personajesDesbloqueados_NIV:{//"5,@,#,....." recorro lista personaje recursos y actualizo recBloqueante a vacio char ** mens = string_split(elMensaje,","); int i; int cantPersonajes=atoi(mens[0]); for(i=1;i<=cantPersonajes;i++){ char * unPersDesbloqueado=mens[i]; t_personaje_niv1 * unPers=buscarPersonajeListaPersonajes(listaPersonajesRecursos,unPersDesbloqueado); pthread_mutex_lock(&mutex_listas); unPers->recursoBloqueante=string_new(); pthread_mutex_unlock(&mutex_listas); pthread_mutex_lock(&mutex_log); log_info(logger, "Personajes %s desbloqueados",mens[i]); pthread_mutex_unlock(&mutex_log); } break; } case PLA_actualizarRecursos_NIV:{ //"3;F,1;C,3;....." actualizo la lista de recursos sumandole esas cantidades char ** mens = string_split(elMensaje,";"); int cantRecursos= atoi(mens[0]); int i; pthread_mutex_lock(&mutex_log); log_info(logger, "Recursos desbloqueados: %s",elMensaje); pthread_mutex_unlock(&mutex_log); for(i=1;i<=cantRecursos;i++){ char** mensajeIndividual= string_split(mens[i],","); pthread_mutex_lock(&mutex_listas); int cantidad=atoi(mensajeIndividual[1]); sumarRecurso(items, mensajeIndividual[0][0],cantidad); pthread_mutex_unlock(&mutex_listas); if(graficar) nivel_gui_dibujar(items,nombre); } break; } case PLA_nivelFinalizado_NIV:{ //recibe personaje que termino el nivel ej: "@" char id=elMensaje[0]; t_personaje_niv1 * personaje = malloc(sizeof(t_personaje_niv1)); personaje = buscarPersonajeListaPersonajes(listaPersonajesRecursos,string_substring_until(elMensaje,1)); pthread_mutex_lock(&mutex_listas); // liberarRecursosDelPersonaje(personaje->recursosActuales); BorrarItem(items,id); borrarPersonajeListaPersonajes(listaPersonajesRecursos,elMensaje); pthread_mutex_unlock(&mutex_listas); pthread_mutex_lock(&mutex_log); log_info(logger, "El personaje %c ha terminado el nivel ",id); pthread_mutex_unlock(&mutex_log); if(graficar){ nivel_gui_dibujar(items,nombre); } break; } case PLA_perMuereInterbloqueo_NIV:{ char id=elMensaje[0]; t_personaje_niv1 * personaje = malloc(sizeof(t_personaje_niv1)); personaje = buscarPersonajeListaPersonajes(listaPersonajesRecursos,string_substring_until(elMensaje,1)); pthread_mutex_lock(&mutex_listas); // liberarRecursosDelPersonaje(personaje->recursosActuales); BorrarItem(items,id); borrarPersonajeListaPersonajes(listaPersonajesRecursos,elMensaje); pthread_mutex_unlock(&mutex_listas); pthread_mutex_lock(&mutex_log); log_info(logger, "El personaje %c ha muerto por interbloqueo ",id); pthread_mutex_unlock(&mutex_log); if(graficar) nivel_gui_dibujar(items,nombre); break; } case PLA_perMuereNaturalmente_NIV: { char id = elMensaje[0]; t_personaje_niv1 * personaje = malloc(sizeof(t_personaje_niv1)); personaje = buscarPersonajeListaPersonajes(listaPersonajesRecursos,string_substring_until(elMensaje, 1)); pthread_mutex_lock(&mutex_listas); liberarRecursosDelPersonaje(personaje->recursosActuales); BorrarItem(items, id); borrarPersonajeListaPersonajes(listaPersonajesRecursos, elMensaje); pthread_mutex_unlock(&mutex_listas); pthread_mutex_lock(&mutex_log); log_info(logger, "El personaje %c ha muerto por causas externas", id); pthread_mutex_unlock(&mutex_log); if (graficar) nivel_gui_dibujar(items, nombre); break; } { default: pthread_mutex_lock(&mutex_log); log_info(logger, "Recibi mensaje inexistente, la ejecucion del nivel finalizara"); pthread_mutex_unlock(&mutex_log); eliminarEstructuras(); break; } free(elMensaje); } }
//Recibe y procesa un mensaje recibido void receiptMessage(void * arguments) { args_receiptMessage * args = arguments; int numbytes; /* bytes recibidos por cada lectura (0 = desconexion del cliente) */ char buffer[MAXDATASIZE]; /* buffer de lectura */ bool bufferUsed; /* determina si se analizo por lo menos una vez un nuevo set de datos */ unsigned int n = -1; /* cantidad de argumentos del packete que recibo */ int i = 0; /* ayuda a saber la ultima posicion de lectura en el buffer (tambien se usa como i en otros casos) */ int j = 0; /* j de for */ int seps = 0; /* cantidad de separadores ,(coma) contados en el encabezado del paquete */ char * packet_head; /* encabezado del paquete */ char * packet_body; /* cuerpo del paquete */ char * exceeded; /* datos excedidos del final del paquete */ char * str_tmp; /* temporar para operaciones de string */ bool isExceeded = false; /* determina si hay datos excedidos cargados en el buffer */ bool fullHead = false; /* determina si ya fue recibido el encabezado del paquete */ int bytesBody = 0; /* determina los bytes que contendrá el cuerpo del paquete */ char ** head = NULL; /* encabezado divido por n, name y bytes de los args */ char * b; /* utilizado para extraer bytes del buffer */ void (*fn)(); /* utilizado para guardar la funcion que hay que ejecutar del cliente */ char ** packet_args; /* Argumentos que se envian por la funcion */ //loopeo while(1) { //si en la ultima lectura dejo informacion excedida la guardo if(isExceeded) exceeded = string_duplicate(buffer); //Pongo en blanco el buffer buffer[0] = '\0'; //Espero a recibir un mensaje del job, si se produce un error lo informo error y finalizo hilo if ((numbytes=recv(args->connection->socket, buffer, MAXDATASIZE-1, 0)) == -1) { //perror("recv"); break; } //si en la ultima lectura dejo informacion excedida la agrego al inicio del buffer if(isExceeded) { exceeded = string_new(); string_append(&exceeded, buffer); buffer[sizeof(exceeded)] = '\0'; //mejor que memset? strcpy(buffer, exceeded); free(exceeded); } //finalizo el hilo if(numbytes == 0) break; else { //Corta el bufer hasta donde recibe informacion buffer[numbytes] = '\0'; //analizo el buffer si es la primera vez que lo voy a analizar o si queda informacion excedida para seguir analizando //(Analizar significa, buscar paquetes completos y ejecutarlos) bufferUsed = false; while(!bufferUsed || isExceeded) { bufferUsed = true; isExceeded = false; i = 0; //si comienzo a leer un nuevo paquete inicializo el head y el body if(n == -1) { packet_head = string_new(); packet_body = string_new(); } //recorro buffer hasta armar cabezal si no esta armado if(!fullHead) { for(i = 0; i < strlen(buffer); i++) { b = buffer[i]; //primer caracter es [n] (cantidad de args) if(n == -1) n = atoi(&b); //cuento comas else if(b == ',') seps++; //voy completando cabezal string_append(&packet_head, &b); //fianlizo cuando llego al ultimo separador if(n+2 == seps) { fullHead = true; i++; //dejo posicion en el primer byte del cuerpo del paquete break; } } } //cabezal completo if(fullHead) { //si el cabezal no fue explodiado, le doy explode y calculo los bytes del cabezal if(head == NULL) { //hago explode head = string_n_split(packet_head, n+2, ","); for(j = 2; j < n+2; j++) bytesBody += atoi(head[j]); } //Agrego al cuerpo del packete todos los datos str_tmp = string_substring_from(buffer, i); string_append(&packet_body, str_tmp); free(str_tmp); //paquete completo if(bytesBody <= strlen(packet_body)) { //si el paquete esta excedido, corto el paquete en la posicion correspondiente y guardo el excedente sobre el buffer if(bytesBody < strlen(packet_body)) { isExceeded = true; exceeded = string_substring_from(packet_body, bytesBody); str_tmp = string_substring_until(packet_body, bytesBody); free(packet_body); packet_body = str_tmp; buffer[0] = '\0'; strcpy(buffer, exceeded); free(exceeded); } //llamo a la funcion que maneja los mensajes recibidos if(args->fns_receipts != NULL) { i = 0; //armo argumentos en array packet_args = malloc(sizeof(char*)*n); for(j = 2; j < n+2; j++) { char * part = string_substring(packet_body, i, atoi(head[j])); packet_args[j-2] = part; i += atoi(head[j]); } //Si n=0 el split no toma el vacio despues de la coma final.. quito ultima coma if(n==0) head[1][strlen(head[1])-1] = '\0'; //Ejecuto la función solicitada, si no existe la función muestro error fn = dictionary_get(args->fns_receipts, head[1]); if(fn != NULL) fn(args->connection, packet_args); else printf("Cliente SOCK%d(%s:%d) intento ejecutar la función inexistente '%s'.\n", args->connection->socket, args->connection->ip, args->connection->port, head[1]); //libero argumentos for(i = 0; i < n; i++) free(packet_args[i]); free(packet_args); } free(packet_head); free(packet_body); for(i = 0; i < n+3; i++) free(head[i]); free(head); n = -1; seps = 0; fullHead = false; bytesBody = 0; head = NULL; } } } } } //cierro socket close(args->connection->socket); //Informo a la funcion que maneja los cierres (si existe y la estructura de conexion lo permite) if(args->connection->run_fn_connectionClosed && args->fn_connectionClosed != NULL) args->fn_connectionClosed(args->connection); //libero memoria if(isExceeded) free(exceeded); if(n != -1) { free(packet_head); free(packet_body); } free(args); }