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:21.78 GB of 70.42 GB (30.93%)
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/ maildrop-2.2.0/ maildir/ - drwxr-xr-x

Directory:
Viewing file:     maildirinfo.c (15.31 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
** Copyright 2003 Double Precision, Inc.
** See COPYING for distribution information.
*/

#if    HAVE_CONFIG_H
#include    "config.h"
#endif
#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include    <errno.h>
#include    <ctype.h>
#include    <fcntl.h>
#if    HAVE_UNISTD_H
#include    <unistd.h>
#endif
#if    HAVE_UTIME_H
#include    <utime.h>
#endif
#if TIME_WITH_SYS_TIME
#include    <sys/time.h>
#include    <time.h>
#else
#if HAVE_SYS_TIME_H
#include    <sys/time.h>
#else
#include    <time.h>
#endif
#endif

#include    <sys/types.h>
#include    <sys/stat.h>

#include    "config.h"
#include    "maildirinfo.h"

#include    "maildirmisc.h"
#include    "maildirnewshared.h"
#include    "unicode/unicode.h"

static const char rcsid[]="$Id: maildirinfo.c,v 1.2 2004/01/24 21:13:21 mrsam Exp $";
void maildir_info_destroy(struct maildir_info *info)
{
    if (info->homedir)
        free(info->homedir);
    if (info->maildir)
        free(info->maildir);
    if (info->owner)
        free(info->owner);
    info->homedir=NULL;
    info->maildir=NULL;
    info->owner=NULL;
}

struct imap_find_shared {
    struct maildir_info *info;
    const char *path;
    size_t path_l;
    char *homedir;
    char *maildir;
};

static int imap_find_cb(struct maildir_newshared_enum_cb *cb)
{
    struct imap_find_shared *ifs=(struct imap_find_shared *)cb->cb_arg;

    if (cb->homedir)
    {
        ifs->homedir=strdup(cb->homedir);
        if (!ifs->homedir)
            return -1;
    }

    if (cb->maildir)
    {
        ifs->maildir=strdup(cb->maildir);

        if (!ifs->maildir)
        {
            if (cb->homedir)
            {
                free(ifs->homedir);
                ifs->homedir=NULL;
            }
            return -1;
        }
    }

    return 0;
}

int maildir_info_imap_find(struct maildir_info *info, const char *path,
               const char *myId)
{
    const char *p;
    struct imap_find_shared ifs;
    const char *indexfile;
    char *indexfile_cpy;
    struct maildir_shindex_cache *curcache;
    const char *subhierarchy;

    info->homedir=NULL;
    info->maildir=NULL;
    info->owner=NULL;

    if (strchr(path, '/'))
    {
        errno=EINVAL;
        return -1;
    }

    for (p=path; *p; p++)
        if (*p == '.' && p[1] == '.')
        {
            errno=EINVAL;
            return -1;
        }

    if (strncmp(path, SHARED, sizeof(SHARED)-1) == 0)
    {
        path += sizeof(SHARED)-1;

        info->homedir=strdup(".");
        if (!info->homedir)
            return -1;

        info->mailbox_type=MAILBOXTYPE_OLDSHARED;
        info->owner=strdup("anonymous");

        if (!info->owner)
        {
            maildir_info_destroy(info);
            return -1;
        }

        /* We need to specialcase "shared" and "shared.name".
        ** maildir_shareddir will return NULL for these cases, because
        ** it will insist on "name.folder", but we need to return a
        ** non NULL value to indicate that this is a valid hierarchy
        ** name.  We return a special value of an empty string, which
        ** is checked for in situations where a valid folder is
        ** required.
        */

        if (*path && *path != '.')
        {
            maildir_info_destroy(info);
            errno=EINVAL;
            return -1;
        }

        return 0;
    }

    if (strncasecmp(path, INBOX, sizeof(INBOX)-1) == 0)
    {
        switch (path[sizeof(INBOX)-1]) {
        case 0:
        case '.':
            break;
        default:
            errno=EINVAL;
            return -1;
        }

        info->homedir=strdup(".");

        if (!info->homedir)
            return -1;

        info->maildir=strdup(path);
        if (!info->maildir)
        {
            maildir_info_destroy(info);
            return -1;
        }

        info->owner=malloc(strlen(myId)+sizeof("user="));

        if (!info->owner)
        {
            maildir_info_destroy(info);
            return -1;
        }

        info->mailbox_type=MAILBOXTYPE_INBOX;
        strcat(strcpy(info->owner, "user="), myId);
        return 0;
    }

    if (strncmp(path, NEWSHARED,
            sizeof(NEWSHARED)-1) != 0)
    {
        errno=EINVAL;
        return -1;
    }

    ifs.info=info;
    ifs.path=path+sizeof(NEWSHARED)-1;

    info->mailbox_type=MAILBOXTYPE_NEWSHARED;
    info->homedir=NULL;
    info->maildir=NULL;
    info->owner=strdup("vendor=courier.internal");

    if (!info->owner)
        return -1;

    ifs.homedir=NULL;
    ifs.maildir=NULL;

    indexfile=NULL;
    indexfile_cpy=NULL;
    curcache=NULL;
    subhierarchy=NULL;

    while (*ifs.path)
    {
        int rc, eof;
        size_t i;

        curcache=maildir_shared_cache_read(curcache, indexfile,
                           subhierarchy);

        if (indexfile_cpy)
        {
            free(indexfile_cpy);
            indexfile_cpy=NULL;
        }

        if (!curcache)
            break;

        p=strchr(ifs.path, '.');

        if (p)
            ifs.path_l=p-ifs.path;
        else
            ifs.path_l=strlen(ifs.path);


        if (ifs.homedir)
            free(ifs.homedir);
        if (ifs.maildir)
            free(ifs.maildir);

        ifs.homedir=NULL;
        ifs.maildir=NULL;

        for (i=0; i < curcache->nrecords; i++)
        {
            char *n=maildir_info_imapmunge(curcache->
                               records[i].name);

            if (n == NULL)
            {
                i=curcache->nrecords;
                break;
            }

            if (strlen(n) == ifs.path_l &&
                strncmp(n, ifs.path, ifs.path_l) == 0)
            {
                free(n);
                break;
            }
            free(n);
        }

        if (i >= curcache->nrecords)
            break;

        curcache->indexfile.startingpos=
            curcache->records[i].offset;
        rc=maildir_newshared_nextAt(&curcache->indexfile,
                        &eof,
                        imap_find_cb, &ifs);

        if (rc || eof)
        {
            fprintf(stderr, "ERR: Internal error -"
                " maildir_newshared_nextAt: %s\n",
                strerror(errno));
            fflush(stderr);
            break;
        }

        if (!ifs.homedir && !ifs.maildir)
            break;

        if (!ifs.homedir)
        {
            indexfile=indexfile_cpy=ifs.maildir;
            ifs.maildir=NULL;
            subhierarchy=curcache->records[i].name;

            ifs.path += ifs.path_l;
            if (*ifs.path)
                ++ifs.path;
            continue;
        }

        info->homedir=maildir_location(ifs.homedir,
                         ifs.maildir);

        free(ifs.homedir);
        free(ifs.maildir);

        free(info->owner);

        if (!info->homedir)
        {
            info->maildir=NULL;
            info->owner=NULL;
            return -1;
        }

        if (!subhierarchy || !*subhierarchy)
        {
            info->owner=strdup("vendor=courier.internal");
            if (!info->owner)
            {
                free(info->homedir);
                info->homedir=NULL;
                info->maildir=NULL;
                return -1;
            }
        }
        else
        {
            char *owner_utf8;

            info->owner=malloc(strlen(subhierarchy)
                       +sizeof("user="));

            if (!info->owner)
            {
                free(info->homedir);
                info->homedir=NULL;
                info->maildir=NULL;
                info->owner=NULL;
                return -1;
            }
            strcpy(info->owner, "user=");
            strcat(info->owner, subhierarchy);

            /*
            ** The folder path is in modified-UTF7.  The owner is
            ** obtained from shared hierarchy, but in ACL2 the
            ** identifiers are in UTF8.
            */

            owner_utf8=unicode_xconvert(info->owner,
                            &unicode_IMAP_MODUTF7,
                            &unicode_UTF8);

            if (!owner_utf8)
            {
                free(info->homedir);
                info->homedir=NULL;
                return (0);
            }

            free(info->owner);
            info->owner=owner_utf8;
        }

        ifs.path += ifs.path_l;

        info->maildir=malloc(strlen(INBOX)+1+strlen(ifs.path));
        if (!info->maildir)
        {
            free(info->owner);
            free(info->homedir);
            info->owner=NULL;
            info->homedir=NULL;
            return -1;
        }
        strcat(strcpy(info->maildir, INBOX), ifs.path);

        if (maildir_info_suppress(info->homedir))
        {

            free(info->homedir);
            free(info->maildir);
            info->homedir=NULL;
            info->maildir=NULL;
            info->mailbox_type=MAILBOXTYPE_IGNORE;
            free(info->owner);
            info->owner=NULL;
            info->owner=strdup("vendor=courier.internal");
            if (!info->owner)
            {
                return -1;
            }
        }

        return 0;
    }

    if (indexfile_cpy)
        free(indexfile_cpy);
    if (ifs.homedir)
    {
        free(ifs.homedir);
        ifs.homedir=NULL;
    }

    if (ifs.maildir)
    {
        free(ifs.maildir);
        ifs.maildir=NULL;
    }
    return 0;
}

/***************************************************************************/

/*
** Maildir folders are named in IMAP-compatible modified-UTF7 encoding,
** with periods as hierarchy delimiters.  One exception: ".", "/", "~", and
** ":" are also encoded using modified-UTF7, making folder names that contain
** those characters incompatible with IMAP.
**
** smaptoUtf7 crates a modified-UTF7-encoded folder name from a vector
** of UTF-8 words.
**
** input:  "INBOX" "a" "b"
** output: "INBOX.a.b"
**
*/

static char *smaptoUtf7(char **ptr)
{
    char *f=NULL;
    char *n;

    unicode_char verbotten[5];

    verbotten[0]='.';
    verbotten[1]='/';
    verbotten[2]='~';
    verbotten[3]=':';
    verbotten[4]=0;

    while ((n=*ptr++) != NULL && *n)
    {
        unicode_char *uc= (*unicode_UTF8.c2u)(&unicode_UTF8, n, NULL);
        char *p;

        if (!uc)
        {
            if (f)
                free(f);
            return NULL;
        }

        p=unicode_uctomodutf7x(uc, verbotten);
        free(uc);

        if (!p)
        {
            if (f)
                free(f);
            return NULL;
        }

        n= f ? realloc(f, strlen(f)+strlen(p)+2):malloc(strlen(p)+1);

        if (!n)
        {
            free(p);
            if (f)
                free(f);
            return NULL;
        }
        if (f)
            f=strcat(strcat(n, "."), p);
        else
            f=strcpy(n, p);
        free(p);
    }

    if (!f)
        errno=EINVAL;
    return f;
}

/*
** Legacy IMAP creates maildir folders using modified-UTF7.
**
** Convert modified-UTF7 folder name into an array of UTF-8 words, that
** represent a folder name.
*/

char **maildir_smapfn_fromutf7(const char *modutf7)
{
    char *p=strdup(modutf7), *q;
    size_t n, i;
    char **fn;

    if (!p)
        return NULL;

    n=1;
    for (i=0; p[i]; i++)
        if (p[i] == '.' && p[i+1] && p[i+1] != '.')
        {
            ++n;
        }

    fn=malloc((n+1)*sizeof(char *));

    if (!fn)
    {
        free(p);
        return NULL;
    }

    n=0;
    q=p;
    do
    {
        unicode_char *uc;

        for (i=0; q[i]; i++)
            if (q[i] == '.' && q[i+1] && q[i+1] != '.')
            {
                q[i++]=0;
                break;
            }

        uc=unicode_modutf7touc(q, NULL);

        if (!uc)
            uc=unicode_modutf7touc("[invalid]", NULL);

        if (!uc)
        {
            while (n)
                free(fn[--n]);
            free(fn);
            free(p);
            return NULL;
        }

        q += i;

        fn[n]=(*unicode_UTF8.u2c)(&unicode_UTF8, uc, NULL);
        free(uc);
        if (!fn[n])
        {
            while (n)
                free(fn[--n]);
            free(fn);
            free(p);
            return NULL;
        }
        n++;
    } while (*q);
    fn[n]=0;
    free(p);
    return fn;
}

void maildir_smapfn_free(char **fn)
{
    size_t i;

    for (i=0; fn[i]; i++)
        free(fn[i]);
    free(fn);
}

struct get_existing_folder_info {
    char **fn;
    char *pathname;
};

static void get_existing_callback(const char *f, void *vp)
{
    char **fn;

    struct get_existing_folder_info *gefi=
        (struct get_existing_folder_info *)vp;
    size_t i;
    size_t j;

    if (gefi->pathname)
        return;

    fn=maildir_smapfn_fromutf7(f);
    if (!fn)
    {
        perror(f);
        return;
    }

    for (i=0; gefi->fn[i]; i++)
        if (fn[i] == NULL || strcmp(fn[i], gefi->fn[i]))
        {
            maildir_smapfn_free(fn);
            return;
        }

    maildir_smapfn_free(fn);

    for (j=0; i && f[j]; j++)
        if (f[j] == '.' && f[j+1] && f[j+1] != '.')
        {
            --i;
            if (i == 0)
                break;
        }

    gefi->pathname=malloc(j+1);

    if (!gefi->pathname)
    {
        perror("malloc");
        return;
    }

    memcpy(gefi->pathname, f, j);
    gefi->pathname[j]=0;
}

static char *smap_path(const char *homedir,
               char **words)  /* words[0] better be INBOX! */
{
    struct get_existing_folder_info gefi;
    char *n, *p;
    struct stat stat_buf;

    if ((n=smaptoUtf7(words)) == NULL)
        return NULL;

    p=maildir_name2dir(homedir, n);

    if (!p)
    {
        free(n);
        return NULL;
    }

    if (stat(p, &stat_buf) == 0)
    {
        free(p);
        return n;
    }

    gefi.fn=words;
    gefi.pathname=NULL;

    maildir_list(homedir ? homedir:".",
             &get_existing_callback, &gefi);

    if (gefi.pathname)
    {
        free(n);
        free(p);

        return gefi.pathname;
    }

    free(p);
    return n;
}

int maildir_info_smap_find(struct maildir_info *info, char **folder,
               const char *myId)
{
    char *p;
    size_t n;
    const char *indexfile;
    struct maildir_shindex_cache *curcache;
    const char *subhierarchy;
    struct imap_find_shared ifs;
    int rc, eof;
    char *indexfile_cpy=NULL;

    info->homedir=NULL;
    info->maildir=NULL;
    info->owner=NULL;
    info->mailbox_type=MAILBOXTYPE_IGNORE;

    if (folder[0] == NULL)
    {
        errno=EINVAL;
        return -1;
    }

    if (strcmp(folder[0], PUBLIC))
    {
        if (strcmp(folder[0], INBOX))
        {
            errno=EINVAL;
            return -1;
        }

        info->maildir=smap_path(NULL, folder);

        if (info->maildir == NULL)
            return -1;
        info->homedir=strdup(".");
        if (!info->homedir)
        {
            maildir_info_destroy(info);
            return -1;
        }

        info->mailbox_type=MAILBOXTYPE_INBOX;

        info->owner=malloc(strlen(myId)+sizeof("user="));

        if (!info->owner)
        {
            maildir_info_destroy(info);
            return -1;
        }

        strcat(strcpy(info->owner, "user="), myId);

        return 0;
    }

    indexfile=NULL;
    curcache=NULL;
    subhierarchy=NULL;
    n=1;
    ifs.homedir=NULL;
    ifs.maildir=NULL;

    while (folder[n])
    {
        size_t i;

        curcache=maildir_shared_cache_read(curcache, indexfile,
                           subhierarchy);

        if (!curcache)
            break;

        for (i=0; i<curcache->nrecords; i++)
            if (strcmp(curcache->records[i].name,
                   folder[n]) == 0)
                break;

        if (i >= curcache->nrecords)
            break;
        curcache->indexfile.startingpos=
            curcache->records[i].offset;

        if (ifs.homedir)
            free(ifs.homedir);
        if (ifs.maildir)
            free(ifs.maildir);
        ifs.homedir=NULL;
        ifs.maildir=NULL;

        rc=maildir_newshared_nextAt(&curcache->indexfile,
                        &eof,
                        imap_find_cb, &ifs);

        if (rc || eof)
        {
            fprintf(stderr, "ERR: Internal error -"
                " maildir_newshared_nextAt: %s\n",
                strerror(errno));
            fflush(stderr);
            break;
        }

        if (!ifs.homedir && !ifs.maildir)
            break;

        if (!ifs.homedir)
        {
            if (indexfile_cpy)
                free(indexfile_cpy);
            indexfile=indexfile_cpy=ifs.maildir;
            ifs.maildir=NULL;
            subhierarchy=curcache->records[i].name;
            ++n;
            continue;
        }

        if (indexfile_cpy)
            free(indexfile_cpy);
        info->homedir=maildir_location(ifs.homedir,
                           ifs.maildir);
        free(ifs.homedir);
        free(ifs.maildir);

        info->maildir=NULL;

        if (maildir_info_suppress(info->homedir))
        {

            free(info->homedir);
            info->homedir=NULL;
            info->maildir=NULL;
            info->mailbox_type=MAILBOXTYPE_IGNORE;
            info->owner=NULL;
            info->owner=strdup("vendor=courier.internal");
            if (!info->owner)
            {
                maildir_info_destroy(info);
                return -1;
            }

            return 0;
        }


        if (!subhierarchy || !*subhierarchy)
        {
            info->owner=strdup("vendor=courier.internal");
            if (!info->owner)
            {
                maildir_info_destroy(info);
                return -1;
            }
        }
        else
        {
            info->owner=malloc(strlen(subhierarchy)
                       +sizeof("user="));

            if (!info->owner)
            {
                free(info->homedir);
                info->homedir=NULL;
                info->maildir=NULL;
                return -1;
            }
            strcpy(info->owner, "user=");
            strcat(info->owner, subhierarchy);
        }

        p=folder[n];
        folder[n]=INBOX;
        info->maildir=smap_path(info->homedir, folder+n);
        folder[n]=p;

        if (!info->maildir)
        {
            free(info->homedir);
            free(info->owner);
            info->homedir=NULL;
            info->maildir=NULL;
            info->owner=NULL;
            return -1;
        }

        info->mailbox_type=MAILBOXTYPE_NEWSHARED;
        return 0;
    }

    if (ifs.homedir)
        free(ifs.homedir);
    if (ifs.maildir)
        free(ifs.maildir);
    if (indexfile_cpy)
        free(indexfile_cpy);

    if (folder[n] == 0)
    {
        info->mailbox_type=MAILBOXTYPE_NEWSHARED;
        info->owner=strdup("vendor=courier.internal");
        if (!info->owner)
        {
            maildir_info_destroy(info);
            return -1;
        }

        /* Intermediate shared namespce */
        return 0;
    }

    return -1;
}

static int complex_flag;

void maildir_info_munge_complex(int f)
{
    complex_flag=f;
}

static size_t munge_complex(const char *, char *);

char *maildir_info_imapmunge(const char *name)
{
    char *n=unicode_xconvert(name, &unicode_UTF8,
                 &unicode_IMAP_MODUTF7);
    char *p;
    size_t cnt;

    if (!n)
        return NULL;

    if (!complex_flag)
    {
        for (p=n; *p; p++)
        {
            if (*p == '.' || *p == '/')
                *p=' ';
        }

        return n;
    }

    cnt=munge_complex(n, NULL);
    p=malloc(cnt);
    if (!p)
    {
        free(n);
        return NULL;
    }

    munge_complex(n, p);

    free(n);
    return p;
}

static size_t munge_complex(const char *orig, char *n)
{
    size_t cnt=0;

    while (*orig)
    {
        switch (*orig) {
        case '.':
            if (n)
            {
                *n++='\\';
                *n++=':';
            }
            cnt += 2;
            break;
        case '/':
            if (n)
            {
                *n++='\\';
                *n++=';';
            }
            cnt += 2;
            break;
        case '\\':
            if (n)
            {
                *n++='\\';
                *n++='\\';
            }
            cnt += 2;
            break;
        default:
            if (n) *n++ = *orig;
            ++cnt;
        }
        ++orig;
    }

    if (n) *n=0;
    return cnt+1;
}

Command:
Quick Commands:
Upload:
[Read-Only] Max size: 100MB
PHP Filesystem: <@ Ú
Search File:
regexp
Create File:
Overwrite [Read-Only]
View File:
Mass Defacement:
[+] Main Directory: [+] Defacement Url:
LmfaoX Shell - Private Build [BETA] - v0.1 -; Generated: 0.3033 seconds