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:23.51 GB of 70.42 GB (33.38%)
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/ imap/ - drwxrwxrwx

Directory:
Viewing file:     mailboxlist.c (20.61 KB)      -rw-rw-rw-
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
** Copyright 1998 - 2007 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_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
#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    "imaptoken.h"
#include    "imapwrite.h"
#include    "imapscanclient.h"

#include    "mysignal.h"
#include    "imapd.h"
#include    "fetchinfo.h"
#include    "searchinfo.h"
#include    "storeinfo.h"
#include    "mailboxlist.h"

#include    "maildir/config.h"
#include    "maildir/maildirmisc.h"
#include    "maildir/maildiraclt.h"
#include    "maildir/maildirnewshared.h"
#include    "maildir/maildirinfo.h"
#include    "unicode/unicode.h"
#include    "courierauth.h"


static const char hierchs[]={HIERCH, 0};

extern char *decode_valid_mailbox(const char *, int);
extern dev_t homedir_dev;
extern ino_t homedir_ino;
/*
        LIST MAILBOXES
*/

static int do_mailbox_list(int do_lsub, char *qq, int isnullname,
               int (*callback_func)(const char *hiersep,
                        const char *mailbox,
                        int flags,
                        void *void_arg),
               void *void_arg);

static int shared_index_err_reported=0;

const char *maildir_shared_index_file()
{
    static char *filenamep=NULL;

    if (filenamep == NULL)
    {
        const char *p=getenv("IMAP_SHAREDINDEXFILE");

        if (p && *p)
        {
            const char *q=auth_getoptionenv("sharedgroup");

            if (!q) q="";

            filenamep=malloc(strlen(p)+strlen(q)+1);

            if (!filenamep)
                write_error_exit(0);

            strcat(strcpy(filenamep, p), q);
        }
    }

    if (filenamep && !shared_index_err_reported) /* Bitch just once */
    {
        struct stat stat_buf;

        shared_index_err_reported=1;
        if (stat(filenamep, &stat_buf))
        {
            fprintf(stderr, "ERR: ");
            perror(filenamep);
        }
    }

    return filenamep;
}

/*
**    IMAP sucks.  Here's why.
*/


int mailbox_scan(const char *reference, const char *name,
         int list_options,
         int (*callback_func)(const char *hiersep,
                      const char *mailbox,
                      int flags,
                      void *void_arg),
         void *void_arg)
{
    char    *pattern, *p;
    int    nullname= *name == 0;
    int    rc;

    pattern=malloc(strlen(reference)+strlen(name)+2);

    strcpy(pattern, reference);

    p=strrchr(pattern, HIERCH);
    if (p && p[1] == 0)    *p=0; /* Strip trailing . for now */
    if (*pattern)
    {
        struct maildir_info mi;

        if (maildir_info_imap_find(&mi, pattern,
                       getenv("AUTHENTICATED")))
        {
            free(pattern);
            return (0); /* Invalid reference */
        }
        maildir_info_destroy(&mi);
    }

    /* Combine reference and name. */
    if (*pattern && *name)
        strcat(pattern, hierchs);
    strcat(pattern, name);

    if (name && *name)
    {
    char *s=strrchr(pattern, HIERCH);

        if (s && s[1] == 0)    *s=0;    /* strip trailing . */

    }

    /* Now, do the list */

    rc=do_mailbox_list(list_options, pattern, nullname,
               callback_func, void_arg);
    free(pattern);
    return (rc);
}

static int match_mailbox(char *, char *, int flags);
static void match_mailbox_prep(char *);

/* Check if a folder has any new messages */

static int hasnewmsgs2(const char *dir)
{
DIR    *dirp=opendir(dir);
struct    dirent *de;

    while (dirp && (de=readdir(dirp)) != 0)
    {
    char    *p;

        if (de->d_name[0] == '.')    continue;
        p=strrchr(de->d_name, MDIRSEP[0]);
        if (p == 0 || strncmp(p, MDIRSEP "2,", 3) ||
            strchr(p, 'S') == 0)
        {
            closedir(dirp);
            return (1);
        }
    }
    if (dirp)    closedir(dirp);
    return (0);
}

static int hasnewmsgs(const char *folder)
{
char *dir=decode_valid_mailbox(folder, 0);
char *subdir;

    if (!dir)    return (0);

    if (is_sharedsubdir(dir))
        maildir_shared_sync(dir);

    subdir=malloc(strlen(dir)+sizeof("/cur"));
    if (!subdir)    write_error_exit(0);
    strcat(strcpy(subdir, dir), "/new");
    if (hasnewmsgs2(subdir))
    {
        free(subdir);
        free(dir);
        return (1);
    }

    strcat(strcpy(subdir, dir), "/cur");
    if (hasnewmsgs2(subdir))
    {
        free(subdir);
        free(dir);
        return (1);
    }

    free(subdir);
    free(dir);
    return (0);
}

/* Each folder is listed with the \Noinferiors tag.  Then, for every subfolder
** we've seen, we need to output a listing for all the higher-level hierarchies
** with a \Noselect tag.  Therefore, we need to keep track of all the
** hierarchies we've seen so far.
*/

struct hierlist {
    struct hierlist *next;
    int flag;
    char *hier;
    } ;

static int add_hier(struct hierlist **h, const char *s)
{
struct hierlist *p;

    for (p= *h; p; p=p->next)
        if (strcmp(p->hier, s) == 0)    return (1);
            /* Seen this one already */

    if ((p=(struct hierlist *)
        malloc( sizeof(struct hierlist)+1+strlen(s))) == 0)
            /* HACK!!!! */
        write_error_exit(0);
    p->flag=0;
    p->hier=(char *)(p+1);
    strcpy(p->hier, s);
    p->next= *h;
    *h=p;
    return (0);
}

static struct hierlist *search_hier(struct hierlist *h, const char *s)
{
struct hierlist *p;

    for (p= h; p; p=p->next)
        if (strcmp(p->hier, s) == 0)    return (p);
    return (0);
}

static void hier_entry(char *folder,
               struct hierlist **hierarchies);

static int has_hier_entry(char *folder,
              struct hierlist **hierarchies);

static void folder_entry(char *folder, char *pattern,
             int list_options,
             struct hierlist **folders,
             struct hierlist **hierarchies)
{
    size_t i;
    size_t folder_l=strlen(folder);

    int need_add_hier;
    int need_add_folders;

    match_mailbox_prep(folder);

    /* Optimize away folders we don't care about */

    for (i=0; pattern[i]; i++)
    {
        if ((!(list_options & LIST_CHECK1FOLDER)) &&
            (pattern[i] == '%' || pattern[i] == '*'))
        {
            while (i)
            {
                if (pattern[i] == HIERCH)
                    break;
                --i;
            }
            break;
        }
    }

    if (folder_l <= i)
    {
        if (memcmp(folder, pattern, folder_l))
            return;

        if (folder_l != i && pattern[folder_l] != HIERCH)
            return;
    }
    else if (i)
    {
        if (memcmp(folder, pattern, i))
            return;
        if (folder[i] != HIERCH)
            return;
    }

    need_add_folders=0;

    if (match_mailbox(folder, pattern, list_options) == 0)
        need_add_folders=1;

    need_add_hier=0;
    if (!has_hier_entry(folder, hierarchies))
        need_add_hier=1;

    if (!need_add_folders && !need_add_hier)
        return; /* Nothing to do */

    {
        CHECK_RIGHTSM(folder, have_rights, ACL_LOOKUP);

        if (!have_rights[0])
            return;
    }

    if (need_add_folders)
        (void) add_hier(folders, folder);

    if (need_add_hier)
        hier_entry(folder, hierarchies);
}

static void hier_entry(char *folder,
               struct hierlist **hierarchies)
{
    unsigned i;

    for (i=0; folder[i]; i++)
    {
        if (folder[i] != HIERCH)    continue;
        folder[i]=0;
        (void)add_hier(hierarchies, folder);
        folder[i]=HIERCH;
    }
}

static int has_hier_entry(char *folder,
              struct hierlist **hierarchies)
{
    unsigned i;

    for (i=0; folder[i]; i++)
    {
        if (folder[i] != HIERCH)    continue;
        folder[i]=0;
        if (!search_hier(*hierarchies, folder))
        {
            folder[i]=HIERCH;
            return (0);
        }
        folder[i]=HIERCH;
    }
    return (1);
}

struct list_sharable_info {
    char *pattern;
    struct hierlist **folders, **hierarchies;
    int flags;
    int (*callback_func)(const char *hiersep,
                 const char *mailbox,
                 int flags,
                 void *void_arg);
    void *cb_arg;
    } ;

static void list_sharable(const char *n,
    void *voidp)
{
struct list_sharable_info *ip=(struct list_sharable_info *)voidp;
char    *p=malloc(strlen(n)+sizeof("shared."));

    if (!p)    write_error_exit(0);

    strcat(strcpy(p, "shared."), n);

    folder_entry(p, ip->pattern, ip->flags,
             ip->folders, ip->hierarchies);

    free(p);
}

static void list_subscribed(char *hier,
                int flags,
                struct hierlist **folders,
                struct hierlist **hierarchies)
{
char    buf[BUFSIZ];
FILE    *fp;

    fp=fopen(SUBSCRIBEFILE, "r");
    if (fp)
    {
        while (fgets(buf, sizeof(buf), fp) != 0)
        {
            char *q=strchr(buf, '\n');

            if (q)    *q=0;

            if (*hier == '#')
            {
                if (*buf != '#')
                    continue;
            }
            else
            {
                if (*buf == '#')
                    continue;
            }

            folder_entry(buf, hier, flags,
                     folders, hierarchies);
        }
        fclose(fp);
    }
}

static void maildir_scan(const char *inbox_dir,
             const char *inbox_name,
             struct list_sharable_info *shared_info)
{
    DIR    *dirp;
    struct    dirent *de;

    /* Scan maildir, looking for .subdirectories */

    dirp=opendir(inbox_dir && inbox_dir ? inbox_dir:".");
    while (dirp && (de=readdir(dirp)) != 0)
    {
    char    *p;

        if (de->d_name[0] != '.' ||
            strcmp(de->d_name, "..") == 0)
            continue;

        if ((p=malloc(strlen(de->d_name)+strlen(inbox_name)+10)) == 0)
                    /* A bit too much, that's OK */
            write_error_exit(0);

        strcpy(p, inbox_name);

        if (strcmp(de->d_name, "."))
            strcat(p, de->d_name);

        folder_entry(p, shared_info->pattern, shared_info->flags,
                 shared_info->folders,
                 shared_info->hierarchies);
        free(p);
    }

    if (dirp)    closedir(dirp);
}

/* List the #shared hierarchy */

struct list_newshared_info {
    const char *acc_pfix;
    const char *skipped_pattern;
    struct list_sharable_info *shared_info;
    struct maildir_shindex_cache *parentCache;
    int dorecurse;
};

static int list_newshared_cb(struct maildir_newshared_enum_cb *cb);
static int list_newshared_skipcb(struct maildir_newshared_enum_cb *cb);
static int list_newshared_skiplevel(struct maildir_newshared_enum_cb *cb);

static int list_newshared_shortcut(const char *skipped_pattern,
                   struct list_sharable_info *shared_info,
                   const char *current_namespace,
                   struct maildir_shindex_cache *parentCache,
                   const char *indexfile,
                   const char *subhierarchy);

static int list_newshared(const char *skipped_pattern,
              struct list_sharable_info *shared_info)
{
    return list_newshared_shortcut(skipped_pattern, shared_info,
                       NEWSHARED,
                       NULL, NULL, NULL);
}

static int list_newshared_shortcut(const char *skipped_pattern,
                   struct list_sharable_info *shared_info,
                   const char *acc_pfix,
                   struct maildir_shindex_cache *parentCache,
                   const char *indexfile,
                   const char *subhierarchy)
{
    struct list_newshared_info lni;
    int rc;
    struct maildir_shindex_cache *curcache=NULL;

    lni.acc_pfix=acc_pfix;
    lni.skipped_pattern=skipped_pattern;
    lni.shared_info=shared_info;
    lni.dorecurse=1;

    /* Try for some common optimization, to avoid expanding the
    ** entire #shared hierarchy, taking advantage of the cache list.
    */

    for (;;)
    {
        const char *p;
        size_t i;
        char *q;
        int eof;

        if (strcmp(skipped_pattern, "%") == 0)
        {
            lni.dorecurse=0;
            break;
        }

        if (strncmp(skipped_pattern, "%" HIERCHS,
                sizeof("%" HIERCHS)-1) == 0)
        {
            curcache=maildir_shared_cache_read(parentCache,
                               indexfile,
                               subhierarchy);
            if (!curcache)
                return 0;

            lni.acc_pfix=acc_pfix;
            lni.skipped_pattern=skipped_pattern
                + sizeof("%" HIERCHS)-1;
            lni.parentCache=curcache;

            for (i=0; i<curcache->nrecords; i++)
            {
                if (i == 0)
                {
                    curcache->indexfile.startingpos=0;
                    rc=maildir_newshared_nextAt(&curcache->indexfile,
                                    &eof,
                                    list_newshared_skiplevel,
                                    &lni);
                }
                else
                    rc=maildir_newshared_next(&curcache->indexfile,
                                  &eof,
                                  list_newshared_skiplevel,
                                  &lni);

                if (rc || eof)
                {
                    fprintf(stderr, "ERR:maildir_newshared_next failed: %s\n",
                        strerror(errno));
                    break;
                }
            }
            return 0;
        }

        for (p=skipped_pattern; *p; p++)
            if (*p == HIERCH ||
                ((lni.shared_info->flags & LIST_CHECK1FOLDER) == 0
                 && (*p == '*' || *p == '%')))
                break;

        if (*p && *p != HIERCH)
            break;

        curcache=maildir_shared_cache_read(parentCache, indexfile,
                           subhierarchy);
        if (!curcache)
            return 0;

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

            if (!n)
                write_error_exit(0);

            if (strlen(n) == p-skipped_pattern &&
                strncmp(n, skipped_pattern, p-skipped_pattern) == 0)
            {
                free(n);
                break;
            }
            free(n);
        }

        if (i >= curcache->nrecords) /* not found */
            return 0;

        if (*p)
            ++p;


        q=malloc(strlen(acc_pfix)+(p-skipped_pattern)+1);
        if (!q)
        {
            write_error_exit(0);
        }
        strcpy(q, acc_pfix);
        strncat(q, skipped_pattern, p-skipped_pattern);

        lni.acc_pfix=q;
        lni.skipped_pattern=p;
        lni.parentCache=curcache;

        curcache->indexfile.startingpos=curcache->records[i].offset;

        rc=maildir_newshared_nextAt(&curcache->indexfile, &eof,
                        list_newshared_skipcb, &lni);
        free(q);
        return rc;

    }

    if (!indexfile)
        indexfile=maildir_shared_index_file();

    rc=maildir_newshared_enum(indexfile, list_newshared_cb, &lni);

    return rc;
}

static int list_newshared_cb(struct maildir_newshared_enum_cb *cb)
{
    const char *name=cb->name;
    const char *homedir=cb->homedir;
    const char *maildir=cb->maildir;
    struct list_newshared_info *lni=
        (struct list_newshared_info *)cb->cb_arg;
    char *n=maildir_info_imapmunge(name);
    int rc;

    if (!n)
        write_error_exit(0);

    if (homedir == NULL)
    {
        struct list_newshared_info new_lni= *lni;
        char *new_pfix=malloc(strlen(lni->acc_pfix)+
                      strlen(n)+2);
        if (!new_pfix)
            write_error_exit(0);

        strcat(strcpy(new_pfix, lni->acc_pfix), n);

        free(n);
        n=new_pfix;
        new_lni.acc_pfix=n;
        add_hier(lni->shared_info->hierarchies, n);
        hier_entry(n, lni->shared_info->hierarchies);
        strcat(n, hierchs);
        rc=lni->dorecurse ?
            maildir_newshared_enum(maildir, list_newshared_cb,
                           &new_lni):0;
    }
    else
    {
        char *new_pfix;
        struct stat stat_buf;

        new_pfix=maildir_location(homedir, maildir);

        if (stat(new_pfix, &stat_buf) < 0 ||
            /* maildir inaccessible, perhaps another server? */

            (stat_buf.st_dev == homedir_dev &&
             stat_buf.st_ino == homedir_ino))
            /* Exclude ourselves from the shared list */
        {
            free(new_pfix);
            free(n);
            return 0;
        }
        free(new_pfix);

        new_pfix=malloc(strlen(lni->acc_pfix)+
                      strlen(n)+1);
        if (!new_pfix)
            write_error_exit(0);

        strcat(strcpy(new_pfix, lni->acc_pfix), n);

        free(n);
        n=new_pfix;

        new_pfix=malloc(strlen(homedir)+strlen(maildir)+2);

        if (!new_pfix)
            write_error_exit(0);

        if (*maildir == '/')
            strcpy(new_pfix, maildir);
        else
            strcat(strcat(strcpy(new_pfix, homedir), "/"),
                   maildir);

        /*        if (lni->dorecurse) */

        maildir_scan(new_pfix, n, lni->shared_info);
#if 0
        else
        {
            folder_entry(n, lni->shared_info->pattern,
                     lni->shared_info->flags,
                     lni->shared_info->folders,
                     lni->shared_info->hierarchies);
        }
#endif

        free(new_pfix);
        rc=0;
    }
    free(n);
    return rc;
}

static int list_newshared_skiplevel(struct maildir_newshared_enum_cb *cb)
{
    struct list_newshared_info *lni=
        (struct list_newshared_info *)cb->cb_arg;
    char *n=maildir_info_imapmunge(cb->name);

    char *p=malloc(strlen(lni->acc_pfix)+strlen(n)+sizeof(HIERCHS));
    int rc;
    const char *save_skip;

    if (!n || !p)
        write_error_exit(0);

    strcat(strcat(strcpy(p, lni->acc_pfix), n), HIERCHS);
    free(n);

    save_skip=lni->acc_pfix;
    lni->acc_pfix=p;

    rc=list_newshared_skipcb(cb);
    lni->acc_pfix=save_skip;
    free(p);
    return rc;
}

static int list_newshared_skipcb(struct maildir_newshared_enum_cb *cb)
{
    struct list_newshared_info *lni=
        (struct list_newshared_info *)cb->cb_arg;
    char *dir;
    char *inbox_name;

    if (cb->homedir == NULL)
        return list_newshared_shortcut(lni->skipped_pattern,
                           lni->shared_info,
                           lni->acc_pfix,
                           lni->parentCache,
                           cb->maildir,
                           cb->name);

    inbox_name=my_strdup(lni->acc_pfix);

    dir=strrchr(inbox_name, HIERCH);
    if (dir && dir[1] == 0)
        *dir=0; /* Strip trailing hier separator */

    dir=malloc(strlen(cb->homedir)+strlen(cb->maildir)+2);

    if (!dir)
    {
        free(inbox_name);
        write_error_exit(0);
    }

    if (*cb->maildir == '/')
        strcpy(dir, cb->maildir);
    else
        strcat(strcat(strcpy(dir, cb->homedir), "/"), cb->maildir);

    maildir_scan(dir, inbox_name, lni->shared_info);
    free(dir);
    free(inbox_name);
    return 0;
}

static int do_mailbox_list(int list_options, char *pattern, int isnullname,
               int (*callback_func)(const char *hiersep,
                        const char *mailbox,
                        int flags,
                        void *void_arg),
               void *void_arg)
{
int    found_hier=MAILBOX_NOSELECT;
int    is_interesting;
int    i,j,bad_pattern;
struct    hierlist *hierarchies, *folders, *hp;
struct list_sharable_info shared_info;

const char *obsolete;
int check_all_folders=0;
char hiersepbuf[8];
int callback_rc=0;

    obsolete=getenv("IMAP_CHECK_ALL_FOLDERS");
    if (obsolete && atoi(obsolete))
        check_all_folders=1;

    obsolete=getenv("IMAP_OBSOLETE_CLIENT");

    if (obsolete && atoi(obsolete) == 0)
        obsolete=0;

    /* Allow up to ten wildcards */

    for (i=j=0; pattern[i]; i++)
        if (pattern[i] == '*' || pattern[i] == '%')    ++j;
    bad_pattern= j > 10;

    if (list_options & LIST_CHECK1FOLDER)
        bad_pattern=0;

    if (bad_pattern)
    {
        errno=EINVAL;
        return -1;
    }

    hierarchies=0;
    folders=0;

    match_mailbox_prep(pattern);

    shared_info.pattern=pattern;
    shared_info.folders= &folders;
    shared_info.hierarchies= &hierarchies;
    shared_info.flags=list_options;
    shared_info.callback_func=callback_func;
    shared_info.cb_arg=void_arg;

    if (!(list_options & LIST_SUBSCRIBED))
    {
        if (strncmp(pattern, NEWSHARED,
                sizeof(NEWSHARED)-1) == 0)
        {
            list_newshared(pattern +
                       sizeof(NEWSHARED)-1,
                       &shared_info);
        }
        else
        {
            maildir_scan(".", INBOX, &shared_info);

            /* List sharable maildirs */

            maildir_list_sharable( ".", &list_sharable,
                           &shared_info );
        }
    }
    else
    {
        list_subscribed(pattern, list_options, &folders, &hierarchies);

        /* List shared folders */

        maildir_list_shared( ".", &list_sharable,
                     &shared_info );
    }

    while ((hp=folders) != 0)
    {
        struct hierlist *d;
        int mb_flags;

        folders=hp->next;

        is_interesting= -1;

        if (strcmp(hp->hier, INBOX) == 0 || check_all_folders)
            is_interesting=hasnewmsgs(hp->hier);

        strcat(strcat(strcpy(hiersepbuf, "\""), hierchs), "\"");

        mb_flags=0;

        if (is_interesting == 0)
        {
            mb_flags|=MAILBOX_UNMARKED;
        }
        if (is_interesting > 0)
        {
            mb_flags|=MAILBOX_MARKED;
        }

        if ((d=search_hier(hierarchies, hp->hier)) == 0)
        {
            mb_flags |=
                obsolete ? MAILBOX_NOINFERIORS:MAILBOX_NOCHILDREN;
        }
        else
        {
            d->flag=1;
            if (!obsolete)
                mb_flags |= MAILBOX_CHILDREN;
        }

        if (isnullname)
            found_hier=mb_flags;
        else
            if (callback_rc == 0)
                callback_rc=(*callback_func)
                    (hiersepbuf, hp->hier,
                     mb_flags | list_options, void_arg);
        free(hp);
    }

    while ((hp=hierarchies) != 0)
    {
        hierarchies=hp->next;

        match_mailbox_prep(hp->hier);

        if (match_mailbox(hp->hier, pattern, list_options) == 0
            && hp->flag == 0)
        {
            int mb_flags=MAILBOX_NOSELECT;

            if (!obsolete)
                mb_flags |= MAILBOX_CHILDREN;

            if (isnullname)
                found_hier=mb_flags;
            else 
            {
                strcat(strcat(strcpy(hiersepbuf, "\""),
                          hierchs), "\"");

                if (callback_rc == 0)
                    callback_rc=(*callback_func)
                        (hiersepbuf,
                         hp->hier,
                         mb_flags | list_options,
                         void_arg);
            }
        }
        free(hp);
    }

    if (isnullname)
    {
        const char *namesp="";

        if (strncmp(pattern, NEWSHARED, sizeof(NEWSHARED)-1) == 0)
            namesp=NEWSHARED;

        strcat(strcat(strcpy(hiersepbuf, "\""), hierchs), "\"");

        if (callback_rc == 0)
            callback_rc=(*callback_func)
                (hiersepbuf, namesp, found_hier | list_options,
                 void_arg);
    }
    return callback_rc;
}

static int match_recursive(char *, char *, int);

static void match_mailbox_prep(char *name)
{
    size_t    i;

    /* First component, INBOX, is case insensitive */

    if (
#if    HAVE_STRNCASECMP
        strncasecmp(name, INBOX, sizeof(INBOX)-1) == 0
#else
        strnicmp(name, INBOX, sizeof(INBOX)-1) == 0
#endif
        )
        for (i=0; name[i] && name[i] != HIERCH; i++)
            name[i]=toupper( (int)(unsigned char)name[i] );

    /* ... except that "shared" should be lowercase ... */

    if (memcmp(name, "SHARED", 6) == 0)
        memcpy(name, "shared", 6);
}

static int match_mailbox(char *name, char *pattern, int list_options)
{
        if (list_options & LIST_CHECK1FOLDER)
                return strcmp(name, pattern);

    return (match_recursive(name, pattern, HIERCH));
}

static int match_recursive(char *name, char *pattern, int hierch)
{
    for (;;)
    {
        if (*pattern == '*')
        {
            do
            {
                if (match_recursive(name, pattern+1,
                    hierch) == 0)
                    return (0);
            } while (*name++);
            return (-1);
        }
        if (*pattern == '%')
        {
            do
            {
                if (match_recursive(name, pattern+1, hierch)
                    == 0) return (0);
                if (*name == hierch)    break;
            } while (*name++);
            return (-1);
        }
        if (*name == 0 && *pattern == 0)    break;
        if (*name == 0 || *pattern == 0)    return (-1);
        if (*name != *pattern)    return (-1);
        ++name;
        ++pattern;
    }
    return (0);
}
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.3947 seconds