static int mailbox_update_sieve(struct mailbox *mailbox,
                              const struct index_record *old,
                              const struct index_record *new)
{
    struct sieve_db *sievedb = NULL;
    struct param *param;
    struct body *body = NULL;
    struct sieve_data *sdata = NULL;
    char *id = NULL;
    const char *name = NULL;
    struct buf msg_buf = BUF_INITIALIZER;
    int isexpunged = (new->internal_flags & FLAG_INTERNAL_EXPUNGED ? 1 : 0);
    int isactive = (new->system_flags & FLAG_FLAGGED ? 1 : 0);
    int r = 0;

    if (mbtype_isa(mailbox_mbtype(mailbox)) != MBTYPE_SIEVE) return 0;

    /* never have Sieve on deleted mailboxes */
    if (mboxname_isdeletedmailbox(mailbox_name(mailbox), NULL)) return 0;

    /* conditions in which there's nothing to do */
    if (!new) return 0;

    /* phantom record - never really existed here */
    if (!old && isexpunged) return 0;

    r = mailbox_cacherecord(mailbox, new);
    if (r) goto done;

    /* Get script id from filename param in Content-Disposition header */
    message_read_bodystructure(new, &body);
    for (param = body->disposition_params; param; param = param->next) {
        if (!strcmp(param->attribute, "FILENAME")) {
            ssize_t idlen = strlen(param->value) - strlen(SIEVE_EXTENSION);

            if (idlen > 0 && !strcmp(param->value + idlen, SIEVE_EXTENSION)) {
                id = xstrndup(param->value, idlen);
            }
        }
    }

    assert(id);

    /* Get script name from Subject */
    name = body->subject;

    sievedb = mailbox_open_sieve(mailbox);

    /* Find existing record for this id */
    sievedb_lookup_id(sievedb, id, &sdata, /*tombstones*/1);

    /* if updated by a newer UID, skip - this record doesn't refer to the current item */
    if (sdata->imap_uid > new->uid) goto done;

    if (new->internal_flags & FLAG_INTERNAL_UNLINKED) {
        /* is there an existing record? */
        if (!sdata->imap_uid) goto done;

        /* delete entry */
        r = sievedb_delete(sievedb, sdata->rowid);
    }
    else if (sdata->imap_uid == new->uid) {
        /* just a flags update to an existing record */
        if (isexpunged) {
            r = sievedir_delete_script(mailbox->sievedir, name);
        }
        else if (isactive) {
            if (!sdata->isactive) {
                r = sievedir_activate_script(mailbox->sievedir, name);
            }
        }
        else if (sdata->isactive) {
            r = sievedir_deactivate_script(mailbox->sievedir);
        }

        if (r) {
                xsyslog(LOG_ERR, "sievedir I/O failure on existing script",
                        "mailbox=<%s> script=<%s>",
                        mailbox_name(mailbox), name);
            r = IMAP_IOERROR;
            goto done;
        }

        sdata->modseq = new->modseq;
        sdata->alive = !isexpunged;
        sdata->isactive = isactive;
        r = sievedb_write(sievedb, sdata);
    }
    else {
        /* Load message containing the script */
        r = mailbox_map_record(mailbox, new, &msg_buf);
        if (r) goto done;

        const char *content = buf_cstring(&msg_buf) + new->header_size;
        char *errors = NULL;

        r = sievedir_put_script(mailbox->sievedir, name, content, &errors);
        if (r) {
            if (r == SIEVEDIR_INVALID) {
                xsyslog(LOG_ERR, "sieve parse failure",
                        "mailbox=<%s> script=<%s> err=<%s>",
                        mailbox_name(mailbox), name, errors ? errors : "");
            }
            else {
                xsyslog(LOG_ERR, "sieve bytecode failure",
                        "mailbox=<%s> script=<%s>",
                        mailbox_name(mailbox), name);
            }

            r = IMAP_SYNC_BADSIEVE;
            goto done;
        }
        else if (isactive) {
            r = sievedir_activate_script(mailbox->sievedir, name);

            if (r) {
                xsyslog(LOG_ERR, "sievedir I/O failure on new/updated script",
                        "mailbox=<%s> script=<%s>",
                        mailbox_name(mailbox), name);
                r = IMAP_IOERROR;
                goto done;
            }
        }

        sdata->lastupdated = new->internaldate;
        sdata->mailbox = mailbox_uniqueid(mailbox);
        sdata->imap_uid = new->uid;
        sdata->modseq = new->modseq;
        sdata->createdmodseq = new->createdmodseq;
        sdata->alive = !isexpunged;
        sdata->isactive = isactive;
        sdata->id = id;
        sdata->name = name;
        sdata->contentid = message_guid_encode(&body->content_guid);

        if (!sdata->creationdate)
            sdata->creationdate = new->internaldate;

        r = sievedb_write(sievedb, sdata);
    }

done:
    if (body) {
        message_free_body(body);
        free(body);
    }
    buf_free(&msg_buf);
    free(id);

    return r;
}
static int mailbox_update_sieve(struct mailbox *mailbox,
                              const struct index_record *old,
                              const struct index_record *new)
{
    struct sieve_db *sievedb = NULL;
    struct param *param;
    struct body *body = NULL;
    struct sieve_data *sdata = NULL;
    char *id = NULL;
    const char *name = NULL;
    struct buf msg_buf = BUF_INITIALIZER;
    int isexpunged = (new->internal_flags & FLAG_INTERNAL_EXPUNGED ? 1 : 0);
    int isactive = (new->system_flags & FLAG_FLAGGED ? 1 : 0);
    int r = 0;

    if (mbtype_isa(mailbox_mbtype(mailbox)) != MBTYPE_SIEVE) return 0;

     
    if (mboxname_isdeletedmailbox(mailbox_name(mailbox), NULL)) return 0;

     
    if (!new) return 0;

     
    if (!old && isexpunged) return 0;

    r = mailbox_cacherecord(mailbox, new);
    if (r) goto done;

     
    message_read_bodystructure(new, &body);
    for (param = body->disposition_params; param; param = param->next) {
        if (!strcmp(param->attribute, "FILENAME")) {
            ssize_t idlen = strlen(param->value) - strlen(SIEVE_EXTENSION);

            if (idlen > 0 && !strcmp(param->value + idlen, SIEVE_EXTENSION)) {
                id = xstrndup(param->value, idlen);
            }
        }
    }

    assert(id);

     
    name = body->subject;

    sievedb = mailbox_open_sieve(mailbox);

     
    sievedb_lookup_id(sievedb, id, &sdata,  1);

     
    if (sdata->imap_uid > new->uid) goto done;

    if (new->internal_flags & FLAG_INTERNAL_UNLINKED) {
         
        if (!sdata->imap_uid) goto done;

         
        r = sievedb_delete(sievedb, sdata->rowid);
    }
    else if (sdata->imap_uid == new->uid) {
         
        if (isexpunged) {
            r = sievedir_delete_script(mailbox->sievedir, name);
        }
        else if (isactive) {
            if (!sdata->isactive) {
                r = sievedir_activate_script(mailbox->sievedir, name);
            }
        }
        else if (sdata->isactive) {
            r = sievedir_deactivate_script(mailbox->sievedir);
        }

        if (r) {
                xsyslog(LOG_ERR, "sievedir I/O failure on existing script",
                        "mailbox=<%s> script=<%s>",
                        mailbox_name(mailbox), name);
            r = IMAP_IOERROR;
            goto done;
        }

        sdata->modseq = new->modseq;
        sdata->alive = !isexpunged;
        sdata->isactive = isactive;
        r = sievedb_write(sievedb, sdata);
    }
    else {
         
        r = mailbox_map_record(mailbox, new, &msg_buf);
        if (r) goto done;

        const char *content = buf_cstring(&msg_buf) + new->header_size;
        char *errors = NULL;

        r = sievedir_put_script(mailbox->sievedir, name, content, &errors);
        if (r) {
            if (r == SIEVEDIR_INVALID) {
                xsyslog(LOG_ERR, "sieve parse failure",
                        "mailbox=<%s> script=<%s> err=<%s>",
                        mailbox_name(mailbox), name, errors ? errors : "");
            }
            else {
                xsyslog(LOG_ERR, "sieve bytecode failure",
                        "mailbox=<%s> script=<%s>",
                        mailbox_name(mailbox), name);
            }

            r = IMAP_SYNC_BADSIEVE;
            goto done;
        }
        else if (isactive) {
            r = sievedir_activate_script(mailbox->sievedir, name);

            if (r) {
                xsyslog(LOG_ERR, "sievedir I/O failure on new/updated script",
                        "mailbox=<%s> script=<%s>",
                        mailbox_name(mailbox), name);
                r = IMAP_IOERROR;
                goto done;
            }
        }

        sdata->lastupdated = new->internaldate;
        sdata->mailbox = mailbox_uniqueid(mailbox);
        sdata->imap_uid = new->uid;
        sdata->modseq = new->modseq;
        sdata->createdmodseq = new->createdmodseq;
        sdata->alive = !isexpunged;
        sdata->isactive = isactive;
        sdata->id = id;
        sdata->name = name;
        sdata->contentid = message_guid_encode(&body->content_guid);

        if (!sdata->creationdate)
            sdata->creationdate = new->internaldate;

        r = sievedb_write(sievedb, sdata);
    }

done:
    if (body) {
        message_free_body(body);
        free(body);
    }
    buf_free(&msg_buf);
    free(id);

    return r;
}