Back to index

courier  0.68.2
Classes | Defines | Functions
maildirinfo.h File Reference
#include "config.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  maildir_info

Defines

#define MAILBOXTYPE_INBOX   0 /* Inbox maildir */
#define MAILBOXTYPE_OLDSHARED   1 /* Legacy shared hierarchy */
#define MAILBOXTYPE_NEWSHARED   2 /* #shared hierarchy */
#define MAILBOXTYPE_IGNORE   255 /* Ignore this mailbox */

Functions

void maildir_info_destroy (struct maildir_info *)
int maildir_info_imap_find (struct maildir_info *info, const char *path, const char *myid)
int maildir_info_suppress (const char *maildir)
int maildir_info_smap_find (struct maildir_info *info, char **folder, const char *myid)
char ** maildir_smapfn_fromutf7 (const char *modutf7)
void maildir_smapfn_free (char **fn)
void maildir_info_munge_complex (int)
char * maildir_info_imapmunge (const char *name)

Class Documentation

struct maildir_info

Definition at line 16 of file maildirinfo.h.

Class Members
char * homedir
int mailbox_type
char * maildir
char * owner

Define Documentation

#define MAILBOXTYPE_IGNORE   255 /* Ignore this mailbox */

Definition at line 48 of file maildirinfo.h.

#define MAILBOXTYPE_INBOX   0 /* Inbox maildir */

Definition at line 44 of file maildirinfo.h.

#define MAILBOXTYPE_NEWSHARED   2 /* #shared hierarchy */

Definition at line 46 of file maildirinfo.h.

#define MAILBOXTYPE_OLDSHARED   1 /* Legacy shared hierarchy */

Definition at line 45 of file maildirinfo.h.


Function Documentation

void maildir_info_destroy ( struct maildir_info )

Definition at line 42 of file maildirinfo.c.

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

Here is the caller graph for this function:

int maildir_info_imap_find ( struct maildir_info info,
const char *  path,
const char *  myid 
)

Definition at line 92 of file maildirinfo.c.

{
       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=
                            libmail_u_convert_tobuf(info->owner,
                                                 unicode_x_imap_modutf7,
                                                 "utf-8", NULL);

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

Here is the call graph for this function:

Here is the caller graph for this function:

char* maildir_info_imapmunge ( const char *  name)

Definition at line 862 of file maildirinfo.c.

{
       char *n=libmail_u_convert_tobuf(name, "utf8",
                                   unicode_x_imap_modutf7, NULL);
       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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 855 of file maildirinfo.c.

Here is the caller graph for this function:

int maildir_info_smap_find ( struct maildir_info info,
char **  folder,
const char *  myid 
)

Definition at line 639 of file maildirinfo.c.

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

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_info_suppress ( const char *  maildir)

Definition at line 150 of file imapd.c.

{
       struct stat stat_buf;

       if (stat(maildir, &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 */

           )
       {
              return 1;
       }

       return 0;
}

Here is the caller graph for this function:

void maildir_smapfn_free ( char **  fn)

Definition at line 535 of file maildirinfo.c.

{
       size_t i;

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

Here is the caller graph for this function:

char** maildir_smapfn_fromutf7 ( const char *  modutf7)

Definition at line 480 of file maildirinfo.c.

{
       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
       {
              for (i=0; q[i]; i++)
                     if (q[i] == '.' && q[i+1] && q[i+1] != '.')
                     {
                            q[i++]=0;
                            break;
                     }

              fn[n]=libmail_u_convert_tobuf(q,
                                         unicode_x_imap_modutf7 " ./~:",
                                         "utf-8", NULL);
              q += i;

              if (!fn[n])
              {
                     while (n)
                            free(fn[--n]);
                     free(fn);
                     free(p);
                     return NULL;
              }
              n++;
       } while (*q);
       fn[n]=0;
       free(p);
       return fn;
}

Here is the call graph for this function:

Here is the caller graph for this function: