Attachment* AttachArea::addAttachment( DtMail::Message *msg, DtMail::BodyPart *lastAttBP, String name, DtMailBuffer buf ) { DtMailEnv mail_error; DtMail::BodyPart * bp = NULL; if (!name) name = "noname"; mail_error.clear(); bp = msg->newBodyPart(mail_error, lastAttBP); bp->setContents(mail_error, buf.buffer, buf.size, NULL, name, 0, NULL); Attachment *attachment = new Attachment(this, name, bp, _iconCount + 1); attachment->setAttachArea(this); attachment->initialize(); addToList(attachment); // Update the display. The Compose Window needs immediate update. this->manageList(); return(attachment); }
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; } }
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; }
Attachment* AttachArea::addAttachment( DtMail::Message* msg, DtMail::BodyPart *lastAttBP, char *filename, char *name ) { int fd; struct stat s; Boolean validtype = TRUE; DtMail::BodyPart * bp = NULL; DtMailEnv mail_error; int answer; char *helpId = NULL; mail_error.clear(); char *errormsg = new char[512]; char *buf = new char[2048]; char *buffer = NULL, *lbl; char *fname_start; for (fname_start = filename + strlen(filename) - 1; fname_start >= filename && *fname_start != '/'; fname_start--) { continue; } if (*fname_start == '/') { fname_start += 1; } bp = msg->newBodyPart(mail_error, lastAttBP); if (SafeAccess(filename, F_OK) != 0) { sprintf(buf, GETMSG(DT_catd, 3, 34, "%s does not exist."), filename); answer = this->handleErrorDialog(GETMSG(DT_catd, 1, 81, "Mailer"), buf); delete [] buf; delete [] errormsg; return(NULL); } SafeStat(filename, &s); if(S_ISFIFO(s.st_mode)) { sprintf(errormsg, GETMSG(DT_catd, 12, 4, "Cannot attach FIFO files: %s"), filename); validtype = FALSE; } else if(S_ISCHR(s.st_mode)) { sprintf( errormsg, GETMSG(DT_catd, 12, 5, "Cannot attach character special files: %s"), filename ); validtype = FALSE; } else if(S_ISDIR(s.st_mode)) { sprintf( errormsg, GETMSG(DT_catd, 12, 6, "Cannot attach directories: %s"), filename ); validtype = FALSE; } else if(S_ISBLK(s.st_mode)) { sprintf(errormsg, GETMSG(DT_catd, 12, 7, "Cannot attach block special files: %s"), filename ); validtype = FALSE; } else if(S_ISSOCK(s.st_mode)) { sprintf(errormsg, GETMSG(DT_catd, 12, 8, "Cannot attach socket files: %s"), filename ); validtype = FALSE; } if(validtype == FALSE) { answer = this->handleErrorDialog(GETMSG(DT_catd, 1, 81, "Mailer"), errormsg, NULL); delete [] buf; delete [] errormsg; return(NULL); } fd = SafeOpen(filename, O_RDONLY); if (fd < 0) { sprintf(buf, GETMSG(DT_catd, 3, 35, "Unable to open %s."), filename); helpId = DTMAILHELPNOOPEN; answer = this->handleErrorDialog(GETMSG(DT_catd, 1, 82, "Mailer"), buf, helpId); delete [] buf; delete [] errormsg; return(NULL); } int page_size = (int)sysconf(_SC_PAGESIZE); size_t map_size = (size_t) (s.st_size + (page_size - (s.st_size % page_size))); char * map; #if defined(__osf__) // This version of mmap does NOT allow requested length to be // greater than the file size ... in contradiction to the // documentation (don't round up). map = (char *) mmap(0, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0); #else map = (char *) mmap(0, map_size, PROT_READ, MAP_PRIVATE, fd, 0); #endif if (map == (char *)-1) { // We could not map it for some reason. Let's just read it into // buffer and pass it to XmText. // buffer = new char[s.st_size + 1]; if (!buffer) { sprintf(buf, "%s", GETMSG(DT_catd, 3, 36, "Unable to allocate memory.")); helpId = DTMAILHELPNOALLOCMEM; answer = this->handleErrorDialog(GETMSG(DT_catd, 1, 83, "Mailer"), buf, helpId); return(NULL); } if (read(fd, buffer, (unsigned int) s.st_size) < 0) { SafeClose(fd); return(NULL); } buffer[s.st_size] = 0; bp->setContents( mail_error, buffer, s.st_size, NULL, fname_start, 0, NULL ); } else { // We now have a mapped file. XmText wants a zero terminated // buffer. We get luck with mmap because unless the file is // an even page size, we will have some zero fill bytes that // are legal to access. // // Of course in the case of an even page size file we must // copy the buffer, terminate it and then give it to XmText. // bp->setContents( mail_error, map, s.st_size, NULL, fname_start, 0, NULL ); munmap(map, map_size); } SafeClose(fd); // _iconCount + 1 because iconCount starts at 0 and we want // attachmentCount to begin at 1. attachmentCount is set to be // in the widget's userData. if(name) lbl = strdup(name); else { if(strchr(filename, '/') == NULL) // The name does not include a slash lbl = strdup(filename); else // The name does include a slash lbl = strdup(strrchr(filename, '/')+1); } Attachment *attachment = new Attachment(this, lbl, bp, _iconCount + 1); attachment->setAttachArea(this); attachment->initialize(); addToList( attachment ); // Update the display. The Compose Window needs immediate update. this->manageList(); delete [] buf; delete [] errormsg; return(attachment); }
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); } }
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; }