1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2000-2012 Jeffrey Stedfast
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License
7 * as published by the Free Software Foundation; either version 2.1
8 * of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free
17 * Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
28 #include "gmime-filter-from.h"
32 * SECTION: gmime-filter-from
33 * @title: GMimeFilterFrom
34 * @short_description: Escape MBox From_ lines
35 * @see_also: #GMimeFilter
37 * A #GMimeFilter used for escaping MBox From_ lines using either the
38 * traditional ">From " or quoted-printable encoding.
42 static void g_mime_filter_from_class_init (GMimeFilterFromClass *klass);
43 static void g_mime_filter_from_init (GMimeFilterFrom *filter, GMimeFilterFromClass *klass);
44 static void g_mime_filter_from_finalize (GObject *object);
46 static GMimeFilter *filter_copy (GMimeFilter *filter);
47 static void filter_filter (GMimeFilter *filter, char *in, size_t len,
48 size_t prespace, char **out,
49 size_t *outlen, size_t *outprespace);
50 static void filter_complete (GMimeFilter *filter, char *in, size_t len,
51 size_t prespace, char **out,
52 size_t *outlen, size_t *outprespace);
53 static void filter_reset (GMimeFilter *filter);
56 static GMimeFilterClass *parent_class = NULL;
60 g_mime_filter_from_get_type (void)
62 static GType type = 0;
65 static const GTypeInfo info = {
66 sizeof (GMimeFilterFromClass),
67 NULL, /* base_class_init */
68 NULL, /* base_class_finalize */
69 (GClassInitFunc) g_mime_filter_from_class_init,
70 NULL, /* class_finalize */
71 NULL, /* class_data */
72 sizeof (GMimeFilterFrom),
74 (GInstanceInitFunc) g_mime_filter_from_init,
77 type = g_type_register_static (GMIME_TYPE_FILTER, "GMimeFilterFrom", &info, 0);
85 g_mime_filter_from_class_init (GMimeFilterFromClass *klass)
87 GObjectClass *object_class = G_OBJECT_CLASS (klass);
88 GMimeFilterClass *filter_class = GMIME_FILTER_CLASS (klass);
90 parent_class = g_type_class_ref (GMIME_TYPE_FILTER);
92 object_class->finalize = g_mime_filter_from_finalize;
94 filter_class->copy = filter_copy;
95 filter_class->filter = filter_filter;
96 filter_class->complete = filter_complete;
97 filter_class->reset = filter_reset;
101 g_mime_filter_from_init (GMimeFilterFrom *filter, GMimeFilterFromClass *klass)
103 filter->midline = FALSE;
107 g_mime_filter_from_finalize (GObject *object)
109 G_OBJECT_CLASS (parent_class)->finalize (object);
114 filter_copy (GMimeFilter *filter)
116 GMimeFilterFrom *from = (GMimeFilterFrom *) filter;
118 return g_mime_filter_from_new (from->mode);
122 struct fromnode *next;
127 filter_filter (GMimeFilter *filter, char *in, size_t len, size_t prespace,
128 char **out, size_t *outlen, size_t *outprespace)
130 GMimeFilterFrom *from = (GMimeFilterFrom *) filter;
131 struct fromnode *head = NULL, *tail = (struct fromnode *) &head, *node;
132 register char *inptr, *inend;
140 while (inptr < inend) {
144 while (inptr < inend && (c = *inptr++) != '\n')
148 if (c == '\n' || !from->midline) {
149 left = (size_t) (inend - inptr);
151 from->midline = TRUE;
154 g_mime_filter_backup (filter, inptr, left);
155 from->midline = FALSE;
160 if (!strncmp (inptr, "From ", 5)) {
163 node = g_alloca (sizeof (struct fromnode));
164 node->pointer = inptr;
173 from->midline = FALSE;
179 if (from->mode == GMIME_FILTER_FROM_MODE_ARMOR)
180 len += (fromcount * 2);
184 g_mime_filter_set_size (filter, len, FALSE);
188 outptr = filter->outbuf;
190 memcpy (outptr, inptr, (unsigned) (node->pointer - inptr));
191 outptr += node->pointer - inptr;
192 if (from->mode == GMIME_FILTER_FROM_MODE_ARMOR) {
196 inptr = node->pointer + 1;
199 inptr = node->pointer;
205 memcpy (outptr, inptr, (size_t) (inend - inptr));
206 outptr += inend - inptr;
207 *out = filter->outbuf;
208 *outlen = (size_t) (outptr - filter->outbuf);
209 *outprespace = filter->outbuf - filter->outreal;
212 *outlen = (size_t) (inend - in);
213 *outprespace = prespace;
218 filter_complete (GMimeFilter *filter, char *in, size_t len, size_t prespace,
219 char **out, size_t *outlen, size_t *outprespace)
221 filter_filter (filter, in, len, prespace, out, outlen, outprespace);
225 filter_reset (GMimeFilter *filter)
227 GMimeFilterFrom *from = (GMimeFilterFrom *) filter;
229 from->midline = FALSE;
234 * g_mime_filter_from_new:
237 * Creates a new GMimeFilterFrom filter. If @mode is
238 * #GMIME_FILTER_FROM_MODE_ARMOR, the from-filter will encode from
239 * lines using the quoted-printable encoding resulting in "=46rom ".
240 * Using the #GMIME_FILTER_FROM_MODE_DEFAULT or
241 * #GMIME_FILTER_FROM_MODE_ESCAPE mode (they are the same), from lines
242 * will be escaped to ">From ".
244 * Note: If you plan on using a from-filter in mode ARMOR, you should
245 * remember to also use a #GMimeFilterBasic filter with an encoding of
246 * #GMIME_CONTENT_ENCODING_QUOTEDPRINTABLE.
248 * Returns: a new from filter with mode @mode.
251 g_mime_filter_from_new (GMimeFilterFromMode mode)
253 GMimeFilterFrom *new;
255 new = g_object_newv (GMIME_TYPE_FILTER_FROM, 0, NULL);
256 new->midline = FALSE;
258 case GMIME_FILTER_FROM_MODE_ARMOR:
261 case GMIME_FILTER_FROM_MODE_ESCAPE:
263 new->mode = GMIME_FILTER_FROM_MODE_ESCAPE;
267 return (GMimeFilter *) new;