diff -ruN --exclude=CVS ../qmail.orig/Makefile ./Makefile --- ../qmail.orig/Makefile 2012-06-09 00:08:18.000000000 +0200 +++ ./Makefile 2012-06-09 00:31:50.000000000 +0200 @@ -7,7 +7,7 @@ PORTNAME= qmail PORTVERSION?= ${QMAIL_VERSION} -PORTREVISION?= 7 +PORTREVISION?= 8 CATEGORIES= mail MASTER_SITES+= ${MASTER_SITE_QMAIL} DISTNAME= ${PORTNAME}-${QMAIL_VERSION} @@ -352,7 +352,7 @@ . endif . if defined(WITH_SRS) -BUILD_DEPENDS= srs:${PORTSDIR}/mail/libsrs2 +BUILD_DEPENDS= srs:${PORTSDIR}/mail/libsrs2 MASTER_SITES+= http://qmail-ldap-smtpauthuser.googlecode.com/svn/trunk/:srs_ldap SRS_LDAP_PATCH = qmail-ldap-1.03-20060201-SRS.patch DISTFILES+= ${SRS_LDAP_PATCH}:srs_ldap @@ -380,8 +380,7 @@ .endif .if defined(WITH_MAILDIRQUOTA_PATCH) && !defined(BARRIER_MAILDIRQUOTA_PATCH) -PATCH_SITES+= http://www.alexdupre.com/qmail/:quota -PATCHFILES+= qmail-maildir++.patch:quota +EXTRA_PATCHES+= ${FILESDIR}/extra-patch-qmail-maildir++ .endif .if defined(WITH_BLOCKEXEC_PATCH) && !defined(BARRIER_BLOCKEXEC_PATCH) diff -ruN --exclude=CVS ../qmail.orig/distinfo ./distinfo --- ../qmail.orig/distinfo 2012-06-09 00:08:18.000000000 +0200 +++ ./distinfo 2012-06-09 00:18:12.000000000 +0200 @@ -22,8 +22,6 @@ SIZE (qmail/outgoingip.patch-spamcontrol-25) = 6751 SHA256 (qmail/qmail-1.03-qmtpc_outgoingip_20090630.patch) = a5b521d3f35aa0842ea3fe69f6e51fa3be5e9c0acfad8671de36fa62a5cb9539 SIZE (qmail/qmail-1.03-qmtpc_outgoingip_20090630.patch) = 10364 -SHA256 (qmail/qmail-maildir++.patch) = 79e3f1f8f95b58b6d17e5469f125d873fe212d0a5a6d19b538ad57176fbafb52 -SIZE (qmail/qmail-maildir++.patch) = 38088 SHA256 (qmail/qmail-block-executables.patch) = 97512624eb02db51e10ab6d0dd834a8797a238d0e006bd1c6c94a183d291b456 SIZE (qmail/qmail-block-executables.patch) = 5070 SHA256 (qmail/qmail-discard-double-bounces.patch) = 14489eefd9908f60af13fadd574d0e9bb936e5d1b706690ce52efef68529a8d8 diff -ruN --exclude=CVS ../qmail.orig/files/extra-patch-qmail-maildir++ ./files/extra-patch-qmail-maildir++ --- ../qmail.orig/files/extra-patch-qmail-maildir++ 1970-01-01 01:00:00.000000000 +0100 +++ ./files/extra-patch-qmail-maildir++ 2012-06-09 00:27:18.000000000 +0200 @@ -0,0 +1,1643 @@ +diff -ruN Makefile Makefile +--- Makefile Wed Aug 6 17:05:13 2003 ++++ Makefile Wed Aug 6 17:09:48 2003 +@@ -890,6 +890,38 @@ + readwrite.h open.h headerbody.h maildir.h strerr.h + ./compile maildirwatch.c + ++maildirgetquota.o: \ ++compile maildirgetquota.c maildirgetquota.h maildirmisc.h ++ ./compile maildirgetquota.c ++ ++maildirflags.o: \ ++compile maildirflags.c ++ ./compile maildirflags.c ++ ++maildiropen.o: \ ++compile maildiropen.c maildirmisc.h ++ ./compile maildiropen.c ++ ++maildirparsequota.o: \ ++compile maildirparsequota.c ++ ./compile maildirparsequota.c ++ ++maildirquota.o: \ ++compile maildirquota.c maildirquota.h maildirmisc.h numlib.h ++ ./compile maildirquota.c ++ ++overmaildirquota.o: \ ++compile overmaildirquota.c ++ ./compile overmaildirquota.c ++ ++strtimet.o: \ ++compile strtimet.c ++ ./compile strtimet.c ++ ++strpidt.o: \ ++compile strpidt.c ++ ./compile strpidt.c ++ + mailsubj: \ + warn-auto.sh mailsubj.sh conf-qmail conf-break conf-split + cat warn-auto.sh mailsubj.sh \ +@@ -1174,12 +1206,15 @@ + load qmail-local.o qmail.o quote.o now.o gfrom.o myctime.o \ + slurpclose.o case.a getln.a getopt.a sig.a open.a seek.a lock.a fd.a \ + wait.a env.a stralloc.a alloc.a strerr.a substdio.a error.a str.a \ +-fs.a datetime.a auto_qmail.o auto_patrn.o socket.lib ++fs.a datetime.a auto_qmail.o auto_patrn.o socket.lib maildirquota.o \ ++maildirgetquota.o maildiropen.o maildirparsequota.o overmaildirquota.o \ ++strtimet.o strpidt.o + ./load qmail-local qmail.o quote.o now.o gfrom.o myctime.o \ + slurpclose.o case.a getln.a getopt.a sig.a open.a seek.a \ + lock.a fd.a wait.a env.a stralloc.a alloc.a strerr.a \ + substdio.a error.a str.a fs.a datetime.a auto_qmail.o \ +- auto_patrn.o `cat socket.lib` ++ auto_patrn.o `cat socket.lib` maildirquota.o maildirgetquota.o \ ++ maildiropen.o maildirparsequota.o overmaildirquota.o strtimet.o strpidt.o + + qmail-local.0: \ + qmail-local.8 +@@ -1269,11 +1304,13 @@ + qmail-pop3d: \ + load qmail-pop3d.o commands.o case.a timeoutread.o timeoutwrite.o \ + maildir.o prioq.o now.o env.a strerr.a sig.a open.a getln.a \ +-stralloc.a alloc.a substdio.a error.a str.a fs.a socket.lib ++stralloc.a alloc.a substdio.a error.a str.a fs.a socket.lib maildirquota.o \ ++maildirparsequota.o maildirflags.o maildiropen.o strtimet.o strpidt.o + ./load qmail-pop3d commands.o case.a timeoutread.o \ + timeoutwrite.o maildir.o prioq.o now.o env.a strerr.a sig.a \ + open.a getln.a stralloc.a alloc.a substdio.a error.a str.a \ +- fs.a `cat socket.lib` ++ fs.a `cat socket.lib` maildirquota.o maildirgetquota.o \ ++ maildirparsequota.o maildirflags.o maildiropen.o strtimet.o strpidt.o + + qmail-pop3d.0: \ + qmail-pop3d.8 +diff -ruN TARGETS TARGETS +--- TARGETS Wed Aug 6 17:05:13 2003 ++++ TARGETS Wed Aug 6 17:09:48 2003 +@@ -15,6 +15,14 @@ + slurpclose.o + make-makelib + makelib ++maildirflags.o ++maildirparsequota.o ++maildiropen.o ++maildirgetquota.o ++maildirquota.o ++overmaildirquota.o ++strtimet.o ++strpidt.o + case_diffb.o + case_diffs.o + case_lowerb.o +diff -ruN maildirflags.c maildirflags.c +--- maildirflags.c Thu Jan 1 01:00:00 1970 ++++ maildirflags.c Wed Aug 6 17:09:48 2003 +@@ -0,0 +1,23 @@ ++/* ++** Copyright 2000 Double Precision, Inc. ++** See COPYING for distribution information. ++*/ ++ ++#include ++#include ++ ++static const char rcsid[]="$Id: maildirflags.c,v 1.1 2000/10/07 01:10:19 mrsam Exp $"; ++ ++int maildir_hasflag(const char *filename, char flag) ++{ ++ const char *p=strrchr(filename, '/'); ++ ++ if (p) ++ filename=p+1; ++ ++ p=strrchr(p, ':'); ++ if (p && strncmp(p, ":2,", 3) == 0 && ++ strchr(p+3, flag)) ++ return (1); ++ return (0); ++} +diff -ruN maildirgetquota.c maildirgetquota.c +--- maildirgetquota.c Thu Jan 1 01:00:00 1970 ++++ maildirgetquota.c Wed Aug 6 17:09:48 2003 +@@ -0,0 +1,50 @@ ++/* ++** Copyright 1998 - 2000 Double Precision, Inc. ++** See COPYING for distribution information. ++*/ ++ ++#include "maildirgetquota.h" ++#include "maildirmisc.h" ++#if HAVE_UNISTD_H ++#include ++#endif ++#include ++#include ++#include ++#include ++#include ++ ++int maildir_getquota(const char *dir, char buf[QUOTABUFSIZE]) ++{ ++char *p; ++struct stat stat_buf; ++int n; ++int l; ++ ++ p=(char *)malloc(strlen(dir)+sizeof("/maildirfolder")); ++ if (!p) return (-1); ++ ++ strcat(strcpy(p, dir), "/maildirfolder"); ++ if (stat(p, &stat_buf) == 0) ++ { ++ strcat(strcpy(p, dir), "/.."); ++ n=maildir_getquota(p, buf); ++ free(p); ++ return (n); ++ } ++ ++ strcat(strcpy(p, dir), "/maildirsize"); ++ n=maildir_safeopen(p, O_RDONLY, 0); ++ free(p); ++ if (n < 0) return (n); ++ if ((l=read(n, buf, QUOTABUFSIZE-1)) < 0) ++ { ++ close(n); ++ return (-1); ++ } ++ close(n); ++ for (n=0; n ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++static const char maildirgetquota_h_rcsid[]="$Id: maildirgetquota.h,v 1.5 1999/12/06 13:21:05 mrsam Exp $"; ++ ++#define QUOTABUFSIZE 256 ++ ++int maildir_getquota(const char *, char [QUOTABUFSIZE]); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif +diff -ruN maildirmisc.h maildirmisc.h +--- maildirmisc.h Thu Jan 1 01:00:00 1970 ++++ maildirmisc.h Wed Aug 6 17:09:48 2003 +@@ -0,0 +1,145 @@ ++#ifndef maildirmisc_h ++#define maildirmisc_h ++ ++/* ++** Copyright 2000 Double Precision, Inc. ++** See COPYING for distribution information. ++*/ ++ ++#if HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++static const char maildirmisc_h_rcsid[]="$Id: maildirmisc.h,v 1.8 2000/12/25 17:33:06 mrsam Exp $"; ++ ++/* ++** ++** Miscellaneous maildir-related code ++** ++*/ ++ ++/* Some special folders */ ++ ++#define INBOX "INBOX" ++#define DRAFTS "Drafts" ++#define SENT "Sent" ++#define TRASH "Trash" ++ ++#define SHAREDSUBDIR "shared-folders" ++ ++char *maildir_folderdir(const char *, /* maildir */ ++ const char *); /* folder name */ ++ /* Returns the directory corresponding to foldername (foldername is ++ ** checked to make sure that it's a valid name, else we set errno ++ ** to EINVAL, and return (0). ++ */ ++ ++char *maildir_filename(const char *, /* maildir */ ++ const char *, /* folder */ ++ const char *); /* filename */ ++ /* ++ ** Builds the filename to this message, suitable for opening. ++ ** If the file doesn't appear to be there, search the maildir to ++ ** see if someone changed the flags, and return the current filename. ++ */ ++ ++int maildir_safeopen(const char *, /* filename */ ++ int, /* mode */ ++ int); /* perm */ ++ ++/* ++** Same arguments as open(). When we're accessing a shared maildir, ++** prevent someone from playing cute and dumping a bunch of symlinks ++** in there. This function will open the indicate file only if the ++** last component is not a symlink. ++** This is implemented by opening the file with O_NONBLOCK (to prevent ++** a DOS attack of someone pointing the symlink to a pipe, causing ++** the open to hang), clearing O_NONBLOCK, then stat-int the file ++** descriptor, lstating the filename, and making sure that dev/ino ++** match. ++*/ ++ ++int maildir_semisafeopen(const char *, /* filename */ ++ int, /* mode */ ++ int); /* perm */ ++ ++/* ++** Same thing, except that we allow ONE level of soft link indirection, ++** because we're reading from our own maildir, which points to the ++** message in the sharable maildir. ++*/ ++ ++int maildir_mkdir(const char *); /* directory */ ++/* ++** Create maildir including all subdirectories in the path (like mkdir -p) ++*/ ++ ++void maildir_purgetmp(const char *); /* maildir */ ++ /* purges old stuff out of tmp */ ++ ++void maildir_purge(const char *, /* directory */ ++ unsigned); /* time_t to purge */ ++ ++void maildir_getnew(const char *, /* maildir */ ++ const char *); /* folder */ ++ /* move messages from new to cur */ ++ ++int maildir_deletefolder(const char *, /* maildir */ ++ const char *); /* folder */ ++ /* deletes a folder */ ++ ++int maildir_mddelete(const char *); /* delete a maildir folder by path */ ++ ++void maildir_list_sharable(const char *, /* maildir */ ++ void (*)(const char *, void *), /* callback function */ ++ void *); /* 2nd arg to callback func */ ++ /* list sharable folders */ ++ ++int maildir_shared_subscribe(const char *, /* maildir */ ++ const char *); /* folder */ ++ /* subscribe to a shared folder */ ++ ++void maildir_list_shared(const char *, /* maildir */ ++ void (*)(const char *, void *), /* callback function */ ++ void *); /* 2nd arg to the callback func */ ++ /* list subscribed folders */ ++ ++int maildir_shared_unsubscribe(const char *, /* maildir */ ++ const char *); /* folder */ ++ /* unsubscribe from a shared folder */ ++ ++char *maildir_shareddir(const char *, /* maildir */ ++ const char *); /* folder */ ++ /* ++ ** Validate and return a path to a shared folder. folderdir must be ++ ** a name of a valid shared folder. ++ */ ++ ++void maildir_shared_sync(const char *); /* maildir */ ++ /* "sync" the shared folder */ ++ ++int maildir_sharedisro(const char *); /* maildir */ ++ /* maildir is a shared read-only folder */ ++ ++int maildir_unlinksharedmsg(const char *); /* filename */ ++ /* Remove a message from a shared folder */ ++ ++/* Internal function that reads a symlink */ ++ ++char *maildir_getlink(const char *); ++ ++ /* Determine whether the maildir filename has a certain flag */ ++ ++int maildir_hasflag(const char *filename, char); ++ ++#define MAILDIR_DELETED(f) maildir_hasflag((f), 'T') ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif +diff -ruN maildiropen.c maildiropen.c +--- maildiropen.c Thu Jan 1 01:00:00 1970 ++++ maildiropen.c Wed Aug 6 17:09:48 2003 +@@ -0,0 +1,133 @@ ++/* ++** Copyright 2000 Double Precision, Inc. ++** See COPYING for distribution information. ++*/ ++ ++#if HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#if HAVE_UNISTD_H ++#include ++#endif ++#include ++#include ++#include ++#include ++ ++#include "maildirmisc.h" ++ ++static const char rcsid[]="$Id: maildiropen.c,v 1.7 2000/12/10 04:43:44 mrsam Exp $"; ++ ++char *maildir_getlink(const char *filename) ++{ ++#if HAVE_READLINK ++size_t bufsiz; ++char *buf; ++ ++ bufsiz=0; ++ buf=0; ++ ++ for (;;) ++ { ++ int n; ++ ++ if (buf) free(buf); ++ bufsiz += 256; ++ if ((buf=malloc(bufsiz)) == 0) ++ { ++ perror("malloc"); ++ return (0); ++ } ++ if ((n=readlink(filename, buf, bufsiz)) < 0) ++ { ++ free(buf); ++ return (0); ++ } ++ if (n < bufsiz) ++ { ++ buf[n]=0; ++ break; ++ } ++ } ++ return (buf); ++#else ++ return (0); ++#endif ++} ++ ++int maildir_semisafeopen(const char *path, int mode, int perm) ++{ ++ ++#if HAVE_READLINK ++ ++char *l=maildir_getlink(path); ++ ++ if (l) ++ { ++ int f; ++ ++ if (*l != '/') ++ { ++ char *q=malloc(strlen(path)+strlen(l)+2); ++ char *s; ++ ++ if (!q) ++ { ++ free(l); ++ return (-1); ++ } ++ ++ strcpy(q, path); ++ if ((s=strchr(q, '/')) != 0) ++ s[1]=0; ++ else *q=0; ++ strcat(q, l); ++ free(l); ++ l=q; ++ } ++ ++ f=maildir_safeopen(l, mode, perm); ++ ++ free(l); ++ return (f); ++ } ++#endif ++ ++ return (maildir_safeopen(path, mode, perm)); ++} ++ ++int maildir_safeopen(const char *path, int mode, int perm) ++{ ++struct stat stat1, stat2; ++ ++int fd=open(path, mode ++#ifdef O_NONBLOCK ++ | O_NONBLOCK ++#else ++ | O_NDELAY ++#endif ++ , perm); ++ ++ if (fd < 0) return (fd); ++ if (fcntl(fd, F_SETFL, (mode & O_APPEND)) || fstat(fd, &stat1) ++ || lstat(path, &stat2)) ++ { ++ close(fd); ++ return (-1); ++ } ++ ++ if (stat1.st_dev != stat2.st_dev || stat1.st_ino != stat2.st_ino) ++ { ++ close(fd); ++ errno=ENOENT; ++ return (-1); ++ } ++ ++ return (fd); ++} +diff -ruN maildirparsequota.c maildirparsequota.c +--- maildirparsequota.c Thu Jan 1 01:00:00 1970 ++++ maildirparsequota.c Wed Aug 6 17:09:48 2003 +@@ -0,0 +1,44 @@ ++/* ++** Copyright 1998 - 1999 Double Precision, Inc. ++** See COPYING for distribution information. ++*/ ++ ++#if HAVE_CONFIG_H ++#include "config.h" ++#endif ++#include "maildirquota.h" ++#include ++#include ++ ++static const char rcsid[]="$Id: maildirparsequota.c,v 1.2 1999/12/06 13:21:05 mrsam Exp $"; ++ ++int maildir_parsequota(const char *n, unsigned long *s) ++{ ++const char *o; ++int yes; ++ ++ if ((o=strrchr(n, '/')) == 0) o=n; ++ ++ for (; *o; o++) ++ if (*o == ':') break; ++ yes=0; ++ for ( ; o >= n; --o) ++ { ++ if (*o == '/') break; ++ ++ if (*o == ',' && o[1] == 'S' && o[2] == '=') ++ { ++ yes=1; ++ o += 3; ++ break; ++ } ++ } ++ if (yes) ++ { ++ *s=0; ++ while (*o >= '0' && *o <= '9') ++ *s= *s*10 + (*o++ - '0'); ++ return (0); ++ } ++ return (-1); ++} +diff -ruN maildirquota.c maildirquota.c +--- maildirquota.c Thu Jan 1 01:00:00 1970 ++++ maildirquota.c Wed Aug 6 17:09:48 2003 +@@ -0,0 +1,685 @@ ++/* ++** Copyright 1998 - 2002 Double Precision, Inc. ++** See COPYING for distribution information. ++*/ ++ ++#if HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++/* #if HAVE_DIRENT_H */ ++#include ++#define NAMLEN(dirent) strlen((dirent)->d_name) ++/* #else ++#define dirent direct ++#define NAMLEN(dirent) (dirent)->d_namlen ++#if HAVE_SYS_NDIR_H ++#include ++#endif ++#if HAVE_SYS_DIR_H ++#include ++#endif ++#if HAVE_NDIR_H ++#include ++#endif ++#endif */ ++#include ++/* #if HAVE_SYS_STAT_H */ ++#include ++/* #endif */ ++#include ++ ++#include "maildirquota.h" ++#include "maildirmisc.h" ++#include ++#include ++#include ++#include ++/* #if HAVE_FCNTL_H */ ++#include ++/* #endif */ ++#if HAVE_UNISTD_H ++#include ++#endif ++#include ++#include "numlib.h" ++ ++static const char rcsid[]="$Id: maildirquota.c,v 1.9 2002/05/01 04:05:33 mrsam Exp $"; ++ ++/* Read the maildirsize file */ ++ ++int maildirsize_read(const char *filename, /* The filename */ ++ int *fdptr, /* Keep the file descriptor open */ ++ off_t *sizeptr, /* Grand total of maildir size */ ++ unsigned *cntptr, /* Grand total of message count */ ++ unsigned *nlines, /* # of lines in maildirsize */ ++ struct stat *statptr) /* The stats on maildirsize */ ++{ ++char buf[5120]; ++int f; ++char *p; ++unsigned l; ++int n; ++int first; ++ ++ if ((f=maildir_safeopen(filename, O_RDWR|O_APPEND, 0)) < 0) ++ return (-1); ++ p=buf; ++ l=sizeof(buf); ++ ++ while (l) ++ { ++ n=read(f, p, l); ++ if (n < 0) ++ { ++ close(f); ++ return (-1); ++ } ++ if (n == 0) break; ++ p += n; ++ l -= n; ++ } ++ if (l == 0 || fstat(f, statptr)) /* maildir too big */ ++ { ++ close(f); ++ return (-1); ++ } ++ ++ *sizeptr=0; ++ *cntptr=0; ++ *nlines=0; ++ *p=0; ++ p=buf; ++ first=1; ++ while (*p) ++ { ++ long n=0; ++ int c=0; ++ char *q=p; ++ ++ while (*p) ++ if (*p++ == '\n') ++ { ++ p[-1]=0; ++ break; ++ } ++ ++ if (first) ++ { ++ first=0; ++ continue; ++ } ++ sscanf(q, "%ld %d", &n, &c); ++ *sizeptr += n; ++ *cntptr += c; ++ ++ *nlines; ++ } ++ *fdptr=f; ++ return (0); ++} ++ ++static char *makenewmaildirsizename(const char *, int *); ++static int countcurnew(const char *, time_t *, off_t *, unsigned *); ++static int countsubdir(const char *, const char *, ++ time_t *, off_t *, unsigned *); ++static int statcurnew(const char *, time_t *); ++static int statsubdir(const char *, const char *, time_t *); ++ ++#define MDQUOTA_SIZE 'S' /* Total size of all messages in maildir */ ++#define MDQUOTA_BLOCKS 'B' /* Total # of blocks for all messages in ++ maildir -- NOT IMPLEMENTED */ ++#define MDQUOTA_COUNT 'C' /* Total number of messages in maildir */ ++ ++static int qcalc(off_t s, unsigned n, const char *quota, int *percentage) ++{ ++off_t i; ++int spercentage=0; ++int npercentage=0; ++ ++ errno=ENOSPC; ++ while (quota && *quota) ++ { ++ int x=1; ++ ++ if (*quota < '0' || *quota > '9') ++ { ++ ++quota; ++ continue; ++ } ++ i=0; ++ while (*quota >= '0' && *quota <= '9') ++ i=i*10 + (*quota++ - '0'); ++ switch (*quota) { ++ default: ++ if (i < s) ++ { ++ *percentage=100; ++ return (-1); ++ } ++ ++ /* ++ ** For huge quotas, over 20mb, ++ ** divide numerator & denominator by 1024 to prevent ++ ** an overflow when multiplying by 100 ++ */ ++ ++ x=1; ++ if (i > 20000000) x=1024; ++ ++ spercentage = i ? (s/x) * 100 / (i/x):100; ++ break; ++ case 'C': ++ ++ if (i < n) ++ { ++ *percentage=100; ++ return (-1); ++ } ++ ++ /* Ditto */ ++ ++ x=1; ++ if (i > 20000000) x=1024; ++ ++ npercentage = i ? ((off_t)n/x) * 100 / (i/x):100; ++ break; ++ } ++ } ++ *percentage = spercentage > npercentage ? spercentage:npercentage; ++ return (0); ++} ++ ++static int doaddquota(const char *, int, const char *, long, int, int); ++ ++static int docheckquota(const char *dir, ++ int *maildirsize_fdptr, ++ const char *quota_type, ++ long xtra_size, ++ int xtra_cnt, int *percentage); ++ ++ ++int maildir_checkquota(const char *dir, ++ int *maildirsize_fdptr, ++ const char *quota_type, ++ long xtra_size, ++ int xtra_cnt) ++{ ++int dummy; ++ ++ return (docheckquota(dir, maildirsize_fdptr, quota_type, ++ xtra_size, xtra_cnt, &dummy)); ++} ++ ++int maildir_readquota(const char *dir, const char *quota_type) ++{ ++int percentage=0; ++int fd=-1; ++ ++ (void)docheckquota(dir, &fd, quota_type, 0, 0, &percentage); ++ if (fd >= 0) ++ close(fd); ++ return (percentage); ++} ++ ++static int docheckquota(const char *dir, ++ int *maildirsize_fdptr, ++ const char *quota_type, ++ long xtra_size, ++ int xtra_cnt, ++ int *percentage) ++{ ++char *checkfolder=(char *)malloc(strlen(dir)+sizeof("/maildirfolder")); ++char *newmaildirsizename; ++struct stat stat_buf; ++int maildirsize_fd; ++off_t maildirsize_size; ++unsigned maildirsize_cnt; ++unsigned maildirsize_nlines; ++int n; ++time_t tm; ++time_t maxtime; ++DIR *dirp; ++struct dirent *de; ++ ++ if (checkfolder == 0) return (-1); ++ *maildirsize_fdptr= -1; ++ strcat(strcpy(checkfolder, dir), "/maildirfolder"); ++ if (stat(checkfolder, &stat_buf) == 0) /* Go to parent */ ++ { ++ strcat(strcpy(checkfolder, dir), "/.."); ++ n=docheckquota(checkfolder, maildirsize_fdptr, ++ quota_type, xtra_size, xtra_cnt, percentage); ++ free(checkfolder); ++ return (n); ++ } ++ if (!quota_type || !*quota_type) return (0); ++ ++ strcat(strcpy(checkfolder, dir), "/maildirsize"); ++ time(&tm); ++ if (maildirsize_read(checkfolder, &maildirsize_fd, ++ &maildirsize_size, &maildirsize_cnt, ++ &maildirsize_nlines, &stat_buf) == 0) ++ { ++ n=qcalc(maildirsize_size+xtra_size, maildirsize_cnt+xtra_cnt, ++ quota_type, percentage); ++ ++ if (n == 0) ++ { ++ free(checkfolder); ++ *maildirsize_fdptr=maildirsize_fd; ++ return (0); ++ } ++ close(maildirsize_fd); ++ ++ if (maildirsize_nlines == 1 && tm < stat_buf.st_mtime + 15*60) ++ return (n); ++ } ++ ++ maxtime=0; ++ maildirsize_size=0; ++ maildirsize_cnt=0; ++ ++ if (countcurnew(dir, &maxtime, &maildirsize_size, &maildirsize_cnt)) ++ { ++ free(checkfolder); ++ return (-1); ++ } ++ ++ dirp=opendir(dir); ++ while (dirp && (de=readdir(dirp)) != 0) ++ { ++ if (countsubdir(dir, de->d_name, &maxtime, &maildirsize_size, ++ &maildirsize_cnt)) ++ { ++ free(checkfolder); ++ closedir(dirp); ++ return (-1); ++ } ++ } ++ if (dirp) ++ { ++#if CLOSEDIR_VOID ++ closedir(dirp); ++#else ++ if (closedir(dirp)) ++ { ++ free(checkfolder); ++ return (-1); ++ } ++#endif ++ } ++ ++ newmaildirsizename=makenewmaildirsizename(dir, &maildirsize_fd); ++ if (!newmaildirsizename) ++ { ++ free(checkfolder); ++ return (-1); ++ } ++ ++ *maildirsize_fdptr=maildirsize_fd; ++ ++ if (doaddquota(dir, maildirsize_fd, quota_type, maildirsize_size, ++ maildirsize_cnt, 1)) ++ { ++ free(newmaildirsizename); ++ unlink(newmaildirsizename); ++ close(maildirsize_fd); ++ *maildirsize_fdptr= -1; ++ free(checkfolder); ++ return (-1); ++ } ++ ++ strcat(strcpy(checkfolder, dir), "/maildirsize"); ++ ++ if (rename(newmaildirsizename, checkfolder)) ++ { ++ free(checkfolder); ++ unlink(newmaildirsizename); ++ close(maildirsize_fd); ++ *maildirsize_fdptr= -1; ++ } ++ free(checkfolder); ++ free(newmaildirsizename); ++ ++ tm=0; ++ ++ if (statcurnew(dir, &tm)) ++ { ++ close(maildirsize_fd); ++ *maildirsize_fdptr= -1; ++ return (-1); ++ } ++ ++ dirp=opendir(dir); ++ while (dirp && (de=readdir(dirp)) != 0) ++ { ++ if (statsubdir(dir, de->d_name, &tm)) ++ { ++ close(maildirsize_fd); ++ *maildirsize_fdptr= -1; ++ closedir(dirp); ++ return (-1); ++ } ++ } ++ if (dirp) ++ { ++#if CLOSEDIR_VOID ++ closedir(dirp); ++#else ++ if (closedir(dirp)) ++ { ++ close(maildirsize_fd); ++ *maildirsize_fdptr= -1; ++ return (-1); ++ } ++#endif ++ } ++ ++ if (tm != maxtime) /* Race condition, someone changed something */ ++ { ++ errno=EAGAIN; ++ return (-1); ++ } ++ ++ return (qcalc(maildirsize_size+xtra_size, maildirsize_cnt+xtra_cnt, ++ quota_type, percentage)); ++} ++ ++int maildir_addquota(const char *dir, int maildirsize_fd, ++ const char *quota_type, long maildirsize_size, int maildirsize_cnt) ++{ ++ if (!quota_type || !*quota_type) return (0); ++ return (doaddquota(dir, maildirsize_fd, quota_type, maildirsize_size, ++ maildirsize_cnt, 0)); ++} ++ ++static int doaddquota(const char *dir, int maildirsize_fd, ++ const char *quota_type, long maildirsize_size, int maildirsize_cnt, ++ int isnew) ++{ ++union { ++ char buf[100]; ++ struct stat stat_buf; ++ } u; /* Scrooge */ ++char *newname2=0; ++char *newmaildirsizename=0; ++struct iovec iov[3]; ++int niov; ++struct iovec *p; ++int n; ++ ++ niov=0; ++ if ( maildirsize_fd < 0) ++ { ++ newname2=(char *)malloc(strlen(dir)+sizeof("/maildirfolder")); ++ if (!newname2) return (-1); ++ strcat(strcpy(newname2, dir), "/maildirfolder"); ++ if (stat(newname2, &u.stat_buf) == 0) ++ { ++ strcat(strcpy(newname2, dir), "/.."); ++ n=doaddquota(newname2, maildirsize_fd, quota_type, ++ maildirsize_size, maildirsize_cnt, ++ isnew); ++ free(newname2); ++ return (n); ++ } ++ ++ strcat(strcpy(newname2, dir), "/maildirsize"); ++ ++ if ((maildirsize_fd=maildir_safeopen(newname2, ++ O_RDWR|O_APPEND, 0644)) < 0) ++ { ++ newmaildirsizename=makenewmaildirsizename(dir, &maildirsize_fd); ++ if (!newmaildirsizename) ++ { ++ free(newname2); ++ return (-1); ++ } ++ ++ maildirsize_fd=maildir_safeopen(newmaildirsizename, ++ O_CREAT|O_RDWR|O_APPEND, 0644); ++ ++ if (maildirsize_fd < 0) ++ { ++ free(newname2); ++ return (-1); ++ } ++ isnew=1; ++ } ++ } ++ ++ if (isnew) ++ { ++ iov[0].iov_base=(caddr_t)quota_type; ++ iov[0].iov_len=strlen(quota_type); ++ iov[1].iov_base=(caddr_t)"\n"; ++ iov[1].iov_len=1; ++ niov=2; ++ } ++ ++ ++ sprintf(u.buf, "%ld %d\n", maildirsize_size, maildirsize_cnt); ++ iov[niov].iov_base=(caddr_t)u.buf; ++ iov[niov].iov_len=strlen(u.buf); ++ ++ p=iov; ++ ++niov; ++ n=0; ++ while (niov) ++ { ++ if (n) ++ { ++ if (n < p->iov_len) ++ { ++ p->iov_base= ++ (caddr_t)((char *)p->iov_base + n); ++ p->iov_len -= n; ++ } ++ else ++ { ++ n -= p->iov_len; ++ ++p; ++ --niov; ++ continue; ++ } ++ } ++ ++ n=writev( maildirsize_fd, p, niov); ++ ++ if (n <= 0) ++ { ++ if (newname2) ++ { ++ close(maildirsize_fd); ++ free(newname2); ++ } ++ return (-1); ++ } ++ } ++ if (newname2) ++ { ++ close(maildirsize_fd); ++ ++ if (newmaildirsizename) ++ { ++ rename(newmaildirsizename, newname2); ++ free(newmaildirsizename); ++ } ++ free(newname2); ++ } ++ return (0); ++} ++ ++/* New maildirsize is built in the tmp subdirectory */ ++ ++static char *makenewmaildirsizename(const char *dir, int *fd) ++{ ++char hostname[256]; ++struct stat stat_buf; ++time_t t; ++char *p; ++ ++ hostname[0]=0; ++ hostname[sizeof(hostname)-1]=0; ++ gethostname(hostname, sizeof(hostname)-1); ++ p=(char *)malloc(strlen(dir)+strlen(hostname)+130); ++ if (!p) return (0); ++ ++ for (;;) ++ { ++ char tbuf[NUMBUFSIZE]; ++ char pbuf[NUMBUFSIZE]; ++ ++ time(&t); ++ strcat(strcpy(p, dir), "/tmp/"); ++ sprintf(p+strlen(p), "%s.%s_NeWmAiLdIrSiZe.%s", ++ str_time_t(t, tbuf), ++ str_pid_t(getpid(), pbuf), hostname); ++ ++ if (stat( (const char *)p, &stat_buf) < 0 && ++ (*fd=maildir_safeopen(p, ++ O_CREAT|O_RDWR|O_APPEND, 0644)) >= 0) ++ break; ++ sleep(3); ++ } ++ return (p); ++} ++ ++static int statcurnew(const char *dir, time_t *maxtimestamp) ++{ ++char *p=(char *)malloc(strlen(dir)+5); ++struct stat stat_buf; ++ ++ if (!p) return (-1); ++ strcat(strcpy(p, dir), "/cur"); ++ if ( stat(p, &stat_buf) == 0 && stat_buf.st_mtime > *maxtimestamp) ++ *maxtimestamp=stat_buf.st_mtime; ++ strcat(strcpy(p, dir), "/new"); ++ if ( stat(p, &stat_buf) == 0 && stat_buf.st_mtime > *maxtimestamp) ++ *maxtimestamp=stat_buf.st_mtime; ++ free(p); ++ return (0); ++} ++ ++static int statsubdir(const char *dir, const char *subdir, time_t *maxtime) ++{ ++char *p; ++int n; ++ ++ if ( *subdir != '.' || strcmp(subdir, ".") == 0 || ++ strcmp(subdir, "..") == 0 || strcmp(subdir, "." TRASH) == 0) ++ return (0); ++ ++ p=(char *)malloc(strlen(dir)+strlen(subdir)+2); ++ if (!p) return (-1); ++ strcat(strcat(strcpy(p, dir), "/"), subdir); ++ n=statcurnew(p, maxtime); ++ free(p); ++ return (n); ++} ++ ++static int docount(const char *, time_t *, off_t *, unsigned *); ++ ++static int countcurnew(const char *dir, time_t *maxtime, ++ off_t *sizep, unsigned *cntp) ++{ ++char *p=(char *)malloc(strlen(dir)+5); ++int n; ++ ++ if (!p) return (-1); ++ strcat(strcpy(p, dir), "/new"); ++ n=docount(p, maxtime, sizep, cntp); ++ if (n == 0) ++ { ++ strcat(strcpy(p, dir), "/cur"); ++ n=docount(p, maxtime, sizep, cntp); ++ } ++ free(p); ++ return (n); ++} ++ ++static int countsubdir(const char *dir, const char *subdir, time_t *maxtime, ++ off_t *sizep, unsigned *cntp) ++{ ++char *p; ++int n; ++ ++ if ( *subdir != '.' || strcmp(subdir, ".") == 0 || ++ strcmp(subdir, "..") == 0 || strcmp(subdir, "." TRASH) == 0) ++ return (0); ++ ++ p=(char *)malloc(strlen(dir)+strlen(subdir)+2); ++ if (!p) return (2); ++ strcat(strcat(strcpy(p, dir), "/"), subdir); ++ n=countcurnew(p, maxtime, sizep, cntp); ++ free(p); ++ return (n); ++} ++ ++static int docount(const char *dir, time_t *dirstamp, ++ off_t *sizep, unsigned *cntp) ++{ ++struct stat stat_buf; ++char *p; ++DIR *dirp; ++struct dirent *de; ++unsigned long s; ++ ++ if (stat(dir, &stat_buf)) return (0); /* Ignore */ ++ if (stat_buf.st_mtime > *dirstamp) *dirstamp=stat_buf.st_mtime; ++ if ((dirp=opendir(dir)) == 0) return (0); ++ while ((de=readdir(dirp)) != 0) ++ { ++ const char *n=de->d_name; ++ ++ if (*n == '.') continue; ++ ++ /* PATCH - do not count msgs marked as deleted */ ++ ++ for ( ; *n; n++) ++ { ++ if (n[0] != ':' || n[1] != '2' || ++ n[2] != ',') continue; ++ n += 3; ++ while (*n >= 'A' && *n <= 'Z') ++ { ++ if (*n == 'T') break; ++ ++n; ++ } ++ break; ++ } ++ if (*n == 'T') continue; ++ n=de->d_name; ++ ++ ++ if (maildir_parsequota(n, &s) == 0) ++ stat_buf.st_size=s; ++ else ++ { ++ p=(char *)malloc(strlen(dir)+strlen(n)+2); ++ if (!p) ++ { ++ closedir(dirp); ++ return (-1); ++ } ++ strcat(strcat(strcpy(p, dir), "/"), n); ++ if (stat(p, &stat_buf)) ++ { ++ free(p); ++ continue; ++ } ++ free(p); ++ } ++ *sizep += stat_buf.st_size; ++ ++*cntp; ++ } ++ ++#if CLOSEDIR_VOID ++ closedir(dirp); ++#else ++ if (closedir(dirp)) ++ return (-1); ++#endif ++ return (0); ++} +diff -ruN maildirquota.h maildirquota.h +--- maildirquota.h Thu Jan 1 01:00:00 1970 ++++ maildirquota.h Wed Aug 6 17:09:48 2003 +@@ -0,0 +1,45 @@ ++#ifndef maildirquota_h ++#define maildirquota_h ++ ++/* ++** Copyright 1998 - 1999 Double Precision, Inc. ++** See COPYING for distribution information. ++*/ ++ ++#if HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++#include ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++static const char maildirquota_h_rcsid[]="$Id: maildirquota.h,v 1.2 2000/09/04 17:10:28 mrsam Exp $"; ++ ++int maildir_checkquota(const char *, /* Pointer to directory */ ++ int *, /* Initialized to -1, or opened descriptor for maildirsize */ ++ const char *, /* The quota */ ++ long, /* Extra bytes planning to add/remove from maildir */ ++ int); /* Extra messages planning to add/remove from maildir */ ++ ++int maildir_addquota(const char *, /* Pointer to the maildir */ ++ int, /* Must be the int pointed to by 2nd arg to checkquota */ ++ const char *, /* The quota */ ++ long, /* +/- bytes */ ++ int); /* +/- files */ ++ ++int maildir_readquota(const char *, /* Directory */ ++ const char *); /* Quota, from getquota */ ++ ++int maildir_parsequota(const char *, unsigned long *); ++ /* Attempt to parse file size encoded in filename. Returns 0 if ++ ** parsed, non-zero if we didn't parse. */ ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif +diff -ruN numlib.h numlib.h +--- numlib.h Thu Jan 1 01:00:00 1970 ++++ numlib.h Wed Aug 6 17:09:48 2003 +@@ -0,0 +1,45 @@ ++#ifndef numlib_h ++#define numlib_h ++ ++/* ++** Copyright 1998 - 1999 Double Precision, Inc. ++** See COPYING for distribution information. ++*/ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++static const char numlib_h_rcsid[]="$Id: numlib.h,v 1.3 2001/08/12 15:46:40 mrsam Exp $"; ++ ++#if HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++#include ++ ++#define NUMBUFSIZE 60 ++ ++/* Convert various system types to decimal */ ++ ++char *str_time_t(time_t, char *); ++char *str_off_t(off_t, char *); ++char *str_pid_t(pid_t, char *); ++char *str_ino_t(ino_t, char *); ++char *str_uid_t(uid_t, char *); ++char *str_gid_t(gid_t, char *); ++char *str_size_t(size_t, char *); ++ ++char *str_sizekb(unsigned long, char *); /* X Kb or X Mb */ ++ ++/* Convert selected system types to hex */ ++ ++char *strh_time_t(time_t, char *); ++char *strh_pid_t(pid_t, char *); ++char *strh_ino_t(ino_t, char *); ++ ++#ifdef __cplusplus ++} ++#endif ++#endif +diff -ruN overmaildirquota.c overmaildirquota.c +--- overmaildirquota.c Thu Jan 1 01:00:00 1970 ++++ overmaildirquota.c Wed Aug 6 17:10:33 2003 +@@ -0,0 +1,42 @@ ++/* ++** Copyright 1998 - 1999 Double Precision, Inc. ++** See COPYING for distribution information. ++*/ ++ ++#if HAVE_CONFIG_H ++#include "config.h" ++#endif ++#include "maildirquota.h" ++#include ++#include ++#include ++#include ++ ++static const char rcsid[]="$Id: overquota.c,v 1.0 2002/06/09 16:21:05 mrsam Exp $"; ++ ++ ++int user_over_maildirquota( const char *dir, const char *q) ++{ ++struct stat stat_buf; ++int quotafd; ++int ret_value; ++ ++ if (fstat(0, &stat_buf) == 0 && S_ISREG(stat_buf.st_mode) && ++ stat_buf.st_size > 0 && *q) ++ { ++ if (maildir_checkquota(dir, "afd, q, stat_buf.st_size, 1) ++ && errno != EAGAIN) ++ { ++ if (quotafd >= 0) close(quotafd); ++ ret_value = 1; ++ } else { ++ maildir_addquota(dir, quotafd, q, stat_buf.st_size, 1); ++ if (quotafd >= 0) close(quotafd); ++ ret_value = 0; ++ } ++ } else { ++ ret_value = 0; ++ } ++ ++ return(ret_value); ++} +diff -ruN qmail-local.c qmail-local.c +--- qmail-local.c Wed Aug 6 17:05:13 2003 ++++ qmail-local.c Wed Aug 6 17:09:48 2003 +@@ -66,6 +66,7 @@ + + char buf[1024]; + char outbuf[1024]; ++#define QUOTABUFSIZE 256 + + /* child process */ + +@@ -86,9 +87,15 @@ + int fd; + substdio ss; + substdio ssout; ++ char quotabuf[QUOTABUFSIZE]; + + sig_alarmcatch(sigalrm); + if (chdir(dir) == -1) { if (error_temp(errno)) _exit(1); _exit(2); } ++ if (maildir_getquota(dir, quotabuf) == 0) { ++ if (user_over_maildirquota(dir,quotabuf)==1) { ++ _exit(1); ++ } ++ } + pid = getpid(); + host[0] = 0; + gethostname(host,sizeof(host)); +@@ -99,7 +106,10 @@ + s += fmt_str(s,"tmp/"); + s += fmt_ulong(s,time); *s++ = '.'; + s += fmt_ulong(s,pid); *s++ = '.'; +- s += fmt_strn(s,host,sizeof(host)); *s++ = 0; ++ s += fmt_strn(s,host,sizeof(host)); ++ s += fmt_strn(s,",S=",sizeof(",S=")); ++ if (fstat(0,&st) == -1) if (errno == error_noent) break; ++ s += fmt_ulong(s,st.st_size+rpline.len+dtline.len); *s++ = 0; + if (stat(fntmptph,&st) == -1) if (errno == error_noent) break; + /* really should never get to this point */ + if (loop == 2) _exit(1); +@@ -159,6 +169,7 @@ + switch(wait_exitcode(wstat)) + { + case 0: break; ++ case 1: strerr_die1x(1, "User over quota. (#5.1.1)"); + case 2: strerr_die1x(111,"Unable to chdir to maildir. (#4.2.1)"); + case 3: strerr_die1x(111,"Timeout on maildir delivery. (#4.3.0)"); + case 4: strerr_die1x(111,"Unable to read message. (#4.3.0)"); +diff -ruN qmail-pop3d.c qmail-pop3d.c +--- qmail-pop3d.c Wed Aug 6 17:05:13 2003 ++++ qmail-pop3d.c Wed Aug 6 17:09:48 2003 +@@ -16,6 +16,11 @@ + #include "readwrite.h" + #include "timeoutread.h" + #include "timeoutwrite.h" ++#include ++#include "maildirquota.h" ++#include "maildirmisc.h" ++ ++#define QUOTABUFSIZE 256 + + void die() { _exit(0); } + +@@ -45,19 +50,15 @@ + { + substdio_put(&ssout,buf,len); + } +-void puts(s) char *s; +-{ +- substdio_puts(&ssout,s); +-} + void flush() + { + substdio_flush(&ssout); + } + void err(s) char *s; + { +- puts("-ERR "); +- puts(s); +- puts("\r\n"); ++ substdio_puts(&ssout,"-ERR "); ++ substdio_puts(&ssout,s); ++ substdio_puts(&ssout,"\r\n"); + flush(); + } + +@@ -73,7 +74,7 @@ + void err_nosuch() { err("unable to open that message"); } + void err_nounlink() { err("unable to unlink all deleted messages"); } + +-void okay() { puts("+OK \r\n"); flush(); } ++void okay() { substdio_puts(&ssout,"+OK \r\n"); flush(); } + + void printfn(fn) char *fn; + { +@@ -153,11 +154,11 @@ + + total = 0; + for (i = 0;i < numm;++i) if (!m[i].flagdeleted) total += m[i].size; +- puts("+OK "); ++ substdio_puts(&ssout,"+OK "); + put(strnum,fmt_uint(strnum,numm)); +- puts(" "); ++ substdio_puts(&ssout," "); + put(strnum,fmt_ulong(strnum,total)); +- puts("\r\n"); ++ substdio_puts(&ssout,"\r\n"); + flush(); + } + +@@ -171,18 +172,41 @@ + + void pop3_last() + { +- puts("+OK "); ++ substdio_puts(&ssout,"+OK "); + put(strnum,fmt_uint(strnum,last)); +- puts("\r\n"); ++ substdio_puts(&ssout,"\r\n"); + flush(); + } + + void pop3_quit() + { + int i; ++ char quotabuf[QUOTABUFSIZE]; ++ int has_quota=maildir_getquota(".", quotabuf); ++ ++ long deleted_bytes=0; ++ long deleted_messages=0; ++ + for (i = 0;i < numm;++i) + if (m[i].flagdeleted) { +- if (unlink(m[i].fn) == -1) err_nounlink(); ++ unsigned long un=0; ++ const char *filename=m[i].fn; ++ if (has_quota == 0 && !MAILDIR_DELETED(filename)) { ++ if (maildir_parsequota(filename, &un)) { ++ struct stat stat_buf; ++ ++ if (stat(filename, &stat_buf) == 0) ++ un=stat_buf.st_size; ++ } ++ } ++ if (unlink(m[i].fn) == -1) { ++ err_nounlink(); ++ un=0; ++ } ++ if (un) { ++ deleted_bytes -= un; ++ deleted_messages -= 1; ++ } + } + else + if (str_start(m[i].fn,"new/")) { +@@ -192,6 +216,21 @@ + if (!stralloc_0(&line)) die_nomem(); + rename(m[i].fn,line.s); /* if it fails, bummer */ + } ++ ++ if (deleted_messages < 0) { ++ int quotafd; ++ ++ if (maildir_checkquota(".", "afd, quotabuf, deleted_bytes, ++ deleted_messages) && errno != EAGAIN && ++ deleted_bytes >= 0) ++ { ++ if (quotafd >= 0) close (quotafd); ++ } else { ++ maildir_addquota(".", quotafd, quotabuf, ++ deleted_bytes, deleted_messages); ++ if (quotafd >= 0) close(quotafd); ++ } ++ } + okay(); + die(); + } +@@ -222,10 +261,10 @@ + int flaguidl; + { + put(strnum,fmt_uint(strnum,i + 1)); +- puts(" "); ++ substdio_puts(&ssout," "); + if (flaguidl) printfn(m[i].fn); + else put(strnum,fmt_ulong(strnum,m[i].size)); +- puts("\r\n"); ++ substdio_puts(&ssout,"\r\n"); + } + + void dolisting(arg,flaguidl) char *arg; int flaguidl; +@@ -234,7 +273,7 @@ + if (*arg) { + i = msgno(arg); + if (i == -1) return; +- puts("+OK "); ++ substdio_puts(&ssout,"+OK "); + list(i,flaguidl); + } + else { +@@ -242,7 +281,7 @@ + for (i = 0;i < numm;++i) + if (!m[i].flagdeleted) + list(i,flaguidl); +- puts(".\r\n"); ++ substdio_puts(&ssout,".\r\n"); + } + flush(); + } +diff -ruN strpidt.c strpidt.c +--- strpidt.c Thu Jan 1 01:00:00 1970 ++++ strpidt.c Wed Aug 6 17:09:48 2003 +@@ -0,0 +1,26 @@ ++/* ++** Copyright 1998 - 2000 Double Precision, Inc. ++** See COPYING for distribution information. ++*/ ++ ++#if HAVE_CONFIG_H ++#include "config.h" ++#endif ++#include "numlib.h" ++#include ++ ++static const char rcsid[]="$Id: strpidt.c,v 1.3 2000/05/27 04:59:26 mrsam Exp $"; ++ ++char *str_pid_t(pid_t t, char *arg) ++{ ++char buf[NUMBUFSIZE]; ++char *p=buf+sizeof(buf)-1; ++ ++ *p=0; ++ do ++ { ++ *--p= '0' + (t % 10); ++ t=t / 10; ++ } while(t); ++ return (strcpy(arg, p)); ++} +diff -ruN strtimet.c strtimet.c +--- strtimet.c Thu Jan 1 01:00:00 1970 ++++ strtimet.c Wed Aug 6 17:09:48 2003 +@@ -0,0 +1,26 @@ ++/* ++** Copyright 1998 - 2000 Double Precision, Inc. ++** See COPYING for distribution information. ++*/ ++ ++#if HAVE_CONFIG_H ++#include "config.h" ++#endif ++#include "numlib.h" ++#include ++ ++static const char rcsid[]="$Id: strtimet.c,v 1.3 2000/05/27 04:59:26 mrsam Exp $"; ++ ++char *str_time_t(time_t t, char *arg) ++{ ++char buf[NUMBUFSIZE]; ++char *p=buf+sizeof(buf)-1; ++ ++ *p=0; ++ do ++ { ++ *--p= '0' + (t % 10); ++ t=t / 10; ++ } while(t); ++ return (strcpy(arg, p)); ++}