/* * CDE - Common Desktop Environment * * Copyright (c) 1993-2012, The Open Group. All rights reserved. * * These libraries and programs are free software; you can * redistribute them and/or modify them under the terms of the GNU * Lesser General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * These libraries and programs are distributed in the hope that * they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public * License along with these librararies and programs; if not, write * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110-1301 USA */ /* $TOG: DmxMessage.C /main/6 1998/07/24 16:18:17 mgreess $ */ /* *+SNOTICE * * $:$ * * RESTRICTED CONFIDENTIAL INFORMATION: * * The information in this document is subject to special * restrictions in a confidential disclosure agreement between * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this * document outside HP, IBM, Sun, USL, SCO, or Univel without * Sun's specific written approval. This document and all copies * and derivative works thereof must be returned or destroyed at * Sun's request. * * Copyright 1994 Sun Microsystems, Inc. All rights reserved. * *+ENOTICE */ /* * Common Desktop Environment * * (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company * (c) Copyright 1993, 1994, 1995 International Business Machines Corp. * (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc. * (c) Copyright 1993, 1994, 1995 Novell, Inc. * (c) Copyright 1995 Digital Equipment Corp. * (c) Copyright 1995 Fujitsu Limited * (c) Copyright 1995 Hitachi, Ltd. * * * RESTRICTED RIGHTS LEGEND * *Use, duplication, or disclosure by the U.S. Government is subject to *restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in *Technical Data and Computer Software clause in DFARS 252.227-7013. Rights *for non-DOD U.S. Government Departments and Agencies are as set forth in *FAR 52.227-19(c)(1,2). *Hewlett-Packard Company, 3000 Hanover Street, Palo Alto, CA 94304 U.S.A. *International Business Machines Corp., Route 100, Somers, NY 10589 U.S.A. *Sun Microsystems, Inc., 2550 Garcia Avenue, Mountain View, CA 94043 U.S.A. *Novell, Inc., 190 River Road, Summit, NJ 07901 U.S.A. *Digital Equipment Corp., 111 Powdermill Road, Maynard, MA 01754, U.S.A. *Fujitsu Limited, 1015, Kamikodanaka Nakahara-Ku, Kawasaki 211, Japan *Hitachi, Ltd., 6, Kanda Surugadai 4-Chome, Chiyoda-ku, Tokyo 101, Japan */ #include "Dmx.h" // For CHARSET #include #include #if !defined(USL) && !defined(__uxp__) #include #else #include #endif #include "Application.h" #include "DtMail/DtMail.hh" #include "DtMailTypes.h" #include "MailSession.hh" #include "RoamApp.h" #include "str_utils.h" DmxMsg::DmxMsg (void) { // initialize everything message = NULL; addlInfo = NULL; numBPs = 0; cachedValues = DTM_FALSE; return; } void DmxMsg::setHandle (DtMailMessageHandle &h) { msgHandle = h; return; } void DmxMsg::setHeader (DtMailHeaderLine &h) { msgHeader = h; return; } void DmxMsg::setMessage (DtMail::Message *m) { message = m; return; } void DmxMsg::setInfo (char *info) { addlInfo = strdup (info); return; } char * DmxMsg::getMessageHeader (DmxHeaders which) { int i = 0, length = 0; int buflength = 0; char *rtn; const char *str; if (which >= DMXNUMHDRS) return (char *) NULL; length = msgHeader.header_values[which].length (); if (length == 0) str = errorString(which); else str = *((msgHeader.header_values[which])[0]); //need to free this after using it rtn = strdup(str); return (rtn); } 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 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; valgetContents(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::parse (void) { // store the body parts for later reference DtMailEnv env; DtMailBoolean FirstIsText = DTM_FALSE; DtMail::BodyPart *part = NULL, *nextpart = NULL; char *type = NULL, *attr = NULL; int bc = message->getBodyCount (env); if (handleError (env, "getBodyCount") == DTM_TRUE) exit (1); part = message->getFirstBodyPart (env); if (handleError (env, "getFirstBodyPart") == DTM_TRUE) exit (1); part->getContents (env, NULL, NULL, &type, NULL, NULL, NULL); if (handleError (env, "getContents") == DTM_TRUE) exit (1); bodyParts = new (DtMail::BodyPart *[bc]); cachedValues = DTM_TRUE; // cache values bodyParts [0] = part; numBPs++; if (type != NULL) { attr = DtDtsDataTypeToAttributeValue (type, DtDTS_DA_IS_TEXT, NULL); if (attr != NULL) { FirstIsText = DTM_TRUE; } //free (type); // it's allocating some data for us } else { FirstIsText = DTM_FALSE; } // No attachments? We're done. if (bc < 2) return; int i; for (i = 1; i < bc; i++) { nextpart = NULL; nextpart = message->getNextBodyPart (env, part); if (handleError (env, "getNextBodyPart") == DTM_TRUE) exit (1); if (nextpart == NULL) fprintf (stderr, "Error getting part!\n"); bodyParts [i] = nextpart; numBPs++; part = nextpart; } }