|
|
@@ -1,247 +0,0 @@ |
|
|
|
/*- |
|
|
|
* Copyright 2016 Vsevolod Stakhov |
|
|
|
* |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
* You may obtain a copy of the License at |
|
|
|
* |
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
|
|
* |
|
|
|
* Unless required by applicable law or agreed to in writing, software |
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
|
|
* See the License for the specific language governing permissions and |
|
|
|
* limitations under the License. |
|
|
|
*/ |
|
|
|
|
|
|
|
#include "config.h" |
|
|
|
#include "printf.h" |
|
|
|
#include "message.h" |
|
|
|
#include "util.h" |
|
|
|
#include "content_type.h" |
|
|
|
#include "task.h" |
|
|
|
#include "mime_parser.h" |
|
|
|
#include "unix-std.h" |
|
|
|
|
|
|
|
#define MODE_NORMAL 0 |
|
|
|
#define MODE_GMIME 1 |
|
|
|
static gdouble total_time = 0.0; |
|
|
|
|
|
|
|
static void |
|
|
|
rspamd_show_normal (struct rspamd_mime_part *part) |
|
|
|
{ |
|
|
|
rspamd_printf ("got normal part %p: parent: %p, type: %T/%T," |
|
|
|
"length: %z (%z raw)\n", |
|
|
|
part, part->parent_part, |
|
|
|
&part->ct->type, &part->ct->subtype, |
|
|
|
part->parsed_data.len, |
|
|
|
part->raw_data.len); |
|
|
|
} |
|
|
|
|
|
|
|
static void |
|
|
|
rspamd_show_multipart (struct rspamd_mime_part *part) |
|
|
|
{ |
|
|
|
struct rspamd_mime_part *cur; |
|
|
|
guint i; |
|
|
|
|
|
|
|
rspamd_printf ("got multipart part %p, boundary: %T: parent: %p, type: %T/%T, children: [", |
|
|
|
part, &part->ct->boundary, |
|
|
|
part->parent_part, |
|
|
|
&part->ct->type, &part->ct->subtype); |
|
|
|
|
|
|
|
if (part->specific.mp.children) { |
|
|
|
for (i = 0; i < part->specific.mp.children->len; i ++) { |
|
|
|
cur = g_ptr_array_index (part->specific.mp.children, i); |
|
|
|
|
|
|
|
if (i != 0) { |
|
|
|
rspamd_printf (", %p{%T/%T}", cur, |
|
|
|
&cur->ct->type, &cur->ct->subtype); |
|
|
|
} |
|
|
|
else { |
|
|
|
rspamd_printf ("%p{%T/%T}", cur, |
|
|
|
&cur->ct->type, &cur->ct->subtype); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
rspamd_printf ("]\n"); |
|
|
|
} |
|
|
|
|
|
|
|
static void |
|
|
|
rspamd_show_message (struct rspamd_mime_part *part) |
|
|
|
{ |
|
|
|
rspamd_printf ("got message part %p: parent: %p\n", |
|
|
|
part, part->parent_part); |
|
|
|
} |
|
|
|
|
|
|
|
#if 0 |
|
|
|
static void |
|
|
|
mime_foreach_callback (GMimeObject * parent, |
|
|
|
GMimeObject * part, |
|
|
|
gpointer user_data) |
|
|
|
{ |
|
|
|
GMimeContentType *type; |
|
|
|
|
|
|
|
if (GMIME_IS_MESSAGE_PART (part)) { |
|
|
|
/* message/rfc822 or message/news */ |
|
|
|
GMimeMessage *message; |
|
|
|
|
|
|
|
/* g_mime_message_foreach_part() won't descend into |
|
|
|
child message parts, so if we want to count any |
|
|
|
subparts of this child message, we'll have to call |
|
|
|
g_mime_message_foreach_part() again here. */ |
|
|
|
rspamd_printf ("got message part %p: parent: %p\n", |
|
|
|
part, parent); |
|
|
|
message = g_mime_message_part_get_message ((GMimeMessagePart *) part); |
|
|
|
g_mime_message_foreach (message, mime_foreach_callback, part); |
|
|
|
} |
|
|
|
else if (GMIME_IS_MULTIPART (part)) { |
|
|
|
type = (GMimeContentType *) g_mime_object_get_content_type (GMIME_OBJECT ( |
|
|
|
part)); |
|
|
|
rspamd_printf ("got multipart part %p, boundary: %s: parent: %p, type: %s/%s\n", |
|
|
|
part, g_mime_multipart_get_boundary (GMIME_MULTIPART(part)), |
|
|
|
parent, |
|
|
|
g_mime_content_type_get_media_type (type), |
|
|
|
g_mime_content_type_get_media_subtype (type)); |
|
|
|
} |
|
|
|
else { |
|
|
|
type = (GMimeContentType *) g_mime_object_get_content_type (GMIME_OBJECT ( |
|
|
|
part)); |
|
|
|
rspamd_printf ("got normal part %p, parent: %p, type: %s/%s\n", |
|
|
|
part, |
|
|
|
parent, |
|
|
|
g_mime_content_type_get_media_type (type), |
|
|
|
g_mime_content_type_get_media_subtype (type)); |
|
|
|
} |
|
|
|
} |
|
|
|
#endif |
|
|
|
static void |
|
|
|
rspamd_process_file (struct rspamd_config *cfg, const gchar *fname, gint mode) |
|
|
|
{ |
|
|
|
struct rspamd_task *task; |
|
|
|
gint fd; |
|
|
|
gpointer map; |
|
|
|
struct stat st; |
|
|
|
GError *err = NULL; |
|
|
|
#if 0 |
|
|
|
GMimeMessage *message; |
|
|
|
GMimeParser *parser; |
|
|
|
GMimeStream *stream; |
|
|
|
GByteArray tmp; |
|
|
|
#endif |
|
|
|
struct rspamd_mime_part *part; |
|
|
|
guint i; |
|
|
|
gdouble ts1, ts2; |
|
|
|
|
|
|
|
fd = open (fname, O_RDONLY); |
|
|
|
|
|
|
|
if (fd == -1) { |
|
|
|
rspamd_fprintf (stderr, "cannot open %s: %s\n", fname, strerror (errno)); |
|
|
|
exit (EXIT_FAILURE); |
|
|
|
} |
|
|
|
|
|
|
|
if (fstat (fd, &st) == -1) { |
|
|
|
rspamd_fprintf (stderr, "cannot stat %s: %s\n", fname, strerror (errno)); |
|
|
|
exit (EXIT_FAILURE); |
|
|
|
} |
|
|
|
|
|
|
|
map = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); |
|
|
|
close (fd); |
|
|
|
|
|
|
|
if (map == MAP_FAILED) { |
|
|
|
rspamd_fprintf (stderr, "cannot mmap %s: %s\n", fname, strerror (errno)); |
|
|
|
exit (EXIT_FAILURE); |
|
|
|
} |
|
|
|
|
|
|
|
task = rspamd_task_new (NULL, cfg, NULL); |
|
|
|
task->msg.begin = map; |
|
|
|
task->msg.len = st.st_size; |
|
|
|
|
|
|
|
ts1 = rspamd_get_ticks (); |
|
|
|
|
|
|
|
if (mode == MODE_NORMAL) { |
|
|
|
if (!rspamd_mime_parse_task (task, &err)) { |
|
|
|
rspamd_fprintf (stderr, "cannot parse %s: %e\n", fname, err); |
|
|
|
g_error_free (err); |
|
|
|
} |
|
|
|
} |
|
|
|
#if 0 |
|
|
|
else if (mode == MODE_GMIME) { |
|
|
|
tmp.data = map; |
|
|
|
tmp.len = st.st_size; |
|
|
|
stream = g_mime_stream_mem_new_with_byte_array (&tmp); |
|
|
|
g_mime_stream_mem_set_owner (GMIME_STREAM_MEM (stream), FALSE); |
|
|
|
parser = g_mime_parser_new_with_stream (stream); |
|
|
|
message = g_mime_parser_construct_message (parser); |
|
|
|
} |
|
|
|
#endif |
|
|
|
ts2 = rspamd_get_ticks (); |
|
|
|
total_time += ts2 - ts1; |
|
|
|
|
|
|
|
if (mode == MODE_NORMAL) { |
|
|
|
for (i = 0; i < task->parts->len; i ++) { |
|
|
|
part = g_ptr_array_index (task->parts, i); |
|
|
|
|
|
|
|
if (part->ct->flags & RSPAMD_CONTENT_TYPE_MULTIPART) { |
|
|
|
rspamd_show_multipart (part); |
|
|
|
} |
|
|
|
else if (part->ct->flags & RSPAMD_CONTENT_TYPE_MESSAGE) { |
|
|
|
rspamd_show_message (part); |
|
|
|
} |
|
|
|
else { |
|
|
|
rspamd_show_normal (part); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
#if 0 |
|
|
|
else if (mode == MODE_GMIME) { |
|
|
|
g_mime_message_foreach (message, mime_foreach_callback, NULL); |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
rspamd_task_free (task); |
|
|
|
munmap (map, st.st_size); |
|
|
|
#if 0 |
|
|
|
if (mode == MODE_GMIME) { |
|
|
|
g_object_unref (message); |
|
|
|
} |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
int |
|
|
|
main (int argc, char **argv) |
|
|
|
{ |
|
|
|
gint i, start = 1, mode = MODE_NORMAL; |
|
|
|
struct rspamd_config *cfg; |
|
|
|
rspamd_logger_t *logger = NULL; |
|
|
|
|
|
|
|
if (argc > 2 && *argv[1] == '-') { |
|
|
|
start = 2; |
|
|
|
|
|
|
|
if (argv[1][1] == 'g') { |
|
|
|
mode = MODE_GMIME; |
|
|
|
} |
|
|
|
} |
|
|
|
cfg = rspamd_config_new (); |
|
|
|
cfg->libs_ctx = rspamd_init_libs (); |
|
|
|
cfg->log_type = RSPAMD_LOG_CONSOLE; |
|
|
|
rspamd_set_logger (cfg, g_quark_from_static_string ("mime"), &logger, NULL); |
|
|
|
(void) rspamd_log_open (logger); |
|
|
|
g_log_set_default_handler (rspamd_glib_log_function, logger); |
|
|
|
g_set_printerr_handler (rspamd_glib_printerr_function); |
|
|
|
rspamd_config_post_load (cfg, |
|
|
|
RSPAMD_CONFIG_INIT_LIBS|RSPAMD_CONFIG_INIT_URL|RSPAMD_CONFIG_INIT_NO_TLD); |
|
|
|
|
|
|
|
for (i = start; i < argc; i ++) { |
|
|
|
if (argv[i]) { |
|
|
|
rspamd_process_file (cfg, argv[i], mode); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
rspamd_printf ("Total time parsing: %.4f seconds\n", total_time); |
|
|
|
|
|
|
|
rspamd_log_close (logger); |
|
|
|
REF_RELEASE (cfg); |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |