/* * mboxlist_findall() callback function to examine a mailbox */ static int do_timestamp(char *name) { unsigned recno; int r = 0; char ext_name_buf[MAX_MAILBOX_PATH+1]; struct mailbox *mailbox = NULL; struct index_record record; char olddate[RFC822_DATETIME_MAX+1]; char newdate[RFC822_DATETIME_MAX+1]; signals_poll(); /* Convert internal name to external */ (*recon_namespace.mboxname_toexternal)(&recon_namespace, name, "cyrus", ext_name_buf); printf("Working on %s...\n", ext_name_buf); /* Open/lock header */ r = mailbox_open_iwl(name, &mailbox); if (r) return r; for (recno = 1; recno <= mailbox->i.num_records; recno++) { r = mailbox_read_index_record(mailbox, recno, &record); if (r) goto done; if (record.system_flags & FLAG_EXPUNGED) continue; /* 1 day is close enough */ if (abs(record.internaldate - record.gmtime) < 86400) continue; time_to_rfc822(record.internaldate, olddate, sizeof(olddate)); time_to_rfc822(record.gmtime, newdate, sizeof(newdate)); printf(" %u: %s => %s\n", record.uid, olddate, newdate); /* switch internaldate */ record.internaldate = record.gmtime; r = mailbox_rewrite_index_record(mailbox, &record); if (r) goto done; } done: mailbox_close(&mailbox); return r; }
/* * mboxlist_findall() callback function to examine a mailbox */ static int do_timestamp(const char *name) { int r = 0; char ext_name_buf[MAX_MAILBOX_PATH+1]; struct mailbox *mailbox = NULL; const struct index_record *record; char olddate[RFC822_DATETIME_MAX+1]; char newdate[RFC822_DATETIME_MAX+1]; signals_poll(); /* Convert internal name to external */ (*recon_namespace.mboxname_toexternal)(&recon_namespace, name, "cyrus", ext_name_buf); printf("Working on %s...\n", ext_name_buf); /* Open/lock header */ r = mailbox_open_iwl(name, &mailbox); if (r) return r; struct mailbox_iter *iter = mailbox_iter_init(mailbox, 0, ITER_SKIP_EXPUNGED); while ((record = mailbox_iter_step(iter))) { /* 1 day is close enough */ if (labs(record->internaldate - record->gmtime) < 86400) continue; struct index_record copyrecord = *record; time_to_rfc822(copyrecord.internaldate, olddate, sizeof(olddate)); time_to_rfc822(copyrecord.gmtime, newdate, sizeof(newdate)); printf(" %u: %s => %s\n", copyrecord.uid, olddate, newdate); /* switch internaldate */ copyrecord.internaldate = copyrecord.gmtime; r = mailbox_rewrite_index_record(mailbox, ©record); if (r) goto done; } done: mailbox_iter_done(&iter); mailbox_close(&mailbox); return r; }
static int restore_expunged(struct mailbox *mailbox, int mode, unsigned long *uids, unsigned nuids, time_t time_since, unsigned *numrestored, const char *extname) { struct index_record newrecord; annotate_state_t *astate = NULL; unsigned uidnum = 0; char oldfname[MAX_MAILBOX_PATH]; const char *fname; char *userid = mboxname_to_userid(mailbox->name); int r = 0; *numrestored = 0; struct mailbox_iter *iter = mailbox_iter_init(mailbox, 0, ITER_SKIP_UNLINKED); const message_t *msg; while ((msg = mailbox_iter_step(iter))) { const struct index_record *record = msg_record(msg); /* still active */ if (!(record->internal_flags & FLAG_INTERNAL_EXPUNGED)) continue; if (mode == MODE_UID) { while (uidnum < nuids && record->uid > uids[uidnum]) uidnum++; if (uidnum >= nuids) continue; if (record->uid != uids[uidnum]) continue; /* otherwise we want this one */ } else if (mode == MODE_TIME) { if (record->last_updated < time_since) continue; /* otherwise we want this one */ } /* work on a copy */ newrecord = *record; /* duplicate the old filename */ fname = mailbox_record_fname(mailbox, record); xstrncpy(oldfname, fname, MAX_MAILBOX_PATH); /* bump the UID, strip the flags */ newrecord.uid = mailbox->i.last_uid + 1; newrecord.internal_flags &= ~FLAG_INTERNAL_EXPUNGED; if (unsetdeleted) newrecord.system_flags &= ~FLAG_DELETED; /* copy the message file */ fname = mailbox_record_fname(mailbox, &newrecord); r = mailbox_copyfile(oldfname, fname, 0); if (r) break; /* add the flag if requested */ if (addflag) { int userflag = 0; r = mailbox_user_flag(mailbox, addflag, &userflag, 1); if (r) break; newrecord.user_flags[userflag/32] |= 1<<(userflag&31); } /* and append the new record */ r = mailbox_append_index_record(mailbox, &newrecord); if (r) break; /* ensure we have an astate connected to the destination * mailbox, so that the annotation txn will be committed * when we close the mailbox */ r = mailbox_get_annotate_state(mailbox, newrecord.uid, &astate); if (r) break; /* and copy over any annotations */ r = annotate_msg_copy(mailbox, record->uid, mailbox, newrecord.uid, userid); if (r) break; if (verbose) printf("Unexpunged %s: %u => %u\n", extname, record->uid, newrecord.uid); /* mark the old one unlinked so we don't see it again */ struct index_record oldrecord = *record; oldrecord.internal_flags |= FLAG_INTERNAL_UNLINKED | FLAG_INTERNAL_NEEDS_CLEANUP; r = mailbox_rewrite_index_record(mailbox, &oldrecord); if (r) break; (*numrestored)++; } /* better get that seen to */ if (*numrestored) mailbox->i.options |= OPT_MAILBOX_NEEDS_UNLINK; mailbox_iter_done(&iter); free(userid); return r; }
static int restore_expunged(struct mailbox *mailbox, int mode, unsigned long *uids, unsigned nuids, time_t time_since, unsigned *numrestored, const char *mboxname) { uint32_t recno; uint32_t olduid; struct index_record record; unsigned uidnum = 0; char oldfname[MAX_MAILBOX_PATH]; const char *fname; int r = 0; *numrestored = 0; for (recno = 1; recno <= mailbox->i.num_records; recno++) { r = mailbox_read_index_record(mailbox, recno, &record); if (r) return r; /* still active */ if (!(record.system_flags & FLAG_EXPUNGED)) continue; /* no file, unrescuable */ if (record.system_flags & FLAG_UNLINKED) continue; if (mode == MODE_UID) { while (uidnum < nuids && record.uid > uids[uidnum]) uidnum++; if (uidnum >= nuids) continue; if (record.uid != uids[uidnum]) continue; /* otherwise we want this one */ } else if (mode == MODE_TIME) { if (record.last_updated < time_since) continue; /* otherwise we want this one */ } /* mark the old one unlinked so we don't see it again */ olduid = record.uid; record.system_flags |= FLAG_UNLINKED; r = mailbox_rewrite_index_record(mailbox, &record); if (r) return r; /* duplicate the old filename */ fname = mailbox_message_fname(mailbox, olduid); xstrncpy(oldfname, fname, MAX_MAILBOX_PATH); /* bump the UID, strip the flags */ record.uid = mailbox->i.last_uid + 1; record.system_flags &= ~(FLAG_UNLINKED|FLAG_EXPUNGED); if (unsetdeleted) record.system_flags &= ~FLAG_DELETED; /* copy the message file */ fname = mailbox_message_fname(mailbox, record.uid); r = mailbox_copyfile(oldfname, fname, 0); if (r) return r; /* and append the new record */ mailbox_append_index_record(mailbox, &record); if (verbose) printf("Unexpunged %s: %u => %u\n", mboxname, olduid, record.uid); (*numrestored)++; } return 0; }