Пример #1
0
static void tree_show_mini_info (WTree *tree, int tree_lines, int tree_cols)
{
    Dlg_head *h = tree->widget.parent;
    int      line;

    /* Show mini info */
    if (tree->is_panel){
	if (!show_mini_info)
	    return;
	line = tree_lines+2;
    } else
	line = tree_lines+1;

    widget_move (&tree->widget, line, 1);
    hline (' ', tree_cols);
    widget_move (&tree->widget, line, 1);

    if (tree->searching){
	/* Show search string */
	attrset (TREE_NORMALC (h));
	attrset (DLG_FOCUSC (h));
	addch (PATH_SEP);

	addstr ((char *) name_trunc (tree->search_buffer, tree_cols-2));
	addch (' ');
	attrset (DLG_FOCUSC (h));
    } else {
	/* Show full name of selected directory */
	addstr ((char *) name_trunc (tree->selected_ptr->name, tree_cols));
    }
}
Пример #2
0
static void tree_copy (WTree *tree, const char *default_dest)
{
    char   *dest;
    off_t  count = 0;
    double bytes = 0;
    FileOpContext *ctx;

    if (!tree->selected_ptr)
	return;
    g_snprintf (cmd_buf, sizeof(cmd_buf), _("Copy \"%s\" directory to:"),
	     name_trunc (tree->selected_ptr->name, 50));
    dest = input_expand_dialog (_(" Copy "), cmd_buf, MC_HISTORY_FM_TREE_COPY, default_dest);

    if (!dest)
	return;

    if (!*dest){
	g_free (dest);
	return;
    }

    ctx = file_op_context_new (OP_COPY);
    file_op_context_create_ui (ctx, FALSE);
    copy_dir_dir (ctx, tree->selected_ptr->name, dest, 1, 0, 0, 0, &count, &bytes);
    file_op_context_destroy (ctx);

    g_free (dest);
}
Пример #3
0
/*
 * path_trunc() is the same as name_trunc() above but
 * it deletes possible password from path for security
 * reasons.
 */
const char *
path_trunc (const char *path, int trunc_len) {
    const char *ret;
    char *secure_path = strip_password (g_strdup (path), 1);
    
    ret = name_trunc (secure_path, trunc_len);
    g_free (secure_path);
    
    return ret;
}
Пример #4
0
static void
do_link (int symbolic_link, const char *fname)
{
    char *dest = NULL, *src = NULL;

    if (!symbolic_link) {
	src = g_strdup_printf (_("Link %s to:"), name_trunc (fname, 46));
	dest = input_expand_dialog (_(" Link "), src, "");
	if (!dest || !*dest)
	    goto cleanup;
	save_cwds_stat ();
	if (-1 == mc_link (fname, dest))
	    message (1, MSG_ERROR, _(" link: %s "),
		     unix_error_string (errno));
    } else {
	char *s;
	char *d;

	/* suggest the full path for symlink */
	s = concat_dir_and_file (current_panel->cwd, fname);

	if (get_other_type () == view_listing) {
	    d = concat_dir_and_file (other_panel->cwd, fname);
	} else {
	    d = g_strdup (fname);
	}

	symlink_dialog (s, d, &dest, &src);
	g_free (d);
	g_free (s);

	if (!dest || !*dest || !src || !*src)
	    goto cleanup;
	save_cwds_stat ();
	if (-1 == mc_symlink (dest, src))
	    message (1, MSG_ERROR, _(" symlink: %s "),
		     unix_error_string (errno));
    }
    update_panels (UP_OPTIMIZE, UP_KEEPSEL);
    repaint_screen ();

cleanup:
    g_free (src);
    g_free (dest);
}
Пример #5
0
static void tree_move (WTree *tree, const char *default_dest)
{
    char   *dest;
    struct stat buf;
    double bytes = 0;
    off_t  count = 0;
    FileOpContext *ctx;

    if (!tree->selected_ptr)
	return;
    g_snprintf (cmd_buf, sizeof (cmd_buf), _("Move \"%s\" directory to:"),
	     name_trunc (tree->selected_ptr->name, 50));
    dest = input_expand_dialog (_(" Move "), cmd_buf, MC_HISTORY_FM_TREE_MOVE, default_dest);
    if (!dest)
	return;
    if (!*dest){
	g_free (dest);
	return;
    }
    if (stat (dest, &buf)){
	message (1, MSG_ERROR, _(" Cannot stat the destination \n %s "),
		 unix_error_string (errno));
	g_free (dest);
	return;
    }
    if (!S_ISDIR (buf.st_mode)){
	file_error (_(" Destination \"%s\" must be a directory \n %s "),
		    dest);
	g_free (dest);
	return;
    }

    ctx = file_op_context_new (OP_MOVE);
    file_op_context_create_ui (ctx, FALSE);
    move_dir_dir (ctx, tree->selected_ptr->name, dest, &count, &bytes);
    file_op_context_destroy (ctx);

    g_free (dest);
}
Пример #6
0
void edit_symlink_cmd (void)
{
    if (S_ISLNK (selection (current_panel)->st.st_mode)) {
	char buffer [MC_MAXPATHLEN];
	char *p = NULL;
	int i;
	char *dest, *q;

	p = selection (current_panel)->fname;

	q = g_strdup_printf (_(" Symlink `%s\' points to: "), name_trunc (p, 32));

	i = readlink (p, buffer, MC_MAXPATHLEN - 1);
	if (i > 0) {
	    buffer [i] = 0;
	    dest = input_expand_dialog (_(" Edit symlink "), q, buffer);
	    if (dest) {
		if (*dest && strcmp (buffer, dest)) {
		    save_cwds_stat ();
		    if (-1 == mc_unlink (p)){
		        message (1, MSG_ERROR, _(" edit symlink, unable to remove %s: %s "),
				 p, unix_error_string (errno));
		    } else {
			    if (-1 == mc_symlink (dest, p))
				    message (1, MSG_ERROR, _(" edit symlink: %s "),
					     unix_error_string (errno));
		    }
		    update_panels (UP_OPTIMIZE, UP_KEEPSEL);
		    repaint_screen ();
		}
		g_free (dest);
	    }
	}
	g_free (q);
    } else {
	message (1, MSG_ERROR, _("`%s' is not a symbolic link"),
		 selection (current_panel)->fname);
    }
}
Пример #7
0
/* Draw the status line at the top of the widget. The size of the filename
 * field varies depending on the width of the screen and the length of
 * the filename. */
void
edit_status (WEdit *edit)
{
    const int w = edit->widget.cols;
    const size_t status_size = w + 1;
    char * const status = g_malloc (status_size);
    int status_len;
    const char *fname = "";
    int fname_len;
    const int gap = 3; /* between the filename and the status */
    const int right_gap = 2; /* at the right end of the screen */
    const int preferred_fname_len = 16;

    status_string (edit, status, status_size);
    status_len = (int) strlen (status);

    if (edit->filename)
        fname = edit->filename;
    fname_len = strlen(fname);
    if (fname_len < preferred_fname_len)
        fname_len = preferred_fname_len;

    if (fname_len + gap + status_len + right_gap >= w) {
	if (preferred_fname_len + gap + status_len + right_gap >= w)
	    fname_len = preferred_fname_len;
	else
            fname_len = w - (gap + status_len + right_gap);
	fname = name_trunc (fname, fname_len);
    }

    widget_move (edit, 0, 0);
    attrset (SELECTED_COLOR);
    printwstr (fname, fname_len + gap);
    printwstr (status, w - (fname_len + gap));
    attrset (EDITOR_NORMAL_COLOR);

    g_free (status);
}
Пример #8
0
void chmod_cmd (void)
{
    char buffer [BUF_TINY];
    char *fname;
    int i;
    struct stat sf_stat;
    Dlg_head *ch_dlg;

    do {			/* do while any files remaining */
        ch_dlg = init_chmod ();
        if (current_panel->marked)
            fname = next_file ();	/* next marked file */
        else
            fname = selection (current_panel)->fname;	/* single file */

        if (mc_stat (fname, &sf_stat) != 0) {	/* get status of file */
            destroy_dlg (ch_dlg);
            break;
        }

        c_stat = sf_stat.st_mode;
        mode_change = 0;	/* clear changes flag */

        /* set check buttons */
        for (i = 0; i < PERMISSIONS; i++) {
            check_perm[i].check->state = (c_stat & check_perm[i].mode) ? 1 : 0;
            check_perm[i].selected = 0;
        }

        /* Set the labels */
        c_fname = name_trunc (fname, 21);
        add_widget (ch_dlg, label_new (FY+2, FX+2, c_fname));
        c_fown = name_trunc (get_owner (sf_stat.st_uid), 21);
        add_widget (ch_dlg, label_new (FY+6, FX+2, c_fown));
        c_fgrp = name_trunc (get_group (sf_stat.st_gid), 21);
        add_widget (ch_dlg, label_new (FY+8, FX+2, c_fgrp));
        g_snprintf (buffer, sizeof (buffer), "%o", c_stat);
        statl = label_new (FY+4, FX+2, buffer);
        add_widget (ch_dlg, statl);

        run_dlg (ch_dlg);	/* retrieve an action */

        /* do action */
        switch (ch_dlg->ret_value) {
        case B_ENTER:
            if (mode_change)
                if (mc_chmod (fname, c_stat) == -1)
                    message (1, MSG_ERROR, _(" Cannot chmod \"%s\" \n %s "),
                             fname, unix_error_string (errno));
            need_update = 1;
            break;

        case B_CANCEL:
            end_chmod = 1;
            break;

        case B_ALL:
        case B_MARKED:
            and_mask = or_mask = 0;
            and_mask = ~and_mask;

            for (i = 0; i < PERMISSIONS; i++) {
                if (check_perm[i].selected || ch_dlg->ret_value == B_ALL) {
                    if (check_perm[i].check->state & C_BOOL)
                        or_mask |= check_perm[i].mode;
                    else
                        and_mask &= ~check_perm[i].mode;
                }
            }

            apply_mask (&sf_stat);
            break;

        case B_SETMRK:
            and_mask = or_mask = 0;
            and_mask = ~and_mask;

            for (i = 0; i < PERMISSIONS; i++) {
                if (check_perm[i].selected)
                    or_mask |= check_perm[i].mode;
            }

            apply_mask (&sf_stat);
            break;
        case B_CLRMRK:
            and_mask = or_mask = 0;
            and_mask = ~and_mask;

            for (i = 0; i < PERMISSIONS; i++) {
                if (check_perm[i].selected)
                    and_mask &= ~check_perm[i].mode;
            }

            apply_mask (&sf_stat);
            break;
        }

        if (current_panel->marked && ch_dlg->ret_value!=B_CANCEL) {
            do_file_mark (current_panel, c_file, 0);
            need_update = 1;
        }
        destroy_dlg (ch_dlg);
    } while (current_panel->marked && !end_chmod);
    chmod_done ();
}
Пример #9
0
static void show_tree (WTree *tree)
{
    Dlg_head *h = tree->widget.parent;
    tree_entry *current;
    int i, j, topsublevel;
    int x, y;
    int tree_lines, tree_cols;

    /* Initialize */
    x = y = 0;
    tree_lines = tlines (tree);
    tree_cols  = tree->widget.cols;

    attrset (TREE_NORMALC (h));
    widget_move ((Widget*)tree, y, x);
    if (tree->is_panel){
	tree_cols  -= 2;
	x = y = 1;
    }

    g_free (tree->tree_shown);
    tree->tree_shown = g_new (tree_entry*, tree_lines);

    for (i = 0; i < tree_lines; i++)
	tree->tree_shown [i] = NULL;
    if (tree->store->tree_first)
	topsublevel = tree->store->tree_first->sublevel;
    else
	topsublevel = 0;
    if (!tree->selected_ptr){
	tree->selected_ptr = tree->store->tree_first;
	tree->topdiff = 0;
    }
    current = tree->selected_ptr;

    /* Calculate the directory which is to be shown on the topmost line */
    if (tree_navigation_flag){
	i = 0;
	while (current->prev && i < tree->topdiff){
	    current = current->prev;
	    if (current->sublevel < tree->selected_ptr->sublevel){
		if (strncmp (current->name, tree->selected_ptr->name,
			     strlen (current->name)) == 0)
		    i++;
	    } else if (current->sublevel == tree->selected_ptr->sublevel){
		for (j = strlen (current->name) - 1; current->name [j] != PATH_SEP; j--);
		if (strncmp (current->name, tree->selected_ptr->name, j) == 0)
		    i++;
	    } else if (current->sublevel == tree->selected_ptr->sublevel + 1
		       && strlen (tree->selected_ptr->name) > 1){
		if (strncmp (current->name, tree->selected_ptr->name,
			     strlen (tree->selected_ptr->name)) == 0)
		    i++;
	    }
	}
	tree->topdiff = i;
    } else
	current = back_ptr (current, &tree->topdiff);

    /* Loop for every line */
    for (i = 0; i < tree_lines; i++){
	/* Move to the beginning of the line */
	widget_move (&tree->widget, y+i, x);

	hline (' ', tree_cols);
	widget_move (&tree->widget, y+i, x);

	if (!current)
	    continue;

	tree->tree_shown [i] = current;
	if (current->sublevel == topsublevel){

	    /* Top level directory */
	    if (tree->active && current == tree->selected_ptr) {
		if (!use_colors && !tree->is_panel)
			attrset (MARKED_COLOR);
		else
			attrset (SELECTED_COLOR);
	    }

	    /* Show full name */
	    addstr ((char *) name_trunc (current->name, tree_cols - 6));
	} else{
	    /* Sub level directory */

	    acs ();
	    /* Output branch parts */
	    for (j = 0; j < current->sublevel - topsublevel - 1; j++){
		if (tree_cols - 8 - 3 * j < 9)
		    break;
		addch (' ');
		if (current->submask & (1 << (j + topsublevel + 1)))
		    addch (ACS_VLINE);
		else
		    addch (' ');
		addch (' ');
	    }
	    addch (' '); j++;
	    if (!current->next || !(current->next->submask & (1 << current->sublevel)))
		addch (ACS_LLCORNER);
	    else
		addch (ACS_LTEE);
	    addch (ACS_HLINE);
	    noacs ();

	    if (tree->active && current == tree->selected_ptr) {
		/* Selected directory -> change color */
		if (!use_colors && !tree->is_panel)
		    attrset (MARKED_COLOR);
		else
		    attrset (SELECTED_COLOR);
	    }

	    /* Show sub-name */
	    addch (' ');
	    addstr ((char *) name_trunc (current->subname,
				tree_cols - 2 - 4 - 3 * j));
	}
	addch (' ');

	/* Return to normal color */
	attrset (TREE_NORMALC (h));

	/* Calculate the next value for current */
	current = current->next;
	if (tree_navigation_flag){
	    while (current){
		if (current->sublevel < tree->selected_ptr->sublevel){
		    if (strncmp (current->name, tree->selected_ptr->name,
				 strlen (current->name)) == 0)
			break;
		} else if (current->sublevel == tree->selected_ptr->sublevel){
		    for (j = strlen (current->name) - 1; current->name [j] != PATH_SEP; j--);
		    if (strncmp (current->name,tree->selected_ptr->name,j)== 0)
			break;
		} else if (current->sublevel == tree->selected_ptr->sublevel+1
			   && strlen (tree->selected_ptr->name) > 1){
		    if (strncmp (current->name, tree->selected_ptr->name,
				 strlen (tree->selected_ptr->name)) == 0)
			break;
		}
		current = current->next;
	    }
	}
    }
    tree_show_mini_info (tree, tree_lines, tree_cols);
}
static void
init_replace (enum OperationMode mode)
{
    char buffer [128];
	static int rd_xlen = 60, rd_trunc = X_TRUNC;

#ifdef ENABLE_NLS
	static int i18n_flag;
	if (!i18n_flag)
	{
		int l1, l2, l, row;
		register int i = sizeof (rd_widgets) / sizeof (rd_widgets [0]); 
		while (i--)
			rd_widgets [i].text = _(rd_widgets [i].text);

		/* 
		 *longest of "Overwrite..." labels 
		 * (assume "Target date..." are short enough)
		 */
		l1 = max (strlen (rd_widgets [6].text), strlen (rd_widgets [11].text));

		/* longest of button rows */
		i = sizeof (rd_widgets) / sizeof (rd_widgets [0]);
		for (row = l = l2 = 0; i--;)
		{
			if (rd_widgets [i].value != 0)
			{
				if (row != rd_widgets [i].ypos)
				{
					row = rd_widgets [i].ypos;
					l2 = max (l2, l);
					l = 0;
				}
				l += strlen (rd_widgets [i].text) + 4;
			}
		}
		l2 = max (l2, l); /* last row */
		rd_xlen = max (rd_xlen, l1 + l2 + 8);
		rd_trunc = rd_xlen - 6;

		/* Now place buttons */
		l1 += 5; /* start of first button in the row */
		i = sizeof (rd_widgets) / sizeof (rd_widgets [0]);
		
		for (l = l1, row = 0; --i > 1;)
		{
			if (rd_widgets [i].value != 0)
			{
				if (row != rd_widgets [i].ypos)
				{
					row = rd_widgets [i].ypos;
					l = l1;
				}
				rd_widgets [i].xpos = l;
				l += strlen (rd_widgets [i].text) + 4;
			}
		}
		/* Abort button is centered */
		rd_widgets [1].xpos = (rd_xlen - strlen (rd_widgets [1].text) - 3) / 2;

	}
#endif /* ENABLE_NLS */

    replace_colors [0] = ERROR_COLOR;
    replace_colors [1] = COLOR_NORMAL;
    replace_colors [2] = ERROR_COLOR;
    replace_colors [3] = COLOR_NORMAL;
    
    replace_dlg = create_dlg (0, 0, 16, rd_xlen, replace_colors, replace_callback,
			      "[ Replace ]", "replace", DLG_CENTER);
    
    x_set_dialog_title (replace_dlg,
        mode == Foreground ? _(" File exists ") : _(" Background process: File exists "));


	ADD_RD_LABEL(0, name_trunc (file_progress_replace_filename, rd_trunc - strlen (rd_widgets [0].text)), 0 );
	ADD_RD_BUTTON(1);    
    
	ADD_RD_BUTTON(2);
	ADD_RD_BUTTON(3);
	ADD_RD_BUTTON(4);
	ADD_RD_BUTTON(5);
	ADD_RD_LABEL(6,0,0);

    /* "this target..." widgets */
	if (!S_ISDIR (d_stat->st_mode)){
		if ((d_stat->st_size && s_stat->st_size > d_stat->st_size))
			ADD_RD_BUTTON(7);

		ADD_RD_BUTTON(8);
    }
	ADD_RD_BUTTON(9);
	ADD_RD_BUTTON(10);
	ADD_RD_LABEL(11,0,0);
    
	ADD_RD_LABEL(12, file_date (d_stat->st_mtime), (int) d_stat->st_size);
	ADD_RD_LABEL(13, file_date (s_stat->st_mtime), (int) s_stat->st_size);
}
Пример #11
0
void
chown_cmd (void)
{
    char *fname;
    struct stat sf_stat;
    WLEntry *fe;
    Dlg_head *ch_dlg;
    uid_t new_user;
    gid_t new_group;
    char  buffer [BUF_TINY];

    do {			/* do while any files remaining */
	ch_dlg = init_chown ();
	new_user = new_group = -1;

	if (current_panel->marked)
	    fname = next_file ();	        /* next marked file */
	else
	    fname = selection (current_panel)->fname;	        /* single file */
	
	if (mc_stat (fname, &sf_stat) != 0) {	/* get status of file */
	    destroy_dlg (ch_dlg);
	    break;
	}
	
	/* select in listboxes */
	fe = listbox_search_text (l_user, get_owner(sf_stat.st_uid));
	if (fe)
	    listbox_select_entry (l_user, fe);
    
	fe = listbox_search_text (l_group, get_group(sf_stat.st_gid));
	if (fe)
	    listbox_select_entry (l_group, fe);

        chown_label (0, name_trunc (fname, 15));
        chown_label (1, name_trunc (get_owner (sf_stat.st_uid), 15));
	chown_label (2, name_trunc (get_group (sf_stat.st_gid), 15));
	size_trunc_len (buffer, 15, sf_stat.st_size, 0);
	chown_label (3, buffer);
	chown_label (4, string_perm (sf_stat.st_mode));

	run_dlg (ch_dlg);
    
	switch (ch_dlg->ret_value) {
	case B_CANCEL:
	    end_chown = 1;
	    break;
	    
	case B_SETUSR:
	{
	    struct passwd *user;

	    user = getpwnam (l_user->current->text);
	    if (user){
		new_user = user->pw_uid;
		apply_chowns (new_user, new_group);
	    }
	    break;
	}   
	case B_SETGRP:
	{
	    struct group *grp;

	    grp = getgrnam (l_group->current->text);
	    if (grp){
		new_group = grp->gr_gid;
		apply_chowns (new_user, new_group);
	    }
	    break;
	}
	case B_SETALL:
	case B_ENTER:
	{
	    struct group *grp;
	    struct passwd *user;
	    
	    grp = getgrnam (l_group->current->text);
	    if (grp)
		new_group = grp->gr_gid;
	    user = getpwnam (l_user->current->text);
	    if (user)
		new_user = user->pw_uid;
	    if (ch_dlg->ret_value==B_ENTER) {
		need_update = 1;
		if (mc_chown (fname, new_user, new_group) == -1)
		    message (1, MSG_ERROR, _(" Cannot chown \"%s\" \n %s "),
	 		 fname, unix_error_string (errno));
	    } else
		apply_chowns (new_user, new_group);
	    break;
	}
	}
	
	if (current_panel->marked && ch_dlg->ret_value != B_CANCEL){
	    do_file_mark (current_panel, current_file, 0);
	    need_update = 1;
	}
	destroy_dlg (ch_dlg);
    } while (current_panel->marked && !end_chown);
    
    chown_done ();
}
Пример #12
0
void
chown_cmd (void)
{
    char *fname;
    struct stat sf_stat;
    WLEntry *fe;
    uid_t new_user;
    gid_t new_group;
    char  buffer [15];

#if 0
    /* Please no */
    if (!vfs_current_is_local ()) {
	if (vfs_current_is_extfs ()) {
	    message (1, _(" Oops... "),
		     _(" I can't run the Chown command on an extfs "));
	    return;
	} else if (vfs_current_is_tarfs ()) {
	    message (1, _(" Oops... "),
		     _(" I can't run the Chown command on a tarfs "));
	    return;
	}
    }
#endif

    do {			/* do while any files remaining */
	init_chown ();
	new_user = new_group = -1;

	if (cpanel->marked)
	    fname = next_file ();	        /* next marked file */
	else
	    fname = selection (cpanel)->fname;	        /* single file */
	
	if (!stat_file (fname, &sf_stat)){	/* get status of file */
	    destroy_dlg (ch_dlg);
	    break;
	}
	
	/* select in listboxes */
	fe = listbox_search_text (l_user, get_owner(sf_stat.st_uid));
	if (fe)
	    listbox_select_entry (l_user, fe);
    
	fe = listbox_search_text (l_group, get_group(sf_stat.st_gid));
	if (fe)
	    listbox_select_entry (l_group, fe);

        chown_label (0, name_trunc (fname, 15));
        chown_label (1, name_trunc (get_owner (sf_stat.st_uid), 15));
	chown_label (2, name_trunc (get_group (sf_stat.st_gid), 15));
        sprintf (buffer, "%d", c_fsize);
	chown_label (3, buffer);
	chown_label (4, string_perm (sf_stat.st_mode));

	run_dlg (ch_dlg);
    
	switch (ch_dlg->ret_value) {
	case B_CANCEL:
	    end_chown = 1;
	    break;
	    
	case B_SETUSR:
	{
	    struct passwd *user;

	    user = getpwnam (l_user->current->text);
	    if (user){
		new_user = user->pw_uid;
		apply_chowns (new_user, new_group);
	    }
	    break;
	}   
	case B_SETGRP:
	{
	    struct group *grp;

	    grp = getgrnam (l_group->current->text);
	    if (grp){
		new_group = grp->gr_gid;
		apply_chowns (new_user, new_group);
	    }
	    break;
	}
	case B_SETALL:
	case B_ENTER:
	{
	    struct group *grp;
	    struct passwd *user;
	    
	    grp = getgrnam (l_group->current->text);
	    if (grp)
		new_group = grp->gr_gid;
	    user = getpwnam (l_user->current->text);
	    if (user)
		new_user = user->pw_uid;
	    if (ch_dlg->ret_value==B_ENTER) {
		need_update = 1;
		if (mc_chown (fname, new_user, new_group) == -1)
		    message (1, MSG_ERROR, _(" Couldn't chown \"%s\" \n %s "),
	 		 fname, unix_error_string (errno));
	    } else
		apply_chowns (new_user, new_group);
	    break;
	}
	}
	
	if (cpanel->marked && ch_dlg->ret_value != B_CANCEL){
	    do_file_mark (cpanel, current_file, 0);
	    need_update = 1;
	}
	destroy_dlg (ch_dlg);
    } while (cpanel->marked && !end_chown);
    
    chown_done ();
}