void DtMail::Session::poll(DtMailEnv & error) { error.clear(); #if defined(POSIX_THREADS) return; // A thread does this job. #else // We will grab the time and determine what needs to run. // Any events that have expired since the last time we were // called are automatically ran. If the event returns DTM_TRUE, // then reset last_ran to the current time to cause the event // to not run for the full wait interval; otherwise, refrain // and let the event happen again at the next poll interval // time_t now = time(NULL); for (int ev = 0; ev < _events.length(); ev++) { EventRoutine * event = _events[ev]; if ((now - event->last_ran) > event->interval) { if (event->routine(event->client_data) == DTM_TRUE) event->last_ran = now; } } return; #endif }
int DtMail::Session::eventFileDesc(DtMailEnv & error) { error.clear(); return(_event_fd[0]); }
boolean_t handleError (DtMailEnv &dterror, char *msg) { if (dterror.isSet () == DTM_TRUE) { fprintf (stderr, "dtmailpr: (%s) %s\n", msg, (const char *)dterror); dterror.logError (DTM_FALSE, "dtmailpr: (%s) %s\n", msg, (const char *)dterror); dterror.clear (); return B_TRUE; } dterror.clear (); return B_FALSE; }
DtMailBoolean DtMail::Session::pollRequired(DtMailEnv & error) { error.clear(); #if defined(POSIX_THREADS) return(DTM_FALSE); #else return(DTM_TRUE); #endif }
void DtMail::Session::buildImplTable(DtMailEnv & error) { error.clear(); // Let's pick a ridiculous number of implementations. _impls = (Impls *)malloc(sizeof(Impls) * MaxImpls); _impl_names = (const char **)malloc(sizeof(char *) * (MaxImpls + 1)); // We will simply walk through the default implementations // to start, adding them to the impl table. int tbl; for (tbl = 0, _num_impls = 0; initial_impls[tbl].meta_entry_point; tbl++) { // Get the library handle. DynamicLib * dl = CreatePlatformDl(initial_impls[tbl].lib_name); if (dl) { // We are only interested in libraries we can load. _impls[_num_impls].impl_lib = dl; _impls[_num_impls].impl_meta_factory = (MetaImplFactory)dl->getSym(initial_impls[tbl].meta_entry_point); if (_impls[_num_impls].impl_meta_factory == NULL) { delete dl; continue; } _impls[_num_impls].impl_name = strdup(initial_impls[tbl].impl_name); _impl_names[_num_impls] = _impls[_num_impls].impl_name; _num_impls += 1; } } _impl_names[_num_impls] = NULL; if (_num_impls == 0) { error.setError(DTME_NoImplementations); } }
void DtMail::Session::removeEventRoutine(DtMailEnv & error, DtMailEventFunc routine, void * client_data) { error.clear(); for (int slot = 0; slot < _events.length(); slot++) { EventRoutine * event = _events[slot]; if (event->routine == routine && event->client_data == client_data) { delete event; _events.remove(slot); } } }
Boolean FindDialog::compareHeader(DtMailEnv & error, DtMailValueSeq & header, const char * cmpToString) { register int headerOffset = header.length() - 1; error.clear(); while(headerOffset >= 0) { if ((strcasestr(*(header[headerOffset]), cmpToString)) != NULL) { return(TRUE); } headerOffset--; } return(False); }
void DtMail::Session::addEventRoutine(DtMailEnv & error, DtMailEventFunc routine, void * client_data, time_t interval) { error.clear(); EventRoutine * er = new EventRoutine; er->routine = routine; er->client_data = client_data; er->interval = interval; er->last_ran = 0; // This will case this routine to run immediately. _events.append(er); }
void RFCFormat::writeHeaders(DtMailEnv & error, DtMail::Message & msg, DtMailBoolean include_unix_from, const char * extra_headers, const char ** suppress_headers, Buffer & buf) { error.clear(); // First we copy each header from the message to the // buffer. The headers may need encoding to put them away, so // we will apply RFC1522 if necessary. // DtMailHeaderHandle hnd; DtMail::Envelope * env = msg.getEnvelope(error); if (error.isSet()) { return; } char * name = NULL; DtMailValueSeq value; hnd = env->getFirstHeader(error, &name, value); if (!hnd || error.isSet()) { return; } if (include_unix_from && (error.isSet() || strcmp(name, "From") != 0)) { // We require a Unix from line, and we don't have one. // we will make one up using the sender, and the current // date. // char *unix_from = new char[100]; strcpy(unix_from, "From "); DtMailValueSeq sender; env->getHeader(error, DtMailMessageSender, DTM_TRUE, sender); if (error.isSet()) { // We no longer know who this is really from. // strcat(unix_from, "nobody@nowhere"); } else { DtMailAddressSeq * addrSeq = sender[0]->toAddress(); strcat(unix_from, (*addrSeq)[0]->dtm_address); delete addrSeq; } error.clear(); time_t now = time(NULL); char time_format[30]; SafeCtime(&now, time_format, sizeof(time_format)); strcat(unix_from, " "); strcat(unix_from, time_format); buf.appendData(unix_from, strlen(unix_from)); delete [] unix_from; } else { // Put out any header, except Unix From line // if (strcmp(name, "From") == 0) { value.clear(); free(name); hnd = env->getNextHeader(error, hnd, &name, value); } } for (; // First time is determined above. hnd && !error.isSet(); value.clear(), hnd = env->getNextHeader(error, hnd, &name, value)) { const char **hdr; for (hdr = suppress_headers; *hdr; hdr++) { if (strcasecmp(name, *hdr) == 0) break; } //add _is_write_bcc for fixing aix defect 177096 if (*hdr || strcasecmp(name, "bcc") == 0 && !_is_write_bcc ) { free(name); continue; // We will generate these headers. } int name_len = strlen(name); for (int val = 0; val < value.length(); val++) { // // If the value is null or empty do not emit this field const char *valPtr; for (valPtr = *(value[val]); *valPtr && (isspace((unsigned char)*valPtr)); valPtr++) {} if (!*valPtr) continue; buf.appendData(name, name_len); buf.appendData(": ", 2); rfc1522cpy(buf, *(value[val])); } free(name); } error.clear(); buf.appendData(extra_headers, strlen(extra_headers)); // Add new line that terminates the headers. // crlf(buf); }
// // Look for all matching messages. // Boolean FindDialog::findMatching(Boolean findAll) { // TODO - CHECK ERROR!!! DtMailEnv error; unsigned int matchCount = 0; /* NL_COMMENT * This string is displayed on the find dialog status line * when searching for a matching message. */ setStatus(GETMSG(DT_catd, 1, 231, "Searching...")); busyCursor(); theRoamApp.busyAllWindows(NULL); // // Get the active list. // MsgScrollingList * displayList = _roamWindow->list(); // // Find the max. number of messages that we are to find matching. // int numberMessages = displayList->get_num_messages(); // // Are there any messages? // if (numberMessages > 0) { // // A pointer to the currently interesting message. // register DtMailMessageHandle currentHandle = NULL; // // The offset of the currentHandle in the MsgScrollingList. // register int handleOffset; // // Find the current message. We would always start from the // currently selected message. // // Get the handle to the currently displaied message. // DtMailMessageHandle initialHandle = displayList->current_msg_handle(); // // Get the list of DtMailMessageHandle's. MsgHndArray * msgHandles = displayList->get_messages(); // // Up to all of them can match, allocate and clear the list. // DtMailMessageHandle * matchList = NULL; if (findAll) { matchList = new DtMailMessageHandle[numberMessages+1]; } unsigned int matchOffset = 0; // // Deselect all messages. // XmListDeselectAllItems(displayList->baseWidget()); // // Start the search from the initially displaied message (+1). // handleOffset = displayList->position(initialHandle) - 1; if (_searchForward) { handleOffset++; if (handleOffset >= numberMessages) { handleOffset = 0; } } else { handleOffset--; if (handleOffset < 0) { handleOffset = numberMessages - 1; } } for (; handleOffset < numberMessages;) { currentHandle = msgHandles->at(handleOffset)->message_handle; // // See if this message is a match, if it is... // if (compareMessage(currentHandle)) { matchCount++; // // If we are finding all, then add to the list. // If not, then display this message and we are done. // if (findAll) { matchList[matchOffset++] = currentHandle; } else { XmListDeselectAllItems(displayList->baseWidget()); //displayList->set_selected_item_position(handleOffset); displayList->display_and_select_message(error, currentHandle); break; // Only one. } } // // If we have looped back to the initial // message (handle), then we are done. // if (currentHandle == initialHandle) { break; } // // Get the next message. // // If we have reached the end, start over. // (as if the list was a circular list) // // We loop forward (_searchForward == TRUE) else we loop backward. // if (_searchForward) { handleOffset++; if (handleOffset >= numberMessages) { handleOffset = 0; } } else { handleOffset--; if (handleOffset < 0) { handleOffset = numberMessages - 1; } } currentHandle = msgHandles->at(handleOffset)->message_handle; } // // Select all the messages that match, and display the last // one in the list. // if (findAll) { displayList->select_all_and_display_last(error, matchList, matchCount); if (matchCount > 0) { char *line = new char[80]; /* NL_COMMENT * These strings are displayed on the find dialog status line * when one or more matching messages are found. The first * string is displayed when there is one matching message, * and the second string is displayed when there is more than * one. The %d is the number of messages that matched. */ if (matchCount == 1) { strcpy(line, GETMSG(DT_catd, 1, 232, "1 message selected")); } else { sprintf(line, GETMSG(DT_catd, 1, 233, "%d messages selected"), matchCount); } setStatus(line); delete [] line; } // Clean up. delete matchList; matchList = NULL; } } normalCursor(); theRoamApp.unbusyAllWindows(); if (error.isNotSet()) { if (matchCount > 0) { if (!findAll) { clearStatus(); } return(TRUE); } } /* NL_COMMENT * This string is displayed on the find dialog status line when * no matching messages were found. */ setStatus(GETMSG(DT_catd, 1, 234, "No matches were found")); return(False); }
void AttachArea::parseAttachments( DtMailEnv &mail_error, DtMail::Message* msg, Boolean empty, int startBP ) { DtMail::BodyPart * tmpBP; int index = 1; int num_attachments = 0; char * name; // First unmanage and empty out the current contents. // SMD sets this boolean to FALSE so that previous message's attachments // are not cleared. E.g. Including/forwarding multiple messages each // with attachments. // RMW sets this boolean to TRUE so that all attachments are cleared in // the attachment pane everytime a new message is displayed. if ( empty ) { // First unmanage the clipWindow. // Unmanaging the attachment pane is visually ugly XtUnmanageChild(_clipWindow); this->clearAttachArea(); } _deleteCount = 0; // Now fill list with new attachments. tmpBP = msg->getFirstBodyPart(mail_error); if (mail_error.isSet()) { // do something } // Sync up the index with the bodyPart from which to begin // adding attachments into attachPane. // while (startBP > index) { tmpBP = msg->getNextBodyPart(mail_error, tmpBP); index++; } while (tmpBP != NULL) { num_attachments++; tmpBP->getContents( mail_error, NULL, NULL, NULL, &name, NULL, NULL); if (mail_error.isSet()) { // do something } // It is possible for an attachment to not have a name. if (!name) { name = "NoName"; } this->addAttachment(name, tmpBP); tmpBP = msg->getNextBodyPart(mail_error, tmpBP); if (mail_error.isSet()) { // do something } free(name); } }
// // NEEDS TO BE DELETED .. SHOULD NO LONGER BE USED... // void DtMail::Session::setError(DtMailEnv & error, const DTMailError_t minor_code) { error.setError(minor_code); //DtMail::setError(*this, error, minor_code); }
int DtMail::Session::csConvert(char **bp, unsigned long &bp_len, int free_bp, char *from_cs, char *to_cs) { DtMailEnv error; iconv_t cd; size_t ileft = (size_t) bp_len, oleft = (size_t) bp_len, ret = 0; #if defined(_AIX) || defined(sun) || defined(__FreeBSD__) || defined(__NetBSD__) const char *ip = (const char *) *bp; #else char *ip = *bp; #endif char *op = NULL; char *op_start = NULL; int mb_ret = 0; size_t delta; if ( *bp == NULL || **bp == '\0' || bp_len <= 0 ) return 0; if ( to_cs == NULL || from_cs == NULL ) return 0; if ( (cd = iconv_open(to_cs, from_cs)) == (iconv_t) -1 ) { switch (errno) { case EINVAL: error.logError(DTM_FALSE, "DtMail: Conversion from %s to %s is not supported.\n", from_cs, to_cs); break; } // end of switch statement return 0; } // Caller will set _must_free_body to DTM_TRUE if this routine // succeeds. Then this space will be freed appropriately. // Add 1 to buffer size for null terminator. op_start = op = (char *)calloc((unsigned int) bp_len + 1, sizeof(char)); // When ileft finally reaches 0, the conversion still might not be // complete. Here's why we also need to check for E2BIG: Let's // say we're converting from eucJP to ISO-2022-JP, and there's just // enough room in the output buffer for the last input character, // but not enough room for the trailing "ESC ( B" (for switching // back to ASCII). In that case, iconv() will convert the last // input character, decrement ileft to zero, and then set errno to // E2BIG to tell us that it still needs more room for the "ESC ( B". errno = 0; while ( ileft > 0 || errno == E2BIG ) { errno = 0; if ((ret = iconv(cd, &ip, &ileft, &op, &oleft)) == (size_t) -1) { switch (errno) { case E2BIG: // increase output buffer size delta = ileft ? ileft : 3; bp_len += delta; op_start = (char *)realloc( (char *)op_start, (unsigned int) bp_len + 1); op = op_start + bp_len - delta - oleft; oleft += delta; // realloc does not clear out unused space. // Therefore, garbage shows up in output buffer. memset(op, 0, oleft + 1); break; case EILSEQ: // input byte does not belong to input codeset case EINVAL: // invalid input mb_ret = mblen(ip, MB_LEN_MAX); if ( (mb_ret > 0) && (oleft >= mb_ret) ) { strncat(op_start, ip, mb_ret); ip += mb_ret; op += mb_ret; oleft -= mb_ret; ileft -= mb_ret; mb_ret = 0; } else { // mb_ret is either 0 or -1 at this point, // then skip one byte // and try conversion again. ip++; ileft--; } break; case EBADF: // bad conversion descriptor break; } // end of switch statement } } // end of while loop iconv_close(cd); // Is this necessary?? Is _body_decode_len == strlen(_body)?? // Or can _body_decode_len contain spaces?? // Check to see if a body had been allocated by prior decoding. if (free_bp) { free(*bp); } *bp = op_start; bp_len = strlen(*bp); return 1; }
DtMail::Session::Session(DtMailEnv & error, const char * app_name) : _events(16), _valid_keys(2048) { _DtMutex = MutexInit(); error.clear(); _object_signature = 0; _cur_key = 0; // Create the ToolTalk session for managing file locking, // if one doesn't exist. _tt_channel = tt_default_procid(); if (tt_pointer_error(_tt_channel) != TT_OK) { _tt_channel = ttdt_open(&_tt_fd, app_name, "SunSoft", "%I", 0); if (tt_pointer_error(_tt_channel) != TT_OK) { error.setError(DTME_TTFailure); DebugPrintf(1, "DtMail::createSession - ttdt_open returns %s\n", tt_status_message(tt_pointer_error(_tt_channel))); return; } } else { _tt_fd = tt_fd(); } // The event_fd is how we allow async behavior to occur in a // compatible way. We use a Unix domain socket as the file descriptor. // The client will watch for activity on this file descriptor, and // call our event routine when there is activity (either from XtMainLoop, // or through some other method). // pipe(_event_fd); _app_name = strdup(app_name); DtMailEnv b_error; _mail_rc = new MailRc(error, this); buildImplTable(error); if (error.isSet()) { return; } _obj_mutex = MutexInit(); // The default implementation is specified via the DEFAULT_BACKEND // variable. If this is not set in the .mailrc, then choose entry // zero. // const char * value; _mail_rc->getValue(b_error, "DEFAULT_BACKEND", &value); if (b_error.isNotSet()) { _default_impl = lookupImpl(value); if (_default_impl < 0) { _default_impl = 0; } } else { b_error.clear(); _default_impl = 0; } DtMailSigChldList = new DtVirtArray<SigChldInfo *>(8); _busy_cb = NULL; _busy_cb_data = NULL; _canAutoSave = DTM_TRUE; _object_signature = SessionSignature; return; }
char * DmxMsg::getHeaders (DtMailBoolean abbreviated_only) { DtMailEnv error; DtMail::Session *m_session = theRoamApp.session()->session(); DtMail::MailRc *mail_rc = m_session->mailRc(error); DtMail::Envelope *env = message->getEnvelope(error); DtMailHeaderHandle hdr_hnd; char *name; DtMailValueSeq value; // Code from MsgScrollingList - display_message(). // We're trying to reduce heap size by not allocating and // deleting space in every loop iteration. So just have a // fixed size buffer initially. // // Initial line size. When not enough, allocate more. int buffer_size = 2048; char *buffer = new char [buffer_size]; int count = 0; int hdr_num = 0; char *newline = "\n"; char *separator = ": "; int val = 0; // // Iterate through each header in the message and add it // to the buffer. // for (hdr_hnd = env->getFirstHeader(error, &name, value), *buffer = '\0'; hdr_hnd && !error.isSet(); hdr_hnd = env->getNextHeader(error, hdr_hnd, &name, value), hdr_num++) { if (abbreviated_only == DTM_TRUE && (hdr_num != 0 || strcmp(name, "From") != 0)) { DtMailEnv ierror; if (mail_rc->ignore(ierror, name)) { free(name); value.clear(); continue; } } for (val=0; val<value.length(); val++) count += strlen(name) + strlen(*(value[val])) + strlen(separator) + strlen(newline) + 1; if (count > buffer_size) { // Need to increase buffer size. char *new_buffer; buffer_size *= 2; new_buffer = new char [buffer_size]; memset(new_buffer, 0, buffer_size); strcpy(new_buffer, buffer); delete [] buffer; buffer = new_buffer; } for (val=0; val<value.length(); val++) { strcat(buffer, name); if (hdr_num != 0 || strcmp(name, "From") != 0) strcat(buffer, separator); else strcat(buffer, " "); strcat(buffer, *(value[val])); strcat(buffer, newline); } value.clear(); free(name); } // // Need to free this after using; // return buffer; }
void DmxMsg::display ( DmxPrintHeadersEnum header_format, DmxPrintOutputProc print_proc, XtPointer stream) { DtMailEnv env; DtMailBoolean FirstIsText = DTM_FALSE; DtMail::BodyPart *firstPart = NULL, *nextpart = NULL; char *buf = NULL, *description = NULL, *name = NULL, *newline = NULL, *sunDataDescription = NULL, *type = NULL; void *contents = NULL; unsigned long length = 0; int mode = 0; // For CHARSET char v3_cs[64], *mime_cs = NULL, *from_cs = NULL, *to_cs = NULL; // read in body part info if (cachedValues != DTM_TRUE) parse (); firstPart = bodyParts [0]; firstPart->getContents(env, (const void **) &contents, &length, NULL, //type NULL, //name NULL, //mode NULL); //description if (handleError(env, "getContents") == DTM_TRUE) exit (1); // For CHARSET DtMailValueSeq value; DtMailBoolean err = DTM_FALSE; // Get the bodypart's charset - Try MIME first then V3 firstPart->getHeader(env, DtMailMessageContentType, DTM_TRUE, value); if (env.isNotSet()) { mime_cs = firstPart->csFromContentType(value); } else { env.clear(); value.clear(); firstPart->getHeader(env, DtMailMessageV3charset, DTM_TRUE, value); if (env.isNotSet()) { strcpy(v3_cs, *(value[0])); } else { err = DTM_TRUE; env.clear(); value.clear(); } } // If cannot obtain bodypart's charset header, then maybe this message // has only one bodypart, then in this case the charset header maybe // among the message's envelope (main message headers). // Get the envelope of the message (in order to access the headers) DtMail::Envelope *envelope = NULL; if (err == DTM_TRUE) { envelope = message->getEnvelope(env); err = DTM_FALSE; #ifdef DEBUG env.logError( DTM_FALSE, "DEBUG dtmailpr: Looking at main message header\n"); #endif } // Check for MIME charset header and then for V3 charset header if (envelope != NULL) { envelope->getHeader(env, DtMailMessageContentType, DTM_TRUE, value); if (env.isNotSet()) { mime_cs = firstPart->csFromContentType(value); } else { err = DTM_TRUE; env.clear(); } if (mime_cs == NULL || err == DTM_TRUE) { value.clear(); envelope->getHeader(env, DtMailMessageV3charset, DTM_TRUE, value); if (env.isNotSet()) { strcpy(v3_cs, *(value[0])); } else { err = DTM_TRUE; env.clear(); } } } else { #ifdef DEBUG env.logError(DTM_FALSE, "DEBUG dtmailpr: envelope is null\n"); #endif env.clear(); } // Default codeset in case mime_cs and v3_cs are both null. if ((mime_cs == NULL) && (strlen(v3_cs) == 0)) { char *ret = NULL; firstPart->DtXlateOpToStdLocale(DtLCX_OPER_SETLOCALE, setlocale(LC_CTYPE, NULL), NULL, NULL, &ret); strcpy(v3_cs, "DEFAULT"); strcat(v3_cs, "."); strcat(v3_cs, ret); if (ret) free(ret); } // Get iconv from and to codeset and do conversion. int converted = 0; if (mime_cs) { from_cs = firstPart->csToConvName(mime_cs); #ifdef DEBUG env.logError(DTM_FALSE, "DEBUG dtmailpr: mime_cs = %s\n", mime_cs); #endif } else { from_cs = firstPart->csToConvName(v3_cs); #ifdef DEBUG env.logError(DTM_FALSE, "DEBUG dtmailpr: v3_cs = %s\n", v3_cs); #endif } to_cs = firstPart->locToConvName(); #ifdef DEBUG if ( from_cs == NULL ) env.logError(DTM_FALSE, "DEBUG dtmailpr: from_cs is NULL\n"); else env.logError(DTM_FALSE, "DEBUG dtmailpr: from_cs = %s\n", from_cs); if ( to_cs == NULL ) env.logError(DTM_FALSE, "DEBUG dtmailpr: to_cs is NULL\n"); else env.logError(DTM_FALSE, "DEBUG dtmailpr: to_cs = %s\n", to_cs); #endif if ( from_cs && to_cs ) { if ( strcasecmp(from_cs, to_cs) != 0 ) { converted = firstPart->csConvert( (char **)&contents, length, 0, from_cs, to_cs); #ifdef DEBUG env.logError(DTM_FALSE, "DEBUG dtmailpr: converted = %d\n", converted); #endif } } if ( mime_cs ) free ( mime_cs ); if ( from_cs ) free( from_cs ); if ( to_cs ) free ( to_cs ); // End of For CHARSET newline = new char [2]; newline[0] = '\n'; newline[1] = '\0'; // // Print out the message headers. // buf = getPrintedHeaders(header_format); print_proc(stream, buf); print_proc(stream, newline); delete buf; // // Print out the message body. // buf = new char [length + 1]; memset (buf, 0, (unsigned int) length + 1); memmove (buf, contents, (unsigned int) length); buf [length] = '\0'; // null-terminate that puppy print_proc(stream, buf); print_proc(stream, newline); delete [] buf; // For CHARSET if (converted && contents) free(contents); // No attachments? We're done. if (numBPs < 2) return; int i = 0, attbuflen = 0; char *attbuf = NULL; char *sunbuf = NULL; print_proc(stream, newline); for (i = 1; i < numBPs ; i++) { nextpart = bodyParts [i]; if (nextpart == NULL) fprintf (stderr, "Error getting part!\n"); length = 0; type = ""; sunDataDescription = ""; description = ""; name = ""; mode = -1; nextpart->getContents(env, NULL, &length, &type, &name, &mode, &sunDataDescription); if (handleError (env, "getContents") == DTM_TRUE) exit (1); if (type == NULL) type = "(type unknown)"; if (name == NULL) name = "(name unknown)"; if (sunDataDescription == NULL) { description = ""; } else { // should add bracket or something sunbuf = new char [strlen (sunDataDescription) + 10]; sprintf(sunbuf, " (%s)", sunDataDescription); description = sunbuf; } attbuflen = strlen(name) + strlen(type) + strlen(description); attbuf = new char [attbuflen + 64]; sprintf(attbuf, "[%d] \"%s\"%s, %s, %ld bytes", i, name, description, type, length); print_proc(stream, attbuf); print_proc(stream, newline); delete [] attbuf; if (sunbuf != NULL) delete [] sunbuf; } return; }
void DmxMsg::display (void) { DtMailEnv env; boolean_t FirstIsText = B_FALSE; DtMail::BodyPart *firstPart = NULL, *nextpart = NULL; char *type; char *description = NULL; char *sunDataDescription = NULL; char *name = NULL; void * contents = NULL; unsigned long length = 0; int mode = 0; char *buf = NULL; // For CHARSET char *mime_cs = NULL, *from_cs = NULL, *to_cs = NULL; char *v3_cs = new char [64]; if (cachedValues != B_TRUE) parse (); // read in body part info firstPart = bodyParts [0]; firstPart->getContents(env, (const void **) &contents, &length, NULL, //type NULL, //name NULL, //mode NULL); //description if (handleError (env, "getContents") == B_TRUE) exit (1); // For CHARSET DtMailValueSeq value; boolean_t err = B_FALSE; // Get the bodypart's charset - Try MIME first then V3 firstPart->getHeader(env, DtMailMessageContentType, DTM_TRUE, value); if (env.isNotSet()) { mime_cs = firstPart->csFromContentType(value); } else { env.clear(); value.clear(); firstPart->getHeader(env, DtMailMessageV3charset, DTM_TRUE, value); if (env.isNotSet()) { strcpy(v3_cs, *(value[0])); } else { err = B_TRUE; env.clear(); value.clear(); } } // If cannot obtain bodypart's charset header, then maybe this message // has only one bodypart, then in this case the charset header maybe // among the message's envelope (main message headers). // Get the envelope of the message (in order to access the headers) DtMail::Envelope *envelope = NULL; if (err == B_TRUE) { envelope = message->getEnvelope(env); err = B_FALSE; #ifdef DEBUG env.logError(DTM_FALSE, "DEBUG dtmailpr: Looking at main message header\n"); #endif } if (envelope != NULL) { // Check for MIME charset header and then for V3 charset header envelope->getHeader(env, DtMailMessageContentType, DTM_TRUE, value); if (env.isNotSet()) { mime_cs = firstPart->csFromContentType(value); } else { err = B_TRUE; env.clear(); } if (mime_cs == NULL || err == B_TRUE) { value.clear(); envelope->getHeader(env, DtMailMessageV3charset, DTM_TRUE, value); if (env.isNotSet()) { strcpy(v3_cs, *(value[0])); } else { err = B_TRUE; env.clear(); } } } else { #ifdef DEBUG env.logError(DTM_FALSE, "DEBUG dtmailpr: envelope is null\n"); #endif env.clear(); } // Default codeset in case mime_cs and v3_cs are both null. if ((mime_cs == NULL) && (strlen(v3_cs) == 0)) { char *ret = NULL; firstPart->DtXlateOpToStdLocale(DtLCX_OPER_SETLOCALE, setlocale(LC_CTYPE, NULL), NULL, NULL, &ret); strcpy(v3_cs, "DEFAULT"); strcat(v3_cs, "."); strcat(v3_cs, ret); if (ret) free(ret); } // Get iconv from and to codeset and do conversion. int converted = 0; if (mime_cs) { from_cs = firstPart->csToConvName(mime_cs); #ifdef DEBUG env.logError(DTM_FALSE, "DEBUG dtmailpr: mime_cs = %s\n", mime_cs); #endif } else { from_cs = firstPart->csToConvName(v3_cs); #ifdef DEBUG env.logError(DTM_FALSE, "DEBUG dtmailpr: v3_cs = %s\n", v3_cs); #endif } to_cs = firstPart->locToConvName(); #ifdef DEBUG if ( from_cs == NULL ) env.logError(DTM_FALSE, "DEBUG dtmailpr: from_cs is NULL\n"); else env.logError(DTM_FALSE, "DEBUG dtmailpr: from_cs = %s\n", from_cs); if ( to_cs == NULL ) env.logError(DTM_FALSE, "DEBUG dtmailpr: to_cs is NULL\n"); else env.logError(DTM_FALSE, "DEBUG dtmailpr: to_cs = %s\n", to_cs); #endif if ( from_cs && to_cs ) { if ( strcasecmp(from_cs, to_cs) != 0 ) { converted = firstPart->csConvert((char **)&contents, length, 0, from_cs, to_cs); #ifdef DEBUG env.logError(DTM_FALSE, "DEBUG dtmailpr: converted = %d\n", converted); #endif } } if ( mime_cs ) free ( mime_cs ); if ( from_cs ) free( from_cs ); if ( to_cs ) free ( to_cs ); // End of For CHARSET buf = new char [length + 1]; memset (buf, 0, (size_t) length + 1); // have to "seek" length bytes into the // contents buffer memmove (buf, contents, (size_t) length); buf [length] = '\0'; // null-terminate // that puppy // For CHARSET if (converted && contents) free(contents); char *numbuf = new char [10241]; memset (numbuf, 0, 1024); #ifdef NEVER // Don't want "Message 1:" appearing in print output sprintf (numbuf, "Messsage %s:\n%s\n", addlInfo, printHeader (MSGHEADER)); #endif puts(printHeader(MSGHEADER)); puts(buf); fflush(stdout); // No attachments? We're done. if (numBPs < 2) return; int i = 0; char *attbuf = NULL; printf ("\n"); for (i = 1; i < numBPs ; i++) { nextpart = bodyParts [i]; if (nextpart == NULL) fprintf (stderr, "Error getting part!\n"); length = 0; type = ""; sunDataDescription = ""; description = ""; name = ""; mode = -1; nextpart->getContents(env, NULL, &length, &type, &name, &mode, &sunDataDescription); if (handleError (env, "getContents") == B_TRUE) exit (1); if (type == NULL) type = "(unknown)"; if (sunDataDescription == NULL) { description = ""; } else { // should add bracket or something attbuf = new char [strlen (sunDataDescription) +10]; sprintf (attbuf, " (%s)", sunDataDescription); description = attbuf; } if (name == NULL) name = "(name)"; printf ("[%d] \"%s\"%s, ", i, name, description); printf ("%s, %d bytes\n", type, length); if (attbuf != NULL) delete [] attbuf; } delete [] v3_cs; return; }