Hi Wietse,

Further to below - after more testing I am getting errors, but not warnings.  I 
don't know where they are going, but I'm not getting them back at all.

eg.  If I call:
> /usr/sbin/sendmail.postfix -g
> sendmail.postfix: invalid option -- 'g'
> sendmail.postfix: invalid option -- 'g'
> sendmail.postfix: fatal: usage: sendmail.postfix [options]

Then, I do get these errors in my application buffer.

However, if I instead call:
> /usr/sbin/sendmail.postfix -N 'success,delay,failure,invalid' -f 
> k...@kamar.nz k...@test.kamar.kiwi.nz
> sendmail.postfix: warning: unknown DSN NOTIFY command value "invalid" in 
> "success,delay,failure,invalid"
> sendmail.postfix: warning: bad -N option value -- ignored

Then, I don't get these back in either STDOUT or STDERR

I can live with this - as ultimately it doesn't stop the e-mail from being sent.


cheers

Kent.



> 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