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