bengsig@oracle.nl (Bjorn Engsig) (06/21/89)
In one of our sendmail.cf's, I use a specific mailer defined with a Mmailer line. There can be more reasons for this mailer not being able to deliver the mail: 1. The address given to it is invalid, unknown, etc 2. The mailer is temporarily unable to deliver the mail, e.g. another machine is down, disconnected from the network etc. What I would like to do, is to return the mail to sender in case 1, but simply let the mail be in the sendmail queue in case 2 and let sendmail try again on it's next queue run. Currently, my mailer prints error messages and returns non-zero in both cases, whereby sendmail returns the whole thing to the sender. How do I specify, that sendmail should keep the mail in the queue like it does it with currently unreachble tcp machines. I do not want to change sendmail itself, but only the sendmail.cf and the mailer program. Any good solutions, less good ones, kludges, etc. are very welcome. -- Bjorn Engsig, ORACLE Europe \ / "Hofstadter's Law: It always takes Path: mcvax!orcenl!bengsig X longer than you expect, even if you Domain: bengsig@oracle.nl / \ take into account Hofstadter's Law"
karl@giza.cis.ohio-state.edu (Karl Kleinpaste) (06/22/89)
To cause sendmail to re-queue a piece of mail, the Mmailer called should exit(EX_TEMPFAIL). From <sysexits.h>: ** EX_TEMPFAIL -- temporary failure, indicating something that ** is not really an error. In sendmail, this means ** that a mailer (e.g.) could not create a connection, ** and the request should be reattempted later. --Karl
jsloan@thor.wright.edu (John Sloan) (06/22/89)
From article <KARL.89Jun21171531@giza.cis.ohio-state.edu>, by karl@giza.cis.ohio-state.edu (Karl Kleinpaste): > To cause sendmail to re-queue a piece of mail, the Mmailer called > should exit(EX_TEMPFAIL). From <sysexits.h>: > A For mailers which are too brain damaged to do this, like the Ultrix/DECnet mail11, which takes the rather rude approach in emulating VMS mail11 in that if it can't make a network connection immediately, it throws away your email, you can wrap another program around your mailer and then call the wrapper from Sendmail. e.g. /* ** D N E T M A I L ** ** Module dnetmail ** Author jsloan@CS.Wright.EDU ** Project DECnet/Ultrix ** System Ultrix-32 ** Date 18Jun1986 ** Modifications ** ** 17Apr1987 jsloan improved exit statuses ** 18Jun1987 jsloan added more debugging stuff ** ** Abstract ** ** Frontend which sits betweem Sendmail and Mail11. ** Rewrites user address(es), replacing '_' with '$'. ** This is done because VMS allows $s in user names, ** but Sendmail uses '$' internally. Hack hack hack. ** Does not correct headers, so meaningful internet ** routing is difficult. Does not handle multiple ** users dues to laziness of author. ** ** Now returns more meaningful statuses to Sendmail than ** possible with Mail11. ** ** Dnetmail will keep a trace of messages for debugging ** purposes in the file /tmp/DECnetTrace provided the ** file already exists. This feature is compiled in only ** if DEBUG is defined. ** ** Compile with something similar to ** ** cc -O -o dnetmail dnetmail.c ** strip dnetmail ** cp dnetmail /usr/local/mail ** ** Called from Sendmail as ** ** dnetmail from name to user < message ** */ static char header[]="@(#) dnetmail.c version 1.2 from 88/01/27 by jsloan@SPOTS.Wright.Edu"; #include <stdio.h> #include <ctype.h> #include <sysexits.h> #define TRACE "/tmp/DECnetTrace" #define MAIL11 "/usr/bin/mail11 \'%s\' \'%s\' \'%s\' \'%s\'" #define OLD '_' #define NEW '$' extern char *malloc(), *strcopy(), *strcat(); extern int strlen(); extern FILE *popen(); extern int pclose(); main(argc,argv) int argc; char **argv; { char *from, *name, *to, *user, command[512], work[512]; FILE *trace, *pipefd; int index, status; #ifdef DEBUG if ((trace=fopen(TRACE,"r"))!=NULL) { fclose(trace); trace = fopen(TRACE,"a"); } #endif if (argc != 5) { fprintf(stderr,"dnetmail: %d arguments, exit %d\n",argc,EX_USAGE); exit(EX_USAGE); } from = argv[1]; name = argv[2]; to = argv[3]; user = argv[4]; for (index = 0; index <= strlen(user); index++) if (user[index] == OLD) user[index] = NEW; sprintf(command,MAIL11,from,name,to,user); #ifdef DEBUG if (trace != NULL) fprintf(trace,"DNETMAIL exec \"%s\"\n",command); #endif pipefd = popen(command,"w"); if (pipefd == NULL) { fprintf(stderr,"dnetmail: popen failed, exit %d\n",EX_OSERR); exit(EX_OSERR); } while (fgets(work,sizeof(work),stdin)) { fputs(work,pipefd); #ifdef DEBUG if (trace != NULL) fputs(work,trace); #endif } if ((status = pclose(pipefd)) != 0) { fprintf(stderr,"dnetmail: mail11 status %d, exit %d\n",status,EX_TEMPFAIL); fprintf(stderr,"dnetmail: \"%s\" \"%s\" \"%s\" \"%s\"\n",from,name,to,user); exit(EX_TEMPFAIL); } exit(EX_OK); } ---------- Since the wrapper can't discriminate between unreachable hosts and non-existent users (because the mailer just says "it didn't work"), it will cause sendmail to reattempt delivery until the timeout period specified in the cf is reached. Maybe that's not so bad... if a user is finally defined on the target system prior to expiration of the timeout, deliverly will eventually be successful. Man page available upon request. John Sloan +1 513 259 1384 jsloan%spots.wright.edu@relay.cs.net Wright State University Research Center ...!uunet!ncrlnk!wright!jsloan 3171 Research Blvd., Kettering, OH 45420 ...!osu-cis!wright!jsloan Logical Disclaimer: belong(opinions,jsloan). belong(opinions,_):-!,fail.
avolio@decuac.dec.com (Frederick M. Avolio) (06/23/89)
It seems that John Sloanis running very old (version 1.0?) mail11 code. It has worked correctly since the very next version. In other words, the DECNET ULTRIX Mail11 mailer correctly bounces orleaves queued, depending on the error. In fact, thinking about it, it NEVER bounced mail on HOST UNREACHABLE. In the first version it did bounce mail oon such things as when the user's mailbox was not reachable (unmounted file system for example). Fred
pat@orac.pgh.pa.us (Pat Barron) (06/23/89)
In article <449.nlhp3@oracle.nl> bengsig@oracle.nl (Bjorn Engsig) writes: >How do I specify, that sendmail should keep the mail in the queue like it >does it with currently unreachble tcp machines. I do not want to change >sendmail itself, but only the sendmail.cf and the mailer program. >Any good solutions, less good ones, kludges, etc. are very welcome. Sendmail interprets exit codes from programs according to sysexits.h. If you've written your own mailer, it should either exit with a zero return code, or with one of the codes defined in sysexits.h. If you look in sysexits.h, you will see that there is a return code EX_TEMPFAIL defined to be use for temporary failures. If your mailer program calls "exit(EX_TEMPFAIL)" when it detects a temporary failure, the mail should be retried. --Pat. -- Pat Barron Internet: pat@orac.pgh.pa.us - or - orac!pat@gateway.sei.cmu.edu UUCP: ...!uunet!apexepa!sei!orac!pat - or - ...!pitt!darth!orac!pat
bengsig@oracle.nl (Bjorn Engsig) (06/23/89)
From article <449.nlhp3@oracle.nl> by me: |How do I specify, that sendmail should keep the mail in the queue like it |does it with currently unreachble tcp machines. Thank you; many replies suggest that the mailer (started from the Mmailer line) should return one of the values from /usr/include/sysexit.h. However, a single person has actually looked into the code, and she claims that only the [IPC] mail can be kept in queue. It seems I'll have to do some experimenting. -- Bjorn Engsig, ORACLE Europe \ / "Hofstadter's Law: It always takes Path: mcvax!orcenl!bengsig X longer than you expect, even if you Domain: bengsig@oracle.nl / \ take into account Hofstadter's Law"