1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef _LIBMIME_H_ 7 #define _LIBMIME_H_ 8 9 #ifdef XP_UNIX 10 # undef Bool 11 #endif 12 13 #include "nsString.h" 14 #include "nsMailHeaders.h" 15 #include "nsIMimeStreamConverter.h" 16 #include "mozilla/Encoding.h" 17 #include "nsIPrefBranch.h" 18 #include "mozITXTToHTMLConv.h" 19 #include "nsCOMPtr.h" 20 #include "modmimee.h" // for MimeConverterOutputCallback 21 22 #define MIME_DRAFTS 23 24 /* Opaque object describing a block of message headers, and a couple of 25 routines for extracting data from one. 26 */ 27 28 typedef struct MimeHeaders { 29 char* all_headers; /* A char* of the entire header section. */ 30 int32_t all_headers_fp; /* The length (it is not NULL-terminated.) */ 31 int32_t all_headers_size; /* The size of the allocated block. */ 32 33 bool done_p; /* Whether we've read the end-of-headers marker 34 (the terminating blank line.) */ 35 36 char** heads; /* An array of length heads_size which points 37 to the beginning of each distinct header: 38 just after the newline which terminated 39 the previous one. This is to speed search. 40 This is not initialized until all the 41 headers have been read. 42 */ 43 int32_t heads_size; /* The number of entries (pointers) in the heads 44 array (and consequently, how many 45 distinct headers are in here.) */ 46 47 char* obuffer; /* This buffer is used for output. */ 48 int32_t obuffer_size; 49 int32_t obuffer_fp; 50 51 char* munged_subject; /* What a hack. This is a place to write down 52 the subject header, after it's been 53 charset-ified and stuff. Remembered so that 54 we can later use it to generate the 55 <TITLE> tag. (Also works for giving names to 56 RFC822 attachments) */ 57 } MimeHeaders; 58 59 class MimeDisplayOptions; 60 class MimeParseStateObject; 61 typedef struct MSG_AttachmentData MSG_AttachmentData; 62 63 /* Given the name of a header, returns the contents of that header as 64 a newly-allocated string (which the caller must free.) If the header 65 is not present, or has no contents, NULL is returned. 66 67 If `strip_p' is true, then the data returned will be the first token 68 of the header; else it will be the full text of the header. (This is 69 useful for getting just "text/plain" from "text/plain; name=foo".) 70 71 If `all_p' is false, then the first header encountered is used, and 72 any subsequent headers of the same name are ignored. If true, then 73 all headers of the same name are appended together (this is useful 74 for gathering up all CC headers into one, for example.) 75 */ 76 extern char* MimeHeaders_get(MimeHeaders* hdrs, const char* header_name, 77 bool strip_p, bool all_p); 78 79 // clang-format off 80 /* Given a header of the form of the MIME "Content-" headers, extracts a 81 named parameter from it, if it exists. For example, 82 MimeHeaders_get_parameter("text/plain; charset=us-ascii", "charset") 83 would return "us-ascii". 84 85 Returns NULL if there is no match, or if there is an allocation failure. 86 87 RFC2231 - MIME Parameter Value and Encoded Word Extensions: Character Sets, 88 Languages, and Continuations 89 90 RFC2231 has added the character sets, languages, and continuations mechanism. 91 charset, and language information may also be returned to the caller. 92 Note that charset and language should be free()'d while 93 the return value (parameter) has to be PR_FREE'd. 94 95 For example, 96 MimeHeaders_get_parameter("text/plain; name*=us-ascii'en-us'This%20is%20%2A%2A%2Afun%2A%2A%2A", "name") 97 MimeHeaders_get_parameter("text/plain; name*0*=us-ascii'en-us'This%20is%20; CRLFLWSPname*1*=%2A%2A%2Afun%2A%2A%2A", "name") would return "This is ***fun***" and *charset = "us-ascii", *language = "en-us" 98 */ 99 // clang-format on 100 101 extern char* MimeHeaders_get_parameter(const char* header_value, 102 const char* parm_name, char** charset, 103 char** language); 104 105 extern MimeHeaders* MimeHeaders_copy(MimeHeaders* srcHeaders); 106 107 extern void MimeHeaders_free(MimeHeaders* hdrs); 108 109 typedef enum { 110 MimeHeadersAll, /* Show all headers */ 111 MimeHeadersSome, /* Show all "interesting" headers */ 112 MimeHeadersSomeNoRef, /* Same, but suppress the `References' header 113 (for when we're printing this message.) */ 114 MimeHeadersMicro, /* Show a one-line header summary */ 115 MimeHeadersMicroPlus, /* Same, but show the full recipient list as 116 well (To, CC, etc.) */ 117 MimeHeadersCitation, /* A one-line summary geared toward use in a 118 reply citation ("So-and-so wrote:") */ 119 MimeHeadersOnly, /* Just parse and output headers...nothing else! */ 120 MimeHeadersNone /* Skip showing any headers */ 121 } MimeHeadersState; 122 123 /* The signature for various callbacks in the MimeDisplayOptions structure. 124 */ 125 typedef char* (*MimeHTMLGeneratorFunction)(const char* data, void* closure, 126 MimeHeaders* headers); 127 128 class MimeDisplayOptions { 129 public: 130 MimeDisplayOptions(); 131 virtual ~MimeDisplayOptions(); 132 mozITXTToHTMLConv* conv; // For text conversion... 133 nsCOMPtr<nsIPrefBranch> m_prefBranch; /* prefBranch-service */ 134 nsMimeOutputType format_out; // The format out type 135 136 const char* url; /* Base URL for the document. This string should 137 be freed by the caller, after the parser 138 completes (possibly at the same time as the 139 MimeDisplayOptions itself.) */ 140 141 MimeHeadersState headers; /* How headers should be displayed. */ 142 bool fancy_headers_p; /* Whether to do clever formatting of headers 143 using tables, instead of spaces. */ 144 145 bool output_vcard_buttons_p; /* Whether to output the buttons */ 146 /* on vcards. */ 147 148 bool variable_width_plaintext_p; /* Whether text/plain messages should 149 be in variable width, or fixed. */ 150 bool wrap_long_lines_p; /* Whether to wrap long lines in text/plain 151 messages. */ 152 153 bool rot13_p; /* Whether text/plain parts should be rotated 154 Set by "?rot13=true" */ 155 char* part_to_load; /* The particular part of the multipart which 156 we are extracting. Set by "?part=3.2.4" */ 157 158 bool no_output_p; /* Will never write output when this is true. 159 (When false, output or not may depend on other things.) 160 This needs to be in the options, because the method 161 MimeObject_parse_begin is controlling the property 162 "output_p" (on the MimeObject) so we need a way for other 163 functions to override it and tell that we do not want 164 output. */ 165 166 bool write_html_p; /* Whether the output should be HTML, or raw. */ 167 168 bool decrypt_p; /* Whether all traces of xlateion should be 169 eradicated -- this is only meaningful when 170 write_html_p is false; we set this when 171 attaching a message for forwarding, since 172 forwarding someone else a message that wasn't 173 xlated for them doesn't work. We have to 174 dexlate it before sending it. 175 */ 176 177 /* Whether this MIME part is a child of another part (and not top level). */ 178 bool is_child = false; 179 180 uint32_t whattodo; /* from the prefs, we'll get if the user wants to do glyph 181 or structure substitutions and set this member variable. 182 */ 183 184 char* default_charset; /* If this is non-NULL, then it is the charset to 185 assume when no other one is specified via a 186 `charset' parameter. 187 */ 188 bool override_charset; /* If this is true, then we will assume that 189 all data is in the default_charset, regardless 190 of what the `charset' parameter of that part 191 says. (This is to cope with the fact that, in 192 the real world, many messages are mislabelled 193 with the wrong charset.) 194 */ 195 bool force_user_charset; /* this is the new strategy to deal with incorrectly 196 labeled attachments */ 197 198 /* ======================================================================= 199 Stream-related callbacks; for these functions, the `closure' argument 200 is what is found in `options->stream_closure'. (One possible exception 201 is for output_fn; see "output_closure" below.) 202 */ 203 void* stream_closure; 204 205 /* For setting up the display stream, so that the MIME parser can inform 206 the caller of the type of the data it will be getting. */ 207 int (*output_init_fn)(const char* type, const char* charset, const char* name, 208 const char* x_mac_type, const char* x_mac_creator, 209 void* stream_closure); 210 211 /* How the MIME parser feeds its output (HTML or raw) back to the caller. */ 212 MimeConverterOutputCallback output_fn; 213 214 /* Closure to pass to the above output_fn. If NULL, then the 215 stream_closure is used. */ 216 void* output_closure; 217 218 /* A hook for the caller to perform charset-conversion before HTML is 219 returned. Each set of characters which originated in a mail message 220 (body or headers) will be run through this filter before being converted 221 into HTML. (This should return bytes which may appear in an HTML file, 222 ie, we must be able to scan through the string to search for "<" and 223 turn it in to "<", and so on.) 224 225 `input' is a non-NULL-terminated string of a single line from the message. 226 `input_length' is how long it is. 227 `input_charset' is a string representing the charset of this string (as 228 specified by MIME headers.) 229 The conversion is always to UTF-8. 230 `output_ret' is where a newly-malloced string is returned. It may be 231 NULL if no translation is needed. 232 `output_size_ret' is how long the returned string is (it need not be 233 NULL-terminated.). 234 */ 235 int (*charset_conversion_fn)(const char* input_line, int32_t input_length, 236 const char* input_charset, 237 nsACString& output_ret, void* stream_closure); 238 239 /* If true, perform both charset-conversion and decoding of 240 MIME-2 header fields (using RFC-1522 encoding.) 241 */ 242 bool rfc1522_conversion_p; 243 244 /* A hook for the caller to turn a file name into a content-type. */ 245 char* (*file_type_fn)(const char* filename, void* stream_closure); 246 247 /* A hook by which the user may be prompted for a password by the security 248 library. (This is really of type `SECKEYGetPasswordKey'; see sec.h.) */ 249 void* (*passwd_prompt_fn)(void* arg1, void* arg2); 250 251 /* ======================================================================= 252 Various callbacks; for all of these functions, the `closure' argument 253 is what is found in `html_closure'. 254 */ 255 void* html_closure; 256 257 /* For emitting some HTML before the start of the outermost message 258 (this is called before any HTML is written to layout.) */ 259 MimeHTMLGeneratorFunction generate_header_html_fn; 260 261 /* For emitting some HTML after the outermost header block, but before 262 the body of the first message. */ 263 MimeHTMLGeneratorFunction generate_post_header_html_fn; 264 265 /* For emitting some HTML at the very end (this is called after libmime 266 has written everything it's going to write.) */ 267 MimeHTMLGeneratorFunction generate_footer_html_fn; 268 269 /* For turning a message ID into a loadable URL. */ 270 MimeHTMLGeneratorFunction generate_reference_url_fn; 271 272 /* For turning a mail address into a mailto URL. */ 273 MimeHTMLGeneratorFunction generate_mailto_url_fn; 274 275 /* For turning a newsgroup name into a news URL. */ 276 MimeHTMLGeneratorFunction generate_news_url_fn; 277 278 /* ======================================================================= 279 Callbacks to handle the backend-specific inlined image display 280 (internal-external-reconnect junk.) For `image_begin', the `closure' 281 argument is what is found in `stream_closure'; but for all of the 282 others, the `closure' argument is the data that `image_begin' returned. 283 */ 284 285 /* Begins processing an embedded image; the URL and content_type are of the 286 image itself. */ 287 void* (*image_begin)(const char* image_url, const char* content_type, 288 void* stream_closure); 289 290 /* Stop processing an image. */ 291 void (*image_end)(void* image_closure, int status); 292 293 /* Dump some raw image data down the stream. */ 294 int (*image_write_buffer)(const char* buf, int32_t size, void* image_closure); 295 296 /* What HTML should be dumped out for this image. */ 297 char* (*make_image_html)(void* image_closure); 298 299 /* ======================================================================= 300 Other random opaque state. 301 */ 302 MimeParseStateObject* state; /* Some state used by libmime internals; 303 initialize this to 0 and leave it alone. 304 */ 305 306 #ifdef MIME_DRAFTS 307 /* ======================================================================= 308 Mail Draft hooks -- 09-19-1996 309 */ 310 bool decompose_file_p; /* are we decomposing a mime msg 311 into separate files */ 312 bool done_parsing_outer_headers; /* are we done parsing the outer message 313 headers; this is really useful when 314 we have multiple Message/RFC822 315 headers */ 316 bool is_multipart_msg; /* are we decomposing a multipart 317 message */ 318 319 int decompose_init_count; /* used for non multipart message only */ 320 321 bool signed_p; /* to tell draft this is a signed message */ 322 323 bool caller_need_root_headers; /* set it to true to receive the message main 324 headers through the callback 325 decompose_headers_info_fn */ 326 327 /* Callback to gather the outer most headers so we could use the 328 information to initialize the addressing/subject/newsgroups fields 329 for the composition window. */ 330 int (*decompose_headers_info_fn)(void* closure, MimeHeaders* headers); 331 332 /* Callbacks to create temporary files for drafts attachments. */ 333 int (*decompose_file_init_fn)(void* stream_closure, MimeHeaders* headers); 334 335 MimeConverterOutputCallback decompose_file_output_fn; 336 337 int (*decompose_file_close_fn)(void* stream_closure); 338 #endif /* MIME_DRAFTS */ 339 340 int32_t attachment_icon_layer_id; /* Hackhackhack. This is zero if we have 341 not yet emitted the attachment layer 342 stuff. If we have, then this is the 343 id number for that layer, which is a 344 unique random number every time, to keep 345 evil people from writing javascript code 346 to hack it. */ 347 348 bool missing_parts; /* Whether or not this message is going to contain 349 missing parts (from IMAP Mime Parts On Demand) */ 350 351 bool show_attachment_inline_p; /* Whether or not we should display attachment 352 inline (whatever say the 353 content-disposition) */ 354 355 bool show_attachment_inline_text; /* Whether or not we should display text 356 attachment inline (whatever the 357 content-disposition says) */ 358 359 bool quote_attachment_inline_p; /* Whether or not we should include inlined 360 attachments in quotes of replies) */ 361 362 int32_t html_as_p; /* How we should display HTML, which allows us to know if 363 we should display all body parts */ 364 365 /** 366 * Should StartBody/EndBody events be generated for nested MimeMessages. If 367 * false (the default value), the events are only generated for the outermost 368 * MimeMessage. 369 */ 370 bool notify_nested_bodies; 371 372 /** 373 * When true, compels mime parts to only write the actual body 374 * payload and not display-gunk like links to attachments. This was 375 * primarily introduced for the benefit of the javascript emitter. 376 */ 377 bool write_pure_bodies; 378 379 /** 380 * When true, only processes metadata (i.e. size) for streamed attachments. 381 * Mime emitters that expect any attachment data (including inline text and 382 * image attachments) should leave this as false (the default value). At 383 * the moment, only the JS mime emitter uses this. 384 */ 385 bool metadata_only; 386 }; 387 388 #endif /* _MODLMIME_H_ */ 389