2011-10-15 14:56:47 +04:00
|
|
|
/*
|
|
|
|
Main program for the Midnight Commander
|
|
|
|
|
2024-01-01 09:46:17 +03:00
|
|
|
Copyright (C) 1994-2024
|
2014-02-12 10:33:10 +04:00
|
|
|
Free Software Foundation, Inc.
|
2011-10-15 14:56:47 +04:00
|
|
|
|
|
|
|
Written by:
|
|
|
|
Miguel de Icaza, 1994, 1995, 1996, 1997
|
|
|
|
Janne Kukonlehto, 1994, 1995
|
|
|
|
Norbert Warmuth, 1997
|
2009-08-03 13:50:36 +04:00
|
|
|
|
2011-10-15 14:56:47 +04:00
|
|
|
This file is part of the Midnight Commander.
|
2009-08-03 13:50:36 +04:00
|
|
|
|
2011-10-15 14:56:47 +04:00
|
|
|
The Midnight Commander is free software: you can redistribute it
|
|
|
|
and/or modify it under the terms of the GNU General Public License as
|
|
|
|
published by the Free Software Foundation, either version 3 of the License,
|
|
|
|
or (at your option) any later version.
|
2009-08-03 13:50:36 +04:00
|
|
|
|
2011-10-15 14:56:47 +04:00
|
|
|
The Midnight Commander is distributed in the hope that it will be useful,
|
1998-02-27 07:54:42 +03:00
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
2011-10-15 14:56:47 +04:00
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2009-02-05 21:28:18 +03:00
|
|
|
/** \file main.c
|
|
|
|
* \brief Source: this is a main module
|
|
|
|
*/
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
#include <config.h>
|
|
|
|
|
2005-02-08 12:04:03 +03:00
|
|
|
#include <ctype.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <locale.h>
|
2012-10-19 13:08:54 +04:00
|
|
|
#include <pwd.h> /* for username in xterm title */
|
1998-02-27 07:54:42 +03:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2020-02-01 11:49:47 +03:00
|
|
|
#include <sys/types.h>
|
2009-02-27 14:54:26 +03:00
|
|
|
#include <sys/wait.h>
|
2011-09-14 02:07:31 +04:00
|
|
|
#include <signal.h>
|
2020-02-01 11:49:47 +03:00
|
|
|
#include <unistd.h> /* getsid() */
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2010-01-20 18:11:52 +03:00
|
|
|
#include "lib/global.h"
|
2009-05-09 19:17:57 +04:00
|
|
|
|
2011-01-17 12:44:25 +03:00
|
|
|
#include "lib/event.h"
|
2010-01-08 17:47:19 +03:00
|
|
|
#include "lib/tty/tty.h"
|
2010-04-30 17:31:06 +04:00
|
|
|
#include "lib/tty/key.h" /* For init_key() */
|
2013-02-08 10:39:54 +04:00
|
|
|
#include "lib/tty/mouse.h" /* init_mouse() */
|
2010-02-15 14:21:30 +03:00
|
|
|
#include "lib/skin.h"
|
2010-01-21 16:06:15 +03:00
|
|
|
#include "lib/filehighlight.h"
|
2010-11-22 15:02:59 +03:00
|
|
|
#include "lib/fileloc.h"
|
2010-07-08 11:32:37 +04:00
|
|
|
#include "lib/strutil.h"
|
2010-11-22 14:45:18 +03:00
|
|
|
#include "lib/util.h"
|
2011-02-10 18:02:54 +03:00
|
|
|
#include "lib/vfs/vfs.h" /* vfs_init(), vfs_shut() */
|
2010-01-21 13:30:08 +03:00
|
|
|
|
2020-08-19 09:33:24 +03:00
|
|
|
#include "filemanager/filemanager.h"
|
2010-11-22 17:15:28 +03:00
|
|
|
#include "filemanager/treestore.h" /* tree_store_save */
|
2019-12-02 21:58:58 +03:00
|
|
|
#include "filemanager/layout.h"
|
2010-11-22 17:15:28 +03:00
|
|
|
#include "filemanager/ext.h" /* flush_extension_file() */
|
|
|
|
#include "filemanager/command.h" /* cmdline */
|
2011-11-10 00:08:31 +04:00
|
|
|
#include "filemanager/panel.h" /* panalized_panel */
|
2024-05-09 10:23:32 +03:00
|
|
|
#include "filemanager/filenot.h" /* my_rmdir() */
|
2010-11-22 17:15:28 +03:00
|
|
|
|
2024-02-23 12:36:18 +03:00
|
|
|
#ifdef USE_INTERNAL_EDIT
|
|
|
|
#include "editor/edit.h" /* edit_arg_free() */
|
|
|
|
#endif
|
|
|
|
|
2011-02-15 16:44:17 +03:00
|
|
|
#include "vfs/plugins_init.h"
|
|
|
|
|
2011-01-17 12:44:25 +03:00
|
|
|
#include "events_init.h"
|
2010-11-22 14:45:18 +03:00
|
|
|
#include "args.h"
|
2012-10-19 19:24:57 +04:00
|
|
|
#ifdef ENABLE_SUBSHELL
|
2015-11-10 15:54:40 +03:00
|
|
|
#include "subshell/subshell.h"
|
2012-10-19 19:24:57 +04:00
|
|
|
#endif
|
2021-02-14 21:37:23 +03:00
|
|
|
#include "keymap.h"
|
2010-11-28 14:21:17 +03:00
|
|
|
#include "setup.h" /* load_setup() */
|
2010-04-30 17:31:06 +04:00
|
|
|
|
2010-11-22 14:45:18 +03:00
|
|
|
#ifdef HAVE_CHARSET
|
|
|
|
#include "lib/charsets.h"
|
|
|
|
#include "selcodepage.h"
|
|
|
|
#endif /* HAVE_CHARSET */
|
2010-04-30 17:31:06 +04:00
|
|
|
|
2011-02-10 18:02:54 +03:00
|
|
|
#include "consaver/cons.saver.h" /* cons_saver_pid */
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2010-11-22 14:45:18 +03:00
|
|
|
/*** global variables ****************************************************************************/
|
2010-04-30 17:31:06 +04:00
|
|
|
|
2010-11-22 14:45:18 +03:00
|
|
|
/*** file scope macro definitions ****************************************************************/
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2010-11-22 14:45:18 +03:00
|
|
|
/*** file scope type declarations ****************************************************************/
|
2010-11-10 14:09:42 +03:00
|
|
|
|
Update template for .c files.
Add section for forward declarations of local functions. This section is
located before file scope variables because functions can be used in
strucutres (see find.c for example):
/*** forward declarations (file scope functions) *************************************************/
/* button callbacks */
static int start_stop (WButton * button, int action);
static int find_do_view_file (WButton * button, int action);
static int find_do_edit_file (WButton * button, int action);
/*** file scope variables ************************************************************************/
static struct
{
...
bcback_fn callback;
} fbuts[] =
{
...
{ B_STOP, NORMAL_BUTTON, N_("S&uspend"), 0, 0, NULL, start_stop },
...
{ B_VIEW, NORMAL_BUTTON, N_("&View - F3"), 0, 0, NULL, find_do_view_file },
{ B_VIEW, NORMAL_BUTTON, N_("&Edit - F4"), 0, 0, NULL, find_do_edit_file }
};
Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
2023-02-24 09:27:11 +03:00
|
|
|
/*** forward declarations (file scope functions) *************************************************/
|
|
|
|
|
2010-11-22 14:45:18 +03:00
|
|
|
/*** file scope variables ************************************************************************/
|
1998-02-27 07:54:42 +03:00
|
|
|
|
Update template for .c files.
Add section for forward declarations of local functions. This section is
located before file scope variables because functions can be used in
strucutres (see find.c for example):
/*** forward declarations (file scope functions) *************************************************/
/* button callbacks */
static int start_stop (WButton * button, int action);
static int find_do_view_file (WButton * button, int action);
static int find_do_edit_file (WButton * button, int action);
/*** file scope variables ************************************************************************/
static struct
{
...
bcback_fn callback;
} fbuts[] =
{
...
{ B_STOP, NORMAL_BUTTON, N_("S&uspend"), 0, 0, NULL, start_stop },
...
{ B_VIEW, NORMAL_BUTTON, N_("&View - F3"), 0, 0, NULL, find_do_view_file },
{ B_VIEW, NORMAL_BUTTON, N_("&Edit - F4"), 0, 0, NULL, find_do_edit_file }
};
Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
2023-02-24 09:27:11 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2010-11-22 14:45:18 +03:00
|
|
|
/*** file scope functions ************************************************************************/
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
static void
|
2010-11-22 14:45:18 +03:00
|
|
|
check_codeset (void)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2010-11-22 14:45:18 +03:00
|
|
|
const char *current_system_codepage = NULL;
|
2009-09-21 16:34:15 +04:00
|
|
|
|
2010-11-22 14:45:18 +03:00
|
|
|
current_system_codepage = str_detect_termencoding ();
|
2009-10-24 12:58:02 +04:00
|
|
|
|
2010-11-22 14:45:18 +03:00
|
|
|
#ifdef HAVE_CHARSET
|
2010-04-30 17:31:06 +04:00
|
|
|
{
|
2010-11-22 14:45:18 +03:00
|
|
|
const char *_display_codepage;
|
2002-10-31 07:31:52 +03:00
|
|
|
|
2011-02-10 18:02:54 +03:00
|
|
|
_display_codepage = get_codepage_id (mc_global.display_codepage);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2010-11-22 14:45:18 +03:00
|
|
|
if (strcmp (_display_codepage, current_system_codepage) != 0)
|
|
|
|
{
|
2011-02-10 18:02:54 +03:00
|
|
|
mc_global.display_codepage = get_codepage_index (current_system_codepage);
|
|
|
|
if (mc_global.display_codepage == -1)
|
|
|
|
mc_global.display_codepage = 0;
|
2009-11-06 14:41:54 +03:00
|
|
|
|
2016-04-26 09:30:42 +03:00
|
|
|
mc_config_set_string (mc_global.main_config, CONFIG_MISC_SECTION, "display_codepage",
|
2012-01-28 19:28:45 +04:00
|
|
|
cp_display);
|
2010-11-22 14:45:18 +03:00
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2010-11-22 14:45:18 +03:00
|
|
|
#endif
|
2009-11-06 14:41:54 +03:00
|
|
|
|
2011-02-10 18:02:54 +03:00
|
|
|
mc_global.utf8_display = str_isutf8 (current_system_codepage);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2013-09-02 19:50:34 +04:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2010-11-22 14:45:18 +03:00
|
|
|
/** POSIX version. The only version we support. */
|
2015-11-11 15:43:11 +03:00
|
|
|
|
1998-12-03 00:27:27 +03:00
|
|
|
static void
|
2001-06-15 02:33:00 +04:00
|
|
|
OS_Setup (void)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2012-03-16 14:53:34 +04:00
|
|
|
const char *datadir_env;
|
2009-06-30 21:49:40 +04:00
|
|
|
|
2015-11-11 15:43:11 +03:00
|
|
|
mc_shell_init ();
|
2012-03-16 14:53:34 +04:00
|
|
|
|
|
|
|
/* This is the directory, where MC was installed, on Unix this is DATADIR */
|
Fix various typos in the source code (closes MidnightCommander/mc#177).
Found via `codespell -S
po,doc,./misc/syntax,./src/vfs/extfs/helpers/README.it -L
parm,rouge,sav,ect,vie,te,dum,clen,wee,dynamc,childs,ths,fo,nin,unx,nd,iif,iterm,ser,makrs,wil`
Co-authored-by: Yury V. Zaytsev <yury@shurup.com>
Signed-off-by: Kian-Meng Ang <kianmeng@cpan.org>
Signed-off-by: Yury V. Zaytsev <yury@shurup.com>
2023-01-10 06:02:52 +03:00
|
|
|
/* and can be overridden by the MC_DATADIR environment variable */
|
2012-03-16 14:53:34 +04:00
|
|
|
datadir_env = g_getenv ("MC_DATADIR");
|
|
|
|
if (datadir_env != NULL)
|
|
|
|
mc_global.sysconfig_dir = g_strdup (datadir_env);
|
|
|
|
else
|
|
|
|
mc_global.sysconfig_dir = g_strdup (SYSCONFDIR);
|
|
|
|
|
|
|
|
mc_global.share_data_dir = g_strdup (DATADIR);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
static void
|
|
|
|
sigchld_handler_no_subshell (int sig)
|
|
|
|
{
|
2003-02-27 08:09:35 +03:00
|
|
|
#ifdef __linux__
|
1998-02-27 07:54:42 +03:00
|
|
|
int pid, status;
|
|
|
|
|
2014-04-07 16:06:20 +04:00
|
|
|
if (mc_global.tty.console_flag == '\0')
|
2010-04-30 17:31:06 +04:00
|
|
|
return;
|
2002-10-31 07:31:52 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
/* COMMENT: if it were true that after the call to handle_console(..INIT)
|
2011-02-10 18:02:54 +03:00
|
|
|
the value of mc_global.tty.console_flag never changed, we could simply not install
|
|
|
|
this handler at all if (!mc_global.tty.console_flag && !mc_global.tty.use_subshell). */
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
/* That comment is no longer true. We need to wait() on a sigchld
|
|
|
|
handler (that's at least what the tarfs code expects currently). */
|
|
|
|
|
|
|
|
pid = waitpid (cons_saver_pid, &status, WUNTRACED | WNOHANG);
|
2002-10-31 07:31:52 +03:00
|
|
|
|
2010-04-30 17:31:06 +04:00
|
|
|
if (pid == cons_saver_pid)
|
|
|
|
{
|
|
|
|
if (WIFSTOPPED (status))
|
|
|
|
{
|
|
|
|
/* Someone has stopped cons.saver - restart it */
|
|
|
|
kill (pid, SIGCONT);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* cons.saver has died - disable console saving */
|
|
|
|
handle_console (CONSOLE_DONE);
|
2011-02-10 18:02:54 +03:00
|
|
|
mc_global.tty.console_flag = '\0';
|
2010-04-30 17:31:06 +04:00
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2005-02-08 22:59:45 +03:00
|
|
|
/* If we got here, some other child exited; ignore it */
|
2010-04-30 17:31:06 +04:00
|
|
|
#endif /* __linux__ */
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2005-02-08 22:59:45 +03:00
|
|
|
(void) sig;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2003-10-15 01:58:56 +04:00
|
|
|
static void
|
1998-02-27 07:54:42 +03:00
|
|
|
init_sigchld (void)
|
|
|
|
{
|
|
|
|
struct sigaction sigchld_action;
|
|
|
|
|
2013-11-17 09:55:18 +04:00
|
|
|
memset (&sigchld_action, 0, sizeof (sigchld_action));
|
1998-02-27 07:54:42 +03:00
|
|
|
sigchld_action.sa_handler =
|
2012-10-19 19:24:57 +04:00
|
|
|
#ifdef ENABLE_SUBSHELL
|
2011-02-10 18:02:54 +03:00
|
|
|
mc_global.tty.use_subshell ? sigchld_handler :
|
2012-10-19 19:24:57 +04:00
|
|
|
#endif /* ENABLE_SUBSHELL */
|
2010-04-30 17:31:06 +04:00
|
|
|
sigchld_handler_no_subshell;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
sigemptyset (&sigchld_action.sa_mask);
|
|
|
|
|
|
|
|
#ifdef SA_RESTART
|
2001-08-18 19:18:56 +04:00
|
|
|
sigchld_action.sa_flags = SA_RESTART;
|
2010-04-30 17:31:06 +04:00
|
|
|
#endif /* !SA_RESTART */
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2024-07-28 19:50:55 +03:00
|
|
|
if (my_sigaction (SIGCHLD, &sigchld_action, NULL) == -1)
|
2010-04-30 17:31:06 +04:00
|
|
|
{
|
2012-10-19 19:24:57 +04:00
|
|
|
#ifdef ENABLE_SUBSHELL
|
2010-04-30 17:31:06 +04:00
|
|
|
/*
|
|
|
|
* This may happen on QNX Neutrino 6, where SA_RESTART
|
|
|
|
* is defined but not implemented. Fallback to no subshell.
|
|
|
|
*/
|
2011-02-10 18:02:54 +03:00
|
|
|
mc_global.tty.use_subshell = FALSE;
|
2012-10-19 19:24:57 +04:00
|
|
|
#endif /* ENABLE_SUBSHELL */
|
2001-08-18 19:18:56 +04:00
|
|
|
}
|
2002-10-31 07:31:52 +03:00
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2020-02-01 11:49:47 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
|
|
* Check MC_SID to prevent running one mc from another.
|
|
|
|
*
|
|
|
|
* @return TRUE if no parent mc in our session was found, FALSE otherwise.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
check_sid (void)
|
|
|
|
{
|
|
|
|
pid_t my_sid, old_sid;
|
|
|
|
const char *sid_str;
|
|
|
|
|
|
|
|
sid_str = getenv ("MC_SID");
|
|
|
|
if (sid_str == NULL)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
old_sid = (pid_t) strtol (sid_str, NULL, 0);
|
|
|
|
if (old_sid == 0)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
my_sid = getsid (0);
|
|
|
|
if (my_sid == -1)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
/* The parent mc is in a different session, it's OK */
|
|
|
|
return (old_sid != my_sid);
|
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/*** public functions ****************************************************************************/
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
1999-04-17 02:02:09 +04:00
|
|
|
int
|
2002-10-31 07:31:52 +03:00
|
|
|
main (int argc, char *argv[])
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2014-07-15 16:53:06 +04:00
|
|
|
GError *mcerror = NULL;
|
2012-03-04 17:53:38 +04:00
|
|
|
int exit_code = EXIT_FAILURE;
|
2024-05-09 10:23:32 +03:00
|
|
|
const char *tmpdir = NULL;
|
2009-05-02 14:45:48 +04:00
|
|
|
|
2020-02-01 11:49:47 +03:00
|
|
|
mc_global.run_from_parent_mc = !check_sid ();
|
|
|
|
|
1998-03-25 08:16:00 +03:00
|
|
|
/* We had LC_CTYPE before, LC_ALL includs LC_TYPE as well */
|
2012-10-13 09:50:10 +04:00
|
|
|
#ifdef HAVE_SETLOCALE
|
2011-09-14 02:07:31 +04:00
|
|
|
(void) setlocale (LC_ALL, "");
|
2012-10-13 09:50:10 +04:00
|
|
|
#endif
|
|
|
|
(void) bindtextdomain (PACKAGE, LOCALEDIR);
|
|
|
|
(void) textdomain (PACKAGE);
|
1998-12-30 05:51:01 +03:00
|
|
|
|
2012-03-16 11:06:17 +04:00
|
|
|
/* do this before args parsing */
|
|
|
|
str_init_strings (NULL);
|
|
|
|
|
2017-04-13 20:27:46 +03:00
|
|
|
mc_setup_run_mode (argv); /* are we mc? editor? viewer? etc... */
|
|
|
|
|
2014-07-15 16:53:06 +04:00
|
|
|
if (!mc_args_parse (&argc, &argv, "mc", &mcerror))
|
2011-01-17 12:44:25 +03:00
|
|
|
{
|
2012-03-23 13:49:46 +04:00
|
|
|
startup_exit_falure:
|
2014-07-15 16:53:06 +04:00
|
|
|
fprintf (stderr, _("Failed to run:\n%s\n"), mcerror->message);
|
|
|
|
g_error_free (mcerror);
|
2012-03-23 13:49:46 +04:00
|
|
|
startup_exit_ok:
|
2015-11-11 15:43:11 +03:00
|
|
|
mc_shell_deinit ();
|
2012-03-04 17:53:38 +04:00
|
|
|
str_uninit_strings ();
|
|
|
|
return exit_code;
|
2011-01-17 12:44:25 +03:00
|
|
|
}
|
2010-12-29 18:12:59 +03:00
|
|
|
|
2023-12-27 10:22:24 +03:00
|
|
|
/* check terminal type
|
|
|
|
* $TERM must be set and not empty
|
|
|
|
* mc_global.tty.xterm_flag is used in init_key() and tty_init()
|
|
|
|
* Do this after mc_args_parse() where mc_args__force_xterm is set up.
|
|
|
|
*/
|
|
|
|
mc_global.tty.xterm_flag = tty_check_term (mc_args__force_xterm);
|
|
|
|
|
2012-03-16 14:53:34 +04:00
|
|
|
/* do this before mc_args_show_info () to view paths in the --datadir-info output */
|
|
|
|
OS_Setup ();
|
|
|
|
|
|
|
|
if (!g_path_is_absolute (mc_config_get_home_dir ()))
|
|
|
|
{
|
2014-07-15 16:53:06 +04:00
|
|
|
mc_propagate_error (&mcerror, 0, "%s: %s", _("Home directory path is not absolute"),
|
|
|
|
mc_config_get_home_dir ());
|
2012-03-16 14:53:34 +04:00
|
|
|
mc_event_deinit (NULL);
|
|
|
|
goto startup_exit_falure;
|
|
|
|
}
|
|
|
|
|
2012-03-16 11:06:17 +04:00
|
|
|
if (!mc_args_show_info ())
|
|
|
|
{
|
|
|
|
exit_code = EXIT_SUCCESS;
|
|
|
|
goto startup_exit_ok;
|
|
|
|
}
|
|
|
|
|
2014-07-15 16:53:06 +04:00
|
|
|
if (!events_init (&mcerror))
|
2012-03-16 11:06:17 +04:00
|
|
|
goto startup_exit_falure;
|
2012-03-04 17:53:38 +04:00
|
|
|
|
2014-07-15 16:53:06 +04:00
|
|
|
mc_config_init_config_paths (&mcerror);
|
|
|
|
if (mcerror != NULL)
|
2012-03-04 17:53:38 +04:00
|
|
|
{
|
2012-03-16 11:06:17 +04:00
|
|
|
mc_event_deinit (NULL);
|
2012-03-04 17:53:38 +04:00
|
|
|
goto startup_exit_falure;
|
|
|
|
}
|
2011-02-16 15:23:29 +03:00
|
|
|
|
1998-08-27 00:23:10 +04:00
|
|
|
vfs_init ();
|
2011-02-10 18:02:54 +03:00
|
|
|
vfs_plugins_init ();
|
1998-12-02 08:18:20 +03:00
|
|
|
|
2014-01-05 20:26:24 +04:00
|
|
|
load_setup ();
|
|
|
|
|
|
|
|
/* Must be done after load_setup because depends on mc_global.vfs.cd_symlinks */
|
|
|
|
vfs_setup_work_dir ();
|
|
|
|
|
2013-06-14 13:49:47 +04:00
|
|
|
/* Set up temporary directory after VFS initialization */
|
2024-05-09 10:23:32 +03:00
|
|
|
tmpdir = mc_tmpdir ();
|
2013-06-14 13:49:47 +04:00
|
|
|
|
2014-01-05 20:26:24 +04:00
|
|
|
/* do this after vfs initialization and vfs working directory setup
|
|
|
|
due to mc_setctl() and mcedit_arg_vpath_new() calls in mc_setup_by_args() */
|
2014-07-15 16:53:06 +04:00
|
|
|
if (!mc_setup_by_args (argc, argv, &mcerror))
|
2012-03-04 17:53:38 +04:00
|
|
|
{
|
2024-05-09 10:23:32 +03:00
|
|
|
/* At exit, do this before vfs_shut():
|
|
|
|
normally, temporary directory should be empty */
|
|
|
|
vfs_expire (TRUE);
|
|
|
|
(void) my_rmdir (tmpdir);
|
|
|
|
|
2012-03-16 11:06:17 +04:00
|
|
|
vfs_shut ();
|
2014-01-05 20:26:24 +04:00
|
|
|
done_setup ();
|
|
|
|
g_free (saved_other_dir);
|
2012-03-16 11:06:17 +04:00
|
|
|
mc_event_deinit (NULL);
|
|
|
|
goto startup_exit_falure;
|
2012-03-04 17:53:38 +04:00
|
|
|
}
|
2005-07-21 00:29:08 +04:00
|
|
|
|
2016-10-09 09:59:13 +03:00
|
|
|
/* Resolve the other_dir panel option.
|
|
|
|
* 1. Must be done after vfs_setup_work_dir().
|
|
|
|
* 2. Must be done after mc_setup_by_args() because of mc_run_mode.
|
|
|
|
*/
|
|
|
|
if (mc_global.mc_run_mode == MC_RUN_FULL)
|
|
|
|
{
|
|
|
|
char *buffer;
|
|
|
|
vfs_path_t *vpath;
|
|
|
|
|
|
|
|
buffer = mc_config_get_string (mc_global.panels_config, "Dirs", "other_dir", ".");
|
|
|
|
vpath = vfs_path_from_str (buffer);
|
|
|
|
if (vfs_file_is_local (vpath))
|
|
|
|
saved_other_dir = buffer;
|
|
|
|
else
|
|
|
|
g_free (buffer);
|
2021-02-21 19:30:18 +03:00
|
|
|
vfs_path_free (vpath, TRUE);
|
2016-10-09 09:59:13 +03:00
|
|
|
}
|
|
|
|
|
2009-07-12 14:22:41 +04:00
|
|
|
/* NOTE: This has to be called before tty_init or whatever routine
|
1998-02-27 07:54:42 +03:00
|
|
|
calls any define_sequence */
|
|
|
|
init_key ();
|
|
|
|
|
|
|
|
/* Must be done before installing the SIGCHLD handler [[FIXME]] */
|
|
|
|
handle_console (CONSOLE_INIT);
|
2002-10-31 07:31:52 +03:00
|
|
|
|
2012-10-19 19:24:57 +04:00
|
|
|
#ifdef ENABLE_SUBSHELL
|
2020-02-01 11:49:47 +03:00
|
|
|
/* Disallow subshell when invoked as standalone viewer or editor from running mc */
|
|
|
|
if (mc_global.mc_run_mode != MC_RUN_FULL && mc_global.run_from_parent_mc)
|
|
|
|
mc_global.tty.use_subshell = FALSE;
|
|
|
|
|
2011-02-10 18:02:54 +03:00
|
|
|
if (mc_global.tty.use_subshell)
|
2010-04-30 17:31:06 +04:00
|
|
|
subshell_get_console_attributes ();
|
2012-10-19 19:24:57 +04:00
|
|
|
#endif /* ENABLE_SUBSHELL */
|
2002-10-31 07:31:52 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
/* Install the SIGCHLD handler; must be done before init_subshell() */
|
|
|
|
init_sigchld ();
|
2002-10-31 07:31:52 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
/* We need this, since ncurses endwin () doesn't restore the signals */
|
|
|
|
save_stop_handler ();
|
|
|
|
|
|
|
|
/* Must be done before init_subshell, to set up the terminal size: */
|
|
|
|
/* FIXME: Should be removed and LINES and COLS computed on subshell */
|
2011-09-06 19:24:18 +04:00
|
|
|
tty_init (!mc_args__nomouse, mc_global.tty.xterm_flag);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2011-02-10 18:02:54 +03:00
|
|
|
/* start check mc_global.display_codepage and mc_global.source_codepage */
|
2010-11-22 14:45:18 +03:00
|
|
|
check_codeset ();
|
|
|
|
|
2010-05-06 23:19:02 +04:00
|
|
|
/* Removing this from the X code let's us type C-c */
|
|
|
|
load_key_defs ();
|
|
|
|
|
2021-02-14 21:37:23 +03:00
|
|
|
keymap_load (!mc_args__nokeymap);
|
2010-05-06 23:19:02 +04:00
|
|
|
|
2016-01-01 23:19:47 +03:00
|
|
|
#ifdef USE_INTERNAL_EDIT
|
2011-01-22 00:10:36 +03:00
|
|
|
macros_list = g_array_new (TRUE, FALSE, sizeof (macros_t));
|
2016-01-01 23:19:47 +03:00
|
|
|
#endif /* USE_INTERNAL_EDIT */
|
2011-01-22 00:10:36 +03:00
|
|
|
|
2011-09-07 13:06:03 +04:00
|
|
|
tty_init_colors (mc_global.tty.disable_colors, mc_args__force_colors);
|
2009-05-30 21:39:02 +04:00
|
|
|
|
2014-07-15 16:53:06 +04:00
|
|
|
mc_skin_init (NULL, &mcerror);
|
2014-02-08 19:37:11 +04:00
|
|
|
dlg_set_default_colors ();
|
2014-03-25 13:37:57 +04:00
|
|
|
input_set_default_colors ();
|
|
|
|
if (mc_global.mc_run_mode == MC_RUN_FULL)
|
|
|
|
command_set_default_colors ();
|
2014-07-15 16:53:06 +04:00
|
|
|
|
2015-05-09 16:41:44 +03:00
|
|
|
mc_error_message (&mcerror, NULL);
|
2009-09-28 18:04:25 +04:00
|
|
|
|
2012-10-19 19:24:57 +04:00
|
|
|
#ifdef ENABLE_SUBSHELL
|
2001-02-10 07:28:56 +03:00
|
|
|
/* Done here to ensure that the subshell doesn't */
|
|
|
|
/* inherit the file descriptors opened below, etc */
|
2020-02-01 11:49:47 +03:00
|
|
|
if (mc_global.tty.use_subshell && mc_global.run_from_parent_mc)
|
|
|
|
{
|
|
|
|
int r;
|
|
|
|
|
|
|
|
r = query_dialog (_("Warning"),
|
|
|
|
_("GNU Midnight Commander\nis already running on this terminal.\n"
|
|
|
|
"Subshell support will be disabled."),
|
|
|
|
D_ERROR, 2, _("&OK"), _("&Quit"));
|
|
|
|
if (r == 0)
|
|
|
|
{
|
|
|
|
/* parent mc was found and the user wants to continue */
|
|
|
|
;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* parent mc was found and the user wants to quit mc */
|
|
|
|
mc_global.midnight_shutdown = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
mc_global.tty.use_subshell = FALSE;
|
|
|
|
}
|
|
|
|
|
2011-02-10 18:02:54 +03:00
|
|
|
if (mc_global.tty.use_subshell)
|
2010-04-30 17:31:06 +04:00
|
|
|
init_subshell ();
|
2012-10-19 19:24:57 +04:00
|
|
|
#endif /* ENABLE_SUBSHELL */
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2020-02-01 11:49:47 +03:00
|
|
|
if (!mc_global.midnight_shutdown)
|
|
|
|
{
|
|
|
|
/* Also done after init_subshell, to save any shell init file messages */
|
|
|
|
if (mc_global.tty.console_flag != '\0')
|
|
|
|
handle_console (CONSOLE_SAVE);
|
2002-10-31 07:31:52 +03:00
|
|
|
|
2020-02-01 11:49:47 +03:00
|
|
|
if (mc_global.tty.alternate_plus_minus)
|
|
|
|
application_keypad_mode ();
|
1999-03-30 10:09:56 +04:00
|
|
|
|
2020-02-01 11:49:47 +03:00
|
|
|
/* Done after subshell initialization to allow select and paste text by mouse
|
|
|
|
w/o Shift button in subshell in the native console */
|
|
|
|
init_mouse ();
|
2013-02-08 10:39:54 +04:00
|
|
|
|
2020-02-01 11:49:47 +03:00
|
|
|
/* Done after tty_enter_ca_mode (tty_init) because in VTE bracketed mode is
|
|
|
|
separate for the normal and alternate screens */
|
|
|
|
enable_bracketed_paste ();
|
2013-10-01 13:31:13 +04:00
|
|
|
|
2020-02-01 11:49:47 +03:00
|
|
|
/* subshell_prompt is NULL here */
|
|
|
|
mc_prompt = (geteuid () == 0) ? "# " : "$ ";
|
2012-10-30 16:15:33 +04:00
|
|
|
}
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
/* Program main loop */
|
2012-01-28 14:13:32 +04:00
|
|
|
if (mc_global.midnight_shutdown)
|
2012-03-04 18:11:55 +04:00
|
|
|
exit_code = EXIT_SUCCESS;
|
|
|
|
else
|
2012-11-09 10:45:28 +04:00
|
|
|
exit_code = do_nc ()? EXIT_SUCCESS : EXIT_FAILURE;
|
1999-04-06 07:49:34 +04:00
|
|
|
|
2016-05-17 21:14:09 +03:00
|
|
|
disable_bracketed_paste ();
|
|
|
|
|
|
|
|
disable_mouse ();
|
|
|
|
|
1999-04-06 07:49:34 +04:00
|
|
|
/* Save the tree store */
|
2011-09-14 02:07:31 +04:00
|
|
|
(void) tree_store_save ();
|
2002-10-31 07:31:52 +03:00
|
|
|
|
2021-02-14 21:37:23 +03:00
|
|
|
keymap_free ();
|
2009-10-29 22:04:44 +03:00
|
|
|
|
2024-05-09 10:23:32 +03:00
|
|
|
/* At exit, do this before vfs_shut():
|
|
|
|
normally, temporary directory should be empty */
|
|
|
|
vfs_expire (TRUE);
|
|
|
|
(void) my_rmdir (tmpdir);
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
/* Virtual File System shutdown */
|
|
|
|
vfs_shut ();
|
|
|
|
|
2010-04-30 17:31:06 +04:00
|
|
|
flush_extension_file (); /* does only free memory */
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2009-10-24 12:58:02 +04:00
|
|
|
mc_skin_deinit ();
|
2010-11-22 15:02:59 +03:00
|
|
|
tty_colors_done ();
|
2009-09-04 18:22:49 +04:00
|
|
|
|
2009-06-02 21:40:37 +04:00
|
|
|
tty_shutdown ();
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2010-11-22 15:02:59 +03:00
|
|
|
done_setup ();
|
|
|
|
|
2011-09-14 02:07:31 +04:00
|
|
|
if (mc_global.tty.console_flag != '\0' && (quit & SUBSHELL_EXIT) == 0)
|
2010-04-30 17:31:06 +04:00
|
|
|
handle_console (CONSOLE_RESTORE);
|
2011-09-14 02:07:31 +04:00
|
|
|
if (mc_global.tty.alternate_plus_minus)
|
2010-04-30 17:31:06 +04:00
|
|
|
numeric_keypad_mode ();
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2024-07-28 19:50:55 +03:00
|
|
|
(void) my_signal (SIGCHLD, SIG_DFL); /* Disable the SIGCHLD handler */
|
2002-10-31 07:31:52 +03:00
|
|
|
|
2011-09-14 02:07:31 +04:00
|
|
|
if (mc_global.tty.console_flag != '\0')
|
2010-04-30 17:31:06 +04:00
|
|
|
handle_console (CONSOLE_DONE);
|
|
|
|
|
2011-02-10 18:02:54 +03:00
|
|
|
if (mc_global.mc_run_mode == MC_RUN_FULL && mc_args__last_wd_file != NULL
|
2010-11-22 14:45:18 +03:00
|
|
|
&& last_wd_string != NULL && !print_last_revert)
|
2010-04-30 17:31:06 +04:00
|
|
|
{
|
2010-11-22 14:45:18 +03:00
|
|
|
int last_wd_fd;
|
2010-04-30 17:31:06 +04:00
|
|
|
|
2024-09-02 17:51:17 +03:00
|
|
|
last_wd_fd = open (mc_args__last_wd_file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
|
2010-11-22 17:15:28 +03:00
|
|
|
if (last_wd_fd != -1)
|
2010-04-30 17:31:06 +04:00
|
|
|
{
|
2012-07-18 09:41:00 +04:00
|
|
|
ssize_t ret1;
|
|
|
|
int ret2;
|
|
|
|
ret1 = write (last_wd_fd, last_wd_string, strlen (last_wd_string));
|
|
|
|
ret2 = close (last_wd_fd);
|
2013-01-17 16:21:35 +04:00
|
|
|
(void) ret1;
|
|
|
|
(void) ret2;
|
2010-04-30 17:31:06 +04:00
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (last_wd_string);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2015-11-11 15:43:11 +03:00
|
|
|
mc_shell_deinit ();
|
2009-06-30 21:49:40 +04:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
done_key ();
|
2010-06-08 23:23:00 +04:00
|
|
|
|
2016-01-01 23:19:47 +03:00
|
|
|
#ifdef USE_INTERNAL_EDIT
|
2011-01-22 00:10:36 +03:00
|
|
|
if (macros_list != NULL)
|
|
|
|
{
|
|
|
|
guint i;
|
2015-09-14 08:57:51 +03:00
|
|
|
|
2011-01-22 00:10:36 +03:00
|
|
|
for (i = 0; i < macros_list->len; i++)
|
|
|
|
{
|
2013-10-15 10:34:04 +04:00
|
|
|
macros_t *macros;
|
|
|
|
|
2011-01-22 00:10:36 +03:00
|
|
|
macros = &g_array_index (macros_list, struct macros_t, i);
|
|
|
|
if (macros != NULL && macros->macro != NULL)
|
2015-09-14 08:57:51 +03:00
|
|
|
(void) g_array_free (macros->macro, TRUE);
|
2011-01-22 00:10:36 +03:00
|
|
|
}
|
2011-09-14 02:07:31 +04:00
|
|
|
(void) g_array_free (macros_list, TRUE);
|
2011-01-22 00:10:36 +03:00
|
|
|
}
|
2016-01-01 23:19:47 +03:00
|
|
|
#endif /* USE_INTERNAL_EDIT */
|
2011-01-22 00:10:36 +03:00
|
|
|
|
patches by Rostislav Beneš: mc-01-api
add functions for working with strings
some functions are implemented directlu in strutil.c, others have ascii, 8bit
or utf-8 variant. (8bit means singlebyte encodings, where all characters have
width one). Mc autodetects terminal encoding at start and chooses right
variant. If does not know terminal encoding, chooses ascii variant.
contains functions:
1. for translation strings and growing strings
2. for working with characters (next char, prev char, length in
characters, isspace, isalnum, ...)
3. prepeare for display, replace invalid characters with questionmark,
unprintable with dot, left / right / center align
4. comparing strings
in future all string function from util should be moved into strutil, some
function from util have new variant in strutil.
2008-12-29 01:46:37 +03:00
|
|
|
str_uninit_strings ();
|
|
|
|
|
2012-01-07 14:35:01 +04:00
|
|
|
if (mc_global.mc_run_mode != MC_RUN_EDITOR)
|
|
|
|
g_free (mc_run_param0);
|
2024-02-23 12:36:18 +03:00
|
|
|
#ifdef USE_INTERNAL_EDIT
|
2012-01-07 14:35:01 +04:00
|
|
|
else
|
2024-02-23 12:36:18 +03:00
|
|
|
g_list_free_full ((GList *) mc_run_param0, (GDestroyNotify) edit_arg_free);
|
|
|
|
#endif /* USE_INTERNAL_EDIT */
|
2013-11-04 12:09:13 +04:00
|
|
|
|
2010-03-21 13:57:33 +03:00
|
|
|
g_free (mc_run_param1);
|
2013-07-25 10:36:19 +04:00
|
|
|
g_free (saved_other_dir);
|
1999-04-21 23:18:31 +04:00
|
|
|
|
2010-12-29 18:12:59 +03:00
|
|
|
mc_config_deinit_config_paths ();
|
|
|
|
|
2014-07-15 16:53:06 +04:00
|
|
|
(void) mc_event_deinit (&mcerror);
|
|
|
|
if (mcerror != NULL)
|
2011-01-17 12:44:25 +03:00
|
|
|
{
|
2014-07-15 16:53:06 +04:00
|
|
|
fprintf (stderr, _("\nFailed while close:\n%s\n"), mcerror->message);
|
|
|
|
g_error_free (mcerror);
|
2012-03-04 18:11:55 +04:00
|
|
|
exit_code = EXIT_FAILURE;
|
2011-01-17 12:44:25 +03:00
|
|
|
}
|
|
|
|
|
2011-09-14 02:07:31 +04:00
|
|
|
(void) putchar ('\n'); /* Hack to make shell's prompt start at left of screen */
|
2009-02-26 00:53:52 +03:00
|
|
|
|
2012-03-04 18:11:55 +04:00
|
|
|
return exit_code;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2010-11-10 14:09:42 +03:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|