Exemple #1
0
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

}
Exemple #2
0
int
DtMail::Session::eventFileDesc(DtMailEnv & error)
{
    error.clear();

    return(_event_fd[0]);
}
Exemple #3
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;
}
Exemple #4
0
DtMailBoolean
DtMail::Session::pollRequired(DtMailEnv & error)
{
    error.clear();

#if defined(POSIX_THREADS)
    return(DTM_FALSE);
#else
    return(DTM_TRUE);
#endif

}
Exemple #5
0
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);
    }
}
Exemple #6
0
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);
	}
    }
}
Exemple #7
0
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);
}
Exemple #8
0
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);
}
Exemple #9
0
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);
}
Exemple #10
0
//
// 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);
}
Exemple #11
0
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);
    }
}
Exemple #12
0
//
// 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);
}
Exemple #13
0
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;
}
Exemple #14
0
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;
}
Exemple #15
0
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;
}
Exemple #16
0
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;
}
Exemple #17
0
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;
}