Back to index

citadel  8.12
Functions
imap_fetch.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void imap_pick_range (const char *range, int is_uid)
void imap_fetch (int num_parms, ConstStr *Params)
void imap_uidfetch (int num_parms, ConstStr *Params)
void imap_fetch_flags (int seq)
int imap_extract_data_items (citimap_command *Cmd)

Function Documentation

Definition at line 1255 of file imap_fetch.c.

{
       int nArgs;
       int nest = 0;
       const char *pch, *end;

       /* Convert all whitespace to ordinary space characters. */
       pch = ChrPtr(Cmd->CmdBuf);
       end = pch + StrLength(Cmd->CmdBuf);

       while (pch < end)
       {
              if (isspace(*pch)) 
                     StrBufPeek(Cmd->CmdBuf, pch, 0, ' ');
              pch++;
       }

       /* Strip leading and trailing whitespace, then strip leading and
        * trailing parentheses if it's a list
        */
       StrBufTrim(Cmd->CmdBuf);
       pch = ChrPtr(Cmd->CmdBuf);
       if ( (pch[0]=='(') && 
            (pch[StrLength(Cmd->CmdBuf)-1]==')') ) 
       {
              StrBufCutRight(Cmd->CmdBuf, 1);
              StrBufCutLeft(Cmd->CmdBuf, 1);
              StrBufTrim(Cmd->CmdBuf);
       }

       /* Parse any macro data items */
       imap_handle_macros(Cmd);

       /*
        * Now break out the data items.  We throw in one trailing space in
        * order to avoid having to break out the last one manually.
        */
       nArgs = StrLength(Cmd->CmdBuf) / 10 + 10;
       nArgs = CmdAdjust(Cmd, nArgs, 0);
       Cmd->num_parms = 0;
       Cmd->Params[Cmd->num_parms].Key = pch = ChrPtr(Cmd->CmdBuf);
       end = Cmd->Params[Cmd->num_parms].Key + StrLength(Cmd->CmdBuf);

       while (pch < end) 
       {
              if ((*pch=='(') ||
                  (*pch=='[') ||
                  (*pch=='<') ||
                  (*pch=='{'))
                     ++nest;

              else if ((*pch==')') ||
                      (*pch==']') ||
                      (*pch=='>') ||
                      (*pch=='}'))
                     --nest;

              if ((nest <= 0) && (*pch==' '))    {
                     StrBufPeek(Cmd->CmdBuf, pch, 0, '\0');
                     Cmd->Params[Cmd->num_parms].len = 
                            pch - Cmd->Params[Cmd->num_parms].Key;

                     if (Cmd->num_parms + 1 >= Cmd->avail_parms) {
                            nArgs = CmdAdjust(Cmd, nArgs * 2, 1);
                     }
                     Cmd->num_parms++;                  
                     Cmd->Params[Cmd->num_parms].Key = ++pch;
              }
              else if (pch + 1 == end) {
                     Cmd->Params[Cmd->num_parms].len = 
                            pch - Cmd->Params[Cmd->num_parms].Key + 1;

                     Cmd->num_parms++;                  
              }
              pch ++;
       }
       return Cmd->num_parms;

}

Here is the call graph for this function:

Here is the caller graph for this function:

void imap_fetch ( int  num_parms,
ConstStr *  Params 
)

Definition at line 1417 of file imap_fetch.c.

                                                 {
       citimap_command Cmd;
       int num_items;
       
       if (num_parms < 4) {
              IReply("BAD invalid parameters");
              return;
       }

       imap_pick_range(Params[2].Key, 0);

       memset(&Cmd, 0, sizeof(citimap_command));
       Cmd.CmdBuf = NewStrBufPlain(NULL, StrLength(IMAP->Cmd.CmdBuf));
       MakeStringOf(Cmd.CmdBuf, 3);

       num_items = imap_extract_data_items(&Cmd);
       if (num_items < 1) {
              IReply("BAD invalid data item list");
              FreeStrBuf(&Cmd.CmdBuf);
              free(Cmd.Params);
              return;
       }

       imap_do_fetch(&Cmd);
       IReply("OK FETCH completed");
       FreeStrBuf(&Cmd.CmdBuf);
       free(Cmd.Params);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void imap_fetch_flags ( int  seq)

Definition at line 75 of file imap_fetch.c.

{
       citimap *Imap = IMAP;
       int num_flags_printed = 0;
       IAPuts("FLAGS (");
       if (Imap->flags[seq] & IMAP_DELETED) {
              if (num_flags_printed > 0) 
                     IAPuts(" ");
              IAPuts("\\Deleted");
              ++num_flags_printed;
       }
       if (Imap->flags[seq] & IMAP_SEEN) {
              if (num_flags_printed > 0) 
                     IAPuts(" ");
              IAPuts("\\Seen");
              ++num_flags_printed;
       }
       if (Imap->flags[seq] & IMAP_ANSWERED) {
              if (num_flags_printed > 0) 
                     IAPuts(" ");
              IAPuts("\\Answered");
              ++num_flags_printed;
       }
       if (Imap->flags[seq] & IMAP_RECENT) {
              if (num_flags_printed > 0) 
                     IAPuts(" ");
              IAPuts("\\Recent");
              ++num_flags_printed;
       }
       IAPuts(")");
}

Here is the caller graph for this function:

void imap_pick_range ( const char *  range,
int  is_uid 
)

Definition at line 1351 of file imap_fetch.c.

                                                             {
       citimap *Imap = IMAP;
       int i;
       int num_sets;
       int s;
       char setstr[SIZ], lostr[SIZ], histr[SIZ];
       long lo, hi;
       char actual_range[SIZ];

       /* 
        * Handle the "ALL" macro
        */
       if (!strcasecmp(supplied_range, "ALL")) {
              safestrncpy(actual_range, "1:*", sizeof actual_range);
       }
       else {
              safestrncpy(actual_range, supplied_range, sizeof actual_range);
       }

       /*
        * Clear out the IMAP_SELECTED flags for all messages.
        */
       for (i = 0; i < Imap->num_msgs; ++i) {
              Imap->flags[i] = Imap->flags[i] & ~IMAP_SELECTED;
       }

       /*
        * Now set it for all specified messages.
        */
       num_sets = num_tokens(actual_range, ',');
       for (s=0; s<num_sets; ++s) {
              extract_token(setstr, actual_range, s, ',', sizeof setstr);

              extract_token(lostr, setstr, 0, ':', sizeof lostr);
              if (num_tokens(setstr, ':') >= 2) {
                     extract_token(histr, setstr, 1, ':', sizeof histr);
                     if (!strcmp(histr, "*")) snprintf(histr, sizeof histr, "%ld", LONG_MAX);
              } 
              else {
                     safestrncpy(histr, lostr, sizeof histr);
              }
              lo = atol(lostr);
              hi = atol(histr);

              /* Loop through the array, flipping bits where appropriate */
              for (i = 1; i <= Imap->num_msgs; ++i) {
                     if (is_uid) { /* fetch by sequence number */
                            if ( (Imap->msgids[i-1]>=lo)
                               && (Imap->msgids[i-1]<=hi)) {
                                   Imap->flags[i-1] |= IMAP_SELECTED;
                            }
                     }
                     else {        /* fetch by uid */
                            if ( (i>=lo) && (i<=hi)) {
                                   Imap->flags[i-1] |= IMAP_SELECTED;
                            }
                     }
              }
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void imap_uidfetch ( int  num_parms,
ConstStr *  Params 
)

Definition at line 1449 of file imap_fetch.c.

                                                    {
       citimap_command Cmd;
       int num_items;
       int i;
       int have_uid_item = 0;

       if (num_parms < 5) {
              IReply("BAD invalid parameters");
              return;
       }

       imap_pick_range(Params[3].Key, 1);

       memset(&Cmd, 0, sizeof(citimap_command));
       Cmd.CmdBuf = NewStrBufPlain(NULL, StrLength(IMAP->Cmd.CmdBuf));

       MakeStringOf(Cmd.CmdBuf, 4);
#if 0
       IMAP_syslog(LOG_DEBUG, "-------%s--------", ChrPtr(Cmd.CmdBuf));
#endif
       num_items = imap_extract_data_items(&Cmd);
       if (num_items < 1) {
              IReply("BAD invalid data item list");
              FreeStrBuf(&Cmd.CmdBuf);
              free(Cmd.Params);
              return;
       }

       /* If the "UID" item was not included, we include it implicitly
        * (at the beginning) because this is a UID FETCH command
        */
       for (i=0; i<num_items; ++i) {
              if (!strcasecmp(Cmd.Params[i].Key, "UID")) ++have_uid_item;
       }
       if (have_uid_item == 0) {
              if (Cmd.num_parms + 1 >= Cmd.avail_parms)
                     CmdAdjust(&Cmd, Cmd.avail_parms + 1, 1);
              memmove(&Cmd.Params[1], 
                     &Cmd.Params[0], 
                     sizeof(ConstStr) * Cmd.num_parms);

              Cmd.num_parms++;
              Cmd.Params[0] = (ConstStr){HKEY("UID")};
       }

       imap_do_fetch(&Cmd);
       IReply("OK UID FETCH completed");
       FreeStrBuf(&Cmd.CmdBuf);
       free(Cmd.Params);
}

Here is the call graph for this function:

Here is the caller graph for this function: