]>
diplodocus.org Git - nmh/blob - test/fakesmtp.c
2 * fakesmtp - A fake SMTP server used by the nmh test suite
4 * This code is Copyright (c) 2012, by the authors of nmh. See the
5 * COPYRIGHT file in the root directory of the nmh distribution for
6 * complete copyright information.
14 #include <sys/socket.h>
15 #include <sys/types.h>
18 #define PIDFILE "/tmp/fakesmtp.pid"
23 /* Processing top-level SMTP commands (e.g. EHLO, DATA). */
26 /* Processing payload of a DATA command. */
29 /* Looking for the blank line required by XOAUTH2 after 334 response. */
33 void putcrlf(int, char *);
34 int serve(const char *, const char *);
36 static int getsmtp(int, char *);
39 main(int argc
, char *argv
[])
41 int rc
, conn
, smtp_state
;
43 const char *xoauth
= getenv("XOAUTH");
44 const char *smtputf8
= getenv("SMTPUTF8");
47 fprintf(stderr
, "Usage: %s output-filename port\n", argv
[0]);
51 if (!(f
= fopen(argv
[1], "w"))) {
52 fprintf(stderr
, "Unable to open output file \"%s\": %s\n",
53 argv
[1], strerror(errno
));
57 conn
= serve(PIDFILE
, argv
[2]);
60 * Pretend to be an SMTP server.
63 putcrlf(conn
, "220 Not really an ESMTP server");
64 smtp_state
= SMTP_TOP
;
69 rc
= getsmtp(conn
, line
);
74 fprintf(f
, "%s\n", line
);
78 if (strcmp(line
, ".") == 0) {
79 smtp_state
= SMTP_TOP
;
80 putcrlf(conn
, "250 Thanks for the info!");
84 smtp_state
= SMTP_TOP
;
85 putcrlf(conn
, "535 Not no way, not no how!");
90 * Most commands we ignore and send the same response to.
93 if (strcmp(line
, "QUIT") == 0) {
96 putcrlf(conn
, "221 Later alligator!");
100 if (strcmp(line
, "DATA") == 0) {
101 putcrlf(conn
, "354 Go ahead");
102 smtp_state
= SMTP_DATA
;
105 if (strncmp(line
, "EHLO", 4) == 0) {
106 putcrlf(conn
, "250-ready");
107 if (smtputf8
!= NULL
) {
108 putcrlf(conn
, "250-8BITMIME");
109 putcrlf(conn
, "250-SMTPUTF8");
111 if (xoauth
!= NULL
) {
112 putcrlf(conn
, "250-AUTH XOAUTH2");
114 putcrlf(conn
, "250 I'll buy that for a dollar!");
117 if (xoauth
!= NULL
) {
118 /* XOAUTH2 support enabled; handle AUTH (and EHLO above). */
119 if (strncmp(line
, "AUTH", 4) == 0) {
120 if (strncmp(line
, "AUTH XOAUTH2", 12) == 0
121 && strstr(line
, xoauth
) != NULL
) {
122 putcrlf(conn
, "235 OK come in");
125 putcrlf(conn
, "334 base64-json-err");
126 smtp_state
= SMTP_XOAUTH_ERR
;
130 putcrlf(conn
, "250 I'll buy that for a dollar!");
140 * Read a line (up to the \r\n)
144 getsmtp(int socket
, char *data
)
147 static unsigned int bytesinbuf
= 0;
148 static char buffer
[LINESIZE
* 2], *p
;
155 if (bytesinbuf
> 0 && (p
= strchr(buffer
, '\r')) &&
158 strncpy(data
, buffer
, LINESIZE
);
159 data
[LINESIZE
- 1] = '\0';
163 * Shuffle leftover bytes back to the beginning
166 bytesinbuf
-= cc
+ 2; /* Don't forget \r\n */
167 if (bytesinbuf
> 0) {
168 memmove(buffer
, buffer
+ cc
+ 2, bytesinbuf
);
173 if (bytesinbuf
>= sizeof(buffer
)) {
174 fprintf(stderr
, "Buffer overflow in getsmtp()!\n");
178 memset(buffer
+ bytesinbuf
, 0, sizeof(buffer
) - bytesinbuf
);
179 cc
= read(socket
, buffer
+ bytesinbuf
,
180 sizeof(buffer
) - bytesinbuf
);
183 fprintf(stderr
, "Read failed: %s\n", strerror(errno
));