Additional tests - didn't show any problems.
[exim.git] / test / src / mtpscript.c
1 /* $Cambridge: exim/test/src/mtpscript.c,v 1.1 2006/02/06 16:24:05 ph10 Exp $ */
2
3 /* A little hacked up program that allows a script to play the part of a remote
4 SMTP/LMTP server on stdin/stdout for testing purposes. Hacked from the more
5 complicated version that does it over a socket. */
6
7
8 /* ANSI C standard includes */
9
10 #include <ctype.h>
11 #include <signal.h>
12 #include <stdarg.h>
13 #include <stddef.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <time.h>
18
19 /* Unix includes */
20
21 #include <errno.h>
22 #include <unistd.h>
23
24
25 static FILE *log;
26
27
28 /*************************************************
29 * SIGALRM handler - crash out *
30 *************************************************/
31
32 static void
33 sigalrm_handler(int sig)
34 {
35 sig = sig; /* Keep picky compilers happy */
36 fprintf(log, "Server timed out\n");
37 exit(99);
38 }
39
40
41
42 /*************************************************
43 * Main Program *
44 *************************************************/
45
46 int main(int argc, char **argv)
47 {
48 char *logfile;
49 char *logmode = "w";
50 FILE *script;
51 unsigned char sbuffer[1024];
52 unsigned char ibuffer[1024];
53
54 if (argc < 3)
55 {
56 fprintf(stdout, "500 Script and log file required\n");
57 exit(1);
58 }
59
60 /* Get the script and log open */
61
62 script = fopen(argv[1], "r");
63 if (script == NULL)
64 {
65 fprintf(stdout, "500 Failed to open script %s: %s\r\n", argv[1],
66 strerror(errno));
67 exit(1);
68 }
69
70 logfile = argv[2];
71 if (logfile[0] == '+')
72 {
73 logfile++;
74 logmode = "a";
75 }
76
77 log = fopen(logfile, logmode);
78 if (log == NULL)
79 {
80 fprintf(stdout, "500 Failed to open log %s: %s\r\n", logfile,
81 strerror(errno));
82 exit(1);
83 }
84
85 /* SIGALRM handler crashes out */
86
87 signal(SIGALRM, sigalrm_handler);
88
89 /* Read the script, and do what it says. */
90
91 while (fgets(sbuffer, sizeof(sbuffer), script) != NULL)
92 {
93 int n = (int)strlen(sbuffer);
94 while (n > 0 && isspace(sbuffer[n-1])) n--;
95 sbuffer[n] = 0;
96
97 /* If the script line starts with a digit, it is a response line which
98 we are to send. */
99
100 if (isdigit(sbuffer[0]))
101 {
102 fprintf(log, "%s\n", sbuffer);
103 fflush(log);
104 fprintf(stdout, "%s\r\n", sbuffer);
105 fflush(stdout);
106 }
107
108 /* If the script line starts with "*sleep" we just sleep for a while
109 before continuing. Do not write this to the log, as it may not get
110 written at the right place in a log that's being shared. */
111
112 else if (strncmp(sbuffer, "*sleep ", 7) == 0)
113 {
114 sleep(atoi(sbuffer+7));
115 }
116
117 /* Otherwise the script line is the start of an input line we are expecting
118 from the client, or "*eof" indicating we expect the client to close the
119 connection. Read command line or data lines; the latter are indicated
120 by the expected line being just ".". */
121
122 else
123 {
124 int data = strcmp(sbuffer, ".") == 0;
125
126 fprintf(log, "%s\n", sbuffer);
127 fflush(log);
128
129 /* Loop for multiple data lines */
130
131 for (;;)
132 {
133 int n;
134 alarm(5);
135 if (fgets(ibuffer, sizeof(ibuffer), stdin) == NULL)
136 {
137 fprintf(log, "%sxpected EOF read from client\n",
138 (strncmp(sbuffer, "*eof", 4) == 0)? "E" : "Une");
139 goto END_OFF;
140 }
141 alarm(0);
142 n = (int)strlen(ibuffer);
143 while (n > 0 && isspace(ibuffer[n-1])) n--;
144 ibuffer[n] = 0;
145 fprintf(log, "<<< %s\n", ibuffer);
146 if (!data || strcmp(ibuffer, ".") == 0) break;
147 }
148
149 /* Check received what was expected */
150
151 if (strncmp(sbuffer, ibuffer, (int)strlen(sbuffer)) != 0)
152 {
153 fprintf(log, "Comparison failed - bailing out\n");
154 goto END_OFF;
155 }
156 }
157 }
158
159 /* This could appear in the wrong place in a shared log, so forgo it. */
160 /* fprintf(log, "End of script\n"); */
161
162 END_OFF:
163 fclose(script);
164 fclose(log);
165
166 exit(0);
167 }
168
169 /* End of mtpscript.c */