Commit d07b719f d07b719f34ab7c79f4936a165c4fe84d9ea974c3 by Sergey Poznyakoff

New option --copy-permissions (-P).

1 parent 4e2c4c91
...@@ -22,6 +22,9 @@ ...@@ -22,6 +22,9 @@
22 22
23 #include <stdlib.h> 23 #include <stdlib.h>
24 #include <string.h> 24 #include <string.h>
25 #include <sys/stat.h>
26 #include <grp.h>
27 #include <unistd.h>
25 #include <mailutils/mailutils.h> 28 #include <mailutils/mailutils.h>
26 #include <mailutils/tls.h> 29 #include <mailutils/tls.h>
27 #include <mu_asprintf.h> 30 #include <mu_asprintf.h>
...@@ -39,12 +42,16 @@ static struct argp_option options[] = { ...@@ -39,12 +42,16 @@ static struct argp_option options[] = {
39 { "reverse", 'r', NULL, 0, N_("Reverse the sorting order"), 0 }, 42 { "reverse", 'r', NULL, 0, N_("Reverse the sorting order"), 0 },
40 { "emacs", OPT_EMACS, NULL, 0, 43 { "emacs", OPT_EMACS, NULL, 0,
41 N_("Output information used by Emacs rmail interface"), 0 }, 44 N_("Output information used by Emacs rmail interface"), 0 },
45 { "copy-permissions", 'P', NULL, 0,
46 N_("Copy original mailbox permissions and ownership when applicable"),
47 0 },
42 { NULL, 0, NULL, 0, NULL, 0 } 48 { NULL, 0, NULL, 0, NULL, 0 }
43 }; 49 };
44 50
45 static int reverse_order; 51 static int reverse_order;
46 static int preserve_mail; 52 static int preserve_mail;
47 static int emacs_mode; 53 static int emacs_mode;
54 static int copy_meta;
48 55
49 static error_t 56 static error_t
50 parse_opt (int key, char *arg, struct argp_state *state) 57 parse_opt (int key, char *arg, struct argp_state *state)
...@@ -58,11 +65,15 @@ parse_opt (int key, char *arg, struct argp_state *state) ...@@ -58,11 +65,15 @@ parse_opt (int key, char *arg, struct argp_state *state)
58 break; 65 break;
59 66
60 case 'p': 67 case 'p':
61 mu_argp_node_list_new (&lst, "preserve", arg); 68 mu_argp_node_list_new (&lst, "preserve", "yes");
62 break; 69 break;
63 70
71 case 'P':
72 copy_meta = 1;
73 break;
74
64 case OPT_EMACS: 75 case OPT_EMACS:
65 mu_argp_node_list_new (&lst, "emacs", arg); 76 mu_argp_node_list_new (&lst, "emacs", "yes");
66 break; 77 break;
67 78
68 case ARGP_KEY_INIT: 79 case ARGP_KEY_INIT:
...@@ -106,6 +117,7 @@ static const char *movemail_capa[] = { ...@@ -106,6 +117,7 @@ static const char *movemail_capa[] = {
106 "license", 117 "license",
107 "locking", 118 "locking",
108 "mailbox", 119 "mailbox",
120 "auth",
109 NULL 121 NULL
110 }; 122 };
111 123
...@@ -277,6 +289,69 @@ close_mailboxes (void) ...@@ -277,6 +289,69 @@ close_mailboxes (void)
277 mu_mailbox_close (source); 289 mu_mailbox_close (source);
278 } 290 }
279 291
292 static void
293 set_permissions (mu_mailbox_t mbox)
294 {
295 mu_url_t url = NULL;
296 const char *s;
297 int rc;
298 uid_t uid;
299 gid_t gid;
300
301 if (getuid () != 0)
302 {
303 mu_error (_("must be root to use --copy-permissions"));
304 exit (1);
305 }
306 mu_mailbox_get_url (mbox, &url);
307 rc = mu_url_sget_scheme (url, &s);
308 if (rc)
309 die (mbox, _("Cannot get scheme"), rc);
310 if (strcmp (s, "/") == 0
311 || strcmp (s, "mbox") == 0
312 || strcmp (s, "mh") == 0
313 || strcmp (s, "maildir") == 0)
314 {
315 struct stat st;
316
317 rc = mu_url_sget_path (url, &s);
318 if (rc)
319 die (mbox, _("Cannot get path"), rc);
320 if (stat (s, &st))
321 {
322 mu_error (_("Cannot stat mailbox `%s': %s"), s,
323 mu_strerror (errno));
324 exit (1);
325 }
326 uid = st.st_uid;
327 gid = st.st_gid;
328 }
329 else
330 {
331 struct mu_auth_data *auth;
332
333 rc = mu_url_sget_user (url, &s);
334 if (rc)
335 die (mbox, _("Cannot get user"), rc);
336
337 auth = mu_get_auth_by_name (s);
338 if (!auth)
339 {
340 mu_error (_("No such user: %s"), s);
341 exit (1);
342 }
343 else
344 {
345 uid = auth->uid;
346 gid = auth->gid;
347 }
348 mu_auth_data_free (auth);
349 }
350
351 if (mu_switch_to_privs (uid, gid, NULL))
352 exit (1);
353 }
354
280 int 355 int
281 main (int argc, char **argv) 356 main (int argc, char **argv)
282 { 357 {
...@@ -288,6 +363,8 @@ main (int argc, char **argv) ...@@ -288,6 +363,8 @@ main (int argc, char **argv)
288 363
289 /* Native Language Support */ 364 /* Native Language Support */
290 MU_APP_INIT_NLS (); 365 MU_APP_INIT_NLS ();
366 MU_AUTH_REGISTER_ALL_MODULES ();
367
291 /* Register the desired mailbox formats. */ 368 /* Register the desired mailbox formats. */
292 mu_register_all_mbox_formats (); 369 mu_register_all_mbox_formats ();
293 370
...@@ -298,7 +375,7 @@ main (int argc, char **argv) ...@@ -298,7 +375,7 @@ main (int argc, char **argv)
298 #endif 375 #endif
299 mu_argp_init (program_version, NULL); 376 mu_argp_init (program_version, NULL);
300 if (mu_app_init (&argp, movemail_capa, movemail_cfg_param, 377 if (mu_app_init (&argp, movemail_capa, movemail_cfg_param,
301 argc, argv, 0, NULL, NULL)) 378 argc, argv, 0, &index, NULL))
302 exit (1); 379 exit (1);
303 380
304 argc -= index; 381 argc -= index;
...@@ -321,6 +398,9 @@ main (int argc, char **argv) ...@@ -321,6 +398,9 @@ main (int argc, char **argv)
321 compatibility_mode (&source, source_name, argv[2], flags); 398 compatibility_mode (&source, source_name, argv[2], flags);
322 else 399 else
323 open_mailbox (&source, source_name, flags, argv[2]); 400 open_mailbox (&source, source_name, flags, argv[2]);
401
402 if (copy_meta)
403 set_permissions (source);
324 404
325 open_mailbox (&dest, dest_name, MU_STREAM_RDWR | MU_STREAM_CREAT, NULL); 405 open_mailbox (&dest, dest_name, MU_STREAM_RDWR | MU_STREAM_CREAT, NULL);
326 406
......