Here's the patch inline: diff -u --recursive ../orig/php-5.2.12/ext/imap/php_imap.c ./ext/imap/php_imap.c --- ../orig/php-5.2.12/ext/imap/php_imap.c 2009-09-22 14:18:57.000000000 -0400 +++ ./ext/imap/php_imap.c 2010-02-03 14:16:41.000000000 -0500 @@ -152,6 +152,9 @@ PHP_FE(imap_timeout, NULL) #if defined(HAVE_IMAP2000) || defined(HAVE_IMAP2001) + PHP_FE(imap_searchprogram_new, NULL) + PHP_FE(imap_searchprogram_or, NULL) + PHP_FE(imap_searchprogram_setcriterion, NULL) PHP_FE(imap_get_quota, NULL) PHP_FE(imap_get_quotaroot, NULL) PHP_FE(imap_set_quota, NULL) @@ -209,6 +212,7 @@ /* True globals, no need for thread safety */ static int le_imap; +static int le_imap_searchpgm; #define PHP_IMAP_CHECK_MSGNO(msgindex) \ if ((msgindex < 1) || ((unsigned) msgindex > imap_le_struct->imap_stream->nmsgs)) { \ @@ -673,6 +677,7 @@ */ le_imap = zend_register_list_destructors_ex(mail_close_it, NULL, "imap", module_number); + le_imap_searchpgm = zend_register_list_destructors_ex(NULL, NULL, "imapsearchpgm", module_number); return SUCCESS; } /* }}} */ @@ -3693,7 +3698,9 @@ char *search_criteria; MESSAGELIST *cur; int argc = ZEND_NUM_ARGS(); + int criteria_is_string; SEARCHPGM *pgm = NIL; + pisearchpgms *php_searchpgm; if (argc < 2 || argc > 4 || zend_get_parameters_ex(argc, &streamind, &criteria, &search_flags, &charset) == FAILURE) { ZEND_WRONG_PARAM_COUNT(); @@ -3701,8 +3708,25 @@ ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, "imap", le_imap); - convert_to_string_ex(criteria); - search_criteria = estrndup(Z_STRVAL_PP(criteria), Z_STRLEN_PP(criteria)); + switch (Z_TYPE_PP(criteria)) { + case IS_STRING: + convert_to_string_ex(criteria); + search_criteria = estrndup(Z_STRVAL_PP(criteria), Z_STRLEN_PP(criteria)); + pgm = mail_criteria(search_criteria); + criteria_is_string=1; + break; + + case IS_RESOURCE: + ZEND_FETCH_RESOURCE(php_searchpgm, pisearchpgms *, criteria, -1, "imapsearchpgm", le_imap_searchpgm); + pgm = php_searchpgm->searchpgm; + criteria_is_string=0; + break; + + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second argumented is expected to be either a string or a searchprogram resource, %s given", zend_zval_type_name(*criteria)); + RETURN_FALSE; + } + if (argc == 2) { flags = SE_FREE; @@ -3714,17 +3738,18 @@ } } - pgm = mail_criteria(search_criteria); IMAPG(imap_messages) = IMAPG(imap_messages_tail) = NIL; mail_search_full(imap_le_struct->imap_stream, (argc == 4 ? Z_STRVAL_PP(charset) : NIL), pgm, flags); - if (pgm && !(flags & SE_FREE)) { + if (pgm && criteria_is_string && !(flags & SE_FREE)) { mail_free_searchpgm(&pgm); } if (IMAPG(imap_messages) == NIL) { - efree(search_criteria); + if (criteria_is_string) { + efree(search_criteria); + } RETURN_FALSE; } @@ -3736,7 +3761,9 @@ cur = cur->next; } mail_free_messagelist(&IMAPG(imap_messages), &IMAPG(imap_messages_tail)); - efree(search_criteria); + if (criteria_is_string) { + efree(search_criteria); + } } /* }}} */ @@ -4425,6 +4452,148 @@ } /* }}} */ +/* {{{ proto mixed imap_search_program_new() + Get new search program */ +PHP_FUNCTION(imap_searchprogram_new) +{ + pisearchpgms *php_searchpgm; + + if (ZEND_NUM_ARGS() != 0) { + ZEND_WRONG_PARAM_COUNT(); + } + + php_searchpgm = emalloc(sizeof(pisearchpgms)); + php_searchpgm->searchpgm = mail_newsearchpgm(); + ZEND_REGISTER_RESOURCE(return_value, php_searchpgm, le_imap_searchpgm); +} +/* }}} */ + +PHP_FUNCTION(imap_searchprogram_or) +{ + zval **zpgm1, **zpgm2; + pisearchpgms *php_searchpgm_or; + pisearchpgms *php_searchpgm_1; + pisearchpgms *php_searchpgm_2; + + if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &zpgm1, &zpgm2) == FAILURE) { + ZEND_WRONG_PARAM_COUNT(); + } + + ZEND_FETCH_RESOURCE(php_searchpgm_1, pisearchpgms *, zpgm1, -1, "imapsearchpgm", le_imap_searchpgm); + ZEND_FETCH_RESOURCE(php_searchpgm_2, pisearchpgms *, zpgm2, -1, "imapsearchpgm", le_imap_searchpgm); + + php_searchpgm_or = emalloc(sizeof(pisearchpgms)); + php_searchpgm_or->searchpgm = mail_newsearchpgm(); + php_searchpgm_or->searchpgm->or = mail_newsearchor(); + php_searchpgm_or->searchpgm->or->first = php_searchpgm_1->searchpgm; + php_searchpgm_or->searchpgm->or->second = php_searchpgm_2->searchpgm; + ZEND_REGISTER_RESOURCE(return_value, php_searchpgm_or, le_imap_searchpgm); +} + +PHP_FUNCTION(imap_searchprogram_setcriterion) +{ + zval **zpgm, **criterion_name, **criterion_value; + pisearchpgms *php_searchpgm; + char *search_criterion_name; + char *search_criterion_value; + int argc = ZEND_NUM_ARGS(); + int f=0; + + if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &zpgm, &criterion_name, &criterion_value) == FAILURE) { + ZEND_WRONG_PARAM_COUNT(); + } + + ZEND_FETCH_RESOURCE(php_searchpgm, pisearchpgms *, zpgm, -1, "imapsearchpgm", le_imap_searchpgm); + + convert_to_string_ex(criterion_name); + search_criterion_name = estrndup(Z_STRVAL_PP(criterion_name), Z_STRLEN_PP(criterion_name)); + if (argc == 3) { + convert_to_string_ex(criterion_value); + search_criterion_value = estrndup(Z_STRVAL_PP(criterion_value), Z_STRLEN_PP(criterion_value)); + } + + // this comes from mail.c and imapd.c + switch (*ucase (search_criterion_name)) { + case 'A': /* possible ALL, ANSWERED */ + if (!strcmp (search_criterion_name+1,"LL")) f = 1; + else if (!strcmp (search_criterion_name+1,"NSWERED")) f = php_searchpgm->searchpgm->answered = 1; + break; + case 'B': /* possible BCC, BEFORE, BODY */ + if (!strcmp (search_criterion_name+1,"CC")) + f = mail_criteria_string (&php_searchpgm->searchpgm->bcc,&search_criterion_value); + else if (!strcmp (search_criterion_name+1,"EFORE")) + f = mail_criteria_date (&php_searchpgm->searchpgm->before,&search_criterion_value); + else if (!strcmp (search_criterion_name+1,"ODY")) + f = mail_criteria_string (&php_searchpgm->searchpgm->body,&search_criterion_value); + break; + case 'C': /* possible CC */ + if (!strcmp (search_criterion_name+1,"C")) f = mail_criteria_string (&php_searchpgm->searchpgm->cc,&search_criterion_value); + break; + case 'D': /* possible DELETED, DRAFT */ + if (!strcmp (search_criterion_name+1,"ELETED")) f = php_searchpgm->searchpgm->deleted = 1; + else if (!strcmp (search_criterion_name+1,"RAFT")) f = php_searchpgm->searchpgm->draft = 1; + break; + case 'F': /* possible FLAGGED, FROM */ + if (!strcmp (search_criterion_name+1,"LAGGED")) f = php_searchpgm->searchpgm->flagged = 1; + else if (!strcmp (search_criterion_name+1,"ROM")) + f = mail_criteria_string (&php_searchpgm->searchpgm->from,&search_criterion_value); + break; + case 'K': /* possible KEYWORD */ + if (!strcmp (search_criterion_name+1,"EYWORD")) + f = mail_criteria_string (&php_searchpgm->searchpgm->keyword,&search_criterion_value); + break; + case 'N': /* possible NEW */ + if (!strcmp (search_criterion_name+1,"EW")) f = php_searchpgm->searchpgm->recent = php_searchpgm->searchpgm->unseen = 1; + break; + case 'O': /* possible OLD, ON */ + if (!strcmp (search_criterion_name+1,"LD")) f = php_searchpgm->searchpgm->old = 1; + else if (!strcmp (search_criterion_name+1,"N")) + f = mail_criteria_date (&php_searchpgm->searchpgm->on,&search_criterion_value); + break; + case 'R': /* possible RECENT */ + if (!strcmp (search_criterion_name+1,"ECENT")) f = php_searchpgm->searchpgm->recent = 1; + break; + case 'S': /* possible SEEN, SENTBEFORE, SENTON, SENTSINCE, SINCE, SUBJECT */ + if (!strcmp (search_criterion_name+1,"EEN")) f = php_searchpgm->searchpgm->seen = 1; + else if (!strcmp (search_criterion_name+1,"ENTBEFORE")) + f = mail_criteria_date (&php_searchpgm->searchpgm->sentbefore,&search_criterion_value); + else if (!strcmp (search_criterion_name+1,"ENTON")) + f = mail_criteria_date (&php_searchpgm->searchpgm->senton,&search_criterion_value); + else if (!strcmp (search_criterion_name+1,"ENTSINCE")) + f = mail_criteria_date (&php_searchpgm->searchpgm->sentsince,&search_criterion_value); + else if (!strcmp (search_criterion_name+1,"INCE")) + f = mail_criteria_date (&php_searchpgm->searchpgm->since,&search_criterion_value); + else if (!strcmp (search_criterion_name+1,"UBJECT")) + f = mail_criteria_string (&php_searchpgm->searchpgm->subject,&search_criterion_value); + break; + case 'T': /* possible TEXT, TO */ + if (!strcmp (search_criterion_name+1,"EXT")) + f = mail_criteria_string (&php_searchpgm->searchpgm->text,&search_criterion_value); + else if (!strcmp (search_criterion_name+1,"O")) + f = mail_criteria_string (&php_searchpgm->searchpgm->to,&search_criterion_value); + break; + case 'U': /* possible UN* */ + if (search_criterion_name[1] == 'N') { + if (!strcmp (search_criterion_name+2,"ANSWERED")) f = php_searchpgm->searchpgm->unanswered = 1; + else if (!strcmp (search_criterion_name+2,"DELETED")) f = php_searchpgm->searchpgm->undeleted = 1; + else if (!strcmp (search_criterion_name+2,"DRAFT")) f = php_searchpgm->searchpgm->undraft = 1; + else if (!strcmp (search_criterion_name+2,"FLAGGED")) f = php_searchpgm->searchpgm->unflagged = 1; + else if (!strcmp (search_criterion_name+2,"KEYWORD")) + f = mail_criteria_string (&php_searchpgm->searchpgm->unkeyword,&search_criterion_value); + else if (!strcmp (search_criterion_name+2,"SEEN")) f = php_searchpgm->searchpgm->unseen = 1; + } + break; + default: /* we will barf below */ + break; + } + + if (! f) { + RETURN_FALSE; + } + RETURN_TRUE; +} + + #define GETS_FETCH_SIZE 8196LU /* {{{ php_mail_gets */ static char *php_mail_gets(readfn_t f, void *stream, unsigned long size, GETS_DATA *md) diff -u --recursive ../orig/php-5.2.12/ext/imap/php_imap.h ./ext/imap/php_imap.h --- ../orig/php-5.2.12/ext/imap/php_imap.h 2008-12-31 06:17:49.000000000 -0500 +++ ./ext/imap/php_imap.h 2010-02-03 13:56:51.000000000 -0500 @@ -94,6 +94,10 @@ unsigned long msgid; struct _php_imap_message_struct *next; } MESSAGELIST; + +typedef struct _php_imap_searchpgm_struct { + SEARCHPGM *searchpgm; +} pisearchpgms; /* Functions */ @@ -169,6 +173,9 @@ PHP_FUNCTION(imap_timeout); #if defined(HAVE_IMAP2000) || defined(HAVE_IMAP2001) +PHP_FUNCTION(imap_searchprogram_new); +PHP_FUNCTION(imap_searchprogram_or); +PHP_FUNCTION(imap_searchprogram_setcriterion); PHP_FUNCTION(imap_get_quota); PHP_FUNCTION(imap_get_quotaroot); PHP_FUNCTION(imap_set_quota);
On 2010-02-03, at 3:19 PM, Dominik Gehl wrote: > Hi, > > I just checked the mailinglist archive > (http://news.php.net/php.internals/46939) and you're right, the attachment > was missing, even though it's in my sent items ... is there some list policy > which rejects attachments ? > > Dominik > > On 2010-02-03, at 3:08 PM, Pierre Joye wrote: > >> hi, >> >> Can you send patches as attachment please? >> >> Also I like to think again about a nicer approach. As your proposal >> works, it sounds like multiple calls could be avoided. >> >> Cheers, >> >> On Wed, Feb 3, 2010 at 8:37 PM, Dominik Gehl <domi...@dokdok.com> wrote: >>> Attached is a patch which would allow the usage of most of the IMAP4 search >>> criteria. >>> >>> Please let me know if I should contact someone else (IMAP extension >>> maintainer(s) ?) regarding this ... >>> >>> Dominik >>> >>> >>> On 2010-02-02, at 4:14 PM, Dominik Gehl wrote: >>> >>>> I continued thinking about this and came up with the idea of adding a new >>>> resource 'imap_searchpgm' to the imap extension, which would then have >>>> quite a good number of new functions: imap_searchprogram_new, >>>> imap_searchprogram_sentsince, imap_searchprogram_since, >>>> imap_searchprogram_before, imap_searchprogram_on etc. etc. >>>> >>>> The functions could then be defined along the following lines (untested >>>> code ...): >>>> >>>> PHP_FUNCTION(imap_searchprogram_new) >>>> { >>>> int myargc = ZEND_NUM_ARGS(); >>>> >>>> if (myargc != 0) { >>>> ZEND_WRONG_PARAM_COUNT(); >>>> } >>>> >>>> pgm = mail_newsearchpgm(); >>>> searchpgm = emalloc(sizeof(php_imap_searchpgm)); >>>> searchpgm->searchpgm = pgm; >>>> ZEND_REGISTER_RESOURCE(return_value, searchpgm, le_imap_searchpgm); >>>> } >>>> >>>> PHP_FUNCTION(imap_searchprogram_sentsince) >>>> { >>>> zval *zpgm; >>>> php_imap_searchpgm *pgm; >>>> char *criterion = ""; >>>> >>>> if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &zpgm, >>>> &criterion) == FAILURE) { >>>> RETURN_FALSE; >>>> } >>>> >>>> ZEND_FETCH_RESOURCE(pgm, php_imap_search_pgm*, &zpgm, -1, >>>> "imapsearch", le_imap_searchpgm); >>>> >>>> mail_criteria_date(&pgm->searchpgm->sentsince, &criterion); >>>> >>>> RETURN_TRUE; >>>> } >>>> >>>> etc. etc. >>>> >>>> >>>> And finally, the imap_search function could then accept either the >>>> criteria string OR an imap_searchpgm resource. >>>> >>>> Ideas, comments ? >>>> >>>> Thanks, >>>> Dominik >>>> >>>> >>>> On 2010-02-01, at 10:06 AM, Dominik Gehl wrote: >>>> >>>>> Thanks a lot for your reply. I also found a second bug report related to >>>>> this: http://bugs.php.net/bug.php?id=21168 >>>>> >>>>> Now, how about adding an imap_newsearchpgm function to the PHP imap >>>>> extension which would do a call to mail_nsewsearchpgm inside c-client and >>>>> return a structure allowing to contruct IMAP4 search programs (SEARCHPGM >>>>> inside c-client) ? >>>>> >>>>> Anyone interested in this ? >>>>> >>>>> Dominik >>>>> >>>>> On 2010-01-30, at 6:22 PM, Joey Smith wrote: >>>>> >>>>>> There's an open bug on this, #15238 >>>>>> (http://bugs.php.net/bug.php?id=15238&). I'm >>>>>> sure patches would be welcomed. >>>>>> >>>>>> On Fri, Jan 29, 2010 at 03:49:18PM -0500, Dominik Gehl wrote: >>>>>>> Hi, >>>>>>> >>>>>>> I noticed that the imap extension seems to support only IMAP2 search >>>>>>> criteria. >>>>>>> >>>>>>> This is caused by the fact that in ext/imap/php_imap.c, the imap_search >>>>>>> function uses a call to mail_criteria. And >>>>>>> the University of Washington IMAP toolkit mentions in docs/internal.txt: >>>>>>> >>>>>>> SEARCHPGM *mail_criteria (char *criteria); >>>>>>> criteria IMAP2-format search criteria string >>>>>>> >>>>>>> This function accepts an IMAP2-format search criteria string and >>>>>>> parses it. If the parse is successful, it returns a search program >>>>>>> suitable for use in mail_search_full(). >>>>>>> WARNING: This function does not accept IMAP4 search criteria. >>>>>>> >>>>>>> >>>>>>> Is there any specific reason why PHP uses this mail_criteria call ? It >>>>>>> really would be nice to be able to use IMAP4 search criteria ! >>>>>>> >>>>>>> Thanks, >>>>>>> Dominik >>>>>>> >>>>>>> -- >>>>>>> PHP Internals - PHP Runtime Development Mailing List >>>>>>> To unsubscribe, visit: http://www.php.net/unsub.php >>>>>>> >>>>> >>>> >>> >>> >>> >>> -- >>> PHP Internals - PHP Runtime Development Mailing List >>> To unsubscribe, visit: http://www.php.net/unsub.php >>> >> >> >> >> -- >> Pierre >> >> @pierrejoye | http://blog.thepimp.net | http://www.libgd.org > -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php