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 >