EXPORTED int dlist_toguid(struct dlist *dl, struct message_guid **valp) { struct message_guid tmpguid; if (!dl) return 0; switch (dl->type) { case DL_ATOM: case DL_BUF: if (dl->nval != 40) return 0; if (!message_guid_decode(&tmpguid, dl->sval)) return 0; /* successfully parsed - switch to guid value */ dlist_makeguid(dl, &tmpguid); break; case DL_GUID: break; default: return 0; } if (valp) *valp = dl->gval; return 1; }
static int cmd_show_messages(struct backup *backup, const struct cyrbu_cmd_options *options) { struct backup_message *message = NULL; struct backup_mailbox_list *mailboxes = NULL; struct backup_mailbox *mailbox; struct message_guid want_guid; int i; for (i = 0; i < strarray_size(options->argv); i++) { if (!message_guid_decode(&want_guid, strarray_nth(options->argv, i))) continue; message = backup_get_message(backup, &want_guid); if (!message) continue; fprintf(stdout, "guid:\t%s\n", message_guid_encode(message->guid)); mailboxes = backup_get_mailboxes_by_message(backup, message, 0); if (mailboxes) { fprintf(stdout, "mailboxes:\n"); for (mailbox = mailboxes->head; mailbox; mailbox = mailbox->next) { fprintf(stdout, "\t%s\t%s\n", mailbox->uniqueid, mailbox->mboxname); } backup_mailbox_list_empty(mailboxes); free(mailboxes); } fprintf(stdout, "headers:\n"); backup_read_message_data(backup, message, show_message_headers, stdout); fprintf(stdout, "\n"); backup_message_free(&message); } return 0; }
static int cmd_dump_message(struct backup *backup, const struct cyrbu_cmd_options *options) { struct backup_message *message = NULL; struct message_guid want_guid; int r; if (!message_guid_decode(&want_guid, strarray_nth(options->argv, 0))) return IMAP_NOTFOUND; message = backup_get_message(backup, &want_guid); if (!message) return IMAP_NOTFOUND; r = backup_read_message_data(backup, message, dump_buf, stdout); backup_message_free(&message); return r; }
EXPORTED int dlist_parse(struct dlist **dlp, int parsekey, struct protstream *in, const char *alt_reserve_base) { struct dlist *dl = NULL; static struct buf kbuf; static struct buf vbuf; int c; /* handle the key if wanted */ if (parsekey) { c = getastring(in, NULL, &kbuf); c = next_nonspace(in, c); } else { buf_setcstr(&kbuf, ""); c = prot_getc(in); } /* connection dropped? */ if (c == EOF) goto fail; /* check what sort of value we have */ if (c == '(') { dl = dlist_newlist(NULL, kbuf.s); c = next_nonspace(in, ' '); while (c != ')') { struct dlist *di = NULL; prot_ungetc(c, in); c = dlist_parse(&di, 0, in, alt_reserve_base); if (di) dlist_stitch(dl, di); c = next_nonspace(in, c); if (c == EOF) goto fail; } c = prot_getc(in); } else if (c == '%') { /* no whitespace allowed here */ c = prot_getc(in); if (c == '(') { dl = dlist_newkvlist(NULL, kbuf.s); c = next_nonspace(in, ' '); while (c != ')') { struct dlist *di = NULL; prot_ungetc(c, in); c = dlist_parse(&di, 1, in, alt_reserve_base); if (di) dlist_stitch(dl, di); c = next_nonspace(in, c); if (c == EOF) goto fail; } } else if (c == '{') { struct message_guid tmp_guid; static struct buf pbuf, gbuf; unsigned size = 0; const char *fname; const char *part; c = getastring(in, NULL, &pbuf); if (c != ' ') goto fail; c = getastring(in, NULL, &gbuf); if (c != ' ') goto fail; c = getuint32(in, &size); if (c != '}') goto fail; c = prot_getc(in); if (c == '\r') c = prot_getc(in); if (c != '\n') goto fail; if (!message_guid_decode(&tmp_guid, gbuf.s)) goto fail; part = alt_reserve_base ? alt_reserve_base : pbuf.s; if (reservefile(in, part, &tmp_guid, size, &fname)) goto fail; dl = dlist_setfile(NULL, kbuf.s, pbuf.s, &tmp_guid, size, fname); /* file literal */ } else { /* unknown percent type */ goto fail; } c = prot_getc(in); } else if (c == '{') { prot_ungetc(c, in); /* could be binary in a literal */ c = getbastring(in, NULL, &vbuf); dl = dlist_setmap(NULL, kbuf.s, vbuf.s, vbuf.len); } else if (c == '\\') { /* special case for flags */ prot_ungetc(c, in); c = getastring(in, NULL, &vbuf); dl = dlist_setflag(NULL, kbuf.s, vbuf.s); } else { prot_ungetc(c, in); c = getnastring(in, NULL, &vbuf); dl = dlist_setatom(NULL, kbuf.s, vbuf.s); } /* success */ *dlp = dl; return c; fail: dlist_free(&dl); return EOF; }
static int restore_add_object(const char *object_name, const struct restore_options *options, struct backup *backup, struct backup_mailbox_list *mailbox_list, struct sync_folder_list *reserve_folder_list, struct sync_reserve_list *reserve_list) { struct backup_mailbox *mailbox = NULL; struct backup_message *message = NULL; struct message_guid tmp_guid; size_t len; int r; /* try to work out what we're restoring */ len = strlen(object_name); if (len == 24 && strspn(object_name, HEX_DIGITS) == len) { /* looks like a non-libuuid uniqueid */ mailbox = backup_get_mailbox_by_uniqueid(backup, object_name, BACKUP_MAILBOX_ALL_RECORDS); } else if (len == 36 && strspn(object_name, "-" HEX_DIGITS) == len) { /* looks like a libuuid uniqueid */ mailbox = backup_get_mailbox_by_uniqueid(backup, object_name, BACKUP_MAILBOX_ALL_RECORDS); } else if (message_guid_decode(&tmp_guid, object_name)) { /* looks like it's a message guid */ message = backup_get_message(backup, &tmp_guid); } else if (strchr(object_name, '.')) { /* has a dot, might be an mboxname */ mbname_t *mbname = mbname_from_intname(object_name); mailbox = backup_get_mailbox_by_name(backup, mbname, BACKUP_MAILBOX_ALL_RECORDS); mbname_free(&mbname); } else { /* not sure what it is, guess mboxname? */ mbname_t *mbname = mbname_from_intname(object_name); mailbox = backup_get_mailbox_by_name(backup, mbname, BACKUP_MAILBOX_ALL_RECORDS); mbname_free(&mbname); } /* add it to the restore lists */ if (mailbox) { r = restore_add_mailbox(mailbox, options, mailbox_list, reserve_folder_list, reserve_list); if (!r && options->do_submailboxes) { char prefix[MAX_MAILBOX_NAME + 1]; int len; len = snprintf(prefix, sizeof(prefix), "%s.", mailbox->mboxname); /* can only be submailboxes if parent's name is short enough... */ if (len < MAX_MAILBOX_NAME) { struct submailbox_rock rock = { prefix, strlen(prefix), options, mailbox_list, reserve_folder_list, reserve_list, }; r = backup_mailbox_foreach(backup, 0, BACKUP_MAILBOX_ALL_RECORDS, submailbox_cb, &rock); } } backup_mailbox_free(&mailbox); } else if (message) { struct backup_mailbox_list *mailboxes = NULL; if (!options->override_mboxname) mailboxes = backup_get_mailboxes_by_message(backup, message, BACKUP_MAILBOX_MATCH_RECORDS); r = restore_add_message(message, mailboxes, options, mailbox_list, reserve_folder_list, reserve_list); if (mailboxes) { backup_mailbox_list_empty(mailboxes); free(mailboxes); } backup_message_free(&message); } else { r = IMAP_MAILBOX_NONEXISTENT; } return r; }