View | Details | Raw Unified | Return to bug 168870
Collapse All | Expand All

(-)./Makefile (-4 / +3 lines)
Lines 7-13 Link Here
7
7
8
PORTNAME=	qmail
8
PORTNAME=	qmail
9
PORTVERSION?=	${QMAIL_VERSION}
9
PORTVERSION?=	${QMAIL_VERSION}
10
PORTREVISION?=	7
10
PORTREVISION?=	8
11
CATEGORIES=	mail
11
CATEGORIES=	mail
12
MASTER_SITES+=	${MASTER_SITE_QMAIL}
12
MASTER_SITES+=	${MASTER_SITE_QMAIL}
13
DISTNAME=	${PORTNAME}-${QMAIL_VERSION}
13
DISTNAME=	${PORTNAME}-${QMAIL_VERSION}
Lines 352-358 Link Here
352
. endif
352
. endif
353
353
354
. if defined(WITH_SRS)
354
. if defined(WITH_SRS)
355
BUILD_DEPENDS= srs:${PORTSDIR}/mail/libsrs2
355
BUILD_DEPENDS=	srs:${PORTSDIR}/mail/libsrs2
356
MASTER_SITES+=	http://qmail-ldap-smtpauthuser.googlecode.com/svn/trunk/:srs_ldap
356
MASTER_SITES+=	http://qmail-ldap-smtpauthuser.googlecode.com/svn/trunk/:srs_ldap
357
SRS_LDAP_PATCH =	qmail-ldap-1.03-20060201-SRS.patch
357
SRS_LDAP_PATCH =	qmail-ldap-1.03-20060201-SRS.patch
358
DISTFILES+=	${SRS_LDAP_PATCH}:srs_ldap
358
DISTFILES+=	${SRS_LDAP_PATCH}:srs_ldap
Lines 380-387 Link Here
380
.endif
380
.endif
381
381
382
.if defined(WITH_MAILDIRQUOTA_PATCH) && !defined(BARRIER_MAILDIRQUOTA_PATCH)
382
.if defined(WITH_MAILDIRQUOTA_PATCH) && !defined(BARRIER_MAILDIRQUOTA_PATCH)
383
PATCH_SITES+=	http://www.alexdupre.com/qmail/:quota
383
EXTRA_PATCHES+=	${FILESDIR}/extra-patch-qmail-maildir++
384
PATCHFILES+=	qmail-maildir++.patch:quota
385
.endif
384
.endif
386
385
387
.if defined(WITH_BLOCKEXEC_PATCH) && !defined(BARRIER_BLOCKEXEC_PATCH)
386
.if defined(WITH_BLOCKEXEC_PATCH) && !defined(BARRIER_BLOCKEXEC_PATCH)
(-)./distinfo (-2 lines)
Lines 22-29 Link Here
22
SIZE (qmail/outgoingip.patch-spamcontrol-25) = 6751
22
SIZE (qmail/outgoingip.patch-spamcontrol-25) = 6751
23
SHA256 (qmail/qmail-1.03-qmtpc_outgoingip_20090630.patch) = a5b521d3f35aa0842ea3fe69f6e51fa3be5e9c0acfad8671de36fa62a5cb9539
23
SHA256 (qmail/qmail-1.03-qmtpc_outgoingip_20090630.patch) = a5b521d3f35aa0842ea3fe69f6e51fa3be5e9c0acfad8671de36fa62a5cb9539
24
SIZE (qmail/qmail-1.03-qmtpc_outgoingip_20090630.patch) = 10364
24
SIZE (qmail/qmail-1.03-qmtpc_outgoingip_20090630.patch) = 10364
25
SHA256 (qmail/qmail-maildir++.patch) = 79e3f1f8f95b58b6d17e5469f125d873fe212d0a5a6d19b538ad57176fbafb52
26
SIZE (qmail/qmail-maildir++.patch) = 38088
27
SHA256 (qmail/qmail-block-executables.patch) = 97512624eb02db51e10ab6d0dd834a8797a238d0e006bd1c6c94a183d291b456
25
SHA256 (qmail/qmail-block-executables.patch) = 97512624eb02db51e10ab6d0dd834a8797a238d0e006bd1c6c94a183d291b456
28
SIZE (qmail/qmail-block-executables.patch) = 5070
26
SIZE (qmail/qmail-block-executables.patch) = 5070
29
SHA256 (qmail/qmail-discard-double-bounces.patch) = 14489eefd9908f60af13fadd574d0e9bb936e5d1b706690ce52efef68529a8d8
27
SHA256 (qmail/qmail-discard-double-bounces.patch) = 14489eefd9908f60af13fadd574d0e9bb936e5d1b706690ce52efef68529a8d8
(-)./files/extra-patch-qmail-maildir++ (+1643 lines)
Line 0 Link Here
1
diff -ruN Makefile Makefile
2
--- Makefile	Wed Aug  6 17:05:13 2003
3
+++ Makefile	Wed Aug  6 17:09:48 2003
4
@@ -890,6 +890,38 @@
5
 readwrite.h open.h headerbody.h maildir.h strerr.h
6
 	./compile maildirwatch.c
7
 
8
+maildirgetquota.o: \
9
+compile maildirgetquota.c maildirgetquota.h maildirmisc.h
10
+	./compile maildirgetquota.c
11
+
12
+maildirflags.o: \
13
+compile maildirflags.c
14
+	./compile maildirflags.c
15
+
16
+maildiropen.o: \
17
+compile maildiropen.c maildirmisc.h
18
+	./compile maildiropen.c
19
+
20
+maildirparsequota.o: \
21
+compile maildirparsequota.c
22
+	./compile maildirparsequota.c
23
+
24
+maildirquota.o: \
25
+compile maildirquota.c maildirquota.h maildirmisc.h numlib.h
26
+	./compile maildirquota.c
27
+
28
+overmaildirquota.o: \
29
+compile overmaildirquota.c 
30
+	./compile overmaildirquota.c
31
+
32
+strtimet.o: \
33
+compile strtimet.c 
34
+	./compile strtimet.c
35
+
36
+strpidt.o: \
37
+compile strpidt.c 
38
+	./compile strpidt.c
39
+
40
 mailsubj: \
41
 warn-auto.sh mailsubj.sh conf-qmail conf-break conf-split
42
 	cat warn-auto.sh mailsubj.sh \
43
@@ -1174,12 +1206,15 @@
44
 load qmail-local.o qmail.o quote.o now.o gfrom.o myctime.o \
45
 slurpclose.o case.a getln.a getopt.a sig.a open.a seek.a lock.a fd.a \
46
 wait.a env.a stralloc.a alloc.a strerr.a substdio.a error.a str.a \
47
-fs.a datetime.a auto_qmail.o auto_patrn.o socket.lib
48
+fs.a datetime.a auto_qmail.o auto_patrn.o socket.lib maildirquota.o \
49
+maildirgetquota.o maildiropen.o maildirparsequota.o overmaildirquota.o \
50
+strtimet.o strpidt.o
51
 	./load qmail-local qmail.o quote.o now.o gfrom.o myctime.o \
52
 	slurpclose.o case.a getln.a getopt.a sig.a open.a seek.a \
53
 	lock.a fd.a wait.a env.a stralloc.a alloc.a strerr.a \
54
 	substdio.a error.a str.a fs.a datetime.a auto_qmail.o \
55
-	auto_patrn.o  `cat socket.lib`
56
+	auto_patrn.o  `cat socket.lib` maildirquota.o maildirgetquota.o \
57
+    maildiropen.o maildirparsequota.o overmaildirquota.o strtimet.o strpidt.o
58
 
59
 qmail-local.0: \
60
 qmail-local.8
61
@@ -1269,11 +1304,13 @@
62
 qmail-pop3d: \
63
 load qmail-pop3d.o commands.o case.a timeoutread.o timeoutwrite.o \
64
 maildir.o prioq.o now.o env.a strerr.a sig.a open.a getln.a \
65
-stralloc.a alloc.a substdio.a error.a str.a fs.a socket.lib
66
+stralloc.a alloc.a substdio.a error.a str.a fs.a socket.lib maildirquota.o \
67
+maildirparsequota.o maildirflags.o maildiropen.o strtimet.o strpidt.o
68
 	./load qmail-pop3d commands.o case.a timeoutread.o \
69
 	timeoutwrite.o maildir.o prioq.o now.o env.a strerr.a sig.a \
70
 	open.a getln.a stralloc.a alloc.a substdio.a error.a str.a \
71
-	fs.a  `cat socket.lib`
72
+	fs.a  `cat socket.lib` maildirquota.o maildirgetquota.o \
73
+    maildirparsequota.o maildirflags.o maildiropen.o strtimet.o strpidt.o
74
 
75
 qmail-pop3d.0: \
76
 qmail-pop3d.8
77
diff -ruN TARGETS TARGETS
78
--- TARGETS	Wed Aug  6 17:05:13 2003
79
+++ TARGETS	Wed Aug  6 17:09:48 2003
80
@@ -15,6 +15,14 @@
81
 slurpclose.o
82
 make-makelib
83
 makelib
84
+maildirflags.o
85
+maildirparsequota.o
86
+maildiropen.o
87
+maildirgetquota.o
88
+maildirquota.o
89
+overmaildirquota.o
90
+strtimet.o
91
+strpidt.o
92
 case_diffb.o
93
 case_diffs.o
94
 case_lowerb.o
95
diff -ruN maildirflags.c maildirflags.c
96
--- maildirflags.c	Thu Jan  1 01:00:00 1970
97
+++ maildirflags.c	Wed Aug  6 17:09:48 2003
98
@@ -0,0 +1,23 @@
99
+/*
100
+** Copyright 2000 Double Precision, Inc.
101
+** See COPYING for distribution information.
102
+*/
103
+
104
+#include	<sys/types.h>
105
+#include	<string.h>
106
+
107
+static const char rcsid[]="$Id: maildirflags.c,v 1.1 2000/10/07 01:10:19 mrsam Exp $";
108
+
109
+int maildir_hasflag(const char *filename, char flag)
110
+{
111
+	const char *p=strrchr(filename, '/');
112
+
113
+	if (p)
114
+		filename=p+1;
115
+
116
+	p=strrchr(p, ':');
117
+	if (p && strncmp(p, ":2,", 3) == 0 &&
118
+	    strchr(p+3, flag))
119
+		return (1);
120
+	return (0);
121
+}
122
diff -ruN maildirgetquota.c maildirgetquota.c
123
--- maildirgetquota.c	Thu Jan  1 01:00:00 1970
124
+++ maildirgetquota.c	Wed Aug  6 17:09:48 2003
125
@@ -0,0 +1,50 @@
126
+/*
127
+** Copyright 1998 - 2000 Double Precision, Inc.
128
+** See COPYING for distribution information.
129
+*/
130
+
131
+#include	"maildirgetquota.h"
132
+#include	"maildirmisc.h"
133
+#if	HAVE_UNISTD_H
134
+#include	<unistd.h>
135
+#endif
136
+#include	<stdlib.h>
137
+#include	<string.h>
138
+#include	<fcntl.h>
139
+#include	<sys/types.h>
140
+#include	<sys/stat.h>
141
+
142
+int	maildir_getquota(const char *dir, char buf[QUOTABUFSIZE])
143
+{
144
+char	*p;
145
+struct	stat	stat_buf;
146
+int	n;
147
+int	l;
148
+
149
+	p=(char *)malloc(strlen(dir)+sizeof("/maildirfolder"));
150
+	if (!p)	return (-1);
151
+
152
+	strcat(strcpy(p, dir), "/maildirfolder");
153
+	if (stat(p, &stat_buf) == 0)
154
+	{
155
+		strcat(strcpy(p, dir), "/..");
156
+		n=maildir_getquota(p, buf);
157
+		free(p);
158
+		return (n);
159
+	}
160
+
161
+	strcat(strcpy(p, dir), "/maildirsize");
162
+	n=maildir_safeopen(p, O_RDONLY, 0);
163
+	free(p);
164
+	if (n < 0)	return (n);
165
+	if ((l=read(n, buf, QUOTABUFSIZE-1)) < 0)
166
+	{
167
+		close(n);
168
+		return (-1);
169
+	}
170
+	close(n);
171
+	for (n=0; n<l; n++)
172
+		if (buf[n] == '\n')	break;
173
+	buf[n]=0;
174
+	return (0);
175
+}
176
diff -ruN maildirgetquota.h maildirgetquota.h
177
--- maildirgetquota.h	Thu Jan  1 01:00:00 1970
178
+++ maildirgetquota.h	Wed Aug  6 17:09:48 2003
179
@@ -0,0 +1,30 @@
180
+#ifndef	maildirgetquota_h
181
+#define	maildirgetquota_h
182
+
183
+/*
184
+** Copyright 1998 - 1999 Double Precision, Inc.
185
+** See COPYING for distribution information.
186
+*/
187
+
188
+#if	HAVE_CONFIG_H
189
+#include	"config.h"
190
+#endif
191
+
192
+#include	<sys/types.h>
193
+#include	<stdio.h>
194
+
195
+#ifdef  __cplusplus
196
+extern "C" {
197
+#endif
198
+
199
+static const char maildirgetquota_h_rcsid[]="$Id: maildirgetquota.h,v 1.5 1999/12/06 13:21:05 mrsam Exp $";
200
+
201
+#define	QUOTABUFSIZE	256
202
+
203
+int maildir_getquota(const char *, char [QUOTABUFSIZE]);
204
+
205
+#ifdef  __cplusplus
206
+}
207
+#endif
208
+
209
+#endif
210
diff -ruN maildirmisc.h maildirmisc.h
211
--- maildirmisc.h	Thu Jan  1 01:00:00 1970
212
+++ maildirmisc.h	Wed Aug  6 17:09:48 2003
213
@@ -0,0 +1,145 @@
214
+#ifndef	maildirmisc_h
215
+#define	maildirmisc_h
216
+
217
+/*
218
+** Copyright 2000 Double Precision, Inc.
219
+** See COPYING for distribution information.
220
+*/
221
+
222
+#if	HAVE_CONFIG_H
223
+#include	"config.h"
224
+#endif
225
+
226
+#ifdef  __cplusplus
227
+extern "C" {
228
+#endif
229
+
230
+static const char maildirmisc_h_rcsid[]="$Id: maildirmisc.h,v 1.8 2000/12/25 17:33:06 mrsam Exp $";
231
+
232
+/*
233
+**
234
+** Miscellaneous maildir-related code
235
+**
236
+*/
237
+
238
+/* Some special folders */
239
+
240
+#define	INBOX	"INBOX"
241
+#define	DRAFTS	"Drafts"
242
+#define	SENT	"Sent"
243
+#define	TRASH	"Trash"
244
+
245
+#define	SHAREDSUBDIR	"shared-folders"
246
+
247
+char *maildir_folderdir(const char *,		/* maildir */
248
+	const char *);				/* folder name */
249
+	/* Returns the directory corresponding to foldername (foldername is
250
+	** checked to make sure that it's a valid name, else we set errno
251
+	** to EINVAL, and return (0).
252
+	*/
253
+
254
+char *maildir_filename(const char *,		/* maildir */
255
+	const char *,				/* folder */
256
+	const char *);				/* filename */
257
+	/*
258
+	** Builds the filename to this message, suitable for opening.
259
+	** If the file doesn't appear to be there, search the maildir to
260
+	** see if someone changed the flags, and return the current filename.
261
+	*/
262
+
263
+int maildir_safeopen(const char *,		/* filename */
264
+	int,				/* mode */
265
+	int);				/* perm */
266
+
267
+/*
268
+**	Same arguments as open().  When we're accessing a shared maildir,
269
+**	prevent someone from playing cute and dumping a bunch of symlinks
270
+**	in there.  This function will open the indicate file only if the
271
+**	last component is not a symlink.
272
+**	This is implemented by opening the file with O_NONBLOCK (to prevent
273
+**	a DOS attack of someone pointing the symlink to a pipe, causing
274
+**	the open to hang), clearing O_NONBLOCK, then stat-int the file
275
+**	descriptor, lstating the filename, and making sure that dev/ino
276
+**	match.
277
+*/
278
+
279
+int maildir_semisafeopen(const char *,	/* filename */
280
+	int,				/* mode */
281
+	int);				/* perm */
282
+
283
+/*
284
+** Same thing, except that we allow ONE level of soft link indirection,
285
+** because we're reading from our own maildir, which points to the
286
+** message in the sharable maildir.
287
+*/
288
+
289
+int maildir_mkdir(const char *);	/* directory */
290
+/*
291
+** Create maildir including all subdirectories in the path (like mkdir -p)
292
+*/
293
+
294
+void maildir_purgetmp(const char *);		/* maildir */
295
+	/* purges old stuff out of tmp */
296
+
297
+void maildir_purge(const char *,		/* directory */
298
+	unsigned);				/* time_t to purge */
299
+
300
+void maildir_getnew(const char *,		/* maildir */
301
+	const char *);				/* folder */
302
+	/* move messages from new to cur */
303
+
304
+int maildir_deletefolder(const char *,		/* maildir */
305
+	const char *);				/* folder */
306
+	/* deletes a folder */
307
+
308
+int maildir_mddelete(const char *);	/* delete a maildir folder by path */
309
+
310
+void maildir_list_sharable(const char *,	/* maildir */
311
+	void (*)(const char *, void *),		/* callback function */
312
+	void *);				/* 2nd arg to callback func */
313
+	/* list sharable folders */
314
+
315
+int maildir_shared_subscribe(const char *,	/* maildir */
316
+		const char *);			/* folder */
317
+	/* subscribe to a shared folder */
318
+
319
+void maildir_list_shared(const char *,		/* maildir */
320
+	void (*)(const char *, void *),		/* callback function */
321
+	void *);			/* 2nd arg to the callback func */
322
+	/* list subscribed folders */
323
+
324
+int maildir_shared_unsubscribe(const char *,	/* maildir */
325
+		const char *);			/* folder */
326
+	/* unsubscribe from a shared folder */
327
+
328
+char *maildir_shareddir(const char *,		/* maildir */
329
+	const char *);				/* folder */
330
+	/*
331
+	** Validate and return a path to a shared folder.  folderdir must be
332
+	** a name of a valid shared folder.
333
+	*/
334
+
335
+void maildir_shared_sync(const char *);		/* maildir */
336
+	/* "sync" the shared folder */
337
+
338
+int maildir_sharedisro(const char *);		/* maildir */
339
+	/* maildir is a shared read-only folder */
340
+
341
+int maildir_unlinksharedmsg(const char *);	/* filename */
342
+	/* Remove a message from a shared folder */
343
+
344
+/* Internal function that reads a symlink */
345
+
346
+char *maildir_getlink(const char *);
347
+
348
+	/* Determine whether the maildir filename has a certain flag */
349
+
350
+int maildir_hasflag(const char *filename, char);
351
+
352
+#define	MAILDIR_DELETED(f)	maildir_hasflag((f), 'T')
353
+
354
+#ifdef  __cplusplus
355
+}
356
+#endif
357
+
358
+#endif
359
diff -ruN maildiropen.c maildiropen.c
360
--- maildiropen.c	Thu Jan  1 01:00:00 1970
361
+++ maildiropen.c	Wed Aug  6 17:09:48 2003
362
@@ -0,0 +1,133 @@
363
+/*
364
+** Copyright 2000 Double Precision, Inc.
365
+** See COPYING for distribution information.
366
+*/
367
+
368
+#if HAVE_CONFIG_H
369
+#include "config.h"
370
+#endif
371
+
372
+#include	<sys/types.h>
373
+#include	<sys/stat.h>
374
+#include	<string.h>
375
+#include	<stdlib.h>
376
+#include	<time.h>
377
+#if	HAVE_UNISTD_H
378
+#include	<unistd.h>
379
+#endif
380
+#include	<stdio.h>
381
+#include	<ctype.h>
382
+#include	<errno.h>
383
+#include	<fcntl.h>
384
+
385
+#include	"maildirmisc.h"
386
+
387
+static const char rcsid[]="$Id: maildiropen.c,v 1.7 2000/12/10 04:43:44 mrsam Exp $";
388
+
389
+char *maildir_getlink(const char *filename)
390
+{
391
+#if     HAVE_READLINK
392
+size_t	bufsiz;
393
+char	*buf;
394
+
395
+	bufsiz=0;
396
+	buf=0;
397
+
398
+	for (;;)
399
+	{
400
+	int	n;
401
+
402
+		if (buf)	free(buf);
403
+		bufsiz += 256;
404
+		if ((buf=malloc(bufsiz)) == 0)
405
+		{
406
+			perror("malloc");
407
+			return (0);
408
+		}
409
+		if ((n=readlink(filename, buf, bufsiz)) < 0)
410
+		{
411
+			free(buf);
412
+			return (0);
413
+		}
414
+		if (n < bufsiz)
415
+		{
416
+			buf[n]=0;
417
+			break;
418
+		}
419
+	}
420
+	return (buf);
421
+#else
422
+	return (0);
423
+#endif
424
+}
425
+
426
+int maildir_semisafeopen(const char *path, int mode, int perm)
427
+{
428
+
429
+#if	HAVE_READLINK
430
+
431
+char	*l=maildir_getlink(path);
432
+
433
+	if (l)
434
+	{
435
+	int	f;
436
+
437
+		if (*l != '/')
438
+		{
439
+		char	*q=malloc(strlen(path)+strlen(l)+2);
440
+		char	*s;
441
+
442
+			if (!q)
443
+			{
444
+				free(l);
445
+				return (-1);
446
+			}
447
+
448
+			strcpy(q, path);
449
+			if ((s=strchr(q, '/')) != 0)
450
+				s[1]=0;
451
+			else	*q=0;
452
+			strcat(q, l);
453
+			free(l);
454
+			l=q;
455
+		}
456
+
457
+		f=maildir_safeopen(l, mode, perm);
458
+
459
+		free(l);
460
+		return (f);
461
+	}
462
+#endif
463
+
464
+	return (maildir_safeopen(path, mode, perm));
465
+}
466
+		
467
+int maildir_safeopen(const char *path, int mode, int perm)
468
+{
469
+struct	stat	stat1, stat2;
470
+
471
+int	fd=open(path, mode
472
+#ifdef	O_NONBLOCK
473
+			| O_NONBLOCK
474
+#else
475
+			| O_NDELAY
476
+#endif
477
+				, perm);
478
+
479
+	if (fd < 0)	return (fd);
480
+	if (fcntl(fd, F_SETFL, (mode & O_APPEND)) || fstat(fd, &stat1)
481
+	    || lstat(path, &stat2))
482
+	{
483
+		close(fd);
484
+		return (-1);
485
+	}
486
+
487
+	if (stat1.st_dev != stat2.st_dev || stat1.st_ino != stat2.st_ino)
488
+	{
489
+		close(fd);
490
+		errno=ENOENT;
491
+		return (-1);
492
+	}
493
+
494
+	return (fd);
495
+}
496
diff -ruN maildirparsequota.c maildirparsequota.c
497
--- maildirparsequota.c	Thu Jan  1 01:00:00 1970
498
+++ maildirparsequota.c	Wed Aug  6 17:09:48 2003
499
@@ -0,0 +1,44 @@
500
+/*
501
+** Copyright 1998 - 1999 Double Precision, Inc.
502
+** See COPYING for distribution information.
503
+*/
504
+
505
+#if HAVE_CONFIG_H
506
+#include "config.h"
507
+#endif
508
+#include	"maildirquota.h"
509
+#include	<stdlib.h>
510
+#include	<string.h>
511
+
512
+static const char rcsid[]="$Id: maildirparsequota.c,v 1.2 1999/12/06 13:21:05 mrsam Exp $";
513
+
514
+int maildir_parsequota(const char *n, unsigned long *s)
515
+{
516
+const char *o;
517
+int	yes;
518
+
519
+	if ((o=strrchr(n, '/')) == 0)	o=n;
520
+
521
+	for (; *o; o++)
522
+		if (*o == ':')	break;
523
+	yes=0;
524
+	for ( ; o >= n; --o)
525
+	{
526
+		if (*o == '/')	break;
527
+
528
+		if (*o == ',' && o[1] == 'S' && o[2] == '=')
529
+		{
530
+			yes=1;
531
+			o += 3;
532
+			break;
533
+		}
534
+	}
535
+	if (yes)
536
+	{
537
+		*s=0;
538
+		while (*o >= '0' && *o <= '9')
539
+			*s= *s*10 + (*o++ - '0');
540
+		return (0);
541
+	}
542
+	return (-1);
543
+}
544
diff -ruN maildirquota.c maildirquota.c
545
--- maildirquota.c	Thu Jan  1 01:00:00 1970
546
+++ maildirquota.c	Wed Aug  6 17:09:48 2003
547
@@ -0,0 +1,685 @@
548
+/*
549
+** Copyright 1998 - 2002 Double Precision, Inc.
550
+** See COPYING for distribution information.
551
+*/
552
+
553
+#if HAVE_CONFIG_H
554
+#include "config.h"
555
+#endif
556
+
557
+#include <sys/types.h>
558
+/* #if HAVE_DIRENT_H */
559
+#include <dirent.h>
560
+#define NAMLEN(dirent) strlen((dirent)->d_name)
561
+/* #else
562
+#define dirent direct
563
+#define NAMLEN(dirent) (dirent)->d_namlen
564
+#if HAVE_SYS_NDIR_H
565
+#include <sys/ndir.h>
566
+#endif
567
+#if HAVE_SYS_DIR_H
568
+#include <sys/dir.h>
569
+#endif
570
+#if HAVE_NDIR_H
571
+#include <ndir.h>
572
+#endif
573
+#endif */
574
+#include	<sys/types.h>
575
+/* #if	HAVE_SYS_STAT_H */
576
+#include	<sys/stat.h>
577
+/* #endif */
578
+#include	<sys/uio.h>
579
+
580
+#include	"maildirquota.h"
581
+#include	"maildirmisc.h"
582
+#include	<stdio.h>
583
+#include	<stdlib.h>
584
+#include	<string.h>
585
+#include	<errno.h>
586
+/* #if	HAVE_FCNTL_H */
587
+#include	<fcntl.h>
588
+/* #endif */
589
+#if	HAVE_UNISTD_H
590
+#include	<unistd.h>
591
+#endif
592
+#include	<time.h>
593
+#include	"numlib.h"
594
+
595
+static const char rcsid[]="$Id: maildirquota.c,v 1.9 2002/05/01 04:05:33 mrsam Exp $";
596
+
597
+/* Read the maildirsize file */
598
+
599
+int maildirsize_read(const char *filename,	/* The filename */
600
+	int *fdptr,	/* Keep the file descriptor open */
601
+	off_t *sizeptr,	/* Grand total of maildir size */
602
+	unsigned *cntptr, /* Grand total of message count */
603
+	unsigned *nlines, /* # of lines in maildirsize */
604
+	struct stat *statptr)	/* The stats on maildirsize */
605
+{
606
+char buf[5120];
607
+int f;
608
+char *p;
609
+unsigned l;
610
+int n;
611
+int first;
612
+
613
+	if ((f=maildir_safeopen(filename, O_RDWR|O_APPEND, 0)) < 0)
614
+		return (-1);
615
+	p=buf;
616
+	l=sizeof(buf);
617
+
618
+	while (l)
619
+	{
620
+		n=read(f, p, l);
621
+		if (n < 0)
622
+		{
623
+			close(f);
624
+			return (-1);
625
+		}
626
+		if (n == 0)	break;
627
+		p += n;
628
+		l -= n;
629
+	}
630
+	if (l == 0 || fstat(f, statptr))	/* maildir too big */
631
+	{
632
+		close(f);
633
+		return (-1);
634
+	}
635
+
636
+	*sizeptr=0;
637
+	*cntptr=0;
638
+	*nlines=0;
639
+	*p=0;
640
+	p=buf;
641
+	first=1;
642
+	while (*p)
643
+	{
644
+	long n=0;
645
+	int c=0;
646
+	char	*q=p;
647
+
648
+		while (*p)
649
+			if (*p++ == '\n')
650
+			{
651
+				p[-1]=0;
652
+				break;
653
+			}
654
+
655
+		if (first)
656
+		{
657
+			first=0;
658
+			continue;
659
+		}
660
+		sscanf(q, "%ld %d", &n, &c);
661
+		*sizeptr += n;
662
+		*cntptr += c;
663
+		++ *nlines;
664
+	}
665
+	*fdptr=f;
666
+	return (0);
667
+}
668
+
669
+static char *makenewmaildirsizename(const char *, int *);
670
+static int countcurnew(const char *, time_t *, off_t *, unsigned *);
671
+static int countsubdir(const char *, const char *,
672
+		time_t *, off_t *, unsigned *);
673
+static int statcurnew(const char *, time_t *);
674
+static int statsubdir(const char *, const char *, time_t *);
675
+
676
+#define	MDQUOTA_SIZE	'S'	/* Total size of all messages in maildir */
677
+#define	MDQUOTA_BLOCKS	'B'	/* Total # of blocks for all messages in
678
+				maildir -- NOT IMPLEMENTED */
679
+#define	MDQUOTA_COUNT	'C'	/* Total number of messages in maildir */
680
+
681
+static int qcalc(off_t s, unsigned n, const char *quota, int *percentage)
682
+{
683
+off_t i;
684
+int	spercentage=0;
685
+int	npercentage=0;
686
+
687
+	errno=ENOSPC;
688
+	while (quota && *quota)
689
+	{
690
+		int x=1;
691
+
692
+		if (*quota < '0' || *quota > '9')
693
+		{
694
+			++quota;
695
+			continue;
696
+		}
697
+		i=0;
698
+		while (*quota >= '0' && *quota <= '9')
699
+			i=i*10 + (*quota++ - '0');
700
+		switch (*quota)	{
701
+		default:
702
+			if (i < s)
703
+			{
704
+				*percentage=100;
705
+				return (-1);
706
+			}
707
+
708
+			/*
709
+			** For huge quotas, over 20mb,
710
+			** divide numerator & denominator by 1024 to prevent
711
+			** an overflow when multiplying by 100
712
+			*/
713
+
714
+			x=1;
715
+			if (i > 20000000) x=1024;
716
+
717
+			spercentage = i ? (s/x) * 100 / (i/x):100;
718
+			break;
719
+		case 'C':
720
+
721
+			if (i < n)
722
+			{
723
+				*percentage=100;
724
+				return (-1);
725
+			}
726
+
727
+			/* Ditto */
728
+
729
+			x=1;
730
+			if (i > 20000000) x=1024;
731
+
732
+			npercentage = i ? ((off_t)n/x) * 100 / (i/x):100;
733
+			break;
734
+		}
735
+	}
736
+	*percentage = spercentage > npercentage ? spercentage:npercentage;
737
+	return (0);
738
+}
739
+
740
+static int	doaddquota(const char *, int, const char *, long, int, int);
741
+
742
+static int docheckquota(const char *dir,
743
+	int *maildirsize_fdptr,
744
+	const char *quota_type,
745
+	long xtra_size,
746
+	int xtra_cnt, int *percentage);
747
+
748
+
749
+int maildir_checkquota(const char *dir,
750
+	int *maildirsize_fdptr,
751
+	const char *quota_type,
752
+	long xtra_size,
753
+	int xtra_cnt)
754
+{
755
+int	dummy;
756
+
757
+	return (docheckquota(dir, maildirsize_fdptr, quota_type,
758
+		xtra_size, xtra_cnt, &dummy));
759
+}
760
+
761
+int maildir_readquota(const char *dir, const char *quota_type)
762
+{
763
+int	percentage=0;
764
+int	fd=-1;
765
+
766
+	(void)docheckquota(dir, &fd, quota_type, 0, 0, &percentage);
767
+	if (fd >= 0)
768
+		close(fd);
769
+	return (percentage);
770
+}
771
+
772
+static int docheckquota(const char *dir,
773
+	int *maildirsize_fdptr,
774
+	const char *quota_type,
775
+	long xtra_size,
776
+	int xtra_cnt,
777
+	int *percentage)
778
+{
779
+char	*checkfolder=(char *)malloc(strlen(dir)+sizeof("/maildirfolder"));
780
+char	*newmaildirsizename;
781
+struct stat stat_buf;
782
+int	maildirsize_fd;
783
+off_t	maildirsize_size;
784
+unsigned maildirsize_cnt;
785
+unsigned maildirsize_nlines;
786
+int	n;
787
+time_t	tm;
788
+time_t	maxtime;
789
+DIR	*dirp;
790
+struct dirent *de;
791
+
792
+	if (checkfolder == 0)	return (-1);
793
+	*maildirsize_fdptr= -1;
794
+	strcat(strcpy(checkfolder, dir), "/maildirfolder");
795
+	if (stat(checkfolder, &stat_buf) == 0)	/* Go to parent */
796
+	{
797
+		strcat(strcpy(checkfolder, dir), "/..");
798
+		n=docheckquota(checkfolder, maildirsize_fdptr,
799
+			quota_type, xtra_size, xtra_cnt, percentage);
800
+		free(checkfolder);
801
+		return (n);
802
+	}
803
+	if (!quota_type || !*quota_type)	return (0);
804
+
805
+	strcat(strcpy(checkfolder, dir), "/maildirsize");
806
+	time(&tm);
807
+	if (maildirsize_read(checkfolder, &maildirsize_fd,
808
+		&maildirsize_size, &maildirsize_cnt,
809
+		&maildirsize_nlines, &stat_buf) == 0)
810
+	{
811
+		n=qcalc(maildirsize_size+xtra_size, maildirsize_cnt+xtra_cnt,
812
+			quota_type, percentage);
813
+
814
+		if (n == 0)
815
+		{
816
+			free(checkfolder);
817
+			*maildirsize_fdptr=maildirsize_fd;
818
+			return (0);
819
+		}
820
+		close(maildirsize_fd);
821
+
822
+		if (maildirsize_nlines == 1 && tm < stat_buf.st_mtime + 15*60)
823
+			return (n);
824
+	}
825
+
826
+	maxtime=0;
827
+	maildirsize_size=0;
828
+	maildirsize_cnt=0;
829
+
830
+	if (countcurnew(dir, &maxtime, &maildirsize_size, &maildirsize_cnt))
831
+	{
832
+		free(checkfolder);
833
+		return (-1);
834
+	}
835
+
836
+	dirp=opendir(dir);
837
+	while (dirp && (de=readdir(dirp)) != 0)
838
+	{
839
+		if (countsubdir(dir, de->d_name, &maxtime, &maildirsize_size,
840
+			&maildirsize_cnt))
841
+		{
842
+			free(checkfolder);
843
+			closedir(dirp);
844
+			return (-1);
845
+		}
846
+	}
847
+	if (dirp)
848
+	{
849
+#if	CLOSEDIR_VOID
850
+		closedir(dirp);
851
+#else
852
+		if (closedir(dirp))
853
+		{
854
+			free(checkfolder);
855
+			return (-1);
856
+		}
857
+#endif
858
+	}
859
+
860
+	newmaildirsizename=makenewmaildirsizename(dir, &maildirsize_fd);
861
+	if (!newmaildirsizename)
862
+	{
863
+		free(checkfolder);
864
+		return (-1);
865
+	}
866
+
867
+	*maildirsize_fdptr=maildirsize_fd;
868
+
869
+	if (doaddquota(dir, maildirsize_fd, quota_type, maildirsize_size,
870
+		maildirsize_cnt, 1))
871
+	{
872
+		free(newmaildirsizename);
873
+		unlink(newmaildirsizename);
874
+		close(maildirsize_fd);
875
+		*maildirsize_fdptr= -1;
876
+		free(checkfolder);
877
+		return (-1);
878
+	}
879
+
880
+	strcat(strcpy(checkfolder, dir), "/maildirsize");
881
+
882
+	if (rename(newmaildirsizename, checkfolder))
883
+	{
884
+		free(checkfolder);
885
+		unlink(newmaildirsizename);
886
+		close(maildirsize_fd);
887
+		*maildirsize_fdptr= -1;
888
+	}
889
+	free(checkfolder);
890
+	free(newmaildirsizename);
891
+
892
+	tm=0;
893
+
894
+	if (statcurnew(dir, &tm))
895
+	{
896
+		close(maildirsize_fd);
897
+		*maildirsize_fdptr= -1;
898
+		return (-1);
899
+	}
900
+
901
+	dirp=opendir(dir);
902
+	while (dirp && (de=readdir(dirp)) != 0)
903
+	{
904
+		if (statsubdir(dir, de->d_name, &tm))
905
+		{
906
+			close(maildirsize_fd);
907
+			*maildirsize_fdptr= -1;
908
+			closedir(dirp);
909
+			return (-1);
910
+		}
911
+	}
912
+	if (dirp)
913
+	{
914
+#if	CLOSEDIR_VOID
915
+		closedir(dirp);
916
+#else
917
+		if (closedir(dirp))
918
+		{
919
+			close(maildirsize_fd);
920
+			*maildirsize_fdptr= -1;
921
+			return (-1);
922
+		}
923
+#endif
924
+	}
925
+
926
+	if (tm != maxtime)	/* Race condition, someone changed something */
927
+	{
928
+		errno=EAGAIN;
929
+		return (-1);
930
+	}
931
+
932
+	return (qcalc(maildirsize_size+xtra_size, maildirsize_cnt+xtra_cnt,
933
+		quota_type, percentage));
934
+}
935
+
936
+int	maildir_addquota(const char *dir, int maildirsize_fd,
937
+	const char *quota_type, long maildirsize_size, int maildirsize_cnt)
938
+{
939
+	if (!quota_type || !*quota_type)	return (0);
940
+	return (doaddquota(dir, maildirsize_fd, quota_type, maildirsize_size,
941
+			maildirsize_cnt, 0));
942
+}
943
+
944
+static int doaddquota(const char *dir, int maildirsize_fd,
945
+	const char *quota_type, long maildirsize_size, int maildirsize_cnt,
946
+	int isnew)
947
+{
948
+union	{
949
+	char	buf[100];
950
+	struct stat stat_buf;
951
+	} u;				/* Scrooge */
952
+char	*newname2=0;
953
+char	*newmaildirsizename=0;
954
+struct	iovec	iov[3];
955
+int	niov;
956
+struct	iovec	*p;
957
+int	n;
958
+
959
+	niov=0;
960
+	if ( maildirsize_fd < 0)
961
+	{
962
+		newname2=(char *)malloc(strlen(dir)+sizeof("/maildirfolder"));
963
+		if (!newname2)	return (-1);
964
+		strcat(strcpy(newname2, dir), "/maildirfolder");
965
+		if (stat(newname2, &u.stat_buf) == 0)
966
+		{
967
+			strcat(strcpy(newname2, dir), "/..");
968
+			n=doaddquota(newname2, maildirsize_fd, quota_type,
969
+					maildirsize_size, maildirsize_cnt,
970
+					isnew);
971
+			free(newname2);
972
+			return (n);
973
+		}
974
+
975
+		strcat(strcpy(newname2, dir), "/maildirsize");
976
+
977
+		if ((maildirsize_fd=maildir_safeopen(newname2,
978
+			O_RDWR|O_APPEND, 0644)) < 0)
979
+		{
980
+			newmaildirsizename=makenewmaildirsizename(dir, &maildirsize_fd);
981
+			if (!newmaildirsizename)
982
+			{
983
+				free(newname2);
984
+				return (-1);
985
+			}
986
+
987
+			maildirsize_fd=maildir_safeopen(newmaildirsizename,
988
+				O_CREAT|O_RDWR|O_APPEND, 0644);
989
+
990
+			if (maildirsize_fd < 0)
991
+			{
992
+				free(newname2);
993
+				return (-1);
994
+			}
995
+			isnew=1;
996
+		}
997
+	}
998
+
999
+	if (isnew)
1000
+	{
1001
+		iov[0].iov_base=(caddr_t)quota_type;
1002
+		iov[0].iov_len=strlen(quota_type);
1003
+		iov[1].iov_base=(caddr_t)"\n";
1004
+		iov[1].iov_len=1;
1005
+		niov=2;
1006
+	}
1007
+
1008
+
1009
+	sprintf(u.buf, "%ld %d\n", maildirsize_size, maildirsize_cnt);
1010
+	iov[niov].iov_base=(caddr_t)u.buf;
1011
+	iov[niov].iov_len=strlen(u.buf);
1012
+
1013
+	p=iov;
1014
+	++niov;
1015
+	n=0;
1016
+	while (niov)
1017
+	{
1018
+		if (n)
1019
+		{
1020
+			if (n < p->iov_len)
1021
+			{
1022
+				p->iov_base=
1023
+					(caddr_t)((char *)p->iov_base + n);
1024
+				p->iov_len -= n;
1025
+			}
1026
+			else
1027
+			{
1028
+				n -= p->iov_len;
1029
+				++p;
1030
+				--niov;
1031
+				continue;
1032
+			}
1033
+		}
1034
+
1035
+		n=writev( maildirsize_fd, p, niov);
1036
+
1037
+		if (n <= 0)
1038
+		{
1039
+			if (newname2)
1040
+			{
1041
+				close(maildirsize_fd);
1042
+				free(newname2);
1043
+			}
1044
+			return (-1);
1045
+		}
1046
+	}
1047
+	if (newname2)
1048
+	{
1049
+		close(maildirsize_fd);
1050
+
1051
+		if (newmaildirsizename)
1052
+		{
1053
+			rename(newmaildirsizename, newname2);
1054
+			free(newmaildirsizename);
1055
+		}
1056
+		free(newname2);
1057
+	}
1058
+	return (0);
1059
+}
1060
+
1061
+/* New maildirsize is built in the tmp subdirectory */
1062
+
1063
+static char *makenewmaildirsizename(const char *dir, int *fd)
1064
+{
1065
+char	hostname[256];
1066
+struct	stat stat_buf;
1067
+time_t	t;
1068
+char	*p;
1069
+
1070
+	hostname[0]=0;
1071
+	hostname[sizeof(hostname)-1]=0;
1072
+	gethostname(hostname, sizeof(hostname)-1);
1073
+	p=(char *)malloc(strlen(dir)+strlen(hostname)+130);
1074
+	if (!p)	return (0);
1075
+
1076
+	for (;;)
1077
+	{
1078
+	char	tbuf[NUMBUFSIZE];
1079
+	char	pbuf[NUMBUFSIZE];
1080
+
1081
+		time(&t);
1082
+		strcat(strcpy(p, dir), "/tmp/");
1083
+		sprintf(p+strlen(p), "%s.%s_NeWmAiLdIrSiZe.%s",
1084
+			str_time_t(t, tbuf),
1085
+			str_pid_t(getpid(), pbuf), hostname);
1086
+
1087
+		if (stat( (const char *)p, &stat_buf) < 0 &&
1088
+			(*fd=maildir_safeopen(p,
1089
+				O_CREAT|O_RDWR|O_APPEND, 0644)) >= 0)
1090
+			break;
1091
+		sleep(3);
1092
+	}
1093
+	return (p);
1094
+}
1095
+
1096
+static int statcurnew(const char *dir, time_t *maxtimestamp)
1097
+{
1098
+char	*p=(char *)malloc(strlen(dir)+5);
1099
+struct	stat	stat_buf;
1100
+
1101
+	if (!p)	return (-1);
1102
+	strcat(strcpy(p, dir), "/cur");
1103
+	if ( stat(p, &stat_buf) == 0 && stat_buf.st_mtime > *maxtimestamp)
1104
+		*maxtimestamp=stat_buf.st_mtime;
1105
+	strcat(strcpy(p, dir), "/new");
1106
+	if ( stat(p, &stat_buf) == 0 && stat_buf.st_mtime > *maxtimestamp)
1107
+		*maxtimestamp=stat_buf.st_mtime;
1108
+	free(p);
1109
+	return (0);
1110
+}
1111
+
1112
+static int statsubdir(const char *dir, const char *subdir, time_t *maxtime)
1113
+{
1114
+char	*p;
1115
+int	n;
1116
+
1117
+	if ( *subdir != '.' || strcmp(subdir, ".") == 0 ||
1118
+		strcmp(subdir, "..") == 0 || strcmp(subdir, "." TRASH) == 0)
1119
+		return (0);
1120
+
1121
+	p=(char *)malloc(strlen(dir)+strlen(subdir)+2);
1122
+	if (!p)	return (-1);
1123
+	strcat(strcat(strcpy(p, dir), "/"), subdir);
1124
+	n=statcurnew(p, maxtime);
1125
+	free(p);
1126
+	return (n);
1127
+}
1128
+
1129
+static int docount(const char *, time_t *, off_t *, unsigned *);
1130
+
1131
+static int countcurnew(const char *dir, time_t *maxtime,
1132
+	off_t *sizep, unsigned *cntp)
1133
+{
1134
+char	*p=(char *)malloc(strlen(dir)+5);
1135
+int	n;
1136
+
1137
+	if (!p)	return (-1);
1138
+	strcat(strcpy(p, dir), "/new");
1139
+	n=docount(p, maxtime, sizep, cntp);
1140
+	if (n == 0)
1141
+	{
1142
+		strcat(strcpy(p, dir), "/cur");
1143
+		n=docount(p, maxtime, sizep, cntp);
1144
+	}
1145
+	free(p);
1146
+	return (n);
1147
+}
1148
+
1149
+static int countsubdir(const char *dir, const char *subdir, time_t *maxtime,
1150
+	off_t *sizep, unsigned *cntp)
1151
+{
1152
+char	*p;
1153
+int	n;
1154
+
1155
+	if ( *subdir != '.' || strcmp(subdir, ".") == 0 ||
1156
+		strcmp(subdir, "..") == 0 || strcmp(subdir, "." TRASH) == 0)
1157
+		return (0);
1158
+
1159
+	p=(char *)malloc(strlen(dir)+strlen(subdir)+2);
1160
+	if (!p)	return (2);
1161
+	strcat(strcat(strcpy(p, dir), "/"), subdir);
1162
+	n=countcurnew(p, maxtime, sizep, cntp);
1163
+	free(p);
1164
+	return (n);
1165
+}
1166
+
1167
+static int docount(const char *dir, time_t *dirstamp,
1168
+	off_t *sizep, unsigned *cntp)
1169
+{
1170
+struct	stat	stat_buf;
1171
+char	*p;
1172
+DIR	*dirp;
1173
+struct dirent *de;
1174
+unsigned long	s;
1175
+
1176
+	if (stat(dir, &stat_buf))	return (0);	/* Ignore */
1177
+	if (stat_buf.st_mtime > *dirstamp)	*dirstamp=stat_buf.st_mtime;
1178
+	if ((dirp=opendir(dir)) == 0)	return (0);
1179
+	while ((de=readdir(dirp)) != 0)
1180
+	{
1181
+	const char *n=de->d_name;
1182
+
1183
+		if (*n == '.')	continue;
1184
+
1185
+		/* PATCH - do not count msgs marked as deleted */
1186
+
1187
+		for ( ; *n; n++)
1188
+		{
1189
+			if (n[0] != ':' || n[1] != '2' ||
1190
+				n[2] != ',')	continue;
1191
+			n += 3;
1192
+			while (*n >= 'A' && *n <= 'Z')
1193
+			{
1194
+				if (*n == 'T')	break;
1195
+				++n;
1196
+			}
1197
+			break;
1198
+		}
1199
+		if (*n == 'T')	continue;
1200
+		n=de->d_name;
1201
+
1202
+
1203
+		if (maildir_parsequota(n, &s) == 0)
1204
+			stat_buf.st_size=s;
1205
+		else
1206
+		{
1207
+			p=(char *)malloc(strlen(dir)+strlen(n)+2);
1208
+			if (!p)
1209
+			{
1210
+				closedir(dirp);
1211
+				return (-1);
1212
+			}
1213
+			strcat(strcat(strcpy(p, dir), "/"), n);
1214
+			if (stat(p, &stat_buf))
1215
+			{
1216
+				free(p);
1217
+				continue;
1218
+			}
1219
+			free(p);
1220
+		}
1221
+		*sizep += stat_buf.st_size;
1222
+		++*cntp;
1223
+	}
1224
+
1225
+#if	CLOSEDIR_VOID
1226
+	closedir(dirp);
1227
+#else
1228
+	if (closedir(dirp))
1229
+		return (-1);
1230
+#endif
1231
+	return (0);
1232
+}
1233
diff -ruN maildirquota.h maildirquota.h
1234
--- maildirquota.h	Thu Jan  1 01:00:00 1970
1235
+++ maildirquota.h	Wed Aug  6 17:09:48 2003
1236
@@ -0,0 +1,45 @@
1237
+#ifndef	maildirquota_h
1238
+#define	maildirquota_h
1239
+
1240
+/*
1241
+** Copyright 1998 - 1999 Double Precision, Inc.
1242
+** See COPYING for distribution information.
1243
+*/
1244
+
1245
+#if	HAVE_CONFIG_H
1246
+#include	"config.h"
1247
+#endif
1248
+
1249
+#include	<sys/types.h>
1250
+#include	<stdio.h>
1251
+
1252
+#ifdef  __cplusplus
1253
+extern "C" {
1254
+#endif
1255
+
1256
+static const char maildirquota_h_rcsid[]="$Id: maildirquota.h,v 1.2 2000/09/04 17:10:28 mrsam Exp $";
1257
+
1258
+int maildir_checkquota(const char *,	/* Pointer to directory */
1259
+	int *,	/* Initialized to -1, or opened descriptor for maildirsize */
1260
+	const char *,	/* The quota */
1261
+	long,		/* Extra bytes planning to add/remove from maildir */
1262
+	int);		/* Extra messages planning to add/remove from maildir */
1263
+
1264
+int maildir_addquota(const char *,	/* Pointer to the maildir */
1265
+	int,	/* Must be the int pointed to by 2nd arg to checkquota */
1266
+	const char *,	/* The quota */
1267
+	long,	/* +/- bytes */
1268
+	int);	/* +/- files */
1269
+
1270
+int maildir_readquota(const char *,	/* Directory */
1271
+	const char *);			/* Quota, from getquota */
1272
+
1273
+int maildir_parsequota(const char *, unsigned long *);
1274
+	/* Attempt to parse file size encoded in filename.  Returns 0 if
1275
+	** parsed, non-zero if we didn't parse. */
1276
+
1277
+#ifdef  __cplusplus
1278
+}
1279
+#endif
1280
+
1281
+#endif
1282
diff -ruN numlib.h numlib.h
1283
--- numlib.h	Thu Jan  1 01:00:00 1970
1284
+++ numlib.h	Wed Aug  6 17:09:48 2003
1285
@@ -0,0 +1,45 @@
1286
+#ifndef	numlib_h
1287
+#define	numlib_h
1288
+
1289
+/*
1290
+** Copyright 1998 - 1999 Double Precision, Inc.
1291
+** See COPYING for distribution information.
1292
+*/
1293
+
1294
+#ifdef	__cplusplus
1295
+extern "C" {
1296
+#endif
1297
+
1298
+static const char numlib_h_rcsid[]="$Id: numlib.h,v 1.3 2001/08/12 15:46:40 mrsam Exp $";
1299
+
1300
+#if	HAVE_CONFIG_H
1301
+#include	"config.h"
1302
+#endif
1303
+
1304
+#include	<sys/types.h>
1305
+#include	<time.h>
1306
+
1307
+#define	NUMBUFSIZE	60
1308
+
1309
+/* Convert various system types to decimal */
1310
+
1311
+char	*str_time_t(time_t, char *);
1312
+char	*str_off_t(off_t, char *);
1313
+char	*str_pid_t(pid_t, char *);
1314
+char	*str_ino_t(ino_t, char *);
1315
+char	*str_uid_t(uid_t, char *);
1316
+char	*str_gid_t(gid_t, char *);
1317
+char	*str_size_t(size_t, char *);
1318
+
1319
+char	*str_sizekb(unsigned long, char *);	/* X Kb or X Mb */
1320
+
1321
+/* Convert selected system types to hex */
1322
+
1323
+char	*strh_time_t(time_t, char *);
1324
+char	*strh_pid_t(pid_t, char *);
1325
+char	*strh_ino_t(ino_t, char *);
1326
+
1327
+#ifdef	__cplusplus
1328
+}
1329
+#endif
1330
+#endif
1331
diff -ruN overmaildirquota.c overmaildirquota.c
1332
--- overmaildirquota.c	Thu Jan  1 01:00:00 1970
1333
+++ overmaildirquota.c	Wed Aug  6 17:10:33 2003
1334
@@ -0,0 +1,42 @@
1335
+/*
1336
+** Copyright 1998 - 1999 Double Precision, Inc.
1337
+** See COPYING for distribution information.
1338
+*/
1339
+
1340
+#if HAVE_CONFIG_H
1341
+#include "config.h"
1342
+#endif
1343
+#include        "maildirquota.h"
1344
+#include        <stdlib.h>
1345
+#include        <string.h>
1346
+#include        <errno.h>
1347
+#include        <sys/stat.h>
1348
+
1349
+static const char rcsid[]="$Id: overquota.c,v 1.0 2002/06/09 16:21:05 mrsam Exp $";
1350
+
1351
+
1352
+int user_over_maildirquota( const char *dir, const char *q)
1353
+{
1354
+struct  stat    stat_buf;
1355
+int     quotafd;
1356
+int     ret_value;
1357
+
1358
+        if (fstat(0, &stat_buf) == 0 && S_ISREG(stat_buf.st_mode) &&
1359
+                stat_buf.st_size > 0 && *q)
1360
+        {
1361
+                if (maildir_checkquota(dir, &quotafd, q, stat_buf.st_size, 1)
1362
+                        && errno != EAGAIN)
1363
+                {
1364
+                        if (quotafd >= 0)       close(quotafd);
1365
+                        ret_value = 1;
1366
+                } else {
1367
+                        maildir_addquota(dir, quotafd, q, stat_buf.st_size, 1);
1368
+                        if (quotafd >= 0)       close(quotafd);
1369
+                        ret_value = 0;
1370
+                }
1371
+        } else {
1372
+                ret_value = 0;
1373
+        }
1374
+
1375
+        return(ret_value);
1376
+}
1377
diff -ruN qmail-local.c qmail-local.c
1378
--- qmail-local.c	Wed Aug  6 17:05:13 2003
1379
+++ qmail-local.c	Wed Aug  6 17:09:48 2003
1380
@@ -66,6 +66,7 @@
1381
 
1382
 char buf[1024];
1383
 char outbuf[1024];
1384
+#define QUOTABUFSIZE    256
1385
 
1386
 /* child process */
1387
 
1388
@@ -86,9 +87,15 @@
1389
  int fd;
1390
  substdio ss;
1391
  substdio ssout;
1392
+ char quotabuf[QUOTABUFSIZE];
1393
 
1394
  sig_alarmcatch(sigalrm);
1395
  if (chdir(dir) == -1) { if (error_temp(errno)) _exit(1); _exit(2); }
1396
+ if (maildir_getquota(dir, quotabuf) == 0) {
1397
+  if (user_over_maildirquota(dir,quotabuf)==1) {
1398
+   _exit(1);
1399
+  }
1400
+ }
1401
  pid = getpid();
1402
  host[0] = 0;
1403
  gethostname(host,sizeof(host));
1404
@@ -99,7 +106,10 @@
1405
    s += fmt_str(s,"tmp/");
1406
    s += fmt_ulong(s,time); *s++ = '.';
1407
    s += fmt_ulong(s,pid); *s++ = '.';
1408
-   s += fmt_strn(s,host,sizeof(host)); *s++ = 0;
1409
+   s += fmt_strn(s,host,sizeof(host));
1410
+   s += fmt_strn(s,",S=",sizeof(",S="));
1411
+   if (fstat(0,&st) == -1) if (errno == error_noent) break;
1412
+   s += fmt_ulong(s,st.st_size+rpline.len+dtline.len); *s++ = 0;
1413
    if (stat(fntmptph,&st) == -1) if (errno == error_noent) break;
1414
    /* really should never get to this point */
1415
    if (loop == 2) _exit(1);
1416
@@ -159,6 +169,7 @@
1417
  switch(wait_exitcode(wstat))
1418
   {
1419
    case 0: break;
1420
+   case 1: strerr_die1x(1, "User over quota. (#5.1.1)");
1421
    case 2: strerr_die1x(111,"Unable to chdir to maildir. (#4.2.1)");
1422
    case 3: strerr_die1x(111,"Timeout on maildir delivery. (#4.3.0)");
1423
    case 4: strerr_die1x(111,"Unable to read message. (#4.3.0)");
1424
diff -ruN qmail-pop3d.c qmail-pop3d.c
1425
--- qmail-pop3d.c	Wed Aug  6 17:05:13 2003
1426
+++ qmail-pop3d.c	Wed Aug  6 17:09:48 2003
1427
@@ -16,6 +16,11 @@
1428
 #include "readwrite.h"
1429
 #include "timeoutread.h"
1430
 #include "timeoutwrite.h"
1431
+#include <errno.h>
1432
+#include "maildirquota.h"
1433
+#include "maildirmisc.h"
1434
+
1435
+#define QUOTABUFSIZE 256
1436
 
1437
 void die() { _exit(0); }
1438
 
1439
@@ -45,19 +50,15 @@
1440
 {
1441
   substdio_put(&ssout,buf,len);
1442
 }
1443
-void puts(s) char *s;
1444
-{
1445
-  substdio_puts(&ssout,s);
1446
-}
1447
 void flush()
1448
 {
1449
   substdio_flush(&ssout);
1450
 }
1451
 void err(s) char *s;
1452
 {
1453
-  puts("-ERR ");
1454
-  puts(s);
1455
-  puts("\r\n");
1456
+  substdio_puts(&ssout,"-ERR ");
1457
+  substdio_puts(&ssout,s);
1458
+  substdio_puts(&ssout,"\r\n");
1459
   flush();
1460
 }
1461
 
1462
@@ -73,7 +74,7 @@
1463
 void err_nosuch() { err("unable to open that message"); }
1464
 void err_nounlink() { err("unable to unlink all deleted messages"); }
1465
 
1466
-void okay() { puts("+OK \r\n"); flush(); }
1467
+void okay() { substdio_puts(&ssout,"+OK \r\n"); flush(); }
1468
 
1469
 void printfn(fn) char *fn;
1470
 {
1471
@@ -153,11 +154,11 @@
1472
  
1473
   total = 0;
1474
   for (i = 0;i < numm;++i) if (!m[i].flagdeleted) total += m[i].size;
1475
-  puts("+OK ");
1476
+  substdio_puts(&ssout,"+OK ");
1477
   put(strnum,fmt_uint(strnum,numm));
1478
-  puts(" ");
1479
+  substdio_puts(&ssout," ");
1480
   put(strnum,fmt_ulong(strnum,total));
1481
-  puts("\r\n");
1482
+  substdio_puts(&ssout,"\r\n");
1483
   flush();
1484
 }
1485
 
1486
@@ -171,18 +172,41 @@
1487
 
1488
 void pop3_last()
1489
 {
1490
-  puts("+OK ");
1491
+  substdio_puts(&ssout,"+OK ");
1492
   put(strnum,fmt_uint(strnum,last));
1493
-  puts("\r\n");
1494
+  substdio_puts(&ssout,"\r\n");
1495
   flush();
1496
 }
1497
 
1498
 void pop3_quit()
1499
 {
1500
   int i;
1501
+  char quotabuf[QUOTABUFSIZE];
1502
+  int has_quota=maildir_getquota(".", quotabuf);
1503
+
1504
+  long deleted_bytes=0;
1505
+  long deleted_messages=0;
1506
+
1507
   for (i = 0;i < numm;++i)
1508
     if (m[i].flagdeleted) {
1509
-      if (unlink(m[i].fn) == -1) err_nounlink();
1510
+      unsigned long un=0;
1511
+      const char *filename=m[i].fn;
1512
+      if (has_quota == 0 && !MAILDIR_DELETED(filename)) {
1513
+          if (maildir_parsequota(filename, &un)) {
1514
+              struct stat stat_buf;
1515
+
1516
+              if (stat(filename, &stat_buf) == 0)
1517
+                  un=stat_buf.st_size;
1518
+          }
1519
+      }
1520
+      if (unlink(m[i].fn) == -1) {
1521
+          err_nounlink();
1522
+          un=0;
1523
+      }
1524
+      if (un) {
1525
+          deleted_bytes -= un;
1526
+          deleted_messages -= 1;
1527
+      }
1528
     }
1529
     else
1530
       if (str_start(m[i].fn,"new/")) {
1531
@@ -192,6 +216,21 @@
1532
 	if (!stralloc_0(&line)) die_nomem();
1533
 	rename(m[i].fn,line.s); /* if it fails, bummer */
1534
       }
1535
+
1536
+    if (deleted_messages < 0) {
1537
+        int quotafd;
1538
+
1539
+        if (maildir_checkquota(".", &quotafd, quotabuf, deleted_bytes,
1540
+                               deleted_messages) && errno != EAGAIN &&
1541
+                               deleted_bytes >= 0)
1542
+            {
1543
+                if (quotafd >= 0) close (quotafd);
1544
+            } else {
1545
+                 maildir_addquota(".", quotafd, quotabuf,
1546
+                                 deleted_bytes, deleted_messages);
1547
+                 if (quotafd >= 0) close(quotafd);
1548
+            }
1549
+        }
1550
   okay();
1551
   die();
1552
 }
1553
@@ -222,10 +261,10 @@
1554
 int flaguidl;
1555
 {
1556
   put(strnum,fmt_uint(strnum,i + 1));
1557
-  puts(" ");
1558
+  substdio_puts(&ssout," ");
1559
   if (flaguidl) printfn(m[i].fn);
1560
   else put(strnum,fmt_ulong(strnum,m[i].size));
1561
-  puts("\r\n");
1562
+  substdio_puts(&ssout,"\r\n");
1563
 }
1564
 
1565
 void dolisting(arg,flaguidl) char *arg; int flaguidl;
1566
@@ -234,7 +273,7 @@
1567
   if (*arg) {
1568
     i = msgno(arg);
1569
     if (i == -1) return;
1570
-    puts("+OK ");
1571
+    substdio_puts(&ssout,"+OK ");
1572
     list(i,flaguidl);
1573
   }
1574
   else {
1575
@@ -242,7 +281,7 @@
1576
     for (i = 0;i < numm;++i)
1577
       if (!m[i].flagdeleted)
1578
 	list(i,flaguidl);
1579
-    puts(".\r\n");
1580
+    substdio_puts(&ssout,".\r\n");
1581
   }
1582
   flush();
1583
 }
1584
diff -ruN strpidt.c strpidt.c
1585
--- strpidt.c	Thu Jan  1 01:00:00 1970
1586
+++ strpidt.c	Wed Aug  6 17:09:48 2003
1587
@@ -0,0 +1,26 @@
1588
+/*
1589
+** Copyright 1998 - 2000 Double Precision, Inc.
1590
+** See COPYING for distribution information.
1591
+*/
1592
+
1593
+#if	HAVE_CONFIG_H
1594
+#include	"config.h"
1595
+#endif
1596
+#include	"numlib.h"
1597
+#include	<string.h>
1598
+
1599
+static const char rcsid[]="$Id: strpidt.c,v 1.3 2000/05/27 04:59:26 mrsam Exp $";
1600
+
1601
+char *str_pid_t(pid_t t, char *arg)
1602
+{
1603
+char	buf[NUMBUFSIZE];
1604
+char	*p=buf+sizeof(buf)-1;
1605
+
1606
+	*p=0;
1607
+	do
1608
+	{
1609
+		*--p= '0' + (t % 10);
1610
+		t=t / 10;
1611
+	} while(t);
1612
+	return (strcpy(arg, p));
1613
+}
1614
diff -ruN strtimet.c strtimet.c
1615
--- strtimet.c	Thu Jan  1 01:00:00 1970
1616
+++ strtimet.c	Wed Aug  6 17:09:48 2003
1617
@@ -0,0 +1,26 @@
1618
+/*
1619
+** Copyright 1998 - 2000 Double Precision, Inc.
1620
+** See COPYING for distribution information.
1621
+*/
1622
+
1623
+#if	HAVE_CONFIG_H
1624
+#include	"config.h"
1625
+#endif
1626
+#include	"numlib.h"
1627
+#include	<string.h>
1628
+
1629
+static const char rcsid[]="$Id: strtimet.c,v 1.3 2000/05/27 04:59:26 mrsam Exp $";
1630
+
1631
+char *str_time_t(time_t t, char *arg)
1632
+{
1633
+char	buf[NUMBUFSIZE];
1634
+char	*p=buf+sizeof(buf)-1;
1635
+
1636
+	*p=0;
1637
+	do
1638
+	{
1639
+		*--p= '0' + (t % 10);
1640
+		t=t / 10;
1641
+	} while(t);
1642
+	return (strcpy(arg, p));
1643
+}

Return to bug 168870