This patch is ugly hack to c-client adds OR criteria from IMAP4 spec to search string passed to mail_criteria(). Note that parentheses syntax is not implemented. --- imap-2007f-orig/src/c-client/mail.c 2013-01-23 17:10:23.000000000 +0200 +++ imap-2007f/src/c-client/mail.c 2013-01-25 18:19:04.000000000 +0200 @@ -3990,24 +3990,56 @@ } return NIL; } + + +SEARCHPGM *mail_criteria_fixed (char *criteria, int *skip); + +static int mail_criteria_or(SEARCHOR **orpgm, char **r) { + + char tmp[MAILTMPLEN], *pr; + int skip = 1; /* set mail_criteria_fixed to do one run from a loop only */ + + pr = *r; /* save original pointer to reset in case of error */ + + while (*orpgm) orpgm = &(*orpgm)->next; /* find tail of list */ + *orpgm = mail_newsearchor (); /* make new entry */ + + (*orpgm)->first = mail_criteria_fixed(*r, &skip); +/* if ( !(*orpgm)->first ) return NIL; // FIXME: does not work ? */ + *r = *r+skip; /* update original criteria with processed tokens */ + + (*orpgm)->second = mail_criteria_fixed(*r, &skip); +/* if ( !(*orpgm)->first ) { *r = pr; return NIL; } // FIXME: does not work ? */ + *r = *r+skip; + + return T; +} + + /* Mail parse search criteria - * Accepts: criteria + * [DG]: fixed for OR criterion by recursive calling: + * Accepts: criteria, skip + * "skip" - do one run only when set and updated with offset of chars parsed * Returns: search program if parse successful, else NIL */ -SEARCHPGM *mail_criteria (char *criteria) +SEARCHPGM *mail_criteria_fixed (char *criteria, int *skip) { SEARCHPGM *pgm = NIL; - char *criterion,*r,tmp[MAILTMPLEN]; - int f; + char *criterion,*r,tmp[MAILTMPLEN],*pr; + int f, fcount=0; if (criteria) { /* only if criteria defined */ - /* make writeable copy of criteria */ - criteria = cpystr (criteria); + + criteria = cpystr (criteria); /* make writeable copy of criteria */ + + pr = criteria; /* save original criteria's start to calculate difference */ + /* for each criterion */ for (pgm = mail_newsearchpgm (), criterion = strtok_r (criteria," ",&r); criterion; (criterion = strtok_r (NIL," ",&r))) { f = NIL; /* init then scan the criterion */ + switch (*ucase (criterion)) { case 'A': /* possible ALL, ANSWERED */ if (!strcmp (criterion+1,"LL")) f = T; @@ -4036,12 +4068,13 @@ if (!strcmp (criterion+1,"EYWORD")) f = mail_criteria_string (&pgm->keyword,&r); break; - case 'N': /* possible NEW */ if (!strcmp (criterion+1,"EW")) f = pgm->recent = pgm->unseen = T; break; case 'O': /* possible OLD, ON */ if (!strcmp (criterion+1,"LD")) f = pgm->old = T; + else if (!strcmp (criterion+1,"R")) /* [DG]: OR is possible in this patch */ + f = mail_criteria_or (&pgm->or,&r); else if (!strcmp (criterion+1,"N")) f = mail_criteria_date (&pgm->on,&r); break; @@ -4066,6 +4099,7 @@ if (!strcmp (criterion+2,"ANSWERED")) f = pgm->unanswered = T; else if (!strcmp (criterion+2,"DELETED")) f = pgm->undeleted = T; else if (!strcmp (criterion+2,"FLAGGED")) f = pgm->unflagged = T; + else if (!strcmp (criterion+2,"DRAFT")) f = pgm->undraft = T; else if (!strcmp (criterion+2,"KEYWORD")) f = mail_criteria_string (&pgm->unkeyword,&r); else if (!strcmp (criterion+2,"SEEN")) f = pgm->unseen = T; @@ -4080,12 +4114,26 @@ mail_free_searchpgm (&pgm); break; } + fcount++; /* count rounds */ + if ( *skip && fcount == 1 ) { /* */ + (*skip) = r - pr; + break; + } } /* no longer need copy of criteria */ fs_give ((void **) &criteria); } return pgm; } + +/* [DG]: this is wrapper over original function ot add additional arg */ +SEARCHPGM *mail_criteria (char *criteria) +{ + int skip = 0; + return mail_criteria_fixed (criteria, &skip); + +} + /* Parse a date * Accepts: pointer to date integer to return