Back to index

courier  0.68.2
Defines | Functions | Variables
imaptoken.c File Reference
#include "imaptoken.h"
#include "imapwrite.h"
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include "numlib/numlib.h"

Go to the source code of this file.

Defines

#define BUFSIZ   8192
#define UNREAD(c)   (*--imap_readptr=(c), ++imap_readptrleft)
#define appendch(c)   alloc_tokenbuf(l+1); curtoken.tokenbuf[l++]=(c);

Functions

void bye ()
void bye_msg (const char *type)
void disconnected ()
static void disconnected_timeout (void)
int doidle (time_t idletimeout, int extraFd)
size_t doread (char *buf, size_t bufsiz)
void readfill ()
void unread (int c)
void read_eol ()
void read_timeout (time_t t)
static void alloc_tokenbuf (unsigned l)
void ignorepunct ()
static struct imaptokendo_readtoken (int touc)
static struct imaptokenreadtoken (int touc)
struct imaptokennexttoken (void)
struct imaptokennexttoken_nouc (void)
struct imaptokennexttoken_okbracket (void)
struct imaptokennexttoken_nouc_okbracket (void)
struct imaptokencurrenttoken (void)
struct imaptokennexttoken_noparseliteral (void)
void read_string (char **ptr, unsigned long *left, unsigned long cnt)
char * my_strdup (const char *s)
int ismsgset (struct imaptoken *tok)
int ismsgset_str (const char *p)

Variables

static struct imaptoken
static char readbuf [BUFSIZ]
char * imap_readptr = 0
size_t imap_readptrleft = 0
time_t start_time
static time_t readtimeout
FILE * debugfile
unsigned long header_count
unsigned long body_count
unsigned long bytes_received_count = 0
unsigned long bytes_sent_count
static char LPAREN_CHAR = '('
static char RPAREN_CHAR = ')'
static char LBRACKET_CHAR = '['
static char RBRACKET_CHAR = ']'

Define Documentation

#define appendch (   c)    alloc_tokenbuf(l+1); curtoken.tokenbuf[l++]=(c);
#define BUFSIZ   8192

Definition at line 24 of file imaptoken.c.

#define UNREAD (   c)    (*--imap_readptr=(c), ++imap_readptrleft)

Definition at line 152 of file imaptoken.c.


Function Documentation

static void alloc_tokenbuf ( unsigned  l) [static]

Definition at line 176 of file imaptoken.c.

{
       if (l >= curtoken.tokenbuf_size)
       {
       char   *p=curtoken.tokenbuf ? realloc(curtoken.tokenbuf, l + 256):
                     malloc(l + 256);

              if (!p)
                     write_error_exit("malloc");

              curtoken.tokenbuf_size = l+256;
              curtoken.tokenbuf=p;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void bye ( )

Definition at line 2240 of file imapd.c.

Here is the call graph for this function:

Here is the caller graph for this function:

void bye_msg ( const char *  type)

Definition at line 46 of file imaptoken.c.

{
       const char *a=getenv("AUTHENTICATED");
       char buf[NUMBUFSIZE];
       const char *tls=getenv("IMAP_TLS");

       libmail_str_time_t(time(NULL)-start_time, buf);

       if (tls && atoi(tls))
              tls=", starttls=1";
       else
              tls="";

       if (a && *a)
              fprintf(stderr, "%s, user=%s, "
                     "ip=[%s], headers=%lu, body=%lu, rcvd=%lu, sent=%lu, time=%s%s\n",
                     type,
                     a, getenv("TCPREMOTEIP"), header_count, body_count, bytes_received_count, bytes_sent_count,
                     buf, tls);
       else
              fprintf(stderr, "DEBUG: Disconnected, ip=[%s], time=%s%s\n",
                     getenv("TCPREMOTEIP"),
                     buf, tls);
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct imaptoken* currenttoken ( void  ) [read]

Definition at line 468 of file imaptoken.c.

{
       return (&curtoken);
}

Here is the caller graph for this function:

void disconnected ( )

Definition at line 71 of file imaptoken.c.

{
       bye_msg("INFO: DISCONNECTED");
       bye();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void disconnected_timeout ( void  ) [static]

Definition at line 77 of file imaptoken.c.

{
       writes("* BYE Disconnected for inactivity.\r\n");
       writeflush();
       bye_msg("INFO: TIMEOUT");
       bye();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static struct imaptoken* do_readtoken ( int  touc) [static, read]

Definition at line 220 of file imaptoken.c.

{
int    c=0;
unsigned l;

#define       appendch(c)   alloc_tokenbuf(l+1); curtoken.tokenbuf[l++]=(c);

       if (curtoken.tokentype == IT_ERROR)       return (&curtoken);

       do
       {
              c=READ();
       } while (c == '\r' || c == ' ' || c == '\t');

       if (c == '\n')
       {
              UNREAD(c);
              curtoken.tokentype=IT_EOL;
              return (&curtoken);
       }
       c=(unsigned char)c;
       if (c == LPAREN_CHAR)
       {
              curtoken.tokentype=IT_LPAREN;
              return (&curtoken);
       }

       if (c == RPAREN_CHAR)
       {
              curtoken.tokentype=IT_RPAREN;
              return (&curtoken);
       }

       if (c == LBRACKET_CHAR)
       {
              curtoken.tokentype=IT_LBRACKET;
              return (&curtoken);
       }

       if (c == RBRACKET_CHAR)
       {
              curtoken.tokentype=IT_RBRACKET;
              return (&curtoken);
       }

       if (c == '"')
       {
              l=0;
              while ((c=READ()) != '"')
              {
                     if (c == '\\')
                            c=READ();
                     if (c == '\r' || c == '\n')
                     {
                            UNREAD(c);
                            curtoken.tokentype=IT_ERROR;
                            return (&curtoken);
                     }
                     if (l < 8192)
                     {
                            appendch(c);
                     }
              }
              appendch(0);
              curtoken.tokentype=IT_QUOTED_STRING;
              return (&curtoken);
       }

       if (c == '{')
       {
              curtoken.tokennum=0;
              while ((c=READ()) != '}')
              {
                     if (!isdigit((int)(unsigned char)c))
                     {
                            UNREAD(c);
                            curtoken.tokentype=IT_ERROR;
                            return (&curtoken);
                     }
                     curtoken.tokennum = curtoken.tokennum*10 + (c-'0');
              }
              c=READ();
              if (c == '\r')
              {
                     c=READ();
              }
              if (c != '\n')
              {
                     curtoken.tokentype=IT_ERROR;
                     return (&curtoken);
              }
              curtoken.tokentype=IT_LITERAL_STRING_START;
              return (&curtoken);
       }

       l=0;
       if (c == '\\')
       {
              appendch(c);  /* Message flag */
              c=READ();
       }
       else if (isdigit(c))
       {
              curtoken.tokentype=IT_NUMBER;
              curtoken.tokennum=0;
              do
              {
                     appendch(c);
                     curtoken.tokennum = curtoken.tokennum*10 +
                            (c-'0');
                     c=READ();
              } while (isdigit( (int)(unsigned char)c));

              /* Could be stuff like mime.spec, so continue reading. */
       }

       while (c != '\r' && c != '\n'
              && !isspace((int)(unsigned char)c)
              && c != '\\' && c != '"' && c != LPAREN_CHAR && c != RPAREN_CHAR
              && c != '{' && c != '}' && c != LBRACKET_CHAR && c != RBRACKET_CHAR)
       {
              curtoken.tokentype=IT_ATOM;
              if (l < IT_MAX_ATOM_SIZE)
              {
                     if (touc)
                            c=toupper(c);
                     appendch(c);
              }
              else
              {
                     write_error_exit("max atom size too small");  
              }
              c=READ();
       }
       if (l == 0)
       {
              curtoken.tokentype=IT_ERROR;
              return (&curtoken);
       }
       appendch(0);
       UNREAD(c);

       if (strcmp(curtoken.tokenbuf, "NIL") == 0)
              curtoken.tokentype=IT_NIL;
       return (&curtoken);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int doidle ( time_t  idletimeout,
int  extraFd 
)

Definition at line 85 of file imaptoken.c.

{
fd_set fds;
struct timeval tv;
time_t t;

       time(&t);
       if (t >= readtimeout)   disconnected_timeout();
       if (imap_readptrleft > 0) return 1;

       FD_ZERO(&fds);
       FD_SET(0, &fds);

       if (extraFd > 0)
       {
              FD_SET(extraFd, &fds);
       }
       else
       {
              extraFd=0;
       }

       tv.tv_sec=idletimeout;
       tv.tv_usec=0;

       select(extraFd + 1, &fds, 0, 0, &tv);
       return (FD_ISSET(0, &fds));
}

Here is the call graph for this function:

Here is the caller graph for this function:

size_t doread ( char *  buf,
size_t  bufsiz 
)

Definition at line 114 of file imaptoken.c.

{
fd_set fds;
struct timeval       tv;
time_t t;
int n = 0;

       time(&t);
       if (t >= readtimeout)       disconnected_timeout();

       FD_ZERO(&fds);
       FD_SET(0, &fds);
       tv.tv_sec=readtimeout - t;
       tv.tv_usec=0;

       if (select(1, &fds, 0, 0, &tv) <= 0)
       {
              disconnected_timeout();
              return (0);
       }
       if (!FD_ISSET(0, &fds) || (n=read(0, buf, bufsiz)) <= 0)
       {
              if ( n > 0 )
                     bytes_received_count += n; /* count received bytes */
              disconnected();
              return (0);
       }
       if ( n > 0 )
              bytes_received_count += n; /* count received bytes */
       return (n);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void ignorepunct ( )

Definition at line 196 of file imaptoken.c.

Here is the caller graph for this function:

int ismsgset ( struct imaptoken tok)

Definition at line 518 of file imaptoken.c.

{

       if (tok->tokentype == IT_NUMBER)   return (1);
       if (tok->tokentype != IT_ATOM)            return (0);

       return ismsgset_str(tok->tokenbuf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ismsgset_str ( const char *  p)

Definition at line 528 of file imaptoken.c.

{
       while (isdigit((int)(unsigned char)*p) || *p == '*')
       {
              if (*p == '0')       return (0);
              if (*p == '*')
                     ++p;
              else
                     do
                     {
                            ++p;
                     } while (isdigit((int)(unsigned char)*p));

              if (*p == ':')
              {
                     ++p;
                     if (!isdigit((int)(unsigned char)*p) &&
                            *p != '*')
                            return (0);
                     if (*p == '0')       return (0);
                     if (*p == '*')
                            ++p;
                     else
                            do
                            {
                                   ++p;
                            } while (isdigit((int)(unsigned char)*p));
              }
              if (*p != ',')       break;
              ++p;
       }
       if (*p)       return (0);
       return (1);
}

Here is the caller graph for this function:

char* my_strdup ( const char *  s)

Definition at line 510 of file imaptoken.c.

{
char   *q=strdup(s);

       if (!q)       write_error_exit("malloc");
       return (q);
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct imaptoken* nexttoken ( void  ) [read]

Definition at line 430 of file imaptoken.c.

{
       return (readtoken(1));
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct imaptoken* nexttoken_noparseliteral ( void  ) [read]

Definition at line 473 of file imaptoken.c.

{
       return (do_readtoken(0));
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct imaptoken* nexttoken_nouc ( void  ) [read]

Definition at line 435 of file imaptoken.c.

{
       return (readtoken(0));
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct imaptoken* nexttoken_nouc_okbracket ( void  ) [read]

Definition at line 455 of file imaptoken.c.

{
       struct imaptoken *t;

       LBRACKET_CHAR=RBRACKET_CHAR='\n';

       t=nexttoken_nouc();

       LBRACKET_CHAR='[';
       RBRACKET_CHAR=']';
       return (t);
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct imaptoken* nexttoken_okbracket ( void  ) [read]

Definition at line 442 of file imaptoken.c.

{
       struct imaptoken *t;

       LBRACKET_CHAR=RBRACKET_CHAR='\n';

       t=nexttoken();

       LBRACKET_CHAR='[';
       RBRACKET_CHAR=']';
       return (t);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void read_eol ( )

Definition at line 159 of file imaptoken.c.

{
int    c;

       while ( (c=READ()) != '\n')
              ;
       curtoken.tokentype=IT_EOL;
}

Here is the caller graph for this function:

void read_string ( char **  ptr,
unsigned long *  left,
unsigned long  cnt 
)

Definition at line 480 of file imaptoken.c.

{
       if (imap_readptrleft == 0)
       {
              /* Keep reading until we fill the buffer or until we've
              ** read the entire string.
              */

              read_timeout(SOCKET_TIMEOUT);
              imap_readptr=readbuf;
              while (imap_readptrleft < sizeof(readbuf) && imap_readptrleft < cnt)
                     imap_readptrleft += doread(readbuf+imap_readptrleft,
                                          sizeof(readbuf)-imap_readptrleft);
       }

       if (cnt < imap_readptrleft) /* Can satisfy fully from buffer */
       {
              *ptr=imap_readptr;
              *left=cnt;
              imap_readptr += cnt;
              imap_readptrleft -= cnt;
              return;
       }

       *ptr=imap_readptr;
       *left=imap_readptrleft;
       imap_readptrleft=0;
       return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void read_timeout ( time_t  t)

Definition at line 168 of file imaptoken.c.

{
time_t tt;

       time(&tt);
       readtimeout=tt+t;
}

Here is the caller graph for this function:

void readfill ( )

Definition at line 146 of file imaptoken.c.

Here is the call graph for this function:

static struct imaptoken* readtoken ( int  touc) [static, read]

Definition at line 367 of file imaptoken.c.

{
struct imaptoken *tok=do_readtoken(touc);

       if (tok->tokentype == IT_LITERAL_STRING_START)
       {
       unsigned long nbytes=curtoken.tokennum;

              if (nbytes > 8192)
              {
                     writes("* NO [ALERT] IMAP command too long.\r\n");
                     tok->tokentype=IT_ERROR;
              }
              else
              {
              unsigned long i;

                     writes("+ OK\r\n");
                     writeflush();
                     alloc_tokenbuf(nbytes+1);
                     for (i=0; i<nbytes; i++)
                            tok->tokenbuf[i]= READ();
                     tok->tokenbuf[i]=0;
                     tok->tokentype=IT_QUOTED_STRING;
              }
       }

       if (debugfile)
       {
       char   *p=0;

              fprintf(debugfile, "READ: ");
              switch (tok->tokentype) {
              case IT_ATOM:
                     p=curtoken.tokenbuf; fprintf(debugfile, "ATOM"); break;
              case IT_NUMBER:
                     p=curtoken.tokenbuf; fprintf(debugfile, "NUMBER"); break;
              case IT_QUOTED_STRING:
                     p=curtoken.tokenbuf; fprintf(debugfile, "QUOTED_STRING"); break;
              case IT_LPAREN:
                     fprintf(debugfile, "LPAREN"); break;
              case IT_RPAREN:
                     fprintf(debugfile, "RPAREN"); break;
              case IT_NIL:
                     fprintf(debugfile, "NIL"); break;
              case IT_ERROR:
                     fprintf(debugfile, "ERROR"); break;
              case IT_EOL:
                     fprintf(debugfile, "EOL"); break;
              case IT_LBRACKET:
                     fprintf(debugfile, "LBRACKET"); break;
              case IT_RBRACKET:
                     fprintf(debugfile, "RBRACKET"); break;
              }

              if (p)
                     fprintf(debugfile, ": %s", p);
              fprintf(debugfile, "\n");
              fflush(debugfile);
       }
       return (tok);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void unread ( int  c)

Definition at line 154 of file imaptoken.c.

{
       UNREAD(c);
}

Here is the caller graph for this function:


Variable Documentation

unsigned long body_count

Definition at line 42 of file fetch.c.

unsigned long bytes_received_count = 0

Definition at line 41 of file imaptoken.c.

unsigned long bytes_sent_count

Definition at line 42 of file imaptoken.c.

FILE* debugfile

Definition at line 125 of file imapd.c.

unsigned long header_count

Definition at line 42 of file fetch.c.

char* imap_readptr = 0

Definition at line 31 of file imaptoken.c.

size_t imap_readptrleft = 0

Definition at line 32 of file imaptoken.c.

struct imaptoken [static]

Definition at line 28 of file imaptoken.c.

char LBRACKET_CHAR = '[' [static]

Definition at line 193 of file imaptoken.c.

char LPAREN_CHAR = '(' [static]

Definition at line 191 of file imaptoken.c.

char RBRACKET_CHAR = ']' [static]

Definition at line 194 of file imaptoken.c.

char readbuf[BUFSIZ] [static]

Definition at line 29 of file imaptoken.c.

time_t readtimeout [static]

Definition at line 35 of file imaptoken.c.

char RPAREN_CHAR = ')' [static]

Definition at line 192 of file imaptoken.c.

time_t start_time

Definition at line 33 of file imaptoken.c.