1 /*-
2 * Copyright 2016 Vsevolod Stakhov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "config.h"
18 #include "printf.h"
19 #include "message.h"
20 #include "util.h"
21 #include "content_type.h"
22
23 static gdouble total_time = 0;
24 static gint total_parsed = 0;
25 static gint total_valid = 0;
26 static gint total_type = 0;
27 static gint total_subtype = 0;
28 static gint total_charset = 0;
29 static gint total_attrs = 0;
30 static gint total_boundaries = 0;
31 static gboolean verbose = 1;
32
33 #define MODE_NORMAL 0
34 #define MODE_GMIME 1
35 #define MODE_COMPARE 2
36
37 static void
rspamd_process_file(const gchar * fname,gint mode)38 rspamd_process_file (const gchar *fname, gint mode)
39 {
40 rspamd_mempool_t *pool;
41 GIOChannel *f;
42 GError *err = NULL;
43 GString *buf;
44 struct rspamd_content_type *ct;
45 gdouble t1, t2;
46 rspamd_ftok_t t;
47
48 f = g_io_channel_new_file (fname, "r", &err);
49
50 if (!f) {
51 rspamd_fprintf (stderr, "cannot open %s: %e\n", fname, err);
52 g_error_free (err);
53
54 return;
55 }
56
57 g_io_channel_set_encoding (f, NULL, NULL);
58 buf = g_string_sized_new (8192);
59 pool = rspamd_mempool_new (rspamd_mempool_suggest_size (), "test");
60
61 while (g_io_channel_read_line_string (f, buf, NULL, &err)
62 == G_IO_STATUS_NORMAL) {
63
64 while (buf->len > 0 && g_ascii_isspace (buf->str[buf->len - 1])) {
65 buf->len --;
66 }
67
68 if (mode == MODE_NORMAL) {
69 t1 = rspamd_get_virtual_ticks ();
70 ct = rspamd_content_type_parse (buf->str, buf->len, pool);
71 t2 = rspamd_get_virtual_ticks ();
72 }
73 else {
74 rspamd_fprintf (stderr, "gmime is no longer supported\n");
75 exit (EXIT_FAILURE);
76 }
77
78 total_time += t2 - t1;
79 total_parsed ++;
80
81 if (mode == MODE_NORMAL) {
82
83 if (ct) {
84 total_valid ++;
85
86 if (ct->type.len > 0) {
87 total_type ++;
88 }
89 if (ct->subtype.len > 0) {
90 total_subtype ++;
91 }
92 if (ct->charset.len > 0) {
93 total_charset ++;
94 }
95 if (ct->boundary.len > 0) {
96 total_boundaries ++;
97 }
98 if (ct->attrs) {
99 total_attrs ++;
100 }
101 }
102 }
103 }
104
105 if (err) {
106 rspamd_fprintf (stderr, "cannot read %s: %e\n", fname, err);
107 g_error_free (err);
108 }
109
110 g_io_channel_unref (f);
111 g_string_free (buf, TRUE);
112 rspamd_mempool_delete (pool);
113 }
114
115 int
main(int argc,char ** argv)116 main (int argc, char **argv)
117 {
118 gint i, start = 1, mode = MODE_NORMAL;
119
120 if (argc > 2 && *argv[1] == '-') {
121 start = 2;
122
123 if (argv[1][1] == 'g') {
124 mode = MODE_GMIME;
125 }
126 else if (argv[1][1] == 'c') {
127 mode = MODE_COMPARE;
128 }
129 }
130
131 for (i = start; i < argc; i ++) {
132 if (argv[i]) {
133 rspamd_process_file (argv[i], mode);
134 }
135 }
136
137 if (mode != MODE_COMPARE) {
138 rspamd_printf ("Parsed %d received headers in %.3f seconds\n"
139 "Total valid (has type): %d\n"
140 "Total known type: %d\n"
141 "Total known subtype: %d\n"
142 "Total known charset: %d\n"
143 "Total has attrs: %d\n"
144 "Total has boundaries: %d\n",
145 total_parsed, total_time,
146 total_valid, total_type,
147 total_subtype, total_charset,
148 total_attrs,
149 total_boundaries);
150 }
151 else {
152 rspamd_printf ("Parsed %d received headers in %.3f seconds\n"
153 "Total valid (parsed by both): %d\n"
154 "Total same type: %d\n"
155 "Total same subtype: %d\n"
156 "Total same charset: %d\n"
157 "Total same boundaries: %d\n",
158 total_parsed, total_time,
159 total_valid, total_type,
160 total_subtype, total_charset,
161 total_boundaries);
162 }
163
164 return 0;
165 }
166