1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
4  *
5  * This library is free software: you can redistribute it and/or modify it
6  * under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation.
8  *
9  * This library is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
12  * for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this library. If not, see <http://www.gnu.org/licenses/>.
16  *
17  * Authors: Michael Zucchi <notzed@ximian.com>
18  *          Jeffrey Stedfast <fejj@ximian.com>
19  */
20 
21 #if !defined (__CAMEL_H_INSIDE__) && !defined (CAMEL_COMPILATION)
22 #error "Only <camel/camel.h> can be included directly."
23 #endif
24 
25 #ifndef CAMEL_MIME_UTILS_H
26 #define CAMEL_MIME_UTILS_H
27 
28 #include <time.h>
29 #include <glib.h>
30 #include <glib-object.h>
31 #include <camel/camel-enums.h>
32 #include <camel/camel-utils.h>
33 #include <camel/camel-name-value-array.h>
34 
35 G_BEGIN_DECLS
36 
37 /* maximum recommended size of a line from camel_header_fold() */
38 #define CAMEL_FOLD_SIZE (77)
39 /* maximum hard size of a line from camel_header_fold() */
40 #define CAMEL_FOLD_MAX_SIZE (998)
41 
42 typedef enum {
43 	CAMEL_UUDECODE_STATE_INIT = 0,
44 	CAMEL_UUDECODE_STATE_BEGIN = (1 << 16),
45 	CAMEL_UUDECODE_STATE_END = (1 << 17)
46 } CamelUUDecodeState;
47 
48 #define CAMEL_UUDECODE_STATE_MASK   (CAMEL_UUDECODE_STATE_BEGIN | CAMEL_UUDECODE_STATE_END)
49 
50 typedef struct _camel_header_param {
51 	struct _camel_header_param *next;
52 	gchar *name;
53 	gchar *value;
54 } CamelHeaderParam;
55 
56 /* describes a content-type */
57 typedef struct {
58 	gchar *type;
59 	gchar *subtype;
60 	struct _camel_header_param *params;
61 	guint refcount;
62 } CamelContentType;
63 
64 typedef struct _CamelContentDisposition {
65 	gchar *disposition;
66 	struct _camel_header_param *params;
67 	guint refcount;
68 } CamelContentDisposition;
69 
70 typedef enum _camel_header_address_t {
71 	CAMEL_HEADER_ADDRESS_NONE,	/* uninitialised */
72 	CAMEL_HEADER_ADDRESS_NAME,
73 	CAMEL_HEADER_ADDRESS_GROUP
74 } CamelHeaderAddressType;
75 
76 typedef struct _camel_header_address {
77 	/* < private > */
78 	struct _camel_header_address *next;
79 	CamelHeaderAddressType type;
80 	gchar *name;
81 	union {
82 		gchar *addr;
83 		struct _camel_header_address *members;
84 	} v;
85 	guint refcount;
86 } CamelHeaderAddress;
87 
88 /* Time utilities */
89 time_t		camel_mktime_utc		(struct tm *tm);
90 void		camel_localtime_with_offset	(time_t tt,
91 						 struct tm *tm,
92 						 gint *offset);
93 
94 /* Address lists */
95 GType camel_header_address_get_type (void) G_GNUC_CONST;
96 CamelHeaderAddress *camel_header_address_new (void);
97 CamelHeaderAddress *camel_header_address_new_name (const gchar *name, const gchar *addr);
98 CamelHeaderAddress *camel_header_address_new_group (const gchar *name);
99 CamelHeaderAddress *camel_header_address_ref (CamelHeaderAddress *addrlist);
100 void camel_header_address_unref (CamelHeaderAddress *addrlist);
101 void camel_header_address_set_name (CamelHeaderAddress *addrlist, const gchar *name);
102 void camel_header_address_set_addr (CamelHeaderAddress *addrlist, const gchar *addr);
103 void camel_header_address_set_members (CamelHeaderAddress *addrlist, CamelHeaderAddress *group);
104 void camel_header_address_add_member (CamelHeaderAddress *addrlist, CamelHeaderAddress *member);
105 void camel_header_address_list_append_list (CamelHeaderAddress **addrlistp, CamelHeaderAddress **addrs);
106 void camel_header_address_list_append (CamelHeaderAddress **addrlistp, CamelHeaderAddress *addr);
107 void camel_header_address_list_clear (CamelHeaderAddress **addrlistp);
108 
109 CamelHeaderAddress *camel_header_address_decode (const gchar *in, const gchar *charset);
110 CamelHeaderAddress *camel_header_mailbox_decode (const gchar *in, const gchar *charset);
111 /* for mailing */
112 gchar *camel_header_address_list_encode (CamelHeaderAddress *addrlist);
113 /* for display */
114 gchar *camel_header_address_list_format (CamelHeaderAddress *addrlist);
115 
116 /* structured header prameters */
117 struct _camel_header_param *camel_header_param_list_decode (const gchar *in);
118 gchar *camel_header_param (struct _camel_header_param *params, const gchar *name);
119 struct _camel_header_param *camel_header_set_param (struct _camel_header_param **paramsp, const gchar *name, const gchar *value);
120 void camel_header_param_list_format_append (GString *out, struct _camel_header_param *params);
121 gchar *camel_header_param_list_format (struct _camel_header_param *params);
122 void camel_header_param_list_free (struct _camel_header_param *params);
123 
124 /* Content-Type header */
125 GType camel_content_type_get_type (void) G_GNUC_CONST;
126 CamelContentType *camel_content_type_new (const gchar *type, const gchar *subtype);
127 CamelContentType *camel_content_type_decode (const gchar *in);
128 void camel_content_type_unref (CamelContentType *content_type);
129 CamelContentType *camel_content_type_ref (CamelContentType *content_type);
130 const gchar *camel_content_type_param (CamelContentType *content_type, const gchar *name);
131 void camel_content_type_set_param (CamelContentType *content_type, const gchar *name, const gchar *value);
132 gboolean camel_content_type_is (const CamelContentType *content_type, const gchar *type, const gchar *subtype);
133 gchar *camel_content_type_format (CamelContentType *content_type);
134 gchar *camel_content_type_simple (CamelContentType *content_type);
135 
136 /* DEBUGGING function */
137 void camel_content_type_dump (CamelContentType *content_type);
138 
139 /* Content-Disposition header */
140 GType camel_content_disposition_get_type (void) G_GNUC_CONST;
141 CamelContentDisposition *camel_content_disposition_new (void);
142 CamelContentDisposition *camel_content_disposition_decode (const gchar *in);
143 CamelContentDisposition *camel_content_disposition_ref (CamelContentDisposition *disposition);
144 void camel_content_disposition_unref (CamelContentDisposition *disposition);
145 gchar *camel_content_disposition_format (CamelContentDisposition *disposition);
146 gboolean camel_content_disposition_is_attachment (const CamelContentDisposition *disposition, const CamelContentType *content_type);
147 gboolean camel_content_disposition_is_attachment_ex (const CamelContentDisposition *disposition, const CamelContentType *content_type, const CamelContentType *parent_content_type);
148 
149 /* decode the contents of a content-encoding header */
150 gchar *camel_content_transfer_encoding_decode (const gchar *in);
151 
152 /* fold a header */
153 gchar *camel_header_address_fold (const gchar *in, gsize headerlen);
154 gchar *camel_header_fold (const gchar *in, gsize headerlen);
155 gchar *camel_header_unfold (const gchar *in);
156 
157 gchar *camel_headers_dup_mailing_list (const CamelNameValueArray *headers);
158 
159 /* decode a header which is a simple token */
160 gchar *camel_header_token_decode (const gchar *in);
161 
162 gint camel_header_decode_int (const gchar **in);
163 
164 /* decode/encode a string type, like a subject line */
165 gchar *camel_header_decode_string (const gchar *in, const gchar *default_charset);
166 gchar *camel_header_encode_string (const guchar *in);
167 
168 /* decode (text | comment) - a one-way op */
169 gchar *camel_header_format_ctext (const gchar *in, const gchar *default_charset);
170 
171 /* encode a phrase, like the real name of an address */
172 gchar *camel_header_encode_phrase (const guchar *in);
173 
174 /* FIXME: these are the only 2 functions in this header which are ch_(action)_type
175  * rather than ch_type_(action) */
176 
177 /* decode an email date field into a GMT time, + optional offset */
178 time_t camel_header_decode_date (const gchar *str, gint *tz_offset);
179 gchar *camel_header_format_date (time_t date, gint tz_offset);
180 
181 /* decode a message id */
182 gchar *camel_header_msgid_decode (const gchar *in);
183 gchar *camel_header_contentid_decode (const gchar *in);
184 
185 /* generate msg id */
186 gchar *camel_header_msgid_generate (const gchar *domain);
187 
188 /* decode a References or In-Reply-To header */
189 GSList *camel_header_references_decode (const gchar *in);
190 
191 /* decode content-location */
192 gchar *camel_header_location_decode (const gchar *in);
193 
194 /* nntp stuff */
195 GSList *camel_header_newsgroups_decode (const gchar *in);
196 
197 const gchar *camel_transfer_encoding_to_string (CamelTransferEncoding encoding);
198 CamelTransferEncoding camel_transfer_encoding_from_string (const gchar *string);
199 
200 /* decode the mime-type header */
201 void camel_header_mime_decode (const gchar *in, gint *maj, gint *min);
202 
203 gsize camel_uudecode_step (guchar *in, gsize inlen, guchar *out, gint *state, guint32 *save);
204 
205 gsize camel_uuencode_step (guchar *in, gsize len, guchar *out, guchar *uubuf, gint *state,
206 		      guint32 *save);
207 gsize camel_uuencode_close (guchar *in, gsize len, guchar *out, guchar *uubuf, gint *state,
208 		       guint32 *save);
209 
210 gsize camel_quoted_decode_step (guchar *in, gsize len, guchar *out, gint *savestate, gint *saveme);
211 
212 gsize camel_quoted_encode_step (guchar *in, gsize len, guchar *out, gint *state, gint *save);
213 gsize camel_quoted_encode_close (guchar *in, gsize len, guchar *out, gint *state, gint *save);
214 
215 /* camel ctype type functions for rfc822/rfc2047/other, which are non-locale specific */
216 enum {
217 	CAMEL_MIME_IS_CTRL = 1 << 0,
218 	CAMEL_MIME_IS_LWSP = 1 << 1,
219 	CAMEL_MIME_IS_TSPECIAL = 1 << 2,
220 	CAMEL_MIME_IS_SPECIAL = 1 << 3,
221 	CAMEL_MIME_IS_SPACE = 1 << 4,
222 	CAMEL_MIME_IS_DSPECIAL = 1 << 5,
223 	CAMEL_MIME_IS_QPSAFE = 1 << 6,
224 	CAMEL_MIME_IS_ESAFE	= 1 << 7,	/* encoded word safe */
225 	CAMEL_MIME_IS_PSAFE	= 1 << 8,	/* encoded word in phrase safe */
226 	CAMEL_MIME_IS_ATTRCHAR  = 1 << 9	/* attribute-char safe (rfc2184) */
227 };
228 
229 extern gushort camel_mime_special_table[256];
230 
231 #define camel_mime_is_ctrl(x) ((camel_mime_special_table[(guchar)(x)] & CAMEL_MIME_IS_CTRL) != 0)
232 #define camel_mime_is_lwsp(x) ((camel_mime_special_table[(guchar)(x)] & CAMEL_MIME_IS_LWSP) != 0)
233 #define camel_mime_is_tspecial(x) ((camel_mime_special_table[(guchar)(x)] & CAMEL_MIME_IS_TSPECIAL) != 0)
234 #define camel_mime_is_type(x, t) ((camel_mime_special_table[(guchar)(x)] & (t)) != 0)
235 #define camel_mime_is_ttoken(x) ((camel_mime_special_table[(guchar)(x)] & (CAMEL_MIME_IS_TSPECIAL|CAMEL_MIME_IS_LWSP|CAMEL_MIME_IS_CTRL)) == 0)
236 #define camel_mime_is_atom(x) ((camel_mime_special_table[(guchar)(x)] & (CAMEL_MIME_IS_SPECIAL|CAMEL_MIME_IS_SPACE|CAMEL_MIME_IS_CTRL)) == 0)
237 #define camel_mime_is_dtext(x) ((camel_mime_special_table[(guchar)(x)] & CAMEL_MIME_IS_DSPECIAL) == 0)
238 #define camel_mime_is_fieldname(x) ((camel_mime_special_table[(guchar)(x)] & (CAMEL_MIME_IS_CTRL|CAMEL_MIME_IS_SPACE)) == 0)
239 #define camel_mime_is_qpsafe(x) ((camel_mime_special_table[(guchar)(x)] & CAMEL_MIME_IS_QPSAFE) != 0)
240 #define camel_mime_is_especial(x) ((camel_mime_special_table[(guchar)(x)] & CAMEL_MIME_IS_ESPECIAL) != 0)
241 #define camel_mime_is_psafe(x) ((camel_mime_special_table[(guchar)(x)] & CAMEL_MIME_IS_PSAFE) != 0)
242 #define camel_mime_is_attrchar(x) ((camel_mime_special_table[(guchar)(x)] & CAMEL_MIME_IS_ATTRCHAR) != 0)
243 
244 G_END_DECLS
245 
246 #endif /* CAMEL_MIME_UTILS_H */
247