Пример #1
0
static int cmd_show_mailboxes(struct backup *backup,
                              const struct cyrbu_cmd_options *options)
{
    struct backup_mailbox *mailbox = NULL;
    struct backup_mailbox_message *record = NULL;
    int i;

    for (i = 0; i < strarray_size(options->argv); i++) {
        char ts_deleted[32] = "";
        const char *arg = strarray_nth(options->argv, i);

        /* argument could be a uniqueid */
        mailbox = backup_get_mailbox_by_uniqueid(backup, arg, 1);

        /* or it could be an mboxname */
        if (!mailbox) {
            mbname_t *mbname = mbname_from_intname(arg);
            if (!mbname) continue;
            mailbox = backup_get_mailbox_by_name(backup, mbname, 1);
            mbname_free(&mbname);
        }

        /* or it could be junk */
        if (!mailbox) continue;

        fprintf(stdout, "mboxname: %s\n", mailbox->mboxname);
        fprintf(stdout, "uniqueid: %s\n", mailbox->uniqueid);

        if (mailbox->deleted) {
            strftime(ts_deleted, sizeof(ts_deleted), "%F %T",
                     localtime(&mailbox->deleted));

            fprintf(stdout, "deleted:  %s\n", ts_deleted);
        }

        fprintf(stdout, "messages:\n");
        fprintf(stdout, "       uid  expunged time        guid\n");

        for (record = mailbox->records->head; record; record = record->next) {
            char ts_expunged[32] = "                   ";

            if (record->expunged)
                strftime(ts_expunged, sizeof(ts_expunged), "%F %T",
                         localtime(&record->expunged));

            fprintf(stdout, "%10d  %s  %s\n",
                            record->uid,
                            ts_expunged,
                            message_guid_encode(&record->guid));
        }

        fprintf(stdout, "\n");

        backup_mailbox_free(&mailbox);
    }

    return 0;
}
Пример #2
0
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;
}
Пример #3
0
static int want_append_mailbox(struct backup *orig_backup,
                               int orig_chunk_id,
                               struct dlist *dlist)
{
    struct dlist *record = NULL;
    const char *uniqueid = NULL;
    struct backup_mailbox *mailbox = NULL;
    int mailbox_last_chunk_id = 0;

    if (!dlist_getatom(dlist, "UNIQUEID", &uniqueid)) {
        syslog(LOG_DEBUG, "%s: MAILBOX line with no UNIQUEID", __func__);
        return 1; /* better keep it for now */
    }

    dlist_getlist(dlist, "RECORD", &record);
    if (record && record->head) {
        struct dlist *ki = NULL, *next = NULL;
        int keep = 0;

        /* keep MAILBOX lines that contain the last RECORD for any message, */
        /* pruning out stale RECORDs */
        for (ki = record->head; ki; ki = next) {
            const char *guid = NULL;
            struct backup_mailbox_message *mailbox_message = NULL;

            /* save next pointer now in case we need to unstitch */
            next = ki->next;

            if (!dlist_getatom(ki, "GUID", &guid)) {
                syslog(LOG_DEBUG, "%s: MAILBOX RECORD with no GUID", __func__);
                keep = 1; /* better keep it for now */
                continue;
            }

            mailbox_message = backup_get_mailbox_message(orig_backup, uniqueid, guid);
            if (mailbox_message) {
                int mailbox_message_last_chunk_id = mailbox_message->last_chunk_id;
                backup_mailbox_message_free(&mailbox_message);

                if (mailbox_message_last_chunk_id == orig_chunk_id) {
                    syslog(LOG_DEBUG, "%s: keeping MAILBOX line containing last RECORD for guid %s",
                                        __func__, guid);
                    keep = 1;
                    continue;
                }
            }

            /* don't need this record */
            syslog(LOG_DEBUG, "%s: pruning stale MAILBOX RECORD for guid %s",
                              __func__, guid);
            dlist_unstitch(record, ki);
            dlist_unlink_files(ki);
            dlist_free(&ki);
        }

        if (keep) return 1;
    }

    mailbox = backup_get_mailbox_by_uniqueid(orig_backup, uniqueid,
                                             BACKUP_MAILBOX_NO_RECORDS);
    if (!mailbox) {
        /* what? */
        syslog(LOG_DEBUG, "%s: couldn't find mailbox entry for uniqueid %s", __func__, uniqueid);
        return 1; /* better keep it for now */
    }

    mailbox_last_chunk_id = mailbox->last_chunk_id;
    backup_mailbox_free(&mailbox);

    if (mailbox_last_chunk_id == orig_chunk_id) {
        /* keep all mailbox lines from the chunk recorded as its last */
        syslog(LOG_DEBUG, "%s: keeping MAILBOX line from its last known chunk", __func__);
        return 1;
    }

    syslog(LOG_DEBUG, "%s: discarding stale MAILBOX line (chunk %d, last %d, uniqueid %s)",
                        __func__, orig_chunk_id, mailbox_last_chunk_id, uniqueid);
    return 0;
}