With a few minor exceptions for tests that had additional concerns and tests I don...
[exim.git] / test / src / mtpscript.c
CommitLineData
c55a77db
PH
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
4SMTP/LMTP server on stdin/stdout for testing purposes. Hacked from the more
5complicated 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
25static FILE *log;
26
27
28/*************************************************
29* SIGALRM handler - crash out *
30*************************************************/
31
32static void
33sigalrm_handler(int sig)
34{
35sig = sig; /* Keep picky compilers happy */
36fprintf(log, "Server timed out\n");
37exit(99);
38}
39
40
41
42/*************************************************
43* Main Program *
44*************************************************/
45
46int main(int argc, char **argv)
47{
48char *logfile;
49char *logmode = "w";
50FILE *script;
51unsigned char sbuffer[1024];
52unsigned char ibuffer[1024];
53
54if (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
62script = fopen(argv[1], "r");
63if (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
70logfile = argv[2];
71if (logfile[0] == '+')
72 {
73 logfile++;
74 logmode = "a";
75 }
76
77log = fopen(logfile, logmode);
78if (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
87signal(SIGALRM, sigalrm_handler);
88
89/* Read the script, and do what it says. */
90
91while (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
162END_OFF:
163fclose(script);
164fclose(log);
165
166exit(0);
167}
168
169/* End of mtpscript.c */