static char *fetchline(void) { static EditLine *el; static History *hist; HistEvent hevent; char *line; int count; if (!el) { hist = history_init(); history(hist, &hevent, H_SETSIZE, 100); el = el_init(progname, stdin, stdout, stderr); el_source(el, NULL); el_set(el, EL_SIGNAL, 1); el_set(el, EL_PROMPT, el_get_prompt); el_set(el, EL_HIST, history, (const char *)hist); } line = strdup(el_gets(el, &count)); if (line) { if (count > 0) { line[count-1] = '\0'; } if (*line) { history(hist, &hevent, H_ENTER, line); } } return line; }
/* Prompt for input with the level of current nest (block nest depth) */ static char *readline(cchar *msg) { HistEvent ev; cchar *str; char *result; ssize len; int count; if (eh == NULL) { eh = initEditLine(); } prompt = msg; el_set(eh, EL_PROMPT, issuePrompt); el_set(eh, EL_SIGNAL, 1); str = el_gets(eh, &count); if (str && count > 0) { result = strdup(str); len = slen(result); if (result[len - 1] == '\n') { result[len - 1] = '\0'; } count = history(cmdHistory, &ev, H_ENTER, result); return result; } return NULL; }
std::string EditLine::gets() { int count; const char* c = el_gets(el, &count); if(c == 0) { safe_exit(0); } std::string s = c; return s.substr(0, s.size() - 1); }
static int preadfd(void) { int nr; parsenextc = parsefile->buf; #ifndef NO_HISTORY if (el != NULL && gotwinch) { gotwinch = 0; el_resize(el); } #endif retry: #ifndef NO_HISTORY if (parsefile->fd == 0 && el) { static const char *rl_cp; static int el_len; if (rl_cp == NULL) rl_cp = el_gets(el, &el_len); if (rl_cp == NULL) nr = 0; else { nr = el_len; if (nr > BUFSIZ) nr = BUFSIZ; memcpy(parsenextc, rl_cp, nr); if (nr != el_len) { el_len -= nr; rl_cp += nr; } else rl_cp = NULL; } } else #endif nr = read(parsefile->fd, parsenextc, BUFSIZ); if (nr <= 0) { if (nr < 0) { if (errno == EINTR) goto retry; if (parsefile->fd == 0 && errno == EWOULDBLOCK) { int flags = fcntl(0, F_GETFL, 0); if (flags >= 0 && flags & O_NONBLOCK) { flags &=~ O_NONBLOCK; if (fcntl(0, F_SETFL, flags) >= 0) { out2fmt_flush("sh: turning off NDELAY mode\n"); goto retry; } } } } nr = -1; } return nr; }
IoObject *IoEditLine_readLine(IoEditLine *self, IoObject *locals, IoMessage *m) { int count = 0; const char *line = NULL; DATA(self)->prompt = IoMessage_locals_symbolArgAt_(m, locals, 0); line = el_gets(DATA(self)->editline, &count); if (line && count >= 0) return IOSEQ(line, (size_t)count); else return IONIL(self); }
const char * EditLineReader::readLine(const char *prompt, const char *input) { _prompt = prompt; el_push(_editLine, input); int n; const char *line = el_gets(_editLine, &n); if (line) history(_history, &_event, H_ENTER, line); return line; }
const char* CliContext::PromptUser(const char* prompt) { fPrompt = prompt; int count; const char* line = el_gets(fEditLine, &count); fPrompt = NULL; ProcessPendingEvents(); return line; }
static int preadfd(void) { int nr; parsenextc = parsefile->buf; #if !defined(NO_HISTORY) if (el != NULL && gotwinch) { gotwinch = 0; el_resize(el); } #endif retry: #ifndef NO_HISTORY if (parsefile->fd == 0 && el) { const char *rl_cp; rl_cp = el_gets(el, &nr); if (rl_cp == NULL) nr = 0; else { /* XXX - BUFSIZE should redesign so not necessary */ (void) strcpy(parsenextc, rl_cp); } } else #endif nr = read(parsefile->fd, parsenextc, BUFSIZ - 1); if (nr <= 0) { if (nr < 0) { if (errno == EINTR) goto retry; #ifdef EWOULDBLOCK if (parsefile->fd == 0 && errno == EWOULDBLOCK) { int flags = fcntl(0, F_GETFL, 0); if (flags >= 0 && flags & O_NONBLOCK) { flags &=~ O_NONBLOCK; if (fcntl(0, F_SETFL, flags) >= 0) { out2str("sh: turning off NDELAY mode\n"); goto retry; } } } #endif /* EWOULDBLOCK */ } nr = -1; } return nr; }
/* * This is a simple wrapper for el_gets(), allowing our SIGUSR1 signal * handler (above) to take effect only after we've done a setjmp(). * * We don't want it to do anything outside of here as we're going to * service the ppp descriptor anyway. */ static const char * SmartGets(EditLine *e, int *count, int fd) { const char *result; if (setjmp(pppdead)) result = NULL; else { data = fd; if (want_sem_post) /* Let the Monitor thread in again */ sem_post(&sem_select); result = el_gets(e, count); } data = -1; return result; }
int main(int argc, char **argv) { EditLine *el; History *hist; const char *buf; int num, state; check_args(argc, argv); if(connect_uri) { sql_conn = sql_connect(connect_uri); if(!sql_conn) { fprintf(stderr, "%s: [%s] %s\n", short_program_name, sql_sqlstate(NULL), sql_error(NULL)); exit(EXIT_FAILURE); } } fprintf(stderr, "%s interactive SQL shell (%s)\n\n", PACKAGE, VERSION); fprintf(stderr, "Type: \\c URI to establish a new connection\n" " \\g or ; to execute query\n" " \\G to execute the query showing results in long format\n" " \\q to end the SQL session\n" "\n" ); hist = history_init(); el = el_init(argv[0], stdin, stdout, stderr); el_set(el, EL_EDITOR, "emacs"); el_set(el, EL_SIGNAL, 1); el_set(el, EL_PROMPT, prompt); el_set(el, EL_HIST, history, hist); el_source(el, NULL); while((buf = el_gets(el, &num)) != NULL && num != 0) { state = parse_query(buf); if(state == 0) { exec_queries(hist); } } return 0; }
static void _commandLine(struct Debugger* debugger) { struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger; const char* line; _printStatus(cliDebugger, 0); int count = 0; HistEvent ev; while (debugger->state == DEBUGGER_PAUSED) { line = el_gets(cliDebugger->elstate, &count); if (!line) { return; } if (line[0] == '\n') { if (history(cliDebugger->histate, &ev, H_FIRST) >= 0) { _parse(cliDebugger, ev.str, strlen(ev.str) - 1); } } else { _parse(cliDebugger, line, count - 1); history(cliDebugger->histate, &ev, H_ENTER, line); } } }
char * readline(const char* prompt) { static EditLine *e; #ifdef H_SETSIZE HistEvent ev; #endif int count; const char *str; if(e == NULL){ #ifdef EL_INIT_FOUR e = el_init("", stdin, stdout, stderr); #else e = el_init("", stdin, stdout); #endif el_set(e, EL_PROMPT, ret_prompt); h = history_init(); #ifdef H_SETSIZE history(h, &ev, H_SETSIZE, 25); #else history(h, H_EVENT, 25); #endif el_set(e, EL_HIST, history, h); el_set(e, EL_EDITOR, "emacs"); /* XXX? */ } pr = prompt ? prompt : ""; str = el_gets(e, &count); if (str && count > 0) { char *ret = strdup (str); if (ret == NULL) return NULL; if (ret[strlen(ret) - 1] == '\n') ret[strlen(ret) - 1] = '\0'; return ret; } return NULL; }
static char * getLine(char *buf, int len, InputRef src) { int n; if (src->el) { int count; const char *line; line = el_gets(src->el, &count); if (line == NULL) return NULL; strncpy(buf, line, len); } else { if (fgets(buf, len, src->fp) == NULL) return NULL; } n = strlen(buf); if (buf[n-1] == '\n') { /* the entire line fit in the buffer, remove the newline */ buf[n-1] = '\0'; } else if (!src->el) { /* eat the remainder of the line */ do { n = fgetc(src->fp); } while ((n != '\n') && (n != EOF)); } if (src->h && (buf[0] != '\0')) { HistEvent ev; history(src->h, &ev, H_ENTER, buf); } return buf; }
smartgets(int *count, int fd) #endif { const char *result; data = fd; signal(SIGALRM, check_fd); ualarm(500000, 500000); result = setjmp(pppdead) ? NULL : #ifdef HAVE_LIBEDIT el_gets(e, count); #else readline(prompt); if (result != NULL) *count = strlen(result); #endif ualarm(0,0); signal(SIGALRM, SIG_DFL); data = -1; return result; }
repl::repl(FILE * in, FILE * out, CommandHandler handler) noexcept { auto t = new std::thread([=]() { init_editline(in, out); const char * line; int length; io::log::info("init done"); while((line = el_gets(el, &length))) { io::log::info("got line: {}", line); // io::log::info("el->el_flags | NO_TTY {}", el->el_flags&0x02); if(length > 1) { history(hist, &ev, H_ENTER, line); } } history_end(hist); el_end(el); fclose(in); fclose(out); }); }
char *cli_query_str(char *s, int size, const char *prompt) { const char *line; int read, read_length; set_query_prompt(prompt); line = el_gets(el, &read); clear_query_prompt(); if (!line) return ""; strncpy(s, line, size); s[size-1] = '\0'; //forcing NULL /* Strip line-feed character */ read_length = strlen(s); if (read_length > 0 && s[read_length-1] == '\n') { s[read_length-1] = '\0'; //forcing NULL } return s; }
char *x_readline(const char *prompt) { static char buffer[1024]; int count = 0; const char *cp; if (!el) { hist = history_init(); history(hist, &ev, H_SETSIZE, HISTORY_SIZE); history(hist, &ev, H_SETUNIQUE, 1); el = el_init("GS+", stdin, stdout, stderr); el_set(el, EL_EDITOR, "emacs"); el_set(el, EL_BIND, "-e", NULL, NULL, NULL); el_set(el, EL_HIST, history, hist); el_set(el, EL_PROMPT, prompt_fn); el_set(el, EL_SIGNAL, 1); el_source(el, NULL); } el_prompt = prompt; cp = el_gets(el, &count); el_prompt = NULL; if (count <= 0) { if (prompt) fputc('\n', stdout); return NULL; } if (count > sizeof(buffer) - 1) return ""; memcpy(buffer, cp, count); cleanup_buffer(buffer, count); if (*buffer) history(hist, &ev, H_ENTER, buffer); return buffer; }
void interact( const char *const argv_0) { EditLine *const el = el_init(argv_0, stdin, stdout, stderr); el_set(el, EL_PROMPT, &prompt); el_set(el, EL_EDITOR, "emacs"); History *const hist = history_init(); if (!hist) { fprintf(stderr, "Could not initalize history\n"); exit(EXIT_FAILURE); } HistEvent ev; history(hist, &ev, H_SETSIZE, 100); el_set(el, EL_HIST, history, hist); const pid_t child_pid = _gen_child(); verbose_printf("child process is %d\n", child_pid); if (options.verbose) help(); char buf[PAGE_SIZE]; size_t buf_sz = 0; int end = 0; struct proc_info_t info = {}; ARCH_INIT_PROC_INFO(info); ptrace_launch(child_pid); ptrace_cont(child_pid, &info); ptrace_reap(child_pid, &info); display(&info); for (;;) { int count; const char *const line = el_gets(el, &count); if (count == -1) { perror("el_gets"); exit(EXIT_FAILURE); } // count is 0 == ^d if (!count || strcasestr(line, ".quit") || strcasestr(line, ".exit")) break; // We have input, add it to the our history history(hist, &ev, H_ENTER, line); // If we start with a ., we have a command if (line[0] == '.') { if (strcasestr(line, "help")) { help(); continue; } if (strcasestr(line, "info")) { display(&info); continue; } if (strcasestr(line, "showmap")) { char cmd[PATH_MAX] = { 0 }; snprintf(cmd, sizeof(cmd), "cat /proc/%d/maps", child_pid); if (system(cmd)) fprintf(stderr, "sh: %s failed\n", cmd); continue; } if (strcasestr(line, "read")) { ui_read(child_pid, line); continue; } if (strcasestr(line, "write")) { continue; } if (strcasestr(line, "begin")) { in_block = 1; continue; } // Note the lack of continue. Need to fall through... if (strcasestr(line, "end")) { in_block = 0; end = 1; } } if (buf_sz + count > sizeof(buf)) { printf("Buffer full (max: 0x%lx), please use '.end'\n", sizeof(buf)); continue; } // Since we fell through, we want to avoid adding adding .end to our buffer if (!end) { memcpy(buf + buf_sz, line, count); buf_sz += count; } if (!in_block) { verbose_printf("Trying to assemble(%zu):\n%s", buf_sz, buf); uint8_t bytecode[PAGE_SIZE]; const size_t bytecode_sz = assemble(bytecode, sizeof(bytecode), buf, buf_sz); memset(buf, 0, sizeof(buf)); buf_sz = 0; end = 0; verbose_printf("Got asm(%zu):\n", bytecode_sz); verbose_dump(bytecode, bytecode_sz, -1); if (!bytecode_sz) { fprintf(stderr, "'%s' assembled to 0 length bytecode\n", buf); continue; } ptrace_write(child_pid, (void *)options.start, bytecode, bytecode_sz); ptrace_reset(child_pid, options.start); ptrace_cont(child_pid, &info); ptrace_reap(child_pid, &info); display(&info); } } ptrace_detatch(child_pid, &info); printf("\n"); history_end(hist); el_end(el); }
/* * Command parser. */ static void cmdscanner(void) { register struct cmd *c; static EditLine *el; static History *hist; HistEvent he; size_t len; int num; const char *bp; num = 0; bp = NULL; el = NULL; hist = NULL; for (;;) { if (fromatty) { if (!el) { el = el_init("lpc", stdin, stdout, stderr); hist = history_init(); history(hist, &he, H_SETSIZE, 100); el_set(el, EL_HIST, history, hist); el_set(el, EL_EDITOR, "emacs"); el_set(el, EL_PROMPT, lpc_prompt); el_set(el, EL_SIGNAL, 1); el_source(el, NULL); /* * EditLine init may call 'cgetset()' to set a * capability-db meant for termcap (eg: to set * terminal type 'xterm'). Reset that now, or * that same db-information will be used for * printcap (giving us an "xterm" printer, with * all kinds of invalid capabilities...). */ cgetset(NULL); } if ((bp = el_gets(el, &num)) == NULL || num == 0) quit(0, NULL); len = (num > MAX_CMDLINE - 1) ? MAX_CMDLINE - 1 : num; memcpy(cmdline, bp, len); cmdline[len] = 0; history(hist, &he, H_ENTER, bp); } else { if (fgets(cmdline, MAX_CMDLINE, stdin) == NULL) quit(0, NULL); if (cmdline[0] == 0 || cmdline[0] == '\n') break; } makeargv(); if (margc == 0) continue; if (el != NULL && el_parse(el, margc, margv) != -1) continue; c = getcmd(margv[0]); if (c == (struct cmd *)-1) { printf("?Ambiguous command\n"); continue; } if (c == NULL) { printf("?Invalid command\n"); continue; } if ((c->c_opts & LPC_PRIVCMD) && getuid() && ingroup(LPR_OPER) == 0) { printf("?Privileged command\n"); continue; } /* * Two different commands might have the same generic rtn * (eg: "clean" and "tclean"), and just use different * handler routines for distinct command-setup. The handler * routine might also be set on a generic routine for * initial parameter processing. */ if (c->c_generic != NULL) generic(c->c_generic, c->c_opts, c->c_handler, margc, margv); else (*c->c_handler)(margc, margv); } }
void CommandPrompt::execute() { for (;;) { #ifdef ZORBA_HAVE_LIBEDIT_H const char* lBuf; int lCharsRead = -1; lBuf = el_gets(theEditLine, &lCharsRead); std::string lCommandLine(lBuf, lCharsRead - 1); #else bool lWithOutput = true; if (lWithOutput) { std::cout << "(xqdb) "; } lWithOutput = true; std::string lCommandLine; std::getline(std::cin, lCommandLine); if (std::cin.fail()) { lWithOutput = false; std::cin.clear(); continue; } #endif std::vector<std::string> lArgs; // split the command into arguments parseLine(lCommandLine, lArgs); std::string::size_type lSize = lArgs.size(); // empty command? do nothing! if (lSize == 0) { lArgs = theLastArgs; if (lArgs.size() == 0) { continue; } } #ifdef ZORBA_HAVE_LIBEDIT_H else { HistEvent lHistoryEvent; history(theHistory, &lHistoryEvent, H_ENTER, lCommandLine.c_str()); } #endif theLastArgs = lArgs; UntypedCommand* lCommand = NULL; // help is not a command but a hook here if (lArgs.at(0) == "h" || lArgs.at(0) == "help") { std::string lCmd = ""; // if the user needs the help for a specific command if (lSize > 1) { // do nothing if we don't have a command starting with this prefix? // findCommand will print the appropriate errors if (!findCommand(lArgs[1], lCommand)) { continue; } } printHelp(lCommand); continue; } if (findCommand(lArgs[0], lCommand) && lCommand->execute(lArgs)) { return; } continue; } }
int main(int argc, char *argv[]) { int port = DEFAULT_PORT; /* Port number to listen for connections */ int ssocket = 0; /* Socket file descriptor */ int debug_once = 1; /* Whether to allow more than one debug session (1 = no) */ struct sockaddr_in server_in; struct sockaddr_in client_in; socklen_t client_in_len; int fd; /* Filedescriptor for userinput */ fd_buf cxt = { NULL, 0 }; struct in_addr *iaddr; char *buffer; /* Buffer with data from the server */ char *cmd; /* Command to send to the server */ char *prev_cmd = NULL; /* Last send command to the server */ int length; /* Length of read buffer */ #ifndef WIN32 int opt; /* Current option during parameter parsing */ #endif #ifdef HAVE_LIBEDIT int num = 0; /* Add SIGTERM signal handler */ signal (SIGTERM, handle_sigterm); initialize_libedit (argv[0]); #else fd_buf std_in = { NULL, 0 }; #endif #ifdef WIN32 /* Initialise Windows' WinSock library */ WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(2, 2); WSAStartup(wVersionRequested, &wsaData); #endif /* Display copyright notice and version number */ printf("Xdebug Simple DBGp client (%s)\n", DEBUGCLIENT_VERSION); printf("Copyright 2002-2007 by Derick Rethans.\n"); #ifdef HAVE_LIBEDIT printf("- libedit support: enabled\n"); #endif #ifndef WIN32 /* Option handling */ while (1) { opt = getopt(argc, argv, "hp:v1"); if (opt == -1) { break; } switch (opt) { case 'h': printf("\nUsage:\n"); printf("\tdebugclient [-h] [-p port] [-v]\n"); printf("\t-h\tShow this help\n"); printf("\t-p\tSpecify the port to listen on (default = 9000)\n"); printf("\t-v\tShow version number and exit\n"); printf("\t-1\tDebug once and then exit\n"); exit(0); break; case 'v': exit(0); break; case 'p': port = atoi(optarg); printf("Listening on TCP port %d.\n", port); break; case '1': debug_once = 0; break; } } #endif /* Main loop that listens for connections from the debug client and that * does all the communications handling. */ do { ssocket = socket(AF_INET, SOCK_STREAM, 0); if (ssocket < 0) { fprintf(stderr, "socket: couldn't create socket\n"); exit(-1); } memset(&server_in, 0, sizeof(struct sockaddr)); server_in.sin_family = AF_INET; server_in.sin_addr.s_addr = htonl(INADDR_ANY); server_in.sin_port = htons((unsigned short int) port); memset(&client_in, 0, sizeof(client_in)); client_in_len = sizeof(client_in); /* Loop until we can bind to the listening socket. */ while (bind(ssocket, (struct sockaddr *) &server_in, sizeof(struct sockaddr_in)) < 0) { fprintf(stderr, "bind: couldn't bind AF_INET socket?\n"); sleep(5); } if (listen(ssocket, 0) == -1) { fprintf(stderr, "listen: listen call failed\n"); exit(-2); } printf("\nWaiting for debug server to connect.\n"); #ifdef WIN32 fd = accept(ssocket, (struct sockaddr *) &client_in, NULL); if (fd == -1) { printf("accept: %d\n", WSAGetLastError()); exit(-3); } #else fd = accept(ssocket, (struct sockaddr *) &client_in, &client_in_len); if (fd == -1) { perror("accept"); exit(-3); } #endif close(ssocket); iaddr = &client_in.sin_addr; printf("Connect\n"); /* Get the message from the server*/ while ((buffer = fd_read_line_delim(fd, &cxt, FD_RL_SOCKET, '\0', &length)) > 0) { buffer = fd_read_line_delim(fd, &cxt, FD_RL_SOCKET, '\0', &length); printf ("%s\n", buffer); if (strstr(buffer, "<stream") == NULL) { /* The server requires a new command */ #ifdef HAVE_LIBEDIT /* Copy the prompt string */ sprintf(prompt, "(cmd) "); if ((cmd = (char *) el_gets(el, &num)) != NULL && num != 0) { /* Add command to history */ #ifdef XDC_OLD_LIBEDIT history(hist, H_ENTER, cmd); #else history(hist, &ev, H_ENTER, cmd); #endif /* We overwrite the \n with \0 for libedit builds */ cmd[strlen(cmd) - 1] = '\0'; #else printf("(cmd) "); fflush(stdout); if ((cmd = fd_read_line(0, &std_in, FD_RL_FILE))) { #endif /* If there is a 'previous' command, and when the command * just consists of an "enter", then we set the command to * the previous command. */ if (prev_cmd && ((strlen(cmd) == 0) || (strlen(cmd) == 1 && cmd[0] == '\n'))) { cmd = prev_cmd; } else { if (prev_cmd) { free(prev_cmd); } prev_cmd = strdup(cmd); } /* Send the command to the debug server */ if (send(fd, cmd, strlen(cmd), MSG_NOSIGNAL) == -1) { break; } if (send(fd, "\0", 1, MSG_NOSIGNAL) == -1) { break; } /* If cmd is quit exit from while */ if (strncmp(cmd, "quit", 4) == 0) { break; } } } } printf("Disconnect\n\n"); close(fd); if (prev_cmd) { free(prev_cmd); prev_cmd = NULL; } /* Sleep some time to reset the TCP/IP connection */ sleep(1); } while (debug_once); }
int cmdloop(void *arg) { struct clitenv *env = arg; EditLine *el = env->el; History *hist = env->hist; const char *elline; int cnt; char **argv; int maxargs = 16; /* XXX */ int stop; stop = 0; if ((argv = calloc(sizeof(char *), maxargs)) == NULL) err(1, "malloc"); while (!stop && (elline = el_gets(el, &cnt)) != NULL) { char *line, *orgline; struct c**t *cmdp; char **ap; int argc, res; HistEvent ev; memset(argv, 0, sizeof(char *) * maxargs); history(hist, &ev, H_ENTER, elline); orgline = line = strdup(elline); if (line == NULL) err(1, "strdup"); argc = 0; for (ap = argv; (*ap = strsep(&line, " \t\n")) != NULL;) { if (**ap != '\0') { ++ap; if (++argc == maxargs) break; } } if (argc == maxargs) { fprintf(stderr, "Too many arguments\n"); goto cmdout; } if (!argc) goto cmdout; /* * Editline commands. */ if (el_parse(el, argc, (const char **)argv) != -1) goto cmdout; if ((res = name_to_cmd(argv[0], env->cmds, env->ncmds, &cmdp)) == 1) { if (argc - 1 > cmdp->maxargc) fprintf(stderr, "Too many arguments\n"); else if (argc - 1 < cmdp->minargc) fprintf(stderr, "Too few arguments\n"); else stop = (*cmdp->handler)(argc, argv, cmdp->arg ? cmdp->arg : env); } else { fprintf(stderr, "%s command: %s\n", res == 0 ? "unknown" : "ambiguous", argv[0]); } cmdout: free(orgline); } free(argv); return stop; }
int main(int argc, char *argv[]) { int num, err_nbr; int last_char_idx; char *buf; sys_user_auth_type setting; struct passwd *passwd; char *tmp_ssh_server_addr, *tmp_ssh_client_addr; int tmp_ssh_server_port, tmp_ssh_client_port; openlog ( "cli", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH ); num = atexit(bye); if (num != 0) { fprintf(stderr, "cannot set exit function\n"); return EXIT_FAILURE; } /* * Handle SIGINT to disable it's action on the CLI. * Do not use SIGINT because it is inherited by the * process children. (i.e. fork(), vfork(), system()). */ signal(SIGINT, signalHandlerInt); signal(SIGTERM, __quit_handler); signal(SIGHUP, hup_handler); parse_cmd_line(argc, argv); acc_el_initialize(); #ifdef ACCEDIAN_CONFIG_DISCOVERY_ENABLED if (acd_cap_discovery()) { discovery_module_init(); } #endif #ifndef ACCEDIAN_SIM_I386 port_system_state_t sys_state = PORT_SYSTEM_STATE_UNKNOWN; FILE *fpInit = fopen("/tmp/init_complete","r"); if(!fpInit) { printf("The system is not ready yet\n"); // Initialization sequence is not stellar, we need the IPCs to logout. (ref. #7737) cmd_initialize(&cli_backend_handle); exit(-1); } else { fclose(fpInit); } #endif #ifdef ACCEDIAN_SIM_I386 sim_get_hostname(); #endif cli_register_all_commands(); //if(1) { /* CLI was spawned from command prompt. Need to get a session ID. */ if (session_id == 0) { memset(&setting, 0, sizeof(setting)); /* Change root to admin because we don't want to deal with root user in config */ /* AN ISSUE ONLY FOR DEV LOADS! */ if (getuid() == 0) { strcpy(setting.username, "admin"); } else { passwd = getpwuid(getuid()); strcpy(setting.username, passwd->pw_name); } strcpy(setting.password, "ignored");/* Ignored. syd_cmd_login */ strcpy(setting.host, "root_dev"); /* does not authenticate */ setting.session_type = ACC_SESSION_CLI; sys_cmd_login(cli_backend_handle, &setting); GET_CMD_ERRNO(cli_backend_handle, err_nbr); if (err_nbr != GEN_NO_ERROR) { cli_perror(cmd_get_error_string(err_nbr)); exit (-1); } session_id = setting.session_id; } } cliLogCommand("New Session"); #ifndef ACCEDIAN_SIM_I386 /* Get the interface IPv4 or IPv6 address this CLI instance is running on... */ buf = getenv("SSH_CONNECTION"); if(buf != NULL) { tmp_ssh_server_addr = (char *)malloc(strlen(buf)+1); tmp_ssh_client_addr = (char *)malloc(strlen(buf)+1); if(sscanf(buf, "%s %d %s %d\n", tmp_ssh_server_addr, &tmp_ssh_server_port, tmp_ssh_client_addr, &tmp_ssh_client_port) != 4) { printf("Failed to fetch interface IP address.\n"); } else { if(inet_pton(AF_INET6, tmp_ssh_client_addr, ¤t_ipv6_intf) != 1) { /* Trying to convert IPv6 address. */ if(inet_pton(AF_INET, tmp_ssh_client_addr, ¤t_intf) != 1) { /* IPv6 failed, trying to convert IPv4 address. */ printf("Failed to convert interface IPv4/IPv6 address.\n"); } else if(inet_ntop(AF_INET, ¤t_intf, current_str_intf, sizeof(current_str_intf)) == NULL) { /* IPv4 detected, trying to reconvert the address. */ printf("Failed to reconvert interface IPv4 address.\n"); } } else if(current_ipv6_intf.s6_addr32[0] == 0 && current_ipv6_intf.s6_addr32[1] == 0 && current_ipv6_intf.s6_addr32[2] == 0xffff) { /* IPv6 detected, verifying if this is a IPv4-mapped address. */ current_intf = current_ipv6_intf.s6_addr32[3]; if(inet_ntop(AF_INET, ¤t_intf, current_str_intf, sizeof(current_str_intf)) == NULL) { /* IPv4-mapped detected, trying to reconvert the address. */ printf("Failed to reconvert interface IPv4-mapped address.\n"); } } else if(inet_ntop(AF_INET6, ¤t_ipv6_intf, current_str_intf, sizeof(current_str_intf)) == NULL) { /* IPv6 detected, trying to reconvert the address. */ printf("Failed to reconvert interface IPv6 address.\n"); } } free(tmp_ssh_server_addr); free(tmp_ssh_client_addr); } if ( port_cmd_get_system_state(cli_backend_handle, &sys_state) ) { if ( sys_state != PORT_SYSTEM_SYSTEM_READY ) { printf("System not ready. Firmware upgrade in progress.\n"); } } #endif // Start thread checking on the session validity (#8011) if (ACD_TRUE != init_cli_check_session_thread()) { printf("CLI initialization failure.\n"); syslog(LOG_ERR, "Could not initialize CLI thread"); quit_handler(0,0); } for (;;) { buf = (char *)el_gets(el, &num); if (buf) { int offset = 0; //Fix to strip command header from Nakina EMS, when using CLICommand object. if((unsigned char)buf[0] == 0xff && (unsigned char)buf[1] == 0xfb && buf[2] == 0x1) { //Skip escape sequence offset = 3; } // Strip LF character (0x0A); (ex.: "string\n", "string\r\n") last_char_idx = strlen(buf)-1; if (last_char_idx >= 0 && buf[last_char_idx] == '\n') { buf[last_char_idx] = '\0'; } // Strip CR character (0x0D) last_char_idx = strlen(buf)-1; if (last_char_idx >= 0 && buf[last_char_idx] == '\r') { buf[last_char_idx] = '\0'; } // Execute command consolehandler(&buf[offset]); // This is a fix made for support of the SSH connection with Nakina // When connection has no TTY, send prompt after command result. // Don't send prompt if the buffer is empty. if(!el_is_tty(el) && buf[offset] != 0) { printf("ACCEDIAN:>"); } //Invalid, el_gets() cannot unblock with 0 bytes in NO_TTY mode. This means connection was lost, exit now. if(!el_is_tty(el) && num==0 && offset==0) { syslog(LOG_NOTICE, "CLI session terminated, connection loss with EMS.\n"); quit_handler(0,0); } } else { if (write(STDOUT_FILENO, "\nUse EXIT or QUIT to exit\n", strlen("\nUse EXIT or QUIT to exit\n")) < 0) { /* Whoa, stdout disappeared from under us... Make /dev/null's */ int fd; fd = open("/dev/null", O_RDWR); if (fd > -1) { dup2(fd, STDOUT_FILENO); dup2(fd, STDIN_FILENO); } else printf("Failed to open /dev/null to recover from dead console. Bad things will happen!\n"); break; } } } return 0; }
int main(int argc, char *argv[]) { EditLine *el = NULL; int num; const char *buf; Tokenizer *tok; #if 0 int lastevent = 0; #endif int ncontinuation; History *hist; HistEvent ev; (void) setlocale(LC_CTYPE, ""); (void) signal(SIGINT, sig); (void) signal(SIGQUIT, sig); (void) signal(SIGHUP, sig); (void) signal(SIGTERM, sig); hist = history_init(); /* Init the builtin history */ /* Remember 100 events */ history(hist, &ev, H_SETSIZE, 100); tok = tok_init(NULL); /* Initialize the tokenizer */ /* Initialize editline */ el = el_init(*argv, stdin, stdout, stderr); el_set(el, EL_EDITOR, "vi"); /* Default editor is vi */ el_set(el, EL_SIGNAL, 1); /* Handle signals gracefully */ el_set(el, EL_PROMPT_ESC, prompt, '\1');/* Set the prompt function */ /* Tell editline to use this history interface */ el_set(el, EL_HIST, history, hist); /* Add a user-defined function */ el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete); /* Bind tab to it */ el_set(el, EL_BIND, "^I", "ed-complete", NULL); /* * Bind j, k in vi command mode to previous and next line, instead * of previous and next history. */ el_set(el, EL_BIND, "-a", "k", "ed-prev-line", NULL); el_set(el, EL_BIND, "-a", "j", "ed-next-line", NULL); /* * Source the user's defaults file. */ el_source(el, NULL); while ((buf = el_gets(el, &num)) != NULL && num != 0) { int ac, cc, co; #ifdef DEBUG int i; #endif const char **av; const LineInfo *li; li = el_line(el); #ifdef DEBUG (void) fprintf(stderr, "==> got %d %s", num, buf); (void) fprintf(stderr, " > li `%.*s_%.*s'\n", (li->cursor - li->buffer), li->buffer, (li->lastchar - 1 - li->cursor), (li->cursor >= li->lastchar) ? "" : li->cursor); #endif if (gotsig) { (void) fprintf(stderr, "Got signal %d.\n", (int)gotsig); gotsig = 0; el_reset(el); } if (!continuation && num == 1) continue; ac = cc = co = 0; ncontinuation = tok_line(tok, li, &ac, &av, &cc, &co); if (ncontinuation < 0) { (void) fprintf(stderr, "Internal error\n"); continuation = 0; continue; } #ifdef DEBUG (void) fprintf(stderr, " > nc %d ac %d cc %d co %d\n", ncontinuation, ac, cc, co); #endif #if 0 if (continuation) { /* * Append to the right event in case the user * moved around in history. */ if (history(hist, &ev, H_SET, lastevent) == -1) err(1, "%d: %s", lastevent, ev.str); history(hist, &ev, H_ADD , buf); } else { history(hist, &ev, H_ENTER, buf); lastevent = ev.num; } #else /* Simpler */ history(hist, &ev, continuation ? H_APPEND : H_ENTER, buf); #endif continuation = ncontinuation; ncontinuation = 0; if (continuation) continue; #ifdef DEBUG for (i = 0; i < ac; i++) { (void) fprintf(stderr, " > arg# %2d ", i); if (i != cc) (void) fprintf(stderr, "`%s'\n", av[i]); else (void) fprintf(stderr, "`%.*s_%s'\n", co, av[i], av[i] + co); } #endif if (strcmp(av[0], "history") == 0) { int rv; switch (ac) { case 1: for (rv = history(hist, &ev, H_LAST); rv != -1; rv = history(hist, &ev, H_PREV)) (void) fprintf(stdout, "%4d %s", ev.num, ev.str); break; case 2: if (strcmp(av[1], "clear") == 0) history(hist, &ev, H_CLEAR); else goto badhist; break; case 3: if (strcmp(av[1], "load") == 0) history(hist, &ev, H_LOAD, av[2]); else if (strcmp(av[1], "save") == 0) history(hist, &ev, H_SAVE, av[2]); break; badhist: default: (void) fprintf(stderr, "Bad history arguments\n"); break; } } else if (el_parse(el, ac, av) == -1) { switch (fork()) { case 0: execvp(av[0], __DECONST(char **, av)); perror(av[0]); _exit(1); /*NOTREACHED*/ break; case -1: perror("fork"); break; default: if (wait(&num) == -1) perror("wait"); (void) fprintf(stderr, "Exit %x\n", num); break; } } tok_reset(tok); } el_end(el); tok_end(tok); history_end(hist); return (0); }
static int cmdloop(void) { char *line = NULL; const char *elline; int cmd_argc, rval = 0, known; #define scratch known char **cmd_argv; struct cmdtable *cmdp; History *hist; EditLine *elptr; HistEvent hev; curinode = ginode(ROOTINO); curinum = ROOTINO; printactive(); hist = history_init(); history(hist, &hev, H_SETSIZE, 100); /* 100 elt history buffer */ elptr = el_init(__progname, stdin, stdout, stderr); el_set(elptr, EL_EDITOR, "emacs"); el_set(elptr, EL_PROMPT, prompt); el_set(elptr, EL_HIST, history, hist); el_source(elptr, NULL); while ((elline = el_gets(elptr, &scratch)) != NULL && scratch != 0) { if (debug) printf("command `%s'\n", line); history(hist, &hev, H_ENTER, elline); line = strdup(elline); if (line == NULL) errx(1, "out of memory"); cmd_argv = crack(line, &cmd_argc); if (cmd_argc) { /* * el_parse returns -1 to signal that it's not been handled * internally. */ if (el_parse(elptr, cmd_argc, (const char **)cmd_argv) != -1) continue; known = 0; for (cmdp = cmds; cmdp->cmd; cmdp++) { if (!strcmp(cmdp->cmd, cmd_argv[0])) { if (cmd_argc >= cmdp->minargc && cmd_argc <= cmdp->maxargc) rval = (*cmdp->handler)(cmd_argc, cmd_argv); else rval = argcount(cmdp, cmd_argc, cmd_argv); known = 1; break; } } if (!known) { warnx("unknown command `%s'", cmd_argv[0]); rval = 1; } } else rval = 0; free(line); if (rval < 0) return rval; if (rval) warnx("rval was %d", rval); } el_end(elptr); history_end(hist); return rval; }
int main(int argc, char **argv) { int error, i, quit; int curx, cury, maxx, maxy, line_len, loop, max_flen; struct devstat *gsp, *gsq; void *sp, *sq; double dt; struct timespec tp, tq; struct gmesh gmp; struct gprovider *pp; struct gconsumer *cp; struct gident *gid; regex_t f_re, tmp_f_re; short cf, cb; char *p; char f_s[100], pf_s[100], tmp_f_s[100]; const char *line; long double ld[13]; uint64_t u64; EditLine *el; History *hist; HistEvent hist_ev; hist = NULL; el = NULL; maxx = -1; curx = -1; loop = 1; /* Turn on batch mode if output is not tty. */ if (!isatty(fileno(stdout))) flag_b = 1; f_s[0] = '\0'; while ((i = getopt(argc, argv, "abdcf:I:op")) != -1) { switch (i) { case 'a': flag_a = 1; break; case 'b': flag_b = 1; break; case 'c': flag_c = 1; break; case 'd': flag_d = 1; break; case 'f': if (strlen(optarg) > sizeof(f_s) - 1) errx(EX_USAGE, "Filter string too long"); if (regcomp(&f_re, optarg, REG_EXTENDED) != 0) errx(EX_USAGE, "Invalid filter - see re_format(7)"); strncpy(f_s, optarg, sizeof(f_s)); break; case 'o': flag_o = 1; break; case 'I': p = NULL; i = strtoul(optarg, &p, 0); if (p == optarg || errno == EINVAL || errno == ERANGE) { errx(1, "Invalid argument to -I"); } else if (!strcmp(p, "s")) i *= 1000000; else if (!strcmp(p, "ms")) i *= 1000; else if (!strcmp(p, "us")) i *= 1; flag_I = i; break; case 'p': flag_p = 1; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (argc != 0) usage(); i = geom_gettree(&gmp); if (i != 0) err(1, "geom_gettree = %d", i); error = geom_stats_open(); if (error) err(1, "geom_stats_open()"); sq = NULL; sq = geom_stats_snapshot_get(); if (sq == NULL) err(1, "geom_stats_snapshot()"); if (!flag_b) { /* Setup curses */ initscr(); start_color(); use_default_colors(); pair_content(0, &cf, &cb); init_pair(1, COLOR_GREEN, cb); init_pair(2, COLOR_MAGENTA, cb); init_pair(3, COLOR_RED, cb); cbreak(); noecho(); nonl(); nodelay(stdscr, 1); intrflush(stdscr, FALSE); keypad(stdscr, TRUE); /* Setup libedit */ hist = history_init(); if (hist == NULL) err(EX_SOFTWARE, "history_init()"); history(hist, &hist_ev, H_SETSIZE, 100); el = el_init("gstat", stdin, stdout, stderr); if (el == NULL) err(EX_SOFTWARE, "el_init"); el_set(el, EL_EDITOR, "emacs"); el_set(el, EL_SIGNAL, 1); el_set(el, EL_HIST, history, hist); el_set(el, EL_PROMPT, el_prompt); if (f_s[0] != '\0') history(hist, &hist_ev, H_ENTER, f_s); } geom_stats_snapshot_timestamp(sq, &tq); for (quit = 0; !quit;) { sp = geom_stats_snapshot_get(); if (sp == NULL) err(1, "geom_stats_snapshot()"); geom_stats_snapshot_timestamp(sp, &tp); dt = tp.tv_sec - tq.tv_sec; dt += (tp.tv_nsec - tq.tv_nsec) * 1e-9; tq = tp; geom_stats_snapshot_reset(sp); geom_stats_snapshot_reset(sq); move(0,0); PRINTMSG("dT: %5.3fs w: %.3fs", dt, (float)flag_I / 1000000); if (f_s[0] != '\0') { PRINTMSG(" filter: "); if (!flag_b) { getyx(stdscr, cury, curx); getmaxyx(stdscr, maxy, maxx); } strncpy(pf_s, f_s, sizeof(pf_s)); max_flen = maxx - curx - 1; if ((int)strlen(f_s) > max_flen && max_flen >= 0) { if (max_flen > 3) pf_s[max_flen - 3] = '.'; if (max_flen > 2) pf_s[max_flen - 2] = '.'; if (max_flen > 1) pf_s[max_flen - 1] = '.'; pf_s[max_flen] = '\0'; } PRINTMSG("%s", pf_s); } PRINTMSG("\n"); PRINTMSG(" L(q) ops/s "); PRINTMSG(" r/s kBps ms/r "); PRINTMSG(" w/s kBps ms/w "); if (flag_d) PRINTMSG(" d/s kBps ms/d "); if (flag_o) PRINTMSG(" o/s ms/o "); PRINTMSG("%%busy Name\n"); for (;;) { gsp = geom_stats_snapshot_next(sp); gsq = geom_stats_snapshot_next(sq); if (gsp == NULL || gsq == NULL) break; if (gsp->id == NULL) continue; gid = geom_lookupid(&gmp, gsp->id); if (gid == NULL) { geom_deletetree(&gmp); i = geom_gettree(&gmp); if (i != 0) err(1, "geom_gettree = %d", i); gid = geom_lookupid(&gmp, gsp->id); } if (gid == NULL) continue; if (gid->lg_what == ISCONSUMER && !flag_c) continue; if (flag_p && gid->lg_what == ISPROVIDER && ((struct gprovider *)(gid->lg_ptr))->lg_geom->lg_rank != 1) continue; /* Do not print past end of window */ if (!flag_b) { getyx(stdscr, cury, curx); if (curx > 0) continue; } if ((gid->lg_what == ISPROVIDER || gid->lg_what == ISCONSUMER) && f_s[0] != '\0') { pp = gid->lg_ptr; if ((regexec(&f_re, pp->lg_name, 0, NULL, 0) != 0)) continue; } if (gsp->sequence0 != gsp->sequence1) { PRINTMSG("*\n"); continue; } devstat_compute_statistics(gsp, gsq, dt, DSM_QUEUE_LENGTH, &u64, DSM_TRANSFERS_PER_SECOND, &ld[0], DSM_TRANSFERS_PER_SECOND_READ, &ld[1], DSM_MB_PER_SECOND_READ, &ld[2], DSM_MS_PER_TRANSACTION_READ, &ld[3], DSM_TRANSFERS_PER_SECOND_WRITE, &ld[4], DSM_MB_PER_SECOND_WRITE, &ld[5], DSM_MS_PER_TRANSACTION_WRITE, &ld[6], DSM_BUSY_PCT, &ld[7], DSM_TRANSFERS_PER_SECOND_FREE, &ld[8], DSM_MB_PER_SECOND_FREE, &ld[9], DSM_MS_PER_TRANSACTION_FREE, &ld[10], DSM_TRANSFERS_PER_SECOND_OTHER, &ld[11], DSM_MS_PER_TRANSACTION_OTHER, &ld[12], DSM_NONE); if (flag_a && ld[7] < 0.1) { *gsq = *gsp; continue; } PRINTMSG(" %4ju", (uintmax_t)u64); PRINTMSG(" %6.0f", (double)ld[0]); PRINTMSG(" %6.0f", (double)ld[1]); PRINTMSG(" %6.0f", (double)ld[2] * 1024); if (ld[3] > 1e3) PRINTMSG(" %6.0f", (double)ld[3]); else PRINTMSG(" %6.1f", (double)ld[3]); PRINTMSG(" %6.0f", (double)ld[4]); PRINTMSG(" %6.0f", (double)ld[5] * 1024); if (ld[6] > 1e3) PRINTMSG(" %6.0f", (double)ld[6]); else PRINTMSG(" %6.1f", (double)ld[6]); if (flag_d) { PRINTMSG(" %6.0f", (double)ld[8]); PRINTMSG(" %6.0f", (double)ld[9] * 1024); if (ld[10] > 1e3) PRINTMSG(" %6.0f", (double)ld[10]); else PRINTMSG(" %6.1f", (double)ld[10]); } if (flag_o) { PRINTMSG(" %6.0f", (double)ld[11]); if (ld[12] > 1e3) PRINTMSG(" %6.0f", (double)ld[12]); else PRINTMSG(" %6.1f", (double)ld[12]); } if (ld[7] > 80) i = 3; else if (ld[7] > 50) i = 2; else i = 1; if (!flag_b) attron(COLOR_PAIR(i)); PRINTMSG(" %6.1lf", (double)ld[7]); if (!flag_b) { attroff(COLOR_PAIR(i)); PRINTMSG("|"); } else PRINTMSG(" "); if (gid == NULL) { PRINTMSG(" ??"); } else if (gid->lg_what == ISPROVIDER) { pp = gid->lg_ptr; PRINTMSG(" %s", pp->lg_name); } else if (gid->lg_what == ISCONSUMER) { cp = gid->lg_ptr; PRINTMSG(" %s/%s/%s", cp->lg_geom->lg_class->lg_name, cp->lg_geom->lg_name, cp->lg_provider->lg_name); } if (!flag_b) clrtoeol(); PRINTMSG("\n"); *gsq = *gsp; } geom_stats_snapshot_free(sp); if (flag_b) { /* We loop extra to make sure we get the information. */ if (!loop) break; loop = 0; usleep(flag_I); continue; } getyx(stdscr, cury, curx); getmaxyx(stdscr, maxy, maxx); clrtobot(); if (maxy - 1 <= cury) move(maxy - 1, 0); refresh(); usleep(flag_I); while((i = getch()) != ERR) { switch (i) { case '>': flag_I *= 2; break; case '<': flag_I /= 2; if (flag_I < 1000) flag_I = 1000; break; case 'c': flag_c = !flag_c; break; case 'f': move(0,0); clrtoeol(); refresh(); line = el_gets(el, &line_len); if (line == NULL) err(1, "el_gets"); if (line_len > 1) history(hist, &hist_ev, H_ENTER, line); strncpy(tmp_f_s, line, sizeof(f_s)); if ((p = strchr(tmp_f_s, '\n')) != NULL) *p = '\0'; /* * We have to clear since we messed up * curses idea of the screen by using * libedit. */ clear(); refresh(); if (regcomp(&tmp_f_re, tmp_f_s, REG_EXTENDED) != 0) { move(0, 0); printw("Invalid filter"); refresh(); sleep(1); } else { strncpy(f_s, tmp_f_s, sizeof(f_s)); f_re = tmp_f_re; } break; case 'F': f_s[0] = '\0'; break; case 'q': quit = 1; break; default: break; } } } if (!flag_b) { endwin(); el_end(el); } exit(EX_OK); }
int cmdloop(void) { char *line; const char *elline; int cmd_argc, rval = 0, known; #define scratch known char **cmd_argv; struct cmdtable *cmdp; History *hist; EditLine *elptr; HistEvent he; curinode = check_ginode(ROOTINO); curinum = ROOTINO; printactive(0); hist = history_init(); history(hist, &he, H_SETSIZE, 100); /* 100 elt history buffer */ elptr = el_init("fsdb", stdin, stdout, stderr); el_set(elptr, EL_EDITOR, "emacs"); el_set(elptr, EL_PROMPT, prompt); el_set(elptr, EL_HIST, history, hist); el_source(elptr, NULL); while ((elline = el_gets(elptr, &scratch)) != NULL && scratch != 0) { if (check_debug) printf("command `%s'\n", elline); history(hist, &he, H_ENTER, elline); line = strdup(elline); cmd_argv = crack(line, &cmd_argc); /* * el_parse returns -1 to signal that it's not been handled * internally. */ if (el_parse(elptr, cmd_argc, (const char **)cmd_argv) != -1) continue; if (cmd_argc) { known = 0; for (cmdp = cmds; cmdp->cmd; cmdp++) { if (!strcmp(cmdp->cmd, cmd_argv[0])) { if ((cmdp->flags & FL_WR) == FL_WR && nflag) warnx("`%s' requires write access", cmd_argv[0]), rval = 1; else if (cmd_argc >= cmdp->minargc && cmd_argc <= cmdp->maxargc) rval = (*cmdp->handler)(cmd_argc, cmd_argv); else if (cmd_argc >= cmdp->minargc && (cmdp->flags & FL_ST) == FL_ST) { strcpy(line, elline); cmd_argv = recrack(line, &cmd_argc, cmdp->maxargc); rval = (*cmdp->handler)(cmd_argc, cmd_argv); } else rval = argcount(cmdp, cmd_argc, cmd_argv); known = 1; break; } } if (!known) warnx("unknown command `%s'", cmd_argv[0]), rval = 1; } else rval = 0; free(line); if (rval < 0) /* user typed "quit" */ return 0; if (rval) warnx("rval was %d", rval); } el_end(elptr); history_end(hist); return rval; }
int main(int argc, char *argv[]) { int num; const char *buf; Tokenizer *tok; #if 0 int lastevent = 0; #endif int ncontinuation; History *hist; HistEvent ev; (void) signal(SIGINT, sig); (void) signal(SIGQUIT, sig); (void) signal(SIGHUP, sig); (void) signal(SIGTERM, sig); hist = history_init(); /* Init the builtin history */ /* Remember 100 events */ history(hist, &ev, H_SETSIZE, 100); tok = tok_init(NULL); /* Initialize the tokenizer */ /* Initialize editline */ el = el_init(*argv, stdin, stdout, stderr); el_set(el, EL_EDITOR, "vi"); /* Default editor is vi */ el_set(el, EL_SIGNAL, 1); /* Handle signals gracefully */ el_set(el, EL_PROMPT, prompt); /* Set the prompt function */ /* Tell editline to use this history interface */ el_set(el, EL_HIST, history, hist); /* Add a user-defined function */ el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete); /* Bind tab to it */ el_set(el, EL_BIND, "^I", "ed-complete", NULL); /* * Bind j, k in vi command mode to previous and next line, instead * of previous and next history. */ el_set(el, EL_BIND, "-a", "k", "ed-prev-line", NULL); el_set(el, EL_BIND, "-a", "j", "ed-next-line", NULL); /* * Source the user's defaults file. */ el_source(el, NULL); while ((buf = el_gets(el, &num)) != NULL && num != 0) { int ac; const char **av; #ifdef DEBUG (void) fprintf(stderr, "got %d %s", num, buf); #endif if (!continuation && num == 1) continue; ncontinuation = tok_line(tok, buf, &ac, &av) > 0; #if 0 if (continuation) { /* * Append to the right event in case the user * moved around in history. */ if (history(hist, &ev, H_SET, lastevent) == -1) err(1, "%d: %s\n", lastevent, ev.str); history(hist, &ev, H_ADD , buf); } else { history(hist, &ev, H_ENTER, buf); lastevent = ev.num; } #else /* Simpler */ history(hist, &ev, continuation ? H_APPEND : H_ENTER, buf); #endif continuation = ncontinuation; ncontinuation = 0; if (strcmp(av[0], "history") == 0) { int rv; switch (ac) { case 1: for (rv = history(hist, &ev, H_LAST); rv != -1; rv = history(hist, &ev, H_PREV)) (void) fprintf(stdout, "%4d %s", ev.num, ev.str); break; case 2: if (strcmp(av[1], "clear") == 0) history(hist, &ev, H_CLEAR); else goto badhist; break; case 3: if (strcmp(av[1], "load") == 0) history(hist, &ev, H_LOAD, av[2]); else if (strcmp(av[1], "save") == 0) history(hist, &ev, H_SAVE, av[2]); break; badhist: default: (void) fprintf(stderr, "Bad history arguments\n"); break; } } else if (el_parse(el, ac, av) == -1) { switch (fork()) { case 0: execvp(av[0], (char *const *)av); perror(av[0]); _exit(1); /*NOTREACHED*/ break; case -1: perror("fork"); break; default: if (wait(&num) == -1) perror("wait"); (void) fprintf(stderr, "Exit %x\n", num); break; } } tok_reset(tok); } el_end(el); tok_end(tok); history_end(hist); return (0); }
int main(int argc, char **argv) { const char *fields_file = ""; const char *config_file = ""; #if LIBEDIT_IS_UNICODE wchar_t wc; #endif char cmd_buf[500]; const char *cmd; int cmd_len; bool version = false; const char *cfile = NULL; size_t n; nmsg_res res; char *p; int i; axa_set_me(argv[0]); AXA_ASSERT(axa_parse_log_opt(NULL, "trace,off,stderr")); AXA_ASSERT(axa_parse_log_opt(NULL, "error,off,stderr")); axa_syslog_init(); axa_set_core(); axa_client_init(&client); if (strcmp(axa_prog_name, "radtool") == 0) mode = RAD; if (isatty(STDIN_FILENO)) el_e = el_init(axa_prog_name, stdin, stdout, stderr); if (el_e != NULL) { int flag; if (0 > el_get(el_e, EL_EDITMODE, &flag) || !flag) { el_end(el_e); el_e = NULL; } } if (el_e != NULL) { /* prefer emacs mode but let the user choose in .editrc */ el_set(el_e, EL_EDITOR, "emacs"); /* bind emacs search to ^R */ el_set(el_e, EL_BIND, "\022", "em-inc-search-prev", NULL); el_source(el_e, NULL); el_history = history_init(); history(el_history, &el_event, H_SETSIZE, 800); history_get_savefile(); history(el_history, &el_event, H_LOAD, history_savefile); el_set(el_e, EL_HIST, history, el_history); el_set(el_e, EL_PROMPT, el_prompt); el_set(el_e, EL_SIGNAL, 1); el_set(el_e, EL_GETCFN, getcfn); } while ((i = getopt(argc, argv, "hVdNF:E:S:c:n:")) != -1) { switch (i) { case 'n': config_file = optarg; break; case 'V': version = true; break; case 'h': usage(); break; case 'd': ++axa_debug; break; case 'N': no_prompt = true; break; case 'F': fields_file = optarg; break; case 'E': if (axa_tls_cipher_list(&emsg, optarg) == NULL) error_msg("%s", emsg.c); break; case 'S': if (!axa_tls_certs_dir(&emsg, optarg)) error_msg("%s", emsg.c); break; case 'c': if (cfile != NULL) error_msg("only one -c allowed;" " ignoring all but the last"); cfile = optarg; break; default: usage(); } } argc -= optind; argv += optind; if (version) { version_cmd(AXA_TAG_NONE, "", NULL); if (argc == 0) stop(EX_OK); } signal(SIGPIPE, SIG_IGN); if (el_e != NULL) { signal(SIGINT, sigint); signal(SIGTERM, sigterm); signal(SIGHUP, sigterm); } AXA_DEBUG_TO_NMSG(axa_debug); res = nmsg_init(); if (res != nmsg_res_success) { error_msg("nmsg_init(): %s", nmsg_res_lookup(res)); exit(EX_SOFTWARE); } nmsg_input = nmsg_input_open_null(); AXA_ASSERT(nmsg_input != NULL); nmsg_pres = nmsg_output_open_pres(STDOUT_FILENO); axa_load_fields(fields_file); if (!axa_load_client_config(&emsg, config_file)) { axa_error_msg("can't load config file: %s", emsg.c); exit(EXIT_FAILURE); } /* Answer commands from the control file. */ if (cfile != NULL) { axa_asprintf(&p, "source %s", cfile); if (el_e != NULL) history(el_history, &el_event, H_ENTER, p); if (!do_cmds(p)) error_msg(" initial \"-c %s\" failed", cfile); free(p); } /* Answer commands from the command line. */ while (argc != 0) { if (el_e != NULL) history(el_history, &el_event, H_ENTER, *argv); if (!do_cmds(*argv)) { error_msg(" initial command \"%s\" failed", *argv); break; } ++argv; --argc; } for (;;) { cmd_input.tv_sec = 0; fflush(stderr); fflush(stdout); if (in_file_cur > 0) { /* Get a command from a "sourced" file. */ if (interrupted) { close_in_files(); continue; } cmd = axa_fgetln(in_files[in_file_cur].f, in_files[in_file_cur].name, &in_files[in_file_cur].lineno, &in_files[in_file_cur].buf, &in_files[in_file_cur].buf_size); if (cmd == NULL) { close_in_file_cur(); continue; } if (axa_debug != 0) { printf("< %s\n", cmd); fflush(stdout); } } else if (el_e != NULL) { /* Get a command from the terminal via editline(3). */ cmd = el_gets(el_e, &cmd_len); prompt_len = 0; if (!interrupted) { if (cmd == NULL) { fputc('\n', stdout); if (cmd_len == -1) error_msg("el_gets(): %s", strerror(errno)); stop(EX_OK); } /* Save nontrivial command lines. */ if (*(cmd+strspn(cmd, AXA_WHITESPACE)) != '\0') history(el_history, &el_event, H_ENTER, cmd); } } else if (!interrupted) { /* Get a command from stdin. */ n = 0; for (;;) { #if LIBEDIT_IS_UNICODE getcfn(NULL, &wc); cmd_buf[n] = wctob(wc); #else getcfn(NULL, &cmd_buf[n]); #endif if (cmd_buf[n++] == '\n' || n >= sizeof(cmd_buf)-1) break; } cmd_buf[n] = '\0'; cmd = cmd_buf; } if (interrupted) { interrupted = false; if (el_e != NULL) { el_set(el_e, EL_UNBUFFERED, 0); el_reset(el_e); if (prompt_cleared.tv_sec != 0) { packet_counting = true; packet_count = 0; packet_count_total = 0; } } close_in_files(); fputs(" (int)\n", stdout); continue; } if (!do_cmds(cmd)) { fputs(" ?\n", stderr); fflush(stdout); close_in_files(); } } }
int main (int argc, char* argv[]) { #ifdef OSV_CLI putenv("TERM=vt100-qemu"); cli_console_size_dirty(); #else struct winsize sz; ioctl(0, TIOCGWINSZ, &sz); if (sz.ws_col > 0 && sz.ws_row > 0) { con_width = sz.ws_col; con_height = sz.ws_row; signal(SIGWINCH, cli_sigwinch_handler); } #endif /* Context */ env_osv_api = getenv("OSV_API"); /* Process command line options */ int opt = 0; static struct option long_options[] = { {"api", optional_argument, 0, 'a'} }; int long_index = 0; while ((opt = getopt_long(argc, argv, "a:", long_options, &long_index)) != -1) { switch (opt) { case 'a': env_osv_api = optarg; break; } } /* Lua state */ L = cli_luaL_newstate(); if (optind < argc) { /* If we have more arguments, the user is running a single command */ if (L != NULL) { lua_getglobal(L, "cli_command_single"); lua_createtable(L, argc, 0); for (int i=1; i<argc; i++) { lua_pushinteger(L, i); lua_pushstring(L, argv[i]); lua_settable(L, -3); } lua_pushinteger(L, optind - 1); int error = lua_pcall(L, 2, 0, 0); if (error) { fprintf(stderr, "%s\n", lua_tostring(L, -1)); lua_pop(L, 1); } } } else { /* Start a shell */ /* This holds all the state for our line editor */ EditLine *el; /* This holds the info for our history */ History *cli_history; /* Temp variables */ int keepreading = 1; HistEvent ev; /* editline */ int el_count = 0; char *el_line; /* Initialize the EditLine state to use our prompt function and emacs style editing. */ el = el_init(argv[0], stdin, stdout, stderr); el_set(el, EL_PROMPT, &cli_prompt); el_set(el, EL_SIGNAL, 1); el_set(el, EL_EDITOR, "emacs"); /* Initialize the history */ cli_history = history_init(); if (cli_history == 0) { fprintf(stderr, "history could not be initialized\n"); } /* Set the size of the history */ history(cli_history, &ev, H_SETSIZE, 800); /* This sets up the call back functions for history functionality */ el_set(el, EL_HIST, history, cli_history); while (keepreading) { /* el_count is the number of characters read. line is a const char* of our command line with the tailing \n */ el_line = (char *) el_gets(el, &el_count); /* If lua failed to load previously, retry */ if (L == NULL) { cli_luaL_renewstate(&L); } /* with zero input (^D), reset the lua state */ if (L != NULL && el_count == 0) { cli_luaL_renewstate(&L); } else if (L != NULL && el_count > 0) { /* Remove tailing \n */ el_line[strlen(el_line)-1] = '\0'; /* Add commands to history. Don't add empty lines */ if (strlen(el_line) > 0) { history(cli_history, &ev, H_ENTER, el_line); } /* Typing reset is a special case which, like ^D, will reset the lua state */ if (strcmp(el_line, "reset") == 0) { cli_luaL_renewstate(&L); } else { /* Pass the line, as is, to cli() */ lua_getglobal(L, "cli_command"); lua_pushstring(L, el_line); int error = lua_pcall(L, 1, 0, 0); if (error) { fprintf(stderr, "%s\n", lua_tostring(L, -1)); lua_pop(L, 1); } } } } history_end(cli_history); el_end(el); } if (L != NULL) { lua_close(L); } return 0; }