static void sieve_ldap_script_binary_write_metadata (struct sieve_script *script, struct sieve_binary_block *sblock) { struct sieve_ldap_script *lscript = (struct sieve_ldap_script *)script; sieve_binary_emit_cstring(sblock, lscript->dn); if (lscript->modattr == NULL) sieve_binary_emit_cstring(sblock, ""); else sieve_binary_emit_cstring(sblock, lscript->modattr); }
bool ext_include_variables_save (struct sieve_binary_block *sblock, struct sieve_variable_scope_binary *global_vars) { struct sieve_variable_scope *global_scope = sieve_variable_scope_binary_get(global_vars); unsigned int count = sieve_variable_scope_size(global_scope); sieve_size_t jump; sieve_binary_emit_unsigned(sblock, count); jump = sieve_binary_emit_offset(sblock, 0); if ( count > 0 ) { unsigned int size, i; struct sieve_variable *const *vars = sieve_variable_scope_get_variables(global_scope, &size); for ( i = 0; i < size; i++ ) { sieve_binary_emit_cstring(sblock, vars[i]->identifier); } } sieve_binary_resolve_offset(sblock, jump); return TRUE; }
static bool ext_ihave_binary_save (const struct sieve_extension *ext, struct sieve_binary *sbin, void *context) { struct ext_ihave_binary_context *binctx = (struct ext_ihave_binary_context *) context; const char *const *exts; unsigned int count, i; exts = array_get(&binctx->missing_extensions, &count); if ( binctx->block != NULL ) sieve_binary_block_clear(binctx->block); if ( count > 0 ) { if ( binctx->block == NULL ) binctx->block = sieve_binary_extension_create_block(sbin, ext); sieve_binary_emit_unsigned(binctx->block, count); for ( i = 0; i < count; i++ ) { sieve_binary_emit_cstring(binctx->block, exts[i]); } } return TRUE; }
static bool _sieve_binary_save (struct sieve_binary *sbin, struct ostream *stream) { struct sieve_binary_header header; struct sieve_binary_extension_reg *const *regs; struct sieve_binary_block *ext_block; unsigned int ext_count, blk_count, i; uoff_t block_index; blk_count = sieve_binary_block_count(sbin); /* Signal all extensions to finish generating their blocks */ regs = array_get(&sbin->extensions, &ext_count); for ( i = 0; i < ext_count; i++ ) { const struct sieve_binary_extension *binext = regs[i]->binext; if ( binext != NULL && binext->binary_save != NULL ) binext->binary_save(regs[i]->extension, sbin, regs[i]->context); } /* Create header */ header.magic = SIEVE_BINARY_MAGIC; header.version_major = SIEVE_BINARY_VERSION_MAJOR; header.version_minor = SIEVE_BINARY_VERSION_MINOR; header.blocks = blk_count; if ( !_save_aligned(sbin, stream, &header, sizeof(header), NULL) ) { sieve_sys_error(sbin->svinst, "binary save: failed to save header"); return FALSE; } /* Skip block index for now */ if ( !_save_skip_aligned(sbin, stream, sizeof(struct sieve_binary_block_index) * blk_count, &block_index) ) return FALSE; /* Create block containing all used extensions */ ext_block = sieve_binary_block_get(sbin, SBIN_SYSBLOCK_EXTENSIONS); i_assert( ext_block != NULL ); sieve_binary_block_clear(ext_block); ext_count = array_count(&sbin->linked_extensions); sieve_binary_emit_unsigned(ext_block, ext_count); for ( i = 0; i < ext_count; i++ ) { struct sieve_binary_extension_reg * const *ext = array_idx(&sbin->linked_extensions, i); sieve_binary_emit_cstring (ext_block, sieve_extension_name((*ext)->extension)); sieve_binary_emit_unsigned (ext_block, sieve_extension_version((*ext)->extension)); sieve_binary_emit_unsigned(ext_block, (*ext)->block_id); } /* Save all blocks into the binary */ for ( i = 0; i < blk_count; i++ ) { if ( !_save_block(sbin, stream, i) ) return FALSE; } /* Create the block index */ o_stream_seek(stream, block_index); for ( i = 0; i < blk_count; i++ ) { if ( !_save_block_index_record(sbin, stream, i) ) return FALSE; } return TRUE; }