/** Interface for MIME parsing classes Copyright (C) 2000-2016 Free Software Foundation, Inc. Written by: Richard Frith-Macdonald Date: October 2000 This file is part of the GNUstep Base Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 31 Milk Street #960789 Boston, MA 02196 USA. AutogsdocSource: Additions/GSMime.m */ #ifndef __GSMime_h_GNUSTEP_BASE_INCLUDE #define __GSMime_h_GNUSTEP_BASE_INCLUDE #import #if OS_API_VERSION(GS_API_NONE,GS_API_LATEST) #ifdef NeXT_Foundation_LIBRARY #import #else #import #import #import #endif #if defined(__cplusplus) extern "C" { #endif @class NSArray; @class NSMutableArray; @class NSData; @class NSMutableData; @class NSDictionary; @class NSMutableDictionary; @class NSScanner; /* * A trivial class for mantaining state while decoding/encoding data. * Each encoding type requires its own subclass. */ GS_EXPORT_CLASS @interface GSMimeCodingContext : NSObject { BOOL atEnd; /* Flag to say that data has ended. */ } - (BOOL) atEnd; - (BOOL) decodeData: (const void*)sData length: (NSUInteger)length intoData: (NSMutableData*)dData; - (void) setAtEnd: (BOOL)flag; @end GS_EXPORT_CLASS @interface GSMimeHeader : NSObject { #if GS_EXPOSE(GSMimeHeader) NSString *name; NSString *lower; NSString *value; NSMutableDictionary *objects; NSMutableDictionary *params; #endif #if GS_NONFRAGILE #else /* Pointer to private additional data used to avoid breaking ABI * when we don't have the non-fragile ABI available. * Use this mechanism rather than changing the instance variable * layout (see Source/GSInternal.h for details). */ @private id _internal GS_UNUSED_IVAR; #endif } + (GSMimeHeader*) headerWithName: (NSString*)n value: (NSString*)v parameters: (NSDictionary*)p; + (NSString*) makeQuoted: (NSString*)v always: (BOOL)flag; + (NSString*) makeToken: (NSString*)t preservingCase: (BOOL)preserve; + (NSString*) makeToken: (NSString*)t; - (id) copyWithZone: (NSZone*)z; /** How big this header might be when represented as raw MIME data. */ - (NSUInteger) estimatedSize; - (NSString*) fullValue; - (id) initWithName: (NSString*)n value: (NSString*)v; - (id) initWithName: (NSString*)n value: (NSString*)v parameters: (NSDictionary*)p; - (NSString*) name; - (NSString*) namePreservingCase: (BOOL)preserve; - (id) objectForKey: (NSString*)k; - (NSDictionary*) objects; - (NSString*) parameterForKey: (NSString*)k; - (NSDictionary*) parameters; - (NSDictionary*) parametersPreservingCase: (BOOL)preserve; - (NSMutableData*) rawMimeData; - (NSMutableData*) rawMimeDataPreservingCase: (BOOL)preserve; - (NSMutableData*) rawMimeDataPreservingCase: (BOOL)preserve foldedAt: (NSUInteger)fold; - (void) rawMimeDataPreservingCase: (BOOL)preserve foldedAt: (NSUInteger)fold to: (NSMutableData*)md; - (void) setObject: (id)o forKey: (NSString*)k; - (void) setParameter: (NSString*)v forKey: (NSString*)k; - (void) setParameters: (NSDictionary*)d; - (void) setValue: (NSString*)s; - (NSString*) text; - (NSString*) value; @end GS_EXPORT_CLASS @interface GSMimeDocument : NSObject { #if GS_EXPOSE(GSMimeDocument) NSMutableArray *headers; id content; #endif #if !GS_NONFRAGILE void *_unused; #endif } /* Examine xml data/string to find out the characterset encoding specified */ + (NSString*) charsetForXml: (id)xml; + (NSString*) charsetFromEncoding: (NSStringEncoding)enc; /** * Decode the source data from base64 encoding and return the result.
* The source data is expected to be ASCII text and may be multiple * lines or a line of any length (decoding is very tolerant). */ + (NSData*) decodeBase64: (NSData*)source; + (NSString*) decodeBase64String: (NSString*)source; + (GSMimeDocument*) documentWithContent: (id)newContent type: (NSString*)type name: (NSString*)name; /** * Encode the source data to base64 encoding and return the result.
* The resulting data is ASCII text and contains only the base64 encoded * values with no line breaks or extraneous data. This is base64 encoded * data in it's general format as mandated in RFC 3548. If the data is * to be used as part of a MIME document body, line breaks must be * introduced at 76 byte intervals (GSMime does this when automatically * encoding data for you). If the data is to be used in a PEM document * line breaks must be introduced at 74 byte intervals. */ + (NSData*) encodeBase64: (NSData*)source; + (NSString*) encodeBase64String: (NSString*)source; + (NSStringEncoding) encodingFromCharset: (NSString*)charset; - (void) addContent: (id)newContent; - (void) addHeader: (GSMimeHeader*)info; - (GSMimeHeader*) addHeader: (NSString*)name value: (NSString*)value parameters: (NSDictionary*)parameters; - (NSArray*) allHeaders; - (id) content; - (id) contentByID: (NSString*)key; - (id) contentByLocation: (NSString*)key; - (id) contentByName: (NSString*)key; - (id) copyWithZone: (NSZone*)z; - (NSString*) contentFile; - (NSString*) contentID; - (NSString*) contentLocation; - (NSString*) contentName; - (NSString*) contentSubtype; - (NSString*) contentType; - (NSArray*) contentsByName: (NSString*)key; - (void) convertTo7BitSafe; - (void) convertToBase64; // DEPRECATED ... use convertTo7BitSafe - (void) convertToBinary; - (NSData*) convertToData; - (NSString*) convertToText; - (void) deleteContent: (GSMimeDocument*)aPart; - (void) deleteHeader: (GSMimeHeader*)aHeader; - (void) deleteHeaderNamed: (NSString*)name; /** How big this document might be when represented as raw MIME data. */ - (NSUInteger) estimatedSize; - (GSMimeHeader*) headerNamed: (NSString*)name; - (NSArray*) headersNamed: (NSString*)name; - (NSString*) makeBoundary; - (GSMimeHeader*) makeContentID; - (GSMimeHeader*) makeHeader: (NSString*)name value: (NSString*)value parameters: (NSDictionary*)parameters; - (GSMimeHeader*) makeMessageID; - (NSMutableData*) rawMimeData; - (NSMutableData*) rawMimeData: (BOOL)isOuter; - (NSMutableData*) rawMimeData: (BOOL)isOuter foldedAt: (NSUInteger)fold; - (void) setContent: (id)newContent; - (void) setContent: (id)newContent type: (NSString*)type; - (void) setContent: (id)newContent type: (NSString*)type name: (NSString*)name; - (void) setContentType: (NSString*)newType; - (void) setHeader: (GSMimeHeader*)info; - (GSMimeHeader*) setHeader: (NSString*)name value: (NSString*)value parameters: (NSDictionary*)parameters; @end GS_EXPORT_CLASS @interface GSMimeParser : NSObject { #if GS_EXPOSE(GSMimeParser) NSMutableData *data; unsigned char *bytes; unsigned dataEnd; unsigned sectionStart; unsigned lineStart; unsigned lineEnd; unsigned input; /* During header parsing, we use this field to count white space we are * expecting to have after an encoded word. * During bnody parsing, we use the field to count expected content bytes. */ unsigned expect; unsigned rawBodyLength; struct { unsigned int inBody:1; unsigned int isHttp:1; unsigned int complete:1; unsigned int hadErrors:1; unsigned int buggyQuotes:1; unsigned int wantEndOfLine:1; unsigned int excessData:1; unsigned int headersOnly:1; unsigned int encodedWord:1; } flags; NSData *boundary; // Also overloaded to hold excess GSMimeDocument *document; GSMimeParser *child; GSMimeCodingContext *context; NSStringEncoding _defaultEncoding; #endif #if !GS_NONFRAGILE void *_unused; #endif } + (GSMimeDocument*) documentFromData: (NSData*)mimeData; + (GSMimeParser*) mimeParser; - (GSMimeCodingContext*) contextFor: (GSMimeHeader*)info; - (NSMutableData*) data; - (BOOL) decodeData: (NSData*)sData fromRange: (NSRange)aRange intoData: (NSMutableData*)dData withContext: (GSMimeCodingContext*)con; - (NSData*) excess; - (void) expectNoHeaders; - (BOOL) isComplete; - (BOOL) isHttp; - (BOOL) isInBody; - (BOOL) isInHeaders; - (GSMimeDocument*) mimeDocument; - (BOOL) parse: (NSData*)d; /** Parses headers from the supplied data returning YES if more data is * needed before the end of thge headers are reached.
* If body is not NULL and the end of the headers were reached leaving * some unused data, that remaining data is returned.
* NB. The returned data is a reference to part of the original memory * buffer provided in d, so you must copy it if you intend to use it after * modifying or deallocating the original data. */ - (BOOL) parseHeaders: (NSData*)d remaining: (NSData**)body; - (BOOL) parseHeader: (NSString*)aHeader; - (BOOL) scanHeaderBody: (NSScanner*)scanner into: (GSMimeHeader*)info; - (NSString*) scanName: (NSScanner*)scanner; - (BOOL) scanPastSpace: (NSScanner*)scanner; - (NSString*) scanSpecial: (NSScanner*)scanner; - (NSString*) scanToken: (NSScanner*)scanner; - (void) setBuggyQuotes: (BOOL)flag; - (void) setDefaultCharset: (NSString*)aName; - (void) setHeadersOnly; - (void) setIsHttp; @end /** Instances of the GSMimeSerializer class are used to serialise * GSMimeDocument objects to NSMutableData objects, producing data * in a form suitable for sending as an Email over the SMTP protocol * or in other forms. */ GS_EXPORT_CLASS @interface GSMimeSerializer : NSObject { NSUInteger foldAt; /** Fold long lines at this position */ BOOL use8bit; /** Output does not need to be 7bit-safe */ NSString *dataEncoding; /** To make 8bit data 7bit-safe */ NSString *textEncoding; /** To make 8bit text 7bit-safe */ } /** Returns an autorelease GSMimeSerializer configured for transfer * over binary safe protocols with unliumited line lenth). */ + (GSMimeSerializer*) binarySerializer; /** Returns an autorelease GSMimeSerializer configured for Email * to be sent as 7bit data over SMTP. */ + (GSMimeSerializer*) smtp7bitSerializer; /** Returns a copy of the receiver. */ - (id) copyWithZone: (NSZone*)aZone; /** Returns the default content transfer encoding used when 8bit data needs * to be made 7bit safe. This is base64 by default. */ - (NSString*) dataEncoding; /** Encodes the document and returns the resulting raw mime data. */ - (NSMutableData*) encodeDocument: (GSMimeDocument*)document; /** Appends a document part to the supplied data object. */ - (void) encodePart: (GSMimeDocument*)document to: (NSMutableData*)md; /** Returns the maximum line length (excluding the trailing CRLF) to which * we will encode data. See also the -setFoldAt: method. */ - (NSUInteger) foldAt; /** This method allows you to control the position at which lines in * headers and the body data are wrapped.
* RFC 2822 says that the absolute maximum (except for 'binary' content * transfer encoding) is 998 (excluding CRLF), but the recommended * maximum is 78 so we use that by default.
* Setting any ridiculously short value (less than 20) or an excessively * long value (greater than the 998 character limit supported by SMTP) * actually sets a value of zero, meaning that there is no limit. */ - (void) setFoldAt: (NSUInteger)position; /** Sets the content transfer encoding used when 8bit data needs to be sent * in a 7bit safe form.
* Setting a nil/empty encoding reverts to the default (base64).
* Setting an unknown/inapplicable encoding raises an exception. */ - (void) setDataEncoding: (NSString*)encoding; /** Sets the content transfer encoding used when 8bit text needs to be sent * in a 7bit safe form.
* Setting a nil/empty encoding reverts to the default (quoted-printable).
* Setting an unknown/inapplicable encoding raises an exception. */ - (void) setTextEncoding: (NSString*)encoding; /** Sets whether we will allow 8bit data in the output.
* The default is NO (because 8bit data breaks some mail transfer agents). */ - (void) setUse8bit: (BOOL)aFlag; /** Returns the default content transfer encoding used when 8bit text needs * to be made 7bit safe. This is quoted-printable by default. */ - (NSString*) textEncoding; /** Returns YES is we will allow 8bit data in the output, NO if we encode * everything in a 7bit safe form. */ - (BOOL) use8bit; @end /** The error domain for the GSMime system. */ GS_EXPORT NSString* const GSMimeErrorDomain; /** The error codes used in the GSMimeErrorDomain */ typedef enum { GSMimeSMTPAbort, GSMimeSMTPTimeout, GSMimeSMTPCommsEnd, GSMimeSMTPCommsError, GSMimeSMTPServerResponse } GSMimeErrorCode; @class NSError; @class NSStream; @class NSTimer; /** The GSMimeSMTPClient class provides the ability to send EMails * ([GSMimeDocument] instances) via an SMTP server. */ GS_EXPORT_CLASS @interface GSMimeSMTPClient : NSObject { #if GS_NONFRAGILE # if defined(GS_GSMimeSMTPClient_IVARS) @public GS_GSMimeSMTPClient_IVARS; # endif #else @private id _internal; #endif } /** Shut down any message send in progress and abort any queued messages. */ - (void) abort; /** Returns the current delegate. */ - (id) delegate; /** Tries to flush any queued messages to the SMTP server, completing by the * specified limit date.
* If limit is nil then a date in the distant future is used.
* If the queue is emptied in time, this method returns YES, otherwise it * returns NO. */ - (BOOL) flush: (NSDate*)limit; /** Returns the last error encountered, or nil if there is none recorded. */ - (NSError*) lastError; /** Returns the number of messages currently in the queue. */ - (NSUInteger) queueSize; /** Add the message to the queue of emails to be sent by the receiver. */ - (void) send: (GSMimeDocument*)message; /** Add the message to the queue of emails to be sent by the receiver.
* Also adds an envelope ID string to be used to uniquely identify the * message for delivery receipting purposes.
* For this to work, the SMTP gateway being used must support the SMTP * service extension for delivery status notification (RFC 3460). */ - (void) send: (GSMimeDocument*)message envelopeID: (NSString*)envid; /** Set the delegate to receive callback methods indicating when a message * is sent, failed, or removed from the queue unsent. */ - (void) setDelegate: (id)d; /** Set the host for the SMTP server. If this is not set (or is set to nil) * then the GSMimeSMTPClientHost user default is used. If the host is nil * or an empty string then 'localhost' is used. */ - (void) setHostname: (NSString*)s; /** Set the host for the SMTP client to identify itsself to the server. * If this is not set (or is set to nil) then the GSMimeSMTPClientIdentity * user default is used. If the identity is nil or an empty string then * a name of the current host is use. */ - (void) setIdentity: (NSString*)s; /** Sets the maximum number of messages which may remain in the queue. * If this is exceeded then any unsuccessful send attempt results in * excess queued messages discarded as unsent.
* The method returns the previous setting. */ - (NSUInteger) setMaximum: (NSUInteger)m; /** Set the originator for any emails sent by the SMTP client.
* This overrides the value in the 'from' header of an email.
* If this is not set (or is set to nil) then the GSMimeSMTPClientOriginator * user default is used. If the originator is nil or an empty string then * the value in the 'from' header of the email is used. */ - (void) setOriginator: (NSString*)s; /** Set the port for the SMTP server. If this is not set (or is set to nil) * then the GSMimeSMTPClientPort user default is used. If the port is not an * integer in the 1-65535 range, then '25' (the default SMTP port) is used. */ - (void) setPort: (NSString*)s; /** Set the username for authentication to the SMTP server. * If this is not set (or is set to nil) then the GSMimeSMTPClientUsername * user default is used. If the username is nil or an empty string then * authentication is not attempted. */ - (void) setUsername: (NSString*)s; /** returns the receivers current state. */ - (int) state; /** Returns a string describing the receiver's current state */ - (NSString*) stateDesc; @end /** Informal protocol for delegates of the GSMimeSMTPClient class. * The default implementations of these methods do nothing. */ @interface NSObject (GSMimeSMTPClient) - (void) smtpClient: (GSMimeSMTPClient*)client mimeFailed: (GSMimeDocument*)doc; /* Failed to send */ - (void) smtpClient: (GSMimeSMTPClient*)client mimeSent: (GSMimeDocument*)doc; /* Sent successfully */ - (void) smtpClient: (GSMimeSMTPClient*)client mimeUnsent: (GSMimeDocument*)doc; /* Aborted (not sent) */ @end #if defined(__cplusplus) } #endif #endif /* OS_API_VERSION(GS_API_NONE,GS_API_NONE) */ #endif /* __GSMime_h_GNUSTEP_BASE_INCLUDE */