aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmail-remote/qmailr_smtp.c
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2026-02-07 14:08:53 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2026-02-07 14:08:53 +0000
commitde33be8ad62f2c3c2f7c4030b1ebb301a73e0872 (patch)
treed97c4a015881ef52fee4236b07a82737f3e431c4 /src/qmail-remote/qmailr_smtp.c
parent5ca4a0e5b65066f41af7c670e8200b0d0eba41dd (diff)
downloadsmtpd-starttls-proxy-de33be8ad62f2c3c2f7c4030b1ebb301a73e0872.tar.gz
final batch of code, this should be complete!
Diffstat (limited to 'src/qmail-remote/qmailr_smtp.c')
-rw-r--r--src/qmail-remote/qmailr_smtp.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/qmail-remote/qmailr_smtp.c b/src/qmail-remote/qmailr_smtp.c
new file mode 100644
index 0000000..5a778f4
--- /dev/null
+++ b/src/qmail-remote/qmailr_smtp.c
@@ -0,0 +1,53 @@
+/* ISC license. */
+
+#include <strings.h>
+#include <errno.h>
+
+#include <skalibs/types.h>
+#include <skalibs/buffer.h>
+#include <skalibs/tai.h>
+#include <skalibs/unix-timed.h>
+
+#include "qmailr.h"
+
+#include <skalibs/posixishard.h>
+
+int qmailr_smtp_read_line (buffer *in, char *line, size_t max, unsigned int *code, tain const *deadline)
+{
+ unsigned int c ;
+ size_t w = 0 ;
+ ssize_t r = timed_getlnmax_g(in, line, max, &w, '\n', deadline) ;
+ if (r <= 0) return r ;
+ if (w < 4) return (errno = EPROTO, -1) ;
+ line[--w] = 0 ;
+ if (line[w-1] == '\r') line[--w] = 0 ;
+ while (w >= 3 && line[w-1] == ' ') line[--w] = 0 ;
+ if (uint_scan(line, &c) != 3) return (errno = EPROTO, -1) ;
+ *code = c ;
+ return 1 + (line[3] == '-') ;
+}
+
+int qmailr_smtp_read_answer (buffer *in, char *line, size_t max, unsigned int timeout)
+{
+ unsigned int code = 1000 ;
+ tain deadline ;
+ tain_addsec_g(&deadline, timeout) ;
+ for (;;)
+ {
+ unsigned int c ;
+ int r = qmailr_smtp_read_line(in, line, max, &c, &deadline) ;
+ if (r <= 0) return r ;
+ if (code == 1000) code = c ;
+ else if (code != c) return (errno = EPROTO, -1) ;
+ if (r == 1) break ;
+ }
+ return code ;
+}
+
+void qmailr_smtp_quit (buffer *out, unsigned int timeout)
+{
+ tain deadline ;
+ buffer_puts(out, "QUIT\r\n") ;
+ tain_addsec_g(&deadline, timeout) ;
+ buffer_timed_flush_g(out, &deadline) ;
+}