]>
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");
46 fprintf(stderr
, "Usage: %s output-filename port\n", argv
[0]);
50 if (!(f
= fopen(argv
[1], "w"))) {
51 fprintf(stderr
, "Unable to open output file \"%s\": %s\n",
52 argv
[1], strerror(errno
));
56 conn
= serve(PIDFILE
, argv
[2]);
59 * Pretend to be an SMTP server.
62 putcrlf(conn
, "220 Not really an ESMTP server");
63 smtp_state
= SMTP_TOP
;
68 rc
= getsmtp(conn
, line
);
73 fprintf(f
, "%s\n", line
);
77 if (strcmp(line
, ".") == 0) {
78 smtp_state
= SMTP_TOP
;
79 putcrlf(conn
, "250 Thanks for the info!");
83 smtp_state
= SMTP_TOP
;
84 putcrlf(conn
, "535 Not no way, not no how!");
89 * Most commands we ignore and send the same response to.
92 if (strcmp(line
, "QUIT") == 0) {
95 putcrlf(conn
, "221 Later alligator!");
99 if (strcmp(line
, "DATA") == 0) {
100 putcrlf(conn
, "354 Go ahead");
101 smtp_state
= SMTP_DATA
;
104 if (xoauth
!= NULL
) {
105 /* XOAUTH2 support enabled; handle EHLO and AUTH. */
106 if (strncmp(line
, "EHLO", 4) == 0) {
107 putcrlf(conn
, "250-ready");
108 putcrlf(conn
, "250 AUTH XOAUTH2");
111 if (strncmp(line
, "AUTH", 4) == 0) {
112 if (strncmp(line
, "AUTH XOAUTH2", 12) == 0
113 && strstr(line
, xoauth
) != NULL
) {
114 putcrlf(conn
, "235 OK come in");
117 putcrlf(conn
, "334 base64-json-err");
118 smtp_state
= SMTP_XOAUTH_ERR
;
122 putcrlf(conn
, "250 I'll buy that for a dollar!");
132 * Read a line (up to the \r\n)
136 getsmtp(int socket
, char *data
)
139 static unsigned int bytesinbuf
= 0;
140 static char buffer
[LINESIZE
* 2], *p
;
147 if (bytesinbuf
> 0 && (p
= strchr(buffer
, '\r')) &&
150 strncpy(data
, buffer
, LINESIZE
);
151 data
[LINESIZE
- 1] = '\0';
155 * Shuffle leftover bytes back to the beginning
158 bytesinbuf
-= cc
+ 2; /* Don't forget \r\n */
159 if (bytesinbuf
> 0) {
160 memmove(buffer
, buffer
+ cc
+ 2, bytesinbuf
);
165 if (bytesinbuf
>= sizeof(buffer
)) {
166 fprintf(stderr
, "Buffer overflow in getsmtp()!\n");
170 memset(buffer
+ bytesinbuf
, 0, sizeof(buffer
) - bytesinbuf
);
171 cc
= read(socket
, buffer
+ bytesinbuf
,
172 sizeof(buffer
) - bytesinbuf
);
175 fprintf(stderr
, "Read failed: %s\n", strerror(errno
));