* LMTP is like SMTP but with some extra bonus footage added.
*/
void lmtp_greeting(void) {
+ citsmtp *sSMTP;
+
smtp_greeting(0);
+ sSMTP = SMTP;
SMTP->is_lmtp = 1;
}
* We also have an unfiltered LMTP socket that bypasses spam filters.
*/
void lmtp_unfiltered_greeting(void) {
- citsmtp *sSMTP = SMTP;
+ citsmtp *sSMTP;
+
smtp_greeting(0);
+ sSMTP = SMTP;
sSMTP->is_lmtp = 1;
sSMTP->is_unfiltered = 1;
}
* Implements the DATA command
*/
void smtp_data(void) {
- char *body;
+ StrBuf *body;
+ char *defbody; //TODO: remove me
struct CtdlMessage *msg = NULL;
long msgnum = (-1L);
char nowstamp[SIZ];
cprintf("354 Transmit message now - terminate with '.' by itself\r\n");
datestring(nowstamp, sizeof nowstamp, time(NULL), DATESTRING_RFC822);
- body = malloc(4096);
+ defbody = malloc(4096);
- if (body != NULL) {
+ if (defbody != NULL) {
if (sSMTP->is_lmtp && (CC->cs_UDSclientUID != -1)) {
- snprintf(body, 4096,
- "Received: from %s (Citadel from userid %ld)\n"
- " by %s; %s\n",
- sSMTP->helo_node,
- (long int) CC->cs_UDSclientUID,
- config.c_fqdn,
- nowstamp);
+ snprintf(defbody, 4096,
+ "Received: from %s (Citadel from userid %ld)\n"
+ " by %s; %s\n",
+ sSMTP->helo_node,
+ (long int) CC->cs_UDSclientUID,
+ config.c_fqdn,
+ nowstamp);
}
else {
- snprintf(body, 4096,
+ snprintf(defbody, 4096,
"Received: from %s (%s [%s])\n"
" by %s; %s\n",
sSMTP->helo_node,
nowstamp);
}
}
- body = CtdlReadMessageBody(".", config.c_maxmsglen, body, 1, 0);
+ body = CtdlReadMessageBodyBuf(HKEY("."), config.c_maxmsglen, defbody, 1, NULL);
if (body == NULL) {
cprintf("550 Unable to save message: internal error.\r\n");
return;
}
CtdlLogPrintf(CTDL_DEBUG, "Converting message...\n");
- msg = convert_internet_message(body);
+ msg = convert_internet_message_buf(&body);
/* If the user is locally authenticated, FORCE the From: header to
* show up as the real sender. Yes, this violates the RFC standard,
char cmdbuf[SIZ];
citsmtp *sSMTP = SMTP;
+ if (sSMTP == NULL) {
+ CtdlLogPrintf(CTDL_EMERG, "Session SMTP data is null. WTF? We will crash now.\n");
+ }
+
time(&CC->lastcmd);
memset(cmdbuf, 0, sizeof cmdbuf); /* Clear it, just in case */
if (client_getln(cmdbuf, sizeof cmdbuf) < 1) {
char mx_port[256];
int lp, rp;
char *msgtext;
- char *ptr;
+ const char *ptr;
size_t msg_size;
int scan_done;
+ CitContext *CCC=CC;
/* Parse out the host portion of the recipient address */
user, node, name);
/* Load the message out of the database */
- CC->redirect_buffer = malloc(SIZ);
- CC->redirect_len = 0;
- CC->redirect_alloc = SIZ;
+ CCC->redirect_buffer = malloc(SIZ);
+ CCC->redirect_len = 0;
+ CCC->redirect_alloc = SIZ;
CtdlOutputMsg(msgnum, MT_RFC822, HEADERS_ALL, 0, 1, NULL, ESC_DOT);
msgtext = CC->redirect_buffer;
msg_size = CC->redirect_len;
- CC->redirect_buffer = NULL;
- CC->redirect_len = 0;
- CC->redirect_alloc = 0;
+ CCC->redirect_buffer = NULL;
+ CCC->redirect_len = 0;
+ CCC->redirect_alloc = 0;
/* If no envelope_from is supplied, extract one from the message */
if ( (envelope_from == NULL) || (IsEmptyStr(envelope_from)) ) {
return;
}
+ CCC->sReadBuf = NewStrBuf();
+ CCC->sMigrateBuf = NewStrBuf();
+ CCC->sPos = NULL;
+
/* Process the SMTP greeting from the server */
- if (ml_sock_gets(sock, buf) < 0) {
+ if (ml_sock_gets(&sock, buf) < 0) {
*status = 4;
strcpy(dsn, "Connection broken during SMTP conversation");
goto bail;
/* Do a EHLO command. If it fails, try the HELO command. */
snprintf(buf, sizeof buf, "EHLO %s\r\n", config.c_fqdn);
CtdlLogPrintf(CTDL_DEBUG, ">%s", buf);
- sock_write(sock, buf, strlen(buf));
- if (ml_sock_gets(sock, buf) < 0) {
+ sock_write(&sock, buf, strlen(buf));
+ if (ml_sock_gets(&sock, buf) < 0) {
*status = 4;
strcpy(dsn, "Connection broken during SMTP HELO");
goto bail;
if (buf[0] != '2') {
snprintf(buf, sizeof buf, "HELO %s\r\n", config.c_fqdn);
CtdlLogPrintf(CTDL_DEBUG, ">%s", buf);
- sock_write(sock, buf, strlen(buf));
- if (ml_sock_gets(sock, buf) < 0) {
+ sock_write(&sock, buf, strlen(buf));
+ if (ml_sock_gets(&sock, buf) < 0) {
*status = 4;
strcpy(dsn, "Connection broken during SMTP HELO");
goto bail;
CtdlEncodeBase64(encoded, buf, strlen(mx_user) + strlen(mx_user) + strlen(mx_pass) + 2, 0);
snprintf(buf, sizeof buf, "AUTH PLAIN %s\r\n", encoded);
CtdlLogPrintf(CTDL_DEBUG, ">%s", buf);
- sock_write(sock, buf, strlen(buf));
- if (ml_sock_gets(sock, buf) < 0) {
+ sock_write(&sock, buf, strlen(buf));
+ if (ml_sock_gets(&sock, buf) < 0) {
*status = 4;
strcpy(dsn, "Connection broken during SMTP AUTH");
goto bail;
/* previous command succeeded, now try the MAIL FROM: command */
snprintf(buf, sizeof buf, "MAIL FROM:<%s>\r\n", envelope_from);
CtdlLogPrintf(CTDL_DEBUG, ">%s", buf);
- sock_write(sock, buf, strlen(buf));
- if (ml_sock_gets(sock, buf) < 0) {
+ sock_write(&sock, buf, strlen(buf));
+ if (ml_sock_gets(&sock, buf) < 0) {
*status = 4;
strcpy(dsn, "Connection broken during SMTP MAIL");
goto bail;
/* MAIL succeeded, now try the RCPT To: command */
snprintf(buf, sizeof buf, "RCPT TO:<%s@%s>\r\n", user, node);
CtdlLogPrintf(CTDL_DEBUG, ">%s", buf);
- sock_write(sock, buf, strlen(buf));
- if (ml_sock_gets(sock, buf) < 0) {
+ sock_write(&sock, buf, strlen(buf));
+ if (ml_sock_gets(&sock, buf) < 0) {
*status = 4;
strcpy(dsn, "Connection broken during SMTP RCPT");
goto bail;
/* RCPT succeeded, now try the DATA command */
CtdlLogPrintf(CTDL_DEBUG, ">DATA\n");
- sock_write(sock, "DATA\r\n", 6);
- if (ml_sock_gets(sock, buf) < 0) {
+ sock_write(&sock, "DATA\r\n", 6);
+ if (ml_sock_gets(&sock, buf) < 0) {
*status = 4;
strcpy(dsn, "Connection broken during SMTP DATA");
goto bail;
}
/* If we reach this point, the server is expecting data.*/
- sock_write(sock, msgtext, msg_size);
+ sock_write(&sock, msgtext, msg_size);
if (msgtext[msg_size-1] != 10) {
CtdlLogPrintf(CTDL_WARNING, "Possible problem: message did not "
"correctly terminate. (expecting 0x10, got 0x%02x)\n",
buf[msg_size-1]);
- sock_write(sock, "\r\n", 2);
+ sock_write(&sock, "\r\n", 2);
}
- sock_write(sock, ".\r\n", 3);
- if (ml_sock_gets(sock, buf) < 0) {
+ sock_write(&sock, ".\r\n", 3);
+ if (ml_sock_gets(&sock, buf) < 0) {
*status = 4;
strcpy(dsn, "Connection broken during SMTP message transmit");
goto bail;
*status = 2;
CtdlLogPrintf(CTDL_DEBUG, ">QUIT\n");
- sock_write(sock, "QUIT\r\n", 6);
- ml_sock_gets(sock, buf);
+ sock_write(&sock, "QUIT\r\n", 6);
+ ml_sock_gets(&sock, buf);
CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
CtdlLogPrintf(CTDL_INFO, "SMTP client: delivery to <%s> @ <%s> (%s) succeeded\n",
user, node, name);
bail: free(msgtext);
- sock_close(sock);
+ FreeStrBuf(&CCC->sReadBuf);
+ FreeStrBuf(&CCC->sMigrateBuf);
+ if (sock != -1)
+ sock_close(sock);
/* Write something to the syslog (which may or may not be where the
* rest of the Citadel logs are going; some sysadmins want LOG_MAIL).