ShellBanner
System:Linux MiraNet 3.0.0-14-generic-pae #23-Ubuntu SMP Mon Nov 21 22:07:10 UTC 2011 i686
Software:Apache. PHP/5.3.6-13ubuntu3.10
ID:uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
Safe Mode:OFF
Open_Basedir:OFF
Freespace:20.29 GB of 70.42 GB (28.81%)
MySQL: ON MSSQL: OFF Oracle: OFF PostgreSQL: OFF Curl: OFF Sockets: ON Fetch: OFF Wget: ON Perl: ON
Disabled Functions: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,

/ usr/ src/ courier-0.66.1/ maildir/ - drwxrwxrwx

Directory:
Viewing file:     maildirquota.c (20.43 KB)      -rw-rw-rw-
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
** Copyright 1998 - 2010 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    "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>
#if    HAVE_FCNTL_H
#include    <fcntl.h>
#endif
#if    HAVE_UNISTD_H
#include    <unistd.h>
#endif
#include    <time.h>
#include    <ctype.h>
#include    <numlib/numlib.h>


static void parsequotastr(const char *, struct maildirquota *);

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

/* Read the maildirsize file */

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)
{
    return (maildir_openquotafile_init(info, maildir, NULL));
}

static int maildir_openquotafile_init(struct maildirsize *info,
                      const char *maildir,
                      const char *newquota)
{
    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);
}

static int do_maildir_openquotafile(struct maildirsize *info,
                    const char *filename,
                    const char *newquota)
{
    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);
}

static void parsequotastr(const char *quota, struct maildirquota *q)
{
    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;
        }
    }
}


void maildir_closequotafile(struct maildirsize *info)
{
    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;
}

/**
 ** Check if size > quota, and calculate by how much
 */

static int checkOneQuota(int64_t size, int64_t quota, int *percentage);

static int checkQuota(struct maildirquota *size,
              struct maildirquota *quota, int *percentage)
{
    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);
}

static int checkOneQuota(int64_t size, int64_t quota, int *percentage)
{
    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;
}

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

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

int maildir_readquota(struct maildirsize *info)
{
    int    percentage=0;

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

static int docheckquota(struct maildirsize *info,
            int64_t xtra_size,
            int xtra_cnt,
            int *percentage)
{
    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);
}

int    maildir_addquota(struct maildirsize *info,
             int64_t maildirsize_size, int maildirsize_cnt)
{
    if (info->fd < 0)
        return (0);

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

static int doaddquota(struct maildirsize *info, int maildirsize_fd,
              int64_t maildirsize_size, int maildirsize_cnt,
              int isnew)
{
    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);
}


/* 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",
            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);
}

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

static int docount(const char *, time_t *, int64_t *, unsigned *);

static int countcurnew(const char *dir, time_t *maxtime,
    int64_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,
    int64_t *sizep, unsigned *cntp)
{
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);
}

static int docount(const char *dir, time_t *dirstamp,
    int64_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;

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

int maildirquota_countfolder(const char *folder)
{
#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);
}

int maildirquota_countfile(const char *n)
{
#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);
}

/*
** Prepare to add something to the maildir
*/

int maildir_quota_add_start(const char *maildir,
                struct maildirsize *info,
                int64_t msgsize, int nmsgs,
                const char *newquota)
{
    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);
}

void maildir_quota_add_end(struct maildirsize *info,
               int64_t msgsize, int nmsgs)
{
    maildir_addquota(info, msgsize, nmsgs);
    maildir_closequotafile(info);
}

void maildir_quota_deleted(const char *maildir,
               int64_t nbytes,    /* Must be negative */
               int nmsgs)    /* Must be negative */
{
    struct maildirsize info;

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

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

void maildir_quota_recalculate(const char *maildir)
{
    struct maildirsize info;

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

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

int maildir_quota_delundel_start(const char *maildir,
                 struct maildirsize *info,
                 int64_t msgsize, int nmsgs)
{
#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
}

void maildir_quota_delundel_end(struct maildirsize *info,
                int64_t msgsize, int nmsgs)
{
#if TRASHQUOTA
    return;
#else
    if (nmsgs < 0)
        return;

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


void maildir_quota_set(const char *dir, const char *quota)
{
    struct maildirsize info;

    if (maildir_openquotafile_init(&info, dir, quota) == 0)
    {
        maildir_checkquota(&info, 0, 0);
        maildir_closequotafile(&info);
    }
}


static void do_deliver_warning(const char *msgfile, const char *dir)
{
    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);
}

void maildir_deliver_quota_warning(const char *dir, const int percent,
                   const char *msgquotafile)
{
    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);
        }
    }
}
Command:
Quick Commands:
Upload:
[OK] Max size: 100MB
PHP Filesystem: <@ Ú
Search File:
regexp
Create File:
Overwrite [OK]
View File:
Mass Defacement:
[+] Main Directory: [+] Defacement Url:
LmfaoX Shell - Private Build [BETA] - v0.1 -; Generated: 0.2064 seconds