Additions and Changes Made to the Netscape Messaging Access SDK
===============================================================

Additions
---------

base64.h
5/19/00  - Added base64 functions
11/10/00 - Added parameter to rfc822_binary() to control whether we want to
           have CRLF sequences added to the encoded string.

md5.h
10/20/99 - Added basic MD5 algorithm.

base64.c
5/19/00  - Added abse64 functions
11/10/00 - Added parameter to rfc822_binary() to control whether we want to
           have CRLF sequences added to the encoded string.

md5.c
10/20/99 - Added basic MD5 algorithm.

Changes
-------

imap4.h
6/5/99   - Added a new exportable function imap4_clearResponses() to clear any
           pending responses.
10/20/99 - Added functions for authentication implementation.
10/26/00 - Added imap4_isConnected().
11/14/00 - Added imap4_processPLAIN().
3/2/01   - Added imap4_startTLS, imap4_getSocket.
5/16/01  - Added imap4_stopProcessResponses().
10/16/01 - imap4_auth() and smtp_auth() now take a username and password which
           are used as initial client data for the AUTHENTICATE command. Also
           removed all traces of the CDSI macro, since it is no longer useful.
5/27/02  - Added imap4_uidExpunge(). Added boolean flag to imap4_disconnect()
           to allow us to force bytes to be sent out when disconnecting, in
           case the caller doesn't want to wait for a response when shutting
           their connection down.
11/5/02  - Added imap4_sendLocalCommand().
11/15/02 - The fetchdata callback now takes an extra parameter - the data item
           we're getting data for.
12/1/02  - Added imap4_cleanupLocalCommand() and changed the type of the tag
           parameter in imap4_sendLocalCommand().
12/10/02 - Added code to handle X-ORACLE-QUOTA command, and to handle COMMENT
           data item of FETCH command. imap4_append() now takes an extra
           annotations parameter. Added callbacks to handle these 2 commands.
12/12/02 - The IMAP4 library now supports the X-LIST command.
1/10/03  - Added entry points and initial implementations for imap4_xMove,
           imap4_uidXMove, imap4_xDelete, imap4_xOraclePassword,
           imap4_xGetPrefs, imap4_xSetPref. Fixed bug in parseMailboxInfo()
           where we did not properly consider escape characters inside quoted
           strings, so we would end up outputting too many characters.
1/14/03  - Renamed imap4_xSetPrefs() to imap4_xSetPref() to reflect its usage.
1/15/03  - Moved the majority of the logic to parse preferences into
           XGetPrefs() callback so that it can use the services of
           CParenParser. As a consequence we don't need xgetprefsstart() and
           xgetprefsend() callbacks anymore. Also removed parseqstring() since
           it wasn't really doing its job properly.
1/30/03  - Added support for X-RECOVER-MAIL command via imap4_xRecoverMail().
2/5/03   - Updated to reflect new consistent naming schemes of extended Oracle
           commands.
2/27/03  - imap4_cleanupLocalCommand() now no longer takes a parameter for the
           command since it is not needed - we only execute one local command
           at a time.
5/28/03  - imap4_initialize() now takes an extra param that will be used to set
           the chunk size as well as the read and write buffer sizes.
8/14/03  - Added yield callback to sink structure.
3/25/04  - Added initial support for saving and loading custom folder types on
           the mail server. The code might need to be adjusted when the email
           server actually delivers this functionality. For now the folder type
           will only be saved in the current profile.
4/6/04   - Updated the name of the IMAP4 command to set the folder type. It's
	   now called imap4_xOracleSetFolderDesc(). Added extra optional param
           to imap4_append() to allow the message type to be saved to the
           server. Added ability to parse the message type response from the
           server. This data is returned to the client through the
           sink_fetchXMsgType() callback.
4/7/04   - Fixed the way we parse the folder description data from the server
           in parseXOracleList(). Updated the code to reflect that the data is
	   a folder description and not a type.
11/2/04  - Modified code related to displaying the current quota usage to use
           __int64 instead of unsigned longs, so that we can handle quotas
           larger than 4GB.
12/7/04  - Now pass the literal size into imap4_append() rather than
           calculating it by reading the whole input stream.
3/22/05  - Added a new callback that signals when all data for an APPEND
           command has been sent.

imapdata.h
3/2/01   - Added support for STARTTLS command.
5/16/01  - Added field to imap4Client structure.
11/15/02 - The fetchdata callback now takes an extra parameter - the data item
           we're getting data for.
12/10/02 - Added code to handle X-ORACLE-QUOTA command, and to handle COMMENT
           data item of FETCH command. imap4_append() now takes an extra
           annotations parameter. Added callbacks to handle these 2 commands.
12/12/02 - The IMAP4 library now supports the X-LIST command.
1/10/03  - Added entry points and initial implementations for imap4_xMove,
           imap4_uidXMove, imap4_xDelete, imap4_xOraclePassword,
           imap4_xGetPrefs, imap4_xSetPref. Fixed bug in parseMailboxInfo()
           where we did not properly consider escape characters inside quoted
           strings, so we would end up outputting too many characters.
1/15/03  - Moved the majority of the logic to parse preferences into
           XGetPrefs() callback so that it can use the services of
           CParenParser. As a consequence we don't need xgetprefsstart() and
           xgetprefsend() callbacks anymore. Also removed parseqstring()
           since it wasn't really doing its job properly.
1/30/03  - Added support for X-RECOVER-MAIL command via imap4_xRecoverMail().
2/5/03   - Updated to reflect new consistent naming schemes of extended
           Oracle commands.
2/10/03  - Update variables to reflect new Oracle command naming. Fixed
           getExtraLiteral() to handle literals that span multiple lines, and
           that end in CRLF sequences. Previously, we did not get the end of
           the last line of the response. Also optimized the way we looked for
           the end of the literal - instead of reading one line at a time, we
           now read the number of bytes in the literal.
2/10/03  - Updated to reflect correct naming of setpref command.
2/12/03  - Updated the string used for X-ORACLE-MAILRECOVER command.
3/25/04  - Added initial support for saving and loading custom folder types on
           the mail server. The code might need to be adjusted when the email
           server actually delivers this functionality. For now the folder
           type will only be saved in the current profile.
4/6/04   - Updated the name of the IMAP4 command to set the folder type. It's
           now called imap4_xOracleSetFolderDesc(). Added extra optional param
           to imap4_append() to allow the message type to be saved to the
	   server. Added ability to parse the message type response from the
           server. This data is returned to the client through the
           sink_fetchXMsgType() callback.
4/7/04   - Fixed the way we parse the folder description data from the server
           in parseXOracleList(). Updated the code to reflect that the data
           is a folder description and not a type.
11/2/04  - Modified code related to displaying the current quota usage to use
           __int64 instead of unsigned longs, so that we can handle quotas
           larger than 4GB.
3/22/05  - Added a new callback that signals when all data for an APPEND
           command has been sent.

mime.h
3/10/99  - Added a parameter to mime_messagePart_setMessage() to control
           whether to copy memory or not.
6/21/99  - Added exportable functions that enable the caller to decode base64
           and quoted-printable buffers.
8/12/99  - Added mime_decodeModifiedBase64Buffer() and
           mime_encodeModifiedBase64Buffer() functions.
8/26/99  - Added a parameter to mime_decodeModifiedBase64().
5/11/00  - Added mime_messagePart_getBasicPart() to retrieve the attachment
           from unknown message content types.
11/30/00 - Added getDefaultFileExtFromContentType().
12/9/00  - getDefaultFileExtFromContentType() now takes a mime_content_type
           instead of a string.
12/18/00 - Added MIME_ENCODING_UU to mime_encoding_type enumeration.
9/7/01   - Added mime_multiPart_getBasicPart() and parameter to
           mime_message_putByteStream().
9/12/01  - Added mime_message_associateByteStream.
8/20/02  - Started adding support for i18n in mail messages. Fixed access of
           hexmap structure for large char values. We need to treat the chars
           as unsigned chars to ensure correct access into the array. Modified
           mime_bufEncodeQ(), mime_bufEncodeB64(), and
           mime_encodeHeaderString() to allow the user to pass in how many
           bytes they can store in the output buffer.
12/10/02 - We want to export mime_header_clone() so that it can be called from
           outside the library.

mime_internal.h
4/29/99  - Added a data file name field to the mime_basicPart_internal
           structure so that we can delete the file associated with the
		         pTheDataStream field if need be.
5/11/00  - Added field to mime_messagePart_internal structure to handle
           unknown message content subtypes.
9/7/01   - Added mime_basicPart * field to mime_multiPart_internal_t.
9/12/01  - Added pInputStream field to mime_message_internal.

mimeparser.h
11/29/00 - Added stristr().

mimeparser_internal.h
4/29/99  - Replaced the message data vector field with a message data output
           stream in the mimeParser structure.
9/7/01   - Added boolean field to mimeParser_t.
5/12/04  - Added code to handle lines that are longer than 1024 characters.
           Very long header lines and body lines are now handled.
4/7/05   - Added code to stop a buffer overrun when the content-type header
           field is very long. Added a buffer size parameter to
           mimeParser_nGetContentType() to make sure we don't overrun the
           buffer.
4/8/05   - Updated parameter in mimeParser_nGetContentType() to reflect that
           it needs to be the buffer length, rather than the buffer size. The
           original fix was still crashing, but only in release. This stops
           the crash.

nsio.h
3/23/04  - Added void * to the IO structure so that we can pass some context
           into the IO callback functions.

nsmail.h
5/29/00  - Added logon error
3/2/01   - Added NSMAIL_ERR_TLS_INIT.
4/21/02  - Added NSMAIL_ERR_TLS_BADVERSION to detect when the SSL version
           needed by the server doesn't match what we are trying to connect
           with.
5/3/02   - Renamed NSMAIL_ERR_TLS_BADVERSION to NSMAIL_ERR_TLS_BADMETHOD to
           be more consistent with the nomenclature used elsewhere.
12/1/02  - IO_read(), IO_readLine(), IO_readDLine() now make a callback call
           (if it's registered) so that the client can know what data is coming
           from the server. Also updated functions that set and reset the io
           functions to reflect the new function pointer.
3/23/04  - Added void * to the IO structure and nsmail_io_fns structure so
           that we can pass some context into the IO callback functions.

nssocket.h
3/23/04  - Added void * to the IO structure and nsmail_io_fns structure so
           that we can pass some context into the IO callback functions.

nsstream.h
12/7/04  - Added yield callback function to the file_outputStream_tracker
           structure that can be called when generating output streams. This
           function pointer can be passed in via file_outputStream_create().
smtp.h
5/19/00  - Added the auth, LOGIN and CRAMMD5
11/1/00  - Added initial support for AUTH PLAIN mechanism. Added
           smtp_processPLAIN().
3/2/01   - Added smtp_startTLS, smtp_getSocket.
10/16/01 - imap4_auth() and smtp_auth() now take a username and password
           which are used as initial client data for the AUTHENTICATE
           command. Also removed all traces of the CDSI macro, since it is no
           longer useful.
5/29/03  - smtp_initialize() now takes an extra param that will be used to set
           the chunk size as well as the read and write buffer sizes.
8/14/03  - Added yield callback to sink structure.

smtppriv.h
5/19/00  - Added the Auth Response
5/29/00  - ADDED AUTH END
6/12/00  - removed AuthEnd since it had no more use
3/2/01   - Added support for STARTTLS command.

util.h
8/12/99  - Added decodeModifiedBase64() function.
8/26/99  - Added decodeQPHeader() to handle RFC2047 style quoted printable.
3/19/01  - Changed definition of BASE64_NOFIT and BASE64_SOMELEFTto make them
           unique error codes.
10/16/01 - Added generatePlainClientData().
7/14/03  - Added code to handle case where quoted-printable encoded text ends
           line with only LF instead of CRLF. Also improved generic handling
           of bad encoded byte sequences - now we print out the 2 bytes
	   following the '=' instead of printing out NUL chars (and thereby
           stopping the buffer). nConvertHexToDec() now returns an errorcode,
           and takes an out param for the decoded byte.
4/6/05   - Added code to fix Bug 4287596. This bug was happening because we
	   were not gracefully handling badly encoded base64 streams. We
           would decode the trailing byte(s) if the encoded stream suggested
           there were further bytes. This is because the functionality to
           decode base64 streams used the return value both for the number of
           bytes decoded and to return error codes. T solve this, an extra
           parameter was added to return the number of decoded bytes. This is
           all we really care about in most cases, as we want to decode as
           many bytes as possible.

imap4.c
3/12/99  - Commented out code that was causing the app to crash when it
           encountered very long header fields. The individual header fields
           do not need to be parsed as of right now.
3/29/99  - Increased the size of memory buffers by 1 to take the NULL
           character into consideration when doing reads.
4/1/99   - Added code to parseMailboxInfo() so that the SDK no longer chokes
           on folder names that are string literals.
4/6/99   - Did more cleanup of memory buffer sizes so that now both malloc()
           and memset() calls are fixed.
4/20/99  - Added getExtraLiteral() function that retrieves the next line from
           the server if we come across the start of a string literal. Added
           code to handle parsing string literals when parsing the
           BODYSTRUCTURE response as well as all non-FETCH responses.
5/6/99   - Added code to parseFetch() to handle fetching several body parts
           at the same time. Added a new exportable function
           imap4_clearResponses().
5/21/99  - parseMailboxInfo() can now handle parsing folder names that are
           literals.
7/8/99   - Updated resolveFetchDataItem() so that it BODY responses are
           handled the same as BODYSTRUCTURE responses.
7/15/99  - Added a check in parseStatus() to see if the folder name is
           actually a string literal.
8/17/99  - Fixed a parsing problem in parseAcl().
8/23/99  - Updated ACL functions so that parse quoted strings, and string
           literals properly.
8/25/99  - Fixed code in parseMyRights() and parseListRights() to handle end
           of line parsing.
10/20/99 - Added functions for authentication implementation.
11/3/99  - Fixed parseStatus() to handle folder names with '(' characters in
           them.
2/4/00   - Added code to parseNoBad() to handle getting a '*' at the beginning
           of the response line. Added code to parseMailboxInfo() to handle
           getting a NIL hierarchy delimiter.
5/19/00  - Put the rfc functions in base64.c. Removed some none functional
           functions.
9/8/00   - Fixed matchBrackets() so that it now ignores parentheses that are
           inside of quotes.
10/23/00 - getExtraLiteral() now takes an extra parameter - the number of
           chars in the literal. We now get at least that many characters in
           getExtraLiteral(). This fixes a bug that was caused by literals that
           contained embedded CRLF sequences. Callers of getExtraLiteral() now
           need to calculate the number of chars in the literal as well.
10/26/00 - Added imap4_isConnected(). It checks to see if the socket is still
           valid.
10/27/00 - Improved imap4_isConnected() to recognize the case where the server
           has disconnected us because of inactivity.
11/10/00 - Added parameter to rfc822_binary() to control whether we want to
           have CRLF sequences added to the encoded string.
11/14/00 - Added imap4_processPLAIN(), which knows how to properly handle the
           challenge and response for the AUTHENTICATE PLAIN command.
11/24/00 - Added code to matchBrackets() to ignore literal strings when trying
           to find the correct right parentheses. This stops us from having
           forever looking for string literals that do not exist.
11/27/00 - Added code to resolveFetchDataItem() to better recognize the case
           where we are asking for header info, so that in_pimap4->bReadHeader
           is set to TRUE. Although we don't currently care about the value of
           this variable, we might at some point want to use it.
12/2/00  - Added code to make imap4_isConnected() more robust. We now check
           for a SOCKET_ERROR return value from select(). Combined code to deal
           with SOCKET_ERROR return values from select() and recv().
3/2/01   - Added workaround for compiler optimization bug in
           imap4_processCRAMMD5(). Added imap4_startTLS, imap4_getSocket for
           STARTTLS support.
4/19/01  - Now send a blank authorize-id for PLAIN authentication. This is
           allowed by RFC2595 and this allows to login to Netscape 4.15 servers
           that do not like us sending both and authorize-id and authenticate-
           id. Also fixed a silly typo in smtp_startTLS().
5/3/01   - Fixed bug in parseFetch(). When parsing a BODYSTRUCTURE response
           from the server, we were calculating the beginning of the response
           under the assumption that BODYSTRUCTURE would be in the first block
           of bytes read from the server.
5/10/01  - We now handle getting back an empty list of ACLs in parseAcl(). We
           used to return a parse error.
5/16/01  - Added field to imap4Client structure that keeps track of when we
           want to ignore responses from the server. We check for this boolean
           being true in imap4_processResponses() and parseFetch(). Added check
           in imap4_isConnected() to only bother checking the state of the
           socket if we are actually connected. If we aren't connected, we
           haven't initialized the socket properly. Added
           imap4_stopProcessResponses() which sets the field in the
           imap4Client structure.
7/18/01  - Added check to see if we want to ignore the server response to the
           loop in parseFetch() for parsing the message body. This dramatically
           improves the responsiveness of cancelling (or skipping) when
           downloading an email with a large attachment.
8/14/01  - Removed code in parseEndingLine() and parseBye() that was freeing
           memory that was never allocated. This code caused a crash.
10/12/01 - Added local function RemoveAllPendingCommands() to take care of
           freeing items from the pending command list. It is now called in
           imap4_free(), imap4_disconnect(), parseBye(). The pCommand field of
           the pending command list needs to be freed whenever an element is
           removed from the list. As a result we need to allocate memory for
           that field in imap4_connect(). Fixed memory leak in parseMyrights()
           and parseListrights().
10/16/01 - imap4_auth() now takes a username and password which are used as
           initial client data for the AUTHENTICATE command. Also removed all
           traces of the CDSI macro, since it is no longer useful.
           imap4_processPLAIN() now calls generatePlainClientData() to generate
           the data to send to the server. imap4_auth() now calls
           generatePlainClientData() as well if we are trying to authenticate
           using plain and both username and password were passed in. We are
           allowed to send initial client data when using PLAIN without waiting
           for an intermediate server response.
12/6/01  - parseMailboxInfo() now always passes an unquoted folder path to the
           callback function. Now the callback function doesn't need to care
           about the low-level IMAP details of how folder names need to be sent
           across the wire. Also, we now remove quoted characters (e.g. '\\')
           from the strings returned. This lets us handle the Domino IMAP4
           server in a better way - it has "\\" as its hierarchy delimiter.
5/27/02  - Added imap4_uidExpunge(). Added boolean flag to imap4_disconnect()
           to allow us to force bytes to be sent out when disconnecting, in
           case the caller doesn't want to wait for a response when shutting
           their connection down.
7/18/02  - Added code to parseFetch() to handle parsing body responses that
           were not sent with a string literal. RFC2060 states that the string
           for this response could also be either a simple or quoted string. We
           came across this situation when trying to open an empty message on
           the Oracle IMAP4 server. We were returning a parse error that
           resulted in an infinite loop when trying to open a newmail that was
           essentially empty. Now we don't return an error and parse as much
           info as is available.
7/24/02  - Fixed the way we calculate the beginning and end of the quoted
           string in parseFetch(). We used to call sink_fetchData() with a
           string length of -1. This fixes a crash when trying to open an
           embedded message on the Oracle webmail IMAP4 server that got
           returned to us as being empty.
7/24/02  - Changed code in parseFetch() so that it executes the way it used to
           in most cases - only in exceptional cases does it try to do more
           complicated parsing. This fixes a problem we were getting opening
           signed mail (because the response contained a list of header fields
           too, and we weren't prepared for that extra info). So now we only do
           the extra parsing work when the string returned isn't a literal.
           Right now, the only response we get like that is an empty string
           response from the Oracle server, but I added code that should work
           with more complicated responses, too.
11/5/02  - Added imap4_sendLocalCommand(), which lets a caller simulate passing
           a command to the IMAP4 server without actually doing so. This allows
           a client to have a client-side cache for frequently requested data.
11/15/02 - The fetchdata callback now takes an extra parameter - the data item
           we're getting data for.
12/1/02  - Added imap4_cleanupLocalCommand() and changed the type of the tag
           parameter in imap4_sendLocalCommand(). Added code to parseFetch() to
           call the read callback function, if it's registered. This lets us
           associate data with a particular message, by tracking the fetchstart
           and fetchend callbacks too. imap4_cleanupLocalCommand() looks for
           the local command in the command list and removes it. We need to do
           this because we no longer cache the tagged response from the server,
           and so we need to manually remove the local command from the list.
12/10/02 - Added code to handle X-ORACLE-QUOTA command, and to handle COMMENT
           data item of FETCH command. imap4_append() now takes an extra
           annotations parameter. Added callbacks to handle these 2 commands.
12/12/02 - The IMAP4 library now supports the X-LIST command. The callback
           function returns the extra info from this command: uidvalidity,
           uidnext, last-modified-time for each folder.
12/18/02 - Fixed parsing bug when parsing a RFC822TEXT data block that is
           encoded in a quoted string, and that is following by another data
           block that is encoded in a literal. We were looking for a '{' and
           finding the literal block from the second data block.
1/10/03  - Added entry points and initial implementations for imap4_xMove,
           imap4_uidXMove, imap4_xDelete, imap4_xOraclePassword,
           imap4_xGetPrefs, imap4_xSetPref. Fixed bug in parseMailboxInfo()
           where we did not properly consider escape characters inside quoted
           strings, so we would end up outputting too many characters.
1/15/03  - Moved the majority of the logic to parse preferences into
           XGetPrefs() callback so that it can use the services of
           CParenParser. As a consequence we don't need xgetprefsstart() and
           xgetprefsend() callbacks anymore. Also removed parseqstring() since
           it wasn't really doing its job properly.
1/30/03  - Added support for X-RECOVER-MAIL command via imap4_xRecoverMail().
2/5/03   - Updated to reflect new consistent naming schemes of extended Oracle
           commands.
2/10/03  - Update variables to reflect new Oracle command naming. Fixed
           getExtraLiteral() to handle literals that span multiple lines, and
           that end in CRLF sequences. Previously, we did not get the end of
           the last line of the response. Also optimized the way we looked for
           the end of the literal - instead of reading one line at a time, we
           now read the number of bytes in the literal.
2/19/03  - Added 2 new errors that mean we've been disconnected from the server
           in imap4_isConnected().
2/25/03  - Fixed broken ParseFetch() logic when trying to parse a response that
           contained BODY[] section info. We were finding the literal properly,
           and this was messing up all subsequent interaction with the IMAP4
           server. Now we recognize when the dataitem in question has a section
           and we skip directly to the end of the section before trying to find
           the literal. Due to this change, we don't need to look for a list of
           header fields later on in ParseFetch().
2/27/03  - imap4_sendLocalCommand() now makes sure the bConnected and
           pIO->socket fields are set to values that will not cause us
           problems. Since the connection passed into this function is now used
           only for local commands, we can reset these fields without worrying
           about the potential side-effects.imap4_cleanupLocalCommand() now no
           longer takes a parameter for the command since it is not needed - we
           only execute one local command at a time.
           imap4_cleanupLocalCommand() now resets the pIO->readBufferSize to 0
           on successful completion of parseEndingLine(). This is to work
           around the case where there is extra info in the local connection
           that we want to make sure isn't parsed.
5/28/03  - imap4_initialize() now takes an extra param that will be used to set
           the chunk size as well as the read and write buffer sizes.
8/14/03  - Added yield callback to sink structure. It is called (if it is non-
           NULL) inside parsePlus() so that large emails that are being
           appended to the server don't cause the app to block.
9/5/03   - Added code to parseXOracleList() and matchBrackets() to handle
	   quoted strings that contain backslashes. We need to ignore escaped
           " characters when looking for the quote character. This fixes Bug
           3104734.
3/23/04  - Added void * to the IO structure and nsmail_io_fns structure so
           that we can pass some context into the IO callback functions. The
           IO context can now be get and set via imap4_set_option() and
           imap4_get_option().
3/25/04  - Added initial support for saving and loading custom folder types on
           the mail server. The code might need to be adjusted when the email
           server actually delivers this functionality. For now the folder
	   type will only be saved in the current profile.
4/6/04   - Updated the name of the IMAP4 command to set the folder type. It's
           now called imap4_xOracleSetFolderDesc(). Added extra optional param
           to imap4_append() to allow the message type to be saved to the
           server. Added ability to parse the message type response from the
           server. This data is returned to the client through the
           sink_fetchXMsgType() callback.
4/7/04   - Fixed the way we parse the folder description data from the server
           in parseXOracleList(). Updated the code to reflect that the data
           is a folder description and not a type.
11/2/04  - Modified code related to displaying the current quota usage to use
           __int64 instead of unsigned longs, so that we can handle quotas
           larger than 4GB.
12/7/04  - Now pass the literal size into imap4_append() rather than
           calculating it by reading the whole input stream.
1/10/05  - Call to IO_read() in parseFetch() did not check error code
           returned, and this resulted in an infinite loop when there were
	   network problems during this call.
3/22/05  - Added a new callback that signals when all data for an APPEND
           command has been sent.


mime.c
4/6/99   - Previous changes made to this file seem to have been rolledback.
           Did cleanup of memory buffer sizes so that now both malloc() and
           memset() calls are fixed. Added an extra parameter to
           mime_messagePart_setMessage() to handle shallow copying.
4/7/99   - Added a fix to prevent a buffer overrun when dealing with very long
           header field values.
4/29/99  - Made changes to mime_decodeBase64() to better handle the last few
           bytes of a stream we're trying to decode.
6/21/99  - Added exportable functions that enable the caller to decode base64
           and quoted-printable buffers. mime_decodeQP() now calls decodeQP().
8/12/99  - Added mime_decodeModifiedBase64Buffer(),
           mime_encodeModifiedBase64Buffer() and mime_bufEncodeModifiedB64()
           functions. Fixed code to prevent warnings.
8/26/99  - Added a parameter to mime_decodeModifiedBase64(). Now all of the
           encoding and decoding functions return an nsResult.
8/30/99  - Fixed encodeHeaderString().
9/8/99   - Added code to getFileMIMEType() to handle Excel files.
9/9/99   - Update getFileMIMEType() to handle RTF and to return the correct
           type for excel documents.
9/10/99  - In decodeQP(), increated the size of achWriteBuffer by 1 to prevent
           croak!!!
11/3/99  - Added a fix to mime_decodeQP() to handle the case where a read
           buffer doesn't have all of the data required in its buffer (it
           needs bytes that will only be in the next read buffer).
3/7/00   - Modified mime_decodeQP() so that it only copies CRLF sequences, not
           arbitrary CR of LF characters. Modified getFileMIMEType() so that
           the content type parameter is no longer hard-coded to us-ascii, and
           the encoding used is quoted printable instead of 7bit (i.e. no
           encoding). This should allow attachments with foreign characters to
           be encoded properly.
3/23/00  - mime_basicPart_setDataStream() now handles zero length streams
           better when we only to save a reference to the stream.
5/11/00  - Now return MIME_ERR_NOT_FOUND in mime_messagePart_getMessage() if
           there's no embedded message. Added mime_messagePart_getBasicPart()
           for unknown message content subtypes.
11/14/00 - Handle ics extension by setting subtype to calendar.
11/30/00 - Added getDefaultFileExtFromContentType(), which gets the default
           extension for a MIME content type (e.g. text/plain -> "txt")
12/9/00  - getDefaultFileExtFromContentType() now takes a mime_content_type
           instead of a string.
12/15/00 - Fixed a bug in mime_decodeQP(). We weren't handling the case where
           there were stray bytes at the end of a read buffer properly. We now
           no longer lose those stray bytes.
12/18/00 - Fixed warning in getDefaultFileExtFromContentType().
3/16/01  - Now ignore BASE64_SOMELEFT error code coming out of decodeBase64()
           in mime_decodeBase64Buffer(), so that we don't return an error
           when there are stray bytes at the end of a buffer that we could
           ignore.
6/5/01   - Added support for MS Powerpoint and MS Access content types to
           getFileMIMEType() and getDefaultFileExtFromContentType().
9/7/01   - Added code to mime_multiPart_putByteStream() to ensure that we
           don't output the boundary parameter in the Content-Type field twice.
           Added mime_multiPart_getBasicPart(). Added parameter to
           mime_message_putByteStream() so that we can output only top-level
           headers.
9/11/01  - Removed stray fprintf() call that was being output when running
           exmigrate.
9/12/01  - Added mime_message_associateByteStream, which associates an already
           built byte stream with a mime_message. This stream is now used if
           present when mime_message_putByteStream() is called.
10/12/01 - In mime_basicPart_putByteStream(), we need to duplicate the memory
           before passing it into buf_instream_create() so that when we free it
           we don't free the szMessageBody field of mime_basicPart. Also fixed
           a memory leak to do with the buf_instream.
10/12/01 - Added code to mime_basicPart_deleteData() to properly free the
           pTheDataStream's memory. This function is currently not called by
           anyone.
12/7/01  - Modified mime_decodeQP() to handle .vcf file
4/28/02  - Added code to algorithms that read from a stream into a buffer to
           ensure that we don't try to read data into the buffer beyond the
           bounds of the buffer's memory. We do this by making sure that if we
           right at the end of the stream, that we only try to read however
           many bytes are left to be read - not MIME_BUFSIZE bytes. Otherwise
           we could crash.
8/20/02  - Started adding support for i18n in mail messages. Fixed access of
           hexmap structure for large char values. We need to treat the chars
           as unsigned chars to ensure correct access into the array. Modified
           mime_bufEncodeQ(), mime_bufEncodeB64(), and
           mime_encodeHeaderString() to allow the user to pass in how many
           bytes they can store in the output buffer.
2/18/03  - Fixed bug in mime_bufEncodeB64() where did not encode the last 3
           byte sequence of the buffer, even though there's just enough space
           in the output buffer.
7/14/03  - Added code to handle case where quoted-printable encoded text ends
           line with only LF instead of CRLF. Also improved generic handling
           of bad encoded byte sequences - now we print out the 2 bytes
           following the '=' instead of printing out NUL chars (and thereby
           stopping the buffer).
10/28/04 - Fixed several bugs related to multipart/signed emails. We did not
           handle mime_message_putByteStream() being called twice for the
           same mime_message for multipart/signed emails. The second it was
           called, we would output nothing. This is because the input stream
           wasn't being rewound to the beginning. We do so now. In
           nNewMessageStructure(), we now always use the content_type_params
	   that have been parsed - before they were being discarded if they
           happened to start with "boundary". This didn't handle the case
           where some other parameter was first. Also in
           mimeParser_parseLine(), we now make sure that the
           pMessageDataOutStream is reset to NULL if we encounter a start
           or end boundary. Before we were not prepending the necessary
           multipart/signed header when extra unexpected blank lines were
           present between multiparts.
12/3/04  - Modified getDefaultFileExtFromContentType() so that we now return
           an extension for message content types. If the subtype is rfc822,
           we return .eml. Otherwise, we return .txt, so that we can let the
           user open unknown message types as simple text files.
1/20/05  - Fixed a bug in mime_decodeQP() where CRLF sequences would be lost
           if they staddled a buffer block boundary.
3/8/05   - Modified mime_decodeBase64() so that we if we no longer return an
           error if we successfully decode at least some data.
4/6/05   - Added code to fix Bug 4287596. This bug was happening because we
           were not gracefully handling badly encoded base64 streams. We
           would decode the trailing byte(s) if the encoded stream suggested
           there were further bytes. This is because the functionality to
           decode base64 streams used the return value both for the number
           of bytes decoded and to return error codes. T solve this, an
           extra parameter was added to return the number of decoded bytes.
           This is all we really care about in most cases, as we want to
           decode as many bytes as possible.


mime_internal.c
3/12/99  - mime_header_apend() now handles values that are more than 512 bytes
           long.
4/13/99  - Added code to mime_basicPart_internal_clone() to handle cloning a
           basic part with a data stream set. It now reads from the stream and
           fills a buffer. This needs to be improved in the case of large
           files.
4/23/99  - In mime_header_new()  when szName == NULL. If szValue == NULL
           however assume empty string.
4/29/99  - Added code to initialize and free the pDataFileName field of the
           mime_basicPart_internal structure.
5/11/99  - Added a fix to mime_header_new() to prevent a crash. Now
           mime_header_add() calls mime_header_new().
5/11/00  - Added handling for extra field in mime_messagePart_internal_t
           structure.
12/13/00 - Now return MIME_ERR_MAX_NESTED_PARTS_REACHED in
           mime_multiPart_addPart_clonable() when we try to add more parts that
           is allowed to a multipart. This stops a crash when downloading a
           message with "too many" multipart parts.
12/18/00 - Added code to recognize "x-uuencode" to
           mime_translateMimeEncodingType().
1/20/01  - We do not want to add header fields whose name or value is empty in
           mime_header_add(). This stops a crash when cloning the extra_headers
           field.
9/7/01   - Added mime_basicPart * field to mime_multiPart_internal_t. So added
           code to mime_multiPart_internal_new(),
           mime_multiPart_internal_free(), mime_multiPart_internal_clone() to
           manage it.
9/12/01  - Added pInputStream field to mime_message_internal, and added code to
           mime_message_internal_new(), mime_message_internal_free() and
           mime_message_internal_clone() to support it.
10/12/01 - Now free the memory allocated for the pTheDataStream field in
           mime_basicPart_internal_free(). This could cause problems if the
           caller tries to free the same stream again.
4/28/02  - In mime_basicPart_internal_clone(), added check to optimize how we
           deal with very large text parts. If the size of the stream is above
           a certain threshold, we create a stream - otherwise we fall back on
           the old code of just allocating a buffer. Added code to algorithms
           that read from a stream into a buffer to ensure that we don't try to
           read data into the buffer beyond the bounds of the buffer's memory.
           We do this by making sure that if we right at the end of the stream,
           that we only try to read however many bytes are left to be read -
           not MIME_BUFSIZE bytes. Otherwise we could crash. Added code to all
           internal clone functions to stop allocated memory being overwritten
           and thereby creating a memory leak.
9/5/03   - Added code to mime_header_apend() to handle the case where we're
           trying to append to a header that couldn't be found. Rather than
           return an error, we add it. This solves the problem where a folded
           header line contains only CRLF (Bug 3121863).

mimeparser.c
1/14/99  - Fixed a bug in decodeDataBuffer() that was causing problems with
           very long lines in message bodies.
3/10/99  - Added a fix to mimeParser_parseMimeMessage() that stops it from
           choking on messages with lines over 1024 characters long.
3/11/99  - Fixed code that was assigning static text strings that were later
           being changed. Now use strdup() instead.
3/24/99  - Now zero out a buffer that had garbage at the end of it sometimes
           in mimeParser_parseMimeMessage().
3/25/99  - Now only zero out of the buffer in mimeParser_parseMimeMessage() at
           the beginning of the call, not in the middle of the loop.
3/29/99  - Increased the size of memory buffers by 1 to take the NULL
           character into consideration when doing reads.
4/6/99   - Did cleanup of memory buffer sizes so that now both malloc() and
           memset() calls are fixed.
4/7/99   - Added a fix to prevent a buffer overrun when dealing with very long
           header field values in mimeParser_parseLine(). Added code to deal
           with long lines in mimeParser_parseMimeMessage().
4/23/99  - Fixed a memory leak in addHeader().
4/29/99  - Added code to store the encoded and decoded message data bytes in
           streams as opposed to memory. This dramatically speeds up parsing
           long attachments. Made a correction to a fix dealing with mime
           headers. Added a fix to properly calculate the offset in
           mimeParser_parseMimeMessage(). Fixed more memory leaks.
5/20/99  - Added code to fix a parse error that caused problems with parsing
           several embedded message attachments at once.
6/23/99  - Now add the proper CRLF to folded mime header field values in
           mimeParse_parseLine().
8/17/99  - Fixed a bug that was causing the preamble to show up as part of the
           message body for deeply nested embedded messages.
10/18/99 - Commented out some code that resulted in a '\n\r\n' sequence being
           appended to every line that is parsed in a quoted printable message
           body. Now append '\r\n' to each line instead.
4/21/00  - Fixed a bug in mimeParser_parseLine() that was not outputting lines
           of message data that were empty (i.e. only had \r\n).
5/4/00   - Added code to mimeDynamicParser_free() and decodeDataBuffer() to
           better clean up the pMessageDataOutStream field of the mimeParser_t
           structure.
5/11/00  - Added handling for unknown message content subtypes, especially
           message/delivery-status and message/disposition-notification.
5/12/00  - Fixed mimeParser_parseForBoundary() so that it handles long
           boundaries properly. Now as many bytes as possible are stored, up
           to 70 (as per RFC 2046).
10/20/00 - Commented out some lines that were causing emails not to show up if
           the content- headers were ordered badly (i.e.
           Content-Transfer-Encoding before Content-Type).
11/29/00 - Added stristr(), which we now call in mimeParser_parseForBoundary()
           since we need to be able handle when "boundary" is not always in
           lowercase. stristr() does a case-insensitive substring search.
12/7/00  - Added code to properly set the content type in
           nNewMessageStructure(). It was getting lost.
12/18/00 - Fixed warnings in mimeParser_setData() and stristr().
12/19/00 - Added code to mimeParser_parseLine() to add MIME header fields to
           the parent message part as well as the in usual message part. This
           fixes a bug where we were not able to display "Content-" header
           fields when trying to show all Internet headers.
1/15/01  - Commented out code in nNewMessageStructure() so that we do not
           choke on message/partial content type. Put fix in call to addHeader()
           in mimeParser_parseLine() so that we do not add headers to a queue in
           all cases. Now return MIME_CONTENT_APPLICATION as default content
           type when we come accross an unknown unknown media type in
           mimeParser_nGetContentType().
1/20/01  - Rearranged code again in mimeParser_parseLine() to do with adding
           Content-xxx header fields to the list as well. Condit
           still missing around the call to addHeader() that could 
           change the logic path, which we do not want. Now ther
           simple added call to addHeader() when we're d
           "Content-xxx" headers.
2/20/01  - Fixed a bug in mimeParser_parseMimeMessage() in the case where we
           did not have enough bytes at the end of input buffer to determine
           whether we were dealing with a wrapped line.
3/26/01  - Fixed buffer overrun bug in mimeParser_parseForBoundary() that
           would happen when the boundary string in an email was longer than
           the RFC allows. We would write a NULL terminating character in
           memory not associated with a buffer. Fixed it by allocating a new
           buffer to copy the long boundary string into in the case when the
           buffer would be too long for our static character array.
9/7/01   - Added boolean field to mimeParser_t to control whether we should be
           treating the data that is being parsed as opaque. It's set to TRUE
           when parsing multipart/signed parts. When we parsing opaque data,
           we cache the data in a basic part that was added to multipart
           structure. Added code to correctly format that stream for
           multipart/signed parts - we need MIME header fields at the beginning
           of the stream and the trailing boundary at the end of it. Fixed code
           in mimeParser_parseLine() to put CRLF at the end of the preamble
           lines as required by the RFC. Also added code to
           mimeParser_parseMimeMessage() to ensure we put CRLF when folding
           header fields. mimeParser_checkForLineType() now ignores start
           boundaries when we are parsing opaque data - it only cares about
           trailing boundaries.
1/29/02  - Improved the logic of the MIME parser so that we detect when we the
           header fields are finished (i.e. when we come across one blank line
           in the message). This fixes the case where we were treating all of
           the lines of a message as if they were header fields (because they
           contain ':' characters in them).
4/14/02  - Fixed stupid mistake when building the opaque file for a
           multipart/signed part. We used to add the parameters for the
           Content-Type field to the MIME-Version instead. It w
           matter of putting the two fields in the wrong order. Thi
           #1211.
4/28/02  - Added code to prevent small memory leak in nNewMessageStructure().
7/16/02  - Added fix to stop a crash when trying to parse a message where the
           first line of the message is a header field that starts with a space.
           By definition header lines in a message cannot start with a space
           unless it is a folder header field (see RFC2822 for details). This
           fix is being done for the Oracle Email server.
3/19/03  - Added code to support parsing message/external-body parts. We treat
           such parts as unknown message parts, and we render them as file
           attachments (like application/octet-stream).
4/29/03  - Added support for parsing multipart/digest messages. Parts under
           this are by default rfc822 messages. Changed code to recognize the
           start of headers if we haven't gotten any headers yet, and we have
           come across 1 or 2 blank lines - this lets us handle the case where
           there are no headers for a nested part.
5/12/04  - Added code to handle lines that are longer than 1024 characters.
           Very long header lines and body lines are now handled.
6/9/04   - Fixed bug where we messages without a content-type header field
           would not get parsed properly when the whole message was parsed at
           once. Now when message data is encountered and we haven't seen a
           content-type header field, a default content-type of
           will be assumed. This will mean that the whole messag
           show up as the body of the message.
6/23/04  - Fixed boundary case bug when parsing very long lines. When looking
           for the last space character in a line, we didn't handle the case
           where the last space would be the first character of the buffer.
           This was resulting in an infinite loop because we were not
           updating loop variables properly. Now we need handle this case in
           the same way we do when we can't find a space character in the
           buffer - we parse the whole buffer as a line. This fixes Bug
           3717640.
10/13/04 - Fixed a bug in mimeParser_parseMimeMessage() that could lead to a
	   crash when dealing with very long header lines when the data is
	   passed in via a buffer rather than a stream. We now ensure that
           the left over buffer is zeroed out also when we are passed a
           buffer. Also we now make sure that we add a leading space when we
           come across a very long line that only has one space, the first
           character. We were already handling the case where the space
           wasn't the first character. This fixes an issue found when
           investigating Bug 3920779.
10/28/04 - Fixed several bugs related to multipart/signed emails. We did
           not handle mime_message_putByteStream() being called twice for
           the same mime_message for multipart/signed emails. The second
           it was called, we would output nothing. This is because the
	   input stream wasn't being rewound to the beginning. We do so now.
           In nNewMessageStructure(), we now always use the
           content_type_params that have been parsed - before they were
           being discarded if they happened to start with "boundary". This
           didn't handle the case where some other parameter was first.
           Also in mimeParser_parseLine(), we now make sure that the
           pMessageDataOutStream is reset to NULL if we encounter a start
           or end boundary. Before we were not prepending the necessary
           multipart/signed header when extra unexpected blank lines
           were present between multiparts.
11/29/04 - In mimeParser_parseLine() we only want to hard-code the content-
           type to be text/plain if if this is not an unknown message part,
	   where we've decided to treat it as a basic part (actually
           application/octet-stream). This stops us from losing data when
           parsing parts with unknown message subtypes.
12/3/04  - Rather that treat unknown unknown message types as
           application/octet-stream, we now treat them as text/plain, so
           that the user can open them as simple text files.
3/8/05   - Added extra check in decodeDataBuffer() to make sure that there
           is a data stream available to decode from.
4/7/05   - Added code to stop a buffer overrun when the content-type header
           field is very long. Added a buffer size parameter to
           mimeParser_nGetContentType() to make sure we don't overrun the
           buffer.
4/8/05   - Updated parameter in mimeParser_nGetContentType() to reflect that
           it needs to be the buffer length, rather than the buffer size.
           The original fix was still crashing, but only in release. This
           stops the crash.

nsio.c
12/1/02  - IO_read(), IO_readLine(), IO_readDLine() now make a callback call
           (if it's registered) so that the client can know what data is
           coming from the server. Also updated functions that set and reset
           the io functions to reflect the new function pointer.
3/23/04  - Added void * to the IO structure and nsmail_io_fns structure so
           that we can pass some context into the IO callback functions.

nssocket.c
10/27/00 - We only call WSAStartup() and WSACleanup() if DISABLE_NSSOCK_INIT
           is not defined. This is because we now call these functions when
           cstmsg32.dll is loaded and unloaded.
3/23/04  - Added void * to the IO structure and nsmail_io_fns structure so
           that we can pass some context into the IO callback functions.

nsstream.c
12/7/04  - Added yield callback function to the file_outputStream_tracker
           structure that can be called when generating output streams.
           This function pointer can be passed in via
           file_outputStream_create().

smtp.c
5/19/00  - Added the Auth Response
5/19/00  - Added the Auth with LOGIN mechanism (Cram-Md5 not tested)
5/19/00  - Auth and login working
6/12/00  - Changed how the processResponse from the authentication is made.
           Now, an Auth Element is put in the pending list at the end of
      	   smtp_auth. At the begining of the smtp_processLogin, we check the
           pending list for Auth and return an error if it isn't. But the auth
           element is not removed from the list. It will be used in the
           smtp_processResponses call afterwards. AUTHEND is not put in the
           list and may be eliminated.
10/31/00 - Cleaned up smtp_processCRAMMD5() so that it actually works, and to
           properly check for error conditions. Replaced // comments with /* */
           comments, since they are not normally recognized by C compilers.
11/1/00  - Added initial support for AUTH PLAIN mechanism. Added
           smtp_processPLAIN().
11/10/00 - Added parameter to rfc822_binary() to control whether we want to
           have CRLF sequences added to the encoded string. Since IO_send()
           appends a CRLF sequence itself, we don't want to send two of them
           sequentially. This was causing a problem with AUTH LOGIN on the
           mirapoint SMTP server. Also added code after rfc822_binary() calls
           to make sure that we do not send any non-base64 characters to the
           server.
11/25/00 - Fixed busted smtp_processPLAIN() so that it now works.
3/2/01   - Added workaround for compiler optimization bug in
           smtp_processCRAMMD5(). Added smtp_startTLS, smtp_getSocket for
           STARTTLS support.
4/19/01  - Now send a blank authorize-id for PLAIN authentication. This is
           allowed by RFC2595 and this allows to login to Netscape 4.15 servers
           that do not like us sending both and authorize-id and authenticate-
           id. Also fixed a silly typo in smtp_startTLS().
10/16/01 - smtp_auth() now calls generatePlainClientData() if we are trying to
           authenticate using plain and both username and password were passed
           in. We are allowed to send initial client data when using PLAIN
           without waiting for an intermediate server response.
           smtp_processPLAIN() now calls generatePlainClientData() to generate
           the data to send to the server.
1/22/02  - We can now properly handle multi-line responses to all commands in
           smtp_processResponses(). This fixes a problem where we were not
           processing server responses properly when the server gave us a
           multiline welcome message.
5/29/03  - smtp_initialize() now takes an extra param that will be used to set
           the chunk size as well as the read and write buffer sizes.
8/14/03  - Added yield callback to sink structure. It is called (if it is non-
           NULL) inside smtp_sendStream() so that large emails that are being
           sent to the server don't cause the app to block.

util.c
4/29/99  - Added an extra check to allow callers to specify that they want to
           handle any bits still in the queue in decodeBase64().
6/21/99  - Fixed the implementation of decodeHeader() and decodeQP().
8/12/99  - Added decodeModifiedBase64(), decodeBase64WithTable() functions.
           Fixed code to prevent warnings.
8/26/99  - Added decodeQPHeader() to handle RFC2047 style quoted printable.
8/30/99  - Initialize ch = 1 in decodeQPxx functions
3/7/00   - Modified decodeQP() so that it only copies CRLF sequences, not
           arbitrary CR or LF characters.
2/9/01   - Modified decodeHeader() to better conform to RFC822. We now ignore
           whitespace characters between encoded words.
2/10/01  - Stopped a crash in decodeHeader() when we don't find the end of an
           encoded word. This crash would only manifest itself when downloading
           mail, and it would be caught by our exception handling.
6/8/01   - Modified the behavior of szLTrim() and szRTrim() so that if the
           string they are passed is composed completely of whitespace
           characters, that they both leave one whitespace character in the
           resulting string. This works around a bug in
           mimeParser_parseMimeMessage() where folded headers lines were not
           being handled properly if they contained only a space.
10/16/01 - Added generatePlainClientData() which takes a username and password
           and generates the data string that needs to be sent to the server
           when authenticating using the PLAIN mechanism. This code was
           extracted from the IMAP4 and SMTP functionality and put here since
           it is called now from many spots.
12/5/01  - Added code to decodeqp() and decodeqpheader() to ensure that we
           don't read beyond the end of the input buffer. This was causing a
           very hard to reproduce crash. Also added an assert() at the end of
           each function to ensure that we haven't gone beyond the input buffer.
7/14/03  - Added code to handle case where quoted-printable encoded text ends
           line with only LF instead of CRLF. Also improved generic handling of
           bad encoded byte sequences - now we print out the 2 bytes following
           the '=' instead of printing out NUL chars (and thereby stopping the
           buffer). nConvertHexToDec() now returns an errorcode, and takes an
           out param for the decoded byte.
4/6/05   - Added code to fix Bug 4287596. This bug was happening because we
           were not gracefully handling badly encoded base64 streams. We would
           decode the trailing byte(s) if the encoded stream suggested there
           were further bytes. This is because the functionality to decode
           base64 streams used the return value both for the number of bytes
           decoded and to return error codes. T solve this, an extra parameter
           was added to return the number of decoded bytes. This is all we
           really care about in most cases, as we want to decode as many bytes
           as possible.
E-mail this page
Printer View Printer View
Software. Hardware. Complete. About Oracle | Oracle and Sun| Oracle RSS Feeds | Careers | Contact Us | Site Maps | Legal Notices | Terms of Use | Privacy