Back to index

courier  0.68.2
Classes | Defines | Functions | Variables
maildir.c File Reference
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
#include "sqwebmail.h"
#include "maildir.h"
#include "folder.h"
#include "rfc822/rfc822.h"
#include "rfc822/rfc2047.h"
#include "rfc2045/rfc2045.h"
#include "cgi/cgi.h"
#include "pref.h"
#include "sqconfig.h"
#include "dbobj.h"
#include "auth.h"
#include "acl.h"
#include "maildir/maildirquota.h"
#include "maildir/maildirrequota.h"
#include "maildir/maildirgetquota.h"
#include "maildir/maildirmisc.h"
#include "maildir/maildircreate.h"
#include "maildir/maildirinfo.h"
#include "maildir/maildiraclt.h"
#include "maildir/maildirsearch.h"
#include "htmllibdir.h"
#include "unicode/unicode.h"
#include <sys/types.h>
#include <sys/stat.h>
#include "strftime.h"

Go to the source code of this file.

Classes

struct  searchresults_match_context
struct  searchresults
struct  MSGINFO_LIST
struct  add_shared_info

Defines

#define dirent   direct
#define NAMLEN(dirent)   ((dirent)->d_namlen)
#define save_int(n, fp)
#define load_int(n, fp)
#define SEARCHFORMATVER   1
#define SEARCH_MATCH_CONTEXT_LEN   20
#define sr_context_buf_index_inc(sr, n)   ( ( (n)+1 ) % ( (sr)->context_buf_len))
#define sr_context_buf_index_dec(sr, n)   ( ( (n)+ (sr)->context_buf_len - 1 ) % ( (sr)->context_buf_len))

Functions

time_t rfc822_parsedt (const char *)
static void createmdcache (const char *, const char *)
static void maildir_getfoldermsgs (const char *)
static const char * parse_ul (const char *p, unsigned long *ul)
static void change_timestamp (const char *filename, time_t t)
static char * xlate_mdir (const char *foldername)
static char * xlate_shmdir (const char *foldername)
static void cat_n (char *buf, unsigned long n)
const char * showsize (unsigned long n)
char * alloc_filename (const char *dir1, const char *dir2, const char *filename)
char * maildir_find (const char *folder, const char *filename)
char * maildir_basename (const char *filename)
static char * displaydate (time_t t)
static char * maildir_addflagfilename (const char *filename, char flag)
static void closedb ()
static char * foldercachename (const char *folder)
static int opencache (const char *folder, const char *mode)
static void maildir_remflagname (char *filename, char flag)
static MSGINFOget_msginfo (unsigned long n)
static MSGINFOget_msginfo_alloc (unsigned long n)
static void put_msginfo (MSGINFO *m, unsigned long n)
static void update_foldermsgs (const char *folder, const char *newname, size_t pos)
static void maildir_markflag (const char *folder, size_t pos, char flag)
void maildir_markread (const char *folder, size_t pos)
void maildir_markreplied (const char *folder, const char *message)
char * maildir_posfind (const char *folder, size_t *pos)
int maildir_name2pos (const char *folder, const char *filename, size_t *pos)
void maildir_msgpurge (const char *folder, size_t pos)
void maildir_msgpurgefile (const char *folder, const char *msgid)
static int msgcopy (int fromfd, int tofd)
static int do_msgmove (const char *from, const char *file, const char *dest, size_t pos, int check_acls)
void maildir_msgdeletefile (const char *folder, const char *file, size_t pos)
int maildir_msgmovefile (const char *folder, const char *file, const char *dest, size_t pos)
static char * foldercountfilename (const char *folder)
static void maildir_checknew (const char *folder, const char *dir)
static int goodcache (const char *foldername)
void maildir_autopurge ()
void maildir_purgemimegpg ()
void maildir_purgesearch ()
static int subjectcmp (const char *a, const char *b)
static int messagecmp (const MSGINFO **pa, const MSGINFO **pb)
char maildirfile_type (const char *p)
static int docount (const char *fn, unsigned *new_cnt, unsigned *other_cnt)
MSGINFO ** maildir_read (const char *dirname, unsigned nfiles, size_t *starting_pos, int *morebefore, int *moreafter)
static void save_str (const char *str, FILE *fp)
static char * load_str (FILE *fp)
static void save_msginfo (const MSGINFO *p, MATCHEDSTR *context, FILE *fp)
static void load_msginfo (MSGINFO **retinfo, MATCHEDSTR **retmatches, FILE *fp)
static void execute_maildir_search (const char *dirname, size_t pos, const char *searchtxt, const char *charset, unsigned nfiles, MSGINFO ***retval, MATCHEDSTR ***retcontext, unsigned long *last_message_searched)
void maildir_search (const char *dirname, size_t pos, const char *searchtxt, const char *charset, unsigned nfiles)
void maildir_loadsearch (unsigned nfiles, MSGINFO ***retmsginfo, MATCHEDSTR ***retmatches, unsigned long *last_message_searched)
static MATCHEDSTRcreatematches (struct searchresults *sr)
static int searchresults_init (struct searchresults *sr, struct maildir_searchengine *se)
static void searchresults_destroy (struct searchresults *sr)
static int do_maildir_search (const char *filename, struct searchresults *sr)
static void search_found_save_context (struct searchresults *sr)
static int do_search_utf8 (struct searchresults *res)
static int do_search (const char *str, size_t n, void *arg)
static void savematch (struct searchresults_match_context *smc, MATCHEDSTR **curptr)
static char * match_conv (const unicode_char *uc)
static void dodirscan (const char *, const char *, unsigned *, unsigned *)
void maildir_count (const char *folder, unsigned *new_ptr, unsigned *other_ptr)
unsigned maildir_countof (const char *folder)
void maildir_free (MSGINFO **files, unsigned nfiles)
static void addbuf (int c)
char * maildir_readline (FILE *fp)
char * maildir_readheader_nolc (FILE *fp, char **value)
char * maildir_readheader_mimepart (FILE *fp, char **value, int preserve_nl, off_t *mimepos, const off_t *endpos)
char * maildir_readheader (FILE *fp, char **value, int preserve_nl)
void maildir_nfreeinfo (MSGINFO *mi)
MSGINFOmaildir_ngetinfo (const char *filename)
static void maildir_save_start (const char *folder, const char *maildir, time_t t)
static void maildir_saveinfo (MSGINFO *m)
static void maildir_save_end (const char *maildir)
void maildir_savefoldermsgs (const char *folder)
static int chkcache (const char *folder)
void maildir_remcache (const char *folder)
void maildir_reload (const char *folder)
static void addfolder (const char *name, char ***buf, size_t *size, size_t *cnt)
static void list_callback (const char *n, void *vp)
static void list_shared_callback (const char *n, void *vp)
static void list_sharable_callback (const char *n, void *vp)
static int shcomparefunc (char **a, char **b)
void maildir_listfolders (const char *inbox_pfix, const char *homedir, char ***fp)
void maildir_freefolders (char ***fp)
int maildir_create (const char *foldername)
int maildir_delete (const char *foldername, int deletecontent)
int maildir_createmsg (const char *foldername, const char *seq, char **retname)
int maildir_recreatemsg (const char *folder, const char *name, char **baseptr)
static void writeflush (int n)
void maildir_writemsgstr (int n, const char *p)
void maildir_writemsg (int n, const char *p, size_t cnt)
int maildir_writemsg_flush (int n)
int maildir_closemsg (int n, const char *folder, const char *retname, int isok, unsigned long prevsize)
void maildir_deletenewmsg (int n, const char *folder, const char *retname)
void maildir_cleanup ()
void matches_free (MATCHEDSTR **p, unsigned n)
char * folder_toutf7 (const char *foldername)
char * folder_fromutf7 (const char *foldername)

Variables

static time_t current_time
const char * sqwebmail_content_charset
const char * sqwebmail_mailboxid
static char * folderdatname = 0
static struct dbobj
static const char * folderdatmode
static time_t cachemtime
static unsigned long new_cnt
static unsigned long all_cnt
static int isoldestfirst
static char sortorder
static const char spaces [] = " \t\r\n"
static char * buf = 0
size_t bufsize = 0
size_t buflen = 0
static unsigned long save_cnt
static unsigned long savenew_cnt
static time_t save_time
static char * save_dbname
static char * save_tmpdbname
static char writebuf [BUFSIZ]
static char * writebufptr
static int writebufcnt
static int writebufleft
static int writeerr
off_t writebufpos
int writebuf8bit

Class Documentation

struct searchresults_match_context

Definition at line 2008 of file maildir.c.

Collaboration diagram for searchresults_match_context:
Class Members
unicode_char * match_context
unicode_char * match_context_after
size_t match_context_after_len
size_t match_context_after_max_len
unicode_char * match_context_before
struct
searchresults_match_context *
next
struct searchresults

Definition at line 2019 of file maildir.c.

Collaboration diagram for searchresults:
Class Members
unicode_char * context_buf
size_t context_buf_head
size_t context_buf_len
size_t context_buf_tail
int finished
size_t foundcnt
struct
searchresults_match_context *
matched_context_head
struct
searchresults_match_context **
matched_context_tail
char prevchar
struct maildir_searchengine * se
char utf8buf
size_t utf8buf_cnt
struct MSGINFO_LIST

Definition at line 3208 of file maildir.c.

Collaboration diagram for MSGINFO_LIST:
Class Members
MSGINFO * minfo
struct MSGINFO_LIST * next
struct add_shared_info

Definition at line 3368 of file maildir.c.

Class Members
size_t * c
const char * inbox_pfix
char *** p
size_t * s

Define Documentation

#define dirent   direct

Definition at line 47 of file maildir.c.

#define load_int (   n,
  fp 
)
Value:
do {                               \
       int i;                                           \
       int cnt=getc(fp);                                \
       (n)=0;                                           \
       if (cnt != EOF)                                         \
              for (i=0; i<cnt; ++i)                            \
                     (n)=(n) << 8 | (unsigned char)getc(fp);   \
       } while(0);

Definition at line 1712 of file maildir.c.

#define NAMLEN (   dirent)    ((dirent)->d_namlen)

Definition at line 48 of file maildir.c.

#define save_int (   n,
  fp 
)
Value:
do {                                      \
              size_t i;                                        \
              size_t cnt=sizeof((n));                                 \
              putc(cnt, (fp));                                 \
              for (i=0; i<cnt; i++)                                   \
                     putc((n) >> (cnt-1-i)*8, (fp));                  \
       } while(0);

Definition at line 1696 of file maildir.c.

#define SEARCH_MATCH_CONTEXT_LEN   20

Definition at line 2004 of file maildir.c.

#define SEARCHFORMATVER   1

Definition at line 1848 of file maildir.c.

#define sr_context_buf_index_dec (   sr,
  n 
)    ( ( (n)+ (sr)->context_buf_len - 1 ) % ( (sr)->context_buf_len))

Definition at line 2192 of file maildir.c.

#define sr_context_buf_index_inc (   sr,
  n 
)    ( ( (n)+1 ) % ( (sr)->context_buf_len))

Definition at line 2191 of file maildir.c.


Function Documentation

static void addbuf ( int  c) [static]

Definition at line 2751 of file maildir.c.

{
       if (buflen == bufsize)
       {
       char   *newbuf= buf ? realloc(buf, bufsize+512):malloc(bufsize+512);

              if (!newbuf)  enomem();
              buf=newbuf;
              bufsize += 512;
       }
       buf[buflen++]=c;
}

Here is the caller graph for this function:

static void addfolder ( const char *  name,
char ***  buf,
size_t *  size,
size_t *  cnt 
) [static]

Definition at line 3346 of file maildir.c.

{
       if (*cnt >= *size)
       {
       char   **newbuf= *buf ? realloc(*buf, (*size + 10) * sizeof(char *))
                     : malloc( (*size+10) * sizeof(char *));

              if (!newbuf)  enomem();
              *buf=newbuf;
              *size += 10;
       }

       (*buf)[*cnt]=0;
       if ( name && ((*buf)[*cnt]=strdup(name)) == 0)   enomem();
       ++*cnt;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* alloc_filename ( const char *  dir1,
const char *  dir2,
const char *  filename 
)

Definition at line 245 of file maildir.c.

{
char   *p;

       if (!dir1)    dir1="";
       if (!dir2)    dir2="";

       p=malloc(strlen(dir1)+strlen(dir2)+strlen(filename)+3);

       if (!p)       enomem();

       strcpy(p, dir1);
       if (*dir2)
       {
              if (*p)       strcat(p, "/");
              strcat(p, dir2);
       }
       if (*filename)
       {
              if (*p)       strcat(p, "/");
              strcat(p, filename);
       }

       return (p);
}
static void cat_n ( char *  buf,
unsigned long  n 
) [static]

Definition at line 193 of file maildir.c.

{
char   bb[MAXLONGSIZE+1];
char   *p=bb+sizeof(bb)-1;

       *p=0;
       do
       {
              *--p = "0123456789"[n % 10];
              n=n/10;
       } while (n);
       strcat(buf, p);
}

Here is the caller graph for this function:

static void change_timestamp ( const char *  filename,
time_t  t 
) [static]

Definition at line 108 of file maildir.c.

{
#if    HAVE_UTIME
struct utimbuf       ut;

       ut.actime=ut.modtime=t;
       utime(filename, &ut);
#else
#if    HAVE_UTIMES
struct timeval tv;

       tv.tv_sec=t;
       tv.tv_usec=0;
       utimes(filename, &tv);
#else
#error You do not have utime or utimes function.  Upgrade your operating system.
#endif
#endif
}

Here is the caller graph for this function:

static int chkcache ( const char *  folder) [static]

Definition at line 3279 of file maildir.c.

{
       if (opencache(folder, "W")) return (-1);

       if (isoldestfirst != pref_flagisoldest1st)       return (-1);
       if (sortorder != pref_flagsortorder)             return (-1);
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void closedb ( ) [static]

Definition at line 384 of file maildir.c.

{
       if (folderdatname)
       {
              dbobj_close(&folderdat);
              free(folderdatname);
              folderdatname=0;
       }
}

Here is the caller graph for this function:

static MATCHEDSTR * creatematches ( struct searchresults sr) [static]

Definition at line 2495 of file maildir.c.

{
       size_t n=0;
       struct searchresults_match_context *smc;
       MATCHEDSTR *retval, *retptr;

       /* Count, allocate the array */
       for (smc=sr->matched_context_head; smc; smc=smc->next)
              ++n;

       if ((retval=malloc(sizeof(MATCHEDSTR)*(n+1))) == NULL)
              return NULL;

       retptr=retval;

       for (smc=sr->matched_context_head; smc; smc=smc->next)
       {
              savematch(smc, &retptr);
       }

       /* Last one */

       retptr->prefix=NULL;
       retptr->match=NULL;
       retptr->suffix=NULL;
       return retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void createmdcache ( const char *  folder,
const char *  maildir 
) [static]

Definition at line 3213 of file maildir.c.

{
char   *curname;
DIR *dirp;
struct dirent *de;
struct MSGINFO_LIST *milist, *newmi;
MSGINFO       *mi;
unsigned long cnt=0;

       curname=alloc_filename(maildir, "", "cur");

       time(&current_time);

       maildir_save_start(folder, maildir, current_time);

       milist=0;
       dirp=opendir(curname);
       while (dirp && (de=readdir(dirp)) != NULL)
       {
       char   *filename;

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

              filename=alloc_filename(curname, "", de->d_name);
              mi=maildir_ngetinfo(filename);
              free(filename);
              if (!mi)      continue;

              if (!(newmi=malloc(sizeof(struct MSGINFO_LIST)))) enomem();
              newmi->next= milist;
              milist=newmi;
              newmi->minfo=mi;
              ++cnt;
       }
       if (dirp)     closedir(dirp);
       free(curname);

       if (milist)
       {
       MSGINFO **miarray=malloc(sizeof(MSGINFO *) * cnt);
       unsigned long i;

              if (!miarray) enomem();
              i=0;
              while (milist)
              {
                     miarray[i++]=milist->minfo;
                     newmi=milist;
                     milist=newmi->next;
                     free(newmi);
              }

              qsort(miarray, cnt, sizeof(*miarray),
                     ( int (*)(const void *, const void *)) messagecmp);
              for (i=0; i<cnt; i++)
              {
                     maildir_saveinfo(miarray[i]);
                     maildir_nfreeinfo(miarray[i]);
              }
              free(miarray);
       }

       maildir_save_end(maildir);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* displaydate ( time_t  t) [static]

Definition at line 322 of file maildir.c.

{
struct tm *tmp=localtime(&t);
static char   datebuf[40];
const char *date_yfmt;
const char *date_wfmt;

                      
       date_yfmt = getarg ("DSPFMT_YDATE");
       if (*date_yfmt == 0)
              date_yfmt = "%d %b %Y";

       date_wfmt = getarg ("DSPFMT_WDATE");
       if (*date_wfmt == 0)
              date_wfmt = "%a %I:%M %p";

       datebuf[0]='\0';
       if (tmp)
       {
              strftime(datebuf, sizeof(datebuf)-1,
                     (t < current_time - 6 * 24 * 60 * 60 ||
                     t > current_time + 12 * 60 * 60
                     ? date_yfmt : date_wfmt), tmp);
              datebuf[sizeof(datebuf)-1]=0;
       }
       return (datebuf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int do_maildir_search ( const char *  filename,
struct searchresults sr 
) [static]

Definition at line 2457 of file maildir.c.

{
       struct rfc2045src *src;
       struct rfc2045_decodemsgtoutf8_cb cb;
       int fd=maildir_semisafeopen(filename, O_RDONLY, 0);
       struct rfc2045 *rfc2045p;

       if (fd < 0)
              return 0;

       rfc2045p=rfc2045_fromfd(fd);

       if (rfc2045p == NULL)
       {
              close(fd);
              return 0;
       }

       memset(&cb, 0, sizeof(cb));
       cb.output_func=do_search;
       cb.arg=sr;

       if ((src=rfc2045src_init_fd(fd)) != NULL)
       {
              if (rfc2045_decodemsgtoutf8(src, rfc2045p, &cb) == 0)
                     do_search_utf8(sr);
              rfc2045src_deinit(src);
       }

       rfc2045_free(rfc2045p);
       close(fd);
       return sr->foundcnt ? 1:0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int do_msgmove ( const char *  from,
const char *  file,
const char *  dest,
size_t  pos,
int  check_acls 
) [static]

Definition at line 844 of file maildir.c.

{
       char *destdir, *fromdir;
       const char *p;
       char *basename;
       struct stat stat_buf;
       char   *new_filename;
       unsigned long filesize=0;
       int    no_link=0;
       struct maildirsize quotainfo;
       char *newname;
       int from_shared, dest_shared;
       char acl_buf[4];

       if (stat(file, &stat_buf) || stat_buf.st_nlink != 1)
       {
              unlink(file); /* Already moved, or crashed in the middle of
                           ** moving the file, so clean up.
                           */
              return (0);
       }


       /* Update quota */

       destdir=xlate_shmdir(dest);
       if (!destdir) enomem();

       fromdir=xlate_shmdir(from);
       if (!fromdir) enomem();

       from_shared=strncmp(from, SHARED ".", sizeof(SHARED)) == 0;
       dest_shared=strncmp(dest, SHARED ".", sizeof(SHARED)) == 0;

       strcpy(acl_buf, ACL_SEEN ACL_WRITE ACL_DELETEMSGS);
       if (check_acls)
              acl_computeRightsOnFolder(dest, acl_buf);

       if (strcmp(from, dest))
       {
              if (maildir_parsequota(file, &filesize))
                     filesize=stat_buf.st_size;
                     /* Recover from possible corruption */

              if ((dest_shared
                   || !maildirquota_countfolder(destdir)) &&
                  maildirquota_countfile(file))
              {

                     if (!from_shared)
                            maildir_quota_deleted(".", -(int64_t)filesize, -1);
              }
              else if (!dest_shared && maildirquota_countfolder(destdir) &&
                      (from_shared || !maildirquota_countfolder(fromdir))
                      )
                     /* Moving FROM trash */
              {

                     if (maildir_quota_add_start(".", &quotainfo,
                                              filesize, 1, NULL))
                     {
                            free(fromdir);
                            return (-1);
                     }

                     maildir_quota_add_end(&quotainfo, filesize, 1);
              }
       }

       free(fromdir);

       if (from_shared || dest_shared)
       {
              struct maildir_tmpcreate_info createInfo;
              int    fromfd, tofd;
              char   *l;

              if (dest_shared)     /* Copy to the sharable folder */
              {
              char   *p=malloc(strlen(destdir)+sizeof("/shared"));

                     if (!p)
                     {
                            free(destdir);
                            enomem();
                     }
                     strcat(strcpy(p, destdir), "/shared");
                     free(destdir);
                     destdir=p;
              }

              maildir_tmpcreate_init(&createInfo);

              createInfo.maildir=destdir;
              createInfo.uniq="copy";
              createInfo.doordie=1;

              if ( dest_shared )
                     umask (0022);

              if ((tofd=maildir_tmpcreate_fd(&createInfo)) < 0)
              {
                     free(destdir);
                     error(strerror(errno));
              }

              if (dest_shared)
              /* We need to copy it directly into /cur of the dest folder */
              {
                     memcpy(strrchr(createInfo.newname, '/')-3, "cur", 3);
                                          /* HACK!!!!!!!!!!!! */
              }

              if ((fromfd=maildir_semisafeopen(file, O_RDONLY, 0)) < 0)
              {
                     int terrno = errno;
                     free(destdir);
                     close(tofd);
                     unlink(createInfo.tmpname);
                     maildir_tmpcreate_free(&createInfo);
                     error3(__FILE__, __LINE__, "Failed to open for read:",
                            file, terrno);
              }

              umask (0077);
              if (msgcopy(fromfd, tofd))
              {
                     int terrno = errno;
                     close(fromfd);
                     close(tofd);
                     free(destdir);
                     unlink(createInfo.tmpname);
                     maildir_tmpcreate_free(&createInfo);
                     error3(__FILE__, __LINE__, "Failed to copy message",
                            "", terrno);
              }
              close(fromfd);
              close(tofd);

       /*
       ** When we attempt to DELETE a message in the sharable folder,
       ** attempt to remove the UNDERLYING message
       */

              if (from_shared && (l=maildir_getlink(file)) != 0)
              {
                     if (unlink(l))
                     {
                            /* Not our message */

                            if (strcmp(dest, INBOX "." TRASH) == 0)
                            {
                                   free(l);
                                   unlink(createInfo.tmpname);
                                   maildir_tmpcreate_free(&createInfo);
                                   free(destdir);
                                   return (0);
                            }
                     }
                     free(l);
              }

              if (strchr(acl_buf, ACL_DELETEMSGS[0]) == 0)
                     maildir_remflagname(createInfo.newname, 'T');
              if (strchr(acl_buf, ACL_SEEN[0]) == 0)
                     maildir_remflagname(createInfo.newname, 'S');
              if (strchr(acl_buf, ACL_WRITE[0]) == 0)
              {
                     maildir_remflagname(createInfo.newname, 'F');
                     maildir_remflagname(createInfo.newname, 'D');
                     maildir_remflagname(createInfo.newname, 'R');
              }

              if (maildir_movetmpnew(createInfo.tmpname, createInfo.newname))
              {
                     free(destdir);
                     unlink(createInfo.tmpname);
                     maildir_tmpcreate_free(&createInfo);
                     error(strerror(errno));
              }
              no_link=1;    /* Don't call link(), below */
              maildir_tmpcreate_free(&createInfo);
       }

       p=strrchr(file, '/');
       if (p) ++p;
       else   p=file;

       if ( (basename=strdup(p)) == NULL)
              enomem();
       maildir_remflagname(basename, 'T');       /* Remove any deleted flag for new name */

       if (strchr(acl_buf, ACL_SEEN[0]) == 0)
              maildir_remflagname(basename, 'S');
       if (strchr(acl_buf, ACL_WRITE[0]) == 0)
       {
              maildir_remflagname(basename, 'F');
              maildir_remflagname(basename, 'D');
              maildir_remflagname(basename, 'R');
       }
       newname=alloc_filename(destdir, "cur", basename);
       free(destdir);
       free(basename);

       /* When DELETE is called for a message in TRASH, from and dest will
       ** be the same, so we just mark the file as Trashed, to be removed
       ** in checknew.
       */

       if (no_link == 0 && strcmp(from, dest))
       {
              if (link(file, newname))
              {
                     free(newname);
                     return (-1);
              }
       }
       free(newname);

       if ((new_filename=maildir_addflagfilename(file, 'T')) != 0)
       {
              rename(file, new_filename);
              update_foldermsgs(from, new_filename, pos);
              free(new_filename);
       }
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int do_search ( const char *  str,
size_t  n,
void *  arg 
) [static]

Definition at line 2398 of file maildir.c.

{
       struct searchresults *res=(struct searchresults *)arg;

       int rc=0;

       while (n && rc == 0)
       {
              char ch=*str++;
              --n;

              if (strchr(spaces, ch))
              {
                     ch=' ';

                     if (res->prevchar == ' ')
                            continue;
              }
              res->prevchar=ch;

              if (res->utf8buf_cnt >= sizeof(res->utf8buf)-1)
              {
                     size_t n;
                     char save_ch;
                     size_t save_n;

                     for (n=res->utf8buf_cnt-1;
                          n > sizeof(res->utf8buf_cnt)/2; --n)
                            if ((unsigned char)((res->utf8buf[n] ^ 0xC0)
                                              & 0xC0))
                                   break;

                     save_n=res->utf8buf_cnt;
                     save_ch=res->utf8buf[n];

                     res->utf8buf_cnt=n;

                     rc=do_search_utf8(res);

                     if (rc)
                            return rc;

                     res->utf8buf[n]=save_ch;

                     while (n < save_n)
                     {
                            res->utf8buf[res->utf8buf_cnt++]=
                                   res->utf8buf[n];
                            ++n;
                     }
              }

              res->utf8buf[res->utf8buf_cnt]=ch;
              ++res->utf8buf_cnt;
       }

       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int do_search_utf8 ( struct searchresults res) [static]

Definition at line 2320 of file maildir.c.

{
       unicode_char *uc=NULL;
       size_t n;
       libmail_u_convert_handle_t h;

       if (res->utf8buf_cnt == 0)
              return 0;

       if (res->finished)
              return -1;

       res->utf8buf[res->utf8buf_cnt]=0;
       res->utf8buf_cnt=0;

       h=libmail_u_convert_tou_init("utf-8",
                                 &uc,
                                 &n,
                                 1);

       if (h)
       {
              libmail_u_convert(h, res->utf8buf, strlen(res->utf8buf));
              if (libmail_u_convert_deinit(h, NULL) == 0)
                     ;
              else
                     uc=NULL;
       }

       for (n=0; uc && uc[n]; n++)
       {
              struct searchresults_match_context *c;

              unicode_char origch=uc[n];
              unicode_char ch=unicode_lc(origch);

              maildir_search_step_unicode(res->se, ch);

              /* Record the context, one char at a time */

              res->context_buf[res->context_buf_head]=origch;
              res->context_buf_head =
                     sr_context_buf_index_inc(res, res->context_buf_head);

              if (res->context_buf_head == res->context_buf_tail)
                     res->context_buf_tail =
                            sr_context_buf_index_inc(res, res->context_buf_tail);
              /* Accumulate post-match context for matched hits */

              for (c=res->matched_context_head; c; c=c->next)
              {
                     if (c->match_context_after_len <
                         c->match_context_after_max_len)
                            c->match_context_after[c->match_context_after_len++]=origch;
              }

              if (maildir_search_found(res->se))
              {
                     search_found_save_context(res);
                     if (++res->foundcnt > 3)
                     {
                            res->finished=1;
                            break;
                     }

                     maildir_search_reset(res->se);
              }
       }

       if (uc)
              free(uc);

       if (res->finished)
              return 1;

       return 0;            
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int docount ( const char *  fn,
unsigned *  new_cnt,
unsigned *  other_cnt 
) [static]

Definition at line 1645 of file maildir.c.

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

       if (filename) ++filename;
       else          filename=fn;

       if (*filename == '.')       return (0);   /* We don't want this one */

       c=maildirfile_type(filename);

       if (c == MSGTYPE_NEW)
              ++ *new_cnt;
       else
              ++ *other_cnt;
       return (1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void dodirscan ( const char *  folder,
const char *  dir,
unsigned *  new_cnt,
unsigned *  other_cnt 
) [static]

Definition at line 2625 of file maildir.c.

{
       DIR *dirp;
       struct dirent *de;
       char   *curname;
       struct stat cur_stat;
       struct stat c_stat;
       const  char *p;
       char   cntbuf[MAXLONGSIZE*2+4];
       char   *cntfilename;
       FILE   *fp;
       struct maildir_tmpcreate_info createInfo;

       *new_cnt=0;
       *other_cnt=0;
       curname=alloc_filename(dir, "cur", "");

       if (stat(curname, &cur_stat))
       {
              free(curname);
              return;
       }

       cntfilename=foldercountfilename(folder);
       fp=fopen(cntfilename, "r");

       if (fp)
       {
              char buf[BUFSIZ];

              if (fstat(fileno(fp), &c_stat) == 0 &&
                  c_stat.st_mtime > cur_stat.st_mtime &&
                  fgets(buf, sizeof(buf), fp))
              {
                     unsigned long n;
                     unsigned long o;

                     if ((p=parse_ul(buf, &n)) && (p=parse_ul(p, &o)))
                     {
                            *new_cnt=n;
                            *other_cnt=o;
                            free(curname);
                            fclose(fp);
                            free(cntfilename);
                            return;       /* Valid cache of count */
                     }
              }
              fclose(fp);
       }

       dirp=opendir(curname);
       while (dirp && (de=readdir(dirp)) != NULL)
              docount(de->d_name, new_cnt, other_cnt);
       if (dirp)     closedir(dirp);
       sprintf(cntbuf, "%u %u\n", *new_cnt, *other_cnt);

       maildir_tmpcreate_init(&createInfo);
       createInfo.maildir=".";
       createInfo.uniq="count";
       createInfo.doordie=1;

       fp=maildir_tmpcreate_fp(&createInfo);
       if (!fp)
       {
              free(curname);
              free(cntfilename);
              maildir_tmpcreate_free(&createInfo);
              return;
       }

       fprintf(fp, "%s", cntbuf);
       fclose(fp);
       
       if (rename(createInfo.tmpname, cntfilename) < 0 ||
           stat(cntfilename, &c_stat) < 0)
       {
              unlink(cntfilename);
              free(curname);
              free(cntfilename);
              maildir_tmpcreate_free(&createInfo);
              return;
       }
       maildir_tmpcreate_free(&createInfo);


       if (c_stat.st_mtime != cur_stat.st_mtime)
       {
              struct stat stat2;

              if (stat(curname, &stat2)
                  || stat2.st_mtime != cur_stat.st_mtime)
              {
                     /* cur directory changed while we were there, punt */

                     c_stat.st_mtime=cur_stat.st_mtime;
                     /* Reset it below */
              }
       }

       if (c_stat.st_mtime == cur_stat.st_mtime)
              /* Potential race condition */
       {
              change_timestamp(cntfilename, c_stat.st_mtime-1);
                            /* ... So rebuild it next time */
       }
       free(curname);
       free(cntfilename);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void execute_maildir_search ( const char *  dirname,
size_t  pos,
const char *  searchtxt,
const char *  charset,
unsigned  nfiles,
MSGINFO ***  retval,
MATCHEDSTR ***  retcontext,
unsigned long *  last_message_searched 
) [static]

Definition at line 2053 of file maildir.c.

{
       MSGINFO       **msginfo;
       MATCHEDSTR **matches;
       unsigned long i;
       unsigned j;
       char *utf8str;
       char *p, *q;

       if ((*retval=msginfo=malloc(sizeof(MSGINFO *)*nfiles)) == 0)
              enomem();

       if ((*retcontext=matches=malloc(sizeof(MATCHEDSTR *)*nfiles)) == 0)
       {
              free(msginfo);
              enomem();
       }

       for (i=0; i<nfiles; i++)
       {
              msginfo[i]=0;
              matches[i]=0;
       }

       if (opencache(dirname, "W"))       return;

       if (pos >= all_cnt) return;

       utf8str=libmail_u_convert_toutf8(searchtxt, charset, NULL);

       if (!utf8str)
              return;

       /* Normalize whitespace in the search string */

       p=q=utf8str;

       while (*p && strchr(spaces, *p))
              ++p;

       while (*p)
       {
              while (*p && !strchr(spaces, *p))
              {
                     *q++ = *p++;
              }

              while (*p && strchr(spaces, *p))
                     ++p;

              if (*p)
                     *q++=' ';
       }
       *q=0;

       if (*utf8str)
       {
              struct maildir_searchengine se;
              int rc=-1;
              unicode_char *ustr;
              size_t ustr_size;
              libmail_u_convert_handle_t h;

              maildir_search_init(&se);

              h=libmail_u_convert_tou_init("utf-8",
                                        &ustr,
                                        &ustr_size,
                                        1);

              if (h)
              {
                     libmail_u_convert(h, utf8str, strlen(utf8str));
                     if (libmail_u_convert_deinit(h, NULL) == 0)
                     {
                            size_t n;

                            for (n=0; ustr[n]; ++n)
                                   ustr[n]=unicode_lc(ustr[n]);

                            rc=maildir_search_start_unicode(&se, ustr);
                            free(ustr);
                     }
              }

              j=0;

              for (i=0, j=0; rc == 0 && pos+i<all_cnt && j<nfiles; ++i)
              {
                     MSGINFO *info=get_msginfo_alloc(pos+i);
                     char *filename;

                     if (!info)
                            continue;

                     *last_message_searched= pos+i;

                     filename=maildir_find(dirname, info->filename);

                     maildir_search_reset(&se);

                     if (filename)
                     {
                            struct searchresults sr;

                            info->msgnum=pos+i;

                            if (searchresults_init(&sr, &se) == 0)
                            {
                                   if (do_maildir_search(filename, &sr))
                                   {
                                          msginfo[j]=info;
                                          matches[j]=creatematches(&sr);
                                          info=NULL;
                                          ++j;
                                   }

                                   searchresults_destroy(&sr);
                            }
                            free(filename);
                     }

                     if (info)
                            maildir_nfreeinfo(info);
              }
              maildir_search_destroy(&se);
       }

       free(utf8str);
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* folder_fromutf7 ( const char *  foldername)

Definition at line 3934 of file maildir.c.

{
       char *p;
       int converr;

       p=libmail_u_convert_tobuf(foldername,
                              unicode_x_imap_modutf7,
                              sqwebmail_content_charset,
                              &converr);

       if (p && converr)
       {
              free(p);
              p=NULL;
       }

       if (p)
              return (p);

       p=strdup(foldername);
       if (!p)
              enomem();
       return (p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* folder_toutf7 ( const char *  foldername)

Definition at line 3911 of file maildir.c.

{
       char *p;
       int converr;

       p=libmail_u_convert_tobuf(foldername, sqwebmail_content_charset,
                              unicode_x_imap_modutf7, &converr);

       if (p && converr)
       {
              free(p);
              p=NULL;
       }

       if (p)
              return (p);

       p=strdup(foldername);
       if (!p)
              enomem();
       return (p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* foldercachename ( const char *  folder) [static]

Definition at line 394 of file maildir.c.

{
       char *f;

       if (strchr(folder, '/'))
       {
              enomem();
              return NULL;
       }

       f=malloc(sizeof(MAILDIRCURCACHE "/" DBNAME ".")+strlen(folder));
       if (!f)
              enomem();

       return strcat(strcpy(f, MAILDIRCURCACHE "/" DBNAME "."),
                    folder);
}

Here is the caller graph for this function:

static char* foldercountfilename ( const char *  folder) [static]

Definition at line 1097 of file maildir.c.

{
       char *f=malloc(sizeof(MAILDIRCURCACHE "/cnt.") + strlen(folder));

       if (!f)
              enomem();

       strcat(strcpy(f, MAILDIRCURCACHE "/cnt."), folder);
       return f;
}

Here is the caller graph for this function:

static MSGINFO* get_msginfo ( unsigned long  n) [static]

Definition at line 521 of file maildir.c.

{
char   namebuf[MAXLONGSIZE+40];
char   *p;
size_t len;
unsigned long ul;

static char *buf=0;
size_t bufsize=0;
static MSGINFO msginfo_buf;

       sprintf(namebuf, "REC%lu", n);

       p=dbobj_fetch(&folderdat, namebuf, strlen(namebuf), &len, "");
       if (!p)       return (0);

       if (!buf || len > bufsize)
       {
              buf= buf ? realloc(buf, len+1):malloc(len+1);
              if (!buf)     enomem();
              bufsize=len;
       }
       memcpy(buf, p, len);
       buf[len]=0;
       free(p);

       memset(&msginfo_buf, 0, sizeof(msginfo_buf));
       msginfo_buf.filename= msginfo_buf.date_s= msginfo_buf.from_s=
       msginfo_buf.subject_s= msginfo_buf.size_s="";

       for (p=buf; (p=strtok(p, "\n")) != 0; p=0)
       {
       char   *q=strchr(p, '=');

              if (!q)       continue;
              *q++=0;

              if (strcmp(p, "FILENAME") == 0)
                     msginfo_buf.filename=q;
              else if (strcmp(p, "FROM") == 0)
                     msginfo_buf.from_s=q;
              else if (strcmp(p, "SUBJECT") == 0)
                     msginfo_buf.subject_s=q;
              else if (strcmp(p, "SIZES") == 0)
                     msginfo_buf.size_s=q;
              else if (strcmp(p, "DATE") == 0 &&
                     parse_ul(q, &ul))
              {
                     msginfo_buf.date_n=ul;
                     msginfo_buf.date_s=displaydate(msginfo_buf.date_n);
              }
              else if (strcmp(p, "SIZEN") == 0 &&
                     parse_ul(q, &ul))
                     msginfo_buf.size_n=ul;
              else if (strcmp(p, "TIME") == 0 &&
                     parse_ul(q, &ul))
                     msginfo_buf.mi_mtime=ul;
              else if (strcmp(p, "INODE") == 0 &&
                     parse_ul(q, &ul))
                     msginfo_buf.mi_ino=ul;
       }
       return (&msginfo_buf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static MSGINFO* get_msginfo_alloc ( unsigned long  n) [static]

Definition at line 585 of file maildir.c.

{
MSGINFO       *msginfop=get_msginfo(n);
MSGINFO *p;

       if (!msginfop)       return (0);

       if ((p= (MSGINFO *) malloc(sizeof(*p))) == 0)
              enomem();

       memset(p, 0, sizeof(*p));
       if ((p->filename=strdup(msginfop->filename)) == 0 ||
              (p->date_s=strdup(msginfop->date_s)) == 0 ||
              (p->from_s=strdup(msginfop->from_s)) == 0 ||
              (p->subject_s=strdup(msginfop->subject_s)) == 0 ||
              (p->size_s=strdup(msginfop->size_s)) == 0)
              enomem();
       p->date_n=msginfop->date_n;
       p->size_n=msginfop->size_n;
       p->mi_mtime=msginfop->mi_mtime;
       p->mi_ino=msginfop->mi_ino;
       return (p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int goodcache ( const char *  foldername) [static]

Definition at line 1240 of file maildir.c.

{
       struct maildir_info minfo;
       char *folderdir;
       struct stat stat_buf;

       if (maildir_info_imap_find(&minfo, foldername, login_returnaddr())<0
           || minfo.homedir == NULL || minfo.maildir == NULL)
              return 0;

       maildir_info_destroy(&minfo);

       folderdir=xlate_shmdir(foldername);

       if (stat(folderdir, &stat_buf) < 0)
       {
              free(folderdir);
              return 0;
       }
       free(folderdir);
       return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void list_callback ( const char *  n,
void *  vp 
) [static]

Definition at line 3375 of file maildir.c.

{
       struct add_shared_info *i=
              (struct add_shared_info *)vp;
       char *o;

       while (*n)
       {
              if (*n == '.')
                     break;
              ++n;
       }

       o=malloc(strlen(i->inbox_pfix)+strlen(n)+1);
       if (!o)
              enomem();
       strcat(strcpy(o, i->inbox_pfix), n);

       addfolder(o, i->p, i->s, i->c);

       free(o);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void list_sharable_callback ( const char *  n,
void *  vp 
) [static]

Definition at line 3412 of file maildir.c.

{
       struct add_shared_info *i=
              (struct add_shared_info *)vp;
       char *p=malloc(sizeof(SHARED ".") + strlen(n));
       size_t j;

       if (!p)
              enomem();
       strcat(strcpy(p, SHARED "."), n);

       for (j=0; j< *i->c; j++)
              if (strcmp( (*i->p)[j], p) == 0)
              {
                     free(p);
                     return;
              }

       addfolder(p, i->p, i->s, i->c);
       free(p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void list_shared_callback ( const char *  n,
void *  vp 
) [static]

Definition at line 3398 of file maildir.c.

{
       struct add_shared_info *i=
              (struct add_shared_info *)vp;
       char *p=malloc(sizeof(SHARED ".") + strlen(n));

       if (!p)
              enomem();
       strcat(strcpy(p, SHARED "."), n);

       addfolder(p, i->p, i->s, i->c);
       free(p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void load_msginfo ( MSGINFO **  retinfo,
MATCHEDSTR **  retmatches,
FILE *  fp 
) [static]

Definition at line 1777 of file maildir.c.

{
       MSGINFO *p=malloc(sizeof(MSGINFO));
       size_t context_cnt;
       MATCHEDSTR *c;

       if (p == 0)
              enomem();

       load_int(p->msgnum, fp);
       p->filename=load_str(fp);
       p->date_s=load_str(fp);
       p->from_s=load_str(fp);
       p->subject_s=load_str(fp);
       p->size_s=load_str(fp);
       load_int(p->date_n, fp);
       load_int(p->size_n, fp);
       load_int(p->mi_mtime, fp);
       load_int(p->mi_ino, fp);

       *retinfo=p;

       load_int(context_cnt, fp);

       *retmatches=NULL;

       if (context_cnt)
       {
              *retmatches=c=malloc(sizeof(MATCHEDSTR)*(context_cnt+1));

              for (; context_cnt; --context_cnt)
              {
                     char *prefix=load_str(fp);
                     char *match=load_str(fp);
                     char *suffix=load_str(fp);

                     if (c)
                     {
                            c->prefix=prefix;
                            c->match=match;
                            c->suffix=suffix;
                            ++c;
                     }
                     else
                     {
                            free(prefix);
                            free(match);
                            free(suffix);
                     }
              }

              if (c)
              {
                     c->prefix=NULL;
                     c->match=NULL;
                     c->suffix=NULL;
              }
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* load_str ( FILE *  fp) [static]

Definition at line 1721 of file maildir.c.

{
       size_t l;
       size_t i;
       char *str;

       load_int(l, fp);

       if (feof(fp))
              l=0;

       str=malloc(l+1);

       if (!str)
              enomem();

       for (i=0; i<l; i++)
       {
              char c=getc(fp);

              str[i]=c;
       }

       str[i]=0;
       return str;
}

Here is the caller graph for this function:

static char* maildir_addflagfilename ( const char *  filename,
char  flag 
) [static]

Definition at line 354 of file maildir.c.

{
char   *new_filename=malloc(strlen(filename)+5);
              /* We can possibly add as many as four character */
char   *p;
char   *q;

       strcpy(new_filename, filename);
       p=strrchr(new_filename, '/');
       if (!p)       p=new_filename;
       if ((q=strchr(p, ':')) == 0)
              strcat(new_filename, ":2,");
       else if (q[1] != '2' && q[2] != ',')
              strcpy(p, ":2,");
       p=strchr(p, ':');
       if (strchr(p, flag))
       {
              free(new_filename);
              return (0);          /* Already set */
       }

       p += 2;
       while (*p && *p < flag)     p++;
       q=p+strlen(p);
       while ((q[1]=*q) != *p)
              --q;
       *p=flag;
       return (new_filename);
}

Here is the caller graph for this function:

Definition at line 1263 of file maildir.c.

{
       char   *dir;
       char   *dirbuf;
       struct stat   stat_buf;
       DIR    *dirp;
       struct dirent *dire;
       char   *filename;
       char buffer[80];
       size_t n, i;
       FILE *fp;

       /* This is called when logging in.  Version 0.18 supports maildir
       ** quotas, so automatically upgrade all folders.
       */

       for (dirp=opendir("."); dirp && (dire=readdir(dirp)) != 0; )
       {
              if (dire->d_name[0] != '.') continue;
              if (strcmp(dire->d_name, "..") == 0)      continue;

              if (strcmp(dire->d_name, "."))
              {
                     filename=alloc_filename(dire->d_name,
                                          "maildirfolder", "");
                     if (!filename)       enomem();
                     close(open(filename, O_RDWR|O_CREAT, 0644));
                     free(filename);
              }

              /* Eliminate obsoleted cache files */

              filename=alloc_filename(dire->d_name, MAILDIRCOUNTCACHE, "");

              if (!filename)       enomem();
              unlink(filename);
              free(filename);

              filename=alloc_filename(dire->d_name, MAILDIRCURCACHE, "");

              if (!filename)       enomem();
              unlink(filename);
              free(filename);

              filename=alloc_filename(dire->d_name, "", 
                                   MAILDIRCURCACHE "." DBNAME);
              if (!filename)       enomem();
              unlink(filename);
              free(filename);
       }

       /* Version 0.24 top level remove */

       unlink(MAILDIRCURCACHE);

       /* Version 4 top level remove */

       unlink(MAILDIRCURCACHE "." DBNAME);
       mkdir (MAILDIRCURCACHE, 0700);

       if (dirp)
              closedir(dirp);

       /*
       ** Periodically purge stale cache files of nonexistent folders.
       ** This is done by using a counter that runs from 0 up until the
       ** # of files in MAILDIRCURCACHE.  At each login, we check if
       ** file #n is for an existing folder.  If not, the stale file is
       ** removed.
       */

       n=0;

       if ((fp=fopen(MAILDIRCURCACHE "/.purgecnt", "r")) != NULL)
       {
              if (fgets(buffer, sizeof(buffer), fp) != NULL)
                     n=atoi(buffer);
              fclose(fp);
       }

       i=0;

       for (dirp=opendir(MAILDIRCURCACHE); dirp && (dire=readdir(dirp)); )
       {
              char *folderdir;

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

              if (strncmp(dire->d_name, DBNAME ".", sizeof(DBNAME)) == 0 ||
                  strncmp(dire->d_name, "cnt.", 4) == 0)
              {
                     if (i == n)
                     {
                            if (!goodcache(strchr(dire->d_name, '.')+1))
                            {
                                   folderdir=malloc(sizeof(MAILDIRCURCACHE
                                                        "/")
                                                  + strlen(dire->
                                                          d_name));
                                   if (!folderdir)
                                          enomem();
                                   strcat(strcpy(folderdir,
                                                MAILDIRCURCACHE "/"),
                                          dire->d_name);
                                   unlink(folderdir);
                                   free(folderdir);
                            }
                            break;
                     }
                     ++i;
                     continue;
              }

              folderdir=malloc(sizeof(MAILDIRCURCACHE "/")
                             + strlen(dire->d_name));
              if (!folderdir)
                     enomem();
              strcat(strcpy(folderdir, MAILDIRCURCACHE "/"), dire->d_name);
              unlink(folderdir);
              free(folderdir);
       }
       if (dirp)
              closedir(dirp);

       if (i == n)
              ++i;
       else
              i=0;


       if ((fp=fopen(MAILDIRCURCACHE "/.purgecnt.tmp", "w")) == NULL ||
           fprintf(fp, "%lu\n", (unsigned long)i) < 0 ||
           fflush(fp) < 0)
              enomem();

       fclose(fp);
       if (rename(MAILDIRCURCACHE "/.purgecnt.tmp",
                 MAILDIRCURCACHE "/.purgecnt") < 0)
              enomem();

       dir=xlate_mdir(INBOX "." TRASH);

       /* Delete old files in tmp */

       time(&current_time);
       dirbuf=alloc_filename(dir, "cur", "");
       free(dir);

       for (dirp=opendir(dirbuf); dirp && (dire=readdir(dirp)) != 0; )
       {
              if (dire->d_name[0] == '.') continue;
              filename=alloc_filename(dirbuf, dire->d_name, "");
              if (stat(filename, &stat_buf) == 0 &&
                  pref_autopurge &&
                  stat_buf.st_ctime < current_time
                  - pref_autopurge * 24 * 60 * 60)
              {
                     if (maildirquota_countfolder(dirbuf) &&
                         maildirquota_countfile(filename))
                     {
                            unsigned long filesize=0;

                            if (maildir_parsequota(filename, &filesize))
                                   filesize=stat_buf.st_size;

                            if (filesize > 0)
                                   maildir_quota_deleted(".",
                                                       -(int64_t)filesize,
                                                       -1);
                     }

                     unlink(filename);
              }

              free(filename);
       }
       if (dirp)     closedir(dirp);
       free(dirbuf);

       maildir_purgemimegpg();
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* maildir_basename ( const char *  filename)

Definition at line 306 of file maildir.c.

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

       if (q) ++q;
       else   q=filename;
       p=alloc_filename("", "", q);
       if ((r=strchr(p, ':')) != 0)       *r='\0';
       return (p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void maildir_checknew ( const char *  folder,
const char *  dir 
) [static]

Definition at line 1112 of file maildir.c.

{
       char   *dirbuf;
       struct stat   stat_buf;
       DIR    *dirp;
       struct dirent *dire;
       char   acl_buf[2];

       /* Delete old files in tmp */

       maildir_purgetmp(dir);

       /* Move everything from new to cur */

       dirbuf=alloc_filename(dir, "new", "");

       for (dirp=opendir(dirbuf); dirp && (dire=readdir(dirp)) != 0; )
       {
       char   *oldname, *newname;
       char   *p;

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

              oldname=alloc_filename(dirbuf, dire->d_name, "");

              newname=malloc(strlen(oldname)+4);
              if (!newname) enomem();

              strcat(strcat(strcpy(newname, dir), "/cur/"), dire->d_name);
              p=strrchr(newname, '/');
              if ((p=strchr(p, ':')) != NULL)    *p=0;  /* Someone screwed up */
              strcat(newname, ":2,");
              rename(oldname, newname);
              free(oldname);
              free(newname);
       }
       if (dirp)     closedir(dirp);
       free(dirbuf);

       /* Look for any messages mark as deleted.  When we delete a message
       ** we link it into the Trash folder, and mark the original with a T,
       ** which we delete when we check for new messages.
       */

       dirbuf=alloc_filename(dir, "cur", "");
       if (stat(dirbuf, &stat_buf))
       {
              free(dirbuf);
              return;
       }

       /* If the count cache file is still current, the directory hasn't
       ** changed, so we don't need to scan it for deleted messages.  When
       ** a message is deleted, the rename bumps up the timestamp.
       **
       ** This depends on dodirscan() being called after this function,
       ** which updates MAILDIRCOUNTCACHE
       */

       {
              char *f=foldercountfilename(folder);
              struct stat c_stat_buf;

              if (stat(f, &c_stat_buf) == 0 && c_stat_buf.st_mtime >
                  stat_buf.st_mtime)
              {
                     free(f);
                     free(dirbuf);
                     return;
              }
              free(f);
       }

       strcpy(acl_buf, ACL_EXPUNGE);
       acl_computeRightsOnFolder(folder, acl_buf);

       for (dirp=opendir(dirbuf); dirp && (dire=readdir(dirp)) != 0; )
       {
       char   *p;

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

              if (maildirfile_type(dire->d_name) == MSGTYPE_DELETED &&
                  acl_buf[0])
              {
                     p=alloc_filename(dirbuf, "", dire->d_name);


                     /*
                     ** Because of the funky way we do things,
                     ** if we were compiled with --enable-trashquota,
                     ** purging files from Trash should decrease the
                     ** quota
                     */

                     if (strcmp(folder, INBOX "." TRASH) == 0 &&
                         maildirquota_countfolder(dir))
                     {
                            struct stat stat_buf;
                            unsigned long filesize=0;

                            if (maildir_parsequota(dire->d_name,
                                                 &filesize))
                                   if (stat(p, &stat_buf) == 0)
                                          filesize=stat_buf.st_size;

                            if (filesize > 0)
                                   maildir_quota_deleted(".",
                                                       -(int64_t)filesize,
                                                       -1);
                     }

                     maildir_unlinksharedmsg(p);
                            /* Does The Right Thing if this is a shared
                            ** folder
                            */
                            
                     free(p);
              }
       }
       if (dirp)     closedir(dirp);
       free(dirbuf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_cleanup ( )

Definition at line 3881 of file maildir.c.

{
       closedb();
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_closemsg ( int  n,
const char *  folder,
const char *  retname,
int  isok,
unsigned long  prevsize 
)

Definition at line 3773 of file maildir.c.

{
       char   *dir=xlate_mdir(folder);
       char   *oldname=alloc_filename(dir, "tmp", retname);
       char   *newname;
       struct stat   stat_buf;

 
       writeflush(n);       /* If there's still anything in the buffer */
       if (fstat(n, &stat_buf))
       {
              close(n);
              unlink(oldname);
              enomem();
       }

       newname=maildir_find(folder, retname);
              /* If we called recreatemsg before */

       if (!newname)
       {
              newname=alloc_filename(dir, "cur:2,S", retname);
              /* Hack of the century          ^^^^ */
              strcat(strcat(strcat(strcpy(newname, dir), "/cur/"),
                     retname), ":2,S");
       }

       if (writeerr)
       {
              close(n);
              unlink(oldname);
              enomem();
       }

       close(n);

       if (isok)
       {
              if (prevsize < stat_buf.st_size)
              {
                     struct maildirsize info;

                     if (maildir_quota_add_start(".", &info,
                                              stat_buf.st_size-prevsize,
                                              prevsize == 0 ? 1:0,
                                              NULL))
                     {
                            if (isok < 0) /* Force it */
                            {
                                   maildir_quota_deleted(".", (int64_t)
                                                       (stat_buf.st_size
                                                        -prevsize),
                                                       prevsize == 0
                                                       ? 1:0);
                                   isok= -2;
                            }
                            else
                                   isok=0;
                     }
                     maildir_quota_add_end(&info, stat_buf.st_size-prevsize,
                                         prevsize == 0 ? 1:0);
              }
              else if (prevsize != stat_buf.st_size)
              {
                     maildir_quota_deleted(".", (int64_t)
                                         (stat_buf.st_size-prevsize),
                                         prevsize == 0 ? 1:0);
              }
       }

       if (isok)
              rename(oldname, newname);
              
       unlink(oldname);

       if (isok)
       {
       char   *realnewname=maildir_requota(newname, stat_buf.st_size);

              if (strcmp(newname, realnewname))
                     rename(newname, realnewname);
              free(realnewname);
       }
       free(dir);
       free(oldname);
       free(newname);
       return (isok && isok != -2? 0:-1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_count ( const char *  folder,
unsigned *  new_ptr,
unsigned *  other_ptr 
)

Definition at line 2570 of file maildir.c.

{
       struct maildir_info minfo;
       char *dir;

       *new_ptr=0;
       *other_ptr=0;

       if (maildir_info_imap_find(&minfo, folder,
                               login_returnaddr()) < 0)
              return;

       if (minfo.mailbox_type == MAILBOXTYPE_OLDSHARED)
       {
              dir=maildir_shareddir(".", strchr(folder, '.')+1);

              if (!dir)
              {
                     maildir_info_destroy(&minfo);
                     return;
              }

              maildir_shared_sync(dir);
       }
       else
       {
              if (minfo.homedir == NULL || minfo.maildir == NULL)
              {
                     maildir_info_destroy(&minfo);
                     return;
              }

              dir=maildir_name2dir(minfo.homedir, minfo.maildir);

              if (!dir)
              {
                     maildir_info_destroy(&minfo);
                     return;
              }
       }

       maildir_info_destroy(&minfo);
       maildir_checknew(folder, dir);
       dodirscan(folder, dir, new_ptr, other_ptr);
       free(dir);
}

Here is the call graph for this function:

Here is the caller graph for this function:

unsigned maildir_countof ( const char *  folder)

Definition at line 2619 of file maildir.c.

{
       maildir_getfoldermsgs(folder);
       return (all_cnt);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_create ( const char *  foldername)

Definition at line 3493 of file maildir.c.

{
       char   *dir;
       int    rc= -1;

       dir=xlate_mdir(foldername);
       if (!dir)
              return 0;

       if (mkdir(dir, 0700) == 0)
       {
       char *tmp=alloc_filename(dir, "tmp", "");

              if (mkdir(tmp, 0700) == 0)
              {
              char *tmp2=alloc_filename(dir, "new", "");

                     if (mkdir(tmp2, 0700) == 0)
                     {
                     char *tmp3=alloc_filename(dir, "cur", "");

                            if (mkdir(tmp3, 0700) == 0)
                            {
                            char *tmp4=alloc_filename(dir, "maildirfolder",
                                   "");

                                   close(open(tmp4, O_RDWR|O_CREAT, 0600));
                                   rc=0;
                                   free(tmp4);
                            }
                            free(tmp3);
                     }
                     if (rc)       rmdir(tmp2);
                     free (tmp2);
              }
              if (rc)       rmdir(tmp);
              free(tmp);
       }
       if (rc)       rmdir(dir);
       free(dir);
       return (rc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_createmsg ( const char *  foldername,
const char *  seq,
char **  retname 
)

Definition at line 3599 of file maildir.c.

{
       char   *p;
       char   *dir=xlate_mdir(foldername);
       char   *filename;
       int    n;
       struct maildir_tmpcreate_info createInfo;

       /* Create a new file in the tmp directory. */

       maildir_tmpcreate_init(&createInfo);

       createInfo.maildir=dir;
       createInfo.uniq=seq;
       createInfo.doordie=1;

       if ((n=maildir_tmpcreate_fd(&createInfo)) < 0)
       {
              error("maildir_createmsg: cannot create temp file.");
       }

       /*
       ** Ok, new maildir semantics: filename in new is different than in tmp.
       ** Originally this whole scheme was designed with the filenames being
       ** the same.  We can fix it like this:
       */

       close(n);

       memcpy(strrchr(createInfo.newname, '/')-3, "tmp", 3); /* Hack */

       if (rename(createInfo.tmpname, createInfo.newname) < 0 ||
           (n=open(createInfo.newname, O_RDWR)) < 0)
       {
              error("maildir_createmsg: cannot create temp file.");
       }


       filename=createInfo.newname;
       createInfo.newname=NULL;

       maildir_tmpcreate_free(&createInfo);

       p=strrchr(filename, '/');
       *retname=strdup(p+1);

       if (*retname == 0)
       {
              close(n);
              free(filename);
              enomem();
       }
       free(filename);

       /* Buffer writes */

       writebufcnt=0;
       writebufpos=0;
       writebuf8bit=0;
       writebufleft=0;
       writeerr=0;
       return (n);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_delete ( const char *  foldername,
int  deletecontent 
)

Definition at line 3536 of file maildir.c.

{
       char   *dir, *tmp, *new, *cur;
       int    rc=0;

       struct maildir_info minfo;

       if (maildir_info_imap_find(&minfo, foldername, login_returnaddr())<0)
              return -1;

       if (strcmp(minfo.maildir, INBOX) == 0 ||
           strcmp(minfo.maildir, INBOX "." SENT) == 0 ||
           strcmp(minfo.maildir, INBOX "." TRASH) == 0 ||
           strcmp(minfo.maildir, INBOX "." DRAFTS) == 0 ||
           (dir=maildir_name2dir(minfo.homedir, minfo.maildir)) == NULL)

       {
              maildir_info_destroy(&minfo);
              return (-1);
       }

       tmp=alloc_filename(dir, "tmp", "");
       cur=alloc_filename(dir, "cur", "");
       new=alloc_filename(dir, "new", "");

       if (!deletecontent)
       {
              if (rmdir(new) || rmdir(cur))
              {
                     mkdir(new, 0700);
                     mkdir(cur, 0700);
                     rc= -1;
              }
       }

       if (rc == 0 && maildir_del(dir))
              rc= -1;

       if (rc == 0)
              maildir_acl_delete(minfo.homedir,
                               strchr(minfo.maildir, '.'));

       maildir_info_destroy(&minfo);
       free(tmp);
       free(new);
       free(cur);
       free(dir);
       return (rc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_deletenewmsg ( int  n,
const char *  folder,
const char *  retname 
)

Definition at line 3870 of file maildir.c.

{
char   *dir=xlate_mdir(folder);
char   *oldname=alloc_filename(dir, "tmp", retname);

       close(n);
       unlink(oldname);
       free(oldname);
       free(dir);
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* maildir_find ( const char *  folder,
const char *  filename 
)

Definition at line 279 of file maildir.c.

{
char   *p;
char   *d=xlate_shmdir(folder);
int    fd;

       if (!d)       return (0);
       p=maildir_filename(d, 0, filename);
       free(d);

       if (!p)       enomem();

       if ((fd=open(p, O_RDONLY)) >= 0)
       {
              close(fd);
              return (p);
       }
       free(p);
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_free ( MSGINFO **  files,
unsigned  nfiles 
)

Definition at line 2736 of file maildir.c.

{
unsigned i;

       for (i=0; i<nfiles; i++)
       {
              if ( files[i] )
                     maildir_nfreeinfo( files[i] );
       }
       free(files);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_freefolders ( char ***  fp)

Definition at line 3484 of file maildir.c.

{
size_t cnt;

       for (cnt=0; (*fp)[cnt]; cnt++)
              free( (*fp)[cnt] );
       free(*fp);
}

Here is the caller graph for this function:

static void maildir_getfoldermsgs ( const char *  folder) [static]

Definition at line 3288 of file maildir.c.

{
char   *dir=xlate_shmdir(folder);

       if (!dir)     return;

       while ( chkcache(folder) )
       {
              closedb();
              createmdcache(folder, dir);
       }
       free(dir);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_listfolders ( const char *  inbox_pfix,
const char *  homedir,
char ***  fp 
)

Definition at line 3441 of file maildir.c.

{
       size_t fbsize=0;
       size_t fbcnt=0;
       struct add_shared_info info;
       size_t sh_cnt;

       *fp=0;

       info.p=fp;
       info.s= &fbsize;
       info.c= &fbcnt;
       info.inbox_pfix=inbox_pfix;

       if (!homedir)
              homedir=".";

       /*
       ** Sort unsubscribed folders AFTER all subscribed folders.
       ** This is done by grabbing INBOX, then shared subscribed folders
       ** first, memorizing the folder cnt, adding unsubscribed folders,
       ** then sorting the unsubscribed folders separately.
       */

       maildir_list(homedir, list_callback, &info);

       if (strcmp(homedir, ".") == 0)
              maildir_list_shared(".", list_shared_callback, &info);

       sh_cnt=fbcnt;
       if (strcmp(homedir, ".") == 0)
              maildir_list_sharable(".", list_sharable_callback, &info);

       qsort( (*fp), sh_cnt, sizeof(**fp),
              (int (*)(const void *, const void *))shcomparefunc);

       qsort( (*fp)+sh_cnt, fbcnt-sh_cnt, sizeof(**fp),
              (int (*)(const void *, const void *))shcomparefunc);
       addfolder(NULL, fp, &fbsize, &fbcnt);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_loadsearch ( unsigned  nfiles,
MSGINFO ***  retmsginfo,
MATCHEDSTR ***  retmatches,
unsigned long *  last_message_searched 
)

Definition at line 1911 of file maildir.c.

{
       MSGINFO       **msginfo;
       MATCHEDSTR **matches;

       unsigned i;
       const char *filename;
       char *buf;
       FILE *fp;
       char ver;

       if ((msginfo=malloc(sizeof(MSGINFO *)*nfiles)) == 0)
              enomem();

       if ((matches=malloc(sizeof(MATCHEDSTR *)*nfiles)) == 0)
       {
              free(msginfo);
              enomem();
       }

       for (i=0; i<nfiles; i++)
       {
              msginfo[i]=0;
              matches[i]=0;
       }

       filename=cgi(SEARCHRESFILENAME);
       CHECKFILENAME(filename);

       buf=malloc(strlen(filename)+5);

       if (!buf)
       {
              free(msginfo);
              enomem();
       }

       strcat(strcpy(buf, "tmp/"), filename);

       fp=fopen(buf, "r");
       free(buf);

       if (fp)
       {
              load_int(ver, fp);

              if (ver == SEARCHFORMATVER)
              {
                     load_int(*last_message_searched, fp);
                     for (i=0; i<nfiles; ++i)
                     {
                            int ch=getc(fp);

                            if (ch == EOF)
                                   break;
                            ungetc(ch, fp);

                            load_msginfo(&msginfo[i], &matches[i], fp);
                     }
              }
       }
       fclose(fp);

       for (i=0; i<nfiles; ++i)
       {
              MSGINFO *p;

              if (msginfo[i] == 0)
                     continue;

              p=get_msginfo(msginfo[i]->msgnum);

              if (p && p->mi_ino == msginfo[i]->mi_ino) /* Safety first */
              {
                     char *f=strdup(p->filename);
                     if (f)
                     {
                            if (msginfo[i]->filename)
                                   free(msginfo[i]->filename);
                            msginfo[i]->filename=f;
                     }
              }
       }

       *retmsginfo=msginfo;
       *retmatches=matches;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void maildir_markflag ( const char *  folder,
size_t  pos,
char  flag 
) [static]

Definition at line 659 of file maildir.c.

{
MSGINFO       *p;
char   *filename;
char   *new_filename;

       if (opencache(folder, "W") || (p=get_msginfo(pos)) == 0)
       {
              error("Internal error in maildir_markflag");
              return;
       }

       filename=maildir_find(folder, p->filename);
       if (!filename)       return;

       if ((new_filename=maildir_addflagfilename(filename, flag)) != 0)
       {
              rename(filename, new_filename);
              update_foldermsgs(folder, new_filename, pos);
              free(new_filename);
       }
       free(filename);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_markread ( const char *  folder,
size_t  pos 
)

Definition at line 683 of file maildir.c.

{
       char acl_buf[2];

       strcpy(acl_buf, ACL_SEEN);
       acl_computeRightsOnFolder(folder, acl_buf);
       if (acl_buf[0])
              maildir_markflag(folder, pos, 'S');
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_markreplied ( const char *  folder,
const char *  message 
)

Definition at line 693 of file maildir.c.

{
       char   *filename;
       char   *new_filename;
       char acl_buf[2];

       strcpy(acl_buf, ACL_WRITE);
       acl_computeRightsOnFolder(folder, acl_buf);

       if (acl_buf[0] == 0)
              return;

       filename=maildir_find(folder, message);

       if (filename &&
              (new_filename=maildir_addflagfilename(filename, 'R')) != 0)
       {
              rename(filename, new_filename);
              free(new_filename);
       }
       if (filename) free(filename);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_msgdeletefile ( const char *  folder,
const char *  file,
size_t  pos 
)

Definition at line 1074 of file maildir.c.

{
char *filename=maildir_find(folder, file);

       if (filename)
       {
              (void)do_msgmove(folder, filename, INBOX "." TRASH, pos, 0);
              free(filename);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_msgmovefile ( const char *  folder,
const char *  file,
const char *  dest,
size_t  pos 
)

Definition at line 1085 of file maildir.c.

{
       char *filename=maildir_find(folder, file);
       int    rc;

       if (!filename)       return (0);
       rc=do_msgmove(folder, filename, dest, pos, 1);
       free(filename);
       return (rc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_msgpurge ( const char *  folder,
size_t  pos 
)

Definition at line 768 of file maildir.c.

{
char *filename=maildir_posfind(folder, &pos);

       if (filename)
       {
              unlink(filename);
              free(filename);
       }
}

Here is the call graph for this function:

void maildir_msgpurgefile ( const char *  folder,
const char *  msgid 
)

Definition at line 779 of file maildir.c.

{
char *filename=maildir_find(folder, msgid);

       if (filename)
       {
              char *d=xlate_shmdir(folder);

              if (d)
              {
                     if (strncmp(folder, SHARED ".", sizeof(SHARED))
                         && maildirquota_countfolder(d) &&
                         maildirquota_countfile(filename))
                     {
                            unsigned long filesize=0;

                            if (maildir_parsequota(filename, &filesize))
                            {
                                   struct stat stat_buf;

                                   if (stat(filename, &stat_buf) == 0)
                                          filesize=stat_buf.st_size;
                            }

                            if (filesize > 0)
                                   maildir_quota_deleted(".",
                                                       -(int64_t)filesize,
                                                       -1);
                     }
                     free(d);
              }
              unlink(filename);
              free(filename);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_name2pos ( const char *  folder,
const char *  filename,
size_t *  pos 
)

Definition at line 732 of file maildir.c.

{
       char *p, *q;
       size_t len;

       maildir_reload(folder);
       if (opencache(folder, "R"))
       {
              error("Internal error in maildir_name2pos");
              return (0);
       }

       p=malloc(strlen(filename)+10);
       if (!p)
              enomem();
       strcat(strcpy(p, "FILE"), filename);
       q=strchr(p, ':');
       if (q)
              *q=0;

       q=dbobj_fetch(&folderdat, p, strlen(p), &len, "");
       free(p);

       if (!q)
              return (-1);

       *pos=0;
       for (p=q; len; --len, p++)
       {
              if (isdigit((int)(unsigned char)*p))
                     *pos = *pos * 10 + (*p-'0');
       }
       free(q);
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_nfreeinfo ( MSGINFO mi)

Definition at line 2878 of file maildir.c.

{
       if (mi->filename)    free(mi->filename);
       if (mi->date_s)      free(mi->date_s);
       if (mi->from_s)      free(mi->from_s);
       if (mi->subject_s)   free(mi->subject_s);
       if (mi->size_s)      free(mi->size_s);
       free(mi);
}

Here is the caller graph for this function:

MSGINFO* maildir_ngetinfo ( const char *  filename)

Definition at line 2890 of file maildir.c.

{
FILE   *fp;
MSGINFO       *mi;
struct stat stat_buf;
char   *hdr, *val;
const char *p;
int    is_sent_header=0;
char   *fromheader=0;
int    fd;

       /* Hack - see if we're reading a message from the Sent or Drafts
              folder */

       p=strrchr(filename, '/');
       if ((p && p - filename >=
              sizeof(SENT) + 5 && strncmp(p - (sizeof(SENT) + 5),
                     "/." SENT "/", sizeof(SENT)+2) == 0)
              || strncmp(filename, "." SENT "/", sizeof(SENT)+1) == 0
              || strncmp(filename, "./." SENT ".", sizeof(SENT)+3) == 0
              || strncmp(filename, "." SENT ".", sizeof(SENT)+1) == 0)
              is_sent_header=1;
       if ((p && p - filename >=
              sizeof(DRAFTS) + 5 && strncmp(p-(sizeof(DRAFTS) + 5),
                     "/." DRAFTS "/", sizeof(DRAFTS)+2) == 0)
              || strncmp(filename, "." DRAFTS "/", sizeof(DRAFTS)+1) == 0)
              is_sent_header=1;

       if ((mi=(MSGINFO *)malloc(sizeof(MSGINFO))) == 0)
              enomem();

       memset(mi, '\0', sizeof(*mi));

       fp=0;
       fd=maildir_semisafeopen(filename, O_RDONLY, 0);
       if (fd >= 0)
              if ((fp=fdopen(fd, "r")) == 0)
                     close(fd);

       if (fp == NULL)
       {
              free(mi);
              return (NULL);
       }

       /* mi->filename shall be the base filename, normalized as :2, */

       if ((p=strrchr(filename, '/')) != NULL)
              p++;
       else   p=filename;

       if (!(mi->filename=strdup(p)))
              enomem();

       if (fstat(fileno(fp), &stat_buf) == 0)
       {
              mi->mi_mtime=stat_buf.st_mtime;
              mi->mi_ino=stat_buf.st_ino;
              mi->size_n=stat_buf.st_size;
              mi->size_s=strdup( showsize(stat_buf.st_size));
              mi->date_n=mi->mi_mtime;    /* Default if no Date: */
              if (!mi->size_s)     enomem();
       }
       else
       {
              free(mi->filename);
              fclose(fp);
              free(mi);
              return (0);
       }


       while ((hdr=maildir_readheader(fp, &val, 0)) != 0)
       {
              if (strcmp(hdr, "subject") == 0)
              {
                     char *uibuf=rfc822_display_hdrvalue_tobuf("subject",
                                                          val,
                                                          "utf-8",
                                                          NULL, NULL);

                     if (mi->subject_s)   free(mi->subject_s);

                     mi->subject_s=uibuf;
                     if (!mi->subject_s)  enomem();
              }

              if (strcmp(hdr, "date") == 0 && mi->date_s == 0)
              {
              time_t t=rfc822_parsedt(val);

                     if (t)
                     {
                            mi->date_n=t;
                            mi->date_s=strdup(displaydate(mi->date_n));
                            if (!mi->date_s)     enomem();
                     }
              }

              if ((is_sent_header ?
                     strcmp(hdr, "to") == 0 || strcmp(hdr, "cc") == 0:
                     strcmp(hdr, "from") == 0) && fromheader == 0)
              {
                     struct rfc822t *from_addr;
                     struct rfc822a *from_addra;
                     char   *p;
                     int dotflag=0;
                     int cnt;

                     from_addr=rfc822t_alloc_new(val, NULL, NULL);
                     if (!from_addr)      enomem();
                     from_addra=rfc822a_alloc(from_addr);
                     if (!from_addra)     enomem();

                     p=NULL;

                     for (cnt=0; cnt<from_addra->naddrs; ++cnt)
                     {
                            if (from_addra->addrs[cnt].tokens == NULL)
                                   continue;

                            if (p)
                            {
                                   dotflag=1;
                                   break;
                            }

                            p=rfc822_display_name_tobuf(from_addra, cnt,
                                                     "utf-8");
                     }

                     if (p)
                     {
                            if (fromheader)      free(fromheader);
                            if ((fromheader=malloc(strlen(p)+7)) == 0)
                                   enomem();
                            strcpy(fromheader, p);
                            if (dotflag)
                                   strcat(fromheader, "...");

                            free(p);
                     }

                     rfc822a_free(from_addra);
                     rfc822t_free(from_addr);
              }

              if (mi->date_s && fromheader && mi->subject_s)
                     break;
       }
       fclose(fp);

       mi->from_s=fromheader;
       if (!mi->date_s)
              mi->date_s=strdup(displaydate(mi->date_n));
       if (!mi->date_s)     enomem();
       if (!mi->from_s && !(mi->from_s=strdup("")))     enomem();
       if (!mi->subject_s && !(mi->subject_s=strdup("")))      enomem();
       return (mi);
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* maildir_posfind ( const char *  folder,
size_t *  pos 
)

Definition at line 716 of file maildir.c.

{
MSGINFO       *p;
char   *filename;

       if (opencache(folder, "R") || (p=get_msginfo( *pos)) == 0)
       {
              error("Internal error in maildir_posfind");
              return (0);
       }

       filename=maildir_find(folder, p->filename);
       return(filename);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1454 of file maildir.c.

{
       DIR    *dirp;
       struct dirent *dire;
       char *p;

       for (dirp=opendir("tmp"); dirp && (dire=readdir(dirp)) != 0; )
       {
              if (strstr(dire->d_name, ":mimegpg:") == 0 &&
                  strstr(dire->d_name, ":calendar:") == 0)     continue;

              p=malloc(sizeof("tmp/")+strlen(dire->d_name));

              if (p)
              {
                     strcat(strcpy(p, "tmp/"), dire->d_name);
                     unlink(p);
                     free(p);
              }
       }

       if (dirp)
              closedir(dirp);
}

Here is the caller graph for this function:

Definition at line 1481 of file maildir.c.

{
       DIR    *dirp;
       struct dirent *dire;
       char *p;

       for (dirp=opendir("tmp"); dirp && (dire=readdir(dirp)) != 0; )
       {
              if (strstr(dire->d_name, ":search:") == 0)       continue;

              p=malloc(sizeof("tmp/")+strlen(dire->d_name));

              if (p)
              {
                     strcat(strcpy(p, "tmp/"), dire->d_name);
                     unlink(p);
                     free(p);
              }
       }

       if (dirp)
              closedir(dirp);
}

Here is the caller graph for this function:

MSGINFO** maildir_read ( const char *  dirname,
unsigned  nfiles,
size_t *  starting_pos,
int *  morebefore,
int *  moreafter 
)

Definition at line 1664 of file maildir.c.

{
MSGINFO       **msginfo;
size_t i;

       if ((msginfo=malloc(sizeof(MSGINFO *)*nfiles)) == 0)
              enomem();
       for (i=0; i<nfiles; i++)
              msginfo[i]=0;

       if (opencache(dirname, "W"))       return (msginfo);

       if (nfiles > all_cnt)       nfiles=all_cnt;
       if (*starting_pos + nfiles > all_cnt)
              *starting_pos=all_cnt-nfiles;

       *morebefore = *starting_pos > 0;

       for (i=0; i<nfiles; i++)
       {
              if (*starting_pos + i >= all_cnt)  break;
              if ((msginfo[i]= get_msginfo_alloc(*starting_pos + i)) == 0)
                     break;

              msginfo[i]->msgnum=*starting_pos+i;
       }
       *moreafter= *starting_pos + i < all_cnt;
       return (msginfo);
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* maildir_readheader ( FILE *  fp,
char **  value,
int  preserve_nl 
)

Definition at line 2860 of file maildir.c.

{
       return (maildir_readheader_mimepart(fp, value, preserve_nl, 0, 0));
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* maildir_readheader_mimepart ( FILE *  fp,
char **  value,
int  preserve_nl,
off_t *  mimepos,
const off_t *  endpos 
)

Definition at line 2812 of file maildir.c.

{
       int    c;
       int    eatspaces=0;

       buflen=0;

       if (mimepos && *mimepos >= *endpos)       return (0);

       while (mimepos == 0 || *mimepos < *endpos)
       {
              if ((c=getc(fp)) != '\n' && c >= 0)
              {
                     if (c != ' ' && c != '\t' && c != '\r')
                            eatspaces=0;

                     if (!eatspaces)
                            addbuf(c);
                     if (mimepos)  ++ *mimepos;
                     continue;
              }
              if ( c == '\n' && mimepos)  ++ *mimepos;
              if (buflen == 0)     return (0);
              if (c < 0)    break;
              c=getc(fp);
              if (c >= 0)   ungetc(c, fp);
              if (c < 0 || c == '\n' || !isspace(c))    break;
              addbuf(preserve_nl ? '\n':' ');
              if (!preserve_nl)
                     eatspaces=1;
       }
       addbuf(0);

       for ( *value=buf; **value; (*value)++)
       {
              if (**value == ':')
              {
                     **value='\0';
                     ++*value;
                     break;
              }
              **value=tolower(**value);
       }
       while (**value && isspace((int)(unsigned char)**value)) ++*value;
       return(buf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* maildir_readheader_nolc ( FILE *  fp,
char **  value 
)

Definition at line 2777 of file maildir.c.

{
       int c;

       buflen=0;

       while ((c=getc(fp)) != EOF)
       {
              if (c != '\n')
              {
                     addbuf(c);
                     continue;
              }
              c=getc(fp);
              if (c >= 0) ungetc(c, fp);
              if (c < 0 || c == '\n' || !isspace(c)) break;
              addbuf('\n');
       }
       addbuf(0);

       if (c == EOF && buf[0] == 0) return (0);

       for ( *value=buf; **value; (*value)++)
       {
              if (**value == ':')
              {
                     **value='\0';
                     ++*value;
                     break;
              }
       }
       while (**value && isspace((int)(unsigned char)**value)) ++*value;
       return(buf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* maildir_readline ( FILE *  fp)

Definition at line 2764 of file maildir.c.

{
int    c;

       buflen=0;
       while ((c=getc(fp)) != '\n' && c >= 0)
              if (buflen < 8192)
                     addbuf(c);
       if (c < 0 && buflen == 0)   return (NULL);
       addbuf(0);
       return (buf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_recreatemsg ( const char *  folder,
const char *  name,
char **  baseptr 
)

Definition at line 3667 of file maildir.c.

{
char   *dir=xlate_mdir(folder);
char   *base;
char   *p;
int    n;

       base=maildir_basename(name);
       p=alloc_filename(dir, "tmp", base);

       free(dir);
       *baseptr=base;
       n=maildir_safeopen(p, O_CREAT|O_RDWR|O_TRUNC, 0644);
       if (n < 0)    free(base);
       free(p);
       writebufcnt=0;
       writebufleft=0;
       writeerr=0;
       writebufpos=0;
       writebuf8bit=0;
       return (n);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_reload ( const char *  folder)

Definition at line 3314 of file maildir.c.

{
char   *dir=xlate_shmdir(folder);
char   *curname;
struct stat   stat_buf;

       if (!dir)     return;

       curname=alloc_filename(dir, "cur", ".");
       time(&current_time);

       /* Remove old cache file when: */

       if (opencache(folder, "W") == 0)
       {
              if ( stat(curname, &stat_buf) != 0 ||
                     stat_buf.st_mtime >= cachemtime)
              {
                     closedb();
                     createmdcache(folder, dir);
              }
       }
       free(dir);
       maildir_getfoldermsgs(folder);
       free(curname);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_remcache ( const char *  folder)

Definition at line 3302 of file maildir.c.

{
       char   *dir=xlate_shmdir(folder);
       char   *cachename=foldercachename(folder);

       unlink(cachename);
       if (folderdatname && strcmp(folderdatname, cachename) == 0)
              closedb();
       free(cachename);
       free(dir);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void maildir_remflagname ( char *  filename,
char  flag 
) [static]

Definition at line 496 of file maildir.c.

{
char   *p;

       p=strrchr(filename, '/');
       if (!p)       p=filename;
       if ((p=strchr(p, ':')) == 0)       return;
       else if (p[1] != '2' && p[2] != ',')
              return;

       p=strchr(p, ':');
       p += 3;

       while (*p && isalpha((int)(unsigned char)*p))
       {
              if (*p == flag)
              {
                     while ( (*p=p[1]) != 0)
                            p++;
                     return;
              }
              p++;
       }
}

Here is the caller graph for this function:

static void maildir_save_end ( const char *  maildir) [static]

Definition at line 3168 of file maildir.c.

{
char   *curname;
char   *rec;

       curname=alloc_filename(maildir, "", "cur");

       rec=malloc(MAXLONGSIZE*4+sizeof(
                     "SAVETIME=\n"
                     "COUNT=\n"
                     "NEWCOUNT=\n"
                     "SORT=\n")+100);

       if (!rec)     enomem();
       sprintf(rec,
              "SAVETIME=%lu\nCOUNT=%lu\nNEWCOUNT=%lu\nSORT=%d%c\n",
              (unsigned long)save_time,
              (unsigned long)save_cnt,
              (unsigned long)savenew_cnt,
                     pref_flagisoldest1st,
                     pref_flagsortorder);
       if (dbobj_store(&tmpdb, "HEADER", 6, rec, strlen(rec), "R"))
              enomem();
       dbobj_close(&tmpdb);
       free(rec);

       rename(save_tmpdbname, save_dbname);
       unlink(save_tmpdbname);

       free(curname);
       free(save_dbname);
       free(save_tmpdbname);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void maildir_save_start ( const char *  folder,
const char *  maildir,
time_t  t 
) [static]

Definition at line 3062 of file maildir.c.

{
       int fd;
       struct maildir_tmpcreate_info createInfo;

       save_dbname=foldercachename(folder);

       save_time=t;
#if 1
       {
         int f = -1;
         char *tmpfname = alloc_filename(maildir,
                                      "", MAILDIRCURCACHE ".nfshack");
         if (tmpfname) {
           f = open(tmpfname, O_CREAT|O_WRONLY, 0600);
           free(tmpfname);
         }
         if (f != -1) {
           struct stat s;
           if (write(f, ".", 1) != 1)
                  ; /* ignore */
           fsync(f);
           if (fstat(f, &s) == 0)
             save_time = s.st_mtime;
           close(f);
           unlink(tmpfname);
         }
       }
#endif

       maildir_tmpcreate_init(&createInfo);
       createInfo.maildir=maildir;
       createInfo.uniq="sqwebmail-db";
       createInfo.doordie=1;

       if ((fd=maildir_tmpcreate_fd(&createInfo)) < 0)
       {
              fprintf(stderr, "ERR: Can't create cache file %s: %s\n",
                     maildir, strerror(errno));
              error(strerror(errno));
       }
       close(fd);

       save_tmpdbname=createInfo.tmpname;
       createInfo.tmpname=NULL;
       maildir_tmpcreate_free(&createInfo);

       dbobj_init(&tmpdb);

       if (dbobj_open(&tmpdb, save_tmpdbname, "N")) {
              fprintf(stderr, "ERR: Can't create cache file |%s|: %s\n", save_tmpdbname, strerror(errno));
              error("Can't create cache file.");
       }

       save_cnt=0;
       savenew_cnt=0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_savefoldermsgs ( const char *  folder)

Definition at line 3202 of file maildir.c.

{
}

Here is the caller graph for this function:

static void maildir_saveinfo ( MSGINFO m) [static]

Definition at line 3121 of file maildir.c.

{
char   *rec, *p;
char   recnamebuf[MAXLONGSIZE+40];

       rec=malloc(strlen(m->filename)+strlen(m->from_s)+
              strlen(m->subject_s)+strlen(m->size_s)+MAXLONGSIZE*4+
              sizeof("FILENAME=\nFROM=\nSUBJECT=\nSIZES=\nDATE=\n"
                     "SIZEN=\nTIME=\nINODE=\n")+100);
       if (!rec)     enomem();

       sprintf(rec, "FILENAME=%s\nFROM=%s\nSUBJECT=%s\nSIZES=%s\n"
              "DATE=%lu\n"
              "SIZEN=%lu\n"
              "TIME=%lu\n"
              "INODE=%lu\n",
              m->filename,
              m->from_s,
              m->subject_s,
              m->size_s,
              (unsigned long)m->date_n,
              (unsigned long)m->size_n,
              (unsigned long)m->mi_mtime,
              (unsigned long)m->mi_ino);
       sprintf(recnamebuf, "REC%lu", (unsigned long)save_cnt);
       if (dbobj_store(&tmpdb, recnamebuf, strlen(recnamebuf),
              rec, strlen(rec), "R"))
              enomem();
       free(rec);

       /* Reverse lookup */
       rec=malloc(strlen(m->filename)+10);
       if (!rec)
              enomem();
       strcat(strcpy(rec, "FILE"), m->filename);
       if ((p=strchr(rec, ':')) != 0)
              *p=0;
       sprintf(recnamebuf, "%lu", (unsigned long)save_cnt);
       if (dbobj_store(&tmpdb, rec, strlen(rec),
                     recnamebuf, strlen(recnamebuf), "R"))
              enomem();

       save_cnt++;
       if (maildirfile_type(m->filename) == MSGTYPE_NEW)
              savenew_cnt++;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_search ( const char *  dirname,
size_t  pos,
const char *  searchtxt,
const char *  charset,
unsigned  nfiles 
)

Definition at line 1850 of file maildir.c.

{
       struct maildir_tmpcreate_info createInfo;

       MSGINFO **p;
       MATCHEDSTR **pcontext;
       char *filename;
       FILE *fp;
       unsigned i;

       unsigned long last_message_searched=0;

       execute_maildir_search(dirname, pos, searchtxt, charset,
                            nfiles, &p, &pcontext, &last_message_searched);

       maildir_purgesearch();

       maildir_tmpcreate_init(&createInfo);

       createInfo.uniq=":search:";
       createInfo.doordie=1;

       if ((fp=maildir_tmpcreate_fp(&createInfo)) == NULL)
       {
              if (p)
                     maildir_free(p, nfiles);
              error("Can't create new file.");
       }

       filename=createInfo.tmpname;
       createInfo.tmpname=NULL;
       maildir_tmpcreate_free(&createInfo);

       chmod(filename, 0600);

       {
              char ver=SEARCHFORMATVER;

              save_int(ver, fp);
              save_int(last_message_searched, fp);
       }

       for (i=0; i<nfiles; i++)
              if (p[i])
                     save_msginfo(p[i], pcontext[i], fp);
       fflush(fp);
       if (ferror(fp) || fclose(fp))
              error("Cannot create temp file");

       cgi_put(SEARCHRESFILENAME, strrchr(filename, '/')+1);

       if (p)
              maildir_free(p, nfiles);
       if (pcontext)
              matches_free(pcontext, nfiles);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_writemsg ( int  n,
const char *  p,
size_t  cnt 
)

Definition at line 3730 of file maildir.c.

{
int    c;
size_t i;

       writebufpos += cnt;  /* I'm optimistic */
       for (i=0; i<cnt; i++)
              if (p[i] & 0x80)     writebuf8bit=1;

       while (cnt)
       {
              /* Flush buffer if it's full.  No need to flush if we've
              ** already had an error before. */

              if (writebufleft == 0)      writeflush(n);

              c=writebufleft;
              if (c > cnt)  c=cnt;
              memcpy(writebufptr, p, c);
              writebufptr += c;
              p += c;
              cnt -= c;
              writebufcnt += c;
              writebufleft -= c;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int maildir_writemsg_flush ( int  n)

Definition at line 3767 of file maildir.c.

{
       writeflush(n);
       return (writeerr);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void maildir_writemsgstr ( int  n,
const char *  p 
)

Definition at line 3725 of file maildir.c.

{
       maildir_writemsg(n, p, strlen(p));
}

Here is the call graph for this function:

Here is the caller graph for this function:

char maildirfile_type ( const char *  p)

Definition at line 1610 of file maildir.c.

{
const char *q=strrchr(p, '/');
int    seen_trash=0, seen_r=0, seen_s=0;

       if (q) p=q;

       if ( !(p=strchr(p, ':')) || *++p != '2' || *++p != ',')
              return (MSGTYPE_NEW);              /* No :2,info */
                            ;
       ++p;
       while (p && isalpha((int)(unsigned char)*p))
              switch (*p++) {
              case 'T':
                     seen_trash=1;
                     break;
              case 'R':
                     seen_r=1;
                     break;
              case 'S':
                     seen_s=1;
                     break;
              }

       if (seen_trash)
              return (MSGTYPE_DELETED);   /* Trashed message */
       if (seen_s)
       {
              if (seen_r)   return (MSGTYPE_REPLIED);
              return (0);
       }

       return (MSGTYPE_NEW);
}

Here is the caller graph for this function:

static char* match_conv ( const unicode_char uc) [static]

Definition at line 2523 of file maildir.c.

{
       char *cbuf;
       size_t csize;
       libmail_u_convert_handle_t h;
       size_t i;

       if ((h=libmail_u_convert_fromu_init("utf-8", &cbuf, &csize, 1)) == NULL)
              return NULL;

       for (i=0; uc[i]; ++i)
              ;

       libmail_u_convert_uc(h, uc, i);

       if (libmail_u_convert_deinit(h, NULL))
              return NULL;
       return cbuf;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void matches_free ( MATCHEDSTR **  p,
unsigned  n 
)

Definition at line 3886 of file maildir.c.

{
       size_t i;

       for (i=0; p && i<n; ++i)
       {
              MATCHEDSTR *q;

              for (q=p[i]; q && q->match; ++q)
              {
                     free(q->prefix);
                     free(q->match);
                     free(q->suffix);
              }
              if (p[i])
                     free(p[i]);
       }
       if (p)
              free(p);
}

Here is the caller graph for this function:

static int messagecmp ( const MSGINFO **  pa,
const MSGINFO **  pb 
) [static]

Definition at line 1571 of file maildir.c.

{
int    gt=1, lt=-1;
int    n;
const MSGINFO *a= *pa;
const MSGINFO *b= *pb;

       if (pref_flagisoldest1st)
       {
              gt= -1;
              lt= 1;
       }

       switch (pref_flagsortorder) {
       case 'F':
              n=strcasecmp(a->from_s, b->from_s);
              if (n) return (n);
              break;
       case 'S':
              n=subjectcmp(a->subject_s, b->subject_s);
              if (n) return (n);
              break;
       }
       if (a->date_n < b->date_n)  return (gt);
       if (a->date_n > b->date_n)  return (lt);

       if (a->mi_ino < b->mi_ino)  return (gt);
       if (a->mi_ino > b->mi_ino)  return (lt);
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int msgcopy ( int  fromfd,
int  tofd 
) [static]

Definition at line 821 of file maildir.c.

{
char   buf[8192];
int    i, j;
char   *p;

       while ((i=read(fromfd, buf, sizeof(buf))) > 0)
       {
              p=buf;
              while (i)
              {
                     j=write(tofd, p, i);
                     if (j <= 0)   return (-1);
                     p += j;
                     i -= j;
              }
       }
       return (i);
}

Here is the caller graph for this function:

static int opencache ( const char *  folder,
const char *  mode 
) [static]

Definition at line 412 of file maildir.c.

{
char   *cachename;
size_t l;
char   *p;
char   *q;
char   *r;
unsigned long ul;

       {
              char   *maildir=xlate_shmdir(folder);

              if (!maildir) return (-1);
              free(maildir);
       }

       cachename=foldercachename(folder);

       if (folderdatname && strcmp(folderdatname, cachename) == 0)
       {
              if (strcmp(mode, "W") == 0 &&
                     strcmp(folderdatmode, "W"))
                     ;
                     /*
                     ** We want to open for write, folder is open for
                     ** read
                     */
              else
              {
                     free(cachename);
                     return (0);
                            /* We already have this folder cache open */
              }
       }
       closedb();
       folderdatmode=mode;

       dbobj_init(&folderdat);
       if (dbobj_open(&folderdat, cachename, mode))     return (-1);
       folderdatname=cachename;

       if ((p=dbobj_fetch(&folderdat, "HEADER", 6, &l, "")) == 0)
              return (0);
       q=malloc(l+1);
       if (!q)       enomem();
       memcpy(q, p, l);
       q[l]=0;
       free(p);

       cachemtime=0;
       new_cnt=0;
       all_cnt=0;
       isoldestfirst=0;
       sortorder=0;

       for (p=q; (p=strtok(p, "\n")) != 0; p=0)
       {
              if ((r=strchr(p, '=')) == 0)       continue;
              *r++=0;
              if (strcmp(p, "SAVETIME") == 0 &&
                     parse_ul(r, &ul))
                     cachemtime=ul;
              else if (strcmp(p, "COUNT") == 0)
                     parse_ul(r, &all_cnt);
              else if (strcmp(p, "NEWCOUNT") == 0)
                     parse_ul(r, &new_cnt);
              else if (strcmp(p, "SORT") == 0)
              {
              unsigned long ul;
              const char *s;

                     if ((s=parse_ul(r, &ul)) != 0)
                     {
                            isoldestfirst=ul;
                            sortorder= *s;
                     }
              }
       }
       free(q);
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static const char* parse_ul ( const char *  p,
unsigned long *  ul 
) [static]

Definition at line 91 of file maildir.c.

{
int    err=1;

       while (p && isspace((int)(unsigned char)*p))     ++p;
       *ul=0;
       while (p && *p >= '0' && *p <= '9')
       {
              *ul *= 10;
              *ul += (*p-'0');
              err=0;
              ++p;
       }
       if (err)      return (0);
       return (p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void put_msginfo ( MSGINFO m,
unsigned long  n 
) [static]

Definition at line 609 of file maildir.c.

{
char   namebuf[MAXLONGSIZE+40];
char   *rec;

       sprintf(namebuf, "REC%lu", n);

       rec=malloc(strlen(m->filename)+strlen(m->from_s)+
              strlen(m->subject_s)+strlen(m->size_s)+MAXLONGSIZE*4+
              sizeof("FILENAME=\nFROM=\nSUBJECT=\nSIZES=\nDATE=\n"
                     "SIZEN=\nTIME=\nINODE=\n")+100);
       if (!rec)     enomem();

       sprintf(rec, "FILENAME=%s\nFROM=%s\nSUBJECT=%s\nSIZES=%s\n"
              "DATE=%lu\n"
              "SIZEN=%lu\n"
              "TIME=%lu\n"
              "INODE=%lu\n",
              m->filename,
              m->from_s,
              m->subject_s,
              m->size_s,
              (unsigned long)m->date_n,
              (unsigned long)m->size_n,
              (unsigned long)m->mi_mtime,
              (unsigned long)m->mi_ino);

       if (dbobj_store(&folderdat, namebuf, strlen(namebuf),
              rec, strlen(rec), "R"))
              enomem();
       free(rec);
}

Here is the caller graph for this function:

time_t rfc822_parsedt ( const char *  )

Definition at line 125 of file rfc822_parsedt.c.

{
unsigned day=0, mon=0, year;
int secs;
int offset;
time_t t;
unsigned y;

       /* Ignore day of the week.  Tolerate "Tue, 25 Feb 1997 ... "
       ** without the comma.  Tolerate "Feb 25 1997 ...".
       */

       while (!day || !mon)
       {
              if (!*rfcdt)  return (0);
              if (my_isalpha(*rfcdt))
              {
                     if (mon)      return (0);
                     mon=parsekey(&rfcdt, mnames);
                     if (!mon)
                            while (*rfcdt && my_isalpha(*rfcdt))
                                   ++rfcdt;
                     continue;
              }

              if (my_isdigit(*rfcdt))
              {
                     if (day)      return (0);
                     day=parsedig(&rfcdt);
                     if (!day)     return (0);
                     continue;
              }
              ++rfcdt;
       }

       while (*rfcdt && my_isspace(*rfcdt))
              ++rfcdt;
       if (!my_isdigit(*rfcdt))    return (0);
       year=parsedig(&rfcdt);
       if (year < 70)       year += 2000;
       if (year < 100)      year += 1900;

       while (*rfcdt && my_isspace(*rfcdt))
              ++rfcdt;

       if (day == 0 || mon == 0 || mon > 12 || day > mdays(mon,year))
              return (0);

       secs=parsetime(&rfcdt);
       if (secs < 0) return (0);

       offset=0;

       /* RFC822 sez no parenthesis, but I've seen (EST) */

       while ( *rfcdt )
       {
              if (my_isalnum(*rfcdt) || *rfcdt == '+' || *rfcdt == '-')
                     break;
              ++rfcdt;
       }

       if (my_isalpha((int)(unsigned char)*rfcdt))
       {
       int    n=parsekey(&rfcdt, zonenames);

              if (n > 0)    offset= zoneoffset[n-1];
       }
       else
       {
       int    sign=1;
       unsigned n;

              switch (*rfcdt)      {
              case '-':
                     sign= -1;
              case '+':
                     ++rfcdt;
              }

              if (my_isdigit(*rfcdt))
              {
                     n=parsedig(&rfcdt);
                     if (n > 2359 || (n % 100) > 59)    n=0;
                     offset = sign * ( (n % 100) * 60 + n / 100 * 60 * 60);
              }
       }

       if (year < 1970)     return (0);
       if (year > 9999)     return (0);

       t=0;
       for (y=1970; y<year; y++)
       {
              if ( leap(y) )
              {
                     if (year-y >= 4)
                     {
                            y += 3;
                            t += ( 365*3+366 ) * 24 * 60 * 60;
                            continue;
                     }
                     t += 24 * 60 * 60;
              }
              t += 365 * 24 * 60 * 60;
       }

       for (y=1; y < mon; y++)
              t += mdays(y, year) * 24 * 60 * 60;

       return ( t + (day-1) * 24 * 60 * 60 + secs - offset );
}

Here is the call graph for this function:

static void save_msginfo ( const MSGINFO p,
MATCHEDSTR context,
FILE *  fp 
) [static]

Definition at line 1748 of file maildir.c.

{
       size_t context_cnt;
       MATCHEDSTR *c;

       save_int(p->msgnum, fp);
       save_str(p->filename, fp);
       save_str(p->date_s, fp);
       save_str(p->from_s, fp);
       save_str(p->subject_s, fp);
       save_str(p->size_s, fp);
       save_int(p->date_n, fp);
       save_int(p->size_n, fp);
       save_int(p->mi_mtime, fp);
       save_int(p->mi_ino, fp);

       for (context_cnt=0, c=context; c && c->match; ++c, ++context_cnt)
              ;

       save_int(context_cnt, fp);

       for (c=context; c && c->match; ++c)
       {
              save_str(c->prefix, fp);
              save_str(c->match, fp);
              save_str(c->suffix, fp);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void save_str ( const char *  str,
FILE *  fp 
) [static]

Definition at line 1704 of file maildir.c.

{
       size_t l=strlen(str);

       save_int(l, fp);
       fprintf(fp, "%s", str);
}

Here is the caller graph for this function:

static void savematch ( struct searchresults_match_context smc,
MATCHEDSTR **  curptr 
) [static]

Definition at line 2543 of file maildir.c.

{
       if ( ((*curptr)->prefix=match_conv(smc->match_context_before))
            == NULL)
              return;

       if ( ((*curptr)->match=match_conv(smc->match_context)) == NULL)
       {
              free( (*curptr)->prefix );
              return;
       }

       smc->match_context_after[smc->match_context_after_len]=0;

       if ( ((*curptr)->suffix=match_conv(smc->match_context_after))
            == NULL)
       {
              free( (*curptr)->match );
              free( (*curptr)->prefix );
              return;
       }
       ++ (*curptr);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void search_found_save_context ( struct searchresults sr) [static]

Definition at line 2235 of file maildir.c.

{
       struct searchresults_match_context *c=
              malloc(sizeof(struct searchresults_match_context));
       size_t n, i, j;;

       if (c == NULL)
              return;

       if ((c->match_context_before=malloc((SEARCH_MATCH_CONTEXT_LEN+1)
                                       * sizeof(unicode_char))) == NULL)
       {
              free(c);
              return;
       }

       if ((c->match_context=malloc((maildir_search_len(sr->se)+1)
                                 * sizeof(unicode_char))) == NULL)
       {
              free(c->match_context_before);
              free(c);
              return;
       }

       if ((c->match_context_after=malloc((SEARCH_MATCH_CONTEXT_LEN+1)
                                      * sizeof(unicode_char))) == NULL)
       {
              free(c->match_context);
              free(c->match_context_before);
              free(c);
              return;
       }

       c->next=NULL;

       *sr->matched_context_tail=c;
       sr->matched_context_tail= &c->next;

       /*
       ** Subtract from the head of the context buffer to arrive at the
       ** start of the matched context
       */

       n=sr->context_buf_head;

       for (i=maildir_search_len(sr->se); i > 0; --i)
       {
              if (n == sr->context_buf_tail)
                     break; /* Shouldn't happen */

              n=sr_context_buf_index_dec(sr, n);
       }

       /* From here to the head is the matched context */

       j=0;
       for (i=n; i != sr->context_buf_head; )
       {
              c->match_context[j++]=sr->context_buf[i];
              i=sr_context_buf_index_inc(sr, i);
       }
       c->match_context[j]=0;

       /* Now, look before the start of the matched context */

       for (i=n, j=0; j<SEARCH_MATCH_CONTEXT_LEN; ++j)
       {
              if (i == sr->context_buf_tail)
                     break; /* Possible */

              i=sr_context_buf_index_dec(sr, i);
       }

       j=0;
       while (i != n)
       {
              c->match_context_before[j++]=sr->context_buf[i];
              i=sr_context_buf_index_inc(sr, i);
       }
       c->match_context_before[j]=0;

       c->match_context_after_len=0;
       c->match_context_after_max_len=SEARCH_MATCH_CONTEXT_LEN;
}

Here is the caller graph for this function:

static void searchresults_destroy ( struct searchresults sr) [static]

Definition at line 2217 of file maildir.c.

Here is the caller graph for this function:

static int searchresults_init ( struct searchresults sr,
struct maildir_searchengine se 
) [static]

Definition at line 2194 of file maildir.c.

Here is the caller graph for this function:

static int shcomparefunc ( char **  a,
char **  b 
) [static]

Definition at line 3434 of file maildir.c.

{
       char   *ca= *a, *cb= *b;

       return (strcasecmp(ca, cb));
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* showsize ( unsigned long  n)

Definition at line 207 of file maildir.c.

{
static char   sizebuf[MAXLONGSIZE+10];

       /* If size is less than 1K bytes, display it as 0.xK */

       if (n < 1024)
       {
              strcpy(sizebuf, "0.");
              cat_n(sizebuf, (int)(10 * n / 1024 ));
              strcat(sizebuf, "K");
       }
       /* If size is less than 1 meg, display is as xK */

       else if (n < 1024 * 1024)
       {
              *sizebuf=0;
              cat_n(sizebuf, (unsigned long)(n+512)/1024);
              strcat(sizebuf, "K");
       }

       /* Otherwise, display in megabytes */

       else
       {
       unsigned long nm=(double)n / (1024.0 * 1024.0) * 10;

              *sizebuf=0;
              cat_n( sizebuf, nm / 10);
              strcat(sizebuf, ".");
              cat_n( sizebuf, nm % 10);
              strcat(sizebuf, "M");
       }
       return (sizebuf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int subjectcmp ( const char *  a,
const char *  b 
) [static]

Definition at line 1505 of file maildir.c.

{
       int    aisre;
       int    bisre;
       int    n;
       char   *as;
       char   *bs;

       as=rfc822_display_hdrvalue_tobuf("subject", a, "utf-8",
                                    NULL, NULL);

       if (!as)
              as=strdup(a);

       bs=rfc822_display_hdrvalue_tobuf("subject", b, "utf-8",
                                    NULL, NULL);

       if (!bs)
              bs=strdup(b);

       if (as)
       {
              char *p=rfc822_coresubj(as, &aisre);

              free(as);
              as=p;
       }

       if (bs)
       {
              char *p=rfc822_coresubj(bs, &bisre);

              free(bs);
              bs=p;
       }

       if (!as || !bs)
       {
              if (as)       free(as);
              if (bs)       free(bs);
              enomem();
       }

       n=strcasecmp(as, bs);
       free(as);
       free(bs);

       if (aisre)
              aisre=1;      /* Just to be sure */

       if (bisre)
              bisre=1;      /* Just to be sure */

       if (n == 0)   n=aisre - bisre;
       return (n);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void update_foldermsgs ( const char *  folder,
const char *  newname,
size_t  pos 
) [static]

Definition at line 642 of file maildir.c.

{
MSGINFO       *p;
char *n;

       n=strrchr(newname, '/')+1;
       if (opencache(folder, "W") || (p=get_msginfo(pos)) == 0)
       {
              error("Internal error in update_foldermsgs");
              return;
       }

       p->filename=n;

       put_msginfo(p, pos);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void writeflush ( int  n) [static]

Definition at line 3693 of file maildir.c.

{
const char    *q=writebuf;
int    c;

       /* Keep calling write() until there's an error, or we're all done */

       while (!writeerr && writebufcnt)
       {
              c=write(n, q, writebufcnt);
              if ( c <= 0)
                     writeerr=1;
              else
              {
                     q += c;
                     writebufcnt -= c;
              }
       }

       /* We have an empty buffer now */

       writebufcnt=0;
       writebufleft=sizeof(writebuf);
       writebufptr=writebuf;
}
static char* xlate_mdir ( const char *  foldername) [static]

Definition at line 130 of file maildir.c.

{
       struct maildir_info minfo;
       char   *p;

       if (maildir_info_imap_find(&minfo, foldername,
                               login_returnaddr())<0)
       {
              cginocache();
              printf("Content-Type: text/plain\n\n"
                     "Unable to translate mailbox: %s\n",
                     foldername);
              cleanup();
              fake_exit(1);
       }

       if (minfo.homedir == NULL || minfo.maildir == NULL)
       {
              maildir_info_destroy(&minfo);
              cginocache();
              printf("Content-Type: text/plain\n\n"
                     "Mailbox \"%s\" is not supported.\n",
                     foldername);
              cleanup();
              fake_exit(1);
              enomem();
       }

       p=maildir_name2dir(minfo.homedir, minfo.maildir);

       maildir_info_destroy(&minfo);
       return p;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* xlate_shmdir ( const char *  foldername) [static]

Definition at line 164 of file maildir.c.

{
       struct maildir_info minfo;
       char   *p;

       if (maildir_info_imap_find(&minfo, foldername,
                               login_returnaddr())<0)
       {
              printf("Content-Type: text/plain\n\n%s\n", foldername);
              enomem();
       }

       if (minfo.mailbox_type == MAILBOXTYPE_OLDSHARED)
              return maildir_shareddir(".", strchr(foldername, '.')+1);

       if (minfo.homedir == NULL || minfo.maildir == NULL)
       {
              maildir_info_destroy(&minfo);
              enomem();
       }

       p=maildir_name2dir(minfo.homedir, minfo.maildir);

       maildir_info_destroy(&minfo);
       return p;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

unsigned long all_cnt [static]

Definition at line 81 of file maildir.c.

char* buf = 0 [static]

Definition at line 2748 of file maildir.c.

size_t buflen = 0

Definition at line 2749 of file maildir.c.

size_t bufsize = 0

Definition at line 2749 of file maildir.c.

time_t cachemtime [static]

Definition at line 80 of file maildir.c.

time_t current_time [static]

Definition at line 70 of file maildir.c.

struct dbobj [static]

Definition at line 77 of file maildir.c.

const char* folderdatmode [static]

Definition at line 78 of file maildir.c.

char* folderdatname = 0 [static]

Definition at line 76 of file maildir.c.

int isoldestfirst [static]

Definition at line 82 of file maildir.c.

unsigned long new_cnt [static]

Definition at line 81 of file maildir.c.

unsigned long save_cnt [static]

Definition at line 3055 of file maildir.c.

char* save_dbname [static]

Definition at line 3058 of file maildir.c.

time_t save_time [static]

Definition at line 3056 of file maildir.c.

char* save_tmpdbname [static]

Definition at line 3059 of file maildir.c.

unsigned long savenew_cnt [static]

Definition at line 3055 of file maildir.c.

char sortorder [static]

Definition at line 83 of file maildir.c.

const char spaces[] = " \t\r\n" [static]

Definition at line 2002 of file maildir.c.

Definition at line 39 of file gpg.c.

const char* sqwebmail_mailboxid

Definition at line 105 of file sqwebmail.c.

char writebuf[BUFSIZ] [static]

Definition at line 3592 of file maildir.c.

Definition at line 3597 of file maildir.c.

int writebufcnt [static]

Definition at line 3594 of file maildir.c.

int writebufleft [static]

Definition at line 3594 of file maildir.c.

off_t writebufpos

Definition at line 3596 of file maildir.c.

char* writebufptr [static]

Definition at line 3593 of file maildir.c.

int writeerr [static]

Definition at line 3595 of file maildir.c.