Hi Wietse,

Thanks for your guidance so far.

I'm trying to use the postfix sendmail command line - and have this working 
(code is still rough).   However, I'm now trying to get any output from the 
command.

To simulate an error, I've intentionally added an invalid -N option - which in 
my manual testing outputs an error about invalid option.

Below is my c code - I can't get the error back in my buffer.  Can you have a 
look at let me know if there's anything obvious I'm doing.

thanks

Kent.


------------------------------------------------------------------------------------------------------
int sendMail ( std::string from, std::string to, std::string message )
{
        int ret_code = -1;
        
        // /usr/sbin/sendmail.postfix -f 'from@email.address' -N 'success, 
delay, failure' 'to@email.address' < tmp

        const char * exec_path = prefs_PostfixUnixPath().c_str();       // 
/usr/sbin/sendmail.postfix 
        std::string _f; _f.assign("-f "); _f.append( from );            // -f 
email@address.domain

        char * child_args[] = {(char *)"-N 'success,delay,failure,invalid'", 
(char *)_f.c_str(), (char *)to.c_str(), NULL};

        int pid;
        int pc[2]; /* Parent to child pipe */
        int cp[2]; /* Child to parent pipe */
        char ch;

        /* Make pipes */
        if( pipe(pc) < 0)       {       log_write("Can't make pipe: pc");       
return -1;      }
        if( pipe(cp) < 0)       {       log_write("Can't make pipe: cp");       
return -1;      }


        // The 'SIGCHLD' signal is triggered when the child fork completes - we 
want to ignore this.
        signal(SIGCHLD,SIG_IGN);                                                
// ignore 'SIGCHLD' signal


        /* Create a child to run command. */
        switch( pid = fork() )
        {
                case -1: 
                                log_write("Error: Can't fork");
                                return -1;
                case 0:
                                                                        // === 
Child ===
                                close(1);                                       
                // Close current stdout.
                                dup2( cp[1], 1 );                               
        // Make stdout go to write end of pipe.
                                close(2);
                                dup2( cp[1], 2 );                               
        // Make stderr go to write end of pipe.
                                close(0);                                       
                // Close current stdin.
                                dup( pc[0] );                                   
        // Make stdin come from read end of pipe.
                                
                                close( pc[1] );                                 
        // Close what we don't need.
                                close( cp[0] );
                                
                                printf("Execute: %s\n", exec_path );
                                
                                execve( exec_path, child_args, NULL);
                                
                                printf("Error: execve failed");         // this 
will only occur if 'execve' had an error.
                                exit(1);
                                
                default:
                                                                        // === 
Parent ===
                                                                                
                                                                // Close what 
we don't need.
                                
                                // the 'pipe' buffer size can vary - let's 
write in 1Kb chunks.  if 'out' == 0, buffer is full - wait and write again.
                                int out = write( pc[1], message.c_str(), 
message.length() );            // write the message to postfix... (this is the 
whole from:, To:, Subject, Body, etc.)
                                
                                
                                close(pc[1]);                                   
                                                // close once written
                                close(cp[1]);

                                int status = 0;
                                char buffer[1024];                              
                                                // Space to store the response 
- is 1Kb enough ???
                                int L = 0;
                                do {
                                        waitpid(pid, &status, 0);
                                        printf("PID Status: %d\n", status );
                                
                                        printf("\nOutput from child:\n");
                                        while( read(cp[0], &ch, 1) == 1)        
                                        // read the reply (if any)  (how do we 
get the errors ???)
                                        {
                                                if( L < 1022 )  buffer[L++] = 
ch;
                                        }
                                        buffer[L] = 0;
                                }
                                while ( !WIFEXITED(status) );
                                
                                printf("Result: %s\n", buffer);
                                ret_code = 1;                                   
                                                // need to check if successful 
or not and return true / false appropriately.
                                break;
        }


        return ret_code;
}








> On 3/06/2017, at 1:32 AM, Wietse Venema <wie...@porcupine.org> wrote:
> 
> Kent:
>> Hi Wietse,
>> 
>> Okay - I think I've worked out the answer to my second question if I use the 
>> sendmail command line, with the -N option.
>> 
>>> /usr/sbin/sendmail.postfix -f t...@dev.kamar.kiwi.nz -N 'success, delay, 
>>> failure' k...@kamar.nz < tmp
>> 
>> Reading through documentation / mailing lists, it looks like this
>> has to be requested per e-mail when using the sendmail command.
>> 
>> Is there anything I can set in the 'main.cf' file to change the
>> default 'delay,failure' to be 'success,delay,failure'  ?
> 
> You can change your sendmail command line.
> 
> You can also specify the notification requirements in SMTP, as
> defined in RFC 3461.
> 
>       Wietse

Reply via email to