int clasifica(char test){ if (es_letra(test)) if (es_vocal(test)) return vocal; else return consonante; if (es_numero(test)) return numero; return err; }
int main(int argc, char *argv[]){ /* Registrando rutina manejadora de señales */ struct sigaction sa_sigint; struct sigaction sa_sigchld; //SIGINT se da cuando se presiona Ctl + C sa_sigint.sa_handler = sig_handler; //Se registra un manejador personalizado sa_sigint.sa_flags = SA_RESTART; if(sigaction(SIGINT, &sa_sigint, NULL) == -1) { perror("SIGINT"); exit(-1); } //SIGCHLD: Enviada cuando un hijo termina. Esta señal será ignorada. //Gracias a la flag agregada SA_NOCLDWAIT los hijos que terminen no se //convertirán en zombies, es por esto que se ignora la señal. //ver: man 3 sigaction y man 3 wait sa_sigchld.sa_handler = SIG_IGN; //Se ignora la señal sa_sigchld.sa_flags = SA_NOCLDSTOP || SA_NOCLDWAIT; if(sigaction(SIGCHLD, &sa_sigchld, NULL) == -1) { perror("SIGCHLD"); exit(-1); } /* Validación de parámetros */ //Número de parámetros, se espera uno o dos parámetros if(argc > 2){ usage(); exit(-1); } //Si se enviaron dos argumentos if(argc == 2){ //Si el segundo argumento es igual a "-h" se imprime el modo de uso if(!strcmp(argv[1], "-h")) //Iguales retorna 0 { usage(); exit(0); } //Se comprueba que el segundo argumento sea numérico. if (!(puerto=es_numero(argv[1]))) { perror("[*] Mal argumento: El puerto debe ser un numero positivo."); exit(-1); } } else { //Si solo se recibe un paŕametro se establece el puerto por defecto puerto = 6666; } printf("\nIniciando servidor *** REVERSE EVIL SHELL ***\n"); socket_des = crear_socket_servidor(puerto); //Se crea el socket escuchando el e lpuerto indicado if (socket_des == -1 ) //Se valida la creación correcta del socket { perror("Error abriendo el socket"); return -1; } whoiam(); //Imprime la dirección ip y el puerto por el que se está escuchando int cliente_descriptor; do { //Escucha conexiones entrantes y retorna un descriptor para el cliente que se conecta cliente_descriptor = escuchar_clientes_nuevos(); //Se divide el proceso actual, el proceso hijo atenderá al cliente conectado, //el padre voverá a la escuha switch(fork()) { case -1: perror("Fork"); break; case 0: { // Se convierte el cliente_descriptor en char* para pasarlo como parámetro al shell en execl char str_sokdes[10]; snprintf(str_sokdes, 10, "%d", cliente_descriptor); //Se escribe el descriptor en el buffer // Se ejecuta el programa revil_shell ubicado en la misma ruta del servidor execl("./revil_shell", "./revil_shell", str_sokdes, (char*)NULL); perror("EXEC"); exit(-1); } break; } }while(1); //El servidor se ejecuta indefinidamente return 0; }
int obtener_orden (char *s, CMD_t *cmd) { int pipecnt=-1; // Cuenta de tuberías int argcnt=0; // Cuenta de argumentos por tubería int cnt; // Cuenta de tokens int ntoks; // Número de tokens int estado=ST_INIT; reset_cmd(cmd); strcpy (cmd->buffer, s); trocea (cmd->buffer); ntoks = numero_de_tokens(); for (cnt=0; cnt<ntoks && estado!=ST_ERR; cnt++) { switch (estado) { case ST_INIT: estado = ST_ERR; if (tipo_token(cnt) == TOK_NOMBRE) { if (es_numero(token_str(cnt))) { cmd->time=atoi(token_str(cnt)); estado = ST_PIPE; } } break; case ST_ARGS: switch (tipo_token(cnt)) { case TOK_NOMBRE: cmd->args[pipecnt][++argcnt] = token_str(cnt); break; case TOK_MAYOR: estado=ST_FSAL;break; case TOK_MENOR: estado=ST_FENT;break; case TOK_TUBO: estado=ST_PIPE;break; case TOK_APPEND: estado=ST_APP;break; case TOK_STDERR: estado=ST_STDERR;break; default: estado=ST_ERR;break; } break; case ST_PIPE: estado=ST_ERR; if (tipo_token(cnt) == TOK_NOMBRE) { cmd->args[++pipecnt][argcnt=0]=token_str(cnt); estado=ST_ARGS; } break; case ST_FENT: estado=ST_ERR; if (tipo_token(cnt) == TOK_NOMBRE && !cmd->fent) { cmd->fent=token_str(cnt); estado = ST_FRED; } break; case ST_FSAL: estado=ST_ERR; if (tipo_token(cnt) == TOK_NOMBRE && !cmd->fsal) { cmd->fsal=token_str(cnt); cmd->append=0; estado = ST_FRED; } break; case ST_APP: estado=ST_ERR; if(tipo_token(cnt) == TOK_NOMBRE && !cmd->fsal) { cmd->fsal=token_str(cnt); cmd->append=1; estado = ST_FRED; } break; case ST_STDERR: estado=ST_ERR; if(tipo_token(cnt) == TOK_NOMBRE && !cmd->fsalerr) { cmd->fsalerr=token_str(cnt); estado = ST_FRED; } break; case ST_FRED: estado=ST_ERR; if ((tipo_token(cnt) == TOK_MAYOR) && (!cmd->fsal)) estado=ST_FSAL; if ((tipo_token(cnt) == TOK_MENOR) && (!cmd->fent)) estado=ST_FENT; if ((tipo_token(cnt) == TOK_STDERR) && (!cmd->fsalerr)) estado=ST_STDERR; break; } } // Miro estados finales if (estado != ST_ARGS && estado != ST_FRED) estado = ST_ERR; return (estado==ST_ERR ? -1 : 0); }