Back to index

courier  0.68.2
Classes | Functions | Variables
fetch.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "imaptoken.h"
#include "imapwrite.h"
#include "imapscanclient.h"
#include "fetchinfo.h"
#include "rfc822/rfc822.h"
#include "rfc2045/rfc2045.h"
#include "maildir/config.h"
#include "maildir/maildirgetquota.h"
#include "maildir/maildirquota.h"
#include "maildir/maildiraclt.h"

Go to the source code of this file.

Classes

struct  fetchheaderinfo

Functions

char * rfc2045id (struct rfc2045 *)
void snapshot_needed ()
void msgenvelope (void(*)(const char *, size_t), FILE *, struct rfc2045 *)
void msgbodystructure (void(*)(const char *, size_t), int, FILE *, struct rfc2045 *)
int is_trash (const char *)
void get_message_flags (struct imapscanmessageinfo *, char *, struct imapflags *)
void append_flags (char *, struct imapflags *)
static int fetchitem (FILE **, int *, struct fetchinfo *, struct imapscaninfo *, unsigned long, struct rfc2045 **)
static void bodystructure (FILE *, struct fetchinfo *, struct imapscaninfo *, unsigned long, struct rfc2045 *)
static void body (FILE *, struct fetchinfo *, struct imapscaninfo *, unsigned long, struct rfc2045 *)
static void fetchmsgbody (FILE *, struct fetchinfo *, struct imapscaninfo *, unsigned long, struct rfc2045 *)
static void dofetchmsgbody (FILE *, struct fetchinfo *, struct imapscaninfo *, unsigned long, struct rfc2045 *)
static void envelope (FILE *, struct fetchinfo *, struct imapscaninfo *, unsigned long, struct rfc2045 *)
void doflags (FILE *, struct fetchinfo *, struct imapscaninfo *, unsigned long, struct rfc2045 *)
static void internaldate (FILE *, struct fetchinfo *, struct imapscaninfo *, unsigned long, struct rfc2045 *)
static void uid (FILE *, struct fetchinfo *, struct imapscaninfo *, unsigned long, struct rfc2045 *)
static void all (FILE *, struct fetchinfo *, struct imapscaninfo *, unsigned long, struct rfc2045 *)
static void fast (FILE *, struct fetchinfo *, struct imapscaninfo *, unsigned long, struct rfc2045 *)
static void full (FILE *, struct fetchinfo *, struct imapscaninfo *, unsigned long, struct rfc2045 *)
static void rfc822size (FILE *, struct fetchinfo *, struct imapscaninfo *, unsigned long, struct rfc2045 *)
static void dofetchheadersbuf (FILE *, struct fetchinfo *, struct imapscaninfo *, unsigned long, struct rfc2045 *, int(*)(struct fetchinfo *fi, const char *))
static void dofetchheadersfile (FILE *, struct fetchinfo *, struct imapscaninfo *, unsigned long, struct rfc2045 *, int(*)(struct fetchinfo *fi, const char *))
static void print_bodysection_partial (struct fetchinfo *, void(*)(const char *))
static void print_bodysection_output (const char *)
static int dofetchheaderfields (struct fetchinfo *, const char *)
static int dofetchheadernotfields (struct fetchinfo *, const char *)
static int dofetchheadermime (struct fetchinfo *, const char *)
static void rfc822 (FILE *, struct fetchinfo *, struct imapscaninfo *, unsigned long, struct rfc2045 *)
static void rfc822header (FILE *, struct fetchinfo *, struct imapscaninfo *, unsigned long, struct rfc2045 *)
static void rfc822text (FILE *, struct fetchinfo *, struct imapscaninfo *, unsigned long, struct rfc2045 *)
struct rfc2045fetch_alloc_rfc2045 (unsigned long, FILE *)
FILE * open_cached_fp (unsigned long)
void fetchflags (unsigned long)
static void fetcherrorprt (const char *p)
static void fetcherror (const char *errmsg, struct fetchinfo *fi, struct imapscaninfo *info, unsigned long j)
char * get_reflagged_filename (const char *fn, struct imapflags *newflags)
int reflag_filename (struct imapscanmessageinfo *mi, struct imapflags *flags, int fd)
int do_fetch (unsigned long n, int byuid, void *p)
void fetchflags_byuid (unsigned long n)
static void countheader (struct fetchheaderinfo *, const char *, size_t)
static void printheader (struct fetchheaderinfo *, const char *, size_t)
void fetch_free_cached ()
void fetch_free_cache ()
void save_cached_offsets (off_t base, off_t virt, off_t phys)
int get_cached_offsets (off_t base, off_t *virt, off_t *phys)

Variables

static const char unavailable []
unsigned long header_count = 0
unsigned long body_count = 0
int current_mailbox_ro
char * current_mailbox_acl
char * current_mailbox
static struct rfc2045cached_rfc2045p
static char * cached_filename
static FILE * cached_fp = 0
static char * cached_fp_filename = 0
static off_t cached_base_offset
static off_t cached_virtual_offset
static off_t cached_phys_offset

Class Documentation

struct fetchheaderinfo

Definition at line 1130 of file fetch.c.

Class Members
unsigned long cnt
unsigned long skipping

Function Documentation

static void all ( FILE *  fp,
struct fetchinfo fi,
struct imapscaninfo i,
unsigned long  msgnum,
struct rfc2045 mimep 
) [static]

Definition at line 585 of file fetch.c.

{
       doflags(fp, fi, i, msgnum, mimep);
       writes(" ");
       internaldate(fp, fi, i, msgnum, mimep);
       writes(" ");
       rfc822size(fp, fi, i, msgnum, mimep);
       writes(" ");
       envelope(fp, fi, i, msgnum, mimep);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void append_flags ( char *  ,
struct imapflags  
)

Definition at line 597 of file imapd.c.

{
       if (flags->drafts)   strcat(buf, "D");
       if (flags->flagged)  strcat(buf, "F");
       if (flags->answered) strcat(buf, "R");
       if (flags->seen)     strcat(buf, "S");
       if (flags->deleted)  strcat(buf, "T");
}

Here is the caller graph for this function:

static void body ( FILE *  fp,
struct fetchinfo fi,
struct imapscaninfo i,
unsigned long  msgnum,
struct rfc2045 mimep 
) [static]

Definition at line 435 of file fetch.c.

{
       writes("BODY ");
       msgbodystructure(writemem, 0, fp, mimep);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void bodystructure ( FILE *  fp,
struct fetchinfo fi,
struct imapscaninfo i,
unsigned long  msgnum,
struct rfc2045 mimep 
) [static]

Definition at line 427 of file fetch.c.

{
       writes("BODYSTRUCTURE ");
       msgbodystructure(writemem, 1, fp, mimep);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void countheader ( struct fetchheaderinfo fi,
const char *  p,
size_t  s 
) [static]

Definition at line 1263 of file fetch.c.

{
       fi->cnt += s;
}

Here is the caller graph for this function:

int do_fetch ( unsigned long  n,
int  byuid,
void *  p 
)

Definition at line 244 of file fetch.c.

{
       struct fetchinfo *fi=(struct fetchinfo *)p;
       FILE   *fp;
       struct rfc2045 *rfc2045p;
       int    seen;
       int    open_err;

       fp=NULL;
       open_err=0;

       writes("* ");
       writen(n);
       writes(" FETCH (");

       if (byuid)
       {
       struct fetchinfo *fip;

              for (fip=fi; fip; fip=fip->next)
                     if (strcmp(fip->name, "UID") == 0)
                            break;

              if (fip == 0)
              {
                     writes("UID ");
                     writen(current_maildir_info.msgs[n-1].uid);
                     writes(" ");
              }
       }
       seen=0;
       rfc2045p=0;
       while (fi)
       {
              if (fetchitem(&fp, &open_err, fi, &current_maildir_info, n-1,
                     &rfc2045p))   seen=1;
              if ((fi=fi->next) != 0)     writes(" ");
       }
       writes(")\r\n");

       if (open_err)
       {
              writes("* NO Cannot open message ");
              writen(n);
              writes("\r\n");
              return (0);
       }


#if SMAP
       if (!smapflag)
#endif
              if (current_mailbox_acl &&
                  strchr(current_mailbox_acl, ACL_SEEN[0]) == NULL)
                     seen=0; /* No permissions */

       if (seen && !current_mailbox_ro)
       {
       struct imapflags     flags;

              get_message_flags(current_maildir_info.msgs+(n-1),
                            0, &flags);
              if (!flags.seen)
              {
                     flags.seen=1;
                     reflag_filename(&current_maildir_info.msgs[n-1],&flags,
                            fileno(fp));
                     current_maildir_info.msgs[n-1].changedflags=1;
              }
       }

       if (current_maildir_info.msgs[n-1].changedflags)
              fetchflags(n-1);
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int dofetchheaderfields ( struct fetchinfo fi,
const char *  name 
) [static]

Definition at line 951 of file fetch.c.

{
       for (fi=fi->bodysublist; fi; fi=fi->next)
       {
       int    i, a, b;

              if (fi->name == 0)   continue;
              for (i=0; fi->name[i] && name[i]; i++)
              {
                     a=(unsigned char)name[i];
                     a=toupper(a);
                     b=fi->name[i];
                     b=toupper(b);
                     if (a != b)   break;
              }
              if (fi->name[i] == 0 && name[i] == 0)     return (1);
       }

       return (0);
}

Here is the caller graph for this function:

static int dofetchheadermime ( struct fetchinfo fi,
const char *  name 
) [static]

Definition at line 977 of file fetch.c.

{
int    i, a;
static const char mv[]="MIME-VERSION";

       for (i=0; i<sizeof(mv)-1; i++)
       {
              a= (unsigned char)name[i];
              a=toupper(a);
              if (a != mv[i])      break;
       }
       if (mv[i] == 0 && name[i] == 0)    return (1);

       for (i=0; i<8; i++)
       {
              a= (unsigned char)name[i];
              a=toupper(a);
              if (a != "CONTENT-"[i])     return (0);
       }
       return (1);
}

Here is the caller graph for this function:

static int dofetchheadernotfields ( struct fetchinfo fi,
const char *  name 
) [static]

Definition at line 972 of file fetch.c.

{
       return (!dofetchheaderfields(fi, name));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void dofetchheadersbuf ( FILE *  fp,
struct fetchinfo fi,
struct imapscaninfo info,
unsigned long  msgnum,
struct rfc2045 mimep,
int(*)(struct fetchinfo *fi, const char *)  headerfunc 
) [static]

Definition at line 999 of file fetch.c.

{
off_t start_pos, end_pos, start_body;
off_t nlines, nbodylines;
size_t i,j,k,l;
char   buf[BUFSIZ+2];
int    goodheader;
unsigned long skipping;
unsigned long cnt;
char   *p;
int    ii;

       rfc2045_mimepos(mimep, &start_pos, &end_pos, &start_body,
              &nlines, &nbodylines);
       if (fseek(fp, start_pos, SEEK_SET) == -1)
       {
              writes("{0}\r\n");
              fetcherror("fseek", fi, info, msgnum);
              return;
       }

       ii=fread(buf, 1, start_body - start_pos, fp);
       if (ii < 0 || (i=ii) != start_body - start_pos)
       {
              fetcherror("unexpected EOF", fi, info, msgnum);
              exit(1);
       }
       goodheader= (*headerfunc)(fi, "");

       l=0;
       for (j=0; j<i; )
       {
              if (buf[j] != '\n' && buf[j] != '\r' &&
                     !isspace((int)(unsigned char)buf[j]))
              {
                     goodheader= (*headerfunc)(fi, "");

                     for (k=j; k<i; k++)
                     {
                            if (buf[k] == '\n' || buf[k] == ':')
                                   break;
                     }

                     if (k < i && buf[k] == ':')
                     {
                            buf[k]=0;
                            goodheader=(*headerfunc)(fi, buf+j);
                            buf[k]=':';
                     }
              }
              else if (buf[j] == '\n')
                     goodheader=0;

              for (k=j; k<i; k++)
                     if (buf[k] == '\n')
                     {
                            ++k;
                            break;
                     }

              if (goodheader)
              {
                     while (j<k)
                            buf[l++]=buf[j++];
              }
              j=k;
       }

       buf[l++]='\n';       /* Always append a blank line */

       cnt=l;
       for (i=0; i<l; i++)
              if (buf[i] == '\n')  ++cnt;

       skipping=0;
       if (fi->ispartial)
       {
              skipping=fi->partialstart;
              if (skipping > cnt)  skipping=cnt;
              cnt -= skipping;
              if (fi->ispartial > 1 && cnt > fi->partialend)
                     cnt=fi->partialend;
       }

       writes("{");
       writen(cnt);
       writes("}\r\n");
       p=buf;
       while (skipping)
       {
              if (*p == '\n')
              {
                     --skipping;
                     if (skipping == 0)
                     {
                            if (cnt)
                            {
                                   writes("\n");
                                   --cnt;
                            }
                            break;
                     }
              }
              --skipping;
              ++p;
       }

       while (cnt)
       {
              if (*p == '\n')
              {
                     writes("\r");
                     if (--cnt == 0)      break;
                     writes("\n");
                     --cnt;
                     ++p;
                     continue;
              }
              for (i=0; i<cnt; i++)
                     if (p[i] == '\n')
                            break;
              writemem(p, i);
              p += i;
              cnt -= i;
              header_count += i;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void dofetchheadersfile ( FILE *  fp,
struct fetchinfo fi,
struct imapscaninfo info,
unsigned long  msgnum,
struct rfc2045 mimep,
int(*)(struct fetchinfo *fi, const char *)  headerfunc 
) [static]

Definition at line 1139 of file fetch.c.

{
off_t start_pos, end_pos, start_body, left;
off_t nlines, nbodylines;
size_t i;
int    c, pass;
char   buf1[256];
int    goodheader;
struct fetchheaderinfo finfo;

       finfo.cnt=0;
       for (pass=0; pass<2; pass++)
       {
       void (*func)(struct fetchheaderinfo *, const char *, size_t)=
                     pass ? printheader:countheader;

              rfc2045_mimepos(mimep, &start_pos, &end_pos, &start_body,
                     &nlines, &nbodylines);
              if (fseek(fp, start_pos, SEEK_SET) == -1)
              {
                     writes("{0}\r\n");
                     fetcherror("fseek", fi, info, msgnum);
                     return;
              }
              if (pass)
              {
                     finfo.skipping=0;
                     if (fi->ispartial)
                     {
                            finfo.skipping=fi->partialstart;
                            if (finfo.skipping > finfo.cnt)
                                   finfo.skipping=finfo.cnt;
                            finfo.cnt -= finfo.skipping;
                            if (fi->ispartial > 1 &&
                                   finfo.cnt > fi->partialend)
                                   finfo.cnt=fi->partialend;
                     }

                     writes("{");
                     writen(finfo.cnt+2); /* BUG */
                     writes("}\r\n");
              }
              left=start_body - start_pos;

              goodheader= (*headerfunc)(fi, "");
              while (left)
              {
                     for (i=0; i<sizeof(buf1)-1 && i<left; i++)
                     {
                            c=getc(fp);
                            if (c == EOF)
                            {
                                   fetcherror("unexpected EOF", fi, info, msgnum);
                                   _exit(1);
                            }

                            if (c == '\n' || c == ':')
                            {
                                   ungetc(c, fp);
                                   break;
                            }
                            buf1[i]=c;
                     }
                     buf1[i]=0;
                     left -= i;

                     if (buf1[0] != '\n' && buf1[0] != '\r' &&
                            !isspace((int)(unsigned char)buf1[0]))
                            goodheader= (*headerfunc)(fi, buf1);
                     else if (buf1[0] == '\n')
                            goodheader=0;

                     if (!goodheader)
                     {
                            while (left)
                            {
                                   c=getc(fp);
                                   --left;
                                   if (c == EOF)
                                   {
                                          fetcherror("unexpected EOF", fi, info, msgnum);
                                          _exit(1);
                                   }
                                   if (c == '\n')       break;
                            }
                            continue;
                     }

                     (*func)(&finfo, buf1, i);

                     i=0;
                     while (left)
                     {
                            c=getc(fp);
                            if (c == EOF)
                            {
                                   fetcherror("unexpected EOF", fi, info, msgnum);
                                   _exit(1);
                            }
                            --left;
                            if (i >= sizeof(buf1))
                            {
                                   (*func)(&finfo, buf1, i);
                                   i=0;
                            }
                            if (c == '\n')
                            {
                                   (*func)(&finfo, buf1, i);
                                   buf1[0]='\r';
                                   i=1;
                            }
                            buf1[i++]=c;
                            if (c == '\n')       break;
                     }
                     (*func)(&finfo, buf1, i);
                     if (pass && finfo.cnt == 0) break;
              }
       }
       writes("\r\n");      /* BUG */
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void dofetchmsgbody ( FILE *  fp,
struct fetchinfo fi,
struct imapscaninfo i,
unsigned long  msgnum,
struct rfc2045 mimep 
) [static]

Definition at line 673 of file fetch.c.

{
const char *p=fi->bodysection;
off_t start_pos, end_pos, start_body;
off_t nlines, nbodylines;
unsigned long cnt;
char   buf[BUFSIZ];
char   rbuf[BUFSIZ];
char   *rbufptr;
int    rbufleft;
unsigned long bufptr;
unsigned long skipping;
int    ismsgrfc822=1;

off_t start_seek_pos;
 struct rfc2045 *headermimep;

/*
** To optimize consecutive FETCHes, we cache our virtual and physical
** position.  What we do is that on the first fetch we count off the
** characters we read, and keep track of both the physical and the CRLF-based
** offset into the message.  Then, on subsequent FETCHes, we attempt to
** use that information.
*/

off_t cnt_virtual_chars;
off_t cnt_phys_chars;

off_t cache_virtual_chars;
off_t cache_phys_chars;

       headermimep=mimep;
 
       while (p && isdigit((int)(unsigned char)*p))
       {
       unsigned long n=0;

              headermimep=mimep;

              do
              {
                     n=n*10 + (*p++ - '0');
              } while (isdigit((int)(unsigned char)*p));

              if (mimep)
              {
                     if (ismsgrfc822)
                     {
                            const char *ct, *dummy;

                            if (mimep->firstpart == 0)
                            {
                                   /* Not a multipart, n must be 1 */
                                   if (n != 1)
                                          mimep=0;
                                   if (*p == '.')
                                          ++p;
                                   continue;
                            }
                            ismsgrfc822=0;

                            rfc2045_mimeinfo(mimep, &ct,
                                           &dummy,
                                           &dummy);

                            if (ct && strcasecmp(ct, "message/rfc822"
                                               ) == 0)
                                   ismsgrfc822=1;
                            /* The content is another message/rfc822 */
                     }

                     mimep=mimep->firstpart;
                     while (mimep)
                     {
                            if (!mimep->isdummy && --n == 0)
                                   break;
                            mimep=mimep->next;
                     }
                     headermimep=mimep;

                     if (mimep && mimep->firstpart &&
                            !mimep->firstpart->isdummy)
                            /* This is a message/rfc822 part */
                     {
                            if (!*p)
                                   break;

                            mimep=mimep->firstpart;
                            ismsgrfc822=1;
                     }
              }
              if (*p == '.')
                     ++p;
       }

       if (p && strcmp(p, "MIME") == 0)
              mimep=headermimep;

       if (mimep == 0)
       {
              writes("{0}\r\n");
              return;
       }

       rfc2045_mimepos(mimep, &start_pos, &end_pos, &start_body,
              &nlines, &nbodylines);


       if (p && strcmp(p, "TEXT") == 0)
       {
              start_seek_pos=start_body;
              cnt=end_pos - start_body + nbodylines;
       }
       else if (p && strcmp(p, "HEADER") == 0)
       {
              start_seek_pos=start_pos;
              cnt= start_body - start_pos + (nlines - nbodylines);
       }
       else if (p && strcmp(p, "HEADER.FIELDS") == 0)
       {
              if (start_body - start_pos <= BUFSIZ)
                     dofetchheadersbuf(fp, fi, i, msgnum, mimep,
                            &dofetchheaderfields);
              else
                     dofetchheadersfile(fp, fi, i, msgnum, mimep,
                            &dofetchheaderfields);
              return;
       }
       else if (p && strcmp(p, "HEADER.FIELDS.NOT") == 0)
       {
              if (start_body - start_pos <= BUFSIZ)
                     dofetchheadersbuf(fp, fi, i, msgnum, mimep,
                            &dofetchheadernotfields);
              else
                     dofetchheadersfile(fp, fi, i, msgnum, mimep,
                            &dofetchheadernotfields);
              return;
       }
       else if (p && strcmp(p, "MIME") == 0)
       {
              if (start_body - start_pos <= BUFSIZ)
                     dofetchheadersbuf(fp, fi, i, msgnum, mimep,
                            &dofetchheadermime);
              else
                     dofetchheadersfile(fp, fi, i, msgnum, mimep,
                            &dofetchheadermime);
              return;
       }
       else if (*fi->bodysection == 0)
       {
              start_seek_pos=start_pos;

              cnt= end_pos - start_pos + nlines;
       }
       else   /* Last possibility: entire body */
       {
              start_seek_pos=start_body;

              cnt= end_pos - start_body + nbodylines;
       }

       skipping=0;
       if (fi->ispartial)
       {
              skipping=fi->partialstart;
              if (skipping > cnt)  skipping=cnt;
              cnt -= skipping;
              if (fi->ispartial > 1 && cnt > fi->partialend)
                     cnt=fi->partialend;
       }

       if (get_cached_offsets(start_seek_pos, &cnt_virtual_chars,
                            &cnt_phys_chars) == 0 &&
           cnt_virtual_chars <= skipping) /* Yeah - cache it, baby! */
       {
              if (fseek(fp, start_seek_pos+cnt_phys_chars, SEEK_SET) == -1)
              {
                     writes("{0}\r\n");
                     fetcherror("fseek", fi, i, msgnum);
                     return;
              }
              skipping -= cnt_virtual_chars;
       }
       else
       {
              if (fseek(fp, start_seek_pos, SEEK_SET) == -1)
              {
                     writes("{0}\r\n");
                     fetcherror("fseek", fi, i, msgnum);
                     return;
              }

              cnt_virtual_chars=0;
              cnt_phys_chars=0;
       }

       cache_virtual_chars=cnt_virtual_chars;
       cache_phys_chars=cnt_phys_chars;

       writes("{");
       writen(cnt);
       writes("}\r\n");
       bufptr=0;
       writeflush();

       rbufptr=0;
       rbufleft=0;

       while (cnt)
       {
       int    c;

              if (!rbufleft)
              {
                     rbufleft=fread(rbuf, 1, sizeof(rbuf), fp);
                     if (rbufleft < 0)    rbufleft=0;
                     rbufptr=rbuf;
              }

              if (!rbufleft)
              {
                     fetcherror("unexpected EOF", fi, i, msgnum);
                     _exit(1);
              }

              --rbufleft;
              c=(int)(unsigned char)*rbufptr++;
              ++cnt_phys_chars;

              if (c == '\n')
              {
                     ++cnt_virtual_chars;

                     if (skipping)
                            --skipping;
                     else
                     {
                            if (bufptr >= sizeof(buf))
                            {
                                   writemem(buf, sizeof(buf));
                                   bufptr=0;
                                   /*writeflush();*/
                            }
                            buf[bufptr++]='\r';
                            --cnt;

                            if (cnt == 0)
                                   break;
                     }
              }

              ++cnt_virtual_chars;
              if (skipping)
                     --skipping;
              else
              {
                     ++body_count;

                     if (bufptr >= sizeof(buf))
                     {
                            writemem(buf, sizeof(buf));
                            bufptr=0;
                            /*writeflush();*/
                     }
                     buf[bufptr++]=c;
                     --cnt;
              }
              cache_virtual_chars=cnt_virtual_chars;
              cache_phys_chars=cnt_phys_chars;
       }
       writemem(buf, bufptr);
       writeflush();
       save_cached_offsets(start_seek_pos, cache_virtual_chars,
                         cache_phys_chars);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void doflags ( FILE *  fp,
struct fetchinfo fi,
struct imapscaninfo i,
unsigned long  msgnum,
struct rfc2045 mimep 
)

Definition at line 490 of file fetch.c.

{
       struct libmail_kwMessageEntry *kme;

       char   buf[256];

#if SMAP
       if (smapflag)
       {
              writes(" FLAGS=");
              get_message_flags(i->msgs+msgnum, buf, 0);
              writes(buf);
       }
       else
#endif
       {
              struct libmail_kwMessage *km;

              writes("FLAGS ");

              get_message_flags(i->msgs+msgnum, buf, 0);

              writes("(");
              writes(buf);

              if (buf[0])
                     strcpy(buf, " ");

              if ((km=i->msgs[msgnum].keywordMsg) != NULL)
                     for (kme=km->firstEntry; kme; kme=kme->next)
                     {
                            writes(buf);
                            strcpy(buf, " ");
                            writes(keywordName(kme->libmail_keywordEntryPtr));
                     }
              writes(")");
       }

       i->msgs[msgnum].changedflags=0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void envelope ( FILE *  fp,
struct fetchinfo fi,
struct imapscaninfo i,
unsigned long  msgnum,
struct rfc2045 mimep 
) [static]

Definition at line 443 of file fetch.c.

{
       writes("ENVELOPE ");
       msgenvelope( &writemem, fp, mimep);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void fast ( FILE *  fp,
struct fetchinfo fi,
struct imapscaninfo i,
unsigned long  msgnum,
struct rfc2045 mimep 
) [static]

Definition at line 598 of file fetch.c.

{
       doflags(fp, fi, i, msgnum, mimep);
       writes(" ");
       internaldate(fp, fi, i, msgnum, mimep);
       writes(" ");
       rfc822size(fp, fi, i, msgnum, mimep);
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct rfc2045 * fetch_alloc_rfc2045 ( unsigned long  msgnum,
FILE *  fp 
) [read]

Definition at line 1501 of file fetch.c.

{
       if (cached_rfc2045p &&
           strcmp(cached_filename,
                 current_maildir_info.msgs[msgnum].filename) == 0)
              return (cached_rfc2045p);

       fetch_free_cached();

       if ((cached_filename=strdup(current_maildir_info.
                                msgs[msgnum].filename))
           == 0) write_error_exit(0);

       if (fseek(fp, 0L, SEEK_SET) == -1)
       {
              write_error_exit(0);
              return (0);
       }
       cached_rfc2045p=rfc2045_fromfp(fp);
       if (!cached_rfc2045p)
       {
              free(cached_filename);
              cached_filename=0;
              write_error_exit(0);
       }
       return (cached_rfc2045p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void fetch_free_cache ( )

Definition at line 1598 of file fetch.c.

Here is the caller graph for this function:

Definition at line 1490 of file fetch.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static void fetcherror ( const char *  errmsg,
struct fetchinfo fi,
struct imapscaninfo info,
unsigned long  j 
) [static]

Definition at line 151 of file fetch.c.

{
struct imapscanmessageinfo *mi=info->msgs+j;

       fprintf(stderr, "IMAP FETCH ERROR: %s, uid=%u, filename=%s: %s",
              errmsg, (unsigned)getuid(), mi->filename, fi->name);
       if (fi->bodysection)
              print_bodysection_partial(fi, &fetcherrorprt);
       fprintf(stderr, "\n");
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void fetcherrorprt ( const char *  p) [static]

Definition at line 146 of file fetch.c.

{
       fprintf(stderr, "%s", p);
}

Here is the caller graph for this function:

void fetchflags ( unsigned long  n)

Definition at line 451 of file fetch.c.

{
#if SMAP
       if (smapflag)
       {
              writes("* FETCH ");
              writen(n+1);
       }
       else
#endif
       {
              writes("* ");
              writen(n+1);
              writes(" FETCH (");
       }

       doflags(0, 0, &current_maildir_info, n, 0);

#if SMAP
       if (smapflag)
       {
              writes("\n");
       }
       else
#endif
              writes(")\r\n");
}

Here is the call graph for this function:

Here is the caller graph for this function:

void fetchflags_byuid ( unsigned long  n)

Definition at line 479 of file fetch.c.

{
       writes("* ");
       writen(n+1);
       writes(" FETCH (");
       uid(0, 0, &current_maildir_info, n, 0);
       writes(" ");
       doflags(0, 0, &current_maildir_info, n, 0);
       writes(")\r\n");
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int fetchitem ( FILE **  fp,
int *  open_err,
struct fetchinfo fi,
struct imapscaninfo i,
unsigned long  msgnum,
struct rfc2045 **  mimep 
) [static]

Definition at line 320 of file fetch.c.

{
       void (*fetchfunc)(FILE *, struct fetchinfo *,
                       struct imapscaninfo *, unsigned long,
                       struct rfc2045 *);
       int    parsemime=0;
       int    rc=0;
       int    do_open=1;

       if (strcmp(fi->name, "ALL") == 0)
       {
              parsemime=1;
              fetchfunc= &all;
       }
       else if (strcmp(fi->name, "BODYSTRUCTURE") == 0)
       {
              parsemime=1;
              fetchfunc= &bodystructure;
       }
       else if (strcmp(fi->name, "BODY") == 0)
       {
              parsemime=1;
              fetchfunc= &body;
              if (fi->bodysection)
              {
                     fetchfunc= &fetchmsgbody;
                     rc=1;
              }
       }
       else if (strcmp(fi->name, "BODY.PEEK") == 0)
       {
              parsemime=1;
              fetchfunc= &body;
              if (fi->bodysection)
                     fetchfunc= &fetchmsgbody;
       }
       else if (strcmp(fi->name, "ENVELOPE") == 0)
       {
              parsemime=1;
              fetchfunc= &envelope;
       }
       else if (strcmp(fi->name, "FAST") == 0)
       {
              parsemime=1;
              fetchfunc= &fast;
       }
       else if (strcmp(fi->name, "FULL") == 0)
       {
              parsemime=1;
              fetchfunc= &full;
       }
       else if (strcmp(fi->name, "FLAGS") == 0)
       {
              fetchfunc= &doflags;
              do_open=0;
       }
       else if (strcmp(fi->name, "INTERNALDATE") == 0)
       {
              fetchfunc= &internaldate;
       }
       else if (strcmp(fi->name, "RFC822") == 0)
       {
              fetchfunc= &rfc822;
              rc=1;
       }
       else if (strcmp(fi->name, "RFC822.HEADER") == 0)
       {
              fetchfunc= &rfc822header;
       }
       else if (strcmp(fi->name, "RFC822.SIZE") == 0)
       {
              parsemime=1;
              fetchfunc= &rfc822size;
       }
       else if (strcmp(fi->name, "RFC822.TEXT") == 0)
       {
              parsemime=1;
              fetchfunc= &rfc822text;
       }
       else if (strcmp(fi->name, "UID") == 0)
       {
              fetchfunc= &uid;
              do_open=0;
       }
       else   return (0);

       if (do_open && *fp == NULL)
       {
              *fp=open_cached_fp(msgnum);
              if (!*fp)
              {
                     *open_err=1;
                     return rc;
              }
       }

       if (parsemime && !*mimep)
       {
              *mimep=fetch_alloc_rfc2045(msgnum, *fp);
       }

       (*fetchfunc)(*fp, fi, i, msgnum, *mimep);
       return (rc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void fetchmsgbody ( FILE *  fp,
struct fetchinfo fi,
struct imapscaninfo i,
unsigned long  msgnum,
struct rfc2045 mimep 
) [static]

Definition at line 624 of file fetch.c.

{
       writes("BODY");
       print_bodysection_partial(fi, &print_bodysection_output);
       writes(" ");
       dofetchmsgbody(fp, fi, i, msgnum, mimep);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void full ( FILE *  fp,
struct fetchinfo fi,
struct imapscaninfo i,
unsigned long  msgnum,
struct rfc2045 mimep 
) [static]

Definition at line 609 of file fetch.c.

{
       doflags(fp, fi, i, msgnum, mimep);
       writes(" ");
       internaldate(fp, fi, i, msgnum, mimep);
       writes(" ");
       rfc822size(fp, fi, i, msgnum, mimep);
       writes(" ");
       envelope(fp, fi, i, msgnum, mimep);
       writes(" ");
       body(fp, fi, i, msgnum, mimep);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int get_cached_offsets ( off_t  base,
off_t *  virt,
off_t *  phys 
)

Definition at line 1616 of file fetch.c.

{
       if (!cached_fp)
              return (-1);
       if (base != cached_base_offset)
              return (-1);

       *virt=cached_virtual_offset;
       *phys=cached_phys_offset;
       return (0);
}

Here is the caller graph for this function:

void get_message_flags ( struct imapscanmessageinfo ,
char *  ,
struct imapflags  
)

Definition at line 479 of file imapd.c.

{
       const char *filename=mi->filename;

       const char *DRAFT="\\Draft";
       const char *FLAGGED="\\Flagged";
       const char *REPLIED="\\Answered";
       const char *SEEN="\\Seen";
       const char *DELETED="\\Deleted";
       const char *RECENT="\\Recent";

       const char *SPC=" ";

       if (buf)
              *buf=0;

       if (flags)
              flags->seen=flags->answered=flags->deleted=flags->flagged
              =flags->recent=flags->drafts=0;

       if ((filename=strrchr(filename, MDIRSEP[0])) == 0
              || strncmp(filename, MDIRSEP "2,", 3))    return;

#if SMAP
       if (smapflag)
       {
              SPC=",";
              DRAFT="DRAFT";
              FLAGGED="MARKED";
              REPLIED="REPLIED";
              SEEN="SEEN";
              DELETED="DELETED";
              RECENT="RECENT";
       }
#endif

       if (strchr(filename, 'D'))
       {
              if (buf) strcat(buf, DRAFT);
              if (flags)  flags->drafts=1;
       }

       if (strchr(filename, 'F'))
       {
              if (buf) strcat(strcat(buf, *buf ? SPC:""), FLAGGED);
              if (flags)    flags->flagged=1;
       }
       if (strchr(filename, 'R'))
       {
              if (buf) strcat(strcat(buf, *buf ? SPC:""), REPLIED);
              if (flags)    flags->answered=1;
       }

       if (strchr(filename, 'S') != NULL)
       {
              if (buf) strcat(strcat(buf, *buf ? SPC:""), SEEN);
              if (flags)    flags->seen=1;
       }

       if (strchr(filename, 'T'))
       {
              if (buf) strcat(strcat(buf, *buf ? SPC:""), DELETED);
              if (flags)    flags->deleted=1;
       }

       if (mi->recentflag)
       {
              if (flags) flags->recent=1;
              if (buf) strcat(strcat(buf, *buf ? SPC:""), RECENT);
       }
}

Here is the caller graph for this function:

char* get_reflagged_filename ( const char *  fn,
struct imapflags newflags 
)

Definition at line 164 of file fetch.c.

{
       char *p=malloc(strlen(fn)+20);
       char *q;

       if (!p)       write_error_exit(0);
       strcpy(p, fn);
       if ((q=strrchr(p, MDIRSEP[0])) != 0)      *q=0;
       strcat(p, MDIRSEP "2,");
       append_flags(p, newflags);
       return p;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void internaldate ( FILE *  fp,
struct fetchinfo fi,
struct imapscaninfo i,
unsigned long  msgnum,
struct rfc2045 mimep 
) [static]

Definition at line 533 of file fetch.c.

{
struct stat   stat_buf;
char   buf[256];
char   *p, *q;

       writes("INTERNALDATE ");
       if (fstat(fileno(fp), &stat_buf) == 0)
       {
              rfc822_mkdate_buf(stat_buf.st_mtime, buf);

              /* Convert RFC822 date to imap date */

              p=strchr(buf, ',');
              if (p) ++p;
              else   p=buf;
              while (*p == ' ')    ++p;
              if ((q=strchr(p, ' ')) != 0)       *q++='-';
              if ((q=strchr(p, ' ')) != 0)       *q++='-';
              writes("\"");
              writes(p);
              writes("\"");
       }
       else
              writes("NIL");
}

Here is the call graph for this function:

Here is the caller graph for this function:

int is_trash ( const char *  )

Definition at line 217 of file imapd.c.

{
       if (strcmp(m, dot_trash))
       {
              /*
               * not trying to delete .Trash but folder inside of .Trash
               */
              return (0);
       }
       else
       {
              /*
               * trying to delete .Trash - stop them
               */
              return (1);
       }
}

Here is the caller graph for this function:

void msgbodystructure ( void(*)(const char *, size_t)  ,
int  ,
FILE *  ,
struct rfc2045  
)

Definition at line 111 of file msgbodystructure.c.

{
const char *content_type_s;
const char *content_transfer_encoding_s;
const char *charset_s;
off_t start_pos, end_pos, start_body;
off_t nlines, nbodylines;
const char *disposition_s;

char   *p, *q;

       rfc2045_mimeinfo(mimep, &content_type_s, &content_transfer_encoding_s,
              &charset_s);
       rfc2045_mimepos(mimep, &start_pos, &end_pos, &start_body,
              &nlines, &nbodylines);

       disposition_s=mimep->content_disposition;

       (*writefunc)("(", 1);

       if (mimep->firstpart && mimep->firstpart->isdummy &&
              mimep->firstpart->next)
              /* MULTIPART */
       {
       struct rfc2045       *childp;

              for (childp=mimep->firstpart; (childp=childp->next) != 0; )
                     msgbodystructure(writefunc, dox, fp, childp);

              (*writefunc)(" \"", 2);
              p=strchr(content_type_s, '/');
              if (p)
                     msgappends(writefunc, p+1, strlen(p+1));
              (*writefunc)("\"", 1);

              if (dox)
              {
                     (*writefunc)(" ", 1);
                     do_param_list(writefunc, mimep->content_type_attr);

                     (*writefunc)(" ", 1);
                     do_disposition(writefunc, disposition_s,
                            mimep->content_disposition_attr);

                     (*writefunc)(" ", 1);
                     contentstr(writefunc, rfc2045_content_language(mimep));
              }
       }
       else
       {
       char   *mybuf;
       char   buf[40];
       const  char *cp;

              mybuf=my_strdup(content_type_s);
              q=strtok(mybuf, " /");
              (*writefunc)("\"", 1);
              if (q)
                     msgappends(writefunc, q, strlen(q));
              (*writefunc)("\" \"", 3);
              if (q) q=strtok(0, " /");
              if (q)
                     msgappends(writefunc, q, strlen(q));
              free(mybuf);
              (*writefunc)("\" ", 2);

              do_param_list(writefunc, mimep->content_type_attr);

              (*writefunc)(" ", 1);
              cp=rfc2045_content_id(mimep);
              if (!cp || !*cp)
                     contentstr(writefunc, cp);
              else
              {
                     (*writefunc)("\"<", 2);
                     msgappends(writefunc, cp, strlen(cp));
                     (*writefunc)(">\"", 2);
              }
              (*writefunc)(" ", 1);
              contentstr(writefunc, rfc2045_content_description(mimep));

              (*writefunc)(" \"", 2);
              msgappends(writefunc, content_transfer_encoding_s,
                     strlen(content_transfer_encoding_s));
              (*writefunc)("\" ", 2);

              sprintf(buf, "%lu", (unsigned long)
                     (end_pos-start_body+nbodylines));
                     /* nbodylines added for CRs */
              (*writefunc)(buf, strlen(buf));

              if (
              (content_type_s[0] == 't' || content_type_s[0] == 'T') &&
              (content_type_s[1] == 'e' || content_type_s[1] == 'E') &&
              (content_type_s[2] == 'x' || content_type_s[2] == 'X') &&
              (content_type_s[3] == 't' || content_type_s[3] == 'T') &&
                     (content_type_s[4] == '/' ||
                      content_type_s[4] == 0))
              {
                     (*writefunc)(" ", 1);
                     sprintf(buf, "%lu", (unsigned long)nbodylines);
                     (*writefunc)(buf, strlen(buf));
              }

              if (mimep->firstpart && !mimep->firstpart->isdummy)
                     /* message/rfc822 */
              {
                     (*writefunc)(" ", 1);
                     msgenvelope(writefunc, fp, mimep->firstpart);
                     (*writefunc)(" ", 1);
                     msgbodystructure(writefunc, dox, fp, mimep->firstpart);
                     (*writefunc)(" ", 1);
                     sprintf(buf, "%lu", (unsigned long)nbodylines);
                     (*writefunc)(buf, strlen(buf));
              }

              if (dox)
              {
                     (*writefunc)(" ", 1);
                     contentstr(writefunc, rfc2045_content_md5(mimep));

                     (*writefunc)(" ", 1);
                     do_disposition(writefunc, disposition_s,
                            mimep->content_disposition_attr);

                     (*writefunc)(" NIL", 4);
                            /* TODO Content-Language: */
              }
       }
       (*writefunc)(")", 1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void msgenvelope ( void(*)(const char *, size_t)  ,
FILE *  ,
struct rfc2045  
)

Definition at line 215 of file msgenvelope.c.

{
char   *date=0, *subject=0;
char   *from=0, *sender=0, *replyto=0, *to=0, *cc=0, *bcc=0;
char   *inreplyto=0, *msgid=0;

off_t start_pos, end_pos, start_body;
off_t nlines, nbodylines;

char   *p, *q, *r;

       rfc2045_mimepos(mimep, &start_pos, &end_pos, &start_body,
              &nlines, &nbodylines);

       if (fseek(fp, start_pos, SEEK_SET) < 0)
       {
              perror("fseek");
              exit(0);
       }

       while ((p=read_header(fp, &start_pos, &start_body)) != 0)
       {
       char   **hdrp=0;
       size_t oldl, newl;
       size_t c;

              if ((q=strchr(p, ':')) != 0)
                     *q++=0;
              for (r=p; *r; r++)
                     *r=tolower((int)(unsigned char)*r);
              if (strcmp(p, "date") == 0) hdrp= &date;
              if (strcmp(p, "subject") == 0)     hdrp= &subject;
              if (strcmp(p, "from") == 0) hdrp= &from;
              if (strcmp(p, "sender") == 0)      hdrp= &sender;
              if (strcmp(p, "reply-to") == 0)    hdrp= &replyto;
              if (strcmp(p, "to") == 0)   hdrp= &to;
              if (strcmp(p, "cc") == 0)   hdrp= &cc;
              if (strcmp(p, "bcc") == 0)  hdrp= &bcc;
              if (strcmp(p, "in-reply-to") == 0) hdrp= &inreplyto;
              if (strcmp(p, "message-id") == 0) hdrp= &msgid;
              if (!hdrp)    continue;
              if (!q)       q="";
              oldl= *hdrp ? strlen(*hdrp):0;
              newl= strlen(q);
              c=oldl+newl+1;
              if (c > 8192) c=8192;
              r= (char *)(*hdrp ? realloc(*hdrp, c+1):malloc(c+1));
              if (!r)
              {
                     perror("malloc");
                     exit(1);
              }
              if (oldl && oldl < c)
                     r[oldl++]=',';
              newl=c-oldl;
              if (newl)     memcpy(r+oldl, q, newl);
              r[oldl+newl]=0;
              *hdrp= r;
       }

#if 1
       if (!replyto)
              replyto=strdup(from ? from:"");
       if (!sender)
              sender=strdup(from ? from:"");

       if (!replyto || !sender)
       {
              perror("malloc");
              exit(1);
       }
#endif

       (*writefunc)("(", 1);
       doenvs(writefunc, date);
       (*writefunc)(" ", 1);
       doenvs(writefunc, subject);
       (*writefunc)(" ", 1);
       doenva(writefunc, from);
       (*writefunc)(" ", 1);
       doenva(writefunc, sender);
       (*writefunc)(" ", 1);
       doenva(writefunc, replyto);
       (*writefunc)(" ", 1);
       doenva(writefunc, to);
       (*writefunc)(" ", 1);
       doenva(writefunc, cc);
       (*writefunc)(" ", 1);
       doenva(writefunc, bcc);
       (*writefunc)(" ", 1);
       doenvs(writefunc, inreplyto);
       (*writefunc)(" ", 1);
       doenvs(writefunc, msgid);
       (*writefunc)(")", 1);
}

Here is the caller graph for this function:

FILE * open_cached_fp ( unsigned long  msgnum)

Definition at line 1535 of file fetch.c.

{
       int    fd;

       if (cached_fp && strcmp(cached_fp_filename,
                            current_maildir_info.msgs[msgnum].filename)
           == 0)
              return (cached_fp);

       if (cached_fp)
       {
              fclose(cached_fp);
              free(cached_fp_filename);
              cached_fp_filename=0;
              cached_fp=0;
       }

       fd=imapscan_openfile(current_mailbox, &current_maildir_info, msgnum);
       if (fd < 0 || (cached_fp=fdopen(fd, "r")) == 0)
       {
              if (fd >= 0)  close(fd);

              if ((cached_fp=tmpfile()) != 0)
              {
                     fprintf(cached_fp, unavailable);
                     if (fseek(cached_fp, 0L, SEEK_SET) < 0 ||
                         ferror(cached_fp))
                     {
                            fclose(cached_fp);
                            cached_fp=0;
                     }
              }

              if (cached_fp == 0)
              {
                     fprintf(stderr, "ERR: %s: %s\n",
                            getenv("AUTHENTICATED"),
#if    HAVE_STRERROR
                            strerror(errno)
#else
                            "error"
#endif

                            );
                     fflush(stderr);
                     _exit(1);
              }
       }

       if ((cached_fp_filename=strdup(current_maildir_info.
                                   msgs[msgnum].filename))
           == 0)
       {
              fclose(cached_fp);
              cached_fp=0;
              write_error_exit(0);
       }
       cached_base_offset=0;
       cached_virtual_offset=0;
       cached_phys_offset=0;
       return (cached_fp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_bodysection_output ( const char *  p) [static]

Definition at line 634 of file fetch.c.

{
       writes(p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_bodysection_partial ( struct fetchinfo fi,
void(*)(const char *)  func 
) [static]

Definition at line 639 of file fetch.c.

{
       (*func)("[");
       if (fi->bodysection)
       {
       struct fetchinfo *subl;

              (*func)(fi->bodysection);
              if (fi->bodysublist)
              {
              char   *p=" (";

                     for (subl=fi->bodysublist; subl; subl=subl->next)
                     {
                            (*func)(p);
                            p=" ";
                            (*func)("\"");
                            (*func)(subl->name);
                            (*func)("\"");
                     }
                     (*func)(")");
              }
       }
       (*func)("]");
       if (fi->ispartial)
       {
       char   buf[80];

              sprintf(buf, "<%lu>", (unsigned long)fi->partialstart);
              (*func)(buf);
       }
}

Here is the caller graph for this function:

static void printheader ( struct fetchheaderinfo fi,
const char *  p,
size_t  s 
) [static]

Definition at line 1268 of file fetch.c.

{
       size_t i;

       if (fi->skipping)
       {
              if (fi->skipping > s)
              {
                     fi->skipping -= s;
                     return;
              }
              p += fi->skipping;
              s -= fi->skipping;
              fi->skipping=0;
       }
       if (s > fi->cnt)     s=fi->cnt;
       for (i=0; i <= s; i++)
              if (p[i] != '\r')
                     ++header_count;
       writemem(p, s);
       fi->cnt -= s;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int reflag_filename ( struct imapscanmessageinfo mi,
struct imapflags flags,
int  fd 
)

Definition at line 177 of file fetch.c.

{
char    *p, *q, *r;
int    rc=0;
struct imapflags old_flags;
struct stat   stat_buf;

       get_message_flags(mi, 0, &old_flags);

       p=get_reflagged_filename(mi->filename, flags);

       q=malloc(strlen(current_mailbox)+strlen(mi->filename)+sizeof("/cur/"));
       r=malloc(strlen(current_mailbox)+strlen(p)+sizeof("/cur/"));
       if (!q || !r) write_error_exit(0);
       strcat(strcat(strcpy(q, current_mailbox), "/cur/"), mi->filename);
       strcat(strcat(strcpy(r, current_mailbox), "/cur/"), p);
       if (strcmp(q, r))
       {
              if (maildirquota_countfolder(current_mailbox)
                     && old_flags.deleted != flags->deleted
                     && fstat(fd, &stat_buf) == 0)
              {
                     struct maildirsize quotainfo;
                     int64_t       nbytes;
                     unsigned long unbytes;
                     int    nmsgs=1;

                     if (maildir_parsequota(mi->filename, &unbytes) == 0)
                            nbytes=unbytes;
                     else
                            nbytes=stat_buf.st_size;
                     if ( flags->deleted )
                     {
                            nbytes= -nbytes;
                            nmsgs= -nmsgs;
                     }

                     if ( maildir_quota_delundel_start(current_mailbox,
                                                   &quotainfo,
                                                   nbytes, nmsgs))
                            rc= -1;
                     else
                            maildir_quota_delundel_end(&quotainfo,
                                                    nbytes, nmsgs);
              }

              if (rc == 0)
                     rename(q, r);

#if SMAP
              snapshot_needed();
#endif
       }
       free(q);
       free(r);
       free(mi->filename);
       mi->filename=p;

#if 0
       if (is_sharedsubdir(current_mailbox))
              maildir_shared_updateflags(current_mailbox, p);
#endif

       return (rc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* rfc2045id ( struct rfc2045 )
static void rfc822 ( FILE *  fp,
struct fetchinfo fi,
struct imapscaninfo info,
unsigned long  msgnum,
struct rfc2045 rfcp 
) [static]

Definition at line 1291 of file fetch.c.

{
unsigned long n=0;
int    c;
char   buf[BUFSIZ];
unsigned long i;

       writes("RFC822 ");

       if (fseek(fp, 0L, SEEK_SET) == -1)
       {
              fetcherror("fseek", fi, info, msgnum);
              writes("{0}\r\n");
              return;
       }
       while ((c=getc(fp)) != EOF)
       {
              ++n;
              if (c == '\n')       ++n;
       }

       if (fseek(fp, 0L, SEEK_SET) == -1)
       {
              fetcherror("fseek", fi, info, msgnum);
              writes("{0}\r\n");
              return;
       }
       writes("{");
       writen(n);
       writes("}\r\n");

       i=0;
       while (n)
       {
              c=getc(fp);
              if (c == '\n')
              {
                     if (i >= sizeof(buf))
                     {
                            writemem(buf, i);
                            i=0;
                     }
                     buf[i++]='\r';
                     if (--n == 0) break;
              }

              if (i >= sizeof(buf))
              {
                     writemem(buf, i);
                     i=0;
              }
              buf[i++]=c;
              --n;
              ++body_count;
       }
       writemem(buf, i);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void rfc822header ( FILE *  fp,
struct fetchinfo fi,
struct imapscaninfo info,
unsigned long  msgnum,
struct rfc2045 rfcp 
) [static]

Definition at line 1351 of file fetch.c.

{
unsigned long n=0;
int    c;
char   buf[BUFSIZ];
unsigned long i;
int    eol;

       writes("RFC822.HEADER ");

       if (fseek(fp, 0L, SEEK_SET) == -1)
       {
              fetcherror("fseek", fi, info, msgnum);
              writes("{0}\r\n");
              return;
       }

       eol=0;
       while ((c=getc(fp)) != EOF)
       {
              ++n;
              if (c != '\n')
              {
                     eol=0;
                     continue;
              }
              ++n;
              if (eol)      break;
              eol=1;
       }

       if (fseek(fp, 0L, SEEK_SET) == -1)
       {
              fetcherror("fseek", fi, info, msgnum);
              writes("{0}\r\n");
              return;
       }
       writes("{");
       writen(n);
       writes("}\r\n");

       i=0;
       while (n)
       {
              c=getc(fp);
              if (c == '\n')
              {
                     if (i >= sizeof(buf))
                     {
                            writemem(buf, i);
                            i=0;
                     }
                     buf[i++]='\r';
                     if (--n == 0) break;
              }

              if (i >= sizeof(buf))
              {
                     writemem(buf, i);
                     i=0;
              }
              buf[i++]=c;
              --n;
              ++header_count;
       }
       writemem(buf, i);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void rfc822size ( FILE *  fp,
struct fetchinfo fi,
struct imapscaninfo i,
unsigned long  msgnum,
struct rfc2045 mimep 
) [static]

Definition at line 570 of file fetch.c.

{
off_t start_pos, end_pos, start_body;
off_t nlines, nbodylines;

       writes("RFC822.SIZE ");

       rfc2045_mimepos(mimep, &start_pos, &end_pos, &start_body,
              &nlines, &nbodylines);

       writen(end_pos - start_pos + nlines);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void rfc822text ( FILE *  fp,
struct fetchinfo fi,
struct imapscaninfo info,
unsigned long  msgnum,
struct rfc2045 rfcp 
) [static]

Definition at line 1421 of file fetch.c.

{
off_t start_pos, end_pos, start_body;
off_t nlines, nbodylines;
unsigned long i;
int    c;
char   buf[BUFSIZ];
unsigned long l;

       writes("RFC822.TEXT {");

       rfc2045_mimepos(rfcp, &start_pos, &end_pos, &start_body,
              &nlines, &nbodylines);

       if (fseek(fp, start_body, SEEK_SET) == -1)
       {
              fetcherror("fseek", fi, info, msgnum);
              writes("0}\r\n");
              return;
       }

       i=end_pos - start_body + nbodylines;

       writen(i);
       writes("}\r\n");

       l=0;
       while (i)
       {
              c=getc(fp);
              if (c == EOF)
              {
                     fetcherror("unexpected EOF", fi, info, msgnum);
                     _exit(1);
              }
              --i;
              if (l >= sizeof(BUFSIZ))
              {
                     writemem(buf, l);
                     l=0;
              }
              if (c == '\n' && i)
              {
                     --i;
                     buf[l++]='\r';
                     if (l >= sizeof(BUFSIZ))
                     {
                            writemem(buf, l);
                            l=0;
                     }
              }
              buf[l++]=c;
              ++body_count;
       }
       writemem(buf, l);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void save_cached_offsets ( off_t  base,
off_t  virt,
off_t  phys 
)

Definition at line 1609 of file fetch.c.

Here is the caller graph for this function:

void snapshot_needed ( )

Definition at line 632 of file smapsnapshot.c.

{
       index_dirty=1;
}

Here is the caller graph for this function:

static void uid ( FILE *  fp,
struct fetchinfo fi,
struct imapscaninfo i,
unsigned long  msgnum,
struct rfc2045 mimep 
) [static]

Definition at line 562 of file fetch.c.

{
       writes("UID ");
       writen(i->msgs[msgnum].uid);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

unsigned long body_count = 0

Definition at line 42 of file fetch.c.

off_t cached_base_offset [static]

Definition at line 1531 of file fetch.c.

char* cached_filename [static]

Definition at line 1488 of file fetch.c.

FILE* cached_fp = 0 [static]

Definition at line 1529 of file fetch.c.

char* cached_fp_filename = 0 [static]

Definition at line 1530 of file fetch.c.

off_t cached_phys_offset [static]

Definition at line 1533 of file fetch.c.

struct rfc2045* cached_rfc2045p [static]

Definition at line 1487 of file fetch.c.

off_t cached_virtual_offset [static]

Definition at line 1532 of file fetch.c.

Definition at line 124 of file imapd.c.

Definition at line 135 of file imapd.c.

Definition at line 134 of file imapd.c.

unsigned long header_count = 0

Definition at line 42 of file fetch.c.

const char unavailable[] [static]
Initial value:
"\
From: System Administrator <root@localhost>\n\
Subject: message unavailable\n\n\
This message is no longer available on the server.\n"

Definition at line 36 of file fetch.c.