2 Chown command -- for the Midnight Commander
4 Copyright (C) 1994, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
6 The Free Software Foundation, Inc.
8 This file is part of the Midnight Commander.
10 The Midnight Commander is free software: you can redistribute it
11 and/or modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation, either version 3 of the License,
13 or (at your option) any later version.
15 The Midnight Commander is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 * \brief Source: chown command
35 #include <sys/types.h>
39 #include "lib/global.h"
41 #include "lib/tty/tty.h"
43 #include "lib/vfs/vfs.h"
44 #include "lib/strutil.h"
46 #include "lib/widget.h"
48 #include "src/setup.h" /* panels_options */
50 /* Needed for the extern declarations of integer parameters */
52 #include "midnight.h" /* current_panel */
56 /*** global variables ****************************************************************************/
58 /*** file scope macro definitions ****************************************************************/
65 #define B_SETALL B_USER
66 #define B_SETUSR (B_USER + 1)
67 #define B_SETGRP (B_USER + 2)
71 #define chown_label(n,txt) label_set_text (chown_label [n].l, txt)
73 /*** file scope type declarations ****************************************************************/
75 /*** file scope variables ************************************************************************/
77 static int need_update
, end_chown
;
78 static int current_file
;
79 static int single_set
;
80 static WListbox
*l_user
, *l_group
;
85 int ret_cmd
, flags
, y
, len
;
87 } chown_but
[BUTTONS
] = {
88 { B_SETALL
, NORMAL_BUTTON
, 5, 0, N_("Set &all") },
89 { B_SETGRP
, NORMAL_BUTTON
, 5, 0, N_("Set &groups") },
90 { B_SETUSR
, NORMAL_BUTTON
, 5, 0, N_("Set &users") },
91 { B_ENTER
, DEFPUSH_BUTTON
, 3, 0, N_("&Set") },
92 { B_CANCEL
, NORMAL_BUTTON
, 3, 0, N_("&Cancel") },
95 /* summary length of three buttons */
96 static unsigned int blen
= 0;
101 } chown_label
[LABELS
] = {
110 /* --------------------------------------------------------------------------------------------- */
111 /*** file scope functions ************************************************************************/
112 /* --------------------------------------------------------------------------------------------- */
117 static gboolean i18n
= FALSE
;
126 for (i
= 0; i
< BUTTONS
; i
++)
127 chown_but
[i
].text
= _(chown_but
[i
].text
);
128 #endif /* ENABLE_NLS */
130 for (i
= 0; i
< BUTTONS
; i
++)
132 chown_but
[i
].len
= str_term_width1 (chown_but
[i
].text
) + 3; /* [], spaces and w/o & */
133 if (chown_but
[i
].flags
== DEFPUSH_BUTTON
)
134 chown_but
[i
].len
+= 2; /* <> */
137 blen
+= chown_but
[i
].len
;
143 /* --------------------------------------------------------------------------------------------- */
146 chown_refresh (WDialog
* h
)
149 const int x
= 7 + GW
* 2;
151 dlg_default_repaint (h
);
153 tty_setcolor (COLOR_NORMAL
);
155 widget_move (h
, y
+ 0, x
);
156 tty_print_string (_("Name"));
157 widget_move (h
, y
+ 2, x
);
158 tty_print_string (_("Owner name"));
159 widget_move (h
, y
+ 4, x
);
160 tty_print_string (_("Group name"));
161 widget_move (h
, y
+ 6, x
);
162 tty_print_string (_("Size"));
163 widget_move (h
, y
+ 8, x
);
164 tty_print_string (_("Permission"));
167 /* --------------------------------------------------------------------------------------------- */
172 while (!current_panel
->dir
.list
[current_file
].f
.marked
)
175 return current_panel
->dir
.list
[current_file
].fname
;
178 /* --------------------------------------------------------------------------------------------- */
181 chown_callback (Widget
* w
, Widget
* sender
, widget_msg_t msg
, int parm
, void *data
)
186 chown_refresh (DIALOG (w
));
190 return dlg_default_callback (w
, sender
, msg
, parm
, data
);
194 /* --------------------------------------------------------------------------------------------- */
202 struct passwd
*l_pass
;
208 end_chown
= need_update
= current_file
= 0;
209 single_set
= (current_panel
->marked
< 2) ? 3 : 0;
211 cols
= GW
* 3 + 2 + 6;
212 lines
= GH
+ 4 + (single_set
? 2 : 4);
215 create_dlg (TRUE
, 0, 0, lines
, cols
, dialog_colors
, chown_callback
, NULL
, "[Chown]",
216 _("Chown command"), DLG_CENTER
);
218 add_widget (ch_dlg
, groupbox_new (2, 3, GH
, GW
, _("User name")));
219 l_user
= listbox_new (3, 4, GH
- 2, GW
- 2, FALSE
, NULL
);
220 add_widget (ch_dlg
, l_user
);
221 /* add field for unknown names (numbers) */
222 listbox_add_item (l_user
, LISTBOX_APPEND_AT_END
, 0, _("<Unknown user>"), NULL
);
223 /* get and put user names in the listbox */
225 while ((l_pass
= getpwent ()) != NULL
)
226 listbox_add_item (l_user
, LISTBOX_APPEND_SORTED
, 0, l_pass
->pw_name
, NULL
);
229 add_widget (ch_dlg
, groupbox_new (2, 4 + GW
, GH
, GW
, _("Group name")));
230 l_group
= listbox_new (3, 5 + GW
, GH
- 2, GW
- 2, FALSE
, NULL
);
231 add_widget (ch_dlg
, l_group
);
232 /* add field for unknown names (numbers) */
233 listbox_add_item (l_group
, LISTBOX_APPEND_AT_END
, 0, _("<Unknown group>"), NULL
);
234 /* get and put group names in the listbox */
236 while ((l_grp
= getgrent ()) != NULL
)
237 listbox_add_item (l_group
, LISTBOX_APPEND_SORTED
, 0, l_grp
->gr_name
, NULL
);
240 add_widget (ch_dlg
, groupbox_new (2, 5 + GW
* 2, GH
, GW
, _("File")));
241 /* add widgets for the file information */
242 for (i
= 0; i
< LABELS
; i
++)
244 chown_label
[i
].l
= label_new (chown_label
[i
].y
, 7 + GW
* 2, "");
245 add_widget (ch_dlg
, chown_label
[i
].l
);
252 add_widget (ch_dlg
, hline_new (lines
- chown_but
[0].y
- 1, -1, -1));
254 y
= lines
- chown_but
[0].y
;
255 x
= (cols
- blen
) / 2;
257 for (i
= 0; i
< BUTTONS
- 2; i
++)
260 button_new (y
, x
, chown_but
[i
].ret_cmd
, chown_but
[i
].flags
,
261 chown_but
[i
].text
, NULL
));
262 x
+= chown_but
[i
].len
+ 1;
267 y
= lines
- chown_but
[i
].y
;
268 add_widget (ch_dlg
, hline_new (y
- 1, -1, -1));
270 button_new (y
, WIDGET (ch_dlg
)->cols
/ 2 - chown_but
[i
].len
, chown_but
[i
].ret_cmd
,
271 chown_but
[i
].flags
, chown_but
[i
].text
, NULL
));
274 button_new (y
, WIDGET (ch_dlg
)->cols
/ 2 + 1, chown_but
[i
].ret_cmd
,
275 chown_but
[i
].flags
, chown_but
[i
].text
, NULL
));
277 /* select first listbox */
278 dlg_select_widget (l_user
);
283 /* --------------------------------------------------------------------------------------------- */
289 update_panels (UP_OPTIMIZE
, UP_KEEPSEL
);
293 /* --------------------------------------------------------------------------------------------- */
296 do_chown (uid_t u
, gid_t g
)
300 vpath
= vfs_path_from_str (current_panel
->dir
.list
[current_file
].fname
);
301 if (mc_chown (vpath
, u
, g
) == -1)
302 message (D_ERROR
, MSG_ERROR
, _("Cannot chown \"%s\"\n%s"),
303 current_panel
->dir
.list
[current_file
].fname
, unix_error_string (errno
));
305 vfs_path_free (vpath
);
306 do_file_mark (current_panel
, current_file
, 0);
309 /* --------------------------------------------------------------------------------------------- */
312 apply_chowns (uid_t u
, gid_t g
)
315 need_update
= end_chown
= 1;
323 while (current_panel
->marked
);
326 /* --------------------------------------------------------------------------------------------- */
327 /*** public functions ****************************************************************************/
328 /* --------------------------------------------------------------------------------------------- */
338 char buffer
[BUF_TINY
];
343 { /* do while any files remaining */
346 ch_dlg
= init_chown ();
347 new_user
= new_group
= -1;
349 if (current_panel
->marked
)
350 fname
= next_file (); /* next marked file */
352 fname
= selection (current_panel
)->fname
; /* single file */
354 vpath
= vfs_path_from_str (fname
);
355 if (mc_stat (vpath
, &sf_stat
) != 0)
356 { /* get status of file */
357 destroy_dlg (ch_dlg
);
358 vfs_path_free (vpath
);
361 vfs_path_free (vpath
);
363 /* select in listboxes */
364 listbox_select_entry (l_user
, listbox_search_text (l_user
, get_owner (sf_stat
.st_uid
)));
365 listbox_select_entry (l_group
, listbox_search_text (l_group
, get_group (sf_stat
.st_gid
)));
367 chown_label (0, str_trunc (fname
, GW
- 4));
368 chown_label (1, str_trunc (get_owner (sf_stat
.st_uid
), GW
- 4));
369 chown_label (2, str_trunc (get_group (sf_stat
.st_gid
), GW
- 4));
370 size_trunc_len (buffer
, GW
- 4, sf_stat
.st_size
, 0, panels_options
.kilobyte_si
);
371 chown_label (3, buffer
);
372 chown_label (4, string_perm (sf_stat
.st_mode
));
374 switch (run_dlg (ch_dlg
))
385 listbox_get_current (l_user
, &text
, NULL
);
386 user
= getpwnam (text
);
389 new_user
= user
->pw_uid
;
390 apply_chowns (new_user
, new_group
);
400 listbox_get_current (l_group
, &text
, NULL
);
401 grp
= getgrnam (text
);
404 new_group
= grp
->gr_gid
;
405 apply_chowns (new_user
, new_group
);
417 listbox_get_current (l_group
, &text
, NULL
);
418 grp
= getgrnam (text
);
420 new_group
= grp
->gr_gid
;
421 listbox_get_current (l_user
, &text
, NULL
);
422 user
= getpwnam (text
);
424 new_user
= user
->pw_uid
;
425 if (ch_dlg
->ret_value
== B_ENTER
)
427 vfs_path_t
*fname_vpath
;
429 fname_vpath
= vfs_path_from_str (fname
);
431 if (mc_chown (fname_vpath
, new_user
, new_group
) == -1)
432 message (D_ERROR
, MSG_ERROR
, _("Cannot chown \"%s\"\n%s"),
433 fname
, unix_error_string (errno
));
434 vfs_path_free (fname_vpath
);
437 apply_chowns (new_user
, new_group
);
442 if (current_panel
->marked
&& ch_dlg
->ret_value
!= B_CANCEL
)
444 do_file_mark (current_panel
, current_file
, 0);
448 destroy_dlg (ch_dlg
);
450 while (current_panel
->marked
&& !end_chown
);
455 /* --------------------------------------------------------------------------------------------- */