Fossil SCM

The test-smtp-probe command is now working.

drh 2018-06-28 17:15 UTC smtp
Commit 9281d52a91d8d2fb15d42437195e8b55652f24dace0d8c09e6701cebbc91ebb6
--- src/http_socket.c
+++ src/http_socket.c
@@ -207,17 +207,22 @@
207207
return total;
208208
}
209209
210210
/*
211211
** Receive content back from the open socket connection.
212
+** Return the number of bytes read.
213
+**
214
+** When bDontBlock is false, this function blocks until all N bytes
215
+** have been read.
212216
*/
213
-size_t socket_receive(void *NotUsed, void *pContent, size_t N){
217
+size_t socket_receive(void *NotUsed, void *pContent, size_t N, int bDontBlock){
214218
ssize_t got;
215219
size_t total = 0;
220
+ int flags = bDontBlock ? MSG_DONTWAIT : 0;
216221
while( N>0 ){
217222
/* WinXP fails for large values of N. So limit it to 64KiB. */
218
- got = recv(iSocket, pContent, N>65536 ? 65536 : N, 0);
223
+ got = recv(iSocket, pContent, N>65536 ? 65536 : N, flags);
219224
if( got<=0 ) break;
220225
total += (size_t)got;
221226
N -= (size_t)got;
222227
pContent = (void*)&((char*)pContent)[got];
223228
}
224229
--- src/http_socket.c
+++ src/http_socket.c
@@ -207,17 +207,22 @@
207 return total;
208 }
209
210 /*
211 ** Receive content back from the open socket connection.
 
 
 
 
212 */
213 size_t socket_receive(void *NotUsed, void *pContent, size_t N){
214 ssize_t got;
215 size_t total = 0;
 
216 while( N>0 ){
217 /* WinXP fails for large values of N. So limit it to 64KiB. */
218 got = recv(iSocket, pContent, N>65536 ? 65536 : N, 0);
219 if( got<=0 ) break;
220 total += (size_t)got;
221 N -= (size_t)got;
222 pContent = (void*)&((char*)pContent)[got];
223 }
224
--- src/http_socket.c
+++ src/http_socket.c
@@ -207,17 +207,22 @@
207 return total;
208 }
209
210 /*
211 ** Receive content back from the open socket connection.
212 ** Return the number of bytes read.
213 **
214 ** When bDontBlock is false, this function blocks until all N bytes
215 ** have been read.
216 */
217 size_t socket_receive(void *NotUsed, void *pContent, size_t N, int bDontBlock){
218 ssize_t got;
219 size_t total = 0;
220 int flags = bDontBlock ? MSG_DONTWAIT : 0;
221 while( N>0 ){
222 /* WinXP fails for large values of N. So limit it to 64KiB. */
223 got = recv(iSocket, pContent, N>65536 ? 65536 : N, flags);
224 if( got<=0 ) break;
225 total += (size_t)got;
226 N -= (size_t)got;
227 pContent = (void*)&((char*)pContent)[got];
228 }
229
--- src/http_transport.c
+++ src/http_transport.c
@@ -325,11 +325,11 @@
325325
got = 0;
326326
#endif
327327
}else if( pUrlData->isFile ){
328328
got = fread(zBuf, 1, N, transport.pFile);
329329
}else{
330
- got = socket_receive(0, zBuf, N);
330
+ got = socket_receive(0, zBuf, N, 0);
331331
}
332332
/* printf("received %d of %d bytes\n", got, N); fflush(stdout); */
333333
if( transport.pLog ){
334334
fwrite(zBuf, 1, got, transport.pLog);
335335
fflush(transport.pLog);
336336
--- src/http_transport.c
+++ src/http_transport.c
@@ -325,11 +325,11 @@
325 got = 0;
326 #endif
327 }else if( pUrlData->isFile ){
328 got = fread(zBuf, 1, N, transport.pFile);
329 }else{
330 got = socket_receive(0, zBuf, N);
331 }
332 /* printf("received %d of %d bytes\n", got, N); fflush(stdout); */
333 if( transport.pLog ){
334 fwrite(zBuf, 1, got, transport.pLog);
335 fflush(transport.pLog);
336
--- src/http_transport.c
+++ src/http_transport.c
@@ -325,11 +325,11 @@
325 got = 0;
326 #endif
327 }else if( pUrlData->isFile ){
328 got = fread(zBuf, 1, N, transport.pFile);
329 }else{
330 got = socket_receive(0, zBuf, N, 0);
331 }
332 /* printf("received %d of %d bytes\n", got, N); fflush(stdout); */
333 if( transport.pLog ){
334 fwrite(zBuf, 1, got, transport.pLog);
335 fflush(transport.pLog);
336
+81 -26
--- src/smtp.c
+++ src/smtp.c
@@ -117,11 +117,13 @@
117117
char *zHostname; /* Hostname of SMTP server for zDest */
118118
u32 smtpFlags; /* Flags changing the operation */
119119
FILE *logFile; /* Write session transcript to this log file */
120120
Blob *pTranscript; /* Record session transcript here */
121121
const char *zLabel; /* Either "CS" or "SC" */
122
+ int atEof; /* True after connection closes */
122123
char *zErr; /* Error message */
124
+ Blob inbuf; /* Input buffer */
123125
};
124126
125127
/* Allowed values for SmtpSession.smtpFlags */
126128
#define SMTP_TRACE_STDOUT 0x00001 /* Debugging info to console */
127129
#define SMTP_TRACE_FILE 0x00002 /* Debugging info to logFile */
@@ -132,10 +134,11 @@
132134
/*
133135
** Shutdown an SmtpSession
134136
*/
135137
void smtp_session_free(SmtpSession *pSession){
136138
socket_close();
139
+ blob_zero(&pSession->inbuf);
137140
fossil_free(pSession->zHostname);
138141
fossil_free(pSession->zErr);
139142
fossil_free(pSession);
140143
}
141144
@@ -159,27 +162,30 @@
159162
memset(p, 0, sizeof(*p));
160163
p->zFrom = zFrom;
161164
p->zDest = zDest;
162165
p->zLabel = zDest==0 ? "CS" : "SC";
163166
p->smtpFlags = smtpFlags;
167
+ blob_init(&p->inbuf, 0, 0);
164168
va_start(ap, smtpFlags);
165169
if( smtpFlags & SMTP_TRACE_FILE ){
166170
p->logFile = va_arg(ap, FILE*);
167171
}else if( smtpFlags & SMTP_TRACE_BLOB ){
168172
p->pTranscript = va_arg(ap, Blob*);
169173
}
170174
va_end(ap);
171175
p->zHostname = smtp_mx_host(zDest);
172176
if( p->zHostname==0 ){
177
+ p->atEof = 1;
173178
p->zErr = mprintf("cannot locate SMTP server for \"%s\"", zDest);
174179
return p;
175180
}
176181
memset(&url, 0, sizeof(url));
177182
url.name = p->zHostname;
178183
url.port = 25;
179184
socket_global_init();
180185
if( socket_open(&url) ){
186
+ p->atEof = 1;
181187
p->zErr = socket_errmsg();
182188
socket_close();
183189
}
184190
return p;
185191
}
@@ -190,10 +196,11 @@
190196
static void smtp_send_line(SmtpSession *p, const char *zFormat, ...){
191197
Blob b = empty_blob;
192198
va_list ap;
193199
char *z;
194200
int n;
201
+ if( p->atEof ) return;
195202
va_start(ap, zFormat);
196203
blob_vappendf(&b, zFormat, ap);
197204
va_end(ap);
198205
z = blob_buffer(&b);
199206
n = blob_size(&b);
@@ -212,27 +219,60 @@
212219
socket_send(0, z, n);
213220
blob_zero(&b);
214221
}
215222
216223
/*
217
-** Read a line of input received from the SMTP server. Append
218
-** the received line onto the end of the blob.
224
+** Read a line of input received from the SMTP server. Make in point
225
+** to the next input line.
226
+**
227
+** Content is actually read into the p->in buffer. Then blob_line()
228
+** is used to extract individual lines, passing each to "in".
219229
*/
220230
static void smtp_recv_line(SmtpSession *p, Blob *in){
221
- int n = blob_size(in);
222
- int iStart = n;
223
- char *z;
224
- do{
225
- size_t got;
226
- blob_resize(in, n+1000);
227
- z = blob_buffer(in);
228
- got = socket_receive(0, z+n, 1000);
229
- in->nUsed += got;
230
- n += got;
231
- }while( n<1 || z[n-1]!='\n' );
232
- z = blob_buffer(in) + iStart;
233
- n = blob_size(in) - iStart - 1;
231
+ int n = blob_size(&p->inbuf);
232
+ char *z = blob_buffer(&p->inbuf);
233
+ int i = blob_tell(&p->inbuf);
234
+ int nDelay = 0;
235
+ if( i<n && z[n-1]=='\n' ){
236
+ blob_line(&p->inbuf, in);
237
+ }else if( p->atEof ){
238
+ blob_init(in, 0, 0);
239
+ }else{
240
+ if( n>0 && i>=n ){
241
+ blob_truncate(&p->inbuf, 0);
242
+ blob_rewind(&p->inbuf);
243
+ n = 0;
244
+ }
245
+ do{
246
+ size_t got;
247
+ blob_resize(&p->inbuf, n+1000);
248
+ z = blob_buffer(&p->inbuf);
249
+ got = socket_receive(0, z+n, 1000, 1);
250
+ if( got>0 ){
251
+ in->nUsed += got;
252
+ n += got;
253
+ z[n] = 0;
254
+ if( n>0 && z[n-1]=='\n' ) break;
255
+ if( got==1000 ) continue;
256
+ }
257
+ nDelay++;
258
+ if( nDelay>100 ){
259
+ blob_init(in, 0, 0);
260
+ p->zErr = mprintf("timeout");
261
+ socket_close();
262
+ p->atEof = 1;
263
+ return;
264
+ }else{
265
+ sqlite3_sleep(25);
266
+ }
267
+ }while( n<1 || z[n-1]!='\n' );
268
+ blob_truncate(&p->inbuf, n);
269
+ blob_line(&p->inbuf, in);
270
+ }
271
+ z = blob_buffer(in);
272
+ n = blob_size(in);
273
+ if( n && z[n-1]=='\n' ) n--;
234274
if( n && z[n-1]=='\r' ) n--;
235275
if( p->smtpFlags & SMTP_TRACE_STDOUT ){
236276
fossil_print("%c: %.*s\n", p->zLabel[0], n, z);
237277
}
238278
if( p->smtpFlags & SMTP_TRACE_FILE ){
@@ -251,15 +291,25 @@
251291
Blob *in, /* Buffer used to hold the reply */
252292
int *piCode, /* The return code */
253293
int *pbMore, /* True if the reply is not complete */
254294
char **pzArg /* Argument */
255295
){
296
+ int n;
297
+ char *z;
256298
blob_truncate(in, 0);
257299
smtp_recv_line(p, in);
258
- *piCode = atoi(blob_str(in));
259
- *pbMore = blob_size(in)>=4 && blob_str(in)[3]=='-';
260
- *pzArg = blob_size(in)>=4 ? blob_str(in)+4 : "";
300
+ z = blob_str(in);
301
+ n = blob_size(in);
302
+ if( z[0]=='#' ){
303
+ *piCode = 0;
304
+ *pbMore = 1;
305
+ *pzArg = z;
306
+ }else{
307
+ *piCode = atoi(z);
308
+ *pbMore = n>=4 && z[3]=='-';
309
+ *pzArg = n>=4 ? z+4 : "";
310
+ }
261311
}
262312
263313
/*
264314
** Have the client send a QUIT message.
265315
*/
@@ -306,26 +356,31 @@
306356
}
307357
308358
/*
309359
** COMMAND: test-smtp-probe
310360
**
311
-** Usage: %fossil test-smtp-probe DOMAIN ME
361
+** Usage: %fossil test-smtp-probe DOMAIN [ME]
312362
**
313363
** Interact with the SMTP server for DOMAIN by setting up a connection
314364
** and then immediately shutting it back down. Log all interaction
315365
** on the console. Use ME as the domain name of the sender.
316366
*/
317367
void test_smtp_probe(void){
318
- char *zHost;
319368
SmtpSession *p;
320369
int rc;
321
- if( g.argc!=4 ) usage("DOMAIN ME");
322
- zHost = smtp_mx_host(g.argv[2]);
323
- if( zHost==0 ){
324
- fossil_fatal("cannot resolve the MX for \"%s\"", g.argv[2]);
370
+ const char *zDomain;
371
+ const char *zSelf;
372
+ if( g.argc!=3 && g.argc!=4 ) usage("DOMAIN [ME]");
373
+ zDomain = g.argv[2];
374
+ zSelf = g.argc==4 ? g.argv[3] : "fossil-scm.org";
375
+ p = smtp_session_new(zSelf, zDomain, SMTP_TRACE_STDOUT);
376
+ if( p->zErr ){
377
+ fossil_fatal("%s", p->zErr);
325378
}
326
- fossil_print("Contacting host \"%s\"\n", zHost);
327
- p = smtp_session_new(g.argv[3], zHost, SMTP_TRACE_STDOUT);
379
+ fossil_print("Connection to \"%s\"\n", p->zHostname);
328380
rc = smtp_client_startup(p);
329381
if( !rc ) smtp_client_quit(p);
382
+ if( p->zErr ){
383
+ fossil_fatal("ERROR: %s\n", p->zErr);
384
+ }
330385
smtp_session_free(p);
331386
}
332387
--- src/smtp.c
+++ src/smtp.c
@@ -117,11 +117,13 @@
117 char *zHostname; /* Hostname of SMTP server for zDest */
118 u32 smtpFlags; /* Flags changing the operation */
119 FILE *logFile; /* Write session transcript to this log file */
120 Blob *pTranscript; /* Record session transcript here */
121 const char *zLabel; /* Either "CS" or "SC" */
 
122 char *zErr; /* Error message */
 
123 };
124
125 /* Allowed values for SmtpSession.smtpFlags */
126 #define SMTP_TRACE_STDOUT 0x00001 /* Debugging info to console */
127 #define SMTP_TRACE_FILE 0x00002 /* Debugging info to logFile */
@@ -132,10 +134,11 @@
132 /*
133 ** Shutdown an SmtpSession
134 */
135 void smtp_session_free(SmtpSession *pSession){
136 socket_close();
 
137 fossil_free(pSession->zHostname);
138 fossil_free(pSession->zErr);
139 fossil_free(pSession);
140 }
141
@@ -159,27 +162,30 @@
159 memset(p, 0, sizeof(*p));
160 p->zFrom = zFrom;
161 p->zDest = zDest;
162 p->zLabel = zDest==0 ? "CS" : "SC";
163 p->smtpFlags = smtpFlags;
 
164 va_start(ap, smtpFlags);
165 if( smtpFlags & SMTP_TRACE_FILE ){
166 p->logFile = va_arg(ap, FILE*);
167 }else if( smtpFlags & SMTP_TRACE_BLOB ){
168 p->pTranscript = va_arg(ap, Blob*);
169 }
170 va_end(ap);
171 p->zHostname = smtp_mx_host(zDest);
172 if( p->zHostname==0 ){
 
173 p->zErr = mprintf("cannot locate SMTP server for \"%s\"", zDest);
174 return p;
175 }
176 memset(&url, 0, sizeof(url));
177 url.name = p->zHostname;
178 url.port = 25;
179 socket_global_init();
180 if( socket_open(&url) ){
 
181 p->zErr = socket_errmsg();
182 socket_close();
183 }
184 return p;
185 }
@@ -190,10 +196,11 @@
190 static void smtp_send_line(SmtpSession *p, const char *zFormat, ...){
191 Blob b = empty_blob;
192 va_list ap;
193 char *z;
194 int n;
 
195 va_start(ap, zFormat);
196 blob_vappendf(&b, zFormat, ap);
197 va_end(ap);
198 z = blob_buffer(&b);
199 n = blob_size(&b);
@@ -212,27 +219,60 @@
212 socket_send(0, z, n);
213 blob_zero(&b);
214 }
215
216 /*
217 ** Read a line of input received from the SMTP server. Append
218 ** the received line onto the end of the blob.
 
 
 
219 */
220 static void smtp_recv_line(SmtpSession *p, Blob *in){
221 int n = blob_size(in);
222 int iStart = n;
223 char *z;
224 do{
225 size_t got;
226 blob_resize(in, n+1000);
227 z = blob_buffer(in);
228 got = socket_receive(0, z+n, 1000);
229 in->nUsed += got;
230 n += got;
231 }while( n<1 || z[n-1]!='\n' );
232 z = blob_buffer(in) + iStart;
233 n = blob_size(in) - iStart - 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234 if( n && z[n-1]=='\r' ) n--;
235 if( p->smtpFlags & SMTP_TRACE_STDOUT ){
236 fossil_print("%c: %.*s\n", p->zLabel[0], n, z);
237 }
238 if( p->smtpFlags & SMTP_TRACE_FILE ){
@@ -251,15 +291,25 @@
251 Blob *in, /* Buffer used to hold the reply */
252 int *piCode, /* The return code */
253 int *pbMore, /* True if the reply is not complete */
254 char **pzArg /* Argument */
255 ){
 
 
256 blob_truncate(in, 0);
257 smtp_recv_line(p, in);
258 *piCode = atoi(blob_str(in));
259 *pbMore = blob_size(in)>=4 && blob_str(in)[3]=='-';
260 *pzArg = blob_size(in)>=4 ? blob_str(in)+4 : "";
 
 
 
 
 
 
 
 
261 }
262
263 /*
264 ** Have the client send a QUIT message.
265 */
@@ -306,26 +356,31 @@
306 }
307
308 /*
309 ** COMMAND: test-smtp-probe
310 **
311 ** Usage: %fossil test-smtp-probe DOMAIN ME
312 **
313 ** Interact with the SMTP server for DOMAIN by setting up a connection
314 ** and then immediately shutting it back down. Log all interaction
315 ** on the console. Use ME as the domain name of the sender.
316 */
317 void test_smtp_probe(void){
318 char *zHost;
319 SmtpSession *p;
320 int rc;
321 if( g.argc!=4 ) usage("DOMAIN ME");
322 zHost = smtp_mx_host(g.argv[2]);
323 if( zHost==0 ){
324 fossil_fatal("cannot resolve the MX for \"%s\"", g.argv[2]);
 
 
 
 
325 }
326 fossil_print("Contacting host \"%s\"\n", zHost);
327 p = smtp_session_new(g.argv[3], zHost, SMTP_TRACE_STDOUT);
328 rc = smtp_client_startup(p);
329 if( !rc ) smtp_client_quit(p);
 
 
 
330 smtp_session_free(p);
331 }
332
--- src/smtp.c
+++ src/smtp.c
@@ -117,11 +117,13 @@
117 char *zHostname; /* Hostname of SMTP server for zDest */
118 u32 smtpFlags; /* Flags changing the operation */
119 FILE *logFile; /* Write session transcript to this log file */
120 Blob *pTranscript; /* Record session transcript here */
121 const char *zLabel; /* Either "CS" or "SC" */
122 int atEof; /* True after connection closes */
123 char *zErr; /* Error message */
124 Blob inbuf; /* Input buffer */
125 };
126
127 /* Allowed values for SmtpSession.smtpFlags */
128 #define SMTP_TRACE_STDOUT 0x00001 /* Debugging info to console */
129 #define SMTP_TRACE_FILE 0x00002 /* Debugging info to logFile */
@@ -132,10 +134,11 @@
134 /*
135 ** Shutdown an SmtpSession
136 */
137 void smtp_session_free(SmtpSession *pSession){
138 socket_close();
139 blob_zero(&pSession->inbuf);
140 fossil_free(pSession->zHostname);
141 fossil_free(pSession->zErr);
142 fossil_free(pSession);
143 }
144
@@ -159,27 +162,30 @@
162 memset(p, 0, sizeof(*p));
163 p->zFrom = zFrom;
164 p->zDest = zDest;
165 p->zLabel = zDest==0 ? "CS" : "SC";
166 p->smtpFlags = smtpFlags;
167 blob_init(&p->inbuf, 0, 0);
168 va_start(ap, smtpFlags);
169 if( smtpFlags & SMTP_TRACE_FILE ){
170 p->logFile = va_arg(ap, FILE*);
171 }else if( smtpFlags & SMTP_TRACE_BLOB ){
172 p->pTranscript = va_arg(ap, Blob*);
173 }
174 va_end(ap);
175 p->zHostname = smtp_mx_host(zDest);
176 if( p->zHostname==0 ){
177 p->atEof = 1;
178 p->zErr = mprintf("cannot locate SMTP server for \"%s\"", zDest);
179 return p;
180 }
181 memset(&url, 0, sizeof(url));
182 url.name = p->zHostname;
183 url.port = 25;
184 socket_global_init();
185 if( socket_open(&url) ){
186 p->atEof = 1;
187 p->zErr = socket_errmsg();
188 socket_close();
189 }
190 return p;
191 }
@@ -190,10 +196,11 @@
196 static void smtp_send_line(SmtpSession *p, const char *zFormat, ...){
197 Blob b = empty_blob;
198 va_list ap;
199 char *z;
200 int n;
201 if( p->atEof ) return;
202 va_start(ap, zFormat);
203 blob_vappendf(&b, zFormat, ap);
204 va_end(ap);
205 z = blob_buffer(&b);
206 n = blob_size(&b);
@@ -212,27 +219,60 @@
219 socket_send(0, z, n);
220 blob_zero(&b);
221 }
222
223 /*
224 ** Read a line of input received from the SMTP server. Make in point
225 ** to the next input line.
226 **
227 ** Content is actually read into the p->in buffer. Then blob_line()
228 ** is used to extract individual lines, passing each to "in".
229 */
230 static void smtp_recv_line(SmtpSession *p, Blob *in){
231 int n = blob_size(&p->inbuf);
232 char *z = blob_buffer(&p->inbuf);
233 int i = blob_tell(&p->inbuf);
234 int nDelay = 0;
235 if( i<n && z[n-1]=='\n' ){
236 blob_line(&p->inbuf, in);
237 }else if( p->atEof ){
238 blob_init(in, 0, 0);
239 }else{
240 if( n>0 && i>=n ){
241 blob_truncate(&p->inbuf, 0);
242 blob_rewind(&p->inbuf);
243 n = 0;
244 }
245 do{
246 size_t got;
247 blob_resize(&p->inbuf, n+1000);
248 z = blob_buffer(&p->inbuf);
249 got = socket_receive(0, z+n, 1000, 1);
250 if( got>0 ){
251 in->nUsed += got;
252 n += got;
253 z[n] = 0;
254 if( n>0 && z[n-1]=='\n' ) break;
255 if( got==1000 ) continue;
256 }
257 nDelay++;
258 if( nDelay>100 ){
259 blob_init(in, 0, 0);
260 p->zErr = mprintf("timeout");
261 socket_close();
262 p->atEof = 1;
263 return;
264 }else{
265 sqlite3_sleep(25);
266 }
267 }while( n<1 || z[n-1]!='\n' );
268 blob_truncate(&p->inbuf, n);
269 blob_line(&p->inbuf, in);
270 }
271 z = blob_buffer(in);
272 n = blob_size(in);
273 if( n && z[n-1]=='\n' ) n--;
274 if( n && z[n-1]=='\r' ) n--;
275 if( p->smtpFlags & SMTP_TRACE_STDOUT ){
276 fossil_print("%c: %.*s\n", p->zLabel[0], n, z);
277 }
278 if( p->smtpFlags & SMTP_TRACE_FILE ){
@@ -251,15 +291,25 @@
291 Blob *in, /* Buffer used to hold the reply */
292 int *piCode, /* The return code */
293 int *pbMore, /* True if the reply is not complete */
294 char **pzArg /* Argument */
295 ){
296 int n;
297 char *z;
298 blob_truncate(in, 0);
299 smtp_recv_line(p, in);
300 z = blob_str(in);
301 n = blob_size(in);
302 if( z[0]=='#' ){
303 *piCode = 0;
304 *pbMore = 1;
305 *pzArg = z;
306 }else{
307 *piCode = atoi(z);
308 *pbMore = n>=4 && z[3]=='-';
309 *pzArg = n>=4 ? z+4 : "";
310 }
311 }
312
313 /*
314 ** Have the client send a QUIT message.
315 */
@@ -306,26 +356,31 @@
356 }
357
358 /*
359 ** COMMAND: test-smtp-probe
360 **
361 ** Usage: %fossil test-smtp-probe DOMAIN [ME]
362 **
363 ** Interact with the SMTP server for DOMAIN by setting up a connection
364 ** and then immediately shutting it back down. Log all interaction
365 ** on the console. Use ME as the domain name of the sender.
366 */
367 void test_smtp_probe(void){
 
368 SmtpSession *p;
369 int rc;
370 const char *zDomain;
371 const char *zSelf;
372 if( g.argc!=3 && g.argc!=4 ) usage("DOMAIN [ME]");
373 zDomain = g.argv[2];
374 zSelf = g.argc==4 ? g.argv[3] : "fossil-scm.org";
375 p = smtp_session_new(zSelf, zDomain, SMTP_TRACE_STDOUT);
376 if( p->zErr ){
377 fossil_fatal("%s", p->zErr);
378 }
379 fossil_print("Connection to \"%s\"\n", p->zHostname);
 
380 rc = smtp_client_startup(p);
381 if( !rc ) smtp_client_quit(p);
382 if( p->zErr ){
383 fossil_fatal("ERROR: %s\n", p->zErr);
384 }
385 smtp_session_free(p);
386 }
387

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button