⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Main program for the Midnight Commander
   Copyright (C) 1994, 1995, 1996, 1997 The Free Software Foundation

   Written by: 1994, 1995, 1996, 1997 Miguel de Icaza
               1994, 1995 Janne Kukonlehto
	       1997 Norbert Warmuth

   This program 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 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   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
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */

#include <config.h>
#include <locale.h>

#ifdef _OS_NT
#    include <windows.h>
#endif

#ifdef __os2__
#    define INCL_DOS
#    define INCL_DOSFILEMGR
#    define INCL_DOSERRORS
#    include <os2.h>
#endif

#include "tty.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/param.h>

#include <sys/stat.h>

#ifdef HAVE_UNISTD_H
#   include <unistd.h>
#endif

/* unistd.h defines _POSIX_VERSION on POSIX.1 systems. */
#if defined(HAVE_DIRENT_H) || defined(_POSIX_VERSION)
#   include <dirent.h>
#   define NLENGTH(dirent) (strlen ((dirent)->d_name))
#else
#   define dirent direct
#   define NLENGTH(dirent) ((dirent)->d_namlen)

#   ifdef HAVE_SYS_NDIR_H
#       include <sys/ndir.h>
#   endif /* HAVE_SYS_NDIR_H */

#   ifdef HAVE_SYS_DIR_H
#       include <sys/dir.h>
#   endif /* HAVE_SYS_DIR_H */

#   ifdef HAVE_NDIR_H
#       include <ndir.h>
#   endif /* HAVE_NDIR_H */
#endif /* not (HAVE_DIRENT_H or _POSIX_VERSION) */

#if HAVE_SYS_WAIT_H
#   include <sys/wait.h>	/* For waitpid() */
#endif

#include <errno.h>
#ifndef OS2_NT
#    include <pwd.h>
#endif
#include <ctype.h>
#include <fcntl.h>	/* For O_RDWR */
#include <signal.h>

/* Program include files */
#include "x.h"
#include "mad.h"
#include "dir.h"
#include "color.h"
#include "global.h"
#include "util.h"
#include "dialog.h"
#include "menu.h"
#include "file.h"
#include "panel.h"
#include "main.h"
#include "win.h"
#include "user.h"
#include "mem.h"
#include "mouse.h"
#include "option.h"
#include "tree.h"
#include "cons.saver.h"
#include "subshell.h"
#include "key.h"	/* For init_key() and mi_getch() */
#include "setup.h"	/* save_setup() */
#include "profile.h"	/* free_profiles() */
#include "boxes.h"
#include "layout.h"
#include "cmd.h"		/* Normal commands */
#include "hotlist.h"
#include "panelize.h"
#ifndef __os2__
#    include "learn.h"
#endif
#include "listmode.h"
#include "background.h"
#include "ext.h"	/* For flush_extension_file() */

/* Listbox for the command history feature */
#include "widget.h"
#include "command.h"
#include "wtools.h"
#include "complete.h"		/* For the free_completion */

#include "chmod.h"
#include "chown.h"

#ifdef OS2_NT
#    include <io.h>
#    include <drive.h>
#endif

#include "../vfs/vfs.h"
#include "../vfs/extfs.h"


#include "popt.h"

/* "$Id: main.c 23951 2006-09-07 09:17:39Z greatlrd $" */

/* When the modes are active, left_panel, right_panel and tree_panel */
/* Point to a proper data structure.  You should check with the functions */
/* get_current_type and get_other_type the types of the panels before using */
/* This pointer variables */

/* The structures for the panels */
WPanel *left_panel;
WPanel *right_panel;

/* The pointer to the tree */
WTree *the_tree;

/* The Menubar */
WMenu *the_menubar;

/* Pointers to the selected and unselected panel */
WPanel *current_panel = NULL;

/* Set when we want use advanced chmod command instead of chmod and/or chown */
int advanced_chfns = 0;

/* Set when main loop should be terminated */
volatile int quit = 0;

/* Set if you want the possible completions dialog for the first time */
int show_all_if_ambiguous = 0;

/* Set when cd symlink following is desirable (bash mode) */
int cd_symlinks = 1;

/* If set then dialogs just clean the screen when refreshing, else */
/* they do a complete refresh, refreshing all the parts of the program */
int fast_refresh = 0;

/* If true, marking a files moves the cursor down */
int   mark_moves_down = 1;

/* If true, at startup the user-menu is invoked */
int   auto_menu = 0;

/* If true, use + and \ keys normally and select/unselect do if M-+ / M-\ and M--
   and keypad + / - */
int   alternate_plus_minus = 0;

/* If true, then the +, - and \ keys have their special meaning only if the
 * command line is emtpy, otherwise they behave like regular letters
 */
int   only_leading_plus_minus = 1;

/* If true, after executing a command, wait for a keystroke */
enum { pause_never, pause_on_dumb_terminals, pause_always };

int   pause_after_run = pause_on_dumb_terminals;

/* It true saves the setup when quitting */
int auto_save_setup = 1;

/* If true, be eight bit clean */
int eight_bit_clean = 0;

/* If true, then display chars 0-255, else iso-8859-1,
   requires eight_bit_clean */
int full_eight_bits = 0;

/* If true use the internal viewer */
int use_internal_view = 1;

/* Have we shown the fast-reload warning in the past? */
int fast_reload_w = 0;

/* Move page/item? When clicking on the top or bottom of a panel */
int mouse_move_pages = 1;

/* If true: l&r arrows are used to chdir if the input line is empty */
int navigate_with_arrows = 0;

/* If it is set, the commander will iconify itself when executing a program */
int iconify_on_exec = 1;

/* If true use +, -, | for line drawing */
int force_ugly_line_drawing = 0;

/* If true message "The shell is already running a command" never */
int force_subshell_execution = 0;

/* If true program softkeys (HP terminals only) on startup and after every
   command ran in the subshell to the description found in the termcap/terminfo
   database */
int reset_hp_softkeys = 0;

/* The prompt */
char *prompt = 0;

/* The widget where we draw the prompt */
WLabel *the_prompt;

/* The hint bar */
WLabel *the_hint;

/* The button bar */
WButtonBar *the_bar;

#ifdef HAVE_X
WButtonBar *the_bar2;
#endif

/* For slow terminals */
int slow_terminal = 0;

/* use mouse? */
int use_mouse_p = GPM_MOUSE;

/* If true, assume we are running on an xterm terminal */
static int force_xterm = 0;

/* Controls screen clearing before an exec */
int clear_before_exec = 1;

/* Asks for confirmation before deleting a file */
int confirm_delete = 1;

/* Asks for confirmation before overwriting a file */
int confirm_overwrite = 1;

/* Asks for confirmation before executing a program by pressing enter */
int confirm_execute = 0;

/* Asks for confirmation before leaving the program */
int confirm_exit = 1;

/* Asks for confirmation when using F3 to view a directory and there
   are tagged files */
int confirm_view_dir = 0;

/* This flag indicates if the pull down menus by default drop down */
int drop_menus = 0;

/* The dialog handle for the main program */
Dlg_head *midnight_dlg;

/* Subshell: if set, then the prompt was not saved on CONSOLE_SAVE */
/* We need to paint it after CONSOLE_RESTORE, see: load_prompt */
int update_prompt = 0;

/* The name which was used to invoke mc */
char *program_name;

/* The home directory */
char *home_dir;

/* The value of the other directory, only used when loading the setup */
char *other_dir = 0;
char *this_dir = 0;

/* If true, then print on stdout the last directory we were at */
static int print_last_wd = 0;
static char *last_wd_string;
static int print_last_revert = 0;

/* On OS/2 and on Windows NT, we need a batch file to do the -P magic */
#ifdef OS2_NT
static char *batch_file_name = 0;
#endif

/* widget colors for the midnight commander */
int midnight_colors [4];

/* Force colors, only used by Slang */
int force_colors = 0;

/* colors specified on the command line: they override any other setting */
char *command_line_colors;

/* File name to view if argument was supplied */
char *view_one_file = 0;

/* File name to view if argument was supplied */
char *edit_one_file = 0;

/* Used so that widgets know if they are being destroyed or
   shut down */
int midnight_shutdown = 0;

/* to show nice prompts */
static int last_paused = 0;

/* Only used at program boot */
int boot_current_is_left = 1;

/* Used for keeping track of the original stdout */
int stdout_fd = 0;

/* The user's shell */
char *shell;

/* mc_home: The home of MC */
char *mc_home;

/* if on, it displays the information that files have been moved to ~/.mc */
int show_change_notice = 0;

char cmd_buf [512];

/* Used during argument processing */
int finish_program = 0;

/* Forward declarations */
char *get_mc_lib_dir ();
int panel_event    (Gpm_Event *event, WPanel *panel);
int menu_bar_event (Gpm_Event *event, void *);
static void menu_cmd (void);

#ifndef HAVE_GNOME
WPanel *
get_current_panel ()
{
	return current_panel;
}

WPanel *
get_other_panel ()
{
	return (WPanel *) get_panel_widget (get_other_index ());
}
#endif

void
try_to_select (WPanel *panel, char *name)
{
    Xtry_to_select (panel, name);
    select_item (panel);
    display_mini_info (panel);
}

/*
 * cd_try_to_select:
 *
 *  If we moved to the parent directory move the selection pointer to
 *  the old directory name
 */
void
cd_try_to_select (WPanel *panel)
{
#ifdef USE_VFS
    char *p, *q;
#endif

    int i, j = 4;

    if (strlen (panel->lwd) > strlen (panel->cwd)
	&& strncmp (panel->cwd, panel->lwd, strlen (panel->cwd)) == 0
	&& strchr (panel->lwd + strlen (panel->cwd) + 1, PATH_SEP) == 0)
	try_to_select (panel, panel->lwd);
    else
#ifdef USE_VFS
	if ((!strncmp (panel->lwd, "tar:", 4) &&
             !strncmp (panel->lwd + 4, panel->cwd, strlen (panel->cwd))) ||
             ((i = extfs_prefix_to_type (panel->lwd)) != -1 &&
             !strncmp (panel->lwd + (j = strlen (extfs_get_prefix (i)) + 1),
             panel->cwd, strlen (panel->cwd)))) {
        p = strdup (panel->lwd + j + strlen (panel->cwd));
        q = strchr (p, PATH_SEP);
        if (q != NULL && (q != p || (q = strchr (q + 1, PATH_SEP)) != NULL))
            *q = 0;
        try_to_select (panel, p);
        free (p);
    } else
#endif
	try_to_select (panel, NULL);
}

void
reload_panelized (WPanel *panel)
{
    int i, j;
    dir_list *list = &panel->dir;

    if (panel != cpanel)
	mc_chdir (panel->cwd);

    for (i = 0, j = 0; i < panel->count; i++){
    	if (list->list [i].f.marked) {
	    /* Unmark the file in advance. In case the following mc_lstat
	     * fails we are done, else we have to mark the file again
	     * (Note: do_file_mark depends on a valid "list->list [i].buf").
	     * IMO that's the best way to update the panel's summary status
	     * -- Norbert
	     */
	    do_file_mark (panel, i, 0);
	}
	if (mc_lstat (list->list [i].fname, &list->list [i].buf)){
	    free (list->list [i].fname);
	    continue;
	}
    	if (list->list [i].f.marked)
	    do_file_mark (panel, i, 1);
	if (j != i)
	    list->list [j] = list->list [i];
	j++;
    }
    if (j == 0)
	panel->count = set_zero_dir (list);
    else
	panel->count = j;

    if (panel != cpanel)
	mc_chdir (cpanel->cwd);
}

void
update_one_panel_widget (WPanel *panel, int force_update, char *current_file)
{
    int free_pointer;

    if (force_update & UP_RELOAD){
	panel->is_panelized = 0;

	ftpfs_flushdir ();
	bzero (&(panel->dir_stat), sizeof (panel->dir_stat));
    }

    /* If current_file == -1 (an invalid pointer) then preserve selection */
    if (current_file == UP_KEEPSEL){
	free_pointer = 1;
	current_file = strdup (panel->dir.list [panel->selected].fname);
    } else
	free_pointer = 0;

    if (panel->is_panelized)
	reload_panelized (panel);
    else
	panel_reload (panel);

    try_to_select (panel, current_file);
    panel->dirty = 1;

    if (free_pointer)
	free (current_file);
}

#ifndef PORT_HAS_UPDATE_PANELS
void
update_one_panel (int which, int force_update, char *current_file)
{
    WPanel *panel;

    if (get_display_type (which) != view_listing)
	return;

    panel = (WPanel *) get_panel_widget (which);
    update_one_panel_widget (panel, force_update, current_file);
}

/* This routine reloads the directory in both panels. It tries to
 * select current_file in current_panel and other_file in other_panel.
 * If current_file == -1 then it automatically sets current_file and
 * other_file to the currently selected files in the panels.
 *
 * if force_update has the UP_ONLY_CURRENT bit toggled on, then it
 * will not reload the other panel.
*/
void
update_panels (int force_update, char *current_file)
{
    int reload_other = !(force_update & UP_ONLY_CURRENT);
    WPanel *panel;

    update_one_panel (get_current_index (), force_update, current_file);
    if (reload_other)
	update_one_panel (get_other_index (), force_update, UP_KEEPSEL);

    if (get_current_type () == view_listing)
	panel = (WPanel *) get_panel_widget (get_current_index ());
    else
	panel = (WPanel *) get_panel_widget (get_other_index ());

    mc_chdir (panel->cwd);
}
#endif

#ifdef WANT_PARSE
static void select_by_index (WPanel *panel, int i);

/* Called by parse_control_file */
static int index_by_name (file_entry *list, int count)
{
    char *name;
    int i;

    name = strtok (NULL, " \t\n");
    if (!name || !*name)
	return -1;
    for (i = 0; i < count; i++){
	if (strcmp (name, list[i].fname) == 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -