1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2002 Ximian, Inc.
5 * Authors: Jeffrey Stedfast <fejj@ximian.com>
6 * Michael Zucchi <notzed@ximian.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU Lesser General Public
10 * License as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
23 /* canonicalisation filter, used for secure mime incoming and outgoing */
32 #include "camel-mime-filter-canon.h"
34 static void filter (CamelMimeFilter *f, char *in, size_t len, size_t prespace,
35 char **out, size_t *outlen, size_t *outprespace);
36 static void complete (CamelMimeFilter *f, char *in, size_t len,
37 size_t prespace, char **out, size_t *outlen,
39 static void reset (CamelMimeFilter *f);
43 camel_mime_filter_canon_class_init (CamelMimeFilterCanonClass *klass)
45 CamelMimeFilterClass *mime_filter_class = (CamelMimeFilterClass *) klass;
47 mime_filter_class->filter = filter;
48 mime_filter_class->complete = complete;
49 mime_filter_class->reset = reset;
53 camel_mime_filter_canon_get_type (void)
55 static CamelType type = CAMEL_INVALID_TYPE;
57 if (type == CAMEL_INVALID_TYPE) {
58 type = camel_type_register (camel_mime_filter_get_type(), "CamelMimeFilterCanon",
59 sizeof (CamelMimeFilterCanon),
60 sizeof (CamelMimeFilterCanonClass),
61 (CamelObjectClassInitFunc) camel_mime_filter_canon_class_init,
71 filter_run(CamelMimeFilter *f, char *in, size_t len, size_t prespace, char **out, size_t *outlen, size_t *outprespace, int last)
73 register unsigned char *inptr, c;
74 const unsigned char *inend, *start;
80 flags = ((CamelMimeFilterCanon *)f)->flags;
82 /* first, work out how much space we need */
89 /* worst case, extra 3 chars per line
90 "From \n" -> "=46rom \r\n"
91 We add 1 extra incase we're called from complete, when we didn't end in \n */
93 camel_mime_filter_set_size(f, len+lf*3+4, FALSE);
99 while (inptr < inend) {
100 /* first, check start of line, we always start at the start of the line */
102 if (flags & CAMEL_MIME_FILTER_CANON_FROM && c == 'F') {
104 if (inptr < inend-4) {
105 if (strncmp(inptr, "rom ", 4) == 0) {
106 strcpy(o, "=46rom ");
117 /* now scan for end of line */
118 while (inptr < inend) {
121 /* check to strip trailing space */
122 if (flags & CAMEL_MIME_FILTER_CANON_STRIP) {
123 while (o>starto && (o[-1] == ' ' || o[-1] == '\t' || o[-1]=='\r'))
126 /* check end of line canonicalisation */
128 if (flags & CAMEL_MIME_FILTER_CANON_CRLF) {
135 } else if (flags & CAMEL_MIME_FILTER_CANON_CRLF) {
149 /* TODO: We should probably track if we end somewhere in the middle of a line,
150 otherwise we potentially backup a full line, which could be large */
152 /* we got to the end of the data without finding anything, backup to start and re-process next time around */
154 *outlen = o - f->outbuf;
156 camel_mime_filter_backup(f, start, inend - start);
157 *outlen = starto - f->outbuf;
161 *outprespace = f->outpre;
165 filter(CamelMimeFilter *f, char *in, size_t len, size_t prespace, char **out, size_t *outlen, size_t *outprespace)
167 filter_run(f, in, len, prespace, out, outlen, outprespace, FALSE);
171 complete(CamelMimeFilter *f, char *in, size_t len, size_t prespace, char **out, size_t *outlen, size_t *outprespace)
173 filter_run(f, in, len, prespace, out, outlen, outprespace, TRUE);
177 reset (CamelMimeFilter *f)
184 * camel_mime_filter_canon_new:
185 * @flags: bitwise flags defining the behaviour of the filter
187 * Create a new filter to canonicalise an input stream.
189 * Returns a new #CamelMimeFilterCanon
192 camel_mime_filter_canon_new(guint32 flags)
194 CamelMimeFilterCanon *chomp = CAMEL_MIME_FILTER_CANON (camel_object_new (CAMEL_MIME_FILTER_CANON_TYPE));
196 chomp->flags = flags;
198 return (CamelMimeFilter *) chomp;