17
17
* Binary dumper object
20
20
struct sieve_binary_dumper {
23
23
/* Dumptime environment */
24
struct sieve_dumptime_env dumpenv;
24
struct sieve_dumptime_env dumpenv;
27
27
struct sieve_binary_dumper *sieve_binary_dumper_create
28
(struct sieve_binary *sbin)
28
(struct sieve_binary *sbin)
31
31
struct sieve_binary_dumper *dumper;
33
pool = pool_alloconly_create("sieve_binary_dumper", 4096);
33
pool = pool_alloconly_create("sieve_binary_dumper", 4096);
34
34
dumper = p_new(pool, struct sieve_binary_dumper, 1);
35
35
dumper->pool = pool;
36
36
dumper->dumpenv.dumper = dumper;
38
38
dumper->dumpenv.sbin = sbin;
39
39
sieve_binary_ref(sbin);
41
41
dumper->dumpenv.svinst = sieve_binary_svinst(sbin);
46
void sieve_binary_dumper_free(struct sieve_binary_dumper **dumper)
46
void sieve_binary_dumper_free(struct sieve_binary_dumper **dumper)
48
48
sieve_binary_unref(&(*dumper)->dumpenv.sbin);
49
49
pool_unref(&((*dumper)->pool));
56
56
return dumper->pool;
63
63
void sieve_binary_dumpf
64
64
(const struct sieve_dumptime_env *denv, const char *fmt, ...)
66
66
string_t *outbuf = t_str_new(128);
70
70
str_vprintfa(outbuf, fmt, args);
73
73
o_stream_send(denv->stream, str_data(outbuf), str_len(outbuf));
79
79
string_t *outbuf = t_str_new(128);
83
83
str_printfa(outbuf, "\n* ");
84
84
str_vprintfa(outbuf, fmt, args);
85
85
str_printfa(outbuf, ":\n\n");
88
88
o_stream_send(denv->stream, str_data(outbuf), str_len(outbuf));
92
92
* Dumping the binary
95
95
bool sieve_binary_dumper_run
96
(struct sieve_binary_dumper *dumper, struct ostream *stream, bool verbose)
96
(struct sieve_binary_dumper *dumper, struct ostream *stream, bool verbose)
98
98
struct sieve_binary *sbin = dumper->dumpenv.sbin;
99
99
struct sieve_dumptime_env *denv = &(dumper->dumpenv);
102
102
dumper->dumpenv.stream = stream;
104
104
/* Dump list of binary blocks */
111
111
for ( i = 0; i < count; i++ ) {
112
112
struct sieve_binary_block *sblock = sieve_binary_block_get(sbin, i);
114
sieve_binary_dumpf(denv,
115
"%3d: size: %"PRIuSIZE_T" bytes\n", i,
114
sieve_binary_dumpf(denv,
115
"%3d: size: %"PRIuSIZE_T" bytes\n", i,
116
116
sieve_binary_block_get_size(sblock));
120
120
/* Dump list of used extensions */
122
122
count = sieve_binary_extensions_count(sbin);
123
123
if ( count > 0 ) {
124
124
sieve_binary_dump_sectionf
125
125
(denv, "Required extensions (block: %d)", SBIN_SYSBLOCK_EXTENSIONS);
127
127
for ( i = 0; i < count; i++ ) {
128
128
const struct sieve_extension *ext = sieve_binary_extension_get_by_index
131
131
struct sieve_binary_block *sblock = sieve_binary_extension_get_block
134
134
if ( sblock == NULL ) {
135
sieve_binary_dumpf(denv, "%3d: %s (id: %d)\n",
135
sieve_binary_dumpf(denv, "%3d: %s (id: %d)\n",
136
136
i, sieve_extension_name(ext), ext->id);
138
sieve_binary_dumpf(denv, "%3d: %s (id: %d; block: %d)\n",
139
i, sieve_extension_name(ext), ext->id,
138
sieve_binary_dumpf(denv, "%3d: %s (id: %d; block: %d)\n",
139
i, sieve_extension_name(ext), ext->id,
140
140
sieve_binary_block_get_id(sblock));
145
145
/* Dump extension-specific elements of the binary */
147
147
count = sieve_binary_extensions_count(sbin);
149
149
for ( i = 0; i < count; i++ ) {
150
150
bool success = TRUE;
153
153
const struct sieve_extension *ext = sieve_binary_extension_get_by_index
156
if ( ext->def != NULL && ext->def->binary_dump != NULL ) {
156
if ( ext->def != NULL && ext->def->binary_dump != NULL ) {
157
157
success = ext->def->binary_dump(ext, denv);
161
161
if ( !success ) return FALSE;
165
165
/* Dump main program */
167
167
sieve_binary_dump_sectionf
168
168
(denv, "Main program (block: %d)", SBIN_SYSBLOCK_MAIN_PROGRAM);
170
dumper->dumpenv.sblock =
170
dumper->dumpenv.sblock =
171
171
sieve_binary_block_get(sbin, SBIN_SYSBLOCK_MAIN_PROGRAM);
172
172
dumper->dumpenv.cdumper = sieve_code_dumper_create(&(dumper->dumpenv));
174
174
if ( dumper->dumpenv.cdumper != NULL ) {
175
175
sieve_code_dumper_run(dumper->dumpenv.cdumper);
177
177
sieve_code_dumper_free(&dumper->dumpenv.cdumper);
180
180
/* Finish with empty line */
181
181
sieve_binary_dumpf(denv, "\n");
206
206
for ( i = 0; i < count; i++ ) {
207
207
struct sieve_binary_block *sblock = sieve_binary_block_get(sbin, i);
209
sieve_binary_dumpf(denv,
210
"%3d: size: %"PRIuSIZE_T" bytes\n", i,
209
sieve_binary_dumpf(denv,
210
"%3d: size: %"PRIuSIZE_T" bytes\n", i,
211
211
sieve_binary_block_get_size(sblock));
224
224
data = (const char *) buffer_get_data(blockbuf, &data_size);
226
226
sieve_binary_dump_sectionf
227
(denv, "Block %d (%"PRIuSIZE_T" bytes, file offset %08llx)", i,
227
(denv, "Block %d (%"PRIuSIZE_T" bytes, file offset %08llx)", i,
228
228
data_size, sblock->offset + 8 /* header size (yuck) */);
230
230
line = t_str_new(128);
236
236
str_printfa(line, "%08llx ", (unsigned long long) offset);
238
238
for ( b = 0; b < len; b++ ) {
239
str_printfa(line, "%02x ", (unsigned int) data[offset+b]);
239
str_printfa(line, "%02x ", (unsigned int) data[offset+b]);
240
240
if ( b == 7 ) str_append_c(line, ' ');