Example #1
0
File: complete.c Project: danrl/nsh
void
endedit()
{
	editing = 0;

	if (elc) {
		el_end(elc);
		elc = NULL;
	}
	if (eli) {
		el_end(eli);
		eli = NULL;
	}
}
Example #2
0
static int acc_el_initialize(void)
{
    HistEvent ev;

    if (el != NULL)
        el_end(el);
    if (el_hist != NULL)
        history_end(el_hist);

    el = el_init("accedian", stdin, stdout, stderr);
    el_set(el, EL_PROMPT, cli_prompt);

    el_set(el, EL_EDITMODE, 1);
    el_set(el, EL_EDITOR, "emacs");
    el_hist = history_init();
    if (!el || !el_hist)
        return -1;

    /* setup history with 100 entries */
    history(el_hist, &ev, H_SETSIZE, 100);
    el_set(el, EL_HIST, history, el_hist);

    el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);

    /* Bind <tab> to command completion */
    el_set(el, EL_BIND, "^I", "ed-complete", NULL);
    #if 0   // Ticket #8152 - This corrupts show_rc passwords containing question marks
    /* Bind ? to command completion */
    el_set(el, EL_BIND, "?", "ed-complete", NULL);
    #endif
    /* Bind ^D to redisplay */
    el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);

    return 0;
}
Example #3
0
void
noit_console_closure_free(void *vncct) {
  noit_console_closure_t ncct = (noit_console_closure_t) vncct;
  noit_log_stream_t lf;
  noitL(noit_debug, "ncct free(%p)\n", (void *)ncct);
  if(ncct->el) el_end(ncct->el);
  if(ncct->hist) {
    history_end(ncct->hist);
    noitL(noit_debug, "ncct free->hist(%p)\n", (void *)ncct->hist);
    free(ncct->hist);
  }
  if(ncct->pty_master >= 0) close(ncct->pty_master);
  if(ncct->pty_slave >= 0) close(ncct->pty_slave);
  if(ncct->outbuf) free(ncct->outbuf);
  if(ncct->telnet) noit_console_telnet_free(ncct->telnet);
  noit_hash_destroy(&ncct->userdata, NULL, noit_console_userdata_free);
  while(ncct->state_stack) {
    noit_console_state_stack_t *tmp;
    tmp = ncct->state_stack;
    ncct->state_stack = tmp->last;
    if(tmp->name) free(tmp->name);
    free(tmp);
  }
  lf = noit_log_stream_find(ncct->feed_path);
  noit_log_stream_remove(ncct->feed_path);
  if(lf) {
    noit_log_stream_free(lf);
  }
  free(ncct);
}
Example #4
0
void bye(void)
{
    cliLogCommand("End Session");


    //Set flag for thread to terminate
    terminate_cli_check_session_thread = ACD_TRUE;

    //Reset EditLine (useful if el_gets() did not complete normally)
    if (el != NULL)
        el_end(el);

    //Free dynamically-allocated data
    cli_command_cleanup(CLEAR_STATIC_DATA);
    cli_free_command_cleanup_arr();

    //Kill session
    if (session_id)
        cli_delete_session();

    //Free IPC handles
    cmd_free(&cli_backend_handle);
    cmd_free(&cli_check_session_thread_ipc_handle);
#ifdef ACCEDIAN_CONFIG_DISCOVERY_ENABLED    
    if (acd_cap_discovery())
    {
      discovery_module_cleanup();
    }
#endif
}
static void
_cleanup_editlineobject(EditLineObject *self)
{
    /* mop up libedit */
    if (self->el)
	el_end(self->el);
    if (self->tok)
	tok_end(self->tok);
    if (self->hist)
	history_end(self->hist);

    /* tidy up the allocated bits */
    if (self->name)
	PyMem_RawFree(self->name);
    if (self->prompt)
	PyMem_RawFree(self->prompt);
    if (self->rprompt)
	PyMem_RawFree(self->rprompt);
    if (self->buffer)
	PyMem_RawFree(self->buffer);
    
    /* manage file-handles? */
    if (self->fin)
	fclose(self->fin);
    if (self->fout)
	fclose(self->fout);
    if (self->ferr)
	fclose(self->ferr);

    /* release my ownership of the I/O refs */
    Py_DECREF(self->pyin);
    Py_DECREF(self->pyout);
    Py_DECREF(self->pyerr);
}
Example #6
0
void AXA_NORETURN
stop(int status)
{
	if (el_e != NULL) {
		if (el_history)
			history(el_history, &el_event, H_SAVE,
					history_savefile);
		history_end(el_history);
		el_end(el_e);
	}
	close_in_files();
	fflush(stderr);
	fflush(stdout);
	disconnect(false);
	if (nmsg_input != NULL)
		nmsg_input_close(&nmsg_input);
	if (nmsg_pres != NULL)
		nmsg_output_close(&nmsg_pres);	/* this closes stdout */
	out_close(false);

	axa_unload_fields();
	axa_unload_client_config();

	axa_io_cleanup();

	exit(status);
}
/*
 * ntp_readline_init - setup, set or reset prompt string
 */
int
ntp_readline_init(
	const char *	prompt
	)
{
	int	success;

	success = 1;

	if (prompt) {
		if (lineedit_prompt) 
			free(lineedit_prompt);
		lineedit_prompt = estrdup(prompt);
	}

#ifdef LE_EDITLINE
	if (NULL == ntp_el) {

# if 4 == EL_INIT_ARGS
		ntp_el = el_init(progname, stdin, stdout, stderr);
# else
		ntp_el = el_init(progname, stdin, stdout);
# endif
		if (ntp_el) {

			el_set(ntp_el, EL_PROMPT, ntp_prompt_callback);
			el_set(ntp_el, EL_EDITOR, "emacs");

			ntp_hist = history_init();

			if (NULL == ntp_hist) {

				mfprintf(stderr, "history_init(): %m\n");
				fflush(stderr);

				el_end(ntp_el);
				ntp_el = NULL;

				success = 0;

			} else {
				ZERO(hev);
#ifdef H_SETSIZE
				history(ntp_hist, &hev, H_SETSIZE, 128);
#endif
				el_set(ntp_el, EL_HIST, history,
				       ntp_hist);
				/* use any .editrc */
				el_source(ntp_el, NULL);
			}
		} else
			success = 0;
	}
#endif	/* LE_EDITLINE */

	ntp_readline_initted = success;

	return success;
}
Example #8
0
void IoEditLine_free(IoEditLine *self)
{
	if (IoObject_dataPointer(self))
	{
		el_end(DATA(self)->editline);
		history_end(DATA(self)->history);
	}
}
Example #9
0
/*
 * ntp_readline_init - setup, set or reset prompt string
 */
int
ntp_readline_init(
	const char *	prompt
	)
{
	int	success;

	success = 1;

	if (prompt) {
		if (lineedit_prompt) 
			free(lineedit_prompt);
		lineedit_prompt = estrdup(prompt);
	}

#ifdef LE_EDITLINE
	if (NULL == ntp_el) {

		ntp_el = el_init(progname, stdin, stdout, stderr);
		if (ntp_el) {

			el_set(ntp_el, EL_PROMPT, ntp_prompt_callback);
			el_set(ntp_el, EL_EDITOR, "emacs");

			ntp_hist = history_init();

			if (NULL == ntp_hist) {

				fprintf(stderr, "history_init(): %s\n",
						strerror(errno));
				fflush(stderr);

				el_end(ntp_el);
				ntp_el = NULL;

				success = 0;

			} else {
				memset(&hev, 0, sizeof hev);

				history(ntp_hist, &hev,	H_SETSIZE, 128);

				el_set(ntp_el, EL_HIST, history, ntp_hist);

				/* use any .editrc */
				el_source(ntp_el, NULL);
			}
		} else
			success = 0;
	}
#endif	/* LE_EDITLINE */

	ntp_readline_initted = success;

	return success;
}
Example #10
0
void
cmdend(void *arg)
{
	struct clitenv *env = arg;

	el_end(env->el);
	history_end(env->hist);

	free(env);
}
Example #11
0
void x_readline_end(void) {
	if (el) {
		el_end(el);
		el = NULL;
	}
	if (hist) {
		history_end(hist);
		hist = NULL;
	}
}
Example #12
0
static void _cliDebuggerDeinit(struct Debugger* debugger) {
	struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger;
	history_end(cliDebugger->histate);
	el_end(cliDebugger->elstate);

	if (cliDebugger->system) {
		cliDebugger->system->deinit(cliDebugger->system);
		free(cliDebugger->system);
		cliDebugger->system = 0;
	}
}
Example #13
0
CommandPrompt::~CommandPrompt()
{
#ifdef ZORBA_HAVE_LIBEDIT_H
  history_end(theHistory);
  el_end(theEditLine);
#endif

  std::map<std::string, UntypedCommand*>::iterator lIter;
  for (lIter = theCommands.begin(); lIter != theCommands.end(); ++lIter) {
    delete lIter->second;
  }
}
Example #14
0
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);
    });
}
/*
 * ntp_readline_uninit - release resources
 */
void
ntp_readline_uninit(
	void
	)
{
#ifdef LE_EDITLINE
	if (ntp_el) {
		el_end(ntp_el);
		ntp_el = NULL;

		history_end(ntp_hist);
		ntp_hist = NULL;
	}
#endif	/* LE_EDITLINE */

	if (lineedit_prompt) {
		free(lineedit_prompt);
		lineedit_prompt = NULL;
	}

	ntp_readline_initted = 0;
}
Example #16
0
void
CliContext::Cleanup()
{
	Terminating();

	while (Event* event = fPendingEvents.RemoveHead())
		delete event;

	if (fEditLine != NULL) {
		el_end(fEditLine);
		fEditLine = NULL;
	}

	if (fHistory != NULL) {
		history_end(fHistory);
		fHistory = NULL;
	}

	if (fTeam != NULL) {
		fTeam->RemoveListener(this);
		fTeam = NULL;
	}

	if (fNodeManager != NULL) {
		fNodeManager->ReleaseReference();
		fNodeManager = NULL;
	}

	if (fCurrentBlock != NULL) {
		fCurrentBlock->ReleaseReference();
		fCurrentBlock = NULL;
	}

	if (fExpressionInfo != NULL) {
		fExpressionInfo->ReleaseReference();
		fExpressionInfo = NULL;
	}
}
Example #17
0
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);
}
Example #18
0
/*
 * Set history and editing status.  Called whenever the status may
 * have changed (figures out what to do).
 */
void
histedit() 
{

#define editing (Eflag || Vflag)

	if (iflag) {
		if (!hist) {
			/*
			 * turn history on
			 */
			INTOFF;
			hist = history_init();
			INTON;

			if (hist != NULL)
				sethistsize(histsizeval());
			else
				out2str("sh: can't initialize history\n");
		}
		if (editing && !el && isatty(0)) { /* && isatty(2) ??? */
			/*
			 * turn editing on
			 */
			INTOFF;
			if (el_in == NULL)
				el_in = fdopen(0, "r");
			if (el_out == NULL)
				el_out = fdopen(2, "w");
			if (el_in == NULL || el_out == NULL)
				goto bad;
			el = el_init(arg0, el_in, el_out);
			if (el != NULL) {
				if (hist)
					el_set(el, EL_HIST, history, hist);
				el_set(el, EL_PROMPT, getprompt);
			} else {
bad:
				out2str("sh: can't initialize editing\n");
			}
			INTON;
		} else if (!editing && el) {
			INTOFF;
			el_end(el);
			el = NULL;
			INTON;
		}
		if (el) {
			if (Vflag)
				el_set(el, EL_EDITOR, "vi");
			else if (Eflag)
				el_set(el, EL_EDITOR, "emacs");
		}
	} else {
		INTOFF;
		if (el) {	/* no editing if not interactive */
			el_end(el);
			el = NULL;
		}
		if (hist) {
			history_end(hist);
			hist = NULL;
		}
		INTON;
	}
}
Example #19
0
File: ui.c Project: idl3r/rappel
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);
}
Example #20
0
EditLineReader::~EditLineReader()
{
	el_end(_editLine);
	history_end(_history);
}
Example #21
0
/*
 * Connect to ppp using either a local domain socket or a tcp socket.
 *
 * If we're given arguments, process them and quit, otherwise create two
 * threads to handle interactive mode.
 */
int
main(int argc, char **argv)
{
    struct sockaddr_un ifsun;
    int n, arg, fd, len, verbose, save_errno, hide1, hide1off, hide2;
    unsigned TimeoutVal;
    char *DoneWord = "x", *next, *start;
    struct sigaction act, oact;
    void *thread_ret;
    pthread_t mon;
    char Command[LINELEN];
    char Buffer[LINELEN];

    verbose = 0;
    TimeoutVal = 2;
    hide1 = hide1off = hide2 = 0;

    for (arg = 1; arg < argc; arg++)
        if (*argv[arg] == '-') {
            for (start = argv[arg] + 1; *start; start++)
                switch (*start) {
                    case 't':
                        TimeoutVal = (unsigned)atoi
                            (start[1] ? start + 1 : argv[++arg]);
                        start = DoneWord;
                        break;
    
                    case 'v':
                        verbose = REC_VERBOSE;
                        break;

                    case 'p':
                        if (start[1]) {
                          hide1 = arg;
                          hide1off = start - argv[arg];
                          passwd = start + 1;
                        } else {
                          hide1 = arg;
                          hide1off = start - argv[arg];
                          passwd = argv[++arg];
                          hide2 = arg;
                        }
                        start = DoneWord;
                        break;
    
                    default:
                        usage();
                }
        }
        else
            break;


    if (argc < arg + 1)
        usage();

    if (hide1) {
      char title[1024];
      int pos, harg;

      for (harg = pos = 0; harg < argc; harg++)
        if (harg == 0 || harg != hide2) {
          if (harg == 0 || harg != hide1)
            n = snprintf(title + pos, sizeof title - pos, "%s%s",
                            harg ? " " : "", argv[harg]);
          else if (hide1off > 1)
            n = snprintf(title + pos, sizeof title - pos, " %.*s",
                            hide1off, argv[harg]);
          else
            n = 0;
          if (n < 0 || n >= sizeof title - pos)
            break;
          pos += n;
        }
#ifdef __FreeBSD__
      setproctitle("-%s", title);
#else
      setproctitle("%s", title);
#endif
    }

    if (*argv[arg] == '/') {
        memset(&ifsun, '\0', sizeof ifsun);
        ifsun.sun_len = strlen(argv[arg]);
        if (ifsun.sun_len > sizeof ifsun.sun_path - 1) {
            warnx("%s: path too long", argv[arg]);
            return 1;
        }
        ifsun.sun_family = AF_LOCAL;
        strcpy(ifsun.sun_path, argv[arg]);

        if (fd = socket(AF_LOCAL, SOCK_STREAM, 0), fd < 0) {
            warnx("cannot create local domain socket");
            return 2;
        }
	if (connect(fd, (struct sockaddr *)&ifsun, sizeof(ifsun)) < 0) {
	    if (errno)
		warn("cannot connect to socket %s", argv[arg]);
	    else
		warnx("cannot connect to socket %s", argv[arg]);
	    close(fd);
	    return 3;
	}
    } else {
        char *addr, *p, *port;
	const char *caddr;
	struct addrinfo hints, *res, *pai;
        int gai;
	char local[] = "localhost";

	addr = argv[arg];
	if (addr[strspn(addr, "0123456789")] == '\0') {
	    /* port on local machine */
	    port = addr;
	    addr = local;
	} else if (*addr == '[') {
	    /* [addr]:port */
	    if ((p = strchr(addr, ']')) == NULL) {
		warnx("%s: mismatched '['", addr);
		return 1;
	    }
	    addr++;
	    *p++ = '\0';
	    if (*p != ':') {
		warnx("%s: missing port", addr);
		return 1;
	    }
	    port = ++p;
	} else {
	    /* addr:port */
	    p = addr + strcspn(addr, ":");
	    if (*p != ':') {
		warnx("%s: missing port", addr);
		return 1;
	    }
	    *p++ = '\0';
	    port = p;
	}
	memset(&hints, 0, sizeof(hints));
	hints.ai_socktype = SOCK_STREAM;
	gai = getaddrinfo(addr, port, &hints, &res);
	if (gai != 0) {
	    warnx("%s: %s", addr, gai_strerror(gai));
	    return 1;
	}
	for (pai = res; pai != NULL; pai = pai->ai_next) {
	    if (fd = socket(pai->ai_family, pai->ai_socktype,
		pai->ai_protocol), fd < 0) {
		warnx("cannot create socket");
		continue;
	    }
	    TimedOut = 0;
	    if (TimeoutVal) {
		act.sa_handler = Timeout;
		sigemptyset(&act.sa_mask);
		act.sa_flags = 0;
		sigaction(SIGALRM, &act, &oact);
		alarm(TimeoutVal);
	    }
	    if (connect(fd, pai->ai_addr, pai->ai_addrlen) == 0)
		break;
	    if (TimeoutVal) {
		save_errno = errno;
		alarm(0);
		sigaction(SIGALRM, &oact, 0);
		errno = save_errno;
	    }
	    caddr = sockaddr_ntop(pai->ai_addr);
	    if (caddr == NULL)
		caddr = argv[arg];
	    if (TimedOut)
		warnx("timeout: cannot connect to %s", caddr);
	    else {
		if (errno)
		    warn("cannot connect to %s", caddr);
		else
		    warnx("cannot connect to %s", caddr);
	    }
	    close(fd);
	}
	freeaddrinfo(res);
	if (pai == NULL)
	    return 1;
	if (TimeoutVal) {
	    alarm(0);
	    sigaction(SIGALRM, &oact, 0);
	}
    }

    len = 0;
    Command[sizeof(Command)-1] = '\0';
    for (arg++; arg < argc; arg++) {
        if (len && len < sizeof(Command)-1)
            strcpy(Command+len++, " ");
        strncpy(Command+len, argv[arg], sizeof(Command)-len-1);
        len += strlen(Command+len);
    }

    switch (Receive(fd, verbose | REC_PASSWD)) {
        case 1:
            fprintf(stderr, "Password incorrect\n");
            break;

        case 0:
            passwd = NULL;
            if (len == 0) {
                struct thread_data td;
                const char *env;
                int size;
#ifndef __OpenBSD__
                HistEvent hev = { 0, "" };
#endif

                td.hist = history_init();
                if ((env = getenv("EL_SIZE"))) {
                    size = atoi(env);
                    if (size < 0)
                      size = 20;
                } else
                    size = 20;
#ifdef __OpenBSD__
                history(td.hist, H_EVENT, size);
                td.edit = el_init("pppctl", stdin, stdout);
#else
                history(td.hist, &hev, H_SETSIZE, size);
                td.edit = el_init("pppctl", stdin, stdout, stderr);
#endif
                el_source(td.edit, NULL);
                el_set(td.edit, EL_PROMPT, GetPrompt);
                if ((env = getenv("EL_EDITOR"))) {
                    if (!strcmp(env, "vi"))
                        el_set(td.edit, EL_EDITOR, "vi");
                    else if (!strcmp(env, "emacs"))
                        el_set(td.edit, EL_EDITOR, "emacs");
                }
                el_set(td.edit, EL_SIGNAL, 1);
                el_set(td.edit, EL_HIST, history, (const char *)td.hist);

                td.ppp = fd;
                td.trm = NULL;

                /*
                 * We create two threads.  The Terminal thread does all the
                 * work while the Monitor thread simply tells the Terminal
                 * thread when ``fd'' becomes readable.  The telling is done
                 * by sending a SIGUSR1 to the Terminal thread.  The
                 * sem_select semaphore is used to prevent the monitor
                 * thread from firing excessive signals at the Terminal
                 * thread (it's abused for exit handling too - see below).
                 *
                 * The Terminal thread never uses td.trm !
                 */
                sem_init(&sem_select, 0, 0);

                pthread_create(&td.trm, NULL, Terminal, &td);
                pthread_create(&mon, NULL, Monitor, &td);

                /* Wait for the terminal thread to finish */
                pthread_join(td.trm, &thread_ret);
                fprintf(stderr, "Connection closed\n");

                /* Get rid of the monitor thread by abusing sem_select */
                timetogo = 1;
                close(fd);
                fd = -1;
                sem_post(&sem_select);
                pthread_join(mon, &thread_ret);

                /* Restore our terminal and release resources */
                el_end(td.edit);
                history_end(td.hist);
                sem_destroy(&sem_select);
            } else {
                start = Command;
                do {
                    next = strchr(start, ';');
                    while (*start == ' ' || *start == '\t')
                        start++;
                    if (next)
                        *next = '\0';
                    strcpy(Buffer, start);
                    Buffer[sizeof(Buffer)-2] = '\0';
                    strcat(Buffer, "\n");
                    if (verbose)
                        write(STDOUT_FILENO, Buffer, strlen(Buffer));
                    write(fd, Buffer, strlen(Buffer));
                    if (Receive(fd, verbose | REC_SHOW) != 0) {
                        fprintf(stderr, "Connection closed\n");
                        break;
                    }
                    if (next)
                        start = ++next;
                } while (next && *next);
                if (verbose)
                    write(STDOUT_FILENO, "quit\n", 5);
                write(fd, "quit\n", 5);
                while (Receive(fd, verbose | REC_SHOW) == 0)
                    ;
                if (verbose)
                    puts("");
            }
            break;

        default:
            warnx("ppp is not responding");
            break;
    }

    if (fd != -1)
        close(fd);
    
    return 0;
}
Example #22
0
void deinitialize_libedit(void)
{
	el_end(el);
	history_end(hist);
}
Example #23
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;
}
Example #24
0
/*
 * Set history and editing status.  Called whenever the status may
 * have changed (figures out what to do).
 */
void
histedit(void)
{

#define editing (Eflag || Vflag)

	if (iflag) {
		if (!hist) {
			/*
			 * turn history on
			 */
			INTOFF;
			hist = history_init();
			INTON;

			if (hist != NULL)
				sethistsize(histsizeval());
			else
				out2fmt_flush("sh: can't initialize history\n");
		}
		if (editing && !el && isatty(0)) { /* && isatty(2) ??? */
			/*
			 * turn editing on
			 */
			char *term;

			INTOFF;
			if (el_in == NULL)
				el_in = fdopen(0, "r");
			if (el_err == NULL)
				el_err = fdopen(1, "w");
			if (el_out == NULL)
				el_out = fdopen(2, "w");
			if (el_in == NULL || el_err == NULL || el_out == NULL)
				goto bad;
			term = lookupvar("TERM");
			if (term) {
				if (setenv("TERM", term, 1) == -1)
					error("setenv: cannot set TERM=1");
			}
			else
				unsetenv("TERM");
			el = el_init(arg0, el_in, el_out, el_err);
			if (el != NULL) {
				if (hist)
					el_set(el, EL_HIST, history, hist);
				el_set(el, EL_PROMPT, getprompt);
				el_set(el, EL_ADDFN, "rl-complete",
				    "ReadLine compatible completion function",
				    _el_fn_complete);
			} else {
bad:
				out2fmt_flush("sh: can't initialize editing\n");
			}
			INTON;
		} else if (!editing && el) {
			INTOFF;
			el_end(el);
			el = NULL;
			INTON;
		}
		if (el) {
			if (Vflag)
				el_set(el, EL_EDITOR, "vi");
			else if (Eflag)
				el_set(el, EL_EDITOR, "emacs");
			el_set(el, EL_BIND, "^I",
			    tabcomplete ? "rl-complete" : "ed-insert", NULL);
			el_source(el, NULL);
		}
	} else {
		INTOFF;
		if (el) {	/* no editing if not interactive */
			el_end(el);
			el = NULL;
		}
		if (hist) {
			history_end(hist);
			hist = NULL;
		}
		INTON;
	}
}
Example #25
0
int
main(int argc, char *argv[])
{
	EditLine *el = NULL;
	int numc, ncontinuation;
	const wchar_t *line;
	TokenizerW *tok;
	HistoryW *hist;
	HistEventW ev;
#ifdef DEBUG
	int i;
#endif

	setlocale(LC_ALL, "");

	(void)signal(SIGINT,  sig);
	(void)signal(SIGQUIT, sig);
	(void)signal(SIGHUP,  sig);
	(void)signal(SIGTERM, sig);

	hist = history_winit();		/* Init built-in history     */
	history_w(hist, &ev, H_SETSIZE, 100);	/* Remember 100 events	     */
	history_w(hist, &ev, H_LOAD, hfile);

	tok = tok_winit(NULL);			/* Init the tokenizer	     */

	el = el_init(argv[0], stdin, stdout, stderr);

	el_wset(el, EL_EDITOR, L"vi");		/* Default editor is vi	     */
	el_wset(el, EL_SIGNAL, 1);		/* Handle signals gracefully */
	el_wset(el, EL_PROMPT_ESC, prompt, '\1'); /* Set the prompt function */

	el_wset(el, EL_HIST, history_w, hist);	/* FIXME - history_w? */

					/* Add a user-defined function	*/
	el_wset(el, EL_ADDFN, L"ed-complete", L"Complete argument", complete);

					/* Bind <tab> to it */
	el_wset(el, EL_BIND, L"^I", L"ed-complete", NULL);

	/*
	* Bind j, k in vi command mode to previous and next line, instead
	* of previous and next history.
	*/
	el_wset(el, EL_BIND, L"-a", L"k", L"ed-prev-line", NULL);
	el_wset(el, EL_BIND, L"-a", L"j", L"ed-next-line", NULL);

	/* Source the user's defaults file. */
	el_source(el, NULL);

	while((line = el_wgets(el, &numc)) != NULL && numc != 0) {
		int ac, cc, co, rc;
		const wchar_t **av;

		const LineInfoW *li;
		li = el_wline(el);

#ifdef DEBUG
		(void)fwprintf(stderr, L"==> got %d %ls", numc, line);
		(void)fwprintf(stderr, L"  > li `%.*ls_%.*ls'\n",
		    (li->cursor - li->buffer), li->buffer,
		    (li->lastchar - 1 - li->cursor),
		    (li->cursor >= li->lastchar) ? L"" : li->cursor);
#endif

		if (gotsig) {
			(void)fprintf(stderr, "Got signal %d.\n", gotsig);
			gotsig = 0;
			el_reset(el);
		}

		if(!continuation && numc == 1)
			continue;	/* Only got a linefeed */

		ac = cc = co = 0;
		ncontinuation = tok_wline(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
		history_w(hist, &ev, continuation ? H_APPEND : H_ENTER, line);

		continuation = ncontinuation;
		ncontinuation = 0;
		if(continuation)
			continue;

#ifdef DEBUG
		for (i = 0; i < ac; ++i) {
			(void)fwprintf(stderr, L"  > arg# %2d ", i);
			if (i != cc)
				(void)fwprintf(stderr, L"`%ls'\n", av[i]);
			else
				(void)fwprintf(stderr, L"`%.*ls_%ls'\n",
				    co, av[i], av[i] + co);
		}
#endif

		if (wcscmp (av[0], L"history") == 0) {
			switch(ac) {
			case 1:
				for(rc = history_w(hist, &ev, H_LAST);
				     rc != -1;
				     rc = history_w(hist, &ev, H_PREV))
					(void)fwprintf(stdout, L"%4d %ls",
					     ev.num, ev.str);
				break;
			case 2:
				if (wcscmp(av[1], L"clear") == 0)
					history_w(hist, &ev, H_CLEAR);
				else
					goto badhist;
				break;
			case 3:
				if (wcscmp(av[1], L"load") == 0)
					history_w(hist, &ev, H_LOAD,
					    my_wcstombs(av[2]));
				else if (wcscmp(av[1], L"save") == 0)
					history_w(hist, &ev, H_SAVE,
					    my_wcstombs(av[2]));
				else
					goto badhist;
				break;
			badhist:
			default:
				(void)fprintf(stderr,
				    "Bad history arguments\n");
				break;
			}
		} else if (el_wparse(el, ac, av) == -1) {
			switch (fork()) {
			case 0: {
				Tokenizer *ntok = tok_init(NULL);
				int nargc;
				const char **nav;
				tok_str(ntok, my_wcstombs(line), &nargc, &nav);
				execvp(nav[0],(char **)nav);
				perror(nav[0]);
				_exit(1);
				/* NOTREACHED */
				break;
			}
			case -1:
				perror("fork");
				break;
			default:
				if (wait(&rc) == -1)
					perror("wait");
				(void)fprintf(stderr, "Exit %x\n", rc);
				break;
			}
		}

		tok_wreset(tok);
	}

	el_end(el);
	tok_wend(tok);
	history_w(hist, &ev, H_SAVE, hfile);
	history_wend(hist);

	fprintf(stdout, "\n");
	return 0;
}
Example #26
0
/*
 * Set history and editing status.  Called whenever the status may
 * have changed (figures out what to do).
 */
void
histedit(void)
{
	FILE *el_err;

#define editing (Eflag || Vflag)

	if (iflag == 1) {
		if (!hist) {
			/*
			 * turn history on
			 */
			INTOFF;
			hist = history_init();
			INTON;

			if (hist != NULL)
				sethistsize(histsizeval());
			else
				out2str("sh: can't initialize history\n");
		}
		if (editing && !el && isatty(0)) { /* && isatty(2) ??? */
			/*
			 * turn editing on
			 */
			char *term, *shname;

			INTOFF;
			if (el_in == NULL)
				el_in = fdopen(0, "r");
			if (el_out == NULL)
				el_out = fdopen(2, "w");
			if (el_in == NULL || el_out == NULL)
				goto bad;
			el_err = el_out;
#if DEBUG
			if (tracefile)
				el_err = tracefile;
#endif
			term = lookupvar("TERM");
			if (term)
				setenv("TERM", term, 1);
			else
				unsetenv("TERM");
			shname = arg0;
			if (shname[0] == '-')
				shname++;
			el = el_init(shname, el_in, el_out, el_err);
			if (el != NULL) {
				if (hist)
					el_set(el, EL_HIST, history, hist);
				el_set(el, EL_PROMPT, getprompt);
				el_set(el, EL_SIGNAL, 1);
				el_set(el, EL_ALIAS_TEXT, alias_text, NULL);
				el_set(el, EL_ADDFN, "rl-complete",
				    "ReadLine compatible completion function",
				    _el_fn_complete);
			} else {
bad:
				out2str("sh: can't initialize editing\n");
			}
			INTON;
		} else if (!editing && el) {
			INTOFF;
			el_end(el);
			el = NULL;
			INTON;
		}
		if (el) {
			el_source(el, NULL);
			if (Vflag)
				el_set(el, EL_EDITOR, "vi");
			else if (Eflag)
				el_set(el, EL_EDITOR, "emacs");
			el_set(el, EL_BIND, "^I", 
			    tabcomplete ? "rl-complete" : "ed-insert", NULL);
		}
	} else {
		INTOFF;
		if (el) {	/* no editing if not interactive */
			el_end(el);
			el = NULL;
		}
		if (hist) {
			history_end(hist);
			hist = NULL;
		}
		INTON;
	}
}
Example #27
0
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;
}
Example #28
0
File: cli.c Project: crxyz/osv
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;
}
Example #29
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);
}
Example #30
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();
		}
	}
}