Here's a new version of the patch. It allows the usage of the following style of code:
$pgm = imap_searchprogram_new(); imap_searchprogram_criteria($pgm1,"DRAFT SMALLER 34567 HEADER Message-Id <d76c58cd-c94d-4de4-b621-83d66437e...@dokdok.com> FROM domi...@dokdok.com"); imap_search($mbox,$pgm)); Dominik diff --git a/external/php-5.2.12/ext/imap/php_imap.c b/external/php-5.2.12/ext/imap/php_imap.c index 16714ae..771c788 100644 --- a/external/php-5.2.12/ext/imap/php_imap.c +++ b/external/php-5.2.12/ext/imap/php_imap.c @@ -152,6 +152,9 @@ zend_function_entry imap_functions[] = { 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_criteria, NULL) PHP_FE(imap_get_quota, NULL) PHP_FE(imap_get_quotaroot, NULL) PHP_FE(imap_set_quota, NULL) @@ -209,6 +212,7 @@ ZEND_GET_MODULE(imap) /* 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)) { \ @@ -240,6 +244,14 @@ static void mail_close_it(zend_rsrc_list_entry *rsrc TSRMLS_DC) } /* }}} */ +static void mailsearchpgm_close_it(zend_rsrc_list_entry *rsrc TSRMLS_DC) +{ + pisearchpgms *php_searchpgm = (pisearchpgms *)rsrc->ptr; + + //mail_free_searchpgm(&php_searchpgm->searchpgm); + efree(php_searchpgm); +} + /* {{{ add_assoc_object */ static int add_assoc_object(zval *arg, char *key, zval *tmp TSRMLS_DC) @@ -673,6 +685,7 @@ PHP_MINIT_FUNCTION(imap) */ le_imap = zend_register_list_destructors_ex(mail_close_it, NULL, "imap", module_number); + le_imap_searchpgm = zend_register_list_destructors_ex(mailsearchpgm_close_it, NULL, "imapsearchpgm", module_number); return SUCCESS; } /* }}} */ @@ -3693,7 +3706,9 @@ PHP_FUNCTION(imap_search) 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 +3716,25 @@ PHP_FUNCTION(imap_search) 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 +3746,18 @@ PHP_FUNCTION(imap_search) } } - 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 +3769,9 @@ PHP_FUNCTION(imap_search) 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 +4460,178 @@ PHP_FUNCTION(imap_timeout) } /* }}} */ +/* {{{ 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_criteria) +{ + zval **zpgm, **zcriteria; + pisearchpgms *php_searchpgm; + char *criteria; + SEARCHHEADER **hdr; + char *header_name, *header_value; + char *search_criterion_name,*r; + int f; + + if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &zpgm, &zcriteria) == FAILURE) { + ZEND_WRONG_PARAM_COUNT(); + } + + ZEND_FETCH_RESOURCE(php_searchpgm, pisearchpgms *, zpgm, -1, "imapsearchpgm", le_imap_searchpgm); + + convert_to_string_ex(zcriteria); + criteria = estrndup(Z_STRVAL_PP(zcriteria), Z_STRLEN_PP(zcriteria)); + + // this comes from mail.c and imapd.c + /* for each criterion */ + for (search_criterion_name = strtok_r (criteria," ",&r); search_criterion_name; (search_criterion_name = strtok_r (NIL," ",&r))) { + f = NIL; /* init then scan the criterion */ + + switch (*ucase (search_criterion_name)) { + case 'A': /* possible ALL, ANSWERED */ + if (!strcmp (search_criterion_name+1,"LL")) f = T; + else if (!strcmp (search_criterion_name+1,"NSWERED")) f = php_searchpgm->searchpgm->answered = T; + break; + case 'B': /* possible BCC, BEFORE, BODY */ + if (!strcmp (search_criterion_name+1,"CC")) + f = mail_criteria_string (&php_searchpgm->searchpgm->bcc,&r); + else if (!strcmp (search_criterion_name+1,"EFORE")) + f = mail_criteria_date (&php_searchpgm->searchpgm->before,&r); + else if (!strcmp (search_criterion_name+1,"ODY")) + f = mail_criteria_string (&php_searchpgm->searchpgm->body,&r); + break; + case 'C': /* possible CC */ + if (!strcmp (search_criterion_name+1,"C")) f = mail_criteria_string (&php_searchpgm->searchpgm->cc,&r); + break; + case 'D': /* possible DELETED, DRAFT */ + if (!strcmp (search_criterion_name+1,"ELETED")) f = php_searchpgm->searchpgm->deleted = T; + else if (!strcmp (search_criterion_name+1,"RAFT")) f = php_searchpgm->searchpgm->draft = T; + break; + case 'F': /* possible FLAGGED, FROM */ + if (!strcmp (search_criterion_name+1,"LAGGED")) f = php_searchpgm->searchpgm->flagged = T; + else if (!strcmp (search_criterion_name+1,"ROM")) + f = mail_criteria_string (&php_searchpgm->searchpgm->from,&r); + break; + case 'H': /* possible HEADER */ + if (!strcmp (search_criterion_name+1,"EADER")) { + header_name = strtok_r (NIL," ",&r); + header_value = strtok_r (NIL," ",&r); + for (hdr = &php_searchpgm->searchpgm->header; *hdr; hdr = &(*hdr)->next); + *hdr = mail_newsearchheader (header_name,header_value); + f = T; /* success */ + } + break; + case 'K': /* possible KEYWORD */ + if (!strcmp (search_criterion_name+1,"EYWORD")) + f = mail_criteria_string (&php_searchpgm->searchpgm->keyword,&r); + break; + case 'L': /* possible LARGER */ + if (!strcmp (search_criterion_name+1,"ARGER")) + f = mail_criteria_number (&php_searchpgm->searchpgm->larger,&r); + break; + case 'N': /* possible NEW */ + if (!strcmp (search_criterion_name+1,"EW")) f = php_searchpgm->searchpgm->recent = php_searchpgm->searchpgm->unseen = T; + break; + case 'O': /* possible OLD, ON */ + if (!strcmp (search_criterion_name+1,"LD")) f = php_searchpgm->searchpgm->old = T; + else if (!strcmp (search_criterion_name+1,"N")) + f = mail_criteria_date (&php_searchpgm->searchpgm->on,&r); + break; + case 'R': /* possible RECENT */ + if (!strcmp (search_criterion_name+1,"ECENT")) f = php_searchpgm->searchpgm->recent = T; + break; + case 'S': /* possible SEEN, SENTBEFORE, SENTON, SENTSINCE, SINCE, SUBJECT */ + if (!strcmp (search_criterion_name+1,"EEN")) f = php_searchpgm->searchpgm->seen = T; + else if (!strcmp (search_criterion_name+1,"ENTBEFORE")) + f = mail_criteria_date (&php_searchpgm->searchpgm->sentbefore,&r); + else if (!strcmp (search_criterion_name+1,"ENTON")) + f = mail_criteria_date (&php_searchpgm->searchpgm->senton,&r); + else if (!strcmp (search_criterion_name+1,"ENTSINCE")) + f = mail_criteria_date (&php_searchpgm->searchpgm->sentsince,&r); + else if (!strcmp (search_criterion_name+1,"INCE")) + f = mail_criteria_date (&php_searchpgm->searchpgm->since,&r); + else if (!strcmp (search_criterion_name+1,"MALLER")) + f = mail_criteria_number (&php_searchpgm->searchpgm->smaller,&r); + else if (!strcmp (search_criterion_name+1,"UBJECT")) + f = mail_criteria_string (&php_searchpgm->searchpgm->subject,&r); + break; + case 'T': /* possible TEXT, TO */ + if (!strcmp (search_criterion_name+1,"EXT")) + f = mail_criteria_string (&php_searchpgm->searchpgm->text,&r); + else if (!strcmp (search_criterion_name+1,"O")) + f = mail_criteria_string (&php_searchpgm->searchpgm->to,&r); + break; + case 'U': /* possible UN* */ + if (search_criterion_name[1] == 'N') { + if (!strcmp (search_criterion_name+2,"ANSWERED")) f = php_searchpgm->searchpgm->unanswered = T; + else if (!strcmp (search_criterion_name+2,"DELETED")) f = php_searchpgm->searchpgm->undeleted = T; + else if (!strcmp (search_criterion_name+2,"DRAFT")) f = php_searchpgm->searchpgm->undraft = T; + else if (!strcmp (search_criterion_name+2,"FLAGGED")) f = php_searchpgm->searchpgm->unflagged = T; + else if (!strcmp (search_criterion_name+2,"KEYWORD")) + f = mail_criteria_string (&php_searchpgm->searchpgm->unkeyword,&r); + else if (!strcmp (search_criterion_name+2,"SEEN")) f = php_searchpgm->searchpgm->unseen = T; + } + break; + default: /* we will barf below */ + break; + } + if (! f) { + RETURN_FALSE; + } + } + + efree(criteria); + + RETURN_TRUE; +} + +int mail_criteria_number (unsigned long *number,unsigned char **arg) +{ + /* can't double this value */ + if (*number || !isdigit (**arg)) return NIL; + *number = 0; + while (isdigit (**arg)) { /* found a digit? */ + *number *= 10; /* add a decade */ + *number += *(*arg)++ - '0'; /* add number */ + } + return T; +} + #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 --git a/external/php-5.2.12/ext/imap/php_imap.h b/external/php-5.2.12/ext/imap/php_imap.h index 8dd60f5..390999f 100644 --- a/external/php-5.2.12/ext/imap/php_imap.h +++ b/external/php-5.2.12/ext/imap/php_imap.h @@ -94,6 +94,10 @@ typedef struct _php_imap_message_struct { 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_thread); 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_criteria); PHP_FUNCTION(imap_get_quota); PHP_FUNCTION(imap_get_quotaroot); PHP_FUNCTION(imap_set_quota); -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php