/* * Executes a shell command entered by the user * * Parameters: * argc - number of arguments in the command * argv - the user's command * mods - special modifiers for the command * * Returns: * 0 on success, -1 otherwise */ int execute_cmd(size_t argc, char *const argv[], const mods_t *const mods) { // Builtin command received if (is_builtin(argv[0])) return execute_builtin(argc, argv, mods); // Non builtin command received int ret = fork(); if (ret == -1) { // fork() failed in the parent perror("ERROR: fork():"); } else if (ret == 0) { // Child code printf("[%d] %s\n", getpid(), argv[0]); if (mods->out_file != NULL && redirect_stdout(mods->out_file) == -1) return -1; execvp(argv[0], argv); printf("ERROR: Cannot exec '%s'\n", argv[0]); return -1; } else { // Parent code if (mods->bg == 0) check_child_status(ret, 0); } return 0; }
/* Arguements: -(struct node*): The List of Commands Returns (void) */ void run_commands(struct node* commands) { while (commands) { char **array = 0; struct node* list = 0; // Redirect append if ( strstr( commands->data, ">>" ) ) { array = split_on_append(commands->data); redirect_append(array); } // Redirect stdout else if ( strstr( commands->data, ">" ) ) { array = split_on_stdout(commands->data); redirect_stdout(array); } // Redirect stdin else if ( strstr( commands->data, "<" ) ) { array = split_on_stdin(commands->data); redirect_stdin(array); } // Pipe else if ( strstr( commands->data, "|" ) ) { list = split_on_pipe(commands->data); redirect_pipe(list); } // Normal Execution else { array = arguementify(commands->data); execute_command(array); } // Cleanup free_list(list); free_string_array(array); // Continue commands = commands->next; } }
void redirect_m(int numb_of_params, char* params[]) { char * commands[COMMAND_COUNT]; PARAMS=params; N_params=numb_of_params; int pars_res = parse(numb_of_params, params, commands); if (pars_res != 0) { printf("error parsing 'redirect' comand.\n"); return; } // --------------------------------------------------------- if (strcmp(commands[1], ">") == 0 || strcmp(commands[1], ">>") == 0) { redirect_stdout(commands[0], commands[1], commands[2]); } else { if (strcmp(commands[1], "<") == 0 && strcmp(commands[3], "\0") == 0) { redirect_stdin(commands[0], commands[1], commands[2]); } else if (strcmp(commands[1], "<") == 0 && (strcmp(commands[3], ">") == 0 || strcmp(commands[3], ">>") == 0)) { redirect_stdin_stdout(commands[0], commands[1], commands[2], commands[3], commands[4]); } } }
int main(int argc, char **argv) { int status; int nrx_fd; int host_rfd; int host_wfd; int use_stdin = 0; char * ser_dev = NULL; int port = 12345; char * filename = default_filename; void * handle = NULL; int host_flash = 0; int input_baudrate = 115200; speed_t baudrate = B115200; int opt; struct ifreq ifr; struct nanoioctl nr; while((opt = getopt(argc, argv, "d:s:p:f:b:i")) != -1) { switch(opt) { case 'b': input_baudrate = atoi(optarg); switch(input_baudrate) { case 9600: baudrate = B9600; break; case 19200: baudrate = B19200; break; case 38400: baudrate = B38400; break; case 57600: baudrate = B57600; break; case 115200: baudrate = B115200; break; default: usage(); } break; case 'd': debug = atoi(optarg); break; case 'f': filename = optarg; break; case 'i': use_stdin = 1; break; case 'p': port = atoi(optarg); break; case 's': ser_dev = optarg; break; default: break; } } if(optind == argc) usage(); strcpy(ifr.ifr_name, argv[optind]); ifr.ifr_data = (char *)&nr; memset(&nr,0,sizeof(nr)); nr.magic = NR_MAGIC; APP_INFO("Nanoradio network interface: %s\n", ifr.ifr_name); APP_INFO("Saving persistent MIB data of type HOST to: %s\n", filename); if(use_stdin) { APP_INFO("Using stdin/stdout as client interface\n"); host_wfd = host_rfd = open_terminal(); redirect_stdout("/tmp/hic_proxy.log"); } else if(ser_dev) { APP_INFO("Using %s (baudrate = %d) as serial client interface\n", ser_dev,input_baudrate); host_wfd = host_rfd = open_serial(ser_dev, baudrate); } else { APP_INFO("Using ethernet as client interface\n"); host_wfd = host_rfd = open_socket(port); } nrx_fd = socket(AF_INET, SOCK_DGRAM, 0); if(nrx_fd < 0) err(1, "socket"); for(;;) { status = poll_host(host_rfd, &ifr); if(status) { if((nr.data[TYPE_INDEX] == HIC_MESSAGE_TYPE_FLASH_PRG)) { APP_DEBUG("flash cmd recieved\n"); //examine flash cmd handle = flash_cmd(&ifr,handle,filename); if(handle) { //send local host flash cmd reply host_write(host_wfd, nr.data, nr.length); } else { //forward to target nrx_write(nrx_fd, &ifr); } } else { //forward to target nrx_write(nrx_fd, &ifr); } } status = poll_target(nrx_fd, &ifr); if(status) host_write(host_wfd, nr.data, nr.length); usleep(5000); } if(!use_stdin) { close(host_rfd); } close(nrx_fd); }
int main(int argc, const char **argv){ if (1 == argc) usage(); int interval = DEFAULT_INTERVAL; int len = 0; int interpret = 1; char *args[ARGS_MAX] = {0}; for (int i = 1; i < argc; ++i) { const char *arg = argv[i]; if (!interpret) goto arg; // -h, --help if (option("-h", "--help", arg)) usage(); // -q, --quiet if (option("-q", "--quiet", arg)) { quiet = 1; continue; } // -x, --halt if (option("-x", "--halt", arg)) { halt = 1; continue; } // -v, --version if (option("-v", "--version", arg)) { printf("%s\n", VERSION); exit(1); } // -i, --interval <n> if (option("-i", "--interval", arg)) { if (argc-1 == i) { fprintf(stderr, "\n --interval requires an argument\n\n"); exit(1); } arg = argv[++i]; char last = arg[strlen(arg) - 1]; // seconds or milliseconds interval = last >= 'a' && last <= 'z' ? string_to_milliseconds(arg) : atoi(arg) * 1000; continue; } // cmd args if (len == ARGS_MAX) { fprintf(stderr, "number of arguments exceeded %d\n", len); exit(1); } arg: args[len++] = (char *) arg; interpret = 0; } // <cmd> if (!len) { fprintf(stderr, "\n <cmd> required\n\n"); exit(1); } // cmd char *val = join(args, len, " "); char *cmd[4] = { "sh", "-c", val, 0 }; // exec loop loop: { pid_t pid; int status; switch (pid = fork()) { // error case -1: perror("fork()"); exit(1); // child case 0: if (quiet) redirect_stdout("/dev/null"); execvp(cmd[0], cmd); // parent default: if (waitpid(pid, &status, 0) < 0) { perror("waitpid()"); exit(1); } // exit > 0 if (WEXITSTATUS(status)) { fprintf(stderr, "\033[90mexit: %d\33[0m\n\n", WEXITSTATUS(status)); if (halt) exit(WEXITSTATUS(status)); } mssleep(interval); goto loop; } } return 0; }
/* * Executes a builtin shell command * * Parameters: * argc - number of arguments in the command * argv - the user's command * mods - special modifiers for the command * * Returns: * 0 on success, -1 otherwise */ int execute_builtin(size_t argc, char *const argv[], const mods_t *const mods) { // Handle file redirection int fd; if (mods->out_file != NULL && (fd = redirect_stdout(mods->out_file)) == -1) return -1; // HELP if (strcmp(argv[0], "help") == 0) { print_help(); } // EXIT else if (strcmp(argv[0], "exit") == 0) { return -1; } // PID else if (strcmp(argv[0], "pid") == 0) { printf("[%d] shell\n", getpid()); } // PPID else if (strcmp(argv[0], "ppid") == 0) { printf("[%d] parent\n", getppid()); } // PWD else if (strcmp(argv[0], "pwd") == 0) { char dir[PATH_MAX]; if (getcwd(dir, sizeof(dir)) == NULL) perror("ERROR: getcwd():"); else printf("%s\n", dir); } // CD else if (strcmp(argv[0], "cd") == 0) { int err = 0; if (argc > 1) err = chdir(argv[1]); else err = chdir(getenv("HOME")); if (err != 0) perror("ERROR: chdir():"); } // GET else if (strcmp(argv[0], "get") == 0) { if (argc > 1) { char *var = getenv(argv[1]); if (var == NULL) printf("ERROR: Unknown variable '%s'.\n", argv[1]); else printf("%s\n", var); } else printf("Usage: get <var>.\n"); } // SET else if (strcmp(argv[0], "set") == 0) { if (argc == 1) printf("Usage: set <var> <value>\n"); else if (argc == 2 && unsetenv(argv[1]) == -1) perror("ERROR: unsetenv():"); else if (setenv(argv[1], argv[2], 1) == -1) perror("ERROR: setenv():"); } // Revert file redirection if (mods->out_file != NULL && restore_stdout(fd) == -1) return -1; return 0; }
int tardiffmerge(int argc, char *argv[], char *flags) { int n, num_diffs; struct File *files, *file; bool input_ok, output_ok, order_files; num_diffs = argc - 1; input_ok = output_ok = false; order_files = (strchr(flags, 'f') == NULL); /* Verify arguments are all diff files: */ input_ok = identify_files((const char**)argv, num_diffs, NULL, &files); for (file = files; file != NULL; file = file->next) { if (file->type == FILE_INVALID) { fprintf(stderr, "%s: %s\n", file->path, file->invalid.error); } else if (file->type != FILE_DIFF) { fprintf(stderr, "%s: not a differences file\n", file->path); input_ok = false; } else /* file->type == FILE_DIFF */ { static uint8_t zero_digest[DS]; if (order_files && memcmp(file->diff.digest1, zero_digest, DS) == 0) { fprintf(stderr, "Input contains version 1.0 difference files; " "merge order cannot be determined.\n"); input_ok = false; } } } if (input_ok && order_files) { mark_usable(files); if (!order_input(&files)) { fprintf(stderr, "Input files could not be ordered!\n"); input_ok = false; } } if (input_ok) { /* Redirect output (if necessary) */ if (strcmp(argv[argc - 1], "-") != 0) redirect_stdout(argv[argc - 1]); n = 0; for (file = files; file != NULL; file = file->next) { InputStream *is; char magic[MAGIC_LEN]; /* Try to open again */ is = OpenFileInputStream(file->path); if (is == NULL) { fprintf(stderr, "%s: could not be opened.\n", file->path); break; } /* Save pointer here, so we can close it later. */ is_diff[n++] = is; /* Verify magic again */ read_data(is, magic, MAGIC_LEN); if (memcmp(magic, MAGIC_STR, MAGIC_LEN) != 0) { fprintf(stderr, "%s: not a differences file\n", file->path); break; } /* Process entire file */ process_input(is); } if (file == NULL) { output_ok = generate_output(); } /* Close open streams: */ while (n-- > 0) is_diff[n]->close(is_diff[n]); munmap(last_blocks, last_num_blocks*sizeof(BlockRef)); } free_files(files); return (input_ok && output_ok) ? EXIT_SUCCESS : EXIT_FAILURE; }
/*=================================================== = Programa principal = ===================================================*/ int main() { char* argumentos[MAX_ARGS]; // Argumentos dos executáveis char buffer[BUFFER_SIZE]; // Buffer que guarda os dados da leitura do pipe int input; // Descritor de ficheiro para o pipe que recebe input dos terminais /** * Inicializar as variáveis e estruturas da par-shell */ initialize_variables(); /** * Atualizar as informações do log da par-shell */ update_log_values(); /** * Catch do signal ctrl+c */ if(signal(SIGINT, sig_handler) == SIG_ERR){ perror("Erro no signal: "); } while(1){ /** * Abrir o pipe que recebe input dos terminais */ if((inputdesc = open(inputpipe,O_RDONLY)) < 0){ perror("Erro no open do pipe: "); exit(EXIT_FAILURE); } /** * Ler informações do pipe */ if((input = read(inputdesc,buffer,BUFFER_SIZE)) <= 0){ // Fechar o pipe apos a leitura close(inputdesc); // Não lê nada mas tambem não dá erro, continua o ciclo (e.g press enter) if(input == 0){ continue; } perror("Erro no read do input"); } else{ buffer[input] = '\0'; if(strcmp(buffer,"exit-global") == 0) { /** * Sair da par-shell */ exit_par_shell(); } if (sscanf(buffer, "/tmp/terminal-%d", &pidterminal) > 0) { /** * Registar um terminal especifico e o seu pipe */ printf("Terminal %d criado\n",pidterminal); if(fflush(stdout) < 0) perror("Erro no fflush de escrita no par-shell na criação de terminal: "); // Inserir pid do terminal na lista de terminais insert_new_terminal(lista_terminais,pidterminal); continue; } if(sscanf(buffer,"stats %d",&pidterminal) > 0){ /** * Enviar o número de processos filhos em execução e * o tempo total de execução da par-shell para o terminal */ // Construir strings de output e do nome do pipe do terminal sprintf(output,"Número de filhos em execução: %d \nTempo total: %g",nfilhos,tempo_total_execucao); sprintf(terminalpipe,"/tmp/terminal-%d",pidterminal); // Abrir o pipe do terminal para escrita if((fd_write = open(terminalpipe, O_WRONLY)) < 0){ perror("Erro no open do stats da par-shell: "); exit(EXIT_FAILURE); } // Escrever no pipe do terminal if(write(fd_write,output,strlen(output)) < 0){ perror("Erro no write do stats da par-shell: "); } // Fechar o pipe do terminal if(close(fd_write) < 0){ perror("Erro no close do stats da par-shell: "); } strcpy(output,"\0"); continue; } else { int i; // Inteiro temporário usado no ciclo de processamento dos argumentos int pid; // Pid do processo filho criado com fork /** * Processar todos os argumentos que poderá receber */ argumentos[0] = strtok(buffer," "); for(i = 1; i < MAX_ARGS; i++){ argumentos[i] = strtok(NULL," "); } /** * Confirmar se podem ser criados filhos */ mutex_lock(); while (! (nfilhos < MAXPAR)) if(pthread_cond_wait(&podeCriarFilhos,&mutex) != 0){ perror("Erro no pthread_cond_wait na par-shell: "); } mutex_unlock(); /** * Criar processo filho usando fork */ pid = fork(); // Registar tempo de inicio do processo filho time_t starttime = time(NULL); if (pid < 0) { perror("Erro no fork: "); continue; } /** * Código do processo filho */ if (pid == 0) { // Redirecionar o output do processo filho redirect_stdout(); // Evitar que o ctrl+c se propague para o processo filho -> signal é ignorado signal(SIGINT,SIG_IGN); // Trocar código do processo filho pelo do executável if(execv(argumentos[0], argumentos) < 0){ perror("Erro no execv:"); exit(EXIT_FAILURE); } } /** * Código do processo pai */ mutex_lock(); nfilhos++; if(pthread_cond_signal(&podeMonitorizar) != 0){ perror("Erro no pthread_cond_signal na par-shell: "); } insert_new_process(list,pid,starttime); mutex_unlock(); } } } return 0; }
int tarpatch(int argc, char *argv[], const char *flags) { InputStream *is_file1, *is_diff; void (*patch_func)(InputStream *, InputStream *, uint8_t[DS]); char magic_buf[MAGIC_LEN]; uint8_t digest_expected[DS], digest_computed[DS]; assert(MD5_DIGEST_LENGTH == DS); assert(argc == 3); /* Open file 1 */ is_file1 = (strcmp(argv[0], "-") == 0) ? OpenStdinInputStream() : OpenFileInputStream(argv[0]); if (is_file1 == NULL) { fprintf(stderr, "Cannot open file 1 (%s) for reading!\n", argv[0]); exit(EXIT_FAILURE); } /* Open diff file */ is_diff = (strcmp(argv[1], "-") == 0) ? OpenStdinInputStream() : OpenFileInputStream(argv[1]); if (is_diff == NULL) { fprintf(stderr, "Cannot open diff file (%s) for reading!\n", argv[1]); exit(EXIT_FAILURE); } /* Redirect output (if necessary) */ if (strcmp(argv[2], "-") != 0) redirect_stdout(argv[2]); if (is_file1->seek(is_file1, 0)) patch_func = patch_forward; else if (fseeko(stdout, 0, SEEK_SET) == 0) patch_func = patch_backward; else { fprintf(stderr, "Neither file 1 nor file 2 is seekable!\n"); exit(EXIT_FAILURE); } /* Read and verify file magic number */ if ( is_diff->read(is_diff, magic_buf, MAGIC_LEN) != MAGIC_LEN || memcmp(magic_buf, MAGIC_STR, MAGIC_LEN) != 0 ) { fprintf(stderr, "Not a diff file!\n"); exit(EXIT_FAILURE); } patch_func(is_file1, is_diff, digest_computed); /* Read and compare output file digest */ read_data(is_diff, digest_expected, DS); if (memcmp(digest_expected, digest_computed, DS) != 0) { char expected_str[2*DS + 1], computed_str[2*DS + 1]; hexstring(expected_str, digest_expected, DS); hexstring(computed_str, digest_computed, DS); fprintf(stderr, "Output file verification failed!\n" "Original file hash: %s (expected)\n" "New file hash: %s (computed)\n", expected_str, computed_str ); exit(EXIT_FAILURE); } return EXIT_SUCCESS; }
bool redirect() { return redirect_stdout(out_pipe_) && redirect_stdin(in_pipe_); }
bool redirect() { return redirect_stdout(pipe_) != -1; }
int monitor(int argc, char *argv[]) { ty_board *board = NULL; int outfd = -1; int r; int c; while ((c = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) { switch (c) { HANDLE_COMMON_OPTIONS(c, print_monitor_usage); case 's': terminal_flags |= TY_TERMINAL_SILENT; break; case 'r': terminal_flags |= TY_TERMINAL_RAW; break; case 'D': if (strcmp(optarg, "input") == 0) { directions = DIRECTION_INPUT; } else if (strcmp(optarg, "output") == 0) { directions = DIRECTION_OUTPUT; } else if (strcmp(optarg, "both") == 0) { directions = DIRECTION_INPUT | DIRECTION_OUTPUT; } else { ty_log(TY_LOG_ERROR, "--direction must be one off input, output or both"); print_monitor_usage(stderr); return EXIT_FAILURE; } break; case 'b': errno = 0; device_rate = (uint32_t)strtoul(optarg, NULL, 10); if (errno) { ty_log(TY_LOG_ERROR, "--baud requires a number"); print_monitor_usage(stderr); return EXIT_FAILURE; } break; case 'd': device_flags &= ~HS_SERIAL_MASK_CSIZE; if (strcmp(optarg, "5") == 0) { device_flags |= HS_SERIAL_CSIZE_5BITS; } else if (strcmp(optarg, "6") == 0) { device_flags |= HS_SERIAL_CSIZE_6BITS; } else if (strcmp(optarg, "7") == 0) { device_flags |= HS_SERIAL_CSIZE_7BITS; } else if (strcmp(optarg, "8") != 0) { ty_log(TY_LOG_ERROR, "--databits must be one off 5, 6, 7 or 8"); print_monitor_usage(stderr); return EXIT_FAILURE; } case 'f': device_flags &= ~HS_SERIAL_MASK_FLOW; if (strcmp(optarg, "x") == 0 || strcmp(optarg, "xonxoff") == 0) { device_flags |= HS_SERIAL_FLOW_XONXOFF; } else if (strcmp(optarg, "h") == 0 || strcmp(optarg, "rtscts") == 0) { device_flags |= HS_SERIAL_FLOW_RTSCTS; } else if (strcmp(optarg, "n") != 0 && strcmp(optarg, "none") == 0) { ty_log(TY_LOG_ERROR, "--flow must be one off x (xonxoff), h (rtscts) or n (none)"); print_monitor_usage(stderr); return EXIT_FAILURE; } break; case MONITOR_OPTION_NORESET: device_flags |= HS_SERIAL_CLOSE_NOHUP; break; case 'p': device_flags &= ~HS_SERIAL_MASK_PARITY; if (strcmp(optarg, "o") == 0 || strcmp(optarg, "odd") == 0) { device_flags |= HS_SERIAL_PARITY_ODD; } else if (strcmp(optarg, "e") == 0 || strcmp(optarg, "even") == 0) { device_flags |= HS_SERIAL_PARITY_EVEN; } else if (strcmp(optarg, "n") != 0 && strcmp(optarg, "none") != 0) { ty_log(TY_LOG_ERROR, "--parity must be one off o (odd), e (even) or n (none)"); print_monitor_usage(stderr); return EXIT_FAILURE; } break; case 'R': reconnect = true; break; case MONITOR_OPTION_TIMEOUT_EOF: errno = 0; timeout_eof = (int)strtol(optarg, NULL, 10); if (errno) { ty_log(TY_LOG_ERROR, "--timeout requires a number"); print_monitor_usage(stderr); return EXIT_FAILURE; } if (timeout_eof < 0) timeout_eof = -1; break; } } if (argc > optind) { ty_log(TY_LOG_ERROR, "No positional argument is allowed"); print_monitor_usage(stderr); return EXIT_FAILURE; } if (ty_standard_get_modes(TY_STANDARD_INPUT) & TY_DESCRIPTOR_MODE_TERMINAL) { #ifdef _WIN32 if (terminal_flags & TY_TERMINAL_RAW && !(terminal_flags & TY_TERMINAL_SILENT)) { terminal_flags |= TY_TERMINAL_SILENT; if (ty_standard_get_modes(TY_STANDARD_OUTPUT) & TY_DESCRIPTOR_MODE_TERMINAL) fake_echo = true; } /* Unlike POSIX platforms, Windows does not implement the console line editing behavior * at the tty layer. Instead, ReadFile() takes care of it and blocks until return is hit. * The problem is that the Wait functions will return the stdin descriptor as soon as * something is typed but then, ReadFile() will block until return is pressed. * Overlapped I/O cannot be used because it is not supported on console descriptors. * * So the best way I found is to have a background thread handle the blocking ReadFile() * and pass the lines in a buffer. When a new line is entered, the input_available * event is set to signal the poll in loop(). I also tried to use an anonymous pipe to * make it simpler, but the Wait functions do not support them. */ if (directions & DIRECTION_OUTPUT && !(terminal_flags & TY_TERMINAL_RAW)) { r = start_stdin_thread(); if (r < 0) goto cleanup; } #endif r = ty_terminal_setup(terminal_flags); if (r < 0) goto cleanup; } r = redirect_stdout(&outfd); if (r < 0) goto cleanup; r = get_board(&board); if (r < 0) goto cleanup; r = loop(board, outfd); cleanup: #ifdef _WIN32 stop_stdin_thread(); #endif ty_board_unref(board); return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; }