Back to index

courier  0.68.2
maildirfilename.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 2000-2002 Double Precision, Inc.
00003 ** See COPYING for distribution information.
00004 */
00005 
00006 #if HAVE_CONFIG_H
00007 #include "config.h"
00008 #endif
00009 
00010 #include <sys/types.h>
00011 #if HAVE_DIRENT_H
00012 #include <dirent.h>
00013 #define NAMLEN(dirent) strlen((dirent)->d_name)
00014 #else
00015 #define dirent direct
00016 #define NAMLEN(dirent) (dirent)->d_namlen
00017 #if HAVE_SYS_NDIR_H
00018 #include <sys/ndir.h>
00019 #endif
00020 #if HAVE_SYS_DIR_H
00021 #include <sys/dir.h>
00022 #endif
00023 #if HAVE_NDIR_H
00024 #include <ndir.h>
00025 #endif
00026 #endif
00027 #include      <sys/types.h>
00028 #include      <sys/stat.h>
00029 #include      <string.h>
00030 #include      <stdlib.h>
00031 #include      <time.h>
00032 #if    HAVE_UNISTD_H
00033 #include      <unistd.h>
00034 #endif
00035 #include      <stdio.h>
00036 #include      <ctype.h>
00037 #include      <errno.h>
00038 
00039 #include      "maildirmisc.h"
00040 
00041 
00042 /*
00043 ** char *maildir_filename(const char *maildir, const char *folder,
00044 **   const char *filename)
00045 **     - find a message in a maildir
00046 **
00047 ** Return the full path to the indicated message.  If the message flags
00048 ** in filename have changed, we search the maildir for this message.
00049 */
00050 
00051 char *maildir_filename(const char *maildir,
00052        const char *folder, const char *filename)
00053 {
00054 struct stat stat_buf;
00055 char   *p, *q;
00056 DIR *dirp;
00057 struct dirent *de;
00058 char   *dir;
00059 
00060        if (strchr(filename, '/') || *filename == '.')
00061        {
00062               errno=ENOENT;
00063               return (0);
00064        }
00065 
00066        dir=maildir_folderdir(maildir, folder);
00067 
00068        if (!dir)     return (0);
00069 
00070        p=malloc(strlen(dir)+strlen(filename)+sizeof("/cur/"));
00071 
00072        if (!p)
00073        {
00074               free(dir);
00075               return (0);
00076        }
00077 
00078        strcat(strcat(strcpy(p, dir), "/cur/"), filename);
00079 
00080        if (stat(p, &stat_buf) == 0)
00081        {
00082               free(dir);
00083               return (p);
00084        }
00085 
00086        /* Oh, a wise guy... */
00087 
00088        q=strrchr(p, '/');
00089        *q=0;
00090        dirp=opendir(p);
00091        *q='/';
00092 
00093        if ( dirp == NULL)
00094        {
00095               free(dir);
00096               return p;
00097        }
00098 
00099        /* Compare filenames, ignore filename size if set by maildirquota */
00100 
00101        while ((de=readdir(dirp)) != NULL)
00102        {
00103        const char *a=filename;
00104        const char *b=de->d_name;
00105 
00106               for (;;)
00107               {
00108                      if ( a[0] == ',' && a[1] == 'S' && a[2] == '=')
00109                      {
00110                             /* File size - quota shortcut - skip */
00111                             a += 3;
00112                             while (*a && isdigit((int)(unsigned char)*a))
00113                                    ++a;
00114                      }
00115 
00116                      if ( b[0] == ',' && b[1] == 'S' && b[2] == '=')
00117                      {
00118                             /* File size - quota shortcut - skip */
00119                             b += 3;
00120                             while (*b && isdigit((int)(unsigned char)*b))
00121                                    ++b;
00122                      }
00123 
00124                      if ( (*a == 0 || *a == MDIRSEP[0]) && (*b == 0 || *b == MDIRSEP[0]))
00125                      {
00126                             free(p);
00127                             p=malloc(strlen(dir)+strlen(de->d_name)+
00128                                    sizeof("/cur/"));
00129                             if (!p)
00130                             {
00131                                    closedir(dirp);
00132                                    free(dir);
00133                                    return (0);
00134                             }
00135 
00136                             strcat(strcat(strcpy(p, dir), "/cur/"),
00137                                    de->d_name);
00138                             closedir(dirp);
00139                             free(dir);
00140                             return (p);
00141                      }
00142                      if ( *a == 0 || *a == MDIRSEP[0] || *b == 0 || *b == MDIRSEP[0] ||
00143                             *a != *b)
00144                             break;
00145 
00146                      ++a;
00147                      ++b;
00148               }
00149        }
00150        closedir(dirp);
00151        free(dir);
00152        return (p);
00153 }