⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qmail-maildir++.patch

📁 相当优秀的 UNIX 进程管理工具
💻 PATCH
📖 第 1 页 / 共 3 页
字号:
+ 		while (*o >= '0' && *o <= '9')+ 			*s= *s*10 + (*o++ - '0');+ 		return (0);+ 	}+ 	return (-1);+ }diff -crN ../qmail-1.03/maildirquota.c ./maildirquota.c*** ../qmail-1.03/maildirquota.c	Wed Dec 31 18:00:00 1969--- ./maildirquota.c	Mon Jun 10 13:25:46 2002****************** 0 ****--- 1,685 ----+ /*+ ** Copyright 1998 - 2002 Double Precision, Inc.+ ** See COPYING for distribution information.+ */+ + #if HAVE_CONFIG_H+ #include "config.h"+ #endif+ + #include <sys/types.h>+ /* #if HAVE_DIRENT_H */+ #include <dirent.h>+ #define NAMLEN(dirent) strlen((dirent)->d_name)+ /* #else+ #define dirent direct+ #define NAMLEN(dirent) (dirent)->d_namlen+ #if HAVE_SYS_NDIR_H+ #include <sys/ndir.h>+ #endif+ #if HAVE_SYS_DIR_H+ #include <sys/dir.h>+ #endif+ #if HAVE_NDIR_H+ #include <ndir.h>+ #endif+ #endif */+ #include	<sys/types.h>+ /* #if	HAVE_SYS_STAT_H */+ #include	<sys/stat.h>+ /* #endif */+ #include	<sys/uio.h>+ + #include	"maildirquota.h"+ #include	"maildirmisc.h"+ #include	<stdio.h>+ #include	<stdlib.h>+ #include	<string.h>+ #include	<errno.h>+ /* #if	HAVE_FCNTL_H */+ #include	<fcntl.h>+ /* #endif */+ #if	HAVE_UNISTD_H+ #include	<unistd.h>+ #endif+ #include	<time.h>+ #include	"numlib.h"+ + static const char rcsid[]="$Id: qmail-maildir++.patch,v 1.1.1.1 2003/09/10 20:43:16 tomcollins 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");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -