]>
diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/mts/sendmail/smail.c
1 /* smail.c - MH interface to SendMail/SMTP */
3 static char ident
[] = "@(#)$Id: smail.c,v 1.30 1996/02/09 23:05:06 jromine Exp $";
8 /* This module implements an interface to SendMail very similar to the
9 MMDF mm_(3) routines. The sm_() routines herein talk SMTP to a
10 sendmail process, mapping SMTP reply codes into RP_-style codes.
14 /* Under 4.2BSD, the alarm handing stuff for time-outs will NOT work due to
15 the way syscalls get restarted. This really is not crucial, since we
16 expect SendMail to be well-behaved and not hang on us. The only time
17 I've ever seen Sendmail hang was with a bogus configuration file...
22 * It appears that some versions of Sendmail will return Code 451
23 * when they don't really want to indicate a failure.
24 * "Code 451 almost always means sendmail has deferred; we don't
25 * really want bomb out at this point since sendmail will rectify
26 * things later." So, if you define SENDMAILBUG, Code 451 is
27 * considered the same as Code 250. Yuck!
31 #endif /* not SENDMAIL */
32 #endif /* SENDMAILBUG */
35 /* HP-UX has this capability. It also handles (some) signals. */
39 #if !defined(BSD42) && !defined(SOCKETS)
41 #endif /* not BSD42 and not SOCKETS */
47 #include "../h/strings.h"
50 #include "../zotnet/mts.h"
65 #define NBITS ((sizeof (int)) * 8)
67 #define min(a,b) ((a) < (b) ? (a) : (b))
70 /* these codes must all be different! */
71 #define SM_OPEN 90 /* Changed from 30 in case of nameserver flakiness */
84 static TYPESIG
alrmser ();
86 static int sm_addrs
= 0;
87 static int sm_alarmed
= 0;
89 static int sm_child
= NOTOK
;
91 static int sm_debug
= 0;
92 static int sm_nl
= TRUE
;
93 static int sm_verbose
= 0;
95 static FILE * sm_rfp
= NULL
;
96 static FILE * sm_wfp
= NULL
;
99 static int sm_ispool
= 0;
100 static char sm_tmpfil
[BUFSIZ
];
103 static char *sm_noreply
= "No reply text given";
104 static char *sm_moreply
= "; ";
106 struct smtp sm_reply
; /* global... */
112 static int rclient(), sm_ierror(), smtalk(), sm_wrecord(), sm_wstream();
113 static int sm_werror(), smhear(), sm_rrecord(), sm_rerror();
119 extern char *sys_errlist
[];
123 static int doingEHLO
;
126 char *EHLOkeys
[MAXEHLO
+ 1];
135 extern char **brkstring (), **copyip (), *getcpy ();
144 int sm_init (client
, server
, watch
, verbose
, debug
, onex
, queued
)
163 #else /* to show the transaction, -watch must imply -snoop */
164 debug
= verbose
= TRUE
;
166 sm_verbose
= verbose
;
168 if (sm_rfp
!= NULL
&& sm_wfp
!= NULL
)
171 if (client
== NULL
|| *client
== '\0')
174 if (client
== NULL
|| *client
== '\0')
175 client
= "localhost";
178 if (pipe (pdi
) == NOTOK
)
179 return sm_ierror ("no pipes");
180 if (pipe (pdo
) == NOTOK
) {
181 (void) close (pdi
[0]);
182 (void) close (pdi
[1]);
183 return sm_ierror ("no pipes");
186 for (i
= 0; (sm_child
= fork ()) == NOTOK
&& i
< 5; i
++)
190 (void) close (pdo
[0]);
191 (void) close (pdo
[1]);
192 (void) close (pdi
[0]);
193 (void) close (pdi
[1]);
194 return sm_ierror ("unable to fork");
197 if (pdo
[0] != fileno (stdin
))
198 (void) dup2 (pdo
[0], fileno (stdin
));
199 if (pdi
[1] != fileno (stdout
))
200 (void) dup2 (pdi
[1], fileno (stdout
));
201 if (pdi
[1] != fileno (stderr
))
202 (void) dup2 (pdi
[1], fileno (stderr
));
203 for (i
= fileno (stderr
) + 1; i
< NBITS
; i
++)
207 vec
[vecp
++] = r1bindex (sendmail
, '/');
210 vec
[vecp
++] = watch
? "-odi" : queued
? "-odq" : "-odb";
211 vec
[vecp
++] = "-oem";
216 #endif /* not RAND */
217 #endif /* not ZMAILER */
220 (void) setgid (getegid ());
221 (void) setuid (geteuid ());
222 execvp (sendmail
, vec
);
223 fprintf (stderr
, "unable to exec ");
225 _exit (-1); /* NOTREACHED */
228 (void) signal (SIGALRM
, alrmser
);
229 (void) signal (SIGPIPE
, SIG_IGN
);
231 (void) close (pdi
[1]);
232 (void) close (pdo
[0]);
233 if ((sm_rfp
= fdopen (pdi
[0], "r")) == NULL
234 || (sm_wfp
= fdopen (pdo
[1], "w")) == NULL
) {
235 (void) close (pdi
[0]);
236 (void) close (pdo
[1]);
237 sm_rfp
= sm_wfp
= NULL
;
238 return sm_ierror ("unable to fdopen");
241 (void) alarm (SM_OPEN
);
249 (void) sm_end (NOTOK
);
253 if (client
&& *client
) {
255 result
= smtalk (SM_HELO
, "EHLO %s", client
);
258 if (500 <= result
&& result
<= 599)
259 result
= smtalk (SM_HELO
, "HELO %s", client
);
266 (void) sm_end (NOTOK
);
273 (void) smtalk (SM_HELO
, "ONEX");
276 (void) smtalk (SM_HELO
, "VERB on");
285 int sm_init (client
, server
, watch
, verbose
, debug
, onex
, queued
)
302 if (!server
|| !*server
)
304 (void) copyip (brkstring (getcpy (server
), " ", "\n"), ap
);
307 #if !defined(SUN40) || defined(MMDFII)
309 #else /* to show the transaction, -watch must imply -snoop */
310 debug
= verbose
= TRUE
;
312 sm_verbose
= verbose
;
318 if (sm_rfp
!= NULL
&& sm_wfp
!= NULL
)
321 if (client
== NULL
|| *client
== '\0')
325 client
= LocalName (); /* no clientname -> LocalName */
327 if (client
== NULL
|| *client
== '\0')
328 client
= "localhost";
329 #endif /* not ZMAILER */
333 for (sd1
= NOTOK
; *ap
; ap
++) {
334 if ((sd1
= rclient (*ap
, "tcp", "smtp")) != NOTOK
)
342 (void) alarm (SM_CLOS
);
343 (void) fclose (sm_rfp
);
347 if ((sm_wfp
= fdopen (sd1
, "w")) == NULL
) {
348 (void) unlink (sm_tmpfil
);
350 return sm_ierror ("unable to fdopen");
353 sm_reply
.text
[sm_reply
.length
= 0] = NULL
;
354 return (sm_reply
.code
= RP_OK
);
357 if ((sd2
= dup (sd1
)) == NOTOK
) {
359 return sm_ierror ("unable to dup");
362 (void) signal (SIGALRM
, alrmser
);
363 (void) signal (SIGPIPE
, SIG_IGN
);
365 if ((sm_rfp
= fdopen (sd1
, "r")) == NULL
366 || (sm_wfp
= fdopen (sd2
, "w")) == NULL
) {
369 sm_rfp
= sm_wfp
= NULL
;
370 return sm_ierror ("unable to fdopen");
373 (void) alarm (SM_OPEN
);
381 (void) sm_end (NOTOK
);
389 if (client
&& *client
) {
391 result
= smtalk (SM_HELO
, "EHLO %s", client
);
394 if (500 <= result
&& result
<= 599)
395 result
= smtalk (SM_HELO
, "HELO %s", client
);
402 (void) sm_end (NOTOK
);
408 if (watch
&& EHLOset ("XVRB"))
409 (void) smtalk (SM_HELO
, "VERB on");
410 if (onex
&& EHLOset ("XONE"))
411 (void) smtalk (SM_HELO
, "ONEX");
412 if (queued
&& EHLOset ("XQUE"))
413 (void) smtalk (SM_HELO
, "QUED");
419 static int rclient (server
, protocol
, service
)
425 char response
[BUFSIZ
];
430 if ((sd
= client (server
, protocol
, service
, FALSE
, response
)) != NOTOK
)
434 if (!server
&& servers
&& (cp
= index (servers
, '/'))) {
436 char *arguments
[MAXARGS
];
438 (void) copyip (brkstring (cp
= getcpy (servers
), " ", "\n"),
441 for (ap
= arguments
; *ap
; ap
++)
445 if ((dp
= rindex (*ap
, '/')) && *++dp
== NULL
)
447 (void) sprintf (sm_tmpfil
, "%s/smtpXXXXXX", *ap
);
448 (void) mktemp (sm_tmpfil
);
450 if ((sd
= creat (sm_tmpfil
, 0600)) != NOTOK
) {
462 (void) sm_ierror ("%s", response
);
469 int sm_winit (mode
, from
)
474 if (sm_ispool
&& !sm_wfp
) {
475 (void) strlen (strcpy (sm_reply
.text
,
476 "unable to create new spool file"));
477 sm_reply
.code
= NOTOK
;
482 switch (smtalk (SM_MAIL
, "%s FROM:<%s>",
483 mode
== S_SEND
? "SEND" : mode
== S_SOML
? "SOML"
484 : mode
== S_SAML
? "SAML" : "MAIL", from
)) {
505 int sm_wadr (mbox
, host
, path
)
509 #endif /* not BERK */
514 switch (smtalk (SM_RCPT
, host
&& *host
? "RCPT TO:<%s%s@%s>"
516 path
? path
: "", mbox
, host
)) {
518 switch (smtalk (SM_RCPT
, "RCPT TO:%s", mbox
)) {
529 #endif /* SENDMAILBUG */
553 switch (smtalk (SM_DATA
, "DATA")) {
562 #endif /* SENDMAILBUG */
579 int sm_wtxt (buffer
, len
)
580 register char *buffer
;
586 (void) alarm (SM_TEXT
);
587 result
= sm_wstream (buffer
, len
);
590 return (result
== NOTOK
? RP_BHST
: RP_OK
);
596 if (sm_wstream ((char *) NULL
, 0) == NOTOK
)
599 switch (smtalk (SM_DOT
+ 3 * sm_addrs
, ".")) {
607 #endif /* SENDMAILBUG */
635 #endif /* not SMTP */
636 if (sm_rfp
== NULL
&& sm_wfp
== NULL
)
641 (void) smtalk (SM_QUIT
, "QUIT");
645 sm_note
.code
= sm_reply
.code
;
646 (void) strncpy (sm_note
.text
, sm_reply
.text
,
647 sm_note
.length
= sm_reply
.length
);/* fall */
649 if (smtalk (SM_RSET
, "RSET") == 250 && type
== DONE
)
652 (void) kill (sm_child
, SIGKILL
);
656 (void) smtalk (SM_QUIT
, "QUIT");
657 #endif /* not SMTP */
659 sm_reply
.code
= sm_note
.code
;
660 (void) strncpy (sm_reply
.text
, sm_note
.text
,
661 sm_reply
.length
= sm_note
.length
);
671 (void) unlink (sm_tmpfil
);
672 (void) fclose (sm_wfp
);
678 if (sm_rfp
!= NULL
) {
679 (void) alarm (SM_CLOS
);
680 (void) fclose (sm_rfp
);
683 if (sm_wfp
!= NULL
) {
684 (void) alarm (SM_CLOS
);
685 (void) fclose (sm_wfp
);
690 status
= pidwait (sm_child
);
696 sm_rfp
= sm_wfp
= NULL
;
698 return (status
? RP_BHST
: RP_OK
);
705 #include <sys/types.h>
706 #include <sys/stat.h>
727 k
= strlen (file
) - sizeof ".bulk";
728 if ((fp
= fopen (file
, "r")) == NULL
) {
729 (void) sprintf (bp
= sm_reply
.text
, "unable to read %s: ", file
);
731 if (errno
> 0 && errno
< sys_nerr
)
732 (void) sprintf (bp
, "%s", sys_errlist
[errno
]);
734 (void) sprintf (bp
, "Error %d", errno
);
735 sm_reply
.length
= strlen (sm_reply
.text
);
736 sm_reply
.code
= NOTOK
;
740 printf ("reading file %s\n", file
);
741 (void) fflush (stdout
);
745 while (fgets (buffer
, sizeof buffer
, fp
)) {
747 (void) strcpy (sender
, buffer
+ sizeof "MAIL FROM:" - 1);
748 if (strcmp (buffer
, "DATA\r\n") == 0) {
755 printf ("no DATA...\n");
756 (void) fflush (stdout
);
759 (void) sprintf (buffer
, "%s.bad", file
);
760 (void) rename (file
, buffer
);
762 (void) sprintf (buffer
, "%*.*sA.bulk", k
, k
, file
);
763 (void) unlink (buffer
);
771 printf ("no %srecipients...\n", j
< 1 ? "sender or " : "");
772 (void) fflush (stdout
);
777 if ((cp
= malloc ((unsigned) (cc
= (pos
= ftell (fp
)) + 1))) == NULL
) {
778 sm_reply
.length
= strlen (strcpy (sm_reply
.text
, "out of memory"));
780 sm_reply
.code
= NOTOK
;
784 (void) fseek (fp
, 0L, 0);
785 for (dp
= cp
, i
= 0; i
++ < j
; dp
+= strlen (dp
))
786 if (fgets (dp
, cc
- (dp
- cp
), fp
) == NULL
) {
787 sm_reply
.length
= strlen (strcpy (sm_reply
.text
, "premature eof"));
794 for (dp
= cp
, i
= cc
- 1; i
> 0; dp
+= cc
, i
-= cc
)
795 if ((cc
= write (fileno (sm_wfp
), dp
, i
)) == NOTOK
) {
797 (void) strcpy (bp
= sm_reply
.text
, "error writing to server: ");
799 if (errno
> 0 && errno
< sys_nerr
)
800 (void) sprintf (bp
, "%s", sys_errlist
[errno
]);
802 (void) sprintf (bp
, "Error %d", errno
);
803 sm_reply
.length
= strlen (sm_reply
.text
);
808 printf ("wrote %d octets to server\n", cc
);
809 (void) fflush (stdout
);
812 for (dp
= cp
, i
= 0; i
++ < j
; dp
= index (dp
, '\n'), dp
++) {
814 if (bp
= index (dp
, '\r'))
816 printf ("=> %s\n", dp
);
817 (void) fflush (stdout
);
822 switch (smhear () + (i
== 1 ? 1000 : i
!= j
? 2000 : 3000)) {
834 (void) smtalk (SM_RSET
, "RSET");
862 if (k
<= 0 || strcmp (sender
, "<>\r\n") == 0)
866 (void) sprintf (buffer
, "%*.*sA.bulk", k
, k
, file
);
867 if ((gp
= fopen (buffer
, "w+")) == NULL
)
869 fprintf (gp
, "MAIL FROM:<>\r\nRCPT TO:%sDATA\r\n", sender
);
872 "To: %*.*s\r\nSubject: Invalid addresses (%s)\r\n",
873 l
- 4, l
- 4, sender
+ 1, file
);
874 fprintf (gp
, "Date: %s\r\nFrom: Postmaster@%s\r\n\r\n",
875 dtimenow (), LocalName ());
877 if (bp
= index (dp
, '\r'))
879 fprintf (gp
, "=> %s\r\n", dp
);
882 fprintf (gp
, "<= %s\r\n", rp_string (result
));
900 (void) smtalk (SM_RSET
, "RSET");
903 (void) sprintf (buffer
, "%*.*sA.bulk", k
, k
, file
);
904 (void) unlink (buffer
);
914 (void) smtalk (SM_RSET
, "RSET");
931 if (fstat (fileno (sm_wfp
), &st
) == NOTOK
932 || (cc
= st
.st_blksize
) < BUFSIZ
)
935 if ((cp
= malloc ((unsigned) cc
)) == NULL
) {
936 (void) smtalk (SM_RSET
, "RSET");
937 sm_reply
.length
= strlen (strcpy (sm_reply
.text
, "out of memory"));
941 (void) fseek (fp
, pos
, 0);
945 for (dp
= cp
, i
= cc
; i
> 0; dp
+= j
, i
-= j
)
946 if ((j
= fread (cp
, sizeof *cp
, i
, fp
)) == OK
) {
948 (void) sprintf (bp
= sm_reply
.text
,
949 "error reading %s: ", file
);
951 if (errno
> 0 && errno
< sys_nerr
)
952 (void) sprintf (bp
, "%s", sys_errlist
[errno
]);
954 (void) sprintf (bp
, "Error %d", errno
);
955 sm_reply
.length
= strlen (sm_reply
.text
);
963 for (dp
= cp
, i
= cc
; i
> 0; dp
+= j
, i
-= j
)
964 if ((j
= write (fileno (sm_wfp
), dp
, i
)) == NOTOK
)
968 printf ("wrote %d octets to server\n", j
);
969 (void) fflush (stdout
);
984 (void) unlink (file
);
995 (void) sprintf (buffer
, "%*.*sA.bulk", k
, k
, file
);
996 (void) unlink (buffer
);
1006 if (k
<= 0 || strcmp (sender
, "<>\r\n") == 0) {
1007 (void) unlink (file
);
1012 (void) ftruncate (fileno (gp
), 0L);
1013 (void) fseek (gp
, 0L, 0);
1016 (void) sprintf (buffer
, "%*.*sA.bulk", k
, k
, file
);
1017 if ((gp
= fopen (buffer
, "w")) == NULL
)
1020 fprintf (gp
, "MAIL FROM:<>\r\nRCPT TO:%sDATA\r\n", sender
);
1021 i
= strlen (sender
);
1022 fprintf (gp
, "To: %*.*s\r\nSubject: Failed mail (%s)\r\n",
1023 i
- 4, i
- 4, sender
+ 1, file
);
1024 fprintf (gp
, "Date: %s\r\nFrom: Postmaster@%s\r\n\r\n",
1025 dtimenow (), LocalName ());
1030 (void) fputs ("\r\n------- Begin Returned message\r\n\r\n", gp
);
1031 (void) fseek (fp
, pos
, 0);
1032 while (fgets (buffer
, sizeof buffer
, fp
)) {
1033 if (buffer
[0] == '-')
1034 (void) fputs ("- ", gp
);
1035 if (strcmp (buffer
, ".\r\n"))
1036 (void) fputs (buffer
, gp
);
1038 (void) fputs ("\r\n------- End Returned Message\r\n\r\n.\r\n", gp
);
1041 (void) unlink (file
);
1055 static int sm_ierror (fmt
, a
, b
, c
, d
)
1062 (void) sprintf (sm_reply
.text
, fmt
, a
, b
, c
, d
);
1063 sm_reply
.length
= strlen (sm_reply
.text
);
1064 sm_reply
.code
= NOTOK
;
1073 static int smtalk (time
, fmt
, a
, b
, c
, d
)
1076 register char *a
, *b
, *c
, *d
;
1078 register int result
;
1079 char buffer
[BUFSIZ
];
1081 (void) sprintf (buffer
, fmt
, a
, b
, c
, d
);
1083 printf ("=> %s\n", buffer
);
1084 (void) fflush (stdout
);
1091 if (strcmp (buffer
, ".") == 0)
1093 fprintf (sm_wfp
, "%s\r\n", buffer
);
1096 (void) fflush (sm_wfp
);
1097 if (ferror (sm_wfp
))
1098 return sm_werror ();
1099 (void) sprintf (file
, "%s%c.bulk", sm_tmpfil
,
1100 (char) (sm_ispool
+ 'a' - 1));
1101 if (rename (sm_tmpfil
, file
) == NOTOK
) {
1103 (void) sprintf (bp
= sm_reply
.text
,
1104 "error renaming %s to %s: ",
1107 if (errno
> 0 && errno
< sys_nerr
)
1108 (void) sprintf (bp
, "%s", sys_errlist
[errno
]);
1110 (void) sprintf (bp
, "Error %d", errno
);
1111 sm_reply
.length
= strlen (sm_reply
.text
);
1112 sm_reply
.code
= NOTOK
;
1115 (void) fclose (sm_wfp
);
1116 if (sm_wfp
= fopen (sm_tmpfil
, "w"))
1117 (void) chmod (sm_tmpfil
, 0600);
1127 (void) fflush (sm_wfp
);
1128 (void) ftruncate (fileno (sm_wfp
), 0L);
1129 (void) fseek (sm_wfp
, 0L, 0);
1138 (void) unlink (sm_tmpfil
);
1148 printf ("<= %d\n", result
);
1149 (void) fflush (stdout
);
1152 sm_reply
.text
[sm_reply
.length
= 0] = NULL
;
1153 return (sm_reply
.code
= result
);
1158 (void) alarm ((unsigned) time
);
1159 if ((result
= sm_wrecord (buffer
, strlen (buffer
))) != NOTOK
)
1168 static int sm_wrecord (buffer
, len
)
1169 register char *buffer
;
1173 return sm_werror ();
1175 (void) fwrite (buffer
, sizeof *buffer
, len
, sm_wfp
);
1176 (void) fputs ("\r\n", sm_wfp
);
1177 (void) fflush (sm_wfp
);
1179 return (ferror (sm_wfp
) ? sm_werror () : OK
);
1184 static int sm_wstream (buffer
, len
)
1185 register char *buffer
;
1192 return sm_werror ();
1194 if (buffer
== NULL
&& len
== 0) {
1196 (void) fputs ("\r\n", sm_wfp
);
1198 return (ferror (sm_wfp
) ? sm_werror () : OK
);
1201 for (bp
= buffer
; len
> 0; bp
++, len
--) {
1205 (void) fputc ('\r', sm_wfp
);
1210 (void) fputc ('.', sm_wfp
);/* FALL THROUGH */
1214 (void) fputc (*bp
, sm_wfp
);
1215 if (ferror (sm_wfp
))
1216 return sm_werror ();
1221 return (ferror (sm_wfp
) ? sm_werror () : OK
);
1228 * AIX by default will inline the strlen and strcpy commands by redefining
1229 * them as __strlen and __strcpy respectively. This causes compile problems
1230 * with the #ifdef MPOP in the middle. Should the #ifdef MPOP be removed,
1231 * remove these #undefs.
1237 static int sm_werror () {
1240 strlen (strcpy (sm_reply
.text
, sm_wfp
== NULL
? "no socket opened"
1241 : sm_alarmed
? "write to socket timed out"
1243 : sm_ispool
? "error writing to spool file"
1245 : "error writing to socket"));
1247 strlen (strcpy (sm_reply
.text
, sm_wfp
== NULL
? "no pipe opened"
1248 : sm_alarmed
? "write to pipe timed out"
1249 : "error writing to pipe"));
1252 return (sm_reply
.code
= NOTOK
);
1257 static int smhear () {
1270 static int at_least_once
= 0;
1272 if (at_least_once
) {
1275 for (ehlo
= EHLOkeys
; ep
= *ehlo
; ehlo
++)
1281 *(ehlo
= EHLOkeys
) = NULL
;
1286 sm_reply
.text
[sm_reply
.length
= 0] = 0;
1288 rp
= sm_reply
.text
, rc
= sizeof sm_reply
.text
- 1;
1289 for (more
= FALSE
; sm_rrecord (bp
= buffer
, &bc
) != NOTOK
;) {
1291 printf ("<= %s\n", buffer
);
1292 (void) fflush (stdout
);
1296 && strncmp (buffer
, "250", sizeof "250" - 1) == 0
1297 && (buffer
[3] == '-' || doingEHLO
== 2)
1299 if (doingEHLO
== 2) {
1300 int len
= strlen (buffer
+ 4);
1302 if (*ehlo
= malloc ((unsigned) (strlen (buffer
+ 4) + 1))) {
1303 (void) strcpy (*ehlo
++, buffer
+ 4);
1305 if (ehlo
>= EHLOkeys
+ MAXEHLO
)
1315 for (; bc
> 0 && (!isascii (*bp
) || !isdigit (*bp
)); bp
++, bc
--)
1321 for (; bc
> 0 && isspace (*bp
); bp
++, bc
--)
1323 if (bc
> 0 && *bp
== '-') {
1326 for (; bc
> 0 && isspace (*bp
); bp
++, bc
--)
1331 if (code
!= sm_reply
.code
|| cont
)
1336 sm_reply
.code
= code
;
1339 (void) strcpy (bp
= buffer
, sm_noreply
);
1340 bc
= strlen (sm_noreply
);
1343 if ((i
= min (bc
, rc
)) > 0) {
1344 (void) strncpy (rp
, bp
, i
);
1346 if (more
&& rc
> strlen (sm_moreply
) + 1) {
1347 (void) strcpy (sm_reply
.text
+ rc
, sm_moreply
);
1348 rc
+= strlen (sm_moreply
);
1353 if (sm_reply
.code
< 100) {
1355 printf ("%s\n", sm_reply
.text
);
1356 (void) fflush (stdout
);
1361 sm_reply
.length
= rp
- sm_reply
.text
;
1363 return sm_reply
.code
;
1371 static int sm_rrecord (buffer
, len
)
1372 register char *buffer
;
1376 return sm_rerror ();
1378 buffer
[*len
= 0] = 0;
1380 (void) fgets (buffer
, BUFSIZ
, sm_rfp
);
1381 *len
= strlen (buffer
);
1382 if (ferror (sm_rfp
) || feof (sm_rfp
))
1383 return sm_rerror ();
1384 if (buffer
[*len
- 1] != '\n')
1385 while (getc (sm_rfp
) != '\n' && !ferror (sm_rfp
) && !feof (sm_rfp
))
1388 if (buffer
[*len
- 2] == '\r')
1390 buffer
[*len
- 1] = 0;
1397 static int sm_rerror () {
1400 strlen (strcpy (sm_reply
.text
, sm_rfp
== NULL
? "no socket opened"
1401 : sm_alarmed
? "read from socket timed out"
1402 : feof (sm_rfp
) ? "premature end-of-file on socket"
1403 : "error reading from socket"));
1404 #else /* not SMTP */
1405 strlen (strcpy (sm_reply
.text
, sm_rfp
== NULL
? "no pipe opened"
1406 : sm_alarmed
? "read from pipe timed out"
1407 : feof (sm_rfp
) ? "premature end-of-file on pipe"
1408 : "error reading from pipe"));
1409 #endif /* not SMTP */
1411 return (sm_reply
.code
= NOTOK
);
1418 static TYPESIG
alrmser (i
)
1422 signal (SIGALRM
, alrmser
);
1427 printf ("timed out...\n");
1428 (void) fflush (stdout
);
1434 char *rp_string (code
)
1437 register char *text
;
1438 static char buffer
[BUFSIZ
];
1440 switch (sm_reply
.code
!= NOTOK
? code
: NOTOK
) {
1460 (void) sprintf (buffer
, "[%s] %s", text
, sm_reply
.text
);
1480 (void) sprintf (buffer
, "[%s] %3d %s", text
, sm_reply
.code
, sm_reply
.text
);
1487 static char *broken
[MAXARGS
+ 1];
1490 static char **brkstring (strg
, brksep
, brkterm
)
1491 register char *strg
;
1492 register char *brksep
,
1501 for (bi
= 0; bi
< MAXARGS
; bi
++) {
1502 while (brkany (c
= *sp
, brksep
))
1504 if (!c
|| brkany (c
, brkterm
)) {
1511 while ((c
= *++sp
) && !brkany (c
, brksep
) && !brkany (c
, brkterm
))
1514 broken
[MAXARGS
] = 0;
1520 static brkany (chr
, strg
)
1527 for (sp
= strg
; *sp
; sp
++)
1534 static char **copyip (p
, q
)
1551 int len
= strlen (s
);
1555 for (ehlo
= EHLOkeys
; ep
= *ehlo
; ehlo
++)
1556 if (strncmp (ep
, s
, len
) == 0) {
1557 for (ep
+= len
; *ep
== ' '; ep
++)