summaryrefslogtreecommitdiffstats
path: root/qmail-pop3d.c
diff options
context:
space:
mode:
Diffstat (limited to 'qmail-pop3d.c')
-rw-r--r--qmail-pop3d.c75
1 files changed, 57 insertions, 18 deletions
diff --git a/qmail-pop3d.c b/qmail-pop3d.c
index 51976c2..d2a6f87 100644
--- a/qmail-pop3d.c
+++ b/qmail-pop3d.c
@@ -16,6 +16,11 @@
16#include "readwrite.h" 16#include "readwrite.h"
17#include "timeoutread.h" 17#include "timeoutread.h"
18#include "timeoutwrite.h" 18#include "timeoutwrite.h"
19#include <errno.h>
20#include "maildirquota.h"
21#include "maildirmisc.h"
22
23#define QUOTABUFSIZE 256
19 24
20void die() { _exit(0); } 25void die() { _exit(0); }
21 26
@@ -45,19 +50,15 @@ void put(buf,len) char *buf; int len;
45{ 50{
46 substdio_put(&ssout,buf,len); 51 substdio_put(&ssout,buf,len);
47} 52}
48void puts(s) char *s;
49{
50 substdio_puts(&ssout,s);
51}
52void flush() 53void flush()
53{ 54{
54 substdio_flush(&ssout); 55 substdio_flush(&ssout);
55} 56}
56void err(s) char *s; 57void err(s) char *s;
57{ 58{
58 puts("-ERR "); 59 substdio_puts(&ssout,"-ERR ");
59 puts(s); 60 substdio_puts(&ssout,s);
60 puts("\r\n"); 61 substdio_puts(&ssout,"\r\n");
61 flush(); 62 flush();
62} 63}
63 64
@@ -73,7 +74,7 @@ void err_toobig() { err("not that many messages"); }
73void err_nosuch() { err("unable to open that message"); } 74void err_nosuch() { err("unable to open that message"); }
74void err_nounlink() { err("unable to unlink all deleted messages"); } 75void err_nounlink() { err("unable to unlink all deleted messages"); }
75 76
76void okay() { puts("+OK \r\n"); flush(); } 77void okay() { substdio_puts(&ssout,"+OK \r\n"); flush(); }
77 78
78void printfn(fn) char *fn; 79void printfn(fn) char *fn;
79{ 80{
@@ -153,11 +154,11 @@ void pop3_stat()
153 154
154 total = 0; 155 total = 0;
155 for (i = 0;i < numm;++i) if (!m[i].flagdeleted) total += m[i].size; 156 for (i = 0;i < numm;++i) if (!m[i].flagdeleted) total += m[i].size;
156 puts("+OK "); 157 substdio_puts(&ssout,"+OK ");
157 put(strnum,fmt_uint(strnum,numm)); 158 put(strnum,fmt_uint(strnum,numm));
158 puts(" "); 159 substdio_puts(&ssout," ");
159 put(strnum,fmt_ulong(strnum,total)); 160 put(strnum,fmt_ulong(strnum,total));
160 puts("\r\n"); 161 substdio_puts(&ssout,"\r\n");
161 flush(); 162 flush();
162} 163}
163 164
@@ -171,18 +172,41 @@ void pop3_rset()
171 172
172void pop3_last() 173void pop3_last()
173{ 174{
174 puts("+OK "); 175 substdio_puts(&ssout,"+OK ");
175 put(strnum,fmt_uint(strnum,last)); 176 put(strnum,fmt_uint(strnum,last));
176 puts("\r\n"); 177 substdio_puts(&ssout,"\r\n");
177 flush(); 178 flush();
178} 179}
179 180
180void pop3_quit() 181void pop3_quit()
181{ 182{
182 int i; 183 int i;
184 char quotabuf[QUOTABUFSIZE];
185 int has_quota=maildir_getquota(".", quotabuf);
186
187 long deleted_bytes=0;
188 long deleted_messages=0;
189
183 for (i = 0;i < numm;++i) 190 for (i = 0;i < numm;++i)
184 if (m[i].flagdeleted) { 191 if (m[i].flagdeleted) {
185 if (unlink(m[i].fn) == -1) err_nounlink(); 192 unsigned long un=0;
193 const char *filename=m[i].fn;
194 if (has_quota == 0 && !MAILDIR_DELETED(filename)) {
195 if (maildir_parsequota(filename, &un)) {
196 struct stat stat_buf;
197
198 if (stat(filename, &stat_buf) == 0)
199 un=stat_buf.st_size;
200 }
201 }
202 if (unlink(m[i].fn) == -1) {
203 err_nounlink();
204 un=0;
205 }
206 if (un) {
207 deleted_bytes -= un;
208 deleted_messages -= 1;
209 }
186 } 210 }
187 else 211 else
188 if (str_start(m[i].fn,"new/")) { 212 if (str_start(m[i].fn,"new/")) {
@@ -192,6 +216,21 @@ void pop3_quit()
192 if (!stralloc_0(&line)) die_nomem(); 216 if (!stralloc_0(&line)) die_nomem();
193 rename(m[i].fn,line.s); /* if it fails, bummer */ 217 rename(m[i].fn,line.s); /* if it fails, bummer */
194 } 218 }
219
220 if (deleted_messages < 0) {
221 int quotafd;
222
223 if (maildir_checkquota(".", &quotafd, quotabuf, deleted_bytes,
224 deleted_messages) && errno != EAGAIN &&
225 deleted_bytes >= 0)
226 {
227 if (quotafd >= 0) close (quotafd);
228 } else {
229 maildir_addquota(".", quotafd, quotabuf,
230 deleted_bytes, deleted_messages);
231 if (quotafd >= 0) close(quotafd);
232 }
233 }
195 okay(); 234 okay();
196 die(); 235 die();
197} 236}
@@ -222,10 +261,10 @@ int i;
222int flaguidl; 261int flaguidl;
223{ 262{
224 put(strnum,fmt_uint(strnum,i + 1)); 263 put(strnum,fmt_uint(strnum,i + 1));
225 puts(" "); 264 substdio_puts(&ssout," ");
226 if (flaguidl) printfn(m[i].fn); 265 if (flaguidl) printfn(m[i].fn);
227 else put(strnum,fmt_ulong(strnum,m[i].size)); 266 else put(strnum,fmt_ulong(strnum,m[i].size));
228 puts("\r\n"); 267 substdio_puts(&ssout,"\r\n");
229} 268}
230 269
231void dolisting(arg,flaguidl) char *arg; int flaguidl; 270void dolisting(arg,flaguidl) char *arg; int flaguidl;
@@ -234,7 +273,7 @@ void dolisting(arg,flaguidl) char *arg; int flaguidl;
234 if (*arg) { 273 if (*arg) {
235 i = msgno(arg); 274 i = msgno(arg);
236 if (i == -1) return; 275 if (i == -1) return;
237 puts("+OK "); 276 substdio_puts(&ssout,"+OK ");
238 list(i,flaguidl); 277 list(i,flaguidl);
239 } 278 }
240 else { 279 else {
@@ -242,7 +281,7 @@ void dolisting(arg,flaguidl) char *arg; int flaguidl;
242 for (i = 0;i < numm;++i) 281 for (i = 0;i < numm;++i)
243 if (!m[i].flagdeleted) 282 if (!m[i].flagdeleted)
244 list(i,flaguidl); 283 list(i,flaguidl);
245 puts(".\r\n"); 284 substdio_puts(&ssout,".\r\n");
246 } 285 }
247 flush(); 286 flush();
248} 287}