--- qmail-smtpd.c.orig Mon Jan 26 16:53:54 2004 +++ qmail-smtpd.c Mon Jan 26 16:57:35 2004 @@ -57,6 +57,7 @@ void err_bmt() { out("533 sorry, your envelope recipient has been denied (#5.7.1)\r\n"); } void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); } void err_unimpl() { out("502 unimplemented (#5.5.1)\r\n"); } +void err_size() { out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); } void err_syntax() { out("555 syntax error (#5.5.4)\r\n"); } void err_wantmail() { out("503 MAIL first (#5.5.1)\r\n"); } void err_wantrcpt() { out("503 RCPT first (#5.5.1)\r\n"); } @@ -210,6 +211,40 @@ return 1; } +int sizelimit(arg) +char *arg; +{ + int i; + long r; + unsigned long sizebytes = 0; + + i = str_chr(arg,'<'); + if (arg[i]) + arg += i + 1; + else { + arg += str_chr(arg,':'); + if (*arg == ':') ++arg; + while (*arg == ' ') ++arg; + } + + arg += str_chr(arg,' '); + if (*arg == ' ') while (*arg == ' ') ++arg; + else return 1; + + i = str_chr(arg,'='); + arg[i] = 0; + if (case_equals(arg,"SIZE")) { + arg += i; + while (*++arg && *arg > 47 && *arg < 58) { + sizebytes *= 10; + sizebytes += *arg - 48; + } + r = databytes - sizebytes; + if (r < 0) return 0; + } + return 1; +} + int bmcheck(which) int which; { int i = 0; @@ -265,9 +300,16 @@ smtp_greet("250 "); out("\r\n"); seenmail = 0; dohelo(arg); } +char size_buf[FMT_ULONG]; +void smtp_size() +{ + size_buf[fmt_ulong(size_buf,(unsigned long) databytes)] = 0; + out("250 SIZE "); out(size_buf); out("\r\n"); +} void smtp_ehlo(arg) char *arg; { - smtp_greet("250-"); out("\r\n250-PIPELINING\r\n250 8BITMIME\r\n"); + smtp_greet("250-"); out("\r\n250-PIPELINING\r\n250-8BITMIME\r\n"); + smtp_size(); seenmail = 0; dohelo(arg); } void smtp_rset() @@ -279,6 +321,7 @@ { if (!addrparse(arg)) { err_syntax(); return; } if (bmfok) flagbarfbmf = bmcheck(BMCHECK_BMF); + if (databytes && !sizelimit(arg)) { err_size(); return; } seenmail = 1; if (!stralloc_copys(&rcptto,"")) die_nomem(); if (!stralloc_copys(&mailfrom,addr.s)) die_nomem();