int main(int argc, char *argv[]) { extern char *optarg; int opt, r = 0; char *alt_config = NULL, *intname = NULL, *extname = NULL; struct mailbox *mailbox = NULL; int mode = MODE_UNKNOWN; unsigned numrestored = 0; time_t time_since = time(NULL); int len, secs = 0; unsigned long *uids = NULL; unsigned nuids = 0; while ((opt = getopt(argc, argv, "C:laudt:f:v")) != EOF) { switch (opt) { case 'C': /* alt config file */ alt_config = optarg; break; case 'l': if (mode != MODE_UNKNOWN) usage(); mode = MODE_LIST; break; case 'a': if (mode != MODE_UNKNOWN) usage(); mode = MODE_ALL; break; case 't': if (mode != MODE_UNKNOWN) usage(); mode = MODE_TIME; secs = atoi(optarg); len = strlen(optarg); if ((secs > 0) && (len > 1)) { switch (optarg[len-1]) { case 'm': secs *= 60; break; case 'h': secs *= (60*60); break; case 'd': secs *= (24*60*60); break; case 'w': secs *= (7*24*60*60); break; } } time_since = time(NULL) - secs; break; case 'u': if (mode != MODE_UNKNOWN) usage(); mode = MODE_UID; break; case 'd': unsetdeleted = 1; break; case 'f': addflag = optarg; break; case 'v': verbose = 1; break; default: usage(); break; } } /* sanity check */ if (mode == MODE_UNKNOWN || (optind + (mode == MODE_UID ? 1 : 0)) >= argc) usage(); cyrus_init(alt_config, "unexpunge", 0, 0); sync_log_init(); if (addflag && addflag[0] == '\\') { syslog(LOG_ERR, "can't set a system flag"); fatal("can't set a system flag", EX_SOFTWARE); } /* Set namespace -- force standard (internal) */ if ((r = mboxname_init_namespace(&unex_namespace, 1)) != 0) { syslog(LOG_ERR, "%s", error_message(r)); fatal(error_message(r), EX_CONFIG); } /* Translate mailboxname */ intname = mboxname_from_external(argv[optind], &unex_namespace, NULL); if (mode == MODE_LIST) { list_expunged(intname); goto done; } /* Open/lock header */ r = mailbox_open_iwl(intname, &mailbox); if (r) { printf("Failed to open mailbox '%s'\n", intname); goto done; } if (mode == MODE_UID) { unsigned i; nuids = argc - ++optind; uids = (unsigned long *) xmalloc(nuids * sizeof(unsigned long)); for (i = 0; i < nuids; i++) uids[i] = strtoul(argv[optind+i], NULL, 10); /* Sort the UIDs so we can binary search */ qsort(uids, nuids, sizeof(unsigned long), compare_uid); } extname = mboxname_to_external(intname, &unex_namespace, NULL); printf("restoring %sexpunged messages in mailbox '%s'\n", mode == MODE_ALL ? "all " : "", extname); r = restore_expunged(mailbox, mode, uids, nuids, time_since, &numrestored, extname); if (!r) { printf("restored %u expunged messages\n", numrestored); syslog(LOG_NOTICE, "restored %u expunged messages in mailbox '%s'", numrestored, extname); } mailbox_close(&mailbox); done: free(intname); free(extname); sync_log_done(); cyrus_done(); exit(r); }
int main(int argc, char *argv[]) { extern char *optarg; int opt, r = 0; char *alt_config = NULL; char buf[MAX_MAILBOX_PATH+1]; struct mailbox *mailbox = NULL; int mode = MODE_UNKNOWN; unsigned numrestored = 0; time_t time_since = time(NULL); int len, secs = 0; unsigned long *uids = NULL; unsigned nuids = 0; char *mboxname = NULL; if ((geteuid()) == 0 && (become_cyrus(/*is_master*/0) != 0)) { fatal("must run as the Cyrus user", EC_USAGE); } while ((opt = getopt(argc, argv, "C:laudt:v")) != EOF) { switch (opt) { case 'C': /* alt config file */ alt_config = optarg; break; case 'l': if (mode != MODE_UNKNOWN) usage(); mode = MODE_LIST; break; case 'a': if (mode != MODE_UNKNOWN) usage(); mode = MODE_ALL; break; case 't': if (mode != MODE_UNKNOWN) usage(); mode = MODE_TIME; secs = atoi(optarg); len = strlen(optarg); if ((secs > 0) && (len > 1)) { switch (optarg[len-1]) { case 'm': secs *= 60; break; case 'h': secs *= (60*60); break; case 'd': secs *= (24*60*60); break; case 'w': secs *= (7*24*60*60); break; } } time_since = time(NULL) - secs; break; case 'u': if (mode != MODE_UNKNOWN) usage(); mode = MODE_UID; break; case 'd': unsetdeleted = 1; break; case 'v': verbose = 1; break; default: usage(); break; } } /* sanity check */ if (mode == MODE_UNKNOWN || (optind + (mode == MODE_UID ? 1 : 0)) >= argc) usage(); cyrus_init(alt_config, "unexpunge", 0, 0); mboxlist_init(0); mboxlist_open(NULL); quotadb_init(0); quotadb_open(NULL); sync_log_init(); /* Set namespace -- force standard (internal) */ if ((r = mboxname_init_namespace(&unex_namespace, 1)) != 0) { syslog(LOG_ERR, "%s", error_message(r)); fatal(error_message(r), EC_CONFIG); } /* Translate mailboxname */ (*unex_namespace.mboxname_tointernal)(&unex_namespace, argv[optind], NULL, buf); if (mode == MODE_LIST) { list_expunged(buf); goto done; } /* Open/lock header */ r = mailbox_open_iwl(buf, &mailbox); if (r) { printf("Failed to open mailbox '%s'\n", buf); goto done; } if (mode == MODE_UID) { unsigned i; nuids = argc - ++optind; uids = (unsigned long *) xmalloc(nuids * sizeof(unsigned long)); for (i = 0; i < nuids; i++) uids[i] = strtoul(argv[optind+i], NULL, 10); /* Sort the UIDs so we can binary search */ qsort(uids, nuids, sizeof(unsigned long), compare_uid); } mboxname = xstrdup(mailbox->name); mboxname_hiersep_toexternal(&unex_namespace, mboxname, 0); printf("restoring %sexpunged messages in mailbox '%s'\n", mode == MODE_ALL ? "all " : "", mboxname); r = restore_expunged(mailbox, mode, uids, nuids, time_since, &numrestored, mboxname); if (!r) { printf("restored %u expunged messages\n", numrestored); syslog(LOG_NOTICE, "restored %u expunged messages in mailbox '%s'", numrestored, mboxname); } mailbox_close(&mailbox); done: sync_log_done(); quotadb_close(); quotadb_done(); mboxlist_close(); mboxlist_done(); cyrus_done(); exit(r); }