home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 2 / goldfish_vol2_cd1.bin / files / comm / mail / smail / src / rcs / deliver.c,v < prev    next >
Text File  |  1993-12-21  |  29KB  |  1,279 lines

  1. head    1.15;
  2. access;
  3. symbols
  4.     C_1:1.15;
  5. locks; strict;
  6. comment    @ * @;
  7.  
  8.  
  9. 1.15
  10. date    93.11.13.23.13.41;    author Aussem;    state Exp;
  11. branches;
  12. next    1.14;
  13.  
  14. 1.14
  15. date    93.11.13.22.11.45;    author Aussem;    state Exp;
  16. branches;
  17. next    1.13;
  18.  
  19. 1.13
  20. date    93.11.09.22.45.05;    author Aussem;    state Exp;
  21. branches;
  22. next    1.12;
  23.  
  24. 1.12
  25. date    93.11.06.16.28.53;    author Aussem;    state Exp;
  26. branches;
  27. next    1.11;
  28.  
  29. 1.11
  30. date    93.11.06.16.03.06;    author Aussem;    state Exp;
  31. branches;
  32. next    1.10;
  33.  
  34. 1.10
  35. date    93.10.29.21.56.53;    author Aussem;    state Exp;
  36. branches;
  37. next    1.9;
  38.  
  39. 1.9
  40. date    93.10.19.00.37.32;    author Aussem;    state Exp;
  41. branches;
  42. next    1.8;
  43.  
  44. 1.8
  45. date    93.10.17.21.14.38;    author Aussem;    state Exp;
  46. branches;
  47. next    1.7;
  48.  
  49. 1.7
  50. date    93.10.16.15.17.42;    author Aussem;    state Exp;
  51. branches;
  52. next    1.6;
  53.  
  54. 1.6
  55. date    93.09.30.21.43.33;    author Aussem;    state Exp;
  56. branches;
  57. next    1.5;
  58.  
  59. 1.5
  60. date    93.09.29.13.14.46;    author Aussem;    state Exp;
  61. branches;
  62. next    1.4;
  63.  
  64. 1.4
  65. date    93.09.18.16.47.47;    author Aussem;    state Exp;
  66. branches;
  67. next    1.3;
  68.  
  69. 1.3
  70. date    93.09.13.22.36.22;    author Aussem;    state Exp;
  71. branches;
  72. next    1.2;
  73.  
  74. 1.2
  75. date    93.09.10.01.52.44;    author Aussem;    state Exp;
  76. branches;
  77. next    1.1;
  78.  
  79. 1.1
  80. date    93.09.08.16.27.13;    author Aussem;    state Exp;
  81. branches;
  82. next    ;
  83.  
  84.  
  85. desc
  86. @delivering routines
  87. @
  88.  
  89.  
  90. 1.15
  91. log
  92. @MAXLINE inserted
  93. Received: header is never longer then MAXLINE
  94. @
  95. text
  96. @/*
  97.  *  Deliver.c
  98.  *
  99.  *  Routines to effect delivery of mail for rmail/smail.
  100.  *
  101.  * This program is free software; you can redistribute it and/or
  102.  * modify it under the terms of the GNU General Public License as
  103.  * published by the Free Software Foundation; either version 2 of
  104.  * the License, or (at your option) any later version.
  105.  *
  106.  * This program is distributed in the hope that it will be useful,
  107.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  108.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  109.  * General Public License for more details.
  110.  *
  111.  * You should have received a copy of the GNU General Public License
  112.  * along with this program; if not, write to the Free Software
  113.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  114.  *
  115.  * $Log: deliver.c,v $
  116.  * Revision 1.14  1993/11/13  22:11:45  Aussem
  117.  * check_site() parameters corrected
  118.  * Recieved lines are written for mails with sendmail too
  119.  * nicer recieved lines
  120.  *
  121.  * Revision 1.13  1993/11/09  22:45:05  Aussem
  122.  * user access check implemented
  123.  *
  124.  * Revision 1.12  1993/11/06  16:28:53  Aussem
  125.  * cosmetic changes in return_*()
  126.  *
  127.  * Revision 1.11  1993/11/06  16:03:06  Aussem
  128.  * from buffer isn't longer overwritten by receipt: generation
  129.  * return_*() functions now works better
  130.  *
  131.  * Revision 1.10  1993/10/29  21:56:53  Aussem
  132.  * received header is now more smail like :-)
  133.  *
  134.  * Revision 1.9  1993/10/19  00:37:32  Aussem
  135.  * BSMTP fully implemented
  136.  *
  137.  * Revision 1.8  1993/10/17  21:14:38  Aussem
  138.  * cosmetic changes
  139.  *
  140.  * Revision 1.7  1993/10/16  15:17:42  Aussem
  141.  * returnmail flag implemented
  142.  * if a mail is returned (because failing or Return-To-Receipt header)
  143.  * smail is started with -M flag. So we can prevent endless loops
  144.  * calling smail.
  145.  *
  146.  * Revision 1.6  1993/09/30  21:43:33  Aussem
  147.  * failed mails will returned to the sender AND postmaster@@<host>
  148.  *
  149.  * Revision 1.5  1993/09/29  13:14:46  Aussem
  150.  * If smail calls smail again, it uses first the uulib:config entry for Sendmail
  151.  * and if not exists sendmail
  152.  *
  153.  * Revision 1.4  1993/09/18  16:47:47  Aussem
  154.  * insert GNU license text in the header
  155.  *
  156.  * Revision 1.3  1993/09/13  22:36:22  Aussem
  157.  * MaxRMailLen will be used to determinate how long a
  158.  * rmail line could be in a uux file
  159.  *
  160.  * Revision 1.2  1993/09/10  01:52:44  Aussem
  161.  * new support for wCNews styled logfile with maillog()
  162.  *
  163.  * Revision 1.1  1993/09/08  16:27:13  Aussem
  164.  * Initial revision
  165.  *
  166.  *
  167.  */
  168.  
  169. static char     *rcsid="$Id: deliver.c,v 1.14 1993/11/13 22:11:45 Aussem Exp Aussem $";
  170.  
  171. # include    <stdio.h>
  172. # include    <stdlib.h>
  173. # include    <sys/types.h>
  174. # include    <sys/stat.h>
  175. # include    <ctype.h>
  176. # include    "defs.h"
  177.  
  178. extern int  exitstat;        /* set if a forked mailer fails */
  179. extern enum edebug debug;    /* how verbose we are         */ 
  180. extern char hostname[];        /* our uucp hostname         */
  181. extern char hostdomain[];    /* our host's domain         */
  182. extern enum ehandle handle;    /* what we handle        */
  183. extern enum erouting routing;    /* how we're routing addresses  */
  184. extern char *uuxargs;        /* arguments given to uux       */
  185. extern int  queuecost;        /* threshold for queueing mail  */
  186. extern int  maxnoqueue;        /* max number of uucico's       */
  187. extern char *spoolfile;        /* file name of spooled message */
  188. extern FILE *spoolfp;        /* file ptr  to spooled message */
  189. extern int spoolmaster;        /* set if creator of spoolfile  */
  190. extern char nows[];        /* local time in ctime(3) format*/
  191. extern char arpanows[];        /* local time in arpadate format*/
  192. extern int asrmail;        /* invoked as rmail (CMK)    */
  193. extern char return_receipt[];
  194. extern int  maxrmaillen;
  195. extern char smailname[];
  196. extern int  returnmail;
  197. extern int  bsmtp;
  198. extern char prgtype_string[];
  199. extern char version[];
  200.  
  201. static char stderrfile[128];        /* error file for stderr traping*/
  202. static char my_stderrfile[128];
  203.  
  204. /*
  205. **
  206. **  deliver():  hand the letter to the proper mail programs.
  207. **
  208. **  Issues one command for each different host of <hostv>,
  209. **  constructing the proper command for LOCAL or UUCP mail.
  210. **  Note that LOCAL mail has blank host names.
  211. **
  212. **  The <userv> names for each host are arguments to the command.
  213. ** 
  214. **  Prepends a "From" line to the letter just before going 
  215. **  out, with a "remote from <hostname>" if it is a UUCP letter.
  216. **
  217. */
  218.  
  219. deliver(argc, hostv, userv, formv, costv)
  220. int argc;                /* number of addresses        */
  221. char *hostv[];                /* host names            */
  222. char *userv[];                /* user names            */
  223. enum eform formv[];            /* form for each address    */
  224. int costv[];                /* cost vector             */
  225. {
  226.     FILE *out;            /* pipe to mailer        */
  227.     char tmpname[SMLBUF];
  228.     char tobuffer[SMLBUF]; /* buffer for receiver of the mail */
  229.     char pipe_cmd[SMLBUF]=";";
  230.     short pipe=0;
  231.     char from[SMLBUF];        /* accumulated from argument     */
  232.     char lcommand[SMLBUF];        /* local command issued     */
  233.     char rcommand[SMLBUF];        /* remote command issued    */
  234.     char scommand[SMLBUF];        /* retry  command issued    */
  235.     char bcommand[SMLBUF];        /* bsmtp  command issued    */
  236.     char bcmd[SMLBUF];           /* bsmtp  command issued    */
  237.     char *command;            /* actual command        */
  238.     char buf[SMLBUF];        /* copying rest of the letter   */
  239.     enum eform form;        /* holds form[i] for speed     */
  240.     long size;            /* number of bytes of message     */
  241.     char *flags;            /* flags for uux        */
  242.     char *sflag;            /* flag  for smail        */
  243.     int i, j, retrying,local=0;
  244.     char *c;
  245.     int noqcnt = 0;            /* number of uucico's started   */
  246.     char *uux_noqueue = UUX_NOQUEUE;/* uucico starts immediately    */
  247.     char *uux_queue   = UUX_QUEUE;    /* uucico job gets queued       */
  248.     off_t message;
  249.     struct stat st;
  250.  
  251. /*
  252. ** rewind the spool file and read the collapsed From_ line
  253. */
  254.     (void) fseek(spoolfp, 0L, 0);
  255.     (void) fgets(from, sizeof(from), spoolfp);
  256.     if((c = index(from, '\n')) != 0) *c = '\0';
  257.     message = ftell(spoolfp);
  258.    ADVISE("From: %s\n",from);
  259.  
  260.    /* is the sender local ? */
  261.    {
  262.     char domain[SMLBUF]="", user[SMLBUF], adr[SMLBUF];
  263.  
  264.    strcpy(adr,from);
  265.     if(islocal(adr, domain, user))
  266.         local=1;
  267.    }
  268. /*
  269. **  We pass through the list of addresses.
  270. */
  271.     stderrfile[0] = '\0';
  272.     for(i = 0; i < argc; i++) {
  273.         char *lend = lcommand;
  274.         char *rend = rcommand;
  275.         char *send = scommand;
  276.         char *bend = bcommand;
  277. /*
  278. **  If we don't have sendmail, arrange to trap standard error
  279. **  for inclusion in the message that is returned with failed mail.
  280. */
  281.         (void) unlink(stderrfile);
  282.         strcpy(stderrfile,tmpnam(NULL));
  283.         strcpy(my_stderrfile,tmpnam(NULL));
  284.  
  285.         (void) freopen(stderrfile, "w", stderr);
  286.         if(debug != YES) {
  287.             (void) freopen(stderrfile, "w", stdout);
  288.         }
  289.         *bend = *lend = *rend = *send = '\0';
  290.  
  291. /*
  292. **  If form == ERROR, the address was bad
  293. **  If form == SENT, it has been sent on a  previous pass.
  294. */
  295.         form = formv[i];
  296.         if (form == SENT) {
  297.             continue;
  298.         }
  299.  
  300.       /*  
  301.       **  if the sender is local and the mail goes UUCP
  302.       **  and the user have not the permission
  303.       */
  304.         if (local && form == UUCP && checkuid(from))
  305.       {
  306.             if(debug!=YES)
  307.           return_notallowedmail(from);
  308.          ADVISE("'%s' is not allowed to send mail via UUCP/BSMTP\n",from);
  309.             maillog(userv[i],hostv[i],from,0,'-');
  310.             continue;
  311.         }
  312.  
  313. /*
  314. **  Build the command based on whether this is local mail or uucp mail.
  315. **  By default, don't allow more than 'maxnoqueue' uucico commands to
  316. **  be started by a single invocation of 'smail'.
  317. */
  318.         if(uuxargs == NULL) {    /* flags not set on command line */
  319.             if(noqcnt < maxnoqueue && costv[i] <= queuecost) {
  320.                 flags = uux_noqueue;
  321.             } else {
  322.                 flags = uux_queue;
  323.             }
  324.         } else {
  325.             flags = uuxargs;
  326.         }
  327.  
  328.         retrying = 0;
  329.         if(routing == JUSTDOMAIN) {
  330.             sflag = "-o";
  331.         } else if(routing == ALWAYS) {
  332.             sflag = "-O";
  333.         } else {
  334.             sflag = "";
  335.         }
  336.  
  337.         (void) sprintf(lcommand, LMAIL(from, hostv[i]));
  338.         (void) sprintf(bcmd, BMAIL(hostv[i],hostdomain));
  339.         (void) sprintf(rcommand, RMAIL(flags, from, hostv[i]));
  340.  
  341.       /* look whether the host is a BSMTP site */
  342.         if(check_site(hostv[i],debug))
  343.          bsmtp=1;
  344.       else
  345.          bsmtp=0;
  346.  
  347. /*
  348. **  For each address with the same host name and form, append the user
  349. **  name to the command line, and set form = ERROR so we skip this address
  350. **  on later passes.
  351. */
  352.         /* we initialized lend (rend) to point at the
  353.          * beginning of its buffer, so that at
  354.          * least one address will be used regardless
  355.          * of the length of lcommand (rcommand).
  356.          */
  357.         for (j = i; j < argc; j++) {
  358.             if ((formv[j] != form)
  359.              || (strcmpic(hostv[i], hostv[j]) != 0)
  360.              || (!bsmtp &&
  361.                   (((lend - lcommand) > maxrmaillen) ||
  362.                 ((rend - rcommand) > maxrmaillen))))
  363.          {
  364.                 continue;
  365.             }
  366.  
  367.             /*
  368.             ** seek to the end of scommand
  369.             ** and add on a 'smail' command
  370.             ** multiple commands are separated by ';'
  371.             */
  372.  
  373.             send += strlen(send);
  374.             if(send != scommand) {
  375.                 *send++ = ';' ;
  376.             }
  377.  
  378.             (void) sprintf(send, RETRY(sflag));
  379.             send += strlen(send);
  380.  
  381.             lend += strlen(lend);
  382.             bend += strlen(bend);
  383.             rend += strlen(rend);
  384.  
  385.             if (form == LOCAL) {
  386.                 (void) sprintf(lend, LARG(userv[j]));
  387.                 (void) sprintf(send, LARG(userv[j]));
  388.                 (void) sprintf(tobuffer, LARG(userv[j]));
  389.             if(userv[j][0]=='|')
  390.                 {
  391.                     pipe=1;
  392.                     strcpy(pipe_cmd,&userv[j][1]);
  393.                     }
  394.             else pipe=0;
  395.             } else {
  396.                 (void) sprintf(lend, RLARG(hostv[i], userv[j]));
  397.                 (void) sprintf(bend, BARG(userv[j]));
  398.                 (void) sprintf(send, RLARG(hostv[i], userv[j]));
  399.                 (void) sprintf(tobuffer, RLARG(hostv[i], userv[j]));
  400.             }
  401.             (void) sprintf(rend, RARG(userv[j]));
  402.             formv[j] = SENT;
  403.         }
  404. retry:
  405. /*
  406. ** rewind the spool file and read the collapsed From_ line
  407. */
  408.         (void) fseek(spoolfp, message, 0);
  409.  
  410.         /* if the address was in a bogus form (usually DOMAIN),
  411.         ** then don't bother trying the uux.
  412.         **
  413.         ** Rather, go straight to the next smail routing level.
  414.         */
  415.         if(form == ERROR) {
  416.             static char errbuf[SMLBUF];
  417.             (void) sprintf(errbuf,
  418.                 "address resolution ('%s' @@ '%s') failed",
  419.                     userv[i], hostv[i]);
  420.             command = errbuf;
  421.             size    = 0;
  422.             goto form_error;
  423.         }
  424.  
  425.         if (retrying) {
  426.             command = scommand;
  427.         } else if (form == LOCAL) {
  428.             command = lcommand;
  429.         } else {
  430.             strcat(rcommand,"\"");
  431.          if(!bsmtp)
  432.          {
  433.                 command = rcommand;
  434.                 if(flags == uux_noqueue) {
  435.                     noqcnt++;
  436.                 }
  437.             }    
  438.             else
  439.                 command=bcmd;
  440.         }
  441.     if(pipe)
  442.         ADVISE(";PIPE: to %s\n", strchr(command,'|'));
  443.     else
  444.         ADVISE(";COMMAND: %s\n", command);
  445.  
  446.         if (debug == YES) {
  447.             out = stdout;
  448.         } else {
  449.             strcpy(tmpname,tmpnam(NULL));
  450.             out = fopen(tmpname, "w");
  451.         }
  452.         if(out == NULL) {
  453.             exitstat = EX_UNAVAILABLE;
  454.             (void) printf("couldn't open %s.\n", tmpname);
  455.             continue;
  456.         }
  457.  
  458.       if(form!=LOCAL && bsmtp)
  459.           {
  460.          write_bsmtp_prologue(out,from);
  461.           fputs(bcommand,out);
  462.          fputs("DATA\n",out);
  463.          }
  464.         size = 0;
  465.         if(fstat(fileno(spoolfp), &st) >= 0) {
  466.             size = st.st_size - message;
  467.         }
  468. /*
  469. **  Output our From_ line.
  470. */
  471.         if (form == LOCAL) {
  472. /* #ifdef SENDMAIL */
  473.             (void) sprintf(buf, LFROM(from, nows, hostname));
  474.             size += strlen(buf);
  475.             (void) fputs(buf, out);
  476. /* #else
  477.             char *p;
  478.             if((p=index(from, '!')) == NULL) {
  479.                 (void) sprintf(buf,
  480.                     LFROM(from, nows, hostname));
  481.                 size += strlen(buf);
  482.                 (void) fputs(buf, out);
  483.             } else {
  484.                 *p = '\0';
  485.                 (void) sprintf(buf, RFROM(p+1, nows, from));
  486.                 size += strlen(buf);
  487.                 (void) fputs(buf, out);
  488.                 *p = '!';
  489.             }
  490. #endif */
  491.         } else {
  492.             (void) sprintf(buf, RFROM(from, nows, hostname));
  493.             size += strlen(buf);
  494.             (void) fputs(buf, out);
  495.         }
  496.  
  497.         /*if(asrmail)/* Received only if Mail coming from */
  498.                 /* remote sites... (CMK)         */
  499.         {
  500.             char domain[SMLBUF]="", user[SMLBUF], tmp[SMLBUF];
  501.             int ret;
  502.             size_t len,tmp_len;
  503.  
  504.          /* Don't overwrite the from buffer */
  505.          strcpy(tmp,from);
  506.  
  507.          ret=islocal(tmp, domain, user);
  508.             if(!ret)
  509.             {
  510.            strcpy(tmp,"Received: from ");
  511.            strcat(tmp,domain);
  512.            strcat(tmp," ");
  513.            strcpy(buf,tmp);
  514.            len=strlen(buf);
  515.  
  516.            strcpy(tmp,"by ");
  517.            strcat(tmp,hostdomain);
  518.            strcat(tmp," ");
  519.            tmp_len=strlen(tmp);
  520.            if(len+tmp_len>MAXLINE)
  521.                {
  522.                strcat(buf,"\n\t");
  523.                len=0;
  524.                }
  525.            len+=tmp_len;
  526.            strcat(buf,tmp);
  527.  
  528.            sprintf(tmp,"with %s ",check_site(domain,NO)?"bsmtp":"uucp");
  529.            tmp_len=strlen(tmp);
  530.            if(len+tmp_len>MAXLINE)
  531.                {
  532.                strcat(buf,"\n\t");
  533.                len=0;
  534.                }
  535.            len+=tmp_len;
  536.            strcat(buf,tmp);
  537.  
  538.            sprintf(tmp,"(%s for <%s@@%s>) ",version,userv[i],hostv[i][0]=='\0'?hostdomain:hostv[i]);
  539.            tmp_len=strlen(tmp);
  540.            if(len+tmp_len>MAXLINE)
  541.                {
  542.                strcat(buf,"\n\t");
  543.                len=0;
  544.                }
  545.            len+=tmp_len;
  546.            strcat(buf,tmp);
  547.  
  548.            sprintf(tmp,"id <AA%05d@@%s>; ",getpid(),hostdomain);
  549.            tmp_len=strlen(tmp);
  550.            if(len+tmp_len>MAXLINE)
  551.                {
  552.                strcat(buf,"\n\t");
  553.                len=0;
  554.                }
  555.            len+=tmp_len;
  556.            strcat(buf,tmp);
  557.  
  558.            strcpy(tmp,arpanows);
  559.            tmp_len=strlen(tmp);
  560.            if(len+tmp_len>MAXLINE)
  561.                {
  562.                strcat(buf,"\n\t");
  563.                len=0;
  564.                }
  565.            len+=tmp_len;
  566.            strcat(buf,tmp);
  567.  
  568.            strcat(buf,"\n");
  569.          }
  570.          else
  571.             {
  572.            strcpy(tmp,"Received: by ");
  573.            strcat(tmp,hostdomain);
  574.            strcat(tmp," ");
  575.            strcpy(buf,tmp);
  576.            len=strlen(buf);
  577.  
  578.            sprintf(tmp,"(%s for <%s@@%s>) ",version,userv[i],hostv[i][0]=='\0'?hostdomain:hostv[i]);
  579.            tmp_len=strlen(tmp);
  580.            if(len+tmp_len>MAXLINE)
  581.                {
  582.                strcat(buf,"\n\t");
  583.                len=0;
  584.                }
  585.            len+=tmp_len;
  586.            strcat(buf,tmp);
  587.  
  588.            sprintf(tmp,"id <AA%05d@@%s>; ",getpid(),hostdomain);
  589.            tmp_len=strlen(tmp);
  590.            if(len+tmp_len>MAXLINE)
  591.                {
  592.                strcat(buf,"\n\t");
  593.                len=0;
  594.                }
  595.            len+=tmp_len;
  596.            strcat(buf,tmp);
  597.  
  598.            strcpy(tmp,arpanows);
  599.            tmp_len=strlen(tmp);
  600.            if(len+tmp_len>MAXLINE)
  601.                {
  602.                strcat(buf,"\n\t");
  603.                len=0;
  604.                }
  605.            len+=tmp_len;
  606.            strcat(buf,tmp);
  607.  
  608.            strcat(buf,"\n");
  609.          }
  610.             size += strlen(buf);
  611.             (void) fputs(buf, out);
  612.         }
  613.  
  614. /*
  615. **  Copy input.
  616. */
  617.         while(fgets(buf, sizeof(buf), spoolfp) != NULL) {
  618.          if(form!=LOCAL && bsmtp)
  619.             hide_dot(buf, sizeof(buf));
  620.             (void) fputs(buf, out);
  621.         }
  622.       if(form!=LOCAL && bsmtp)
  623.          fputs(".\nQUIT\n",out);
  624.  
  625. if (debug != YES)
  626. {
  627. char buf[BIGBUF];
  628. int my_system(char *,char *);
  629.  
  630. fclose(out);
  631. if(!pipe)
  632.     sprintf(buf,command,tmpname);
  633. else
  634.     sprintf(buf,"%s <%s",pipe_cmd,tmpname);
  635. strcpy(command,buf);
  636. exitstat=my_system(buf,my_stderrfile);
  637. if(exitstat==0)
  638.     {
  639.     remove(my_stderrfile);
  640.    /* sent a receipt message if the address is local */
  641.    /* we are rmail an return_receipt is not empty    */
  642.     if(form == LOCAL && return_receipt[0]!='\0' && asrmail)
  643.         {
  644.         size_t pos=ftell(spoolfp);
  645.  
  646.         fseek(spoolfp, 0L, 0);
  647.        return_receiptmail(userv[i]);
  648.         fseek(spoolfp, pos, 0);
  649.         }
  650.     }
  651. remove(tmpname);
  652. #ifdef MAILLOG
  653.     maillog(userv[i],hostv[i],from,size,exitstat==0?'+':'-');
  654. #endif
  655. }
  656.  
  657. /*
  658. **  Get exit status and if non-zero, set global exitstat so when we exit
  659. **  we can indicate an error.
  660. */
  661. form_error:
  662.         if (debug != YES)  {
  663.             if(form == ERROR) {
  664.                 exitstat = EX_NOHOST;
  665.             }
  666.  
  667.             /*
  668.              * The 'retrying' check prevents a smail loop.
  669.              */
  670.             if(exitstat != 0) {
  671.                 /*
  672.                 ** the mail failed, probably because the host
  673.                 ** being uux'ed isn't in L.sys or local user
  674.                 ** is unknown.
  675.                 */
  676.  
  677.                 if((retrying == 0)    /* first pass */
  678.                 && (routing != REROUTE)    /* have higher level */
  679.                 && (form != LOCAL)) {    /* can't route local */
  680.                     /*
  681.                     ** Try again using a higher
  682.                     ** level of routing.
  683.                     */
  684.                     ADVISE("%s failed (%d)\ntrying %s\n",
  685.                         command, exitstat, scommand);
  686.                     exitstat = 0;
  687.                     retrying = 1;
  688.                     form = SENT;
  689.                     goto retry;
  690.                 }
  691.  
  692.                 /*
  693.                 ** if we have no other routing possibilities
  694.                 ** see that the mail is returned to sender.
  695.                 */
  696.  
  697.                 if((routing == REROUTE)
  698.                     || (form == LOCAL)) {
  699.                     /*
  700.                     ** if this was our last chance,
  701.                     ** return the mail to the sender.
  702.                     */
  703.  
  704.                     ADVISE("%s failed (%d)\n",
  705.                         command, exitstat);
  706.                     
  707.                     (void) fseek(spoolfp, message, 0);
  708.                if(returnmail)
  709.                     {
  710.                         return_mail(from, command);
  711.                     }
  712.                     exitstat = 0;
  713.                 }
  714.             }
  715. # ifdef LOG
  716.             else {
  717.                 if(retrying == 0) log(command, from, size); /* */
  718.             }
  719. # endif
  720.         }
  721.     }
  722. /*
  723. **  Update logs and records.
  724. */
  725. # ifdef RECORD
  726.     (void) fseek(spoolfp, message, 0);
  727.     record(command, from, size);
  728. # endif
  729.  
  730. /*
  731. **  close spool file pointer.
  732. **  if we created it, then unlink file.
  733. */
  734.     (void) fclose(spoolfp);
  735.     if(spoolmaster) {
  736.         (void) unlink(spoolfile);
  737.     }
  738.    fclose(stderr);
  739.     if(debug != YES)
  740.             (void) fclose(stdout);
  741.     (void) unlink(stderrfile);
  742. }
  743.  
  744. /*
  745. ** return mail to sender, as determined by From_ line.
  746. */
  747. return_mail(from, fcommand)
  748. char *from, *fcommand;
  749. {
  750.     char buf[SMLBUF];
  751.     char domain[SMLBUF], user[SMLBUF];
  752.     char *r;
  753.     FILE *fp, *out;
  754.     char tmpname[SMLBUF];
  755.     char cmd[SMLBUF];
  756.  
  757.    strcpy(tmpname,tmpnam(NULL));
  758.  
  759.     r = cmd;
  760.  
  761.    /* -M for don't return mail if THIS mail failed */
  762.     (void) sprintf(r, "%s <%s %s -M -f MAILER-DAEMON -R \"Mail Delivery Subsystem\" ", smailname, tmpname,VFLAG);
  763.     r += strlen(r);
  764.  
  765.     if(islocal(from, domain, user)) {
  766.         (void) sprintf(r, LARG(user));
  767.     } else {
  768.         (void) sprintf(r, RLARG(domain, user));
  769.     }
  770.  
  771.     out = fopen(tmpname, "w");
  772.     if(out == NULL) {
  773.         (void) printf("couldn't open %s.\n", tmpname);
  774.         return;
  775.     }
  776.  
  777.     (void) fprintf(out, "Cc: postmaster@@%s\n", hostdomain);
  778.     (void) fprintf(out, "Subject: failed mail\n");
  779.     (void) fprintf(out, "\n");
  780.     (void) fprintf(out, "=======     command failed      =======\n");
  781.     (void) fprintf(out, " COMMAND: %s\n", fcommand);
  782.     (void) fprintf(out, "======= standard error follows  =======\n");
  783.     (void) fflush(stderr);
  784.     if((fp = fopen(my_stderrfile, "r")) != NULL) {
  785.         while(fgets(buf, sizeof(buf), fp) != NULL) {
  786.             (void) fputs(buf, out);
  787.         }
  788.     }
  789.     (void) fclose(fp);
  790.     (void) fprintf(out, "======= text of message follows =======\n");
  791. /*
  792. **  Copy input.
  793. */
  794.     while(fgets(buf, sizeof(buf), spoolfp) != NULL) {
  795.         (void) fputs(buf, out);
  796.     }
  797.     (void) fclose(out);
  798.     system(cmd);
  799.     remove(tmpname);
  800.     remove(my_stderrfile);
  801. }
  802.  
  803. void return_receiptmail(char *from)
  804. {
  805.     char buf[SMLBUF];
  806.     char domain[SMLBUF], user[SMLBUF];
  807.     char *r;
  808.     FILE *out;
  809.     char tmpname[SMLBUF];
  810.     char cmd[SMLBUF];
  811.  
  812.    strcpy(tmpname,tmpnam(NULL));
  813.  
  814.     r = cmd;
  815.  
  816.    /* -M for don't return mail if THIS mail failed */
  817.     (void) sprintf(r, "%s <%s %s -M -f MAILER-DAEMON -R \"Mail Delivery Subsystem\" ", smailname, tmpname,VFLAG);
  818.     r += strlen(r);
  819.  
  820.     if(islocal(return_receipt, domain, user)) {
  821.         (void) sprintf(r, LARG(user));
  822.     } else {
  823.         (void) sprintf(r, RLARG(domain, user));
  824.     }
  825.  
  826.     out = fopen(tmpname, "w");
  827.  
  828.     if(out == NULL) {
  829.         (void) printf("couldn't open %s.\n", tmpname);
  830.         return;
  831.     }
  832.  
  833.     (void) fprintf(out, "Subject: Returned Mail: Return Receipt\n");
  834.     (void) fprintf(out, "\nYour message has been successfully delivered to '%s'\n\n",from);
  835.  
  836.     (void) fprintf(out, "======= header of message follows =======\n");
  837.    /* skip the first line */
  838.    fgets(buf, sizeof(buf), spoolfp);
  839.    /* copy the header */
  840.     while(fgets(buf, sizeof(buf), spoolfp) != NULL && buf[0]!='\n') {
  841.         (void) fputs(buf, out);
  842.     }
  843.     (void) fclose(out);
  844.     system(cmd);
  845.     remove(tmpname);
  846. }
  847.  
  848. /*
  849. ** return mail to sender (who is not allowed to mail via UUCP),
  850. ** as determined by From_ line.
  851. */
  852. return_notallowedmail(from)
  853. char *from;
  854. {
  855.     char buf[SMLBUF];
  856.     char domain[SMLBUF], user[SMLBUF];
  857.     char *r;
  858.     FILE *out;
  859.     char tmpname[SMLBUF];
  860.     char cmd[SMLBUF];
  861.  
  862.    strcpy(tmpname,tmpnam(NULL));
  863.  
  864.     r = cmd;
  865.  
  866.    /* -M for don't return mail if THIS mail failed */
  867.     (void) sprintf(r, "%s <%s %s -M -f MAILER-DAEMON -R \"Mail Delivery Subsystem\" ", smailname, tmpname,VFLAG);
  868.     r += strlen(r);
  869.  
  870.     if(islocal(from, domain, user)) {
  871.         (void) sprintf(r, LARG(user));
  872.     } else {
  873.         (void) sprintf(r, RLARG(domain, user));
  874.     }
  875.  
  876.     out = fopen(tmpname, "w");
  877.     if(out == NULL) {
  878.         (void) printf("couldn't open %s.\n", tmpname);
  879.         return;
  880.     }
  881.  
  882.     (void) fprintf(out, "Cc: postmaster@@%s\n", hostdomain);
  883.     (void) fprintf(out, "Subject: not allowed mail\n");
  884.     (void) fprintf(out, "\n'%s'\nis not allowed to send mail with UUCP/BSMTP trough the \n'%s'\nAsk your local system administrator for more help\n\n",from,hostdomain);
  885.     (void) fprintf(out, "======= text of message follows =======\n");
  886. /*
  887. **  Copy input.
  888. */
  889.     while(fgets(buf, sizeof(buf), spoolfp) != NULL) {
  890.         (void) fputs(buf, out);
  891.     }
  892.     (void) fclose(out);
  893.     system(cmd);
  894.     remove(tmpname);
  895.     remove(my_stderrfile);
  896. }
  897. @
  898.  
  899.  
  900. 1.14
  901. log
  902. @check_site() parameters corrected
  903. Recieved lines are written for mails with sendmail too
  904. nicer recieved lines
  905. @
  906. text
  907. @d21 5
  908. d74 1
  909. a74 1
  910. static char     *rcsid="$Id: deliver.c,v 1.13 1993/11/09 22:45:05 Aussem Exp Aussem $";
  911. d405 1
  912. a405 1
  913.             char domain[SMLBUF]="", user[SMLBUF], adr[SMLBUF];
  914. d407 1
  915. d410 1
  916. a410 1
  917.          strcpy(adr,from);
  918. d412 1
  919. a412 1
  920.          ret=islocal(adr, domain, user);
  921. d415 59
  922. a473 5
  923.             (void) sprintf(buf,
  924.                 "Received: from %s by %s with %s (%s for <%s@@%s>)\n\tid <AA%05d@@%s>; %s\n",
  925.                     domain,hostdomain,check_site(domain,NO)?"bsmtp":"uucp",
  926.                version,userv[i],hostv[i][0]=='\0'?hostdomain:hostv[i],
  927.                     getpid(),hostdomain, arpanows);
  928. d477 37
  929. a513 5
  930.             (void) sprintf(buf,
  931.                 "Received: by %s (%s for <%s@@%s>)\n\tid <AA%05d@@%s>; %s\n",
  932.                     hostdomain,
  933.                version,userv[i],hostv[i][0]=='\0'?hostdomain:hostv[i],
  934.                     getpid(),hostdomain, arpanows);
  935. @
  936.  
  937.  
  938. 1.13
  939. log
  940. @user access check implemented
  941. @
  942. text
  943. @d21 3
  944. d69 1
  945. a69 1
  946. static char     *rcsid="$Id: deliver.c,v 1.12 1993/11/06 16:28:53 Aussem Exp Aussem $";
  947. d98 2
  948. d240 3
  949. a242 1
  950.         if(check_site(hostv[i]))
  951. d397 1
  952. a397 1
  953.         if(asrmail)    /* Received only if Mail coming from */
  954. d401 1
  955. d405 3
  956. a407 1
  957.             if(!islocal(adr, domain, user))
  958. d410 3
  959. a412 2
  960.                 "Received: from %s by %s with %s (%s)\n\tid <AA%05d@@%s>; %s\n",
  961.                     domain,hostdomain,bsmtp?"bsmtp":"uucp",VERSION,
  962. d418 3
  963. a420 2
  964.                 "Received: by %s with %s (%s)\n\tid <AA%05d@@%s>; %s\n",
  965.                     hostdomain,bsmtp?"bsmtp":"uucp",VERSION,
  966. @
  967.  
  968.  
  969. 1.12
  970. log
  971. @cosmetic changes in return_*()
  972. @
  973. text
  974. @d21 3
  975. d66 1
  976. a66 1
  977. static char     *rcsid="$Id: deliver.c,v 1.11 1993/11/06 16:03:06 Aussem Exp Aussem $";
  978. d138 1
  979. a138 1
  980.     int i, j, retrying;
  981. a145 1
  982.  
  983. d153 1
  984. d155 8
  985. d194 14
  986. a594 4
  987. #ifdef ORIG
  988.    /* if this line is included smail splits them into two mails */
  989.     (void) fprintf(out, "From %s\n", from);
  990. #endif
  991. d647 50
  992. @
  993.  
  994.  
  995. 1.11
  996. log
  997. @from buffer isn't longer overwritten by receipt: generation
  998. return_*() functions now works better
  999. @
  1000. text
  1001. @d21 4
  1002. d63 1
  1003. a63 1
  1004. static char     *rcsid="$Id: deliver.c,v 1.10 1993/10/29 21:56:53 Aussem Exp Aussem $";
  1005. d538 1
  1006. a538 1
  1007.     (void) sprintf(r, "%s <%s %s -M ", smailname, tmpname,VFLAG);
  1008. a552 2
  1009.     (void) fprintf(out, "Date: %s\n", arpanows);
  1010.     (void) fprintf(out, "From: MAILER-DAEMON@@%s (Mail Delivery Subsystem)\n", hostdomain);
  1011. d597 1
  1012. a597 1
  1013.     (void) sprintf(r, "%s <%s %s -M ", smailname, tmpname,VFLAG);
  1014. a612 2
  1015.     (void) fprintf(out, "Date: %s\n", arpanows);
  1016.     (void) fprintf(out, "From: MAILER-DAEMON@@%s(Mail Delivery Subsystem)\n", hostdomain);
  1017. @
  1018.  
  1019.  
  1020. 1.10
  1021. log
  1022. @received header is now more smail like :-)
  1023. @
  1024. text
  1025. @d21 3
  1026. d59 1
  1027. a59 1
  1028. static char     *rcsid="$Id: deliver.c,v 1.9 1993/10/19 00:37:32 Aussem Exp Aussem $";
  1029. d364 1
  1030. a364 1
  1031.             char domain[SMLBUF]="", user[SMLBUF];
  1032. d366 3
  1033. a368 2
  1034.          islocal(from, domain, user);
  1035.             if(domain[0]!='\0')
  1036. d419 1
  1037. a419 1
  1038.        return_receiptmail();
  1039. d425 1
  1040. a425 1
  1041.     maillog(&tobuffer[1],from,size,exitstat==0?'+':'-');
  1042. a426 1
  1043.  
  1044. d550 1
  1045. a550 1
  1046.     (void) fprintf(out, "From: MAILER-DAEMON@@%s\n", hostdomain);
  1047. d554 2
  1048. a555 2
  1049.     (void) fprintf(out, "=======     command failed      =======\n\n");
  1050.     (void) fprintf(out, " COMMAND: %s\n\n", fcommand);
  1051. d581 1
  1052. a581 1
  1053. void return_receiptmail(void)
  1054. d612 4
  1055. a615 3
  1056.     (void) fprintf(out, "From: MAILER-DAEMON@@%s\n", hostdomain);
  1057.     (void) fprintf(out, "Subject: %s received your mail\n",hostname);
  1058.     (void) fprintf(out, "\n");
  1059. @
  1060.  
  1061.  
  1062. 1.9
  1063. log
  1064. @BSMTP fully implemented
  1065. @
  1066. text
  1067. @d21 3
  1068. d56 1
  1069. a56 1
  1070. static char     *rcsid="$Id: deliver.c,v 1.8 1993/10/17 21:14:38 Aussem Exp Aussem $";
  1071. a357 8
  1072. #ifdef SENDMAIL
  1073. /*
  1074. **  If using sendmail, insert a Received: line only for mail
  1075. **  that is being passed to uux.  If not using sendmail, always
  1076. **  insert the received line, since sendmail isn't there to do it.
  1077. */
  1078.         if(command == rcommand && handle != ALL)
  1079. #else
  1080. a359 1
  1081. #endif
  1082. d361 5
  1083. d367 11
  1084. a377 3
  1085.                 "Received: by %s (%s)\n\tid AA%05d; %s\n",
  1086.                     hostdomain, VERSION,
  1087.                     getpid(), arpanows);
  1088. @
  1089.  
  1090.  
  1091. 1.8
  1092. log
  1093. @cosmetic changes
  1094. @
  1095. text
  1096. @d21 3
  1097. d53 1
  1098. a53 1
  1099. static char     *rcsid="$Id: deliver.c,v 1.7 1993/10/16 15:17:42 Aussem Exp Aussem $";
  1100. d81 1
  1101. d117 2
  1102. d150 1
  1103. d158 1
  1104. d163 1
  1105. a163 1
  1106.         *lend = *rend = *send = '\0';
  1107. d198 1
  1108. d200 4
  1109. d218 4
  1110. a221 2
  1111.              || ((lend - lcommand) > maxrmaillen)
  1112.              || ((rend - rcommand) > maxrmaillen)) {
  1113. d240 1
  1114. d255 1
  1115. d289 9
  1116. a297 4
  1117.             command = rcommand;
  1118.             if(flags == uux_noqueue) {
  1119.                 noqcnt++;
  1120.             }
  1121. a302 4
  1122. /*
  1123. ** Fork the mailer and set it up for writing so we can send the mail to it,
  1124. ** or for debugging divert the output to stdout.
  1125. */
  1126. a303 5
  1127. /*
  1128. ** We may try to write on a broken pipe, if the uux'd host
  1129. ** is unknown to us.  Ignore this signal, since we can use the
  1130. ** return value of the pclose() as our indication of failure.
  1131. */
  1132. d316 6
  1133. d379 2
  1134. d383 2
  1135. @
  1136.  
  1137.  
  1138. 1.7
  1139. log
  1140. @returnmail flag implemented
  1141. if a mail is returned (because failing or Return-To-Receipt header)
  1142. smail is started with -M flag. So we can prevent endless loops
  1143. calling smail.
  1144. @
  1145. text
  1146. @d21 6
  1147. d50 1
  1148. a50 1
  1149. static char     *rcsid="$Id: deliver.c,v 1.6 1993/09/30 21:43:33 Aussem Exp Aussem $";
  1150. d79 2
  1151. a80 2
  1152. char stderrfile[20];        /* error file for stderr traping*/
  1153. char my_stderrfile[128];
  1154. d501 1
  1155. a501 1
  1156.     (void) sprintf(r, "%s <%s %s -M", smailname, tmpname,VFLAG);
  1157. d562 1
  1158. a562 1
  1159.     (void) sprintf(r, "%s <%s -M %s", smailname, tmpname,VFLAG);
  1160. @
  1161.  
  1162.  
  1163. 1.6
  1164. log
  1165. @failed mails will returned to the sender AND postmaster@@<host>
  1166. @
  1167. text
  1168. @d21 3
  1169. d44 1
  1170. a44 1
  1171. static char     *rcsid="$Id: deliver.c,v 1.5 1993/09/29 13:14:46 Aussem Exp Aussem $";
  1172. d71 1
  1173. d441 1
  1174. a441 8
  1175. #ifdef SENDMAIL
  1176.                     /* if we have sendmail, then it
  1177.                     ** was handed the mail, which failed.
  1178.                     ** sendmail returns the failed mail
  1179.                     ** for us, so we need not do it again.
  1180.                     */
  1181.                     if(form != LOCAL)
  1182. #endif
  1183. d494 2
  1184. a495 1
  1185.     (void) sprintf(r, "%s <%s %s", smailname, tmpname,VFLAG);
  1186. a513 1
  1187.     (void) fprintf(out, "To: %s\n", from);
  1188. a516 1
  1189.  
  1190. d555 2
  1191. a556 1
  1192.     (void) sprintf(r, "%s <%s %s", smailname, tmpname,VFLAG);
  1193. @
  1194.  
  1195.  
  1196. 1.5
  1197. log
  1198. @If smail calls smail again, it uses first the uulib:config entry for Sendmail
  1199. and if not exists sendmail
  1200. @
  1201. text
  1202. @d21 4
  1203. d41 1
  1204. a41 1
  1205. static char     *rcsid="$Id: deliver.c,v 1.4 1993/09/18 16:47:47 Aussem Exp Aussem $";
  1206. d514 1
  1207. @
  1208.  
  1209.  
  1210. 1.4
  1211. log
  1212. @insert GNU license text in the header
  1213. @
  1214. text
  1215. @d21 3
  1216. d37 1
  1217. a37 1
  1218. static char     *rcsid="$Id: deliver.c,v 1.3 1993/09/13 22:36:22 Aussem Exp Aussem $";
  1219. d63 1
  1220. d493 1
  1221. a493 1
  1222.     (void) sprintf(r, "%s <%s %s", SMAIL, tmpname,VFLAG);
  1223. d554 1
  1224. a554 1
  1225.     (void) sprintf(r, "%s <%s %s", SMAIL, tmpname,VFLAG);
  1226. @
  1227.  
  1228.  
  1229. 1.3
  1230. log
  1231. @MaxRMailLen will be used to determinate how long a
  1232. rmail line could be in a uux file
  1233. @
  1234. text
  1235. @d6 14
  1236. d21 4
  1237. d34 1
  1238. a34 1
  1239. static char     *rcsid="$Id: deliver.c,v 1.2 1993/09/10 01:52:44 Aussem Exp Aussem $";
  1240. @
  1241.  
  1242.  
  1243. 1.2
  1244. log
  1245. @new support for wCNews styled logfile with maillog()
  1246. @
  1247. text
  1248. @d7 3
  1249. d16 1
  1250. a16 1
  1251. static char     *rcsid="$Id: deliver.c,v 1.1 1993/09/08 16:27:13 Aussem Exp Aussem $";
  1252. d41 1
  1253. d169 2
  1254. a170 2
  1255.              || ((lend - lcommand) > MAXCLEN)
  1256.              || ((rend - rcommand) > MAXCLEN)) {
  1257. @
  1258.  
  1259.  
  1260. 1.1
  1261. log
  1262. @Initial revision
  1263. @
  1264. text
  1265. @d6 3
  1266. a8 1
  1267.  * $Log$
  1268. d10 1
  1269. d13 1
  1270. a13 1
  1271. static char     *rcsid="$Id$";
  1272. d66 1
  1273. d190 1
  1274. d200 1
  1275. a201 1
  1276.  
  1277. d350 4
  1278. @
  1279.