home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / sendmail-5.65c+IDA-1.4.4.1 / src / RCS / usersmtp.c,v < prev    next >
Encoding:
Text File  |  1991-06-25  |  21.4 KB  |  1,087 lines

  1. head    5.15;
  2. branch    5.15.0;
  3. access;
  4. symbols
  5.     RELEASE:5.15.0.11
  6.     BETA:5.15.0.9
  7.     UICSO:5.15.0
  8.     VANILLA:5.15;
  9. locks; strict;
  10. comment    @ * @;
  11.  
  12.  
  13. 5.15
  14. date    90.06.20.08.37.18;    author paul;    state Exp;
  15. branches
  16.     5.15.0.1;
  17. next    ;
  18.  
  19. 5.15.0.1
  20. date    90.06.20.09.44.12;    author paul;    state Exp;
  21. branches;
  22. next    5.15.0.2;
  23.  
  24. 5.15.0.2
  25. date    90.09.22.18.40.32;    author paul;    state Exp;
  26. branches;
  27. next    5.15.0.3;
  28.  
  29. 5.15.0.3
  30. date    90.10.13.19.16.32;    author paul;    state Exp;
  31. branches;
  32. next    5.15.0.4;
  33.  
  34. 5.15.0.4
  35. date    91.02.17.05.31.21;    author paul;    state Exp;
  36. branches;
  37. next    5.15.0.5;
  38.  
  39. 5.15.0.5
  40. date    91.03.07.18.41.35;    author paul;    state Exp;
  41. branches;
  42. next    5.15.0.6;
  43.  
  44. 5.15.0.6
  45. date    91.04.02.23.09.48;    author paul;    state Exp;
  46. branches;
  47. next    5.15.0.7;
  48.  
  49. 5.15.0.7
  50. date    91.04.05.14.55.15;    author paul;    state Exp;
  51. branches;
  52. next    5.15.0.8;
  53.  
  54. 5.15.0.8
  55. date    91.05.18.18.31.37;    author paul;    state Exp;
  56. branches;
  57. next    5.15.0.9;
  58.  
  59. 5.15.0.9
  60. date    91.05.22.02.30.43;    author paul;    state Exp;
  61. branches;
  62. next    5.15.0.10;
  63.  
  64. 5.15.0.10
  65. date    91.06.13.16.23.34;    author paul;    state Exp;
  66. branches;
  67. next    5.15.0.11;
  68.  
  69. 5.15.0.11
  70. date    91.06.24.20.31.15;    author paul;    state Exp;
  71. branches;
  72. next    ;
  73.  
  74.  
  75. desc
  76. @@
  77.  
  78.  
  79. 5.15
  80. log
  81. @5.64 Berkeley release
  82. @
  83. text
  84. @/*
  85.  * Copyright (c) 1983 Eric P. Allman
  86.  * Copyright (c) 1988 Regents of the University of California.
  87.  * All rights reserved.
  88.  *
  89.  * Redistribution and use in source and binary forms are permitted provided
  90.  * that: (1) source distributions retain this entire copyright notice and
  91.  * comment, and (2) distributions including binaries display the following
  92.  * acknowledgement:  ``This product includes software developed by the
  93.  * University of California, Berkeley and its contributors'' in the
  94.  * documentation or other materials provided with the distribution and in
  95.  * all advertising materials mentioning features or use of this software.
  96.  * Neither the name of the University nor the names of its contributors may
  97.  * be used to endorse or promote products derived from this software without
  98.  * specific prior written permission.
  99.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  100.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  101.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  102.  */
  103.  
  104. # include "sendmail.h"
  105.  
  106. #ifndef lint
  107. #ifdef SMTP
  108. static char sccsid[] = "@@(#)usersmtp.c    5.15 (Berkeley) 6/1/90 (with SMTP)";
  109. #else
  110. static char sccsid[] = "@@(#)usersmtp.c    5.15 (Berkeley) 6/1/90 (without SMTP)";
  111. #endif
  112. #endif /* not lint */
  113.  
  114. # include <sysexits.h>
  115. # include <errno.h>
  116.  
  117. # ifdef SMTP
  118.  
  119. /*
  120. **  USERSMTP -- run SMTP protocol from the user end.
  121. **
  122. **    This protocol is described in RFC821.
  123. */
  124.  
  125. #define REPLYTYPE(r)    ((r) / 100)        /* first digit of reply code */
  126. #define REPLYCLASS(r)    (((r) / 10) % 10)    /* second digit of reply code */
  127. #define SMTPCLOSING    421            /* "Service Shutting Down" */
  128.  
  129. char    SmtpMsgBuffer[MAXLINE];        /* buffer for commands */
  130. char    SmtpReplyBuffer[MAXLINE];    /* buffer for replies */
  131. char    SmtpError[MAXLINE] = "";    /* save failure error messages */
  132. FILE    *SmtpOut;            /* output file */
  133. FILE    *SmtpIn;            /* input file */
  134. int    SmtpPid;            /* pid of mailer */
  135.  
  136. /* following represents the state of the SMTP connection */
  137. int    SmtpState;            /* connection state, see below */
  138.  
  139. #define SMTP_CLOSED    0        /* connection is closed */
  140. #define SMTP_OPEN    1        /* connection is open for business */
  141. #define SMTP_SSD    2        /* service shutting down */
  142. /*
  143. **  SMTPINIT -- initialize SMTP.
  144. **
  145. **    Opens the connection and sends the initial protocol.
  146. **
  147. **    Parameters:
  148. **        m -- mailer to create connection to.
  149. **        pvp -- pointer to parameter vector to pass to
  150. **            the mailer.
  151. **
  152. **    Returns:
  153. **        appropriate exit status -- EX_OK on success.
  154. **        If not EX_OK, it should close the connection.
  155. **
  156. **    Side Effects:
  157. **        creates connection and sends initial protocol.
  158. */
  159.  
  160. jmp_buf    CtxGreeting;
  161.  
  162. smtpinit(m, pvp)
  163.     struct mailer *m;
  164.     char **pvp;
  165. {
  166.     register int r;
  167.     EVENT *gte;
  168.     char buf[MAXNAME];
  169.     extern greettimeout();
  170.  
  171.     /*
  172.     **  Open the connection to the mailer.
  173.     */
  174.  
  175.     if (SmtpState == SMTP_OPEN)
  176.         syserr("smtpinit: already open");
  177.  
  178.     SmtpIn = SmtpOut = NULL;
  179.     SmtpState = SMTP_CLOSED;
  180.     SmtpError[0] = '\0';
  181.     SmtpPhase = "user open";
  182.     setproctitle("%s %s: %s", CurEnv->e_id, pvp[1], SmtpPhase);
  183.     SmtpPid = openmailer(m, pvp, (ADDRESS *) NULL, TRUE, &SmtpOut, &SmtpIn);
  184.     if (SmtpPid < 0)
  185.     {
  186.         if (tTd(18, 1))
  187.             printf("smtpinit: cannot open %s: stat %d errno %d\n",
  188.                pvp[0], ExitStat, errno);
  189.         if (CurEnv->e_xfp != NULL)
  190.         {
  191.             register char *p;
  192.             extern char *errstring();
  193.             extern char *statstring();
  194.  
  195.             if (errno == 0)
  196.             {
  197.                 p = statstring(ExitStat);
  198.                 fprintf(CurEnv->e_xfp,
  199.                     "%.3s %s.%s... %s\n",
  200.                     p, pvp[1], m->m_name, p);
  201.             }
  202.             else
  203.             {
  204.                 r = errno;
  205.                 fprintf(CurEnv->e_xfp,
  206.                     "421 %s.%s... Deferred: %s\n",
  207.                     pvp[1], m->m_name, errstring(errno));
  208.                 errno = r;
  209.             }
  210.         }
  211.         return (ExitStat);
  212.     }
  213.     SmtpState = SMTP_OPEN;
  214.  
  215.     /*
  216.     **  Get the greeting message.
  217.     **    This should appear spontaneously.  Give it five minutes to
  218.     **    happen.
  219.     */
  220.  
  221.     if (setjmp(CtxGreeting) != 0)
  222.         goto tempfail;
  223.     gte = setevent((time_t) 300, greettimeout, 0);
  224.     SmtpPhase = "greeting wait";
  225.     setproctitle("%s %s: %s", CurEnv->e_id, CurHostName, SmtpPhase);
  226.     r = reply(m);
  227.     clrevent(gte);
  228.     if (r < 0 || REPLYTYPE(r) != 2)
  229.         goto tempfail;
  230.  
  231.     /*
  232.     **  Send the HELO command.
  233.     **    My mother taught me to always introduce myself.
  234.     */
  235.  
  236.     smtpmessage("HELO %s", m, MyHostName);
  237.     SmtpPhase = "HELO wait";
  238.     setproctitle("%s %s: %s", CurEnv->e_id, CurHostName, SmtpPhase);
  239.     r = reply(m);
  240.     if (r < 0)
  241.         goto tempfail;
  242.     else if (REPLYTYPE(r) == 5)
  243.         goto unavailable;
  244.     else if (REPLYTYPE(r) != 2)
  245.         goto tempfail;
  246.  
  247.     /*
  248.     **  If this is expected to be another sendmail, send some internal
  249.     **  commands.
  250.     */
  251.  
  252.     if (bitnset(M_INTERNAL, m->m_flags))
  253.     {
  254.         /* tell it to be verbose */
  255.         smtpmessage("VERB", m);
  256.         r = reply(m);
  257.         if (r < 0)
  258.             goto tempfail;
  259.  
  260.         /* tell it we will be sending one transaction only */
  261.         smtpmessage("ONEX", m);
  262.         r = reply(m);
  263.         if (r < 0)
  264.             goto tempfail;
  265.     }
  266.  
  267.     /*
  268.     **  Send the MAIL command.
  269.     **    Designates the sender.
  270.     */
  271.  
  272.     expand("\001g", buf, &buf[sizeof buf - 1], CurEnv);
  273.     if (CurEnv->e_from.q_mailer == LocalMailer ||
  274.         !bitnset(M_FROMPATH, m->m_flags))
  275.     {
  276.         smtpmessage("MAIL From:<%s>", m, buf);
  277.     }
  278.     else
  279.     {
  280.         smtpmessage("MAIL From:<@@%s%c%s>", m, MyHostName,
  281.             buf[0] == '@@' ? ',' : ':', buf);
  282.     }
  283.     SmtpPhase = "MAIL wait";
  284.     setproctitle("%s %s: %s", CurEnv->e_id, CurHostName, SmtpPhase);
  285.     r = reply(m);
  286.     if (r < 0 || REPLYTYPE(r) == 4)
  287.         goto tempfail;
  288.     else if (r == 250)
  289.         return (EX_OK);
  290.     else if (r == 552)
  291.         goto unavailable;
  292.  
  293.     /* protocol error -- close up */
  294.     smtpquit(m);
  295.     return (EX_PROTOCOL);
  296.  
  297.     /* signal a temporary failure */
  298.   tempfail:
  299.     smtpquit(m);
  300.     return (EX_TEMPFAIL);
  301.  
  302.     /* signal service unavailable */
  303.   unavailable:
  304.     smtpquit(m);
  305.     return (EX_UNAVAILABLE);
  306. }
  307.  
  308.  
  309. static
  310. greettimeout()
  311. {
  312.     /* timeout reading the greeting message */
  313.     longjmp(CtxGreeting, 1);
  314. }
  315. /*
  316. **  SMTPRCPT -- designate recipient.
  317. **
  318. **    Parameters:
  319. **        to -- address of recipient.
  320. **        m -- the mailer we are sending to.
  321. **
  322. **    Returns:
  323. **        exit status corresponding to recipient status.
  324. **
  325. **    Side Effects:
  326. **        Sends the mail via SMTP.
  327. */
  328.  
  329. smtprcpt(to, m)
  330.     ADDRESS *to;
  331.     register MAILER *m;
  332. {
  333.     register int r;
  334.     extern char *remotename();
  335.  
  336.     smtpmessage("RCPT To:<%s>", m, remotename(to->q_user, m, FALSE, TRUE));
  337.  
  338.     SmtpPhase = "RCPT wait";
  339.     setproctitle("%s %s: %s", CurEnv->e_id, CurHostName, SmtpPhase);
  340.     r = reply(m);
  341.     if (r < 0 || REPLYTYPE(r) == 4)
  342.         return (EX_TEMPFAIL);
  343.     else if (REPLYTYPE(r) == 2)
  344.         return (EX_OK);
  345.     else if (r == 550 || r == 551 || r == 553)
  346.         return (EX_NOUSER);
  347.     else if (r == 552 || r == 554)
  348.         return (EX_UNAVAILABLE);
  349.     return (EX_PROTOCOL);
  350. }
  351. /*
  352. **  SMTPDATA -- send the data and clean up the transaction.
  353. **
  354. **    Parameters:
  355. **        m -- mailer being sent to.
  356. **        e -- the envelope for this message.
  357. **
  358. **    Returns:
  359. **        exit status corresponding to DATA command.
  360. **
  361. **    Side Effects:
  362. **        none.
  363. */
  364.  
  365. smtpdata(m, e)
  366.     struct mailer *m;
  367.     register ENVELOPE *e;
  368. {
  369.     register int r;
  370.  
  371.     /*
  372.     **  Send the data.
  373.     **    First send the command and check that it is ok.
  374.     **    Then send the data.
  375.     **    Follow it up with a dot to terminate.
  376.     **    Finally get the results of the transaction.
  377.     */
  378.  
  379.     /* send the command and check ok to proceed */
  380.     smtpmessage("DATA", m);
  381.     SmtpPhase = "DATA wait";
  382.     setproctitle("%s %s: %s", CurEnv->e_id, CurHostName, SmtpPhase);
  383.     r = reply(m);
  384.     if (r < 0 || REPLYTYPE(r) == 4)
  385.         return (EX_TEMPFAIL);
  386.     else if (r == 554)
  387.         return (EX_UNAVAILABLE);
  388.     else if (r != 354)
  389.         return (EX_PROTOCOL);
  390.  
  391.     /* now output the actual message */
  392.     (*e->e_puthdr)(SmtpOut, m, CurEnv);
  393.     putline("\n", SmtpOut, m);
  394.     (*e->e_putbody)(SmtpOut, m, CurEnv);
  395.  
  396.     /* terminate the message */
  397.     fprintf(SmtpOut, ".%s", m->m_eol);
  398.     if (Verbose && !HoldErrs)
  399.         nmessage(Arpa_Info, ">>> .");
  400.  
  401.     /* check for the results of the transaction */
  402.     SmtpPhase = "result wait";
  403.     setproctitle("%s %s: %s", CurEnv->e_id, CurHostName, SmtpPhase);
  404.     r = reply(m);
  405.     if (r < 0 || REPLYTYPE(r) == 4)
  406.         return (EX_TEMPFAIL);
  407.     else if (r == 250)
  408.         return (EX_OK);
  409.     else if (r == 552 || r == 554)
  410.         return (EX_UNAVAILABLE);
  411.     return (EX_PROTOCOL);
  412. }
  413. /*
  414. **  SMTPQUIT -- close the SMTP connection.
  415. **
  416. **    Parameters:
  417. **        m -- a pointer to the mailer.
  418. **
  419. **    Returns:
  420. **        none.
  421. **
  422. **    Side Effects:
  423. **        sends the final protocol and closes the connection.
  424. */
  425.  
  426. smtpquit(m)
  427.     register MAILER *m;
  428. {
  429.     int i;
  430.  
  431.     /* if the connection is already closed, don't bother */
  432.     if (SmtpIn == NULL)
  433.         return;
  434.  
  435.     /* send the quit message if not a forced quit */
  436.     if (SmtpState == SMTP_OPEN || SmtpState == SMTP_SSD)
  437.     {
  438.         smtpmessage("QUIT", m);
  439.         (void) reply(m);
  440.         if (SmtpState == SMTP_CLOSED)
  441.             return;
  442.     }
  443.  
  444.     /* now actually close the connection */
  445.     (void) fclose(SmtpIn);
  446.     (void) fclose(SmtpOut);
  447.     SmtpIn = SmtpOut = NULL;
  448.     SmtpState = SMTP_CLOSED;
  449.  
  450.     /* and pick up the zombie */
  451.     i = endmailer(SmtpPid, m->m_argv[0]);
  452.     if (i != EX_OK)
  453.         syserr("smtpquit %s: stat %d", m->m_argv[0], i);
  454. }
  455. /*
  456. **  REPLY -- read arpanet reply
  457. **
  458. **    Parameters:
  459. **        m -- the mailer we are reading the reply from.
  460. **
  461. **    Returns:
  462. **        reply code it reads.
  463. **
  464. **    Side Effects:
  465. **        flushes the mail file.
  466. */
  467.  
  468. reply(m)
  469.     MAILER *m;
  470. {
  471.     (void) fflush(SmtpOut);
  472.  
  473.     if (tTd(18, 1))
  474.         printf("reply\n");
  475.  
  476.     /*
  477.     **  Read the input line, being careful not to hang.
  478.     */
  479.  
  480.     for (;;)
  481.     {
  482.         register int r;
  483.         register char *p;
  484.  
  485.         /* actually do the read */
  486.         if (CurEnv->e_xfp != NULL)
  487.             (void) fflush(CurEnv->e_xfp);    /* for debugging */
  488.  
  489.         /* if we are in the process of closing just give the code */
  490.         if (SmtpState == SMTP_CLOSED)
  491.             return (SMTPCLOSING);
  492.  
  493.         /* get the line from the other side */
  494.         p = sfgets(SmtpReplyBuffer, sizeof SmtpReplyBuffer, SmtpIn);
  495.         if (p == NULL)
  496.         {
  497.             extern char MsgBuf[];        /* err.c */
  498.             extern char Arpa_TSyserr[];    /* conf.c */
  499.  
  500.             /* if the remote end closed early, fake an error */
  501.             if (errno == 0)
  502. # ifdef ECONNRESET
  503.                 errno = ECONNRESET;
  504. # else ECONNRESET
  505.                 errno = EPIPE;
  506. # endif ECONNRESET
  507.  
  508.             message(Arpa_TSyserr, "reply: read error");
  509.             /* if debugging, pause so we can see state */
  510.             if (tTd(18, 100))
  511.                 pause();
  512. # ifdef LOG
  513.             syslog(LOG_INFO, "%s", &MsgBuf[4]);
  514. # endif LOG
  515.             SmtpState = SMTP_CLOSED;
  516.             smtpquit(m);
  517.             return (-1);
  518.         }
  519.         fixcrlf(SmtpReplyBuffer, TRUE);
  520.  
  521.         if (CurEnv->e_xfp != NULL && index("45", SmtpReplyBuffer[0]) != NULL)
  522.         {
  523.             /* serious error -- log the previous command */
  524.             if (SmtpMsgBuffer[0] != '\0')
  525.                 fprintf(CurEnv->e_xfp, ">>> %s\n", SmtpMsgBuffer);
  526.             SmtpMsgBuffer[0] = '\0';
  527.  
  528.             /* now log the message as from the other side */
  529.             fprintf(CurEnv->e_xfp, "<<< %s\n", SmtpReplyBuffer);
  530.         }
  531.  
  532.         /* display the input for verbose mode */
  533.         if (Verbose && !HoldErrs)
  534.             nmessage(Arpa_Info, "%s", SmtpReplyBuffer);
  535.  
  536.         /* if continuation is required, we can go on */
  537.         if (SmtpReplyBuffer[3] == '-' || !isdigit(SmtpReplyBuffer[0]))
  538.             continue;
  539.  
  540.         /* decode the reply code */
  541.         r = atoi(SmtpReplyBuffer);
  542.  
  543.         /* extra semantics: 0xx codes are "informational" */
  544.         if (r < 100)
  545.             continue;
  546.  
  547.         /* reply code 421 is "Service Shutting Down" */
  548.         if (r == SMTPCLOSING && SmtpState != SMTP_SSD)
  549.         {
  550.             /* send the quit protocol */
  551.             SmtpState = SMTP_SSD;
  552.             smtpquit(m);
  553.         }
  554.  
  555.         /* save temporary failure messages for posterity */
  556.         if (SmtpReplyBuffer[0] == '4' && SmtpError[0] == '\0')
  557.             (void) strcpy(SmtpError, &SmtpReplyBuffer[4]);
  558.  
  559.         return (r);
  560.     }
  561. }
  562. /*
  563. **  SMTPMESSAGE -- send message to server
  564. **
  565. **    Parameters:
  566. **        f -- format
  567. **        m -- the mailer to control formatting.
  568. **        a, b, c -- parameters
  569. **
  570. **    Returns:
  571. **        none.
  572. **
  573. **    Side Effects:
  574. **        writes message to SmtpOut.
  575. */
  576.  
  577. /*VARARGS1*/
  578. smtpmessage(f, m, a, b, c)
  579.     char *f;
  580.     MAILER *m;
  581. {
  582.     (void) sprintf(SmtpMsgBuffer, f, a, b, c);
  583.     if (tTd(18, 1) || (Verbose && !HoldErrs))
  584.         nmessage(Arpa_Info, ">>> %s", SmtpMsgBuffer);
  585.     if (SmtpOut != NULL)
  586.         fprintf(SmtpOut, "%s%s", SmtpMsgBuffer,
  587.             m == 0 ? "\r\n" : m->m_eol);
  588. }
  589.  
  590. # endif SMTP
  591. @
  592.  
  593.  
  594. 5.15.0.1
  595. log
  596. @IDA patches
  597. @
  598. text
  599. @a43 1
  600. #define SMTPGOODREPLY    250            /* positive SMTP response */
  601. a48 1
  602. bool    SmtpNeedIntro;            /* set before first error */
  603. d77 2
  604. d84 1
  605. a84 1
  606.     time_t SavedReadTimeout;
  607. d86 1
  608. a97 1
  609.     SmtpNeedIntro = TRUE;
  610. d116 1
  611. a116 1
  612.                     "%.3s %s (%s)... %s\n",
  613. d123 1
  614. a123 1
  615.                     "421 %s (%s)... Deferred: %s\n",
  616. d138 3
  617. a142 3
  618.     SavedReadTimeout = ReadTimeout;
  619.     if (ReadTimeout > 300)
  620.         ReadTimeout = 300;
  621. d144 1
  622. a144 1
  623.     ReadTimeout = SavedReadTimeout;
  624. d224 8
  625. d253 1
  626. a253 1
  627.     smtpmessage("RCPT To:<%s>", m, to->q_user);
  628. d305 1
  629. a305 1
  630.     else if (r != 354 && r != 250)
  631. d361 1
  632. a361 2
  633.     /* now actually close the connection, but without trashing errno */
  634.     i = errno;
  635. a363 1
  636.     errno = i;
  637. d388 1
  638. a388 2
  639.     if (SmtpOut != NULL)
  640.         (void) fflush(SmtpOut);
  641. a392 3
  642.     if (bitnset(M_BSMTP, m->m_flags))
  643.         return (SMTPGOODREPLY);
  644.  
  645. d425 1
  646. a425 12
  647.             /* Report that connection ended prematurely */
  648.             if (CurEnv->e_xfp != NULL)
  649.             {
  650.                 extern char *errstring();
  651.                 extern char *statstring();
  652.  
  653.                 fprintf(CurEnv->e_xfp,
  654.                     "421 %s (%s)... Deferred: %s\n",
  655.                     CurHostName, m->m_name,
  656.                     errstring(errno));
  657.             }
  658.  
  659. a440 5
  660.             /* also record who we were talking before first error */
  661.             if (SmtpNeedIntro)
  662.                 fprintf(CurEnv->e_xfp,
  663.                     "While talking to %s:\n", CurHostName);
  664.             SmtpNeedIntro = FALSE;
  665. @
  666.  
  667.  
  668. 5.15.0.2
  669. log
  670. @First revisions to support HEAD and MULT extensions to SMTP for DEC's
  671. mail11v3 program.
  672. @
  673. text
  674. @d24 1
  675. a24 1
  676. # ifdef SMTP
  677. d26 1
  678. a26 1
  679. # else /* ! SMTP */
  680. d28 2
  681. a29 2
  682. # endif /* SMTP */
  683. #endif /* ! lint */
  684. d34 1
  685. a34 1
  686. #ifdef SMTP
  687. d42 4
  688. a45 4
  689. # define REPLYTYPE(r)    ((r) / 100)        /* first digit of reply code */
  690. # define REPLYCLASS(r)    (((r) / 10) % 10)    /* second digit of reply code */
  691. # define SMTPGOODREPLY    250            /* positive SMTP response */
  692. # define SMTPCLOSING    421            /* "Service Shutting Down" */
  693. a50 3
  694. # ifdef MAIL11V3
  695. bool    SmtpManyStatus;            /* set for multiple status from DATA */
  696. # endif /* MAIL11V3 */
  697. d58 3
  698. a60 3
  699. # define SMTP_CLOSED    0        /* connection is closed */
  700. # define SMTP_OPEN    1        /* connection is open for business */
  701. # define SMTP_SSD    2        /* service shutting down */
  702. a69 1
  703. **        e -- the envelope to deliver (#ifdef MAIL11V3)
  704. a78 4
  705. # ifdef MAIL11V3
  706. smtpinit(m, pvp, e)
  707.     register ENVELOPE *e;
  708. # else /* ! MAIL11V3 */
  709. a79 1
  710. # endif /* MAIL11V3 */
  711. a183 1
  712. # ifdef MAIL11V3
  713. a184 43
  714.     **  If this mailer can do multiple status returns after DATA command,
  715.     **  ask if it will do so.
  716.     */
  717.     if (bitnset(M_MANYSTATUS, m->m_flags))
  718.     {
  719.         smtpmessage("MULT", m);
  720.         r = reply(m);
  721.         if (r < 0)
  722.             goto tempfail;
  723.         else if (r == 250)
  724.             SmtpManyStatus = TRUE;
  725.     }
  726.     else
  727.         SmtpManyStatus = FALSE;
  728.  
  729.     /*
  730.     **  If this mailer wants to see the headers and body early, ask if
  731.     **  now is OK.
  732.     */
  733.  
  734.     if (bitnset(M_PREHEAD, m->m_flags))
  735.     {
  736.         smtpmessage("HEAD", m);
  737.         r = reply(m);
  738.         if (r < 0)
  739.             goto tempfail;
  740.         if (REPLYTYPE(r) == 2 || REPLYTYPE(r) == 3)
  741.         {
  742.             /* Send the header and message... */
  743.             (*e->e_puthdr)(SmtpOut, m, CurEnv);
  744.             putline("\n", SmtpOut, m);
  745.             (*e->e_putbody)(SmtpOut, m, CurEnv);
  746.  
  747.             /* followed by the proper termination. */
  748.             fprintf(SmtpOut, ".%s", m->m_eol);
  749.             r = reply(m);
  750.             if (r < 0)
  751.                 goto tempfail;
  752.         }
  753.     }
  754. # endif /* MAIL11V3 */
  755.  
  756.     /*
  757. a208 7
  758. #ifdef MAIL11V3
  759.     else if (r == 559)
  760.     {
  761.         smtpquit(m);
  762.         return (EX_NOHOST);
  763.     }
  764. #endif /* MAIL11V3 */
  765. a308 7
  766. #ifdef MAIL11V3
  767.     /*
  768.     ** If we are running with mail11v3 support, status is collected in
  769.     ** in deliver().
  770.     */
  771.     return (EX_OK);
  772. #else /* ! MAIL11V3 */
  773. a320 1
  774. #endif /* MAIL11V3 */
  775. d419 1
  776. a419 1
  777. # else /* ! ECONNRESET */
  778. d421 1
  779. a421 1
  780. # endif /* ECONNRESET */
  781. d440 1
  782. a440 1
  783. # endif /* LOG */
  784. a519 18
  785.  
  786. # ifdef MAIL11V3
  787. /*
  788. **  SMTPSTAT -- collect status from DATA command
  789. **
  790. **    Parameters:
  791. **        m -- the mailer we are reading the status from.
  792. **
  793. **    Returns:
  794. **        status of DATA command
  795. **
  796. **    Side Effects:
  797. **        none
  798. */
  799. smtpstat(m)
  800.     struct mailer *m;
  801. {
  802.     int r;
  803. d521 1
  804. a521 14
  805.     /* check the status returned after DATA command */
  806.     r = reply(m);
  807.     if (r < 0 || REPLYTYPE(r) == 4)
  808.         return (EX_TEMPFAIL);
  809.     else if (r == 250)
  810.         return (EX_OK);
  811.     else if (r == 552 || r == 554)
  812.         return (EX_UNAVAILABLE);
  813.     else if (r == 550 || r == 551 || r == 553)
  814.         return (EX_NOUSER);
  815.     return (EX_PROTOCOL);
  816. }
  817. # endif /* MAIL11V3 */
  818. #endif /* SMTP */
  819. @
  820.  
  821.  
  822. 5.15.0.3
  823. log
  824. @Bruce Lilly (bruce%balilly@@sonyd1.broadcast.sony.com) provided varargs
  825. code modified to key off of #define VSPRINTF in conf.h.
  826. @
  827. text
  828. @a576 20
  829. #ifdef VSPRINTF
  830. smtpmessage(va_alist)
  831. va_dcl
  832. {
  833.     va_list    ap;
  834.       char *f;
  835.       MAILER *m;
  836.  
  837.     va_start(ap);
  838.     f = va_arg(ap, char *);
  839.     m = va_arg(ap, MAILER *);
  840.     (void) vsprintf(SmtpMsgBuffer, f, ap);
  841.     if (tTd(18, 1) || (Verbose && !HoldErrs))
  842.         nmessage(Arpa_Info, ">>> %s", SmtpMsgBuffer);
  843.     if (SmtpOut != NULL)
  844.         fprintf(SmtpOut, "%s%s", SmtpMsgBuffer,
  845.             m == 0 ? "\r\n" : m->m_eol);
  846.     va_end(ap);
  847. }
  848. #else /* !VSPRINTF */
  849. a587 1
  850. #endif /* VSPRINTF */
  851. @
  852.  
  853.  
  854. 5.15.0.4
  855. log
  856. @Added static keyword to declaration of reply() and smtpmessage().
  857. @
  858. text
  859. @a35 2
  860. static    reply(), smtpmessage();
  861.  
  862. a446 1
  863. static
  864. a576 1
  865. static
  866. @
  867.  
  868.  
  869. 5.15.0.5
  870. log
  871. @ANSIfied.
  872. @
  873. text
  874. @d31 2
  875. a32 2
  876. #include <sysexits.h>
  877. #include <errno.h>
  878. d36 1
  879. a36 16
  880. # ifdef __STDC__
  881. static reply(MAILER *);
  882. #  ifdef VSPRINTF
  883. /*
  884.  * The following doesn't work as gcc transforms va_alist for some reason.
  885.  *
  886.  * static void smtpmessage(const char *, MAILER *, va_alist);
  887.  */
  888. static void smtpmessage();
  889. #  else /* !VSPRINTF*/
  890. static void smtpmessage();
  891. #  endif /* VSPRINTF*/
  892. # else /* !__STDC__ */
  893. static reply();
  894. static void smtpmessage();
  895. # endif /* __STDC__  */
  896. d49 10
  897. a58 7
  898. static char    SmtpMsgBuffer[MAXLINE];    /* buffer for commands */
  899. static char    SmtpReplyBuffer[MAXLINE]; /* buffer for replies */
  900. char        SmtpError[MAXLINE] = ""; /* save failure error messages */
  901. static bool    SmtpNeedIntro;        /* set before first error */
  902. static FILE    *SmtpOut;        /* output file */
  903. static FILE    *SmtpIn;        /* input file */
  904. static int    SmtpPid;        /* pid of mailer */
  905. d61 1
  906. a61 1
  907. static int    SmtpState;        /* connection state, see below */
  908. d91 1
  909. a91 1
  910.     MAILER *m;
  911. d120 2
  912. d305 1
  913. d337 1
  914. a337 1
  915.     MAILER *m;
  916. a404 1
  917. void
  918. d496 4
  919. d504 1
  920. d580 1
  921. a580 1
  922. static void
  923. d582 1
  924. a582 3
  925. smtpmessage(f, m, va_alist)
  926.     const char *f;
  927.     MAILER *m;
  928. d586 2
  929. d590 2
  930. d602 1
  931. a602 1
  932.     const char *f;
  933. a626 1
  934.  
  935. d628 1
  936. a628 1
  937.     MAILER *m;
  938. @
  939.  
  940.  
  941. 5.15.0.6
  942. log
  943. @Use stdarg instead of varargs when __STDC__ && VSPRINTF are true.
  944. @
  945. text
  946. @d39 6
  947. a44 1
  948. static void smtpmessage(const char *, MAILER *, ...);
  949. a586 6
  950. # ifdef __STDC__
  951. smtpmessage(const char *f, MAILER *m, ...)
  952. {
  953.     va_list    ap;
  954.     va_start(ap, m);
  955. # else /* !__STDC__ */
  956. d593 1
  957. a594 2
  958. # endif /* __STDC__ */
  959.  
  960. @
  961.  
  962.  
  963. 5.15.0.7
  964. log
  965. @Added RCS ID string
  966. @
  967. text
  968. @a25 1
  969. static char  rcsid[] = "@@(#)$Id$ (with SMTP)";
  970. a27 1
  971. static char  rcsid[] = "@@(#)$Id$ (without SMTP)";
  972. @
  973.  
  974.  
  975. 5.15.0.8
  976. log
  977. @System 5 and general improvement patches contributed by Bruce Lilly
  978. (bruce%balilly@@broadcast.sony.com).
  979. @
  980. text
  981. @d25 2
  982. a26 2
  983. static char sccsid[] = "@@(#)usersmtp.c    5.15 (Berkeley) 6/1/90 (with SMTP)    %I% local";
  984. static char  rcsid[] = "@@(#)$Id: usersmtp.c,v 5.15.0.7 1991/04/05 14:55:15 paul Exp paul $ (with SMTP)";
  985. d28 2
  986. a29 2
  987. static char sccsid[] = "@@(#)usersmtp.c    5.15 (Berkeley) 6/1/90 (without SMTP)    %I% local";
  988. static char  rcsid[] = "@@(#)$Id: usersmtp.c,v 5.15.0.7 1991/04/05 14:55:15 paul Exp paul $ (without SMTP)";
  989. d39 1
  990. a39 1
  991. static int reply(MAILER *);
  992. d46 1
  993. a46 1
  994. static int reply();
  995. a93 1
  996. int
  997. d234 1
  998. a234 1
  999.             putline("", SmtpOut, m);
  1000. a306 1
  1001. int
  1002. a341 1
  1003. int
  1004. d370 1
  1005. a370 1
  1006.     putline("", SmtpOut, m);
  1007. d456 1
  1008. a456 1
  1009. static int
  1010. d491 1
  1011. d634 1
  1012. a634 1
  1013. int
  1014. @
  1015.  
  1016.  
  1017. 5.15.0.9
  1018. log
  1019. @Eliminated non-#define VSPRINT as a portable vsprintf() is now included
  1020. in vprintf.c.
  1021. @
  1022. text
  1023. @d26 1
  1024. a26 1
  1025. static char  rcsid[] = "@@(#)$Id: usersmtp.c,v 5.15.0.8 1991/05/18 18:31:37 paul Exp paul $ (with SMTP)";
  1026. d29 1
  1027. a29 1
  1028. static char  rcsid[] = "@@(#)$Id: usersmtp.c,v 5.15.0.8 1991/05/18 18:31:37 paul Exp paul $ (without SMTP)";
  1029. d40 1
  1030. d42 3
  1031. d585 2
  1032. a586 1
  1033. #ifdef __STDC__
  1034. d591 1
  1035. a591 1
  1036. #else /* !__STDC__ */
  1037. d599 1
  1038. a599 1
  1039. #endif /* __STDC__ */
  1040. d609 13
  1041. @
  1042.  
  1043.  
  1044. 5.15.0.10
  1045. log
  1046. @Correct handling of errno in reply() and smtpquit().
  1047. @
  1048. text
  1049. @d26 1
  1050. a26 1
  1051. static char  rcsid[] = "@@(#)$Id: usersmtp.c,v 5.15.0.9 1991/05/22 02:30:43 paul Exp paul $ (with SMTP)";
  1052. d29 1
  1053. a29 1
  1054. static char  rcsid[] = "@@(#)$Id: usersmtp.c,v 5.15.0.9 1991/05/22 02:30:43 paul Exp paul $ (without SMTP)";
  1055. d414 1
  1056. a414 1
  1057.     int i = errno;
  1058. d430 1
  1059. a548 4
  1060.         /* save temporary failure messages for posterity */
  1061.         if (SmtpReplyBuffer[0] == '4' && SmtpError[0] == '\0')
  1062.             (void) strcpy(SmtpError, &SmtpReplyBuffer[4]);
  1063.  
  1064. d556 5
  1065. a560 1
  1066.         errno = 0;
  1067. @
  1068.  
  1069.  
  1070. 5.15.0.11
  1071. log
  1072. @Changed time_t to TIME_TYPE, editted sccsid.
  1073. @
  1074. text
  1075. @d25 2
  1076. a26 2
  1077. static char sccsid[] = "@@(#)usersmtp.c    5.15 (Berkeley) 6/1/90 (with SMTP)";
  1078. static char  rcsid[] = "@@(#)$Id: usersmtp.c,v 5.15.0.10 1991/06/13 16:23:34 paul Exp paul $ (with SMTP)";
  1079. d28 2
  1080. a29 2
  1081. static char sccsid[] = "@@(#)usersmtp.c    5.15 (Berkeley) 6/1/90 (without SMTP)";
  1082. static char  rcsid[] = "@@(#)$Id: usersmtp.c,v 5.15.0.10 1991/06/13 16:23:34 paul Exp paul $ (without SMTP)";
  1083. d101 1
  1084. a101 1
  1085.     TIME_TYPE SavedReadTimeout;
  1086. @
  1087.