Back to index

courier  0.68.2
Defines | Functions
maildirquota.c File Reference
#include <sys/types.h>
#include "maildirquota.h"
#include "maildirmisc.h"
#include "maildircreate.h"
#include "quotawarnmsg.h"
#include "../rfc822/rfc822.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <ctype.h>
#include <numlib/numlib.h>

Go to the source code of this file.

Defines

#define dirent   direct
#define NAMLEN(dirent)   (dirent)->d_namlen
#define DIG(c)   ( (c) >= '0' && (c) <= '9')

Functions

static void parsequotastr (const char *, struct maildirquota *)
static int maildir_openquotafile_init (struct maildirsize *info, const char *maildir, const char *newquota)
static int do_maildir_openquotafile (struct maildirsize *info, const char *filename, const char *newquota)
int maildir_openquotafile (struct maildirsize *info, const char *maildir)
void maildir_closequotafile (struct maildirsize *info)
static int checkOneQuota (int64_t size, int64_t quota, int *percentage)
 Check if size > quota, and calculate by how much.
static int checkQuota (struct maildirquota *size, struct maildirquota *quota, int *percentage)
static char * makenewmaildirsizename (const char *, int *)
static int countcurnew (const char *, time_t *, int64_t *, unsigned *)
static int countsubdir (const char *, const char *, time_t *, int64_t *, unsigned *)
static int statcurnew (const char *, time_t *)
static int statsubdir (const char *, const char *, time_t *)
static int doaddquota (struct maildirsize *, int, int64_t, int, int)
static int docheckquota (struct maildirsize *info, int64_t xtra_size, int xtra_cnt, int *percentage)
int maildir_checkquota (struct maildirsize *info, int64_t xtra_size, int xtra_cnt)
int maildir_readquota (struct maildirsize *info)
int maildir_addquota (struct maildirsize *info, int64_t maildirsize_size, int maildirsize_cnt)
static int docount (const char *, time_t *, int64_t *, unsigned *)
int maildirquota_countfolder (const char *folder)
int maildirquota_countfile (const char *n)
int maildir_quota_add_start (const char *maildir, struct maildirsize *info, int64_t msgsize, int nmsgs, const char *newquota)
void maildir_quota_add_end (struct maildirsize *info, int64_t msgsize, int nmsgs)
void maildir_quota_deleted (const char *maildir, int64_t nbytes, int nmsgs)
void maildir_quota_recalculate (const char *maildir)
int maildir_quota_delundel_start (const char *maildir, struct maildirsize *info, int64_t msgsize, int nmsgs)
void maildir_quota_delundel_end (struct maildirsize *info, int64_t msgsize, int nmsgs)
void maildir_quota_set (const char *dir, const char *quota)
static void do_deliver_warning (const char *msgfile, const char *dir)
void maildir_deliver_quota_warning (const char *dir, const int percent, const char *msgquotafile)

Define Documentation

#define DIG (   c)    ( (c) >= '0' && (c) <= '9')

Definition at line 54 of file maildirquota.c.

#define dirent   direct

Definition at line 15 of file maildirquota.c.

#define NAMLEN (   dirent)    (dirent)->d_namlen

Definition at line 16 of file maildirquota.c.


Function Documentation

static int checkOneQuota ( int64_t  size,
int64_t  quota,
int *  percentage 
) [static]

Check if size > quota, and calculate by how much.

Definition at line 349 of file maildirquota.c.

{
       int x=1;

       if (quota == 0) /* No quota */
       {
              *percentage=0;
              return (0);
       }

       if (size > quota)
       {
              *percentage=100;
              return (-1);
       }

       if (quota > 20000000)
              x=1024;

       *percentage= quota > 0 ? (size/x) * 100 / (quota/x):0;
       return 0;
}

Here is the caller graph for this function:

static int checkQuota ( struct maildirquota size,
struct maildirquota quota,
int *  percentage 
) [static]

Definition at line 325 of file maildirquota.c.

{
       int b_quota;
       int n_quota;

       if (checkOneQuota(size->nbytes, quota->nbytes, &b_quota) ||
           checkOneQuota(size->nmessages, quota->nmessages,
                       &n_quota))
       {
              if (percentage)
                     *percentage= 100;
              errno=ENOSPC;
              return -1;
       }

       if (b_quota < n_quota)
              b_quota=n_quota;

       if (percentage)
              *percentage=b_quota;
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int countcurnew ( const char *  dir,
time_t *  maxtime,
int64_t *  sizep,
unsigned *  cntp 
) [static]

Definition at line 710 of file maildirquota.c.

{
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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int countsubdir ( const char *  dir,
const char *  subdir,
time_t *  maxtime,
int64_t *  sizep,
unsigned *  cntp 
) [static]

Definition at line 728 of file maildirquota.c.

{
char   *p;
int    n;

       if ( *subdir != '.' || strcmp(subdir, ".") == 0 ||
            strcmp(subdir, "..") == 0 ||
            ! maildirquota_countfolder(subdir))
              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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void do_deliver_warning ( const char *  msgfile,
const char *  dir 
) [static]

Definition at line 982 of file maildirquota.c.

{
       int    fdin, fd, ret;
       FILE *fpout;
       time_t t;
       size_t l, msg_len;
       char   *qname = 0;
       struct stat   sb;
       char   hostname[256];
       char   buf[4096];
       size_t n;
       struct maildirsize info;
       struct maildir_tmpcreate_info createInfo;

       fdin=-1;

       if (msgfile && *msgfile)
              fdin=open(msgfile, O_RDONLY);

       if (fdin < 0)
       {
              msgfile=QUOTAWARNMSG;
              fdin=open(msgfile, O_RDONLY);
       }

       if (fdin < 0)
              return;

       l = strlen(dir)+sizeof("/quotawarn");

       /* Send only one warning every 24 hours */
       if ((qname = malloc(l)) == 0)
       {
              close(fdin);
              return;
       }

       strcat(strcpy(qname, dir), "/quotawarn");
       time(&t);
       ret = stat(qname, &sb);
       if ((ret == -1 && errno != ENOENT) ||
           (ret == 0 && (sb.st_mtime + 86400) > t))
       {
              free(qname);
              close(fdin);
              return;
       }

       fd = open(qname, O_WRONLY|O_CREAT|O_TRUNC, 0644);
       free(qname);
       if (fd == -1)
       {
              close(fdin);
              return;
       }
       if (write(fd, buf, 1) < 0)
              perror(msgfile);

       close(fd);

       strcpy(buf, "Date: ");
       rfc822_mkdate_buf(t, buf+strlen(buf));
       strcat(buf, "\n");

       hostname[0]=0;
       hostname[sizeof(hostname)-1]=0;
       gethostname(hostname, sizeof(hostname)-1);
       sprintf(buf+strlen(buf), "Message-Id: <%lu.overquota@%-1.256s>\n",
              (unsigned long)t, hostname);

       if (fstat(fdin, &sb) < 0) {
              close(fdin);
              return;
       }
       msg_len=strlen(buf)+sb.st_size;



       maildir_tmpcreate_init(&createInfo);
       createInfo.maildir=dir;
       createInfo.uniq="warn";
       createInfo.msgsize=msg_len;
       createInfo.doordie=1;

       if ((fpout=maildir_tmpcreate_fp(&createInfo)) == NULL)
       {
              close(fdin);
              return;
       }

       fprintf(fpout, "%s", buf);

       while ((n=read(fdin, buf, sizeof(buf))) > 0)
       {
              if (fwrite(buf, n, 1, fpout) != 1)
              {
                     perror(createInfo.tmpname);
                     break;
              }
       }
       close(fdin);

       if (fflush(fpout) || ferror(fpout))
       {
              fclose(fpout);
              unlink(createInfo.tmpname);
              maildir_tmpcreate_free(&createInfo);
              return;
       }

       if (fseek(fpout, 0L, SEEK_SET) >= 0)
       {
              /* Make sure the quota message's size itself is factored into
              ** the quota. Deliver the message regardless of whether the
              ** user is over quota.
              */
              if (maildirquota_countfolder(dir))
              {
                     maildir_quota_add_start(dir, &info, msg_len, 1, NULL);
                     maildir_quota_add_end(&info, msg_len, 1);
              }
       }

       fclose(fpout);
       if (maildir_movetmpnew(createInfo.tmpname,
                            createInfo.newname))
       {
              unlink(createInfo.tmpname);
              maildir_tmpcreate_free(&createInfo);
              return;
       }
       maildir_tmpcreate_free(&createInfo);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int do_maildir_openquotafile ( struct maildirsize info,
const char *  filename,
const char *  newquota 
) [static]

Definition at line 116 of file maildirquota.c.

{
       char buf[5120];
       char *p;
       unsigned l;
       int n;
       int first;

       /*
       ** When setting a new quota, we don't care about the existing
       ** maildirsize.
       */

       if ((info->fd=(newquota ? open("/dev/null", O_RDWR):
                     maildir_safeopen(filename,
                                   O_RDWR|O_APPEND, 0))) < 0)
              return (0);   /* No quota */

       if (newquota)
       {
              parsequotastr(newquota, &info->quota);

              if (info->quota.nbytes == 0 &&
                  info->quota.nmessages == 0)
              {
                     close(info->fd);
                     info->fd= -1;
                     errno=EINVAL;
                     return (-1);
              }
              info->recalculation_needed=1;
              return (0);
       }

       p=buf;
       l=sizeof(buf);

       while (l)
       {
              n=read(info->fd, p, l);
              if (n < 0)
              {
                     close(info->fd);
                     info->fd= -1;
                     return (-1);
              }
              if (n == 0)   break;
              p += n;
              l -= n;
       }

       if (fstat(info->fd, &info->statbuf))      /* maildir too big */
       {
              close(info->fd);
              info->fd= -1;
              return (-1);
       }

       if (l == 0)   /*
                     ** maildirsize overflowed, still need to read its
                     ** quota
                     */
       {
              p[-1]=0;
              p=strchr(buf, '\n');
              if (p)
                     *p=0;
              parsequotastr(buf, &info->quota);
              info->recalculation_needed=1;
              return (0);
       }


       info->size.nbytes=0;
       info->size.nmessages=0;
       info->nlines=0;
       *p=0;
       p=buf;
       first=1;
       while (*p)
       {
              int64_t n=0;
              int c=0;
              char   *q=p;
              int    neg;

              while (*p)
                     if (*p++ == '\n')
                     {
                            p[-1]=0;
                            break;
                     }

              if (first)
              {
                     parsequotastr(q, &info->quota);
                     first=0;
                     continue;
              }

              while (*q && isspace((int)(unsigned char)*q))
                     ++q;

              neg=0;
              if (*q == '-')
              {
                     neg=1;
                     ++q;
              }

              if (DIG(*q))
              {
                     while (DIG(*q))
                     {
                            n=n*10 + (*q++ - '0');
                     }

                     if (neg)
                            n= -n;

                     neg=0;
                     while (*q && isspace((int)(unsigned char)*q))
                            ++q;

                     if (*q == '-')
                     {
                            neg=1;
                            ++q;
                     }
                     if (DIG(*q))
                     {
                            while (DIG(*q))
                            {
                                   c=c*10 + (*q++ - '0');
                            }

                            if (neg)
                                   c= -c;

                            info->size.nbytes += n;
                            info->size.nmessages += c;
                     }
              }

              ++ info->nlines;
       }
       if (info->size.nbytes < 0 ||
           info->size.nmessages < 0)
              info->recalculation_needed=1;
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int doaddquota ( struct maildirsize info,
int  maildirsize_fd,
int64_t  maildirsize_size,
int  maildirsize_cnt,
int  isnew 
) [static]

Definition at line 571 of file maildirquota.c.

{
       char   n[NUMBUFSIZE];
       char   buf[NUMBUFSIZE * 4 + 32 ];
       char *p;
       int cnt;

       buf[0]=0;

       if (isnew)
       {
              if (info->quota.nbytes > 0)
              {
                     char b[2];

                     b[0]=MDQUOTA_SIZE;
                     b[1]=0;

                     strcat(strcat(buf, libmail_str_int64_t(info->quota.nbytes, n)),
                            b);
              }

              if (info->quota.nmessages > 0)
              {
                     char b[2];

                     b[0]=MDQUOTA_COUNT;
                     b[1]=0;

                     if (buf[0] != 0)
                            strcat(buf, ",");

                     strcat(strcat(buf,
                                  libmail_str_size_t(info->quota.nmessages, n)),
                            b);
              }
              strcat(buf, "\n");
       }

       sprintf(buf + strlen(buf),
              "%12s ", libmail_str_int64_t(maildirsize_size, n));

       sprintf(buf + strlen(buf),
              "%12s\n", libmail_str_int64_t(maildirsize_cnt, n));

       p=buf;
       cnt=strlen(buf);

       while (cnt > 0)
       {
              int c=write( maildirsize_fd, p, cnt);

              if (c < 0)
                     return (-1);

              cnt -= c;
              p += c;
       }

       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int docheckquota ( struct maildirsize info,
int64_t  xtra_size,
int  xtra_cnt,
int *  percentage 
) [static]

Definition at line 402 of file maildirquota.c.

{
       char   *newmaildirsizename;
       int    maildirsize_fd;
       int64_t       maildirsize_size;
       unsigned maildirsize_cnt;

       time_t tm;
       time_t maxtime;
       DIR    *dirp;
       struct dirent *de;

       struct maildirquota new_quota;

       *percentage=0;

       if (info->fd < 0)    /* No quota */
              return (0);

       new_quota=info->size;

       new_quota.nbytes += xtra_size;
       new_quota.nmessages += xtra_cnt;

       if (!info->recalculation_needed &&
           checkQuota(&new_quota, &info->quota, percentage) == 0)
              return (0);   /* New size is under quota */

       /*
       ** Overquota, see if it's time to recalculate the quota anyway
       */

       time(&tm);
       if (!info->recalculation_needed &&
           info->nlines == 1 && tm < info->statbuf.st_mtime + 15*60)
              return (-1);


       maxtime=0;
       maildirsize_size=0;
       maildirsize_cnt=0;

       if (countcurnew(info->maildir,
                     &maxtime, &maildirsize_size, &maildirsize_cnt))
       {
              errno=EIO;
              return (-1);
       }

       dirp=opendir(info->maildir);
       while (dirp && (de=readdir(dirp)) != 0)
       {
              if (countsubdir(info->maildir, de->d_name,
                            &maxtime, &maildirsize_size,
                     &maildirsize_cnt))
              {
                     errno=EIO;
                     closedir(dirp);
                     return (-1);
              }
       }
       if (dirp)
       {
#if    CLOSEDIR_VOID
              closedir(dirp);
#else
              if (closedir(dirp))
              {
                     errno=EIO;
                     return (-1);
              }
#endif
       }

       newmaildirsizename=makenewmaildirsizename(info->maildir,
                                            &maildirsize_fd);
       if (!newmaildirsizename)
       {
              errno=EIO;
              return (-1);
       }

       if (doaddquota(info, maildirsize_fd, maildirsize_size,
              maildirsize_cnt, 1))
       {
              unlink(newmaildirsizename);
              free(newmaildirsizename);
              close(maildirsize_fd);
              errno=EIO;
              return (-1);
       }

       if (rename(newmaildirsizename, info->maildirsizefile))
       {
              unlink(newmaildirsizename);
              close(maildirsize_fd);
              errno=EIO;
              return (-1);
       }

       info->recalculation_needed=0;
       info->size.nbytes=maildirsize_size;
       info->size.nmessages=maildirsize_cnt;
       info->nlines=1;
       close(info->fd);
       info->fd=maildirsize_fd;

       tm=0;

       if (statcurnew(info->maildir, &tm))
       {
              errno=EIO;
              return (-1);
       }

       dirp=opendir(info->maildir);
       while (dirp && (de=readdir(dirp)) != 0)
       {
              if (statsubdir(info->maildir, de->d_name, &tm))
              {
                     errno=EIO;
                     closedir(dirp);
                     return (-1);
              }
       }
       if (dirp)
       {
#if    CLOSEDIR_VOID
              closedir(dirp);
#else
              if (closedir(dirp))
              {
                     errno=EIO;
                     return (-1);
              }
#endif
       }

       if (tm != maxtime)   /* Race condition, someone changed something */
       {
              info->recalculation_needed=1;
              info->nlines=0;
              errno=EAGAIN;
              return (-1);
       }

       *percentage=0;

       new_quota=info->size;

       new_quota.nbytes += xtra_size;
       new_quota.nmessages += xtra_cnt;

       return checkQuota(&new_quota, &info->quota, percentage);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int docount ( const char *  dir,
time_t *  dirstamp,
int64_t *  sizep,
unsigned *  cntp 
) [static]

Definition at line 747 of file maildirquota.c.

{
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;

              if (!maildirquota_countfile(n))
                     continue;

              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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_addquota ( struct maildirsize info,
int64_t  maildirsize_size,
int  maildirsize_cnt 
)

Definition at line 561 of file maildirquota.c.

{
       if (info->fd < 0)
              return (0);

       return (doaddquota(info, info->fd, maildirsize_size,
                        maildirsize_cnt, 0));
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_checkquota ( struct maildirsize info,
int64_t  xtra_size,
int  xtra_cnt 
)

Definition at line 385 of file maildirquota.c.

{
       int    dummy;

       return (docheckquota(info, xtra_size, xtra_cnt, &dummy));
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_closequotafile ( struct maildirsize info)

Definition at line 304 of file maildirquota.c.

{
       if (info->maildir)
              free (info->maildir);
       info->maildir=NULL;

       if (info->maildirsizefile)
              free (info->maildirsizefile);
       info->maildirsizefile=NULL;

       if (info->fd >= 0)
              close(info->fd);
       info->fd= -1;
}

Here is the caller graph for this function:

void maildir_deliver_quota_warning ( const char *  dir,
const int  percent,
const char *  msgquotafile 
)

Definition at line 1116 of file maildirquota.c.

{
       size_t l;
       char *p;
       struct stat   sb;

       /* If we delivered to a folder, dump the warning message into INBOX */

       l = strlen(dir)+sizeof("/maildirfolder");
       if ((p = malloc(l)) == 0)
              return;

       strcat(strcpy(p, dir), "/maildirfolder");

       /* If delivering to a folder, find quotawarn in its parent directory */

       if (stat(p, &sb) == 0)
       {
              strcat(strcpy(p, dir), "/..");
              maildir_deliver_quota_warning(p, percent, msgquotafile);
              free(p);
              return;
       }
       free(p);

       if (percent >= 0)
       {
              struct maildirsize info;

              if (maildir_openquotafile(&info, dir) == 0)
              {
                     if (maildir_readquota(&info) >= percent)
                     {
                            maildir_closequotafile(&info);
                            do_deliver_warning(msgquotafile, dir);
                            return;
                     }
                     maildir_closequotafile(&info);
              }
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_openquotafile ( struct maildirsize info,
const char *  maildir 
)

Definition at line 66 of file maildirquota.c.

{
       return (maildir_openquotafile_init(info, maildir, NULL));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int maildir_openquotafile_init ( struct maildirsize info,
const char *  maildir,
const char *  newquota 
) [static]

Definition at line 71 of file maildirquota.c.

{
       int rc;

       char   *buf=(char *)malloc(strlen(maildir)+sizeof("/maildirfolder"));

       memset(info, 0, sizeof(*info));

       info->fd= -1;

       if (!buf)
              return (-1);

       strcat(strcpy(buf, maildir), "/maildirfolder");
       if (stat(buf, &info->statbuf) == 0)       /* Go to parent */
       {
              strcat(strcpy(buf, maildir), "/..");

              rc=maildir_openquotafile_init(info, buf, newquota);
              free(buf);
              return rc;
       }

       info->maildir=strdup(maildir);

       if (!info->maildir)
       {
              free(buf);
              return (-1);
       }

       strcat(strcpy(info->maildirsizefile=buf, maildir), "/maildirsize");

       rc=do_maildir_openquotafile(info, buf, newquota);

       if (rc == 0)
              return (0);

       free(buf);
       free(info->maildir);
       return (rc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_quota_add_end ( struct maildirsize info,
int64_t  msgsize,
int  nmsgs 
)

Definition at line 906 of file maildirquota.c.

{
       maildir_addquota(info, msgsize, nmsgs);
       maildir_closequotafile(info);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_quota_add_start ( const char *  maildir,
struct maildirsize info,
int64_t  msgsize,
int  nmsgs,
const char *  newquota 
)

Definition at line 850 of file maildirquota.c.

{
       struct maildirquota mq;
       int i;

       if ( maildir_openquotafile(info, maildir))
              info->fd= -1;

       if (newquota != NULL)
       {
              parsequotastr(newquota, &mq);

              if ((mq.nbytes > 0 || mq.nmessages > 0) &&
                  (info->fd < 0 || info->quota.nbytes != mq.nbytes ||
                   info->quota.nmessages != mq.nmessages))
              {
                     if (info->fd < 0)
                     {
                            maildir_quota_set(maildir, newquota);
                            if (maildir_openquotafile(info, maildir))
                                   info->fd= -1;
                     }
                     else
                     {
                            info->quota=mq;
                            info->recalculation_needed=1;
                     }
              }
       }
       if (info->fd < 0)
              return (0);   /* No quota set on this maildir */

       for (i=0; i<5; i++)
       {
              int rc;

              rc=maildir_checkquota(info, msgsize, nmsgs);
              if (rc == 0)
                     return (0);

              if (errno != EAGAIN)
              {
                     maildir_closequotafile(info);
                     return (-1);
              }
       }
       maildir_closequotafile(info);

       /* Cannot recover from a race condition, just punt */

       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_quota_deleted ( const char *  maildir,
int64_t  nbytes,
int  nmsgs 
)

Definition at line 913 of file maildirquota.c.

{
       struct maildirsize info;

       if ( maildir_openquotafile(&info, maildir))
              return;

       maildir_checkquota(&info, nbytes, nmsgs); /* Cleanup */
       maildir_addquota(&info, nbytes, nmsgs);
       maildir_closequotafile(&info);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_quota_delundel_end ( struct maildirsize info,
int64_t  msgsize,
int  nmsgs 
)

Definition at line 956 of file maildirquota.c.

{
#if TRASHQUOTA
       return;
#else
       if (nmsgs < 0)
              return;

       maildir_quota_add_end(info, msgsize, nmsgs);
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_quota_delundel_start ( const char *  maildir,
struct maildirsize info,
int64_t  msgsize,
int  nmsgs 
)

Definition at line 939 of file maildirquota.c.

{
#if TRASHQUOTA
       return (0);
#else
       if (nmsgs < 0)
       {
              maildir_quota_deleted(maildir, msgsize, nmsgs);
              return (0);   /* Always allowed */
       }

       return maildir_quota_add_start(maildir, info, msgsize, nmsgs, NULL);
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_quota_recalculate ( const char *  maildir)

Definition at line 927 of file maildirquota.c.

{
       struct maildirsize info;

       if (maildir_openquotafile(&info, maildir))
              return;
       info.recalculation_needed=1;

       maildir_readquota(&info);
       maildir_closequotafile(&info);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_quota_set ( const char *  dir,
const char *  quota 
)

Definition at line 970 of file maildirquota.c.

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_readquota ( struct maildirsize info)

Definition at line 394 of file maildirquota.c.

{
       int    percentage=0;

       (void)docheckquota(info, 0, 0, &percentage);
       return (percentage);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildirquota_countfile ( const char *  n)

Definition at line 818 of file maildirquota.c.

{
#ifdef TRASHQUOTA

#else
       const char *nn=strrchr(n, '/');

       if (nn != NULL)
              n=nn+1;

       /* do not count msgs marked as deleted */

       for ( ; *n; n++)
       {
              if (n[0] != MDIRSEP[0] || n[1] != '2' ||
                  n[2] != ',')     continue;
              n += 3;
              while (*n >= 'A' && *n <= 'Z')
              {
                     if (*n == 'T')       return (0);
                     ++n;
              }
              break;
       }
#endif
       return (1);
}

Here is the caller graph for this function:

int maildirquota_countfolder ( const char *  folder)

Definition at line 799 of file maildirquota.c.

{
#ifdef TRASHQUOTA

#else

       if (strcmp(folder, "." TRASH) == 0 ||
           strcmp(folder, "." TRASH "/") == 0)
              return (0);

       for ( ; *folder; folder++)
              if (*folder == '/' &&
                  (strcmp(folder+1, "." TRASH) == 0 ||
                   strcmp(folder+1, "." TRASH "/") == 0))
                     return (0);
#endif
       return (1);
}

Here is the caller graph for this function:

static char * makenewmaildirsizename ( const char *  dir,
int *  fd 
) [static]

Definition at line 638 of file maildirquota.c.

{
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",
                     libmail_str_time_t(t, tbuf),
                     libmail_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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void parsequotastr ( const char *  quota,
struct maildirquota q 
) [static]

Definition at line 270 of file maildirquota.c.

{
       int64_t i;
       const char *quota_start = quota;

       q->nbytes=0;
       q->nmessages=0;

       while (quota && *quota)
       {
              if (!DIG(*quota))
              {
                     ++quota;
                     continue;
              }
              i=0;
              while (DIG(*quota))
                     i=i*10 + (*quota++ - '0');
              switch (*quota)      {
              case MDQUOTA_SIZE:
                     q->nbytes=i;
                     break;
              case MDQUOTA_COUNT:
                     q->nmessages=i;
                     break;
              default:
                     fprintf(stderr, "WARN: quota string '%s' not parseable\n",
                            quota_start);
                     break;
              }
       }
}

Here is the caller graph for this function:

static int statcurnew ( const char *  dir,
time_t *  maxtimestamp 
) [static]

Definition at line 671 of file maildirquota.c.

{
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);
}

Here is the caller graph for this function:

static int statsubdir ( const char *  dir,
const char *  subdir,
time_t *  maxtime 
) [static]

Definition at line 687 of file maildirquota.c.

{
char   *p;
int    n;

       if ( *subdir != '.' || strcmp(subdir, ".") == 0 ||
              strcmp(subdir, "..") == 0
#ifndef TRASHQUOTA
                            || strcmp(subdir, "." TRASH) == 0
#endif
              )
              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);
}

Here is the call graph for this function:

Here is the caller graph for this function: