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

📄 maildirquota.c

📁 相当优秀的 UNIX 进程管理工具
💻 C
📖 第 1 页 / 共 2 页
字号:
		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));}static 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=(void *)quota_type;		iov[0].iov_len=strlen(quota_type);		iov[1].iov_base="\n";		iov[1].iov_len=1;		niov=2;	}	sprintf(u.buf, "%ld %d\n", maildirsize_size, maildirsize_cnt);	iov[niov].iov_base=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=					((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;int i;	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);        /* do not hang forever */	for (i=0;i<3;++i)	{	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;		usleep(100);	}	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 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);}static 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);}static 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));}static 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));}static 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);}

⌨️ 快捷键说明

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