1 #ifndef _GNU_SOURCE
2 #define _GNU_SOURCE
3 #endif
4
5 #include "userlist.h"
6 #include "smtp.h"
7 #include <unistd.h>
8 #include <sys/wait.h>
9 #include <csignal>
10 #include <cstdio>
11 #include <cstdlib>
12 #include "postal.h"
13 #include "logit.h"
14
usage()15 void usage()
16 {
17 printf("Usage: postal [-m maximum-message-size] [-M minimum-message-size] [-t threads]\n"
18 " [-c messages-per-connection] [-r messages-per-minute] [-a]\n"
19 " [-b [no]netscape] [-p port] [-[z|Z] debug-file]\n"
20 #ifdef USE_SSL
21 " [-s ssl-percentage]\n"
22 #endif
23 " [-L] [-l local-address] [-f sender-file]\n"
24 " smtp-server user-list-filename\n"
25 "\n"
26 "Postal Version: " VER_STR "\n");
27 exit(eParam);
28 }
29
30 int exitCount = 0;
31
endit(int)32 void endit(int)
33 {
34 exitCount++;
35 if(exitCount > 2)
36 exit(1);
37 }
38
main(int argc,char ** argv)39 int main(int argc, char **argv)
40 {
41 int maxMsgSize = 10;
42 int minMsgSize = 0;
43 int processes = 1;
44 int msgsPerMinute = 0; // 0 for unlimited
45 int msgsPerConnection = 1;
46 const char *ourAddr = NULL;
47 bool allLog = false;
48 TRISTATE netscape = eNONE;
49 PCCHAR debugName = NULL;
50 PCCHAR senderFile = NULL;
51 bool debugMultipleFiles = false;
52 bool useLMTP = false;
53 #ifdef USE_SSL
54 int ssl = 0;
55 #endif
56 #ifdef USE_GNUTLS
57 #if GNUTLS_VERSION_NUMBER <= 0x020b00
58 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
59 #endif
60 gnutls_global_init();
61 if(!gnutls_check_version(GNUTLS_VER))
62 {
63 fprintf(stderr, "Needs version " GNUTLS_VER " of GNUTLS\n");
64 exit(1);
65 }
66 #endif
67 unsigned short port = 25;
68
69 int c;
70 while(-1 != (c = getopt(argc, argv, "ab:f:m:M:p:s:t:c:r:Ll:z:Z:")) )
71 {
72 switch(char(c))
73 {
74 case '?':
75 case ':':
76 usage();
77 break;
78 case 'a':
79 allLog = true;
80 break;
81 case 'b':
82 if(!strcasecmp(optarg, "netscape"))
83 netscape = eWONT;
84 else if(!strcasecmp(optarg, "nonetscape"))
85 netscape = eMUST;
86 break;
87 case 'f':
88 senderFile = optarg;
89 break;
90 case 'L':
91 useLMTP = true;
92 break;
93 case 'l':
94 ourAddr = optarg;
95 break;
96 case 'm':
97 maxMsgSize = atoi(optarg);
98 break;
99 case 'M':
100 minMsgSize = atoi(optarg);
101 break;
102 case 'p':
103 port = atoi(optarg);
104 break;
105 case 's':
106 #ifdef USE_SSL
107 ssl = atoi(optarg);
108 #else
109 usage();
110 #endif
111 break;
112 case 't':
113 processes = atoi(optarg);
114 break;
115 case 'c':
116 msgsPerConnection = atoi(optarg);
117 break;
118 case 'r':
119 msgsPerMinute = atoi(optarg);
120 break;
121 case 'Z':
122 debugMultipleFiles = true;
123 case 'z':
124 debugName = optarg;
125 break;
126 }
127 }
128 if(minMsgSize < 0 || maxMsgSize > MAX_MSG_SIZE || maxMsgSize < minMsgSize)
129 usage();
130
131 if(processes < 1 || processes > MAX_PROCESSES)
132 usage();
133 if(msgsPerMinute < 0 || msgsPerConnection < -1 )
134 usage();
135 #ifdef USE_SSL
136 if(ssl < 0 || ssl > 100)
137 usage();
138 #endif
139
140 if(optind + 2 != argc)
141 usage();
142
143 UserList ul(argv[optind + 1], false);
144 UserList *senderList = NULL;
145 if(senderFile)
146 senderList = new UserList(senderFile, false);
147
148 int fd[2];
149 if(pipe(fd))
150 {
151 printf("Can't create pipe.\n");
152 return eSystem;
153 }
154 struct sigaction sa;
155 memset(&sa, 0, sizeof(sa));
156 sa.sa_sigaction = NULL;
157 sa.sa_handler = SIG_IGN;
158 sa.sa_flags = 0;
159 if(sigaction(SIGPIPE, &sa, NULL))
160 {
161 printf("Can't block SIGPIPE.\n");
162 return eSystem;
163 }
164
165 sa.sa_flags = SA_SIGINFO;
166 sa.sa_handler = &endit;
167 if(sigaction(SIGINT, &sa, NULL))
168 {
169 printf("Can't handle SIGINT.\n");
170 return eSystem;
171 }
172
173 printf("time,messages,data(K),errors,connections"
174 #ifdef USE_SSL
175 ",SSL connections"
176 #endif
177 "\n");
178
179 Logit log("postal.log", allLog, false, 0);
180 Logit *debug = NULL;
181
182 if(debugName)
183 debug = new Logit(debugName, false, debugMultipleFiles, 0);
184
185 smtp mailer(&exitCount, argv[optind], ourAddr, ul, senderList, minMsgSize
186 , maxMsgSize, msgsPerConnection, processes, &log, netscape, useLMTP
187 #ifdef USE_SSL
188 , ssl
189 #endif
190 , port, debug);
191
192 int rc = mailer.doAllWork(msgsPerMinute);
193 if(debug)
194 delete debug;
195 return rc;
196 }
197
198