00001
00002
00003
00004
00005 #include <unistd.h>
00006 #include "my_smtp.h"
00007
00008
00009
00010
00011 static struct sockaddr_in tcp_add;
00012
00013
00014
00015
00016 static int tcp_sock = -1;
00017
00018
00019
00020
00021 extern int smtp_yylex_memory (char *src);
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 static int response_parser (char *response, struct smtp_response *data)
00047 {
00048 int rc;
00049
00050 rc = smtp_yylex_memory(response);
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 if ((rc == 0) || (rc == -1)) { return SMTP_INVALID_ANSWER; }
00064
00065 return rc;
00066 }
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 int client_smtp_connect (
00094 struct smtp_connexion_config *conf,
00095 struct smtp_res *result
00096 )
00097 {
00098 int sock, rc;
00099 char iobuff[SMTP_BUFFER_SIZE];
00100 size_t read_bytes;
00101 struct smtp_response smtp_res;
00102 long ellapsed;
00103
00104
00105 result->error_code = 0;
00106 result->ellapsed = 0;
00107 tcp_sock = -1;
00108
00109
00110
00111
00112
00113 sock = open_tcp_connexion(
00114 &tcp_add,
00115 conf->host,
00116 conf->port,
00117 conf->connect_timeout_sec,
00118 conf->connect_timeout_micro,
00119 &ellapsed
00120 );
00121
00122 if (sock < 0)
00123 {
00124 result->error_code = sock;
00125 return -1;
00126 }
00127
00128 result->ellapsed += ellapsed;
00129
00130
00131
00132
00133
00134 rc = read_from_socket (
00135 sock,
00136 iobuff,
00137 SMTP_BUFFER_SIZE-1,
00138 &read_bytes,
00139 conf->read_timeout_sec,
00140 conf->read_timeout_micro,
00141 &ellapsed
00142 );
00143
00144 if (rc != SCK_READ_OK)
00145 {
00146 smtp_disconnect();
00147 result->error_code = rc;
00148 return -1;
00149 }
00150
00151 result->ellapsed += ellapsed;
00152
00153 iobuff[read_bytes] = 0;
00154
00155
00156
00157
00158
00159 rc = response_parser (iobuff, &smtp_res);
00160
00161 if (rc != SMTP_SERVER_IDENTIFICATION_OK)
00162 {
00163 smtp_disconnect();
00164 result->error_code = SMTP_BAD_ANSWER;
00165 return -1;
00166 }
00167
00168
00169
00170
00171
00172 if (write (sock, conf->id, strlen(conf->id)) != strlen(conf->id))
00173 {
00174 smtp_disconnect();
00175 result->error_code = SMTP_WRITE_ERROR;
00176 return -1;
00177 }
00178
00179
00180
00181
00182
00183 rc = read_from_socket (
00184 sock,
00185 iobuff,
00186 SMTP_BUFFER_SIZE-1,
00187 &read_bytes,
00188 conf->read_timeout_sec,
00189 conf->read_timeout_micro,
00190 &ellapsed
00191 );
00192
00193 if (rc != SCK_READ_OK)
00194 {
00195 smtp_disconnect();
00196 result->error_code = rc;
00197 return -1;
00198 }
00199
00200 result->ellapsed += ellapsed;
00201
00202 iobuff[read_bytes] = 0;
00203
00204
00205
00206
00207
00208 rc = response_parser (iobuff, &smtp_res);
00209
00210 if (rc != SMTP_CLIENT_IDENTIFICATION_OK)
00211 {
00212 smtp_disconnect();
00213 result->error_code = SMTP_BAD_ANSWER;
00214 return -1;
00215 }
00216
00217
00218
00219
00220
00221
00222 tcp_sock = sock;
00223
00224 return 0;
00225 }
00226
00227
00228
00229
00230 void smtp_disconnect() { if (tcp_sock >= 0) { close(tcp_sock); } }
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 int smtp_send_email (
00258 struct smtp_connexion_config *conf,
00259 struct smtp_mail *email,
00260 struct smtp_res *result
00261 )
00262 {
00263 int i, rc;
00264 char iobuff[SMTP_BUFFER_SIZE];
00265 size_t read_bytes;
00266 struct smtp_response smtp_res;
00267 long ellapsed;
00268
00269 result->error_code = 0;
00270 result->ellapsed = 0;
00271
00272
00273
00274
00275
00276 if (
00277 (
00278 strlen(email->from)
00279 +
00280 strlen(SMTP_FROM_TAG_START)
00281 +
00282 strlen(SMTP_FROM_TAG_STOP)
00283 )
00284 >
00285 SMTP_BUFFER_SIZE - 1
00286 )
00287 {
00288 smtp_disconnect();
00289 result->error_code = SMTP_BUFFER_OVERFLOW;
00290 return -1;
00291 }
00292
00293 sprintf (iobuff, "%s%s%s", SMTP_FROM_TAG_START, email->from, SMTP_FROM_TAG_STOP);
00294
00295
00296
00297
00298
00299 if (write (tcp_sock, iobuff, strlen(iobuff)) != strlen(iobuff))
00300 {
00301 smtp_disconnect();
00302 result->error_code = SMTP_WRITE_ERROR;
00303 return -1;
00304 }
00305
00306
00307
00308
00309
00310 rc = read_from_socket (
00311 tcp_sock,
00312 iobuff,
00313 SMTP_BUFFER_SIZE-1,
00314 &read_bytes,
00315 conf->read_timeout_sec,
00316 conf->read_timeout_micro,
00317 &ellapsed
00318 );
00319
00320 if (rc != SCK_READ_OK)
00321 {
00322 smtp_disconnect();
00323 result->error_code = rc;
00324 return -1;
00325 }
00326
00327 result->ellapsed += ellapsed;
00328
00329 iobuff[read_bytes] = 0;
00330
00331
00332
00333
00334
00335 rc = response_parser (iobuff, &smtp_res);
00336
00337 if (rc != SMTP_FROM_OK)
00338 {
00339 smtp_disconnect();
00340 result->error_code = SMTP_BAD_ANSWER;
00341 return -1;
00342 }
00343
00344
00345
00346
00347
00348 for (i=0; i<email->rcpt_number; i++)
00349 {
00350
00351
00352
00353
00354
00355 if (
00356 (
00357 strlen(email->rcpt)
00358 +
00359 strlen(SMTP_RCPT_TAG_START)
00360 +
00361 strlen(SMTP_RCPT_TAG_STOP)
00362 )
00363 >
00364 SMTP_BUFFER_SIZE - 1
00365 )
00366 {
00367 smtp_disconnect();
00368 result->error_code = SMTP_BUFFER_OVERFLOW;
00369 return -1;
00370 }
00371
00372 sprintf (iobuff, "%s%s%s", SMTP_RCPT_TAG_START, email->rcpt, SMTP_RCPT_TAG_STOP);
00373
00374
00375
00376
00377
00378 if (write (tcp_sock, iobuff, strlen(iobuff)) != strlen(iobuff))
00379 {
00380 smtp_disconnect();
00381 result->error_code = SMTP_WRITE_ERROR;
00382 return -1;
00383 }
00384
00385
00386
00387
00388
00389 rc = read_from_socket (
00390 tcp_sock,
00391 iobuff,
00392 SMTP_BUFFER_SIZE-1,
00393 &read_bytes,
00394 conf->read_timeout_sec,
00395 conf->read_timeout_micro,
00396 &ellapsed
00397 );
00398
00399 if (rc != SCK_READ_OK)
00400 {
00401 smtp_disconnect();
00402 result->error_code = rc;
00403 return -1;
00404 }
00405
00406 result->ellapsed += ellapsed;
00407
00408 iobuff[read_bytes] = 0;
00409
00410
00411
00412
00413
00414 rc = response_parser (iobuff, &smtp_res);
00415
00416 if (rc != SMTP_RCPT_OK)
00417 {
00418 smtp_disconnect();
00419 result->error_code = SMTP_BAD_ANSWER;
00420 return -1;
00421 }
00422 }
00423
00424
00425
00426
00427
00428 strcpy (iobuff, "DATA\r\n");
00429
00430 if (write (tcp_sock, iobuff, strlen(iobuff)) != strlen(iobuff))
00431 {
00432 smtp_disconnect();
00433 result->error_code = SMTP_WRITE_ERROR;
00434 return -1;
00435 }
00436
00437
00438
00439
00440
00441 rc = read_from_socket (
00442 tcp_sock,
00443 iobuff,
00444 SMTP_BUFFER_SIZE-1,
00445 &read_bytes,
00446 conf->read_timeout_sec,
00447 conf->read_timeout_micro,
00448 &ellapsed
00449 );
00450
00451 if (rc != SCK_READ_OK)
00452 {
00453 smtp_disconnect();
00454 result->error_code = rc;
00455 return -1;
00456 }
00457
00458 result->ellapsed += ellapsed;
00459
00460 iobuff[read_bytes] = 0;
00461
00462
00463
00464
00465
00466 rc = response_parser (iobuff, &smtp_res);
00467
00468 if (rc != SMTP_DATA_OK)
00469 {
00470 smtp_disconnect();
00471 result->error_code = SMTP_BAD_ANSWER;
00472 return -1;
00473 }
00474
00475
00476
00477
00478
00479 if (write (tcp_sock, email->data, strlen(email->data)) != strlen(email->data))
00480 {
00481 smtp_disconnect();
00482 result->error_code = SMTP_WRITE_ERROR;
00483 return -1;
00484 }
00485
00486
00487
00488
00489
00490 rc = read_from_socket (
00491 tcp_sock,
00492 iobuff,
00493 SMTP_BUFFER_SIZE-1,
00494 &read_bytes,
00495 conf->read_timeout_sec,
00496 conf->read_timeout_micro,
00497 &ellapsed
00498 );
00499
00500 if (rc != SCK_READ_OK)
00501 {
00502 smtp_disconnect();
00503 result->error_code = rc;
00504 return -1;
00505 }
00506
00507 result->ellapsed += ellapsed;
00508
00509 iobuff[read_bytes] = 0;
00510
00511
00512
00513
00514
00515 rc = response_parser (iobuff, &smtp_res);
00516
00517 if (rc != SMTP_END_OF_DATA_OK)
00518 {
00519 smtp_disconnect();
00520 result->error_code = SMTP_BAD_ANSWER;
00521 return -1;
00522 }
00523
00524
00525
00526
00527
00528 strcpy (iobuff, "QUIT\r\n");
00529
00530 if (write (tcp_sock, iobuff, strlen(iobuff)) != strlen(iobuff))
00531 {
00532 smtp_disconnect();
00533 result->error_code = SMTP_WRITE_ERROR;
00534 return -1;
00535 }
00536
00537 smtp_disconnect();
00538
00539 return 0;
00540 }