Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/lavabit/magma.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLadar Levison <ladar@lavabit.com>2017-03-29 11:38:06 +0300
committerLadar Levison <ladar@lavabit.com>2017-03-29 11:38:06 +0300
commit9ebb4f5374918caf73159f6d07f1e63815a4b14a (patch)
tree3a36b192aae6930e696838c21b5ca3ad620f1679
parentfdff4e66e2c988e647500bcfe4b6a2a895b58029 (diff)
Fixed smtp_client_send_data so it dotstuffs, added comments/error checks.
-rw-r--r--src/objects/mail/cleanup.c4
-rw-r--r--src/servers/smtp/messages.c8
-rw-r--r--src/servers/smtp/relay.c56
3 files changed, 26 insertions, 42 deletions
diff --git a/src/objects/mail/cleanup.c b/src/objects/mail/cleanup.c
index f51041a6..0dfb0698 100644
--- a/src/objects/mail/cleanup.c
+++ b/src/objects/mail/cleanup.c
@@ -80,8 +80,8 @@ bool_t mail_message_cleanup(stringer_t **message) {
added++;
}
- // Allocate a new stringer for the cleaned up message.
- if (!(output = st_alloc_opts(MAPPED_T | JOINTED | HEAP, added))) {
+ // Allocate a new string buffer to hold the cleaned version of the message.
+ if (!(output = st_alloc_opts(MAPPED_T | JOINTED | HEAP, added))) {
log_pedantic("Unable to allocate %zu bytes for a new stringer.", added);
return false;
}
diff --git a/src/servers/smtp/messages.c b/src/servers/smtp/messages.c
deleted file mode 100644
index 9a814e03..00000000
--- a/src/servers/smtp/messages.c
+++ /dev/null
@@ -1,8 +0,0 @@
-
-/**
- * @file /magma/servers/smtp/messages.c
- *
- * @brief Handle the SMTP message structure.
- */
-
-#include "magma.h"
diff --git a/src/servers/smtp/relay.c b/src/servers/smtp/relay.c
index 64a012e7..009a4ad6 100644
--- a/src/servers/smtp/relay.c
+++ b/src/servers/smtp/relay.c
@@ -232,45 +232,37 @@ int_t smtp_client_send_rcptto(client_t *client, stringer_t *rcptto) {
*/
int_t smtp_client_send_data(client_t *client, stringer_t *message) {
- chr_t *holder;
- size_t length;
-
- if (!(length = st_length_get(message))) {
- log_pedantic("An invalid message length was discovered.");
- return -1;
+ int64_t sent = 0, line = 0;
+
+ // Send the DATA command and confirm the proceed response was recieved in response.
+ if ((sent = client_write(client, PLACER("DATA\r\n", 6))) != 6 || (line = client_read_line(client)) <= 0 || !pl_starts_with_char(client->line, '3')) {
+ log_pedantic("A%serror occurred while trying to send the DATA command.%s", (sent != 6 || line <= 0 ? " network " : "n "),
+ (sent == 6 && line > 0 ? st_char_get(st_quick(MANAGEDBUF(1024), " { response = %.*s }", st_length_int(&(client->line)),
+ st_char_get(&(client->line)))) : ""));
+ return (sent != 6 || line <= 0 ? -1 : -2);
}
- client_write(client, PLACER("DATA\r\n", 6));
+ // Dot stuff the message using the string replace function, which requires a message be stored in a jointed
+ // buffer, that can be dynamially reallocated if necessary.
+ st_replace(&(message), PLACER("\n.", 2), PLACER("\n..", 3));
- if (client_read_line(client) <= 0) {
- log_pedantic("An error occurred while attempting to send the DATA command.");
- return -1;
+ // Send the message and confirm all of the bytes were sent.
+ if ((sent = client_write(client, message)) != st_length_get(message)) {
+ log_pedantic("Message relay failed. { sent = %li / size = %zu }", sent, st_length_get(message));
}
- else if (*(st_char_get(client->buffer)) != '3') {
- log_pedantic("An error occurred while attempting to send the DATA command. {response = %.*s}",
- st_length_int(&(client->line)), st_char_get(&(client->line)));
- return -2;
- }
-
- client_write(client, message);
-
- holder = st_char_get(message);
- if (length < 2 || *(holder + length - 2) != '\r' || *(holder + length - 2) != '\n') {
- client_write(client, PLACER("\r\n.\r\n", 5));
- }
- else {
- client_write(client, PLACER(".\r\n", 3));
+ // If the message doesn't end witha line break, we'll send a line terminator here, so the termination sequence sent below
+ // will appear on a line by itself.
+ if (!st_cmp_cs_ends(message, PLACER("\n", 1))) {
+ client_write(client, PLACER("\r\n", 2));
}
- if (client_read_line(client) <= 0) {
- log_pedantic("A network error occurred while attempting to transmit the message.");
- return -1;
- }
- else if (*(st_char_get(client->buffer)) != '2') {
- log_pedantic("An error occurred while attempting to transmit the message. {response = %.*s}",
- st_length_int(&(client->line)), st_char_get(&(client->line)));
- return -2;
+ // Read in the result code to see if the message was relayed successfully. If it fails, print the resulting response message.
+ if ((sent = client_write(client, PLACER(".\r\n", 3))) != 3 || (line = client_read_line(client)) <= 0 || !pl_starts_with_char(client->line, '2')) {
+ log_pedantic("A%serror occurred while attempting to transmit the message.%s", (sent != 3 || line <= 0 ? " network " : "n "),
+ (sent == 6 && line > 0 ? st_char_get(st_quick(MANAGEDBUF(1024), " { response = %.*s }", st_length_int(&(client->line)),
+ st_char_get(&(client->line)))) : ""));
+ return (sent != 3 || line <= 0 ? -1 : -2);
}
return 1;