cmd.c

来自「这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统」· C语言 代码 · 共 1,573 行 · 第 1/3 页

C
1,573
字号
        reg_exp_t [strlen(reg_exp_t) - 1] = 0;
    }

    for (i = 0; i < panel->count; i++){
        if (!strcmp (panel->dir.list [i].fname, ".."))
            continue;
	if (S_ISDIR (panel->dir.list [i].buf.st_mode)){
	    if (!dirflag)
                continue;
        } else {
            if (dirflag)
                continue;
	}
	c = regexp_match (reg_exp_t, panel->dir.list [i].fname, match_file);
	if (c == -1){
	    message (1, MSG_ERROR, _("  Malformed regular expression  "));
	    free (reg_exp);
	    return;
	}
	if (c){
	    do_file_mark (panel, i, 1);
	}
    }
    paint_panel (panel);
    free (reg_exp);
}

void select_cmd (void)
{
	select_cmd_panel (cpanel);
}

void unselect_cmd_panel (WPanel *panel)
{
    char *reg_exp, *reg_exp_t;
    int i;
    int c;
    int dirflag = 0;

    reg_exp = input_dialog (_(" Unselect "),"", easy_patterns ? "*" : ".");
    if (!reg_exp)
	return;

    reg_exp_t = reg_exp;

    /* Check if they specified directory matching */
    if (*reg_exp_t == PATH_SEP){
        dirflag = 1;
	reg_exp_t ++;
    }
    if (reg_exp_t [strlen(reg_exp_t) - 1] == PATH_SEP){
        dirflag = 1;
        reg_exp_t [strlen(reg_exp_t) - 1] = 0;
    }
    for (i = 0; i < panel->count; i++){
        if (!strcmp (panel->dir.list [i].fname, ".."))
            continue;
	if (S_ISDIR (panel->dir.list [i].buf.st_mode)){
	    if (!dirflag)
	        continue;
        } else {
            if (dirflag)
                continue;
        }
	c = regexp_match (reg_exp_t, panel->dir.list [i].fname, match_file);
	if (c == -1){
	    message (1, MSG_ERROR, _("  Malformed regular expression  "));
	    free (reg_exp);
	    return;
	}
	if (c){
	    do_file_mark (panel, i, 0);
	}
    }
    paint_panel (panel);
    free (reg_exp);
}

void unselect_cmd (void)
{
	unselect_cmd_panel (cpanel);
}

/* Check if the file exists */
/* If not copy the default */
static int check_for_default(char *default_file, char *file)
{
    struct stat s;
    if (mc_stat (file, &s)){
	if (mc_stat (default_file, &s)){
	    return -1;
	}
	create_op_win (OP_COPY, 0);
        file_mask_defaults ();
	copy_file_file (default_file, file, 1);
	destroy_op_win ();
    }
    return 0;
}

void ext_cmd (void)
{
    char *buffer;
    char *extdir;
    int  dir;

    dir = 0;
    if (geteuid () == 0){
	dir = query_dialog (_("Extension file edit"),
			    _(" Which extension file you want to edit? "), 0, 2,
			    _("&User"), _("&System Wide"));
    }
    extdir = concat_dir_and_file (mc_home, MC_LIB_EXT);

    if (dir == 0){
	buffer = concat_dir_and_file (home_dir, MC_USER_EXT);
	check_for_default (extdir, buffer);
	do_edit (buffer);
	free (buffer);
    } else if (dir == 1)
	do_edit (extdir);

   free (extdir);
   flush_extension_file ();
}

void menu_edit_cmd (void)
{
    char *buffer;
    char *menufile;
    int dir = 0;

    dir = query_dialog (
	_("Menu file edit"),
	_(" Which menu file will you edit? "),
	0, geteuid() ? 2 : 3,
	_("&Local"), _("&Home"), _("&System Wide")
    );

    menufile = concat_dir_and_file(mc_home, MC_GLOBAL_MENU);

    switch (dir){
	case 0:
	    buffer = strdup (MC_LOCAL_MENU);
	    check_for_default (menufile, buffer);
	    break;

	case 1:
	    buffer = concat_dir_and_file (home_dir, MC_HOME_MENU);
	    check_for_default (menufile, buffer);
	    break;

	case 2:
	    buffer = concat_dir_and_file (mc_home, MC_GLOBAL_MENU);
	    break;

	default:
	    free (menufile);
	    return;
    }
    do_edit (buffer);
	if (dir == 0)
		chmod(buffer, 0600);
    free (buffer);
    free (menufile);
}

void quick_chdir_cmd (void)
{
    char *target;

    target = hotlist_cmd (LIST_HOTLIST);
    if (!target)
	return;

    if (get_current_type () == view_tree)
	tree_chdir (the_tree, target);
    else
	do_cd (target, cd_exact);
    free (target);
}

#ifdef USE_VFS
void reselect_vfs (void)
{
    char *target;

    target = hotlist_cmd (LIST_VFSLIST);
    if (!target)
	return;

    do_cd (target, cd_exact);
    free (target);
}
#endif

static int compare_files (char *name1, char *name2, long size)
{
    int file1, file2;
    int result = -1;		/* Different by default */

    file1 = open (name1, O_RDONLY);
    if (file1 >= 0){
	file2 = open (name2, O_RDONLY);
	if (file2 >= 0){
#ifdef HAVE_MMAP
	    /* Ugly if jungle */
	    data1 = mmap (0, size, PROT_READ, MAP_FILE | MAP_PRIVATE, file1, 0);
	    if (data1 != (char*) -1){
		data2 = mmap (0, size, PROT_READ, MAP_FILE | MAP_PRIVATE, file2, 0);
		if (data2 != (char*) -1){
		    rotate_dash ();
		    result = memcmp (data1, data2, size);
		    munmap (data2, size);
		}
		munmap (data1, size);
	    }
#else
	    /* Don't have mmap() :( Even more ugly :) */
	    char buf1[BUFSIZ], buf2[BUFSIZ];
	    int n1, n2;
	    rotate_dash ();
	    do
	    {
		while((n1 = read(file1,buf1,BUFSIZ)) == -1 && errno == EINTR);
		while((n2 = read(file2,buf2,BUFSIZ)) == -1 && errno == EINTR);
	    } while (n1 == n2 && n1 == BUFSIZ && !memcmp(buf1,buf2,BUFSIZ));
	    result = (n1 != n2) || memcmp(buf1,buf2,n1);
#endif
	    close (file2);
	}
	close (file1);
    }
    return result;
}

enum CompareMode {
    compare_quick, compare_size_only, compare_thourough
};

static void
compare_dir (WPanel *panel, WPanel *other, enum CompareMode mode)
{
    int i, j;
    char *src_name, *dst_name;

    panel = get_a_panel (panel);

    /* No marks by default */
    panel->marked = 0;
    panel->total = 0;
    panel->dirs_marked = 0;

    /* Handle all files in the panel */
    for (i = 0; i < panel->count; i++){
	file_entry *source = &panel->dir.list[i];

	/* Default: unmarked */
	file_mark (panel, i, 0);

	/* Skip directories */
	if (S_ISDIR (source->buf.st_mode))
	    continue;

	/* Search the corresponding entry from the other panel */
	for (j = 0; j < other->count; j++){
	    if (strcmp (source->fname,
			other->dir.list[j].fname) == 0)
		break;
	}
	if (j >= other->count)
	    /* Not found -> mark */
	    do_file_mark (panel, i, 1);
	else {
	    /* Found */
	    file_entry *target = &other->dir.list[j];

	    if (mode != compare_size_only){
		/* Older version is not marked */
		if (source->buf.st_mtime < target->buf.st_mtime)
		    continue;
	    }

	    /* Newer version with different size is marked */
	    if (source->buf.st_size != target->buf.st_size){
		do_file_mark (panel, i, 1);
		continue;

	    }
	    if (mode == compare_size_only)
		continue;

	    if (mode == compare_quick){
		/* Thorough compare off, compare only time stamps */
		/* Mark newer version, don't mark version with the same date */
		if (source->buf.st_mtime > target->buf.st_mtime){
		    do_file_mark (panel, i, 1);
		}
		continue;
	    }

	    /* Thorough compare on, do byte-by-byte comparison */
	    src_name = get_full_name (panel->cwd, source->fname);
	    dst_name = get_full_name (other->cwd, target->fname);
	    if (compare_files (src_name, dst_name, source->buf.st_size))
		do_file_mark (panel, i, 1);
	    free (src_name);
	    free (dst_name);
	}
    } /* for (i ...) */
}

void compare_dirs_cmd (void)
{
    enum CompareMode thorough_flag = compare_quick;

    thorough_flag = query_dialog (_(" Compare directories "), _(" Select compare method: "),
				  0, 3, _("&Quick"), _("&Size only"), _("&Thorough"), _("&Cancel"));
    if (thorough_flag < 0 || thorough_flag > 2)
	return;
    if (get_current_type () == view_listing &&
	get_other_type () == view_listing){
	compare_dir (cpanel, opanel, thorough_flag);
	compare_dir (opanel, cpanel, thorough_flag);
	paint_panel (cpanel);
	paint_panel (opanel);
    } else {
	message (1, MSG_ERROR, _(" Both panels should be on the listing view mode to use this command "));
    }
}

void history_cmd (void)
{
    Listbox *listbox;
    Hist *current;

    if (input_w (cmdline)->need_push){
	if (push_history (input_w (cmdline), input_w (cmdline)->buffer) == 2)
	    input_w (cmdline)->need_push = 0;
    }
    if (!input_w (cmdline)->history){
	message (1, MSG_ERROR, _(" The command history is empty "));
	return;
    }
    current = input_w (cmdline)->history;
    while (current->prev)
	current = current->prev;
    listbox = create_listbox_window (60, 10, _(" Command history "),
				     "[Command Menu]");
    while (current){
	LISTBOX_APPEND_TEXT (listbox, 0, current->text,
			     current);
	current = current->next;
    }
    run_dlg (listbox->dlg);
    if (listbox->dlg->ret_value == B_CANCEL)
	current = NULL;
    else
	current = listbox->list->current->data;
    destroy_dlg (listbox->dlg);
    free (listbox);

    if (!current)
	return;
    input_w (cmdline)->history = current;
    assign_text (input_w (cmdline), input_w (cmdline)->history->text);
    update_input (input_w (cmdline), 1);
}

#if !defined(HAVE_XVIEW) && !defined(HAVE_GNOME)
void swap_cmd (void)
{
    swap_panels ();
    touchwin (stdscr);
    repaint_screen ();
}
#endif

void
view_other_cmd (void)
{
    static int message_flag = TRUE;
#ifdef HAVE_SUBSHELL_SUPPORT
    char *new_dir = NULL;
    char **new_dir_p;
#endif

    if (!xterm_flag && !console_flag && !use_subshell){
	if (message_flag)
	    message (1, MSG_ERROR, _(" Not an xterm or Linux console; \n"
				     " the panels cannot be toggled. "));
	message_flag = FALSE;
    } else {
#ifndef HAVE_X
	if (use_mouse_p)
	    shut_mouse ();
	if (clear_before_exec)
	    clr_scr ();
        if (alternate_plus_minus)
            numeric_keypad_mode ();
#endif
#ifndef HAVE_SLANG
	/* With slang we don't want any of this, since there
	 * is no mc_raw_mode supported
	 */
	reset_shell_mode ();
	noecho ();
#endif
	keypad(stdscr, FALSE);
	endwin ();
	if (!status_using_ncurses)
	    do_exit_ca_mode ();
	mc_raw_mode ();
	if (console_flag)
	    restore_console ();

#ifdef HAVE_SUBSHELL_SUPPORT
	if (use_subshell){
	    new_dir_p = vfs_current_is_local () ? &new_dir : NULL;
	    if (invoke_subshell (NULL, VISIBLY, new_dir_p))
		quiet_quit_cmd();  /* User did `exit' or `logout': quit MC quietly */
	} else
#endif
	{
	    if (output_starts_shell){
		fprintf (stderr,
		 _("Type `exit' to return to the Midnight Commander\n\r\n\r"));
		my_system (EXECUTE_AS_SHELL, shell, NULL);
	    } else
		get_key_code (0);
	}
	if (console_flag)
	    handle_console (CONSOLE_SAVE);

	if (!status_using_ncurses)
	    do_enter_ca_mode ();

	reset_prog_mode ();
	keypad(stdscr, TRUE);
#ifndef HAVE_X
	if (use_mouse_p)
	    init_mouse ();
        if (alternate_plus_minus)
            application_keypad_mode ();
#endif

#ifdef HAVE_SUBSHELL_SUPPORT
	if (use_subshell){
	    load_prompt (0, 0);
	    if (new_dir)
		do_possible_cd (new_dir);
	    if (console_flag && output_lines)
		show_console_contents (output_start_y,
				       LINES-keybar_visible-output_lines-1,
				       LINES-keybar_visible-1);
	}
#endif
        touchwin (stdscr);

	/* prevent screen flash when user did 'exit' or 'logout' within
	   subshell */
	if (!quit)
	    repaint_screen ();
    }
}

#ifndef OS2_NT
static void
do_link (int symbolic_link, char *fname)
{
    struct stat s;
    char *dest, *src;
    int  stat_r;

    if (!symbolic_link){
	stat_r = mc_stat (fname, &s);
	if (stat_r != 0){
	    message (1, MSG_ERROR, _(" Couldn't stat %s \n %s "),
		     fname, unix_error_string (errno));
	    return;
	}
	if (!S_ISREG (s.st_mode))
	    return;
    }

    if (!symbolic_link){
        src = copy_strings (_(" Link "), name_trunc (fname, 46),
            _(" to:"), NULL);
	dest = input_expand_dialog (_(" Link "), src, "");
	free (src);
	if (!dest)
	    return;
	if (!*dest) {
	    free (dest);
	    return;
	}
	save_cwds_stat ();
	if (-1 == mc_link (fname, dest))
	    message (1, MSG_ERROR, _(" link: %s "), unix_error_string (errno));
    } else {
#ifdef OLD_SYMLINK_VERSION
        symlink_dialog (fname, "", &dest, &src);
#else
	/* suggest the full path for symlink */
        char s[MC_MAXPATHLEN];
        char d[MC_MAXPATHLEN];

        strcpy(s, cpanel->cwd);
        if ( ! ((s[0] == '/') && (s[1] == 0)))
            strcat(s, "/");
        strcat(s, fname);
	if (get_other_type () == view_listing)
	    strcpy(d, opanel->cwd);
	else
	    strcpy (d,"");

        if ( ! ((d[0] == '/') && (d[1] == 0)))
            strcat(d, "/");
        symlink_dialog (s, d, &dest, &src);
#endif
	if (!dest || !*dest) {
	    if (src)
	        free (src);
	    if (dest)
	        free (dest);

⌨️ 快捷键说明

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