2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
26 * $TOG: DtMailError.C /main/18 1999/02/08 09:32:25 mgreess $
28 * RESTRICTED CONFIDENTIAL INFORMATION:
30 * The information in this document is subject to special
31 * restrictions in a confidential disclosure agreement between
32 * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
33 * document outside HP, IBM, Sun, USL, SCO, or Univel without
34 * Sun's specific written approval. This document and all copies
35 * and derivative works thereof must be returned or destroyed at
38 * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
48 #include <DtMail/DtMail.hh>
49 #include <DtMail/DtMailError.hh>
50 #include <DtMail/Common.h>
51 #include <Dt/MsgCatP.h>
55 #if defined(HPUX) && !defined(hpV4)
56 // HP-UX 9.* syslog.h does not define these.
58 extern "C" int syslog(int, const char *, ...);
59 extern "C" int openlog(const char *, int, int);
62 #include <EUSDebug.hh>
64 // Provide interface to the DtSvc function DtSimpleError
65 // When this interface is better defined, this can be removed
66 // and replaced with the appropriate include file
77 extern "C" void _DtSimpleError(
84 int DtMailDebugLevel = 0;
85 DtMailBoolean DtMailEnv::_syslog_open = DTM_FALSE;
86 nl_catd DtMailEnv::_errorCatalog = (nl_catd) -1;
87 const char * DtMailEnv::DtMailCatalogDataFile = "libDtMail";
88 nl_catd DtMailMsgCat = DtMailEnv::_errorCatalog;// COMPATIBILITY
92 // NOTE - IMPORTANT -- READ ME
94 // The order of the strings below must match the
95 // entries in DtMail/MailError.h.
97 static const char * error_strings[] = {
100 "No error occurred.",
102 // - DTME_AlreadyLocked
103 "The mailbox is locked by another session.",
106 "A bad argument was passed as a parameter to the operation.",
108 // - DTME_BadMailAddress
109 "The specified mail address could not be processed.",
111 // - DTME_BadRunGroup
112 "The dtmail program is not running as group \"mail\".",
114 // - DTME_FileCreateFailed
115 "The requested file could not be created.",
117 // - DTME_FolderNotSet
118 "The mailbox to incorporate was not set.",
120 // - DTME_GetLockRefused
121 "The user refused to take the lock of a locked mailbox.",
123 // - DTME_ImplFailure
124 "The specified implementation could not perform the requested operation.",
126 // - DTME_InitializationFailed
127 "The instance could not be initialized.",
129 // - DTME_InternalFailure
130 "An internal failure occurred while performing the operation.",
132 // - DTME_InvalidError
133 "The error structure is invalid.",
135 // - DTME_InvalidOperationSequence
136 "An operation was attempted before the instance was initialized.",
138 // - DTME_MD5ChecksumFailed
139 "The MD5 signature did not match the message contents.",
141 // - DTME_MailTransportFailed
142 "Unable to communicate with the mail transport.",
145 "There is no data type that matches the transport type.",
147 // - DTME_NoImplementations
148 "No implementations were found for the mail library.",
151 "The mailbox was uninitialized at load time.",
154 "No memory available for operation.",
157 "No message catalog exists for DtMail.",
160 "There is no new mail to incorporate.",
162 // - DTME_NoObjectValue
163 "No value for the object could be found.",
166 "The mailbox does not exist and creation was not requested.",
168 // - DTME_NoSuchImplementation
169 "The specified implementation does not exist.",
172 "The data type is not known to the library.",
175 "The user for this session could not be identified.",
178 "The file specified is not a mailbox.",
181 "The mailbox is not locked for access.",
184 "The requested file is not a mailbox in any format recognized by this implementation.",
186 // - DTME_NotSupported
187 "The operation is not supported by the current implementation.",
189 // - DTME_ObjectAccessFailed
190 "Unable to access an object required to complete the operation.",
192 // - DTME_ObjectCreationFailed
193 "Unable to create an object required to complete the operation.",
195 // - DTME_ObjectInUse
196 "An attempt was made to initialize an object that was already initialized.",
198 // - DTME_ObjectInvalid
199 "An invalid object was referenced.",
201 // - DTME_OpenContainerInterrupted
202 "The user interrupted the process of opening a mailbox.",
204 // - DTME_OperationInvalid
205 "An internal error occurred while performing the operation.",
207 // - DTME_OtherOwnsWrite
208 "Another mail program owns the write access to the mailbox.",
210 // - DTME_RequestDenied
211 "The other session denied the request for lock or copy.",
214 "A ToolTalk message could not be processed.",
216 // - DTME_TransportFailed
217 "The mail delivery transport failed.",
219 // - DTME_UnknownFormat
220 "The message is not in one of the supported formats.",
222 // - DTME_UnknownOpenError
223 "An unknown error occurred when opening a mailbox.",
226 "The user aborted the operation.",
228 // - DTME_UserInterrupted
229 "The user interrupted the operation.",
231 // - DTME_ObjectReadOnly
232 "The mailbox permissions only allow read access.",
234 // - DTME_NoPermission,
235 "The user does not have access to the mailbox.",
237 // - DTME_IsDirectory,
238 "The specified path is a directory.",
240 // - DTME_CannotRemoveStaleMailboxLockFile
241 "Cannot lock mailbox (could not remove stale lock file).\nStale lock file: %s\nReason: %s",
243 // - DTME_CannotCreateMailboxLockFile
244 "Cannot lock mailbox (could not create lock file).\nMailbox lock file: %s\nReason: %s",
246 // - DTME_CannotCreateMailboxLockFile_NoPermission
247 "Cannot create lock file and lock mailbox because the user does not have\naccess to either the mailbox or the directory containing the mailbox.",
249 // - DTME_CannotCreateMailboxLockFile_IsDirectory
250 "Cannot create lock file and lock mailbox because the name for the\nmailbox lock file already exists and is a directory.",
252 // - DTME_CannotCreateMailboxLockFile_NoSuchFile
253 "Cannot create lock file and lock mailbox because a component of the\npath name of the lock file is not a directory.",
255 // - DTME_CannotCreateMailboxLockFile_RemoteAccessLost
256 "Cannot create lock file and lock mailbox because the remote system on\nwhich the lock file was to be created is no longer accessible.",
258 // - DTME_CannotObtainInformationOnOpenMailboxFile
259 "Cannot obtain information on current mailbox file.\nMailbox file: %s\nReason: %s",
261 // - DTME_CannotCreateTemporaryMailboxFile
262 "Cannot create temporary mailbox file.\nTemporary Mailbox file: %s\nReason: %s",
264 // - DTME_CannotCreateTemporaryMailboxFile_NoPermission
265 "Cannot create temporary mailbox file because the user does not have\naccess to either the mailbox or the directory containing the mailbox.",
267 // - DTME_CannotCreateTemporaryMailboxFile_IsDirectory
268 "Cannot create temporary mailbox file because the name for the\ntemporary mailbox already exists and is a directory.",
270 // - DTME_CannotCreateTemporaryMailboxFile_NoSuchFile
271 "Cannot create temporary mailbox file because a component of the\npath name of the temporary file is not a directory.",
273 // - DTME_CannotCreateTemporaryMailboxFile_RemoteAccessLost
274 "Cannot create temporary mailbox file because the remote system on\nwhich the file was to be created is no longer accessible.",
276 // - DTME_CannotSetPermissionsOfTemporaryMailboxFile
277 "Cannot set permissions on temporary mailbox file.\nTemporary Mailbox file: %s\nPermissions requested: %o\nReason: %s",
279 // - DTME_CannotSetOwnerOfTemporaryMailboxFile
280 "Cannot set owner of temporary mailbox file.\nTemporary Mailbox file: %s\nOwner uid requested: %d\nReason: %s",
282 // - DTME_CannotSetGroupOfTemporaryMailboxFile
283 "Cannot set group of temporary mailbox file.\nTemporary Mailbox file: %s\nGroup gid requested: %d\nReason: %s",
285 // - DTME_CannotWriteToTemporaryMailboxFile
286 "Cannot write to temporary mailbox file.\nTemporary Mailbox file: %s\nReason: %s",
288 // - DTME_CannotWriteToTemporaryMailboxFile_ProcessLimitsExceeded
289 "Cannot write to temporary mailbox file because the process's file\nsize limit or the maximum file size has been reached.",
291 // - DTME_CannotWriteToTemporaryMailboxFile_RemoteAccessLost
292 "Cannot write to temporary mailbox file because the remote system on\nwhich the file was created is no longer accessible.",
294 // - DTME_CannotWriteToTemporaryMailboxFile_NoFreeSpaceLeft
295 "Cannot write to temporary mailbox file because there is no free\nspace left on the device on which the file was created.",
297 // - DTME_CannotReadNewMailboxFile
298 "Cannot read new mailbox file\nReason: %s",
300 // - DTME_CannotReadNewMailboxFile_OutOfMemory
301 "Cannot read new mailbox file because no memory is available for the operation.",
303 // - DTME_CannotRemoveMailboxLockFile
304 "Cannot unlock mailbox (could not remove lock file).\nMailbox lock file: %s\nReason: %s",
306 // - DTME_CannotRenameNewMailboxFileOverOld
307 "Cannot rename new mailbox file over old mailbox file.\nOld mailbox file still exists but complete and correct contents\nof mailbox contents have been saved in the new mailbox file.\nThis problem must be corrected manually as soon as possible.\nOld Mailbox file: %s\nNew Mailbox file: %s\nReason: %s",
309 // - DTME_InternalAssertionFailure
310 "An internal error has occurred within this application.\nThere is no way to recover and continue from this error.\nError condition: %s\n",
312 // - DTME_ResourceParsingNoEndif
313 "An error occurred while parsing the .mailrc resource file.\nThere is a conditional if statement that does not have a corresponding endif statement.\n",
315 // - DTME_AlreadyOpened,
316 "This mail folder is already opened.",
318 // - DTME_OutOfSpace,
319 "No Space on Temporary Filesystem.",
321 // - DTME_CannotCreateMailboxDotDtmailLockFile
322 "Mailer has detected a mailbox lockfile:\n%s",
324 // - DTME_MailboxInodeChanged
325 "Mailer can no longer access this mailbox.\nIt would be best to close and reopen it.",
327 // - DTME_MailServerAccess_AuthorizationFailed
328 "Cannot retrieve mail for '%s@%s' using '%s'.\nAuthorization failed.",
330 // - DTME_MailServerAccess_Error
331 "Cannot retrieve mail for '%s@%s' using '%s'.\nThe server returned:\n %s",
333 // - DTME_MailServerAccess_MissingPassword
334 "Please enter a password for '%s@%s' using '%s'",
336 // - DTME_MailServerAccess_ProtocolViolation
337 "Cannot retrieve mail for '%s@%s' using '%s'.\nClient/server protocol error.",
339 // - DTME_MailServerAccess_ServerTimeoutError
340 "Cannot retrieve mail for '%s@%s' using '%s'.\nTimed out waiting for server.",
342 // - DTME_MailServerAccess_SocketIOError
343 "Cannot retrieve mail for '%s@%s' using '%s'.\n%s.",
345 // - DTME_AppendMailboxFile_Error
346 "Cannot append to mailbox",
348 // - DTME_AppendMailboxFile_FileTooBig
349 "Cannot append to mailbox: %s\nSYSERROR(%d): %s.",
351 // - DTME_AppendMailboxFile_LinkLost
352 "Cannot append to mailbox: %s\nSYSERROR(%d): %s.",
354 // - DTME_AppendMailboxFile_NoSpaceLeft
355 "Cannot append to mailbox: %s\nSYSERROR(%d): %s.",
357 // - DTME_AppendMailboxFile_SystemError
358 "Cannot append to mailbox: %s\nSYSERROR(%d): %s.",
360 // - DTME_GetmailCommandRetrieval_SystemError
361 "Getmail command failed: %s\nSYSERROR(%d): %s.",
363 // - DTME_GetmailCommandRetrieval_AbnormalExit
364 "Getmail command exited abnormally: %s.",
366 // - DTME_PathElementPermissions
367 "Search permission denied on a component of the path prefix,\n'%s'.",
369 // - DTME_PathElementNotDirectory
370 "A component of the path prefix is not a directory,\n'%s'.",
372 // - DTME_PathElementDoesNotExist
373 "A component of the path prefix does not exist,\n'%s'.",
375 // - DTME_MailServerAccessInfo_SocketOpen
376 "Opening connection for '%s@%s'.",
378 // - DTME_MailServerAccessInfo_NoMessages
379 "No messages for '%s@%s'.",
381 // - DTME_MailServerAccessInfo_RetrievingMessage
382 "Retrieving message %d of %d for '%s@%s'.",
384 // - DTME_MailServerAccessInfo_MessageTooLarge
385 "Skipping oversized message (%d bytes).",
391 DtMailEnv::DtMailEnv()
393 setCPP(NULL,NULL,NULL);
394 _error = DTME_NoError;
398 _implClearFunc = NULL;
403 #define GETMSG(catd, set, msg, dft) _DtCatgetsCached(catd, set, msg, dft)
405 #define GETMSG(catd, set, msg, dft) catgets(catd, set, msg, dft)
409 DtMailEnv::getMessageText(int set, int msg, char *dft)
411 static int oneTimeFlag = 0; // Only attempt to open message catalog once
414 if ((oneTimeFlag == 0) && (_errorCatalog == (nl_catd) -1))
417 _errorCatalog = catopen((char*) DtMailCatalogDataFile, NL_CAT_LOCALE);
419 if (_errorCatalog != (nl_catd) -1)
420 message = GETMSG(_errorCatalog, set, msg, dft);
426 DtMailEnv::getErrorMessageText()
428 if (_message == NULL)
430 if (_error_minor_code >= DTME_MAXDTME)
431 _error_minor_code = DTME_InvalidError;
433 _message = getMessageText(
434 MailErrorSet, _error_minor_code + 1,
435 (char*) error_strings[_error_minor_code]);
437 if (_message == NULL)
439 _error = DTME_NoMemory;
440 _message = strdup(error_strings[_error_minor_code]);
443 _message = strdup(_message);
449 _error = DTME_NoError;
451 if (_message != NULL) {
452 free((char *)_message);
456 if (_tt_message != NULL) {
457 tt_message_destroy(_tt_message);
461 if (_client != NULL && _implClearFunc != NULL) {
468 DtMailEnv::setError(const DTMailError_t minor_code,
472 clear(); // Clear out and free any old storage.
474 _error_minor_code = minor_code; // Remember original error number
476 if (minor_code != DTME_NoError ) {
478 if (minor_code >= DTME_MAXDTME) {
479 _error = DTME_InvalidError;
482 _tt_message = msg; // Save the new one.
488 // given system error number, include that string into the given message,
489 // which must have a %s embedded within it
492 // DtMailEnv::errnoMessage -- convert current system error number to readable text
494 // Take the current system error number (in the global errno), and
495 // return a pointer to a readable string that describes the error.
501 // const char * -- pointer to ascii text describing current system error
502 // that is safe to refer to in an MT-hot environment
505 DtMailEnv::errnoMessage(void)
507 return(errnoMessage(errno));
510 // DtMailEnv::errnoMessage -- convert system error number to readable text
512 // Given a valid system error number (as returned in the global errno),
513 // return a pointer to a readable string that describes the error.
515 // systemErrorNumber - errno value
519 // const char * -- pointer to ascii text describing system error
520 // that is safe to refer to in an MT-hot environment
523 DtMailEnv::errnoMessage(int systemErrorNumber)
525 // Get the system error message for the given system error
527 const char *syserrstr = strerror(systemErrorNumber);
529 syserrstr = (const char *)"?";
533 // allow variable arguments at end and call vsprintf to process the
534 // error message string
537 DtMailEnv::vSetError(const DTMailError_t minor_code,
542 const int MessageBufferSize = 4096;
543 char *messageBuffer = new char[MessageBufferSize+1];
545 // allow error to come up with the final translated error message
547 setError(minor_code, fatal, msg);
548 if (_message == NULL)
549 getErrorMessageText();
551 // Use the current error message as a format to vsprintf to
552 // construct the final message
556 va_start(var_args, msg);
557 (void) vsprintf(messageBuffer, _message, var_args);
558 assert(strlen(messageBuffer) < MessageBufferSize);
560 free((char *)_message);
561 _message = (const char *)strdup(messageBuffer);
562 delete [] messageBuffer;
567 DtMailEnv::implGetMessage()
569 if (_client != NULL && _implMessageFunc != NULL) {
570 return((*_implMessageFunc)(_client));
576 DtMailEnv::implGetError()
578 if (_client != NULL && _implErrorFunc != NULL) {
579 return((*_implErrorFunc)(_client));
583 #endif /* DEAD_WOOD */
586 DtMailEnv::logError(DtMailBoolean criticalError, const char *format, ...) const
588 const int MessageBufferSize = 8192;
589 char *messageBuffer = new char[MessageBufferSize+1];
593 // Open the log device and:
594 // LOG_PIG - log the pid number of process.
595 // LOG_CONS - log to the console, if the log device can not be opened.
596 // LOG_NOWAIT - Do not wait for syslog to finish, avoids the use of SIGCHLD
598 openlog("libDtMail", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_MAIL);
603 va_start(var_args, format);
604 (void) vsprintf(messageBuffer, format, var_args);
605 assert(strlen(messageBuffer) < MessageBufferSize);
608 syslog(criticalError == DTM_TRUE ? LOG_CRIT|LOG_ERR : LOG_ERR,
611 _DtSimpleError("libDtMail", criticalError == DTM_TRUE ? DtError : DtWarning,
612 NULL, messageBuffer);
613 delete [] messageBuffer;
618 DtMailEnv::logFatalError(DtMailBoolean criticalError, const char *format, ...)
624 va_start(var_args, format);
625 logError(criticalError, format, var_args);
628 #endif /* DEAD_WOOD */