コード例 #1
0
ファイル: exec.c プロジェクト: mywaystar/21sh
static void		shell_exec_pipe(t_cmd *cmd)
{
	t_pipe_cmd	*pcmd;
	int			pipes[2];
	int			pid[2];

	pcmd = (t_pipe_cmd *)cmd;
	if (pipe(pipes) != 0)
		ft_putendl_fd("pipe error", 2);
	else if ((pid[0] = fork()) == 0)
	{
		dup2(pipes[1], STDOUT_FILENO);
		close(pipes[0]);
		shell_exec(pcmd->left);
		exit(0);
	}
	if ((pid[1] = fork()) == 0)
	{
		dup2(pipes[0], STDIN_FILENO);
		close(pipes[1]);
		shell_exec(pcmd->right);
		exit(0);
	}
	close(pipes[0]);
	close(pipes[1]);
	waitpid(-1, 0, 0);
	waitpid(-1, 0, 0);
}
コード例 #2
0
ファイル: shell.c プロジェクト: Sh4d1/projet_mips2016
void shell_loop(void)
{
#ifdef READLINE

    char* input;// shell_prompt[100];
    char **args;
    // Configure readline to auto-complete paths when the tab key is hit.
    rl_bind_key('\t', rl_complete);
    rl_attempted_completion_function = command_completion;

    printf("Bienvenue dans le simulateur MIPS32. N'hésitez pas à utiliser la commande help.\n");
    uint8_t status = 0;
    do {
        input = readline("simips > ");
        if (!input)
            break;
        if (strcmp(input, "") != 0) {
            add_history(input);
        }
        args = shell_split_line(input);
        status = shell_exec(args);
        if (status != OK && status != EMPTY_LINE) {
            printf("%s\n", err_msgs[status]);
        }

        free(input);
        free(args);
    } while (status != QUIT);
    clear_history();
#else
    char *line;
    char **args;

    printf("Bienvenue dans le simulateur MIPS32. N'hésitez pas à utiliser la commande help.\n");
    uint8_t status = 0;
    do {
        printf("simips > ");
        line = shell_read_line();
        args = shell_split_line(line);
        status = shell_exec(args);
        if (status != OK) {
            printf("%s\n", err_msgs[status]);
        }
        free(line);
        free(args);
    } while (status != QUIT);
#endif


}
コード例 #3
0
ファイル: fbcon.c プロジェクト: Julia117/embox
static void *run(void *data) {
	int fd;
	const struct shell *sh;
	struct fbcon *fbcon = (struct fbcon *) data;

	sh = shell_lookup("tish");

	if (!sh) {
		return NULL;
	}

	close(0);
	close(1);
	close(2);

	idesc_init(&fbcon->idesc, &fbcon_idesc_ops, FS_MAY_READ | FS_MAY_WRITE);
	fd = index_descriptor_add(&fbcon->idesc);
	fbcon->vterm.tty.idesc = &fbcon->idesc;

	assert(fd == 0);

	dup2(fd, 1);
	dup2(fd, 2);

	shell_exec(sh, "login");

	return NULL;

}
コード例 #4
0
ファイル: start_script.c プロジェクト: Robotonics/embox
static int run_script(void) {
    const char *command;
    const struct shell *shell;

    shell = shell_lookup(OPTION_STRING_GET(shell_name));
    if (NULL == shell) {
        shell = shell_any();
        if (NULL == shell) {
            return -ENOENT;
        }
    }

    setup_tty(OPTION_STRING_GET(tty_dev));

    printf("\nStarted shell [%s] on device [%s]\n",
           OPTION_STRING_GET(shell_name), OPTION_STRING_GET(tty_dev));

    printf("loading start script:\n");
    array_foreach(command, script_commands, ARRAY_SIZE(script_commands)) {
        int ret;

        printf("> %s \n", command);

        ret = shell_exec(shell, command);

        if (OPTION_GET(BOOLEAN,stop_on_error) && ret) {
            return ret;
        }
    }
コード例 #5
0
ファイル: shell.c プロジェクト: Estella/wraith
void check_last() {
  if (login == DET_IGNORE)
    return;

  if (conf.username) {
    char *out = NULL, buf[50] = "";

    simple_snprintf(buf, sizeof(buf), STR("last -10 %s"), conf.username);
    if (shell_exec(buf, NULL, &out, NULL)) {
      if (out) {
        char *p = NULL;

        p = strchr(out, '\n');
        if (p)
          *p = 0;
        if (strlen(out) > 10) {
          if (last_buf[0]) {
            if (strncmp(last_buf, out, sizeof(last_buf))) {
              char *work = NULL;
              size_t siz = strlen(out) + 7 + 2 + 1;

              work = (char *) my_calloc(1, siz);

              simple_snprintf(work, siz, STR("Login: %s"), out);
              detected(DETECT_LOGIN, work);
              free(work);
            }
          }
          strlcpy(last_buf, out, sizeof(last_buf));
        }
        free(out);
      }
    }
  }
}
コード例 #6
0
ファイル: shell.c プロジェクト: Estella/wraith
void crontab_del() {
  char *tmpFile = NULL, *p = NULL, buf[2048] = "";

  size_t tmplen = strlen(binname) + 100;
  tmpFile = (char *) my_calloc(1, tmplen);

  strlcpy(tmpFile, shell_escape(binname), tmplen);
  if (!(p = strrchr(tmpFile, '/')))
    return;
  p++;
  strcpy(p, STR(".ctb"));
  simple_snprintf(buf, sizeof(buf), STR("crontab -l | grep -v '%s' | grep -v \"^#\" | grep -v \"^\\$\" > %s"), binname, tmpFile);
  if (shell_exec(buf, NULL, NULL, NULL)) {
    simple_snprintf(buf, sizeof(buf), STR("crontab %s"), tmpFile);
    shell_exec(buf, NULL, NULL, NULL);
  }
  unlink(tmpFile);
}
コード例 #7
0
ファイル: system.c プロジェクト: AleksandraButrova/embox
int system(const char *command) {
	const struct shell *sh = shell_any();

	if (!sh) {
		return -ENOENT;
	}

	return shell_exec(sh, command);
}
コード例 #8
0
ファイル: winclip.c プロジェクト: nowox/mintty-1
void
win_open(wstring wpath)
{
  wstring p = wpath;
  while (iswalpha(*p)) p++;
  
  if (*wpath == '\\' || *p == ':') {
    // Looks like it's a Windows path or URI
    shell_exec(wpath);
  }
  else {
    // Need to convert POSIX path to Windows first
    wstring conv_wpath = child_conv_path(wpath);
    delete(wpath);
    if (conv_wpath)
      shell_exec(conv_wpath);
    else
      MessageBox(0, strerror(errno), 0, MB_ICONERROR);
  }
}
コード例 #9
0
ファイル: shell.c プロジェクト: Estella/wraith
void crontab_create(int interval) {
  char tmpFile[161] = "";
  FILE *f = NULL;
  int fd;

  simple_snprintf(tmpFile, sizeof tmpFile, STR("%s.crontab-XXXXXX"), tempdir);
  if ((fd = mkstemp(tmpFile)) == -1) {
    unlink(tmpFile);
    return;
  }

  char buf[256] = "";

  simple_snprintf(buf, sizeof buf, STR("crontab -l | grep -v \"%s\" | grep -v \"^#\" | grep -v \"^\\$\"> %s"), 
                  binname, tmpFile);
  if (shell_exec(buf, NULL, NULL, NULL) && (f = fdopen(fd, "a")) != NULL) {
    buf[0] = 0;
    if (interval == 1)
      strlcpy(buf, "*", 2);
    else {
      int i = 1;
      int si = randint(interval);

      while (i < 60) {
        if (buf[0])
          simple_snprintf(buf, sizeof(buf), "%s,%i", buf[0] ? buf : "", (i + si) % 60);
        else
          simple_snprintf(buf, sizeof(buf), "%i", (i + si) % 60);
        i += interval;
      }
    }
    simple_snprintf(buf + strlen(buf), sizeof buf, STR(" * * * * %s > /dev/null 2>&1"), binname);
    fseek(f, 0, SEEK_END);
    fprintf(f, "\n%s\n", buf);
    fclose(f);
    simple_snprintf(buf, sizeof(buf), STR("crontab %s"), tmpFile);
    shell_exec(buf, NULL, NULL, NULL);
  }
  close(fd);
  unlink(tmpFile);
}
コード例 #10
0
ファイル: exec.c プロジェクト: mywaystar/21sh
static void		shell_exec_redirection(t_cmd *cmd)
{
	t_redirection_cmd	*rcmd;
	int					new_fd;
	int					back_fd;

	rcmd = (t_redirection_cmd *)cmd;
	new_fd = open(rcmd->file, rcmd->mode, S_IRUSR | S_IWUSR);
	back_fd = dup(rcmd->fd);
	dup2(new_fd, rcmd->fd);
	close(new_fd);
	shell_exec(rcmd->cmd);
	dup2(back_fd, rcmd->fd);
}
コード例 #11
0
ファイル: shell.c プロジェクト: Estella/wraith
int crontab_exists() {
  char buf[2048] = "", *out = NULL;

  simple_snprintf(buf, sizeof buf, STR("crontab -l | grep '%s' | grep -v \"^#\""), binname);
  if (shell_exec(buf, NULL, &out, NULL)) {
    if (out && strstr(out, binname)) {
      free(out);
      return 1;
    } else {
      if (out)
        free(out);
      return 0;
    }
  } else
    return (-1);
}
コード例 #12
0
ファイル: shell.c プロジェクト: rsalveti/zephyr
static void shell(void *p1, void *p2, void *p3)
{
	ARG_UNUSED(p1);
	ARG_UNUSED(p2);
	ARG_UNUSED(p3);

	while (1) {
		struct console_input *cmd;

		printk("%s", get_prompt());

		cmd = k_fifo_get(&cmds_queue, K_FOREVER);

		shell_exec(cmd->line);

		k_fifo_put(&avail_queue, cmd);
	}
}
コード例 #13
0
ファイル: debug.c プロジェクト: kirune/wraith
static void write_debug(bool fatal = 1)
{
  if (fatal) {
    segfaulted = 1;
    alarm(0);		/* dont let anything jump out of this signal! */
  }

  putlog(LOG_MISC, "*", "** Paste to bryan:");
  putlog(LOG_MISC, "*", "Version: %s", egg_version);
  const size_t cur_buf = (current_get_buf == 0) ? GET_BUFS - 1 : current_get_buf - 1;
  for (size_t i = 0; i < GET_BUFS; i++)
    putlog(LOG_MISC, "*", "%c %02zu: %s", i == cur_buf ? '*' : '_', i, get_buf[i]);
  putlog(LOG_MISC, "*", "** end");

#ifdef DEBUG
  if (fatal) {
    /* Write GDB backtrace */
    char gdb[1024] = "", btfile[256] = "", std_in[101] = "", *out = NULL;

    simple_snprintf(btfile, sizeof(btfile), ".gdb-backtrace-%d", (int)getpid());

    FILE *f = fopen(btfile, "w");

    if (f) {
      strlcpy(std_in, "bt 100\nbt 100 full\ndetach\nquit\n", sizeof(std_in));
      //simple_snprintf(stdin, sizeof(stdin), "detach\n");
      //simple_snprintf(stdin, sizeof(stdin), "q\n");

      simple_snprintf(gdb, sizeof(gdb), "gdb --pid=%d %s", (int)getpid(), binname);
      shell_exec(gdb, std_in, &out, NULL);
      fprintf(f, "%s\n", out);
      fclose(f);
      free(out);
    }

    //enabling core dumps
    struct rlimit limit;
    if (!getrlimit(RLIMIT_CORE, &limit)) {
      limit.rlim_cur = limit.rlim_max;
      setrlimit(RLIMIT_CORE, &limit);
    }
  }
#endif
}
コード例 #14
0
ファイル: shell.cpp プロジェクト: Jiaozi97/FoxFileSystem
int shell_main(Directory* dir_serv) {
    directory_service = dir_serv;

    fd_init();

    char * line, *cwd;
    char ** token;

    fprintf(stderr, "            FOX Shell Ver 0.000001\n");
    fprintf(stderr, "    built in commands:\n");
    fprintf(stderr, "        ");
    for (int i = 0; i < SH_BUILTIN_COUNT - 1; i++)
    {
        fprintf(stderr, "%s,", builtin_cmds_str[i]);
    }
    fprintf(stderr, "%s\n", builtin_cmds_str[SH_BUILTIN_COUNT - 1]);
    fprintf(stderr, "\n");

    int re = 1;

    while (re) {
        cwd = getcwd(NULL, 0);
        if (cwd == NULL) {
            ERR_ALLO;
        }
        printf("%s $ ", cwd);
        free(cwd);

        line = shell_read_line();
        token = shell_split_line(line);
        re = shell_exec(token);

        free(token);
        free(line);
    }
    return 0;
}
コード例 #15
0
ファイル: home.c プロジェクト: ArduPilot/alceosd
void shell_cmd_home(char *args, void *data)
{
    shell_exec(args, home_cmdmap, data);
}
コード例 #16
0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//message_interpret
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void message_interpret(const char *message, bool from_core, module* caller)
{
    if (!message || !(*message)) return; //If the message is invalid, or empty, don't bother
    if (caller == NULL) caller = currentmodule;

    char buffer[BBI_MAX_LINE_LENGTH];

    // Check, if the message is for us...
    if (memcmp(message, szBBroam, szBBroamLength))
    {
        //The standard BlackBox Messages
        if (!stricmp(message, "@BBShowPlugins"))
        {
            control_pluginsvisible(true);
            return;
        }
        if (!stricmp(message, "@BBHidePlugins"))
        {
            control_pluginsvisible(false);
            return;
        }
        if (!memicmp(message, "@Script",7))
        {
            char* buf = new char[strlen(message)+1]; // local buffer.
            strcpy(buf,message); //NOTE: possible alternate method would be copying out the messages one by one.
            char *start = strchr(buf,'[');
            char *end = strrchr(buf,']');
            if (start && end)
            {
                ++start;
                *end = 0; //terminate string here.
                while (end = strchr(start,'|'))
                {
                    *end = 0;
                    while (*start == ' ') ++start; // skip whitespace
                    message_interpret(start, from_core, caller);
                    start = end+1;
                }
                while (*start == ' ') ++start; // skip whitespace
                message_interpret(start, from_core, caller); // interpret message after last separator character
            }
            else if (!plugin_suppresserrors)
            {
                sprintf(buffer,"Invalid @Script syntax in line:\n\n%s",buf);
                MessageBox(NULL, buffer, szAppName, MB_OK|MB_SYSTEMMODAL);
            }
            delete[] buf;
            return;
        }

        if (from_core) return;
        message = message_preprocess(strcpy(buffer, message)); //NOTE: FIX, possibly should this use the caller argument as well?
        if ('@' == message[0])
        {
            SendMessage(plugin_hwnd_blackbox, BB_BROADCAST, 0, (LPARAM)buffer);
        }
        else
        {
            // bblean only: SendMessage(plugin_hwnd_blackbox, BB_EXECUTE, 0, (LPARAM)string);
            char command[MAX_PATH], arguments[MAX_PATH], *token = command;
            BBTokenize(message, &token, 1, arguments);
            shell_exec(command, arguments);
        }
        return;
    }
    //Tokenize the string
    char *message_tokenptrs[32];
    int tokensfound = tokenize_message(message, 32, message_tokenptrs, buffer, caller);

    //Token Check - we always need at least two tokens for all purposes
    if (tokensfound < 2) return;

    //Find someone to send the message to
    int result = 1;

    for (int i = 0; i < MESSAGE_ENTITY_COUNT; i++)
    {
        if (!strcmp(message_tokenptrs[1], message_entitynames[i]))
        {
            result = (message_functions[i])(tokensfound, message_tokenptrs, from_core, caller);
            break;
        }
    }

    if (1 == result) // 0=ok, 1=error, 2=error&dontcare
    {
        //On an error
        if (!plugin_suppresserrors)
        {
            sprintf(buffer,
                    "There was an error executing your Bro@m command:"
                    "\n"
                    "\n%s"
                    "\n"
                    "\nPossible reasons:"
                    "\n - An control or agent referenced may not exist"
                    "\n - The command may be malformed"
                    "\n - An error occurred while performing the requested action"
                    , message
                   );
            MessageBox(NULL, buffer, szAppName, MB_OK|MB_SYSTEMMODAL);
        }
    }
}
コード例 #17
0
ファイル: tabs.c プロジェクト: ArduPilot/alceosd
void shell_cmd_tabs(char *args, void *data)
{
    shell_exec(args, tabs_cmdmap, data);
}
コード例 #18
0
ファイル: sh.c プロジェクト: arielqw/ariel-ami
// Execute cmd.  Never returns.
void
runcmd(struct cmd *cmd)
{
  int p[2];
  struct backcmd *bcmd;
  struct execcmd *ecmd;
  struct listcmd *lcmd;
  struct pipecmd *pcmd;
  struct redircmd *rcmd;

  if(cmd == 0)
    exit();
  
  switch(cmd->type){
  default:
    panic("runcmd");

  case EXEC:
    ecmd = (struct execcmd*)cmd;
    if(ecmd->argv[0] == 0)
      exit();
    shell_exec(ecmd->argv[0], ecmd->argv, lastExecutedCmd);
    printf(2, "exec %s failed\n", ecmd->argv[0]);
    break;

  case REDIR:
    rcmd = (struct redircmd*)cmd;
    close(rcmd->fd);
    if(open(rcmd->file, rcmd->mode) < 0){
      printf(2, "open %s failed\n", rcmd->file);
      exit();
    }
    runcmd(rcmd->cmd);
    break;

  case LIST:
    lcmd = (struct listcmd*)cmd;
    if(fork1() == 0)
      runcmd(lcmd->left);
    wait();
    runcmd(lcmd->right);
    break;

  case PIPE:
    pcmd = (struct pipecmd*)cmd;
    if(pipe(p) < 0)
      panic("pipe");
    if(fork1() == 0){
      close(1);
      dup(p[1]);
      close(p[0]);
      close(p[1]);
      runcmd(pcmd->left);
    }
    if(fork1() == 0){
      close(0);
      dup(p[0]);
      close(p[0]);
      close(p[1]);
      runcmd(pcmd->right);
    }
    close(p[0]);
    close(p[1]);
    wait();
    wait();
    break;
    
  case BACK:
    bcmd = (struct backcmd*)cmd;
    if(fork1() == 0)
      runcmd(bcmd->cmd);
    break;
  }
  exit();
}
コード例 #19
0
ファイル: shell.c プロジェクト: Estella/wraith
void check_processes()
{
  if (badprocess == DET_IGNORE)
    return;

  char *proclist = NULL, *out = NULL, *p = NULL, *np = NULL, *curp = NULL, buf[1024] = "", bin[128] = "";

  proclist = process_list[0] ? process_list : NULL;

  if (!proclist)
    return;

  if (!shell_exec("ps x", NULL, &out, NULL))
    return;

  /* Get this binary's filename */
  strlcpy(buf, shell_escape(binname), sizeof(buf));
  p = strrchr(buf, '/');
  if (p) {
    p++;
    strlcpy(bin, p, sizeof(bin));
  } else {
    bin[0] = 0;
  }
  /* Fix up the "permitted processes" list */
  p = (char *) my_calloc(1, strlen(proclist) + strlen(bin) + 6);
  strcpy(p, proclist);
  strcat(p, " ");
  strcat(p, bin);
  strcat(p, " ");
  proclist = p;
  curp = out;
  while (curp) {
    np = strchr(curp, '\n');
    if (np)
      *np++ = 0;
    if (atoi(curp) > 0) {
      char *pid = NULL, *tty = NULL, *mystat = NULL, *mytime = NULL, cmd[512] = "", line[2048] = "";

      strlcpy(line, curp, sizeof(line));
      /* it's a process line */
      /* Assuming format: pid tty stat time cmd */
      pid = newsplit(&curp);
      tty = newsplit(&curp);
      mystat = newsplit(&curp);
      mytime = newsplit(&curp);
      strlcpy(cmd, curp, sizeof(cmd));
      /* skip any <defunct> procs "/bin/sh -c" crontab stuff and binname crontab stuff */
      if (!strstr(cmd, "<defunct>") && !strncmp(cmd, "/bin/sh -c", 10) && 
          !strncmp(cmd, shell_escape(binname), strlen(shell_escape(binname)))) {
        /* get rid of any args */
        if ((p = strchr(cmd, ' ')))
          *p = 0;
        /* remove [] or () */
        if (strlen(cmd)) {
          p = cmd + strlen(cmd) - 1;
          if (((cmd[0] == '(') && (*p == ')')) || ((cmd[0] == '[') && (*p == ']'))) {
            *p = 0;
            strcpy(buf, cmd + 1);
            strcpy(cmd, buf);
          }
        }

        /* remove path */
        if ((p = strrchr(cmd, '/'))) {
          p++;
          strcpy(buf, p);
          strcpy(cmd, buf);
        }

        /* skip "ps" */
        if (strcmp(cmd, "ps")) {
          /* see if proc's in permitted list */
          strcat(cmd, " ");
          if ((p = strstr(proclist, cmd))) {
            /* Remove from permitted list */
            while (*p != ' ')
              *p++ = 1;
          } else {
            char *work = NULL;
            size_t size = 0;

            size = strlen(line) + 22;
            work = (char *) my_calloc(1, size);
            simple_snprintf(work, size, "Unexpected process: %s", line);
            detected(DETECT_PROCESS, work);
            free(work);
          }
        }
      }
    }
    curp = np;
  }
  free(proclist);
  if (out)
    free(out);
}
コード例 #20
0
ファイル: mavlink.c プロジェクト: ericyao2013/alceosd
void shell_cmd_mavlink(char *args, void *data)
{
    shell_exec(args, mavlink_cmdmap, data);
}
コード例 #21
0
ファイル: run.c プロジェクト: testfarm/testfarm
int run_loop(void)
{
  return shell_exec(run_shell);
}
コード例 #22
0
ファイル: winclip.c プロジェクト: nobk/mintty
void
win_open(wstring wpath)
{
  wstring p = wpath;
  while (iswalpha(*p)) p++;
  if (*wpath == '\\' || *p == ':' || wcsncmp(W("www."), wpath, 4) == 0) {
    // Looks like it's a Windows path or URI
    shell_exec(wpath);
  }
  else {
    // Need to convert POSIX path to Windows first
    if (support_wsl) {
#ifdef debug_wsl
      printf("open <%ls>\n", wpath);
#endif
      if (wcsncmp(wpath, W("/mnt/"), 5) == 0) {
        wchar * unwsl = newn(wchar, wcslen(wpath) + 6);
        wcscpy(unwsl, W("/cygdrive"));
        wcscat(unwsl, wpath + 4);
        delete(wpath);
        wpath = unwsl;
      }
      else if (*wpath == '/') {  // prepend %LOCALAPPDATA%\lxss[\rootfs]
        char * appd = getenv("LOCALAPPDATA");
        if (appd) {
          wchar * wappd = cs__mbstowcs(appd);
          appd = path_win_w_to_posix(wappd);
          free(wappd);
          wappd = cs__mbstowcs(appd);
          free(appd);

          bool rootfs_mount = true;
          for (uint i = 0; i < lengthof(lxss_mounts); i++) {
            if (ispathprefixw(lxss_mounts[i].w, wpath)) {
              rootfs_mount = false;
              break;
            }
          }

          wchar * unwsl = newn(wchar, wcslen(wappd) + wcslen(wpath) + 13);
          wcscpy(unwsl, wappd);
          free(wappd);
          wcscat(unwsl, W("/lxss"));
          if (rootfs_mount)
            wcscat(unwsl, W("/rootfs"));
          wcscat(unwsl, wpath);
          delete(wpath);
          wpath = unwsl;
        }
      }
    }
    wstring conv_wpath = child_conv_path(wpath);
#ifdef debug_wsl
    printf("open <%ls> <%ls>\n", wpath, conv_wpath);
#endif
    delete(wpath);
    if (conv_wpath)
      shell_exec(conv_wpath);
    else
      message_box(0, strerror(errno), null, MB_ICONERROR, null);
  }
}
コード例 #23
0
/*
** Read input from *in and process it.  If *in==0 then input
** is interactive - the user is typing it it.  Otherwise, input
** is coming from a file or device.  A prompt is issued and history
** is saved only if input is interactive.  An interrupt signal will
** cause this routine to exit immediately, unless input is interactive.
**
** Return the number of errors.
*/
static int process_input(struct callback_data *p, FILE *in){
	char *zLine = 0;
	char *zSql = 0;
	int nSql = 0;
	int nSqlPrior = 0;
	char *zErrMsg;
	int rc;
	int errCnt = 0;
	int lineno = 0;
	int startline = 0;

	while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
		//fflush(p->out);
		free(zLine);
		zLine = one_input_line(in);
		if( zLine==0 ){
			break;  /* We have reached EOF */
		}
		if( seenInterrupt ){
			if( in!=0 ) break;
			seenInterrupt = 0;
		}
		lineno++;
		if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
		if( zLine && zLine[0]=='.' && nSql==0 ){
			continue;
		}
		if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
			memcpy(zLine,";",2);
		}
		nSqlPrior = nSql;
		if( zSql==0 ){
			int i;
			for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
			if( zLine[i]!=0 ){
				nSql = strlen30(zLine);
				zSql = (char*)malloc( nSql+3 );
				if( zSql==0 ){
					fprintf(stderr, "Error: out of memory\n");
					exit(1);
				}
				memcpy(zSql, zLine, nSql+1);
				startline = lineno;
			}
		}else{
			int len = strlen30(zLine);
			zSql = (char*)realloc( zSql, nSql + len + 4 );
			if( zSql==0 ){
				fprintf(stderr,"Error: out of memory\n");
				exit(1);
			}
			zSql[nSql++] = '\n';
			memcpy(&zSql[nSql], zLine, len+1);
			nSql += len;
		}
		if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
			&& sqlite3_complete(zSql) ){
				p->cnt = 0;
				//
				rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);

				if( rc || zErrMsg ){
					char zPrefix[100];
					if( in!=0 || !stdin_is_interactive ){
						sqlite3_snprintf(sizeof(zPrefix), zPrefix, 
							"Error: near line %d:", startline);
					}else{
						sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
					}
					if( zErrMsg!=0 ){
						fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
						sqlite3_free(zErrMsg);
						zErrMsg = 0;
					}else{
						fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
					}
					errCnt++;
				}
				free(zSql);
				zSql = 0;
				nSql = 0;
		}
	}
	if( zSql ){
		if( !_all_whitespace(zSql) ){
			fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
		}
		free(zSql);
	}
	free(zLine);
	return errCnt;
}