示例#1
0
int main(void) {
  
  // Allocate a buffer for the command line read from the user. 
  char command_line_buffer[COMMAND_LINE_BUFFER_SIZE];
  
  // Parse the command line using the next_command() parser. The
  // parser will populate the following array with the result of each call
  // to the parser.
  char* argv[MAX_ARGV_SIZE];  
    
  // Count the number of non empty command lines.
  int command_line_nr = 0;
  
  // Count the number of children forked for each command line. 
  int num_of_children = 0; 
  
  while(1) {

    command_line_nr = read_command_line(command_line_nr, 
                                        command_line_buffer, 
                                        COMMAND_LINE_BUFFER_SIZE);
    
    num_of_children = execute_command_line(command_line_buffer, argv);

    for (int i = 0; i < num_of_children; i ++) {
      // TODO 1: Make the parent wait for all children. 
      wait(NULL);
    }


    fflush(NULL);
 
  } // end while(1)
} // end of main()
示例#2
0
int		main(int argc, char **argv, char **envp)
{
	t_ftsh	*sh;

	sh = NULL;
	sh = intialize_sh(argc, argv, envp);
	if (!sh)
	{
		ft_putendl_fd("Error : could'nt initialize shell", 2);
		return (1);
	}
	while (1)
	{
		catch_signals();
		if (sh->line)
			free(sh->line);
		sh->line = NULL;
		write(1, sh->prompt, ft_strlen(sh->prompt));
		if ((sh->line = get_command_line()) != NULL)
		{
			sh->ret = execute_command_line(sh, &(sh->env_dup));
			ft_tabfree(sh->path_dir);
			sh->path_dir = extract_path_directories(sh->env_dup);
		}
		else
			exit(1);
	}
}
示例#3
0
static void mimeview_view_file(const gchar *filename, MimeInfo *partinfo,
			       const gchar *cmdline)
{
	static gchar *default_image_cmdline = "display '%s'";
	static gchar *default_audio_cmdline = "play '%s'";
	static gchar *default_html_cmdline = DEFAULT_BROWSER_CMD;
	static gchar *mime_cmdline = "metamail -d -b -x -c %s '%s'";
	gchar buf[1024];
	gchar m_buf[1024];
	const gchar *cmd;
	const gchar *def_cmd;
	const gchar *p;

	if (cmdline) {
		cmd = cmdline;
		def_cmd = NULL;
	} else if (MIMETYPE_APPLICATION == partinfo->type &&
		   !g_strcasecmp(partinfo->subtype, "octet-stream")) {
		return;
	} else if (MIMETYPE_IMAGE == partinfo->type) {
		cmd = prefs_common.mime_image_viewer;
		def_cmd = default_image_cmdline;
	} else if (MIMETYPE_AUDIO == partinfo->type) {
		cmd = prefs_common.mime_audio_player;
		def_cmd = default_audio_cmdline;
	} else if (MIMETYPE_TEXT == partinfo->type && !strcmp(partinfo->subtype, "html")) {
		cmd = prefs_common.uri_cmd;
		def_cmd = default_html_cmdline;
	} else {
		gchar *content_type;
		
		content_type = procmime_get_content_type_str(partinfo->type, partinfo->subtype);
		g_snprintf(m_buf, sizeof(m_buf), mime_cmdline,
			   content_type, "%s");
		g_free(content_type);
		cmd = m_buf;
		def_cmd = NULL;
	}

	if (cmd && (p = strchr(cmd, '%')) && *(p + 1) == 's' &&
	    !strchr(p + 2, '%'))
		g_snprintf(buf, sizeof(buf), cmd, filename);
	else {
		if (cmd)
			g_warning("MIME viewer command line is invalid: `%s'", cmd);
		if (def_cmd)
			g_snprintf(buf, sizeof(buf), def_cmd, filename);
		else
			return;
	}

	execute_command_line(buf, TRUE);
}
示例#4
0
void console_tick(void)
{
    switch(console_mode)
    {
        case CONSOLE_MODE_LINE:
            if (got_line)
            {
                if (cmdbuf_len > 0)
                    execute_command_line(cmdbuf, cmdbuf_len);
                cmdbuf_len = 0;
                prompt();
                got_line = FALSE;
            }
        break;
        default:
        break;
    }
}
示例#5
0
void
execute_command_line_i8 (const char *command, GFC_LOGICAL_8 *wait,
			 GFC_INTEGER_8 *exitstat, GFC_INTEGER_8 *cmdstat,
			 char *cmdmsg, gfc_charlen_type command_len,
			 gfc_charlen_type cmdmsg_len)
{
  bool w = wait ? *wait : true;
  int estat, estat_initial, cstat;

  if (exitstat)
    estat_initial = estat = *exitstat;

  execute_command_line (command, w, &estat, cmdstat ? &cstat : NULL,
			cmdmsg, command_len, cmdmsg_len);

  if (exitstat && estat != estat_initial)
    *exitstat = estat;
  if (cmdstat)
    *cmdstat = cstat;
}
示例#6
0
文件: shell.c 项目: lingmar/os16
int main(void) {

    // Allocate a buffer for the command line read from the user.
    char command_line_buffer[COMMAND_LINE_BUFFER_SIZE];

    // Parse the command line using the next_command() parser. The
    // parser will populate the following array with the result of each call
    // to the parser.
    char* argv[MAX_ARGV_SIZE];

    // Count the number of non empty command lines.
    int command_line_nr = 0;

    // Count the number of children forked for each command line.
    int num_of_children = 0;

    while(1) {

        command_line_nr = read_command_line(command_line_nr,
                                            command_line_buffer,
                                            COMMAND_LINE_BUFFER_SIZE);

        num_of_children = execute_command_line(command_line_buffer, argv);

        int status;
        int ret;
        for (int i = 0; i < num_of_children; i ++) {
            ret = wait(&status);
            if (ret < 0) {
                perror("Something went wrong.\n");
                exit(EXIT_FAILURE);
            }
        }


        fflush(NULL);

    } // end while(1)
} // end of main()
示例#7
0
文件: inc.c 项目: mrvdb/claws-mail
void inc_mail(MainWindow *mainwin, gboolean notify)
{
	gint new_msgs = 0;
	gint account_new_msgs = 0;

	if (inc_lock_count) return;

	if (prefs_common.work_offline && 
	    !inc_offline_should_override(TRUE,
		_("Claws Mail needs network access in order "
		  "to get mails.")))
		return;

	inc_lock();
	inc_autocheck_timer_remove();
	main_window_lock(mainwin);

	if (prefs_common.use_extinc && prefs_common.extinc_cmd) {
		/* external incorporating program */
		if (execute_command_line(prefs_common.extinc_cmd, FALSE) < 0) {
			main_window_unlock(mainwin);
			inc_autocheck_timer_set();
			inc_unlock();
			return;
		}
	} else {
		account_new_msgs = inc_account_mail_real(mainwin, cur_account);
		if (account_new_msgs > 0)
			new_msgs += account_new_msgs;
	}

	inc_update_stats(new_msgs);
	inc_finished(mainwin, new_msgs > 0, FALSE);
	main_window_unlock(mainwin);
 	inc_notify_cmd(new_msgs, notify);
	inc_autocheck_timer_set();
	inc_unlock();
}
示例#8
0
int bogofilter_learn(MsgInfo *msginfo, GSList *msglist, gboolean spam)
{
	gchar *cmd = NULL;
	gchar *file = NULL;
	const gchar *bogo_exec = (config.bogopath && *config.bogopath) ? config.bogopath:"bogofilter";
	gint status = 0;

	if (msginfo == NULL && msglist == NULL) {
		return -1;
	}

	if (msginfo) {
		file = procmsg_get_message_file(msginfo);
		if (file == NULL) {
			return -1;
		} else {
			if (message_callback != NULL)
				message_callback(_("Bogofilter: learning from message..."), 0, 0, FALSE);
			if (spam)
				/* learn as spam */
				cmd = g_strdup_printf("%s -s -I '%s'", bogo_exec, file);
			else if (MSG_IS_SPAM(msginfo->flags))
				/* correct bogofilter, this wasn't spam */
				cmd = g_strdup_printf("%s -Sn -I '%s'", bogo_exec, file);
			else 
				/* learn as ham */
				cmd = g_strdup_printf("%s -n -I '%s'", bogo_exec, file);
				
			debug_print("%s\n", cmd);
			if ((status = execute_command_line(cmd, FALSE, NULL)) != 0)
				log_error(LOG_PROTOCOL, _("Learning failed; `%s` returned with status %d."),
						cmd, status);
			g_free(cmd);
			g_free(file);
			if (message_callback != NULL)
				message_callback(NULL, 0, 0, FALSE);
		}
	} else if (msglist) {
		GSList *cur = msglist;
		MsgInfo *info;
		int total = g_slist_length(msglist);
		int done = 0;
		gboolean some_correction = FALSE, some_no_correction = FALSE;
	
		if (message_callback != NULL)
			message_callback(_("Bogofilter: learning from messages..."), total, 0, FALSE);
		
		for (cur = msglist; cur && status == 0; cur = cur->next) {
			info = (MsgInfo *)cur->data;
			if (spam)
				some_no_correction = TRUE;
			else if (MSG_IS_SPAM(info->flags))
				/* correct bogofilter, this wasn't spam */
				some_correction = TRUE;
			else 
				some_no_correction = TRUE;
			
		}
		
		if (some_correction && some_no_correction) {
			/* we potentially have to do different stuff for every mail */
			for (cur = msglist; cur && status == 0; cur = cur->next) {
				info = (MsgInfo *)cur->data;
				file = procmsg_get_message_file(info);

				if (spam)
					/* learn as spam */
					cmd = g_strdup_printf("%s -s -I '%s'", bogo_exec, file);
				else if (MSG_IS_SPAM(info->flags))
					/* correct bogofilter, this wasn't spam */
					cmd = g_strdup_printf("%s -Sn -I '%s'", bogo_exec, file);
				else 
					/* learn as ham */
					cmd = g_strdup_printf("%s -n -I '%s'", bogo_exec, file);
				
				debug_print("%s\n", cmd);
				if ((status = execute_command_line(cmd, FALSE, NULL)) != 0)
					log_error(LOG_PROTOCOL, _("Learning failed; `%s` returned with status %d."),
							cmd, status);

				g_free(cmd);
				g_free(file);
				done++;
				if (message_callback != NULL)
					message_callback(NULL, total, done, FALSE);
			}
		} else if (some_correction || some_no_correction) {
			cur = msglist;
			
			gchar *bogo_args[4];
			GPid bogo_pid;
			gint bogo_stdin;
			GError *error = NULL;
			gboolean bogo_forked;

			bogo_args[0] = (gchar *)bogo_exec;
			if (some_correction && !some_no_correction)
				bogo_args[1] = "-Sn";
			else if (some_no_correction && !some_correction)
				bogo_args[1] = spam ? "-s":"-n";
			bogo_args[2] = "-b";
			bogo_args[3] = NULL;
			debug_print("|%s %s %s ...\n", bogo_args[0], bogo_args[1], bogo_args[2]);
			bogo_forked = g_spawn_async_with_pipes(
					NULL, bogo_args,NULL, G_SPAWN_SEARCH_PATH|G_SPAWN_DO_NOT_REAP_CHILD,
					NULL, NULL, &bogo_pid, &bogo_stdin,
					NULL, NULL, &error);

			while (bogo_forked && cur) {
				gchar *tmp = NULL;
				info = (MsgInfo *)cur->data;
				file = procmsg_get_message_file(info);
				if (file) {
					tmp = g_strdup_printf("%s\n", 
						file);
					write_all(bogo_stdin, tmp, strlen(tmp));
					g_free(tmp);
				}
				g_free(file);
				done++;
				if (message_callback != NULL)
					message_callback(NULL, total, done, FALSE);
				cur = cur->next;
			}
			if (bogo_forked) {
				close(bogo_stdin);
				waitpid(bogo_pid, &status, 0);
				if (!WIFEXITED(status))
					status = -1;
				else
					status = WEXITSTATUS(status);
			}
			if (!bogo_forked || status != 0) {
				log_error(LOG_PROTOCOL, _("Learning failed; `%s %s %s` returned with error:\n%s"),
						bogo_args[0], bogo_args[1], bogo_args[2], 
						error ? error->message:_("Unknown error"));
				if (error)
					g_error_free(error);
			}

		}

		if (message_callback != NULL)
			message_callback(NULL, 0, 0, FALSE);
	}
	return 0;
}
示例#9
0
文件: inc.c 项目: mrvdb/claws-mail
void inc_all_account_mail(MainWindow *mainwin, gboolean autocheck,
			  gboolean notify)
{
	GList *list, *queue_list = NULL;
	IncProgressDialog *inc_dialog;
	gint new_msgs = 0;
	gint account_new_msgs = 0;
	
	if (prefs_common.work_offline && 
	    !inc_offline_should_override( (autocheck == FALSE),
		_("Claws Mail needs network access in order "
		  "to get mails.")))
		return;

	if (inc_lock_count) return;

	inc_autocheck_timer_remove();
	main_window_lock(mainwin);

	list = account_get_list();
	if (!list) {
		inc_update_stats(new_msgs);
		inc_finished(mainwin, new_msgs > 0, autocheck);
		main_window_unlock(mainwin);
 		inc_notify_cmd(new_msgs, notify);
		inc_autocheck_timer_set();
		return;
	}

	if (prefs_common.use_extinc && prefs_common.extinc_cmd) {
		/* external incorporating program */
		if (execute_command_line(prefs_common.extinc_cmd, FALSE) < 0) {
			log_error(LOG_PROTOCOL, _("%s failed\n"), prefs_common.extinc_cmd);
			
			main_window_unlock(mainwin);
			inc_autocheck_timer_set();
			return;
		}
	}
	
	/* check local folders */
	account_new_msgs = inc_all_spool();
	if (account_new_msgs > 0)
		new_msgs += account_new_msgs;

	/* check IMAP4 / News folders */
	for (list = account_get_list(); list != NULL; list = list->next) {
		PrefsAccount *account = list->data;
		if ((account->protocol == A_IMAP4 ||
		     account->protocol == A_NNTP) && account->recv_at_getall) {
			new_msgs += folderview_check_new(FOLDER(account->folder));
		}
	}

	/* check POP3 accounts */
	for (list = account_get_list(); list != NULL; list = list->next) {
		IncSession *session;
		PrefsAccount *account = list->data;

		if (account->recv_at_getall) {
			session = inc_session_new(account);
			if (session)
				queue_list = g_list_append(queue_list, session);
		}
	}

	if (queue_list) {
		inc_dialog = inc_progress_dialog_create(autocheck);
		inc_dialog->queue_list = queue_list;
		inc_dialog->mainwin = mainwin;
		inc_progress_dialog_set_list(inc_dialog);

		toolbar_main_set_sensitive(mainwin);
		main_window_set_menu_sensitive(mainwin);
		new_msgs += inc_start(inc_dialog);
	}

	inc_update_stats(new_msgs);
	inc_finished(mainwin, new_msgs > 0, autocheck);
	main_window_unlock(mainwin);
 	inc_notify_cmd(new_msgs, notify);
	inc_autocheck_timer_set();
}
示例#10
0
static void mimeview_view_file(const gchar *filename, MimeInfo *partinfo,
			       const gchar *cmdline)
{
	const gchar *cmd = NULL;
	gchar buf[BUFFSIZE];

	if (!cmdline) {
#ifdef G_OS_WIN32
		DWORD dwtype;

		if (g_file_test(filename, G_FILE_TEST_IS_EXECUTABLE) ||
		    str_has_suffix_case(filename, ".scr") ||
		    str_has_suffix_case(filename, ".pif") ||
		    GetBinaryType(filename, &dwtype)) {
			alertpanel_full
				(_("Opening executable file"),
				 _("This is an executable file. Opening executable file is restricted for security.\n"
				   "If you want to launch it, save it to somewhere and make sure it is not an virus or something like a malicious program."),
				 ALERT_WARNING, G_ALERTDEFAULT, FALSE,
				 GTK_STOCK_OK, NULL, NULL);
			return;
		}
		execute_open_file(filename, partinfo->content_type);
		return;
#elif defined(__APPLE__)
		if (g_file_test(filename, G_FILE_TEST_IS_EXECUTABLE) ||
		    str_has_suffix_case(filename, ".py") ||
		    str_has_suffix_case(filename, ".rb") ||
		    str_has_suffix_case(filename, ".sh")) {
			alertpanel_full
				(_("Opening executable file"),
				 _("This is an executable file. Opening executable file is restricted for security.\n"
				   "If you want to launch it, save it to somewhere and make sure it is not an virus or something like a malicious program."),
				 ALERT_WARNING, G_ALERTDEFAULT, FALSE,
				 GTK_STOCK_OK, NULL, NULL);
			return;
		}
		execute_open_file(filename, partinfo->content_type);
		return;
#else
		if (MIME_IMAGE == partinfo->mime_type)
			cmd = prefs_common.mime_image_viewer;
		else if (MIME_AUDIO == partinfo->mime_type)
			cmd = prefs_common.mime_audio_player;
		else if (MIME_TEXT_HTML == partinfo->mime_type)
			cmd = prefs_common.uri_cmd;
		if (!cmd) {
			if (prefs_common.mime_cmd) {
				if (str_find_format_times
					(prefs_common.mime_cmd, 's') == 2) {
					g_snprintf(buf, sizeof(buf),
						   prefs_common.mime_cmd,
						   partinfo->content_type,
						   "%s");
					cmd = buf;
				} else
					cmd = prefs_common.mime_cmd;
			} else {
				procmime_execute_open_file
					(filename, partinfo->content_type);
				return;
			}
		}
#endif
	} else
		cmd = cmdline;

	if (cmd && str_find_format_times(cmd, 's') == 1) {
		gchar *cmdbuf;
		cmdbuf = g_strdup_printf(cmd, filename);
		execute_command_line(cmdbuf, TRUE);
		g_free(cmdbuf);
	} else if (cmd)
		g_warning("MIME viewer command line is invalid: '%s'", cmd);
}
示例#11
0
int spamassassin_learn(MsgInfo *msginfo, GSList *msglist, gboolean spam)
{
	gchar *cmd = NULL;
	gchar *file = NULL;
	const gchar *shell = g_getenv("SHELL");
	gchar *spamc_wrapper = NULL;

	if (msginfo == NULL && msglist == NULL) {
		return -1;
	}

	if (config.transport == SPAMASSASSIN_TRANSPORT_TCP
	&&  prefs_common_get_prefs()->work_offline
	&&  !inc_offline_should_override(TRUE,
		_("Claws Mail needs network access in order "
		  "to feed the mail to the remote learner."))) {
		return -1;
	}

	if (msginfo) {
		file = procmsg_get_message_file(msginfo);
		if (file == NULL) {
			return -1;
		}
		if (config.transport == SPAMASSASSIN_TRANSPORT_TCP) {
			spamc_wrapper = spamassassin_create_tmp_spamc_wrapper(spam);
			if (spamc_wrapper != NULL) {
				cmd = g_strconcat(shell?shell:"sh", " ",
								spamc_wrapper, " ", file, NULL);
			}
		} else {
			cmd = g_strdup_printf("sa-learn -u %s%s %s %s",
							config.username,
							prefs_common_get_prefs()->work_offline?" -L":"",
							spam?"--spam":"--ham", file);
		}
	}
	if (msglist) {
		GSList *cur = msglist;
		MsgInfo *info;

		if (config.transport == SPAMASSASSIN_TRANSPORT_TCP) {
			/* execute n-times the spamc command */
			for (; cur; cur = cur->next) {
				info = (MsgInfo *)cur->data;
				gchar *tmpcmd = NULL;
				gchar *tmpfile = get_tmp_file();

				if (spamc_wrapper == NULL) {
					spamc_wrapper = spamassassin_create_tmp_spamc_wrapper(spam);
				}

				if (spamc_wrapper && tmpfile &&
			    	copy_file(procmsg_get_message_file(info), tmpfile, TRUE) == 0) {
					tmpcmd = g_strconcat(shell?shell:"sh", " ", spamc_wrapper, " ",
										tmpfile, NULL);
					debug_print("%s\n", tmpcmd);
					execute_command_line(tmpcmd, FALSE, NULL);
					g_free(tmpcmd);
				}
				g_free(tmpfile);
			}
			g_free(spamc_wrapper);
			return 0;
		} else {
			cmd = g_strdup_printf("sa-learn -u %s%s %s",
					config.username,
					prefs_common_get_prefs()->work_offline?" -L":"",
					spam?"--spam":"--ham");

			/* concatenate all message tmpfiles to the sa-learn command-line */
			for (; cur; cur = cur->next) {
				info = (MsgInfo *)cur->data;
				gchar *tmpcmd = NULL;
				gchar *tmpfile = get_tmp_file();

				if (tmpfile &&
			    	copy_file(procmsg_get_message_file(info), tmpfile, TRUE) == 0) {			
					tmpcmd = g_strconcat(cmd, " ", tmpfile, NULL);
					g_free(cmd);
					cmd = tmpcmd;
				}
				g_free(tmpfile);
			}
		}
	}
	if (cmd == NULL) {
		return -1;
	}
	debug_print("%s\n", cmd);
	/* only run sync calls to sa-learn/spamc to prevent system lockdown */
	execute_command_line(cmd, FALSE, NULL);
	g_free(cmd);
	g_free(spamc_wrapper);

	return 0;
}
示例#12
0
文件: ne.c 项目: vigna/ne
int main(int argc, char **argv) {

	char *locale = setlocale(LC_ALL, "");
	for(int i = 0; i < 256; i++) localised_up_case[i] = toupper(i);

	if (locale) {
		struct re_pattern_buffer re_pb;
		struct re_registers re_reg;
		memset(&re_pb, 0, sizeof re_pb);
		memset(&re_reg, 0, sizeof re_reg);

		re_pb.translate = localised_up_case;
		re_compile_pattern(LOCALE_REGEX, strlen(LOCALE_REGEX), &re_pb);
		if (re_search(&re_pb, locale, strlen(locale), 0, strlen(locale), &re_reg) >= 0) {
			if (re_reg.start[1] >= 0) io_utf8 = true;
		}
		free(re_reg.start);
		free(re_reg.end);
	}

	bool no_config = false;
	char *macro_name = NULL, *key_bindings_name = NULL, *menu_conf_name = NULL, *startup_prefs_name = DEF_PREFS_NAME;

	char * const skiplist = calloc(argc, 1);
	if (!skiplist) exit(1);  /* We need this many flags. */

	for(int i = 1; i < argc; i++) {

		if (argv[i][0] == '-' && (!strcmp(&argv[i][1], "h") || !strcmp(&argv[i][1], "-help" "\0" VERSION_STRING))) {
			puts(ARG_HELP);
			exit(0);
		}

		/* Special arguments start with two dashes. If we find one, we
		   cancel its entry in argv[], so that it will be skipped when opening
		   the specified files. The only exception is +N for skipping to the
		   N-th line. */

		if (argv[i][0] == '-' && argv[i][1] == '-') {
			if (!argv[i][2]) i++; /* You can use "--" to force the next token to be a filename */
			else if (!strcmp(&argv[i][2], "noconfig") || !strcmp(&argv[i][2], "no-config")) {
				no_config = true;
				skiplist[i] = 1; /* argv[i] = NULL; */
			}
			else if (!strcmp(&argv[i][2], "noansi") || !strcmp(&argv[i][2], "no-ansi")) {
				ansi = false;
				skiplist[i] = 1; /* argv[i] = NULL; */
			}
			else if (!strcmp(&argv[i][2], "no-syntax")) {
				do_syntax = false;
				skiplist[i] = 1; /* argv[i] = NULL; */
			}
			else if (!strcmp(&argv[i][2], "prefs")) {
				if (i < argc-1) {
					startup_prefs_name = argv[i+1];
					skiplist[i] = skiplist[i+1] = 1; /* argv[i] = argv[i+1] = NULL; */
				}
			}
			else if (!strcmp(&argv[i][2], "ansi")) {
				ansi = true;
				skiplist[i] = 1; /* argv[i] = NULL; */
			}
			else if (!strcmp(&argv[i][2], "utf8")) {
				io_utf8 = true;
				skiplist[i] = 1; /* argv[i] = NULL; */
			}
			else if (!strcmp(&argv[i][2], "no-utf8")) {
				io_utf8 = false;
				skiplist[i] = 1; /* argv[i] = NULL; */
			}
			else if (!strcmp(&argv[i][2], "macro")) {
				if (i < argc-1) {
					macro_name = argv[i+1];
					skiplist[i] = skiplist[i+1] = 1; /* argv[i] = argv[i+1] = NULL; */
				}
			}
			else if (!strcmp(&argv[i][2], "keys")) {
				if (i < argc-1) {
					key_bindings_name = argv[i+1];
					skiplist[i] = skiplist[i+1] = 1; /* argv[i] = argv[i+1] = NULL; */
				}
			}
			else if (!strcmp(&argv[i][2], "menus")) {
				if (i < argc-1) {
					menu_conf_name = argv[i+1];
					skiplist[i] = skiplist[i+1] = 1; /* argv[i] = argv[i+1] = NULL; */
				}
			}
		}
	}

#ifdef NE_TEST
	/* Dump the builtin menu and key bindings to compare to
	   doc/default.menus and doc/default.keys. */
	int dump_config(void);
	dump_config();
#endif

	/* Unless --noconfig was specified, we try to configure the
	   menus and the keyboard. Note that these functions can exit() on error. */

	if (!no_config) {
		get_menu_configuration(menu_conf_name);
		get_key_bindings(key_bindings_name);
	}

	/* If we cannot even create a buffer, better go... */

	if (!new_buffer()) exit(1);

	/* Now that key_bindings are loaded, try to fix up the message for NOT_FOUND. */
	{
		char *repeat_last_keystroke, *new_not_found;
		if ((repeat_last_keystroke = find_key_strokes(REPEATLAST_A, 1))) {
			if ((new_not_found = malloc(39+strlen(repeat_last_keystroke)))) {
				strcat(strcat(strcpy(new_not_found, "Not Found. (RepeatLast with "), repeat_last_keystroke), " to wrap.)");
				error_msg[NOT_FOUND] = new_not_found;
			}
			free(repeat_last_keystroke);
		}
	}

	clear_buffer(cur_buffer);

	/* The INT_MAX clip always exists, and it is used by the Through command. */

	clip_desc * const cd = alloc_clip_desc(INT_MAX, 0);
	if (!cd) exit(1);

	add_head(&clips, &cd->cd_node);

	/* General terminfo and cursor motion initalization. From here onwards,
	   we cannot exit() lightly. */

	term_init();

	/* We will be always using the last line for the status bar. */

	set_terminal_window(ne_lines-1);

	/* We read in all the key capabilities. */

	read_key_capabilities();

	/* Some initializations of other modules... */

	re_set_syntax(
		RE_CONTEXT_INDEP_ANCHORS |
		RE_CONTEXT_INDEP_OPS     | RE_HAT_LISTS_NOT_NEWLINE |
		RE_NEWLINE_ALT           | RE_NO_BK_PARENS          |
		RE_NO_BK_VBAR            | RE_NO_EMPTY_RANGES
	);

	bool first_file = true;

	load_virtual_extensions();
	load_auto_prefs(cur_buffer, startup_prefs_name);

	buffer *stdin_buffer = NULL;
	if (!isatty(fileno(stdin))) {
		first_file = false;
		const int error = load_fd_in_buffer(cur_buffer, fileno(stdin));
		print_error(error);
		stdin_buffer = cur_buffer;

		if (!(freopen("/dev/tty", "r", stdin))) {
			fprintf(stderr, "Cannot reopen input tty\n");
			abort();
		}
	}

	/* The terminal is prepared for interactive I/O. */

	set_interactive_mode();

	clear_entire_screen();

	/* This function sets fatal_code() as signal interrupt handler
	   for all the dangerous signals (SIGILL, SIGSEGV etc.). */

	set_fatal_code();

	if (argc > 1) {

		/* The first file opened does not need a NEWDOC_A action. Note that
		   file loading can be interrupted (wildcarding can sometimes produce
		   unwanted results). */

		uint64_t first_line = 0, first_col = 0;
		bool binary = false, skip_plus = false, read_only = false;
		stop = false;

		for(int i = 1; i < argc && !stop; i++) {
			if (argv[i] && !skiplist[i]) {
				if (argv[i][0] == '+' && !skip_plus) {       /* looking for "+", or "+N" or "+N,M"  */
					uint64_t tmp_l = INT64_MAX, tmp_c = 0;
					char *d;
					errno = 0;
					if (argv[i][1]) {
						if (isdigit((unsigned char)argv[i][1])) {
							tmp_l = strtoll(argv[i]+1, &d, 10);
							if (!errno) {
								if (*d) {  /* separator between N and M */
									if (isdigit((unsigned char)d[1])) {
										tmp_c = strtoll(d+1, &d, 10);
										if (*d) errno = ERANGE;
									}
									else errno = ERANGE;
								}
							}
						}
						else errno = ERANGE;
					}
					if (!errno) {
						first_line = tmp_l;
						first_col  = tmp_c;
					}
					else {
						skip_plus = true;
						i--;
					}
				}
				else if (!strcmp(argv[i], "--binary")) {
					binary = true;
				}
				else if (!strcmp(argv[i], "--read-only") || !strcmp(argv[i], "--readonly") || !strcmp(argv[i], "--ro")) {
					read_only = true;
				}
				else {
					if (!strcmp(argv[i], "-") && stdin_buffer) {
						stdin_buffer->opt.binary = binary;
						if (read_only) stdin_buffer->opt.read_only = read_only;
						if (first_line) do_action(stdin_buffer, GOTOLINE_A, first_line, NULL);
						if (first_col)  do_action(stdin_buffer, GOTOCOLUMN_A, first_col, NULL);
						stdin_buffer = NULL;
					}
					else {
						if (!strcmp(argv[i], "--")) i++;
						if (!first_file) do_action(cur_buffer, NEWDOC_A, -1, NULL);
						else first_file = false;
						cur_buffer->opt.binary = binary;
						if (i < argc) do_action(cur_buffer, OPEN_A, 0, str_dup(argv[i]));
						if (first_line) do_action(cur_buffer, GOTOLINE_A, first_line, NULL);
						if (first_col)  do_action(cur_buffer, GOTOCOLUMN_A, first_col, NULL);
						if (read_only) cur_buffer->opt.read_only = read_only;
					}
					first_line =
					first_col  = 0;
					skip_plus  =
					binary    =
					read_only  = false;
				}
			}
		}

		free(skiplist);

		/* This call makes current the first specified file. It is called
		   only if more than one buffer exist. */

		if (get_nth_buffer(1)) do_action(cur_buffer, NEXTDOC_A, -1, NULL);

	}

	/* We delay updates. In this way the macro activity does not cause display activity. */

	reset_window();
	delay_update();

	if (macro_name) do_action(cur_buffer, MACRO_A, -1, str_dup(macro_name));
	else if (first_file) {
		/* If there is no file to load, and no macro to execute, we display
		   the "NO WARRANTY" message. */
		about();
	}

	while(true) {
		/* If we are displaying the "NO WARRANTY" info, we should not refresh the
		   window now */
		if (!displaying_info) {
			refresh_window(cur_buffer);
			if (cur_buffer->opt.automatch) automatch_bracket(cur_buffer, true);
		}

		draw_status_bar();
		move_cursor(cur_buffer->cur_y, cur_buffer->cur_x);

		int c = get_key_code();

		if (window_changed_size) {
			print_error(do_action(cur_buffer, REFRESH_A, 0, NULL));
			window_changed_size = displaying_info = false;
			cur_buffer->automatch.shown = 0;
		}

		if (c == INVALID_CHAR) continue; /* Window resizing. */
		const input_class ic = CHAR_CLASS(c);

		if (displaying_info) {
			refresh_window(cur_buffer);
			displaying_info = false;
		}

		if (cur_buffer->automatch.shown) automatch_bracket(cur_buffer, false);

		switch(ic) {
		case INVALID:
			print_error(INVALID_CHARACTER);
			break;

		case ALPHA:
			print_error(do_action(cur_buffer, INSERTCHAR_A, c, NULL));
			break;

		case TAB:
			print_error(do_action(cur_buffer, INSERTTAB_A, 1, NULL));
			break;

		case RETURN:
			print_error(do_action(cur_buffer, INSERTLINE_A, -1, NULL));
			break;

		case COMMAND:
			if (c < 0) c = -c - 1;
			if (key_binding[c]) print_error(execute_command_line(cur_buffer, key_binding[c]));
			break;

		default:
			break;
		}
	}
}