/*----------------------------------------------------------------------
    Routines used to hand off messages to local agents for sending/posting

 The two exported routines are:

    1) send_handoff()  -- used to pass messages to local transport agent
    2) post_handoff()  -- used to pass messages to local posting agent

 ----*/




/*----------------------------------------------------------------------
    Output routine for rfc822_output_body

Normally this is used for writing a message down a TCP stream, but
writing a MIME body out is complex business so we use it here.
We must convert the network CRLF to the local new line convention, in this
case on UNIX it's LF.
 ----*/
static long
unix_puts(stream_x, string)
    void   *stream_x;
    char   *string;
{
    FILE *stream = (FILE *)stream_x;
    char *p;

    for(p = string; *p; p++)
      if(putc((*p=='\015' && *(p+1)=='\012') ? (p++,'\n') : *p, stream) == EOF)
	return(0L);

    return(1L);					/* T for c-client */
}



/*----------------------------------------------------------------------
    General function to write a message to Berkeley format folder

Args:  folder -- The name of the folder
       env    -- The envelope (header) of the message to save
       bod    -- The message body

Returns: 0 if susccessful, -1 if not

----*/
static int
append_message2(filename, header, bod)
    char    *filename;
    METAENV *header;
    BODY    *bod;
{
    int    rv, save_errno;
    FILE  *folder_stream;
    long   start_of_append;

    if(!filename || !(folder_stream = fopen(filename, "w"))){
        q_status_message2(1, 2, 4, "\007Error opening file \"%s\", %s",
			  filename ? pretty_fn(filename) : "<NO FILE NAME>",
			  error_description(errno));
        return(-1);
    }

    (void) chmod(filename, 0600);
    start_of_append = ftell(folder_stream);

    rv = pine_rfc822_output(header,bod,unix_puts,(TCPSTREAM *)folder_stream);

    fclose(folder_stream);

  done:
    if(!rv){
        save_errno = errno;
        truncate(filename, start_of_append);
        q_status_message2(1, 2, 4, "\007Error \"%s\" writing \"%s\"",
                          error_description(save_errno), pretty_fn(filename));
        dprint(1, (debugfile, "Error writing %s: %s\n",
                   filename, error_description(save_errno)));
        return(-1);
    }
    else 
      return(0);
}



/* ----------------------------------------------------------------------
   Hand off given message to local transport agent

  Args: envelope -- The envelope for the BCC and debugging
        header   -- The text of the message header
        errbuf   -- buffer for reporting errors (assumed non-NULL)
     
   Run the mailer process and pipe the message down to it. Using -t
   option for sendmail so it reads the header and decides what to do.
    Returns string error message or NULL if all is OK
   For now this only drives sendmail.

  ----*/
char *
send_handoff(header, body, errbuf)
    METAENV *header;
    BODY    *body;
    char    *errbuf;
{
    char    mail_cmd[MAXPATH+1];
    char   *tmpfile;
    PIPE_S *syspipe;

    dprint(1, (debugfile, "=== calling sendmail ===\n"));
    *errbuf = '\0';

    if(!header->env->to && !header->env->cc && !header->env->bcc)
      return(NULL);		/* nobody to send to, fail silently */

    if(can_access(SENDMAIL, EXECUTE_ACCESS) != 0){
      sprintf(errbuf, "Mail Transport Agent %s %s",
          SENDMAIL,
          (can_access(SENDMAIL, ACCESS_EXISTS) != 0)
            ? "doesn't exist"
            : "isn't executable");
      return(errbuf);
    }

    if((tmpfile = temp_nam(NULL, "pinesend"))
       && append_message2(tmpfile, header, body) >= 0){

	sprintf(mail_cmd, "( ( %s %s ; /bin/rm -f %s ) < %s & )",
		SENDMAIL, SENDMAILFLAGS, tmpfile, tmpfile);

	dprint(6, (debugfile, "Send command \"%s\"\n", mail_cmd));

	if(syspipe = open_system_pipe(mail_cmd, NULL, PIPE_SYS|PIPE_PROT)){
	    close_system_pipe(&syspipe, PIPE_SYS|PIPE_PROT);
	    /*
	     * wire stuff in HERE to support sendmail verbose mode option...
	     */
	}
	else
	  sprintf(errbuf, "Internal error: %s", error_description(errno));
    }
    else
      sprintf(errbuf, "\007Can't write temp file for sending: %s",
	      error_description(errno));

    if(!*errbuf){
	dprint(1, (debugfile, "Send SUCCESSFUL.\nTo: %s@%s\n",
		   (header->env->to && header->env->to->mailbox)
		     ? header->env->to->mailbox : "NULL",
		   (header->env->to && header->env->to->host)
	             ? header->env->to->host : "NULL"));
	dprint(1, (debugfile, "Subject: %s\nMessage ID: %s\n\n",
		   header->env->subject ? header->env->subject : "NULL",
		   header->env->message_id ? header->env->message_id:"NULL"));
    }
    else
      dprint(1,(debugfile, "** SEND FAILED **\n\terror: %s\n\ttmpfile: %s\n\n",
		errbuf, tmpfile ? tmpfile : "<NULL FILENAME>"));

    if(tmpfile)
      fs_give((void **)&tmpfile);

    return(*errbuf ? errbuf : NULL);
}


/*----------------------------------------------------------------------
   Hand off given message to local posting agent

  Args: envelope -- The envelope for the BCC and debugging
        header   -- The text of the message header
        errbuf   -- buffer for reporting errors (assumed non-NULL)
     
  Fork off mailer process and pipe the message into it
  Called to post news via Inews when NNTP is unavailable
  
BUG, this needs to be filled in 
   ----*/
char *
post_handoff(header, body, errbuf)
     METAENV *header;
     BODY    *body;
    char     *errbuf;
{
    sprintf(errbuf, "Can't post, NNTP-server must be defined!");
    return(errbuf);
}
