Beispiel #1
0
int input_init()
{
    int status = CLI_RET_UNKNOWN;

    if (gl) {
        input_deinit();
    }

    gl = new_GetLine(CLI_MAX_LINE_LEN, CLI_MAX_HIST_LEN);

    if (gl) {

        /* Try to set up a clean exit on these signals. If it fails, we'll
        * trudge along with a warning */
        if (gl_trap_signal(gl, SIGINT, GLS_DONT_FORWARD, GLS_ABORT, EINTR)  ||
            gl_trap_signal(gl, SIGQUIT, GLS_DONT_FORWARD, GLS_ABORT, EINTR)) {

            fprintf(stderr, SIGHANLDER_FAILED);
        }

        tab_complete = new_WordCompletion();
        if (tab_complete != NULL) {
            gl_customize_completion(gl, NULL, tab_completion);
        } else {
            /* Non-fatal - complain and carry on */
            fprintf(stderr, "Failed to initialize tab-completion.\n");
        }

        status = 0;
    }

    return status;
}
Beispiel #2
0
/*.......................................................................
 * Create a new DemoRes object containing the resources needed by the
 * demo.
 *
 * Output:
 *  return  DemoRes *  The new object, or NULL on error.
 */
static DemoRes *new_DemoRes(void)
{
  DemoRes *res;  /* The object to be returned */
/*
 * Allocate the container.
 */
  res = (DemoRes *)malloc(sizeof(DemoRes));
  if(!res) {
    fprintf(stderr, "new_DemoRes: Insufficient memory.\n");
    return NULL;
  };
/*
 * Before attempting any operation that might fail, initialize the
 * container at least up to the point at which it can safely be passed
 * to del_DemoRes().
 */
  res->gl = NULL;
  res->pc = NULL;
  res->ppc = NULL;
/*
 * Create the line editor, specifying a max line length of 500 bytes,
 * and 10000 bytes to allocate to storage of historical input lines.
 */
  res->gl = new_GetLine(500, 10000);
  if(!res->gl)
    return del_DemoRes(res);
/*
 * Enable text attribute formatting directives in prompt strings.
 */
  gl_prompt_style(res->gl, GL_FORMAT_PROMPT);
/*
 * Allocate a cache of the executable files found in the user's path.
 */
  res->pc = new_PathCache();
  if(!res->pc)
    return del_DemoRes(res);
/*
 * Populate the cache with the contents of the user's path.
 */
  if(pca_scan_path(res->pc, getenv("PATH")))
    return del_DemoRes(res);
/*
 * Arrange for susequent calls to pca_lookup_file() and pca_path_completions()
 * to only report files that are executable by the user.
 */
  pca_set_check_fn(res->pc, cpl_check_exe, NULL);
/*
 * Allocate a configuration object for use with pca_path_completions().
 */
  res->ppc = new_PcaPathConf(res->pc);
  if(!res->ppc)
    return del_DemoRes(res);
/*
 * Replace the builtin filename completion callback with one which
 * searches for completions of executables in the user's path when
 * invoked on a word at the start of the path, and completes files
 * elsewhere.
 */
  if(gl_customize_completion(res->gl, res, demo_cpl_fn))
    return del_DemoRes(res);
  return res;
}
Beispiel #3
0
int
engine_interp()
{
#ifdef NATIVE_BUILD
	uu_die("native build does not support interactive mode.");
#else
	char *selfmri;
	size_t sfsz;
	int r;

	extern int parens;

	(void) sigset(SIGINT, SIG_IGN);

	est->sc_gl = new_GetLine(512, 8000);
	if (est->sc_gl == NULL)
		uu_die(gettext("Out of memory.\n"));

	/* The longest string is "[snapname]fmri[:instname]> ". */
	sfsz = 1 + max_scf_name_len + 1 + max_scf_fmri_len + 2 +
	    max_scf_name_len + 1 + 2 + 1;
	selfmri = safe_malloc(sfsz);

	r = gl_customize_completion(est->sc_gl, NULL, complete);
	assert(r == 0);

	for (;;) {
		lscf_get_selection_str(selfmri, sfsz - 2);
		(void) strcat(selfmri, "> ");
		est->sc_cmd_buf = gl_get_line(est->sc_gl, selfmri, NULL, -1);

		if (est->sc_cmd_buf == NULL) {
			switch (gl_return_status(est->sc_gl)) {
			case GLR_SIGNAL:
				gl_abandon_line(est->sc_gl);
				continue;

			case GLR_EOF:
				break;

			case GLR_ERROR:
				uu_die(gettext("Error reading terminal: %s.\n"),
				    gl_error_message(est->sc_gl, NULL, 0));
				/* NOTREACHED */

			default:
#ifndef NDEBUG
				(void) fprintf(stderr, "%s:%d: gl_get_line() "
				    "returned unexpected value %d.\n", __FILE__,
				    __LINE__, gl_return_status(est->sc_gl));
#endif
				abort();
			}

			break;
		}

		parens = 0;
		est->sc_cmd_bufsz = strlen(est->sc_cmd_buf);
		est->sc_cmd_bufoff = 0;
		est->sc_cmd_flags = SC_CMD_IACTIVE;

		(void) yyparse();
	}

	free(selfmri);
	est->sc_gl = del_GetLine(est->sc_gl);	/* returns NULL */

#endif	/* NATIVE_BUILD */
	return (0);
}
Beispiel #4
0
int
cexp_main1(int argc, char **argv, void (*callback)(int argc, char **argv, CexpContext ctx))
{
CexpContextRec		context;	/* the public parts of this instance's context */
CexpContext			myContext;
char				*line=0, *prompt=0, *tmp;
char				*symfile=0, *script=0;
int					rval=CEXP_MAIN_INVAL_ARG, quiet=0;
MyGetOptCtxtRec		oc={0}; /* must be initialized */
int					opt;
#ifdef HAVE_TECLA
#define	rl_context  context.gl
#else
#define rl_context  0
#endif
char				optstr[]={
						'h',
						'v',
						's',':',
						'a',':',
						'p',':',
#ifdef YYDEBUG
						'd',
#endif
						'q',
						'\0'
					};

context.prompt = 0;
context.parser = 0;

while ((opt=mygetopt_r(argc, argv, optstr,&oc))>=0) {
	switch (opt) {
		default:  fprintf(stderr,"Unknown Option %c\n",opt);
		case 'h': usage(argv[0]);
		case 'v': version(argv[0]);
			return 0;

#ifdef YYDEBUG
		case 'd': cexpdebug=1;
			break;
#endif
		case 'q': quiet=1;
			break;
		case 's': symfile=oc.optarg;
			break;
		case 'a': cexpBuiltinCpuArch = oc.optarg;
			break;

		case 'p': free(context.prompt); context.prompt = strdup(oc.optarg);
			break;
	}
}

if (argc>oc.optind)
	script=argv[oc.optind];

/* make sure vital code is initialized */

{
	static int initialized=0;
	cexpContextRunOnce(&initialized, cexpInit);
}

if (!cexpSystemModule) {
	if (!symfile) {
		/* try to find a builtin table */
		if ( !cexpModuleLoad(0,0) )
			fprintf(stderr,"No builtin symbol table -- need a symbol file argument\n");
	} else if (!cexpModuleLoad(symfile,"SYSTEM"))
		fprintf(stderr,"Unable to load system symbol table\n");
	if (!cexpSystemModule) {
		usage(argv[0]);
		return CEXP_MAIN_NO_SYMS;
	}
}

#ifdef USE_MDBG
mdbgInit();
#endif

/* initialize the public context */
context.next=0;
#ifdef HAVE_BFD_DISASSEMBLER
{
	extern void cexpDisassemblerInit();
	cexpDisassemblerInit(&context.dinfo, stdout);
}
#endif

cexpContextGetCurrent(&myContext);

if (!myContext) {
	/* topmost frame */
#ifdef HAVE_TECLA
	context.gl = new_GetLine(200,2000);
	if (!context.gl) {
		fprintf(stderr,"Unable to create line editor\n");
		return CEXP_MAIN_NO_MEM;
	}
	/* mute warnings about being unable to 
	 * read ~/.teclarc
	 */
	gl_configure_getline(context.gl,0,0,0);
#endif
	/* register first instance running in this thread's context; */
	cexpContextRegister();
	if (!quiet)
		hello();
} else {
#ifdef HAVE_TECLA
	/* re-use caller's line editor */
	context.gl = myContext->gl;
#endif
}
/* push our frame to the top */
context.next = myContext;
myContext	 = &context;
cexpContextSetCurrent(myContext);

/* See if there is an ancestor with a local prompt
 * and inherit
 */
if ( !context.prompt && context.next && context.next->prompt )
	context.prompt = strdup(context.next->prompt);

do {
	if (!(context.parser=cexpCreateParserCtx(quiet ? 0 : stdout))) {
		fprintf(stderr,"Unable to create parser context\n");
		usage(argv[0]);
		rval = CEXP_MAIN_NO_MEM;
		goto cleanup;
	}

#ifdef HAVE_TECLA
	{
	CPL_MATCH_FN(cexpSymComplete);
	gl_customize_completion(context.gl, context.parser, cexpSymComplete);
	}
#endif

	if (cexpSigHandlerInstaller)
		cexpSigHandlerInstaller(sighandler);

	if (!(rval=setjmp(context.jbuf))) {
		/* call them back to pass the jmpbuf */
		if (callback)
			callback(argc, argv, &context);
	
		if (script) {
			if ( (rval = process_script(context.parser, script, quiet)) )
				goto cleanup;
		} else {

			while ( (line=readline_r(
							checkPrompt( &context, &prompt, argc > 0 ? argv[0] : "Cexp" ),
							rl_context)) ) {
				/* skip empty lines */
				if (*line) {
					if ( '<' == *(tmp=skipsp(line)) ) {
						process_script(context.parser,tmp+1,quiet);
					} else {
						/* interactively process this line */
						cexpResetParserCtx(context.parser,line);
						cexpparse((void*)context.parser);
						add_history(line);
					}
				}
				free(line); line=0;
			}
		}
		
	} else {
			fprintf(stderr,"\nOops, exception caught\n");
			/* setjmp passes 0: first time
			 *               1: longjmp(buf,0) or longjmp(buf,1)
			 *           other: longjmp(buf,other)
			 */
			rval = (rval<2 ? -1 : CEXP_MAIN_KILLED);
	}
	
cleanup:
		script=0;	/* become interactive if script is killed */
		free(line);   			line=0;
		free(prompt);           prompt=0;
		cexpFreeParserCtx(context.parser); context.parser=0;
	
} while (-1==rval);

free(context.prompt);

/* pop our stack context from the chained list anchored 
 * at the running thread
 */
myContext = myContext->next;
cexpContextSetCurrent(myContext);
if ( ! myContext ) {
	/* we'll exit the topmost instance */
#ifdef HAVE_TECLA
	del_GetLine(context.gl);
#endif
	cexpContextUnregister();
}

return rval;
}
Beispiel #5
0
/*.......................................................................
 * This program demonstrates how to use gl_get_line() as a line editor to
 * to enable users to enter input. It takes no arguments.
 */
int main(int argc, char *argv[])
{
  char *line;             /* A line of input */
  GetLine *gl;            /* The line editor */
  int major,minor,micro;  /* The version number of the library */
  int retval;
/*
 * Create the line editor, specifying a max line length of 500 bytes,
 * and 10000 bytes to allocate to storage of historical input lines.
 */
  gl = new_GetLine(500, 5000);
  if(!gl)
    return 1;

  /* setup CLI tab line completion */
  retval = gl_customize_completion(gl,
                                   my_tab_context_string_array,
                                   my_tab_callback);
  if (retval != 0) {
    printf("\nError: cannot set GL tab completion");
    return 1;
  }
/*
 * If the user has the LC_CTYPE or LC_ALL environment variables set,
 * enable display of characters corresponding to the specified locale.
 */
  (void) setlocale(LC_CTYPE, "");
/*
 * Lookup and display the version number of the library.
 */
  libtecla_version(&major, &minor, &micro);
  printf("\n Welcome to the main demo program of libtecla version %d.%d.%d\n",
	 major, minor, micro);
/*
 * Display an introductory banner.
 */
  show_demo_introduction(gl);
/*
 * Load history.
 */
#ifndef WITHOUT_FILE_SYSTEM
  (void) gl_load_history(gl, "~/.demo_history", "#");
#endif
/*
 * Read lines of input from the user and print them to stdout.
 */
  do {
/*
 * Get a new line from the user.
 */
    line = gl_get_line(gl, "$ ", NULL, 0);
    if(!line)
      break;
/*
 * Display what was entered.
 */
    if(printf("You entered: %s", line) < 0 || fflush(stdout))
      break;
/*
 * If the user types "exit", quit the program.
 */
    if(strcmp(line, "exit\n")==0)
      break;
    else if(strcmp(line, "history\n")==0)
      gl_show_history(gl, stdout, "%N  %T   %H\n", 0, -1);
    else if(strcmp(line, "size\n")==0) {
      GlTerminalSize size = gl_terminal_size(gl, 80, 24);
      printf("Terminal size = %d columns x %d lines.\n", size.ncolumn,
	     size.nline);
    } else if(strcmp(line, "clear\n")==0) {
      if(gl_erase_terminal(gl))
	return 1;
    };
  } while(1);
/*
 * Save historical command lines.
 */
#ifndef WITHOUT_FILE_SYSTEM
  (void) gl_save_history(gl, "~/.demo_history", "#", -1);
#endif
/*
 * Clean up.
 */
  gl = del_GetLine(gl);
  return 0;
}
Beispiel #6
0
int
interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
{
	char *pwd;
	char *dir = NULL;
	char cmd[2048];
	struct sftp_conn *conn;
	int err, interactive;
	void *il = NULL;

#ifdef USE_LIBEDIT
        EditLine *el = NULL;
	History *hl = NULL;
	HistEvent hev;

	if (!batchmode && isatty(STDIN_FILENO)) {
		if ((il = el = el_init(__progname, stdin, stdout, stderr)) == NULL)
			fatal("Couldn't initialise editline");
		if ((hl = history_init()) == NULL)
			fatal("Couldn't initialise editline history");
		history(hl, &hev, H_SETSIZE, 100);
		el_set(el, EL_HIST, history, hl);

		el_set(el, EL_PROMPT, prompt);
		el_set(el, EL_EDITOR, "emacs");
		el_set(el, EL_TERMINAL, NULL);
		el_set(el, EL_SIGNAL, 1);
		el_source(el, NULL);
	}
#else
#ifdef USE_LIBTECLA
	GetLine *gl = NULL;

	if (!batchmode && isatty(STDIN_FILENO)) {
		if ((il = gl = new_GetLine(MAX_LINE_LEN, MAX_CMD_HIST)) == NULL)
			fatal("Couldn't initialize GetLine");
		if (gl_customize_completion(gl, NULL, nomatch) != 0) {
			(void) del_GetLine(gl);
			fatal("Couldn't register completion function");
		}
	}
#endif /* USE_LIBTECLA */
#endif /* USE_LIBEDIT */

	conn = do_init(fd_in, fd_out, copy_buffer_len, num_requests);
	if (conn == NULL)
		fatal("Couldn't initialise connection to server");

	pwd = do_realpath(conn, ".");
	if (pwd == NULL)
		fatal("Need cwd");

	if (file1 != NULL) {
		dir = xstrdup(file1);
		dir = make_absolute(dir, pwd);

		if (remote_is_dir(conn, dir) && file2 == NULL) {
			printf(gettext("Changing to: %s\n"), dir);
			snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
			if (parse_dispatch_command(conn, cmd, &pwd, 1) != 0) {
				xfree(dir);
				xfree(pwd);
				xfree(conn);
				return (-1);
			}
		} else {
			if (file2 == NULL)
				snprintf(cmd, sizeof cmd, "get %s", dir);
			else
				snprintf(cmd, sizeof cmd, "get %s %s", dir,
				    file2);

			err = parse_dispatch_command(conn, cmd, &pwd, 1);
			xfree(dir);
			xfree(pwd);
			xfree(conn);
			return (err);
		}
		xfree(dir);
	}

#if defined(HAVE_SETVBUF) && !defined(BROKEN_SETVBUF)
	setvbuf(stdout, NULL, _IOLBF, 0);
	setvbuf(infile, NULL, _IOLBF, 0);
#else
	setlinebuf(stdout);
	setlinebuf(infile);
#endif

	interactive = !batchmode && isatty(STDIN_FILENO);
	err = 0;
	for (;;) {
		char *cp;

		signal(SIGINT, SIG_IGN);

		if (il == NULL) {
			if (interactive)
				printf("sftp> ");
			if (fgets(cmd, sizeof(cmd), infile) == NULL) {
				if (interactive)
					printf("\n");
				break;
			}
			if (!interactive) { /* Echo command */
				printf("sftp> %s", cmd);
				if (strlen(cmd) > 0 &&
				    cmd[strlen(cmd) - 1] != '\n')
					printf("\n");
			}
		}
#ifdef USE_LIBEDIT
		else {
			const char *line;
			int count = 0;

			if ((line = el_gets(el, &count)) == NULL || count <= 0) {
				printf("\n");
 				break;
			}
			history(hl, &hev, H_ENTER, line);
			if (strlcpy(cmd, line, sizeof(cmd)) >= sizeof(cmd)) {
				fprintf(stderr, gettext("Error: input line too long\n"));
				continue;
			}
		}
#else
#ifdef USE_LIBTECLA
		else {
			const char *line;

			line = gl_get_line(gl, "sftp> ", NULL, -1);
			if (line != NULL) {
				if (strlcpy(cmd, line, sizeof(cmd)) >=
				    sizeof(cmd)) {
					fprintf(stderr, gettext(
					    "Error: input line too long\n"));
					continue;
				}
			} else {
				GlReturnStatus rtn;

				rtn = gl_return_status(gl);
				if (rtn == GLR_SIGNAL) {
					gl_abandon_line(gl);
					continue;
				} else if (rtn == GLR_ERROR) {
					fprintf(stderr, gettext(
					    "Error reading terminal: %s/\n"),
					    gl_error_message(gl, NULL, 0));
				}
				break;
			}
		}
#endif /* USE_LIBTECLA */
#endif /* USE_LIBEDIT */

		cp = strrchr(cmd, '\n');
		if (cp)
			*cp = '\0';

		/* Handle user interrupts gracefully during commands */
		interrupted = 0;
		signal(SIGINT, cmd_interrupt);

		err = parse_dispatch_command(conn, cmd, &pwd, batchmode);
		if (err != 0)
			break;
	}