Subject: rfc822_output

From: Mike Trank <[email-masked]>
Date: Sun, 19 Mar 2000 10:52:12 -0600 (CST)

In order to do a mail_append of a message that I have constructed in an
ENVELOPE and a BODY,  I need to get the message into a STRING structure.
To do that I am using "rfc822_output" which has as a parameter a pinter to
a funtion that must be like this:

long myfunction(void *mystream, char *mymsg);

and another parameter which is a stream that will get passed to myfunction
along with the message data.

Since I just want to get the data that rfc822_output will construct, can I
make my own function that ignores the first parameter ( the stream
parameter) and just does something with the data, and then specify NIL in
the rfc822_output function, like this:

long myfunction(void *mystream; char *mymsg)

	{

	/* forget about the stream parameter... it got passed NIL */

	STRING *mystring;

	mail_string_init(mystring, mymsg, strlen(mymsg));
	mail_append(NIL, "/home/mike/Mail/outbox", mystring); 
	return(T);
	
	}

rfc822_output(&scratch[0], msgenv, msgbody, myfunction, NIL, NIL);

Does that make sense?

-- 
------------------------------------------------------------------
 For information about this mailing list, and its archives, see: 
 http://www.washington.edu/imap/c-client-list.html
------------------------------------------------------------------

---

From: Mark Crispin <[email-masked]>
Date: Sun, 19 Mar 2000 12:23:15 -0800 (PST)

On Sun, 19 Mar 2000 10:52:12 -0600 (CST), Mike Trank wrote:
> parameter) and just does something with the data

Unfortunately, your idea won't work.  The problem is that the soutr_t function
is called multiple times: for the header, for each body part, and for the
final CRLF.  Consequently your idea of having the soutr_t function call
mail_append() would end up calling mail_append() for each of these calls
separately.

What you need to do is collect the data in the successive soutr_t function
calls.  After rfc822_output() returns, you can then call mail_append() on the
result.

This is where the stream argument becomes useful.  As you may have noticed,
it's a void* so it can be anything.  The easiest thing would be to open a
temporary file via tmpfile() and pass the FILE* as the stream argument to
rfc822_output().  Your soutr_t function would then be just something that
writes the supplied data to the FILE*.  When rfc822_output() returns, you can
then rewind() the FILE*, and use the file stringstruct via
	INIT (mystring,file_string,file,size);
where file is the FILE * and size is the total number of bytes from the
multiple soutr_t calls (so you need to keep track of that too).

Never call a string driver's methods directly, e.g. you should never call
mail_string_init(), file_string_init(), etc.  Always use the supplied mail.h
interface; in this case INIT().  There is no guarantee that calling a string
driver's methods directly will work now, or in the future.  I'm probably going
to start making these things static to prevent people from doing that, so
please follow the rules.