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