Subject: Fetching mails from a mailqueue

From: Jonas Nielsen <[email-masked]>
Date: Wed, 19 Jul 2000 19:58:10 +0200

Hi

I have problems fetching mail from an outqueue, and sending them.

The problem is that when I use mail_fetchstructure it only fetches
the structure and not the actual text in the body

I have managed to send a message with one attachment, using
rfc822_parsemsg in the sourcecode below.

Apparently I'm using the wrong method, since Mark Crispin once wrote:

"In general, you do not call rfc822_parse_msg() directly.  Instead,
you use the top-level mail_fetch_???() functions.  You build your own
BODY structure when calling smtp_mail()."

To me it seems that using a new variable (BODY body;), parse the text
and copy all 13 attributes, seems to result in a lot of code, making
it hard to believe that it's really the right way. Even if it's 
possible to get all the attributes other ways than parsing the text.

It works for me using rfc822_parse_msg(). But the part only contains
the first and the last body, which means that I can't send messages
with attachments.  It's possible that this has nothing to do that I'm
using rfc822_parse_msg(). If so I would appreciate a solution or hint
to whats wrong. If it has anything to do with it I would like to know
why.

Could anyone lead me in the right direction. I'm using POP, not IMAP.

Please explain as detailed as possible. 

It's very hard to follow the pine source code so I would really
appreciate examples.

The code to the specific function is as follows:

int armd_deliver(A_SESSION* session) /* sends messages from an outqueue

{
  char *hostlist[] = {	                 /* SMTP server host list */
    session->user->smtpserver,
    NIL
  };

  long bodylength, headerlength, msgNo;
  int status,i;

  char *header, *text, *tmpbuf, *buf; 
  char tmp[SZ], bodytext[SZ];          	// scratch buffers, large enough
to 						// hold message header
  char headertext[SZ], seq[16];

  BODY *body,*newbody;
  ENVELOPE *env; 
  MESSAGECACHE *element;
  SENDSTREAM* smtpstream;
  STRING bodystring;
  PART *part,*tmppart;
  int partnr;
  long partlength;
  A_MAIL *the_mail;

  the_mail = (A_MAIL*)malloc(sizeof(A_MAIL)) ;

  printf("\n\nOpening Outbox... ");

  if(init_ok) {
    if (outboxstream = mail_open (outboxstream, outboxpath, NIL)) {
      printf("success, %d mesages to send\n",outboxstream->nmsgs);
    }
    else
       error("Smtp server not reachable");

    /* For each message in outqueue */
    for (msgNo=1; msgNo <= outboxstream->nmsgs; msgNo++) {

      /* Fetch the envelope needed for smtp_mail */
      env = mail_fetchstructure (outboxstream,msgNo,&body);

      /* Fetch the header in text needed for rfc822_parse_msg */
      header = mail_fetchheader(outboxstream,1);
      strcpy(headertext,header);
      headerlength = strlen(headertext);

      /* Fetch the bodytext and convert to the STRING structure which
      /* rfc822_parse_msg needs */
      text = mail_fetchtext_full(outboxstream,1,&bodylength,0);
      strcpy(bodytext,text);
      
      if(bodytext) {
	INIT(&bodystring, mail_string, bodytext, bodylength);

	/* Calling rfc822_parsemsg which return a new body structure without 	
        /* the text */
	rfc822_parse_msg(&the_mail->env,&(the_mail->body), headertext,
         headerlength, &bodystring,"",0);

	/* What would be the alternative here ? using a new variable (BODY
        /* body;), parse the text and copy all 13 attributes ? */

	newbody = the_mail->body;

	/* The first part of the_mail is put into tmppart */
	tmppart = the_mail->body->nested.part;
	partnr = 1;
	
	newbody->nested.part = the_mail->body->nested.part;
	
	/* Put the text into the bodies of the part object */	

	do {
	  part = tmppart;
	  sprintf(seq, "%d",partnr);
	  /* Fetch the section of the body */ 
	  tmpbuf = mail_fetchbody(outboxstream, 1, seq, &partlength);
	  /* Copy it to buf */
	  buf = fs_get(partlength+1);
	  strncpy(buf,tmpbuf,partlength + 1);
	  /* And put it into the specific part */

	  /* prints all the buffers */
	  printf("\nBuf %d start:\n %s \nBuf %d end\n", partnr, buf,partnr); 

	  /* but only inserts the first and last */
	  part->body.contents.text.data = (unsigned char *)buf;
	  part->body.contents.text.size = strlen(buf);
	  tmppart = tmppart->next;
	  partnr++;
	} while (part->next != NIL);
      }

      if (env->to) {
	printf ("Sending... %d message(s)\n", msgNo);
	if (smtpstream = smtp_open (hostlist,0)) {
	  if (smtp_mail (smtpstream,"MAIL", env, newbody)) 
	    puts ("[Smtp Ok]");
	  else printf ("[Failed - %s]\n",smtpstream->reply);
	}
      }
    }
    /* Delete mails from outqueue */
    
    mail_setflag(outboxstream,"1:*","\\DELETED");
    mail_expunge(outboxstream);
    
    mail_close(outboxstream);
    smtp_close(smtpstream);
    printf("End of deliver \n");
  }
  return O00 ;
}
-- 
------------------------------------------------------------------
 For information about this mailing list, and its archives, see: 
 http://www.washington.edu/imap/c-client-list.html
------------------------------------------------------------------