*** Makefile.orig Mon Nov 10 15:54:05 2003 --- Makefile Mon Nov 10 15:54:26 2003 *************** *** 86,92 **** #-Wimplicit -Wshadow -Wid-clash-6 #-Wuninitialized # The place to put your favourite extra cc flag ! CFLAGS0 = #-O #$(GCC_WARNINGS) LDFLAGS0= -s # Read my libs :-) LIBS= --- 86,92 ---- #-Wimplicit -Wshadow -Wid-clash-6 #-Wuninitialized # The place to put your favourite extra cc flag ! CFLAGS0 = -O -I . -I ../courier-imap #$(GCC_WARNINGS) LDFLAGS0= -s # Read my libs :-) LIBS= *** patchlevel.h.orig Mon Nov 10 17:05:44 2003 --- patchlevel.h Mon Nov 10 17:06:27 2003 *************** *** 2,7 **** --- 2,8 ---- v3.22 2001/09/10\n\ Copyright (c) 1990-2001, Stephen R. van den Berg\t\n\ Copyright (c) 1997-2001, Philip A. Guenther\t\t\n\ + Maildir++ aware by Vadim Nosovsky, 8.11.2003\n\ \n\ Submit questions/answers to the procmail-related mailinglist by sending to:\n\ \t\n\ *** src/Makefile.0.orig Sun Nov 9 00:30:03 2003 --- src/Makefile.0 Sun Nov 9 00:31:00 2003 *************** *** 3,9 **** PM_OBJ=cstdio.$(O) common.$(O) exopen.$(O) goodies.$(O) locking.$(O) \ mailfold.$(O) foldinfo.$(O) misc.$(O) pipes.$(O) regexp.$(O) robust.$(O) \ sublib.$(O) acommon.$(O) mcommon.$(O) lastdirsep.$(O) authenticate.$(O) \ ! lmtp.$(O) memblk.$(O) variables.$(O) from.$(O) comsat.$(O) LF_OBJ=exopen.$(O) sublib.$(O) acommon.$(O) mcommon.$(O) authenticate.$(O) \ lastdirsep.$(O) FM_OBJ=common.$(O) fields.$(O) formisc.$(O) sublib.$(O) ecommon.$(O) \ --- 3,10 ---- PM_OBJ=cstdio.$(O) common.$(O) exopen.$(O) goodies.$(O) locking.$(O) \ mailfold.$(O) foldinfo.$(O) misc.$(O) pipes.$(O) regexp.$(O) robust.$(O) \ sublib.$(O) acommon.$(O) mcommon.$(O) lastdirsep.$(O) authenticate.$(O) \ ! lmtp.$(O) memblk.$(O) variables.$(O) from.$(O) comsat.$(O) \ ! ../courier-imap/maildir/libmaildir.a ../courier-imap/numlib/libnumlib.a ../courier-imap/rfc822/librfc822.a LF_OBJ=exopen.$(O) sublib.$(O) acommon.$(O) mcommon.$(O) authenticate.$(O) \ lastdirsep.$(O) FM_OBJ=common.$(O) fields.$(O) formisc.$(O) sublib.$(O) ecommon.$(O) \ *** src/mailfold.c.orig Tue Sep 11 06:58:34 2001 --- src/mailfold.c Mon Nov 10 15:33:35 2003 *************** *** 28,33 **** --- 28,45 ---- #include "shell.h" #include "mailfold.h" + // vlad quota maildir++ + #include "maildir/config.h" + #include "maildir/maildirquota.h" + #include "maildir/maildircreate.h" + #include "maildir/maildirmisc.h" + #include "maildir/quotawarnmsg.h" + //#define DISK_QUOTA 1000L // 10 Mb quota for users + #define QUOTA_WARN_PERCENT 90 + extern int quotaex; + extern u_long diskquota; + // vlad quota maildir++ + int logopened,rawnonl; off_t lasttell; static long lastdump; *************** *** 80,86 **** --- 92,113 ---- long dump(s,type,source,len)const int s,type;const char*source; long len; { int i;long part; + char str[128]; lasttell=i= -1;SETerrno(EBADF); + // vlad quota + //sprintf(str,"%d",quotaex); + //yell("dump quotaex:",str); + //if(s<0 && quota){ + if(quotaex){ + //yell("vlad.dump.fake.quota",""); + SETerrno(EDQUOT); //fake.quota.errno + //quotaex=1; + return EDQUOT; + //return i&&!len?-1:len; + //goto r; + } + // vlad quota + if(s>=0) { if(ft_lock(type)&&(lseek(s,(off_t)0,SEEK_END),fdlock(s))) nlog("Kernel-lock failed\n"); *************** *** 128,133 **** --- 155,163 ---- } i=rclose(s)||i; } /* return an error even if nothing was to be sent */ + // vlad quota + //r: + // vlad quota return i&&!len?-1:len; } *************** *** 194,199 **** --- 224,234 ---- int writefolder(boxname,linkfolder,source,len,ignwerr,dolock) char*boxname,*linkfolder;const char*source;long len;const int ignwerr,dolock; { char*chp,*chp2;mode_t mode;int fd,type; + // vlad quota + char s[1024]; + long curr_diskusage; + // vlad quota + if(*boxname=='|'&&(!linkfolder||linkfolder==Tmnate)) { setlastfolder(boxname); fd=rdup(Deliverymode==2?STDOUT:savstdout); *************** *** 209,214 **** --- 244,264 ---- else linkfolder=0; } + // vlad quota + //nlog("boxname:"),logqnl(boxname); + /* + curr_diskusage = get_diskusage(boxname); + sprintf(s,"%s %d Kbytes", boxname, curr_diskusage); + yell("vlad.delvier.usage",s); + //if(DISK_QUOTA && curr_diskusage > DISK_QUOTA) { + if(diskquota && curr_diskusage > diskquota) { + quotaex = 1; //fake.quota + yell("quota exceeded on",boxname); + //return -1; + } + */ + // vlad quota + type=foldertype(0,0,&mode,0); /* the envelope please! */ chp=strchr(buf,'\0'); switch(type) *************** *** 226,239 **** *chp='\0'; } setlastfolder(boxname); fd=opena(boxname); dumpc: if(dump(fd,type,source,len)&&!ignwerr) dumpf: { switch(errno) { case ENOSPC:nlog("No space left to finish writing"),logqnl(buf); break; #ifdef EDQUOT case EDQUOT:nlog("Quota exceeded while writing"),logqnl(buf); ! break; #endif default:writeerr(buf); } --- 276,297 ---- *chp='\0'; } setlastfolder(boxname); + // vlad quota + //yell("1boxname:",boxname); + // vlad quota fd=opena(boxname); + //yell("4boxname:",boxname); dumpc: if(dump(fd,type,source,len)&&!ignwerr) dumpf: { switch(errno) { case ENOSPC:nlog("No space left to finish writing"),logqnl(buf); break; #ifdef EDQUOT case EDQUOT:nlog("Quota exceeded while writing"),logqnl(buf); ! // vlad quota ! quotaex=1; ! //return 0; ! // vlad quota ! break; #endif default:writeerr(buf); } *************** *** 257,262 **** --- 315,365 ---- ;{ int retries=MAILDIRretries; for(;;) { struct stat stbuf; + // vlad quota + int auto_create = 0; + int quota_warn_percent = -1; + //int i; + const char *quota=NULL; + + struct maildirsize info; + char str[128]; + int doquota=maildirquota_countfolder(boxname); + + quota_warn_percent = QUOTA_WARN_PERCENT; + + yell("Maildir++ boxname",boxname); + sprintf(str,"Maildir++ doquota: %d, len: %ld",doquota, len); + yell(str,""); + + // TODO + // check quota by maildir++ (deliverquota's code) + // open uniq file (deliverquota's code) + // fd=uniq_foldername() + // write message to fd; + // update quota whatsoever + // of course it shouldn't work on mailbox at all !!!!!! + if (doquota && + maildir_quota_add_start(boxname, &info, len, 1, quota)) + { + if (quota_warn_percent >= 0) + maildir_deliver_quota_warning(boxname, quota_warn_percent); + yell("Maildir++ Mail quota exceeded on",boxname); + quotaex = 1; + // set quota flag here + //printf("Mail quota exceeded.\n"); + //exit(77); + } + /* + deliver(0, boxname, stat_buf.st_size, + auto_create, quota_warn_percent, NULL, quota); + */ + if (doquota) + maildir_quota_add_end(&info, len, 1); + //exit(0); + + + // vlad quota + if(0>(fd=unique(buf,chp,linebuf,NORMperm,verbose,doFD|doMAILDIR))) goto nfail; if(dump(fd,ft_MAILDIR,source,len)&&!ignwerr) *** src/misc.c.orig Fri Jun 29 04:21:05 2001 --- src/misc.c Sun Nov 9 00:21:13 2003 *************** *** 273,280 **** int fakedelivery; void Terminate P((void)) ! { ignoreterm(); if(getpid()==thepid) { const char*lstfolder; if(retval!=EXIT_SUCCESS) --- 273,298 ---- int fakedelivery; + // vlad quota + extern int vstdout,quotaex; + // vlad quota + void Terminate P((void)) ! { ! // vlad quota ! char *q = "This user is over quota\n\n"; ! // vlad quota ! ! ignoreterm(); ! ! // vlad quota ! if(quotaex){ ! write(vstdout,q,strlen(q)); ! retvl2 = 1; ! } ! // vlad quota ! ! if(getpid()==thepid) { const char*lstfolder; if(retval!=EXIT_SUCCESS) *************** *** 651,653 **** --- 669,797 ---- ret: return i; } + + + /********************************************** + * quotas by vn vlad@nobulus.com + ***********************************************/ + /* + #include + + int linkchk(FTSENT *); + + + + long get_diskusage(char *dir) + { + FTS *fts; + FTSENT *p; + long blocksize, savednumber = 0; + int ftsoptions=0, depth; + int notused, rval; + char *margv[] = {dir, NULL}; + + char s[128]; + + depth = INT_MAX; + //(void) getbsize(¬used, &blocksize); + //blocksize /= 512; + //sprintf(s,"%d", blocksize); + //yell("vlad.blocksize",s); + + rval = 0; + + + if ((fts = fts_open(margv, ftsoptions, NULL)) == NULL) + err(1, "fts_open"); + + while ((p = fts_read(fts)) != NULL) { + switch (p->fts_info) { + case FTS_D: // Ignore. + break; + case FTS_DP: + p->fts_parent->fts_number += + p->fts_number += p->fts_statp->st_blocks; + + break; + case FTS_DC: // Ignore. + break; + case FTS_DNR: // Warn, continue. + case FTS_ERR: + case FTS_NS: + warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); + rval = 1; + break; + default: + if (p->fts_statp->st_nlink > 1 && linkchk(p)) + break; + p->fts_parent->fts_number += p->fts_statp->st_blocks; + } + savednumber = p->fts_parent->fts_number; + } + + if (errno) + err(1, "fts_read"); + //syslog(LOG_ERR,"%d %d",savednumber, blocksize); + //sprintf(s,"%d", savednumber); + //yell("vlad.blocksize",s); + //return howmany(savednumber,blocksize); + return savednumber/2; + } + + + typedef struct _ID { + dev_t dev; + ino_t inode; + } ID; + + + int linkchk(p) + FTSENT *p; + { + static ID *files; + static int maxfiles, nfiles; + ID *fp, *start; + ino_t ino; + dev_t dev; + + ino = p->fts_statp->st_ino; + dev = p->fts_statp->st_dev; + if ((start = files) != NULL) + for (fp = start + nfiles - 1; fp >= start; --fp) + if (ino == fp->inode && dev == fp->dev) + return (1); + + if (nfiles == maxfiles && (files = realloc((char *)files, + (u_int)(sizeof(ID) * (maxfiles += 128)))) == NULL) + errx(1, "can't allocate memory"); + files[nfiles].inode = ino; + files[nfiles].dev = dev; + ++nfiles; + return (0); + } + + // read diskquota in bytes from ./maildirsize file + u_long get_diskquota(char *maildir){ + FILE *in; + char maildirsizef[1024]; + u_long diskquota=0L; // no quota by default + char str[1024], ch; + + strncpy(maildirsizef,maildir,1000); + strncpy(maildirsizef+strlen(maildirsizef),"maildirsize",1000); + //yell("maildirsize file:",maildirsizef); + + if((in=fopen(maildirsizef,"r")) != NULL){ + if(fgets(str,1023,in)){ + sscanf(str,"%ldS", &diskquota); + diskquota /= 1000; // get quota in Kb + // divide by 1000 not 1024 just for human friendly quotas representation + // in "maildirsize" file + } + } + //yell("str:",str); + sprintf(str,"%ld", diskquota); + yell("quota is:",str); + return diskquota; // no quota by default; + } + */ *** src/procmail.c.orig Thu Nov 6 22:15:11 2003 --- src/procmail.c Sun Nov 9 00:18:03 2003 *************** *** 59,64 **** --- 59,72 ---- privileged=priv_START,lexitcode=EXIT_SUCCESS,ignwerr,crestarg,savstdout, berkeley,mailfilter,erestrict,Deliverymode,ifdepth; /* depth of outermost */ struct dyna_array ifstack; + + // vlad quota + int vstdout; + int quotaex=0; // quota exceeded + u_long diskquota=0L; + //const char *login; + // vlad quota + size_t linebuf=mx(DEFlinebuf,1024/*STRLEN(systm_mbox)<<1*/); volatile int nextexit,lcking; /* if termination is imminent */ pid_t thepid; *************** *** 211,216 **** --- 219,229 ---- spassinvk=auth_newid();passinvk=savepass(spassinvk,uid); /* are we */ checkprivFrom_(euid,passinvk?auth_username(passinvk):0,override); doumask(INIT_UMASK); /* allowed to set the From_ line? */ + + // vlad quota save stdout + vstdout = dup(fileno(stdout)); + // vlad quota + while((savstdout=rdup(STDOUT))<=STDERR) { rclose(savstdout); /* move stdout out of the way */ if(0>(savstdout=opena(devnull))) *************** *** 498,503 **** --- 511,523 ---- setuid(uid); /* make sure we have enough space */ if(linebuf<(len=strlen(chp)+strlen(lockext)+UNIQnamelen)) allocbuffers(linebuf=len,1); /* to perform the lock & delivery */ + // vlad quota + //yell("mbox: ",chp); + //yell("maildir: ",curdir); + //login=getenv(lgname); + //yell("login: ",login); + //diskquota = get_diskquota(chp); + // vlad quota if(writefolder(chp,(char*)0,themail.p,filled,0,1)) /* default */ succeed=1; } /* if all else failed */