1 /* -*- Mode: C++; tab-width: 2; 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 _NSMSGUTILS_H 7 #define _NSMSGUTILS_H 8 9 #include "nsIURL.h" 10 #include "nsString.h" 11 #include "msgCore.h" 12 #include "nsCOMPtr.h" 13 #include "MailNewsTypes2.h" 14 #include "nsTArray.h" 15 #include "nsInterfaceRequestorAgg.h" 16 #include "nsILoadGroup.h" 17 #include "nsINetUtil.h" 18 #include "nsIRequest.h" 19 #include "nsILoadInfo.h" 20 #include "nsServiceManagerUtils.h" 21 #include "nsUnicharUtils.h" 22 #include "nsIFile.h" 23 24 class nsIChannel; 25 class nsIFile; 26 class nsIPrefBranch; 27 class nsIMsgFolder; 28 class nsIMsgMessageService; 29 class nsIUrlListener; 30 class nsIOutputStream; 31 class nsIInputStream; 32 class nsIMsgDatabase; 33 class nsIProxyInfo; 34 class nsIMsgWindow; 35 class nsIStreamListener; 36 class nsICancelable; 37 class nsIProtocolProxyCallback; 38 class nsIMsgSearchTerm; 39 40 #define FILE_IO_BUFFER_SIZE (16 * 1024) 41 #define MSGS_URL "chrome://messenger/locale/messenger.properties" 42 43 // These are utility functions that can used throughout the mailnews code 44 45 NS_MSG_BASE nsresult GetMessageServiceContractIDForURI(const char* uri, 46 nsCString& contractID); 47 48 NS_MSG_BASE nsresult GetMessageServiceFromURI( 49 const nsACString& uri, nsIMsgMessageService** aMessageService); 50 51 NS_MSG_BASE nsresult GetMsgDBHdrFromURI(const nsACString& uri, 52 nsIMsgDBHdr** msgHdr); 53 54 NS_MSG_BASE nsresult NS_MsgGetPriorityFromString( 55 const char* const priority, nsMsgPriorityValue& outPriority); 56 57 NS_MSG_BASE nsresult NS_MsgGetPriorityValueString(const nsMsgPriorityValue p, 58 nsACString& outValueString); 59 60 NS_MSG_BASE nsresult NS_MsgGetUntranslatedPriorityName( 61 const nsMsgPriorityValue p, nsACString& outName); 62 63 NS_MSG_BASE nsresult NS_MsgHashIfNecessary(nsAutoString& name); 64 NS_MSG_BASE nsresult NS_MsgHashIfNecessary(nsAutoCString& name); 65 66 NS_MSG_BASE nsresult FormatFileSize(int64_t size, bool useKB, 67 nsAString& formattedSize); 68 69 /** 70 * given a folder uri, return the path to folder in the user profile directory. 71 * 72 * @param aFolderURI uri of folder we want the path to, without the scheme 73 * @param[out] aPathString result path string 74 * @param aScheme scheme of the uri 75 * @param[optional] aIsNewsFolder is this a news folder? 76 */ 77 NS_MSG_BASE nsresult NS_MsgCreatePathStringFromFolderURI( 78 const char* aFolderURI, nsCString& aPathString, const nsCString& aScheme, 79 bool aIsNewsFolder = false); 80 81 /** 82 * Given a string and a length, removes any "Re:" strings from the front. 83 * It also deals with that dumbass "Re[2]:" thing that some losing mailers do. 84 * 85 * If mailnews.localizedRe is set, it will also remove localized "Re:" strings. 86 * 87 * @return true if it made a change (in which case the caller should look to 88 * modifiedSubject for the result) and false otherwise (in which 89 * case the caller should look at subject for the result) 90 */ 91 NS_MSG_BASE bool NS_MsgStripRE(const nsCString& subject, 92 nsCString& modifiedSubject); 93 94 NS_MSG_BASE char* NS_MsgSACopy(char** destination, const char* source); 95 96 NS_MSG_BASE char* NS_MsgSACat(char** destination, const char* source); 97 98 NS_MSG_BASE nsresult NS_MsgEscapeEncodeURLPath(const nsAString& aStr, 99 nsCString& aResult); 100 101 NS_MSG_BASE nsresult NS_MsgDecodeUnescapeURLPath(const nsACString& aPath, 102 nsAString& aResult); 103 104 NS_MSG_BASE bool WeAreOffline(); 105 106 // Get a folder by Uri, returning null if it doesn't exist (or if some 107 // error occurs). A missing folder is not considered an error. 108 NS_MSG_BASE nsresult FindFolder(const nsACString& aFolderURI, 109 nsIMsgFolder** aFolder); 110 111 // Get a folder by Uri. 112 // A missing folder is considered to be an error. 113 // Returns a non-null folder if and only if result is NS_OK. 114 NS_MSG_BASE nsresult GetExistingFolder(const nsACString& aFolderURI, 115 nsIMsgFolder** aFolder); 116 117 // Get a folder by Uri, creating it if it doesn't already exist. 118 // An error is returned if a folder cannot be found or created. 119 // Created folders will be 'dangling' folders (ie not connected to a 120 // parent). 121 NS_MSG_BASE nsresult GetOrCreateFolder(const nsACString& aFolderURI, 122 nsIMsgFolder** aFolder); 123 124 // Escape lines starting with "From ", ">From ", etc. in a buffer. 125 NS_MSG_BASE nsresult EscapeFromSpaceLine(nsIOutputStream* ouputStream, 126 char* start, const char* end); 127 NS_MSG_BASE bool IsAFromSpaceLine(char* start, const char* end); 128 129 NS_MSG_BASE nsresult NS_GetPersistentFile( 130 const char* relPrefName, const char* absPrefName, 131 const char* dirServiceProp, // Can be NULL 132 bool& gotRelPref, nsIFile** aFile, nsIPrefBranch* prefBranch = nullptr); 133 134 NS_MSG_BASE nsresult NS_SetPersistentFile(const char* relPrefName, 135 const char* absPrefName, 136 nsIFile* aFile, 137 nsIPrefBranch* prefBranch = nullptr); 138 139 NS_MSG_BASE nsresult IsRFC822HeaderFieldName(const char* aHdr, bool* aResult); 140 141 NS_MSG_BASE nsresult NS_GetUnicharPreferenceWithDefault( 142 nsIPrefBranch* prefBranch, // can be null, if so uses the root branch 143 const char* prefName, const nsAString& defValue, nsAString& prefValue); 144 145 NS_MSG_BASE nsresult NS_GetLocalizedUnicharPreferenceWithDefault( 146 nsIPrefBranch* prefBranch, // can be null, if so uses the root branch 147 const char* prefName, const nsAString& defValue, nsAString& prefValue); 148 149 NS_MSG_BASE nsresult NS_GetLocalizedUnicharPreference( 150 nsIPrefBranch* prefBranch, // can be null, if so uses the root branch 151 const char* prefName, nsAString& prefValue); 152 153 /** 154 * this needs a listener, because we might have to create the folder 155 * on the server, and that is asynchronous 156 */ 157 NS_MSG_BASE nsresult GetOrCreateJunkFolder(const nsACString& aURI, 158 nsIUrlListener* aListener); 159 160 // Returns true if the nsIURI is a message under an RSS account 161 NS_MSG_BASE nsresult IsRSSArticle(nsIURI* aMsgURI, bool* aIsRSSArticle); 162 163 // digest needs to be a pointer to a 16 byte buffer 164 #define DIGEST_LENGTH 16 165 166 NS_MSG_BASE nsresult MSGCramMD5(const char* text, int32_t text_len, 167 const char* key, int32_t key_len, 168 unsigned char* digest); 169 NS_MSG_BASE nsresult MSGApopMD5(const char* text, int32_t text_len, 170 const char* password, int32_t password_len, 171 unsigned char* digest); 172 173 // helper functions to convert a 64bits PRTime into a 32bits value (compatible 174 // time_t) and vice versa. 175 NS_MSG_BASE void PRTime2Seconds(PRTime prTime, uint32_t* seconds); 176 NS_MSG_BASE void PRTime2Seconds(PRTime prTime, int32_t* seconds); 177 NS_MSG_BASE void Seconds2PRTime(uint32_t seconds, PRTime* prTime); 178 // helper function to generate current date+time as a string 179 NS_MSG_BASE void MsgGenerateNowStr(nsACString& nowStr); 180 181 // Appends the correct summary file extension onto the supplied fileLocation 182 // and returns it in summaryLocation. 183 NS_MSG_BASE nsresult GetSummaryFileLocation(nsIFile* fileLocation, 184 nsIFile** summaryLocation); 185 186 // Gets a special directory and appends the supplied file name onto it. 187 NS_MSG_BASE nsresult GetSpecialDirectoryWithFileName(const char* specialDirName, 188 const char* fileName, 189 nsIFile** result); 190 191 // cleanup temp files with the given filename and extension, including 192 // the consecutive -NNNN ones that we can find. If there are holes, e.g., 193 // <filename>-1-10,12.<extension> exist, but <filename>-11.<extension> does not 194 // we'll clean up 1-10. If the leaks are common, I think the gaps will tend to 195 // be filled. 196 NS_MSG_BASE nsresult MsgCleanupTempFiles(const char* fileName, 197 const char* extension); 198 199 NS_MSG_BASE nsresult MsgGetFileStream(nsIFile* file, 200 nsIOutputStream** fileStream); 201 202 NS_MSG_BASE nsresult MsgReopenFileStream(nsIFile* file, 203 nsIInputStream* fileStream); 204 205 // Automatically creates an output stream with a suitable buffer 206 NS_MSG_BASE nsresult MsgNewBufferedFileOutputStream(nsIOutputStream** aResult, 207 nsIFile* aFile, 208 int32_t aIOFlags = -1, 209 int32_t aPerm = -1); 210 211 // Automatically creates an output stream with a suitable buffer, but write to a 212 // temporary file first, then rename to aFile 213 NS_MSG_BASE nsresult 214 MsgNewSafeBufferedFileOutputStream(nsIOutputStream** aResult, nsIFile* aFile, 215 int32_t aIOFlags = -1, int32_t aPerm = -1); 216 217 // fills in the position of the passed in keyword in the passed in keyword list 218 // and returns false if the keyword isn't present 219 NS_MSG_BASE bool MsgFindKeyword(const nsCString& keyword, nsCString& keywords, 220 int32_t* aStartOfKeyword, int32_t* aLength); 221 222 NS_MSG_BASE bool MsgHostDomainIsTrusted(nsCString& host, 223 nsCString& trustedMailDomains); 224 225 // gets an nsIFile from a UTF-8 file:// path 226 NS_MSG_BASE nsresult MsgGetLocalFileFromURI(const nsACString& aUTF8Path, 227 nsIFile** aFile); 228 229 NS_MSG_BASE void MsgStripQuotedPrintable(nsCString& aSrc); 230 231 /* 232 * Utility functions that call functions from nsINetUtil 233 */ 234 235 NS_MSG_BASE nsresult MsgEscapeString(const nsACString& aStr, uint32_t aType, 236 nsACString& aResult); 237 238 NS_MSG_BASE nsresult MsgUnescapeString(const nsACString& aStr, uint32_t aFlags, 239 nsACString& aResult); 240 241 NS_MSG_BASE nsresult MsgEscapeURL(const nsACString& aStr, uint32_t aFlags, 242 nsACString& aResult); 243 244 // Given a message db and a set of keys, fetch the corresponding message 245 // headers. 246 NS_MSG_BASE nsresult 247 MsgGetHeadersFromKeys(nsIMsgDatabase* aDB, const nsTArray<nsMsgKey>& aKeys, 248 nsTArray<RefPtr<nsIMsgDBHdr>>& aHeaders); 249 250 NS_MSG_BASE nsresult MsgExamineForProxyAsync(nsIChannel* channel, 251 nsIProtocolProxyCallback* listener, 252 nsICancelable** result); 253 254 NS_MSG_BASE int32_t MsgFindCharInSet(const nsCString& aString, 255 const char* aChars, uint32_t aOffset = 0); 256 NS_MSG_BASE int32_t MsgFindCharInSet(const nsString& aString, 257 const char* aChars, uint32_t aOffset = 0); 258 259 // advances bufferOffset to the beginning of the next line, if we don't 260 // get to maxBufferOffset first. Returns false if we didn't get to the 261 // next line. 262 NS_MSG_BASE bool MsgAdvanceToNextLine(const char* buffer, 263 uint32_t& bufferOffset, 264 uint32_t maxBufferOffset); 265 266 /** 267 * Alerts the user that the login to the server failed. Asks whether the 268 * connection should: retry, cancel, or request a new password. 269 * 270 * @param aMsgWindow The message window associated with this action (cannot 271 * be null). 272 * @param aHostname The hostname of the server for which the login failed. 273 * @param aResult The button pressed. 0 for retry, 1 for cancel, 274 * 2 for enter a new password. 275 * @return NS_OK for success, NS_ERROR_* if there was a failure in 276 * creating the dialog. 277 */ 278 NS_MSG_BASE nsresult MsgPromptLoginFailed(nsIMsgWindow* aMsgWindow, 279 const nsACString& aHostname, 280 const nsACString& aUsername, 281 const nsAString& aAccountname, 282 int32_t* aResult); 283 284 /** 285 * Calculate a PRTime value used to determine if a date is XX 286 * days ago. This is used by various retention setting algorithms. 287 */ 288 NS_MSG_BASE PRTime MsgConvertAgeInDaysToCutoffDate(int32_t ageInDays); 289 290 /** 291 * Converts the passed in term list to its string representation. 292 * 293 * @param aTermList Array of nsIMsgSearchTerms 294 * @param[out] aOutString result representation of search terms. 295 * 296 */ 297 NS_MSG_BASE nsresult MsgTermListToString( 298 nsTArray<RefPtr<nsIMsgSearchTerm>> const& aTermList, nsCString& aOutString); 299 300 NS_MSG_BASE nsresult MsgStreamMsgHeaders(nsIInputStream* aInputStream, 301 nsIStreamListener* aConsumer); 302 303 /** 304 * convert string to uint64_t 305 * 306 * @param str converted string 307 * @returns uint64_t value for success, 0 for parse failure 308 */ 309 NS_MSG_BASE uint64_t ParseUint64Str(const char* str); 310 311 /** 312 * Detect charset of file 313 * 314 * @param aFile The target of nsIFile 315 * @param[out] aCharset The charset string 316 */ 317 NS_MSG_BASE nsresult MsgDetectCharsetFromFile(nsIFile* aFile, 318 nsACString& aCharset); 319 320 /* 321 * Converts a buffer to plain text. Some conversions may 322 * or may not work with certain end charsets which is why we 323 * need that as an argument to the function. If charset is 324 * unknown or deemed of no importance NULL could be passed. 325 * @param[in/out] aConBuf Variable with the text to convert 326 * @param formatFlowed Use format flowed? 327 * @param formatOutput Reformat the output? 328 & @param disallowBreaks Disallow breaks when formatting 329 */ 330 NS_MSG_BASE nsresult ConvertBufToPlainText(nsString& aConBuf, bool formatFlowed, 331 bool formatOutput, 332 bool disallowBreaks); 333 334 #include "nsEscape.h" 335 336 /** 337 * Converts a hex string into an integer. 338 * Processes up to aNumChars characters or the first non-hex char. 339 * It is not an error if less than aNumChars valid hex digits are found. 340 */ 341 NS_MSG_BASE uint64_t MsgUnhex(const char* aHexString, size_t aNumChars); 342 343 /** 344 * Checks if a string is a valid hex literal containing at least aNumChars 345 * digits. 346 */ 347 NS_MSG_BASE bool MsgIsHex(const char* aHexString, size_t aNumChars); 348 349 /** 350 * Convert an uint32_t to a nsMsgKey. 351 * Currently they are mostly the same but we need to preserve the notion that 352 * nsMsgKey is an opaque value that can't be treated as a generic integer 353 * (except when storing it into the database). It enables type safety checks and 354 * may prevent coding errors. 355 */ 356 NS_MSG_BASE nsMsgKey msgKeyFromInt(uint32_t aValue); 357 358 NS_MSG_BASE nsMsgKey msgKeyFromInt(uint64_t aValue); 359 360 NS_MSG_BASE uint32_t msgKeyToInt(nsMsgKey aMsgKey); 361 362 /** 363 * Helper function to extract query part from URL spec. 364 */ 365 nsCString MsgExtractQueryPart(const nsACString& spec, 366 const char* queryToExtract); 367 /** 368 * Helper function to remove query part from URL spec or path. 369 */ 370 void MsgRemoveQueryPart(nsCString& aSpec); 371 372 /** 373 * Helper macro for defining getter/setters. Ported from nsISupportsObsolete.h 374 */ 375 #define NS_IMPL_GETSET(clazz, attr, type, member) \ 376 NS_IMETHODIMP clazz::Get##attr(type* result) { \ 377 NS_ENSURE_ARG_POINTER(result); \ 378 *result = member; \ 379 return NS_OK; \ 380 } \ 381 NS_IMETHODIMP clazz::Set##attr(type aValue) { \ 382 member = aValue; \ 383 return NS_OK; \ 384 } 385 386 /** 387 * Macro and helper function for reporting an error, warning or 388 * informational message to the Error Console 389 * 390 * This will require the inclusion of the following files in the source file 391 * #include "nsIScriptError.h" 392 * #include "nsIConsoleService.h" 393 * 394 */ 395 396 NS_MSG_BASE 397 void MsgLogToConsole4(const nsAString& aErrorText, const nsAString& aFilename, 398 uint32_t aLine, uint32_t flags); 399 400 // Macro with filename and line number 401 #define MSG_LOG_TO_CONSOLE(_text, _flag) \ 402 MsgLogToConsole4(NS_LITERAL_STRING_FROM_CSTRING(_text), \ 403 NS_LITERAL_STRING_FROM_CSTRING(__FILE__), __LINE__, _flag) 404 #define MSG_LOG_ERR_TO_CONSOLE(_text) \ 405 MSG_LOG_TO_CONSOLE(_text, nsIScriptError::errorFlag) 406 #define MSG_LOG_WARN_TO_CONSOLE(_text) \ 407 MSG_LOG_TO_CONSOLE(_text, nsIScriptError::warningFlag) 408 #define MSG_LOG_INFO_TO_CONSOLE(_text) \ 409 MSG_LOG_TO_CONSOLE(_text, nsIScriptError::infoFlag) 410 411 // Helper macros to cope with shoddy I/O error reporting (or lack thereof) 412 #define MSG_NS_ERROR(_txt) \ 413 do { \ 414 NS_ERROR(_txt); \ 415 MSG_LOG_ERR_TO_CONSOLE(_txt); \ 416 } while (0) 417 #define MSG_NS_WARNING(_txt) \ 418 do { \ 419 NS_WARNING(_txt); \ 420 MSG_LOG_WARN_TO_CONSOLE(_txt); \ 421 } while (0) 422 #define MSG_NS_WARN_IF_FALSE(_val, _txt) \ 423 do { \ 424 if (!(_val)) { \ 425 NS_WARNING(_txt); \ 426 MSG_LOG_WARN_TO_CONSOLE(_txt); \ 427 } \ 428 } while (0) 429 #define MSG_NS_INFO(_txt) \ 430 do { \ 431 MSG_LOCAL_INFO_TO_CONSOLE(_txt); \ 432 fprintf(stderr, "(info) %s (%s:%d)\n", _txt, __FILE__, __LINE__); \ 433 } while (0) 434 435 #endif 436