Back to index

courier  0.68.2
Defines | Functions
maildirmisc.h File Reference

Go to the source code of this file.

Defines

#define INBOX   "INBOX"
#define DRAFTS   "Drafts"
#define SENT   "Sent"
#define TRASH   "Trash"
#define SHARED   "shared"
#define SHAREDSUBDIR   "shared-folders"
#define NEWSHAREDSP   "#shared"
#define NEWSHARED   "#shared."
#define PUBLIC   "public" /* SMAP */
#define MAILDIR_DELETED(f)   maildir_hasflag((f), 'T')
#define MAILDIR_RENAME_FOLDER   1
#define MAILDIR_RENAME_SUBFOLDERS   2

Functions

int maildir_make (const char *maildir, int perm, int subdirperm, int folder)
int maildir_del (const char *maildir)
int maildir_del_content (const char *maildir)
char * maildir_name2dir (const char *maildir, const char *foldername)
char * maildir_location (const char *homedir, const char *maildir)
char * maildir_folderdir (const char *, const char *)
char * maildir_filename (const char *, const char *, const char *)
int maildir_safeopen (const char *, int, int)
int maildir_semisafeopen (const char *, int, int)
int maildir_safeopen_stat (const char *path, int mode, int perm, struct stat *stat1)
int maildir_mkdir (const char *)
void maildir_purgetmp (const char *)
void maildir_purge (const char *, unsigned)
void maildir_getnew (const char *, const char *, void(*)(const char *, void *), void *arg)
int maildir_deletefolder (const char *, const char *)
void maildir_list (const char *maildir, void(*func)(const char *, void *), void *voidp)
void maildir_list_sharable (const char *, void(*)(const char *, void *), void *)
int maildir_shared_subscribe (const char *, const char *)
void maildir_list_shared (const char *, void(*)(const char *, void *), void *)
int maildir_shared_unsubscribe (const char *, const char *)
char * maildir_shareddir (const char *, const char *)
void maildir_shared_sync (const char *)
int maildir_sharedisro (const char *)
int maildir_unlinksharedmsg (const char *)
char * maildir_getlink (const char *)
int maildir_hasflag (const char *filename, char)
int maildir_rename (const char *maildir, const char *oldname, const char *newname, int flags, void(*callback_func)(const char *old_path, const char *new_path))

Define Documentation

#define DRAFTS   "Drafts"

Definition at line 31 of file maildirmisc.h.

#define INBOX   "INBOX"

Definition at line 30 of file maildirmisc.h.

#define MAILDIR_DELETED (   f)    maildir_hasflag((f), 'T')

Definition at line 180 of file maildirmisc.h.

#define MAILDIR_RENAME_FOLDER   1

Definition at line 186 of file maildirmisc.h.

#define MAILDIR_RENAME_SUBFOLDERS   2

Definition at line 187 of file maildirmisc.h.

#define NEWSHARED   "#shared."

Definition at line 39 of file maildirmisc.h.

#define NEWSHAREDSP   "#shared"

Definition at line 38 of file maildirmisc.h.

#define PUBLIC   "public" /* SMAP */

Definition at line 41 of file maildirmisc.h.

#define SENT   "Sent"

Definition at line 32 of file maildirmisc.h.

#define SHARED   "shared"

Definition at line 34 of file maildirmisc.h.

#define SHAREDSUBDIR   "shared-folders"

Definition at line 36 of file maildirmisc.h.

#define TRASH   "Trash"

Definition at line 33 of file maildirmisc.h.


Function Documentation

int maildir_del ( const char *  maildir)

Definition at line 135 of file maildirmake2.c.

{
       int rc;
       if ((rc=maildir_del_content(maildir)) == -1)
           return rc;
       return rmdir(maildir) < 0 && errno != ENOENT ? -1:0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_del_content ( const char *  maildir)

Definition at line 67 of file maildirmake2.c.

{
       char *filenamebuf[100];
       int n, i;
       DIR *dirp;
       struct dirent *de;

       do
       {
              dirp=opendir(maildir);
              n=0;
              while (dirp && (de=readdir(dirp)) != 0)
              {
                     if (strcmp(de->d_name, ".") == 0 ||
                         strcmp(de->d_name, "..") == 0)
                            continue;

                     if ((filenamebuf[n]=malloc(strlen(maildir)+
                                             strlen(de->d_name)+2))
                         == NULL)
                     {
                            closedir(dirp);
                            while (n)
                                   free(filenamebuf[--n]);
                            return -1;
                     }
                     strcat(strcat(strcpy(filenamebuf[n], maildir),
                                  "/"), de->d_name);
                     if (++n >= sizeof(filenamebuf)/sizeof(filenamebuf[0]))
                            break;
              }
              if (dirp)
                     closedir(dirp);

              for (i=0; i<n; i++)
              {
                     struct stat s_buf;

                     if (lstat(filenamebuf[i], &s_buf) < 0)
                            continue;

                     if (S_ISDIR(s_buf.st_mode))
                     {
                            if (maildir_del(filenamebuf[i]) < 0)
                            {
                                   while (n)
                                          free(filenamebuf[--n]);
                                   return -1;
                            }
                     }
                     else if (unlink(filenamebuf[i]) < 0)
                     {
                            if (errno != ENOENT)
                            {
                                   while (n)
                                          free(filenamebuf[--n]);
                                   return -1;

                            }
                     }
              }

              for (i=0; i<n; i++)
                     free(filenamebuf[i]);
       } while (n);
       return 0; 
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_deletefolder ( const char *  ,
const char *   
)

Definition at line 41 of file maildirdelfolder.c.

{
char   *s;
int    rc;

       if (*folder == '.')
       {
              errno=EINVAL;
              return (-1);
       }

       s=malloc(strlen(maildir)+strlen(folder)+3);
       if (!s)       return (-1);
       strcat(strcat(strcpy(s, maildir), "/."), folder);

       rc=maildir_del(s);
       free(s);
       return (rc);
}

Here is the call graph for this function:

char* maildir_filename ( const char *  ,
const char *  ,
const char *   
)

Definition at line 51 of file maildirfilename.c.

{
struct stat stat_buf;
char   *p, *q;
DIR *dirp;
struct dirent *de;
char   *dir;

       if (strchr(filename, '/') || *filename == '.')
       {
              errno=ENOENT;
              return (0);
       }

       dir=maildir_folderdir(maildir, folder);

       if (!dir)     return (0);

       p=malloc(strlen(dir)+strlen(filename)+sizeof("/cur/"));

       if (!p)
       {
              free(dir);
              return (0);
       }

       strcat(strcat(strcpy(p, dir), "/cur/"), filename);

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

       /* Oh, a wise guy... */

       q=strrchr(p, '/');
       *q=0;
       dirp=opendir(p);
       *q='/';

       if ( dirp == NULL)
       {
              free(dir);
              return p;
       }

       /* Compare filenames, ignore filename size if set by maildirquota */

       while ((de=readdir(dirp)) != NULL)
       {
       const char *a=filename;
       const char *b=de->d_name;

              for (;;)
              {
                     if ( a[0] == ',' && a[1] == 'S' && a[2] == '=')
                     {
                            /* File size - quota shortcut - skip */
                            a += 3;
                            while (*a && isdigit((int)(unsigned char)*a))
                                   ++a;
                     }

                     if ( b[0] == ',' && b[1] == 'S' && b[2] == '=')
                     {
                            /* File size - quota shortcut - skip */
                            b += 3;
                            while (*b && isdigit((int)(unsigned char)*b))
                                   ++b;
                     }

                     if ( (*a == 0 || *a == MDIRSEP[0]) && (*b == 0 || *b == MDIRSEP[0]))
                     {
                            free(p);
                            p=malloc(strlen(dir)+strlen(de->d_name)+
                                   sizeof("/cur/"));
                            if (!p)
                            {
                                   closedir(dirp);
                                   free(dir);
                                   return (0);
                            }

                            strcat(strcat(strcpy(p, dir), "/cur/"),
                                   de->d_name);
                            closedir(dirp);
                            free(dir);
                            return (p);
                     }
                     if ( *a == 0 || *a == MDIRSEP[0] || *b == 0 || *b == MDIRSEP[0] ||
                            *a != *b)
                            break;

                     ++a;
                     ++b;
              }
       }
       closedir(dirp);
       free(dir);
       return (p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* maildir_folderdir ( const char *  ,
const char *   
)

Definition at line 87 of file maildirpath.c.

{
char   *p;
const char *r;
size_t l;

       if (!maildir) maildir=".";
       l=strlen(maildir);

       if (foldername == 0 ||
              strcasecmp(foldername, INBOX) == 0)
       {
              if ((p=malloc(l+1)) == 0)   return (0);
              strcpy(p, maildir);
              return(p);
       }

       /* Rules: no leading/trailing periods, no /s */
       if (*foldername == '.' || strchr(foldername, '/'))
       {
              errno=EINVAL;
              return (0);
       }

       for (r=foldername; *r; r++)
       {
              if (*r != '.')       continue;
              if (r[1] == 0 || r[1] == '.')
              {
                     errno=EINVAL;
                     return (0);
              }
       }

       if ((p=malloc(l+strlen(foldername)+3)) == 0)     return (0);
       *p=0;
       if (strcmp(maildir, "."))
              strcat(strcpy(p, maildir), "/");
       
       return (strcat(strcat(p, "."), foldername));
}

Here is the caller graph for this function:

char* maildir_getlink ( const char *  )

Definition at line 26 of file maildiropen.c.

{
#if     HAVE_READLINK
size_t bufsiz;
char   *buf;

       bufsiz=0;
       buf=0;

       for (;;)
       {
       int    n;

              if (buf)      free(buf);
              bufsiz += 256;
              if ((buf=malloc(bufsiz)) == 0)
              {
                     perror("malloc");
                     return (0);
              }
              if ((n=readlink(filename, buf, bufsiz)) < 0)
              {
                     free(buf);
                     return (0);
              }
              if (n < bufsiz)
              {
                     buf[n]=0;
                     break;
              }
       }
       return (buf);
#else
       return (0);
#endif
}

Here is the caller graph for this function:

void maildir_getnew ( const char *  ,
const char *  ,
void(*)(const char *, void *)  ,
void *  arg 
)

Definition at line 45 of file maildirgetnew.c.

{
char   *dir=maildir_folderdir(maildir, folder);
char   *newd, *curd;

       if (!dir)     return;

       newd=malloc(strlen(dir)+sizeof("/new"));
       curd=malloc(strlen(dir)+sizeof("/cur"));

       if (newd && curd)
       {
              strcat(strcpy(newd, dir), "/new");
              strcat(strcpy(curd, dir), "/cur");
              do_maildir_getnew(newd, curd, callback_func, callback_arg);
       }

       if (newd)     free(newd);
       if (curd)     free(curd);
       free(dir);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_hasflag ( const char *  filename,
char   
)

Definition at line 11 of file maildirflags.c.

{
       const char *p=strrchr(filename, '/');

       if (p)
              filename=p+1;

       p=strrchr(filename, MDIRSEP[0]);
       if (p && strncmp(p, MDIRSEP "2,", 3) == 0 &&
           strchr(p+3, flag))
              return (1);
       return (0);
}
void maildir_list ( const char *  maildir,
void(*)(const char *, void *)  func,
void *  voidp 
)

Definition at line 42 of file maildirlist.c.

{
       DIR *dirp=opendir(maildir);
       struct dirent *de;

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

              if (strcmp(de->d_name, "..") == 0)
                     continue;

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

              if ((p=malloc(strlen(maildir) + strlen(de->d_name)+20))
                  == NULL)
                     continue;

              strcat(strcat(strcat(strcpy(p, maildir), "/"), de->d_name),
                     "/cur/.");

              if (access(p, X_OK))
              {
                     free(p);
                     continue;
              }

              strcpy(p, INBOX);

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

              (*func)(p, voidp);
              free(p);
       }
       if (dirp)
              closedir(dirp);
}

Here is the caller graph for this function:

void maildir_list_sharable ( const char *  ,
void(*)(const char *, void *)  ,
void *   
)

Definition at line 869 of file maildirshared.c.

{
}

Here is the caller graph for this function:

void maildir_list_shared ( const char *  ,
void(*)(const char *, void *)  ,
void *   
)

Definition at line 881 of file maildirshared.c.

{
}

Here is the caller graph for this function:

char* maildir_location ( const char *  homedir,
const char *  maildir 
)

Definition at line 71 of file maildirpath.c.

{
       char *p;

       if (*maildir == '/')
              return strdup(maildir);

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

       if (!p)
              return NULL;
       strcat(strcat(strcpy(p, homedir), "/"), maildir);
       return p;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_make ( const char *  maildir,
int  perm,
int  subdirperm,
int  folder 
)

Definition at line 39 of file maildirmake2.c.

{
       char *q=malloc(strlen(maildir)+sizeof("/maildirfolder"));
       int fd= -1;

       if (!q)
              return -1;

       if (mkdir(maildir, perm) < 0 ||
           chmod(maildir, perm) < 0 ||
           mkdir(strcat(strcpy(q, maildir), "/tmp"), subdirperm) < 0 ||
           chmod(q, subdirperm) < 0 ||
           mkdir(strcat(strcpy(q, maildir), "/new"), subdirperm) < 0 ||
           chmod(q, subdirperm) < 0 ||
           mkdir(strcat(strcpy(q, maildir), "/cur"), subdirperm) < 0 ||
           chmod(q, subdirperm) < 0 ||
           (folder && (fd=open(strcat(strcpy(q, maildir), "/maildirfolder"),
                            O_CREAT|O_WRONLY, 0600)) < 0))
       {
              free(q);
              return -1;
       }
       if (fd >= 0)
              close(fd);
       free(q);
       return 0;
}

Here is the caller graph for this function:

int maildir_mkdir ( const char *  )

Definition at line 22 of file maildirmkdir.c.

{
char   *buf, *p;
size_t l;

       if (dir == 0 || dir[0] == 0)
       {
              errno = EINVAL;
              return (-1);
       }
       l = strlen(dir);
       if ((buf = malloc(l + sizeof("/tmp"))) == 0)
       {
              errno = ENOMEM;
              return (-1);
       }
       strcpy(buf, dir);
       strcpy(buf+l, "/cur");

       /* We do mkdir -p here */

       p = buf+1;
       while ((p = strchr(p, '/')) != 0)
       {
              *p = '\0';
              if (mkdir(buf, 0700) < 0 && errno != EEXIST)
              {
                     free(buf);
                     return (-1);
              }
              *p++ = '/';
       }

       if (mkdir(buf, 0700) < 0 && errno != EEXIST) {
              free(buf);
              return (-1);
       }
       strcpy(buf+l, "/new");
       if (mkdir(buf, 0700) < 0 && errno != EEXIST) {
              free(buf);
              return (-1);
       }
       /*
        *  make /tmp last because this is the one we open first -
        *  the existence of this directory implies the whole
        *  Maildir structure is complete
        */
       strcpy(buf+l, "/tmp");
       if (mkdir(buf, 0700) < 0 && errno != EEXIST) {
              free(buf);
              return (-1);
       }
       free(buf);
       return (0);
}

Here is the caller graph for this function:

char* maildir_name2dir ( const char *  maildir,
const char *  foldername 
)

Definition at line 25 of file maildirpath.c.

{
       const char *inbox=INBOX;
       int l=strlen(inbox);
       char *p;

       if (!maildir) maildir=".";

       if (foldername && strncasecmp(foldername, INBOX, l) == 0 &&
           strchr(foldername, '/') == NULL)
       {
              if (foldername[l] == 0)
                     return strdup(maildir); /* INBOX: main maildir inbox */

              if (foldername[l] == '.')
              {
                     const char *r;

                     for (r=foldername; *r; r++)
                     {
                            if (*r != '.')       continue;

                            if (r[1] == 0 || r[1] == '.')
                            {
                                   errno=EINVAL;
                                   return (0);
                            }
                     }

                     r=strchr(foldername, '.');

                     p=malloc(strlen(maildir)+strlen(r) + 2);

                     if (!p)
                            return NULL;

                     return (strcat(strcat(strcpy(p, maildir), "/"),
                                   r));
              }
       }

       errno=EINVAL;
       return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_purge ( const char *  ,
unsigned   
)

Definition at line 90 of file maildirpurgetmp.c.

{
       char   *m=malloc(strlen(maildir)+sizeof("/cur"));
       char   *p;
       int adjustquota;
       int nfiles;
       long nbytes;

       int nfiles2;
       long nbytes2;

       p=strrchr(maildir, '/');
       if (p)
              ++p;
       else
              p=".";

       adjustquota=maildirquota_countfolder(p);

       if (!m)       return;
       strcat(strcpy(m, maildir), "/cur");
       dopurge(m, nage, &nfiles, &nbytes);
       strcat(strcpy(m, maildir), "/new");
       dopurge(m, nage, &nfiles2, &nbytes2);
       free(m);

       nfiles += nfiles2;
       nbytes += nbytes2;

       if (adjustquota && nfiles > 0)
              maildir_quota_deleted(maildir, -nbytes, -nfiles);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_purgetmp ( const char *  )

Definition at line 78 of file maildirpurgetmp.c.

{
       char   *m=malloc(strlen(maildir)+sizeof("/tmp"));
       int nfiles;
       long nbytes;

       if (!m)       return;
       strcat(strcpy(m, maildir), "/tmp");
       dopurge(m, 60 * 60 * 36, &nfiles, &nbytes);
       free(m);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_rename ( const char *  maildir,
const char *  oldname,
const char *  newname,
int  flags,
void(*)(const char *old_path, const char *new_path)  callback_func 
)

Definition at line 89 of file maildirrename.c.

{
       struct rename_list *rl;
       int rc= -1;

       if (validrename(oldname, newname))
       {
              errno=EINVAL;
              return (-1);
       }

       rl=NULL;

       if (scan_maildir_rename(maildir, oldname, newname, flags, &rl) == 0 &&
           scan_aclhier_rename(maildir, oldname+1, newname+1, flags, &rl)
           == 0)
       {
              size_t n=0;
              struct rename_list *p, **a;

              for (p=rl; p; p=p->next)
                     ++n;

              if ((a=malloc(sizeof(struct rename_list *)*(n+1))) != NULL)
              {
                     n=0;
                     for (p=rl; p; p=p->next)
                            a[n++]=p;
                     a[n]=NULL;
                     if (n)
                            qsort(a, n, sizeof(*a), cmp_fn);


                     rc=0;
                     for (n=0; a[n]; n++)
                     {
                            if (rename(a[n]->o, a[n]->n))
                            {
                                   rc= -1;
                                   /* Try to undo the damage */

                                   while (n)
                                   {
                                          --n;
                                          rename(a[n]->n,
                                                 a[n]->o);
                                   }
                                   break;
                            }
                            if (rename_func)
                                   (*rename_func)(a[n]->o,
                                                 a[n]->n);
                     }
                     free(a);
              }
       }
       while (rl)
       {
              struct rename_list *p=rl;

              rl=rl->next;
              free(p->o);
              free(p->n);
              free(p);
       }
       return (rc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_safeopen ( const char *  ,
int  ,
int   
)

Definition at line 104 of file maildiropen.c.

{
       struct stat   stat1;

       return maildir_safeopen_stat(path, mode, perm, &stat1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_safeopen_stat ( const char *  path,
int  mode,
int  perm,
struct stat stat1 
)

Definition at line 111 of file maildiropen.c.

{
       struct stat   stat2;

       int    fd=open(path, mode
#ifdef O_NONBLOCK
                     | O_NONBLOCK
#else
                     | O_NDELAY
#endif
                     , perm);

       if (fd < 0)   return (fd);
       if (fcntl(fd, F_SETFL, (mode & O_APPEND)) || fstat(fd, stat1)
           || lstat(path, &stat2))
       {
              close(fd);
              return (-1);
       }

       if (stat1->st_dev != stat2.st_dev || stat1->st_ino != stat2.st_ino)
       {
              close(fd);
              errno=ENOENT;
              return (-1);
       }

       return (fd);
}

Here is the caller graph for this function:

int maildir_semisafeopen ( const char *  ,
int  ,
int   
)

Definition at line 63 of file maildiropen.c.

{

#if    HAVE_READLINK

char   *l=maildir_getlink(path);

       if (l)
       {
       int    f;

              if (*l != '/')
              {
              char   *q=malloc(strlen(path)+strlen(l)+2);
              char   *s;

                     if (!q)
                     {
                            free(l);
                            return (-1);
                     }

                     strcpy(q, path);
                     if ((s=strchr(q, '/')) != 0)
                            s[1]=0;
                     else   *q=0;
                     strcat(q, l);
                     free(l);
                     l=q;
              }

              f=maildir_safeopen(l, mode, perm);

              free(l);
              return (f);
       }
#endif

       return (maildir_safeopen(path, mode, perm));
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_shared_subscribe ( const char *  ,
const char *   
)

Definition at line 875 of file maildirshared.c.

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

Here is the caller graph for this function:

void maildir_shared_sync ( const char *  )

Definition at line 901 of file maildirshared.c.

{
}

Here is the caller graph for this function:

int maildir_shared_unsubscribe ( const char *  ,
const char *   
)

Definition at line 887 of file maildirshared.c.

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

Here is the caller graph for this function:

char* maildir_shareddir ( const char *  ,
const char *   
)

Definition at line 56 of file maildirshared2.c.

{
char    *p, *q;
const char *r;

       if (!maildir)   maildir=".";

       if (strchr(sharedname, '.') == 0 || *sharedname == '.' ||
              strchr(sharedname, '/'))
       {
              errno=EINVAL;
              return (0);
       }

       for (r=sharedname; *r; r++)
       {
              if (*r == '.' && (r[1] == '.' || r[1] == '\0'))
              {
                     errno=EINVAL;
                     return (0);
              }
       }

       p=malloc(strlen(maildir)+sizeof("/" SHAREDSUBDIR "/")+strlen(sharedname));
       if (!p)       return (0);

        *p=0;
        if (strcmp(maildir, "."))
              strcat(strcpy(p, maildir), "/");
       strcat(p, SHAREDSUBDIR "/");
       q=p+strlen(p);
       strcpy(q, sharedname);
       *strchr(q, '.')='/';
       return (p);
}

Here is the caller graph for this function:

int maildir_sharedisro ( const char *  )

Definition at line 905 of file maildirshared.c.

{
       return (-1);
}

Here is the caller graph for this function:

int maildir_unlinksharedmsg ( const char *  )

Definition at line 910 of file maildirshared.c.

{
       return (-1);
}

Here is the caller graph for this function: