30
#ifdef NO_OPENSSL
31
typedef void *SSL;
32
#endif
33
+#ifdef USE_CURL_FOR_IMAP_SEND
34
+#include "http.h"
35
+#endif
36
37
static int verbosity;
38
+static int use_curl; /* strictly opt in */
39
36
-static const char * const imap_send_usage[] = { "git imap-send [-v] [-q] < <mbox>", NULL };
40
+static const char * const imap_send_usage[] = { "git imap-send [-v] [-q] [--[no-]curl] < <mbox>", NULL };
41
42
static struct option imap_send_options[] = {
43
OPT__VERBOSITY(&verbosity),
44
+ OPT_BOOL(0, "curl", &use_curl, "use libcurl to communicate with the IMAP server"),
45
OPT_END()
46
};
47
1349
git_config_get_string("imap.authmethod", &server.auth_method);
1350
}
1351
1347
-int main(int argc, char **argv)
1352
+static int append_msgs_to_imap(struct imap_server_conf *server,
1353
+ struct strbuf* all_msgs, int total)
1354
{
1349
- struct strbuf all_msgs = STRBUF_INIT;
1355
struct strbuf msg = STRBUF_INIT;
1356
struct imap_store *ctx = NULL;
1357
int ofs = 0;
1358
int r;
1354
- int total, n = 0;
1359
+ int n = 0;
1360
+
1361
+ ctx = imap_open_store(server, server->folder);
1362
+ if (!ctx) {
1363
+ fprintf(stderr, "failed to open store\n");
1364
+ return 1;
1365
+ }
1366
+ ctx->name = server->folder;
1367
+
1368
+ fprintf(stderr, "sending %d message%s\n", total, (total != 1) ? "s" : "");
1369
+ while (1) {
1370
+ unsigned percent = n * 100 / total;
1371
+
1372
+ fprintf(stderr, "%4u%% (%d/%d) done\r", percent, n, total);
1373
+
1374
+ if (!split_msg(all_msgs, &msg, &ofs))
1375
+ break;
1376
+ if (server->use_html)
1377
+ wrap_in_html(&msg);
1378
+ r = imap_store_msg(ctx, &msg);
1379
+ if (r != DRV_OK)
1380
+ break;
1381
+ n++;
1382
+ }
1383
+ fprintf(stderr, "\n");
1384
+
1385
+ imap_close_store(ctx);
1386
+
1387
+ return 0;
1388
+}
1389
+
1390
+#ifdef USE_CURL_FOR_IMAP_SEND
1391
+static CURL *setup_curl(struct imap_server_conf *srvc)
1392
+{
1393
+ CURL *curl;
1394
+ struct strbuf path = STRBUF_INIT;
1395
+
1396
+ if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
1397
+ die("curl_global_init failed");
1398
+
1399
+ curl = curl_easy_init();
1400
+
1401
+ if (!curl)
1402
+ die("curl_easy_init failed");
1403
+
1404
+ curl_easy_setopt(curl, CURLOPT_USERNAME, server.user);
1405
+ curl_easy_setopt(curl, CURLOPT_PASSWORD, server.pass);
1406
+
1407
+ strbuf_addstr(&path, server.host);
1408
+ if (!path.len || path.buf[path.len - 1] != '/')
1409
+ strbuf_addch(&path, '/');
1410
+ strbuf_addstr(&path, server.folder);
1411
+
1412
+ curl_easy_setopt(curl, CURLOPT_URL, path.buf);
1413
+ strbuf_release(&path);
1414
+ curl_easy_setopt(curl, CURLOPT_PORT, server.port);
1415
+
1416
+ if (server.auth_method) {
1417
+ struct strbuf auth = STRBUF_INIT;
1418
+ strbuf_addstr(&auth, "AUTH=");
1419
+ strbuf_addstr(&auth, server.auth_method);
1420
+ curl_easy_setopt(curl, CURLOPT_LOGIN_OPTIONS, auth.buf);
1421
+ strbuf_release(&auth);
1422
+ }
1423
+
1424
+ if (server.use_ssl)
1425
+ curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
1426
+
1427
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, server.ssl_verify);
1428
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, server.ssl_verify);
1429
+
1430
+ curl_easy_setopt(curl, CURLOPT_READFUNCTION, fread_buffer);
1431
+
1432
+ curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
1433
+
1434
+ if (0 < verbosity)
1435
+ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
1436
+
1437
+ return curl;
1438
+}
1439
+
1440
+static int curl_append_msgs_to_imap(struct imap_server_conf *server,
1441
+ struct strbuf* all_msgs, int total) {
1442
+ int ofs = 0;
1443
+ int n = 0;
1444
+ struct buffer msgbuf = { STRBUF_INIT, 0 };
1445
+ CURL *curl;
1446
+ CURLcode res = CURLE_OK;
1447
+
1448
+ curl = setup_curl(server);
1449
+ curl_easy_setopt(curl, CURLOPT_READDATA, &msgbuf);
1450
+
1451
+ fprintf(stderr, "sending %d message%s\n", total, (total != 1) ? "s" : "");
1452
+ while (1) {
1453
+ unsigned percent = n * 100 / total;
1454
+ int prev_len;
1455
+
1456
+ fprintf(stderr, "%4u%% (%d/%d) done\r", percent, n, total);
1457
+
1458
+ prev_len = msgbuf.buf.len;
1459
+ if (!split_msg(all_msgs, &msgbuf.buf, &ofs))
1460
+ break;
1461
+ if (server->use_html)
1462
+ wrap_in_html(&msgbuf.buf);
1463
+ lf_to_crlf(&msgbuf.buf);
1464
+
1465
+ curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
1466
+ (curl_off_t)(msgbuf.buf.len-prev_len));
1467
+
1468
+ res = curl_easy_perform(curl);
1469
+
1470
+ if(res != CURLE_OK) {
1471
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
1472
+ curl_easy_strerror(res));
1473
+ break;
1474
+ }
1475
+
1476
+ n++;
1477
+ }
1478
+ fprintf(stderr, "\n");
1479
+
1480
+ curl_easy_cleanup(curl);
1481
+ curl_global_cleanup();
1482
+
1483
+ return 0;
1484
+}
1485
+#endif
1486
+
1487
+int main(int argc, char **argv)
1488
+{
1489
+ struct strbuf all_msgs = STRBUF_INIT;
1490
+ int total;
1491
int nongit_ok;
1492
1493
git_extract_argv0_path(argv[0]);
1502
if (argc)
1503
usage_with_options(imap_send_usage, imap_send_options);
1504
1505
+#ifndef USE_CURL_FOR_IMAP_SEND
1506
+ if (use_curl) {
1507
+ warning("--use-curl not supported in this build");
1508
+ use_curl = 0;
1509
+ }
1510
+#endif
1511
+
1512
if (!server.port)
1513
server.port = server.use_ssl ? 993 : 143;
1514
1542
}
1543
1544
/* write it to the imap server */
1402
- ctx = imap_open_store(&server, server.folder);
1403
- if (!ctx) {
1404
- fprintf(stderr, "failed to open store\n");
1405
- return 1;
1406
- }
1407
-
1408
- fprintf(stderr, "sending %d message%s\n", total, (total != 1) ? "s" : "");
1409
- while (1) {
1410
- unsigned percent = n * 100 / total;
1545
1412
- fprintf(stderr, "%4u%% (%d/%d) done\r", percent, n, total);
1413
- if (!split_msg(&all_msgs, &msg, &ofs))
1414
- break;
1415
- if (server.use_html)
1416
- wrap_in_html(&msg);
1417
- r = imap_store_msg(ctx, &msg);
1418
- if (r != DRV_OK)
1419
- break;
1420
- n++;
1421
- }
1422
- fprintf(stderr, "\n");
1546
+ if (server.tunnel)
1547
+ return append_msgs_to_imap(&server, &all_msgs, total);
1548
1424
- imap_close_store(ctx);
1549
+#ifdef USE_CURL_FOR_IMAP_SEND
1550
+ if (use_curl)
1551
+ return curl_append_msgs_to_imap(&server, &all_msgs, total);
1552
+#endif
1553
1426
- return 0;
1554
+ return append_msgs_to_imap(&server, &all_msgs, total);
1555
}