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); }
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); }