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