Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:46945 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 52007 invoked from network); 4 Feb 2010 21:24:05 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 4 Feb 2010 21:24:05 -0000 Authentication-Results: pb1.pair.com smtp.mail=dominik@dokdok.com; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=dominik@dokdok.com; sender-id=unknown Received-SPF: error (pb1.pair.com: domain dokdok.com from 209.85.221.192 cause and error) X-PHP-List-Original-Sender: dominik@dokdok.com X-Host-Fingerprint: 209.85.221.192 mail-qy0-f192.google.com Received: from [209.85.221.192] ([209.85.221.192:34411] helo=mail-qy0-f192.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 6E/8E-22982-3FA3B6B4 for ; Thu, 04 Feb 2010 16:24:04 -0500 Received: by qyk30 with SMTP id 30so1401954qyk.32 for ; Thu, 04 Feb 2010 13:24:01 -0800 (PST) Received: by 10.224.66.41 with SMTP id l41mr478396qai.307.1265318639609; Thu, 04 Feb 2010 13:23:59 -0800 (PST) Received: from ?192.168.1.101? (modemcable144.86-58-74.mc.videotron.ca [74.58.86.144]) by mx.google.com with ESMTPS id 7sm2048356qwf.14.2010.02.04.13.23.56 (version=TLSv1/SSLv3 cipher=RC4-MD5); Thu, 04 Feb 2010 13:23:57 -0800 (PST) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Apple Message framework v1077) In-Reply-To: Date: Thu, 4 Feb 2010 16:23:55 -0500 Content-Transfer-Encoding: quoted-printable Message-ID: References: <20100130232224.GA18033@joeysmith.com> <75DD619F-181F-4299-B812-ADC963C78CE8@dokdok.com> <9862FA74-6B36-4C0E-AA15-6A5E17273C24@dokdok.com> To: internals@lists.php.net X-Mailer: Apple Mail (2.1077) Subject: Re: [PHP-DEV] imap4 search criteria From: dominik@dokdok.com (Dominik Gehl) Here's a new version of the patch. It allows the usage of the following = style of code: $pgm =3D imap_searchprogram_new(); imap_searchprogram_criteria($pgm1,"DRAFT SMALLER 34567 HEADER Message-Id = FROM = dominik@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[] =3D { PHP_FE(imap_timeout, = NULL) =20 #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) =20 /* True globals, no need for thread safety */ static int le_imap; +static int le_imap_searchpgm; =20 #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) } /* }}} */ =20 +static void mailsearchpgm_close_it(zend_rsrc_list_entry *rsrc = TSRMLS_DC) +{ + pisearchpgms *php_searchpgm =3D (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) */ =20 le_imap =3D zend_register_list_destructors_ex(mail_close_it, = NULL, "imap", module_number); + le_imap_searchpgm =3D = 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 =3D ZEND_NUM_ARGS(); + int criteria_is_string; SEARCHPGM *pgm =3D NIL; + pisearchpgms *php_searchpgm; =20 if (argc < 2 || argc > 4 || zend_get_parameters_ex(argc, = &streamind, &criteria, &search_flags, &charset) =3D=3D FAILURE) { ZEND_WRONG_PARAM_COUNT(); @@ -3701,8 +3716,25 @@ PHP_FUNCTION(imap_search) =20 ZEND_FETCH_RESOURCE(imap_le_struct, pils *, streamind, -1, = "imap", le_imap); =20 - convert_to_string_ex(criteria); - search_criteria =3D estrndup(Z_STRVAL_PP(criteria), = Z_STRLEN_PP(criteria)); + switch (Z_TYPE_PP(criteria)) { + case IS_STRING: + convert_to_string_ex(criteria); + search_criteria =3D = estrndup(Z_STRVAL_PP(criteria), Z_STRLEN_PP(criteria)); + pgm =3D mail_criteria(search_criteria); + criteria_is_string=3D1; + break; + + case IS_RESOURCE: + ZEND_FETCH_RESOURCE(php_searchpgm, pisearchpgms = *, criteria, -1, "imapsearchpgm", le_imap_searchpgm); + pgm =3D php_searchpgm->searchpgm; + criteria_is_string=3D0; + 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; + } + =09 =20 if (argc =3D=3D 2) { flags =3D SE_FREE; @@ -3714,17 +3746,18 @@ PHP_FUNCTION(imap_search) } } =20 - pgm =3D mail_criteria(search_criteria); IMAPG(imap_messages) =3D IMAPG(imap_messages_tail) =3D NIL; =20 mail_search_full(imap_le_struct->imap_stream, (argc =3D=3D 4 ? = Z_STRVAL_PP(charset) : NIL), pgm, flags); =20 - if (pgm && !(flags & SE_FREE)) { + if (pgm && criteria_is_string && !(flags & SE_FREE)) { mail_free_searchpgm(&pgm); } =20 if (IMAPG(imap_messages) =3D=3D NIL) { - efree(search_criteria); + if (criteria_is_string) { + efree(search_criteria); + } RETURN_FALSE; } =20 @@ -3736,7 +3769,9 @@ PHP_FUNCTION(imap_search) cur =3D cur->next; } mail_free_messagelist(&IMAPG(imap_messages), = &IMAPG(imap_messages_tail)); - efree(search_criteria); + if (criteria_is_string) { + efree(search_criteria); + } } /* }}} */ =20 @@ -4425,6 +4460,178 @@ PHP_FUNCTION(imap_timeout) } /* }}} */ =20 +/* {{{ proto mixed imap_search_program_new() + Get new search program */ +PHP_FUNCTION(imap_searchprogram_new) +{ + pisearchpgms *php_searchpgm; + + if (ZEND_NUM_ARGS() !=3D 0) { + ZEND_WRONG_PARAM_COUNT(); + } + + php_searchpgm =3D emalloc(sizeof(pisearchpgms)); + php_searchpgm->searchpgm =3D 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() !=3D 2 || zend_get_parameters_ex(2, &zpgm1, = &zpgm2) =3D=3D 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 =3D emalloc(sizeof(pisearchpgms)); + php_searchpgm_or->searchpgm =3D mail_newsearchpgm(); + php_searchpgm_or->searchpgm->or =3D mail_newsearchor(); + php_searchpgm_or->searchpgm->or->first =3D = php_searchpgm_1->searchpgm; + php_searchpgm_or->searchpgm->or->second =3D = 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() !=3D 2 || zend_get_parameters_ex(2, &zpgm, = &zcriteria) =3D=3D FAILURE) { + ZEND_WRONG_PARAM_COUNT(); + } + + ZEND_FETCH_RESOURCE(php_searchpgm, pisearchpgms *, zpgm, -1, = "imapsearchpgm", le_imap_searchpgm); + + convert_to_string_ex(zcriteria); + criteria =3D estrndup(Z_STRVAL_PP(zcriteria), = Z_STRLEN_PP(zcriteria)); + + // this comes from mail.c and imapd.c + /* for each criterion */ + for (search_criterion_name =3D strtok_r (criteria," ",&r); = search_criterion_name; (search_criterion_name =3D strtok_r (NIL," = ",&r))) { + f =3D NIL; /* init then scan the = criterion */ + + switch (*ucase (search_criterion_name)) { + case 'A': /* possible ALL, = ANSWERED */ + if (!strcmp = (search_criterion_name+1,"LL")) f =3D T; + else if (!strcmp = (search_criterion_name+1,"NSWERED")) f =3D = php_searchpgm->searchpgm->answered =3D T; + break; + case 'B': /* possible BCC, = BEFORE, BODY */ + if (!strcmp = (search_criterion_name+1,"CC")) + f =3D mail_criteria_string = (&php_searchpgm->searchpgm->bcc,&r); + else if (!strcmp = (search_criterion_name+1,"EFORE")) + f =3D mail_criteria_date = (&php_searchpgm->searchpgm->before,&r); + else if (!strcmp = (search_criterion_name+1,"ODY")) + f =3D mail_criteria_string = (&php_searchpgm->searchpgm->body,&r); + break; + case 'C': /* possible CC = */ + if (!strcmp = (search_criterion_name+1,"C")) f =3D mail_criteria_string = (&php_searchpgm->searchpgm->cc,&r); + break; + case 'D': /* possible = DELETED, DRAFT */ + if (!strcmp = (search_criterion_name+1,"ELETED")) f =3D = php_searchpgm->searchpgm->deleted =3D T; + else if (!strcmp = (search_criterion_name+1,"RAFT")) f =3D php_searchpgm->searchpgm->draft = =3D T; + break; + case 'F': /* possible = FLAGGED, FROM */ + if (!strcmp = (search_criterion_name+1,"LAGGED")) f =3D = php_searchpgm->searchpgm->flagged =3D T; + else if (!strcmp = (search_criterion_name+1,"ROM")) + f =3D mail_criteria_string = (&php_searchpgm->searchpgm->from,&r); + break; + case 'H': /* possible = HEADER */ + if (!strcmp = (search_criterion_name+1,"EADER")) { + header_name =3D strtok_r (NIL," = ",&r); + header_value =3D strtok_r (NIL," = ",&r); + for (hdr =3D = &php_searchpgm->searchpgm->header; *hdr; hdr =3D &(*hdr)->next); + *hdr =3D mail_newsearchheader = (header_name,header_value); + f =3D T; /* = success */ + } + break; + case 'K': /* possible = KEYWORD */ + if (!strcmp = (search_criterion_name+1,"EYWORD")) + f =3D mail_criteria_string = (&php_searchpgm->searchpgm->keyword,&r); + break; + case 'L': /* possible = LARGER */ + if (!strcmp = (search_criterion_name+1,"ARGER")) + f =3D mail_criteria_number = (&php_searchpgm->searchpgm->larger,&r); + break; + case 'N': /* possible NEW = */ + if (!strcmp = (search_criterion_name+1,"EW")) f =3D php_searchpgm->searchpgm->recent =3D= php_searchpgm->searchpgm->unseen =3D T; + break; + case 'O': /* possible OLD, = ON */ + if (!strcmp = (search_criterion_name+1,"LD")) f =3D php_searchpgm->searchpgm->old =3D = T; + else if (!strcmp = (search_criterion_name+1,"N")) + f =3D mail_criteria_date = (&php_searchpgm->searchpgm->on,&r); + break; + case 'R': /* possible = RECENT */ + if (!strcmp = (search_criterion_name+1,"ECENT")) f =3D = php_searchpgm->searchpgm->recent =3D T; + break; + case 'S': /* possible = SEEN, SENTBEFORE, SENTON, SENTSINCE, SINCE, SUBJECT */ + if (!strcmp = (search_criterion_name+1,"EEN")) f =3D php_searchpgm->searchpgm->seen =3D = T; + else if (!strcmp = (search_criterion_name+1,"ENTBEFORE")) + f =3D mail_criteria_date = (&php_searchpgm->searchpgm->sentbefore,&r); + else if (!strcmp = (search_criterion_name+1,"ENTON")) + f =3D mail_criteria_date = (&php_searchpgm->searchpgm->senton,&r); + else if (!strcmp = (search_criterion_name+1,"ENTSINCE")) + f =3D mail_criteria_date = (&php_searchpgm->searchpgm->sentsince,&r); + else if (!strcmp = (search_criterion_name+1,"INCE")) + f =3D mail_criteria_date = (&php_searchpgm->searchpgm->since,&r); + else if (!strcmp = (search_criterion_name+1,"MALLER")) + f =3D mail_criteria_number = (&php_searchpgm->searchpgm->smaller,&r); + else if (!strcmp = (search_criterion_name+1,"UBJECT")) + f =3D mail_criteria_string = (&php_searchpgm->searchpgm->subject,&r); + break; + case 'T': /* possible = TEXT, TO */ + if (!strcmp = (search_criterion_name+1,"EXT")) + f =3D mail_criteria_string = (&php_searchpgm->searchpgm->text,&r); + else if (!strcmp = (search_criterion_name+1,"O")) + f =3D mail_criteria_string = (&php_searchpgm->searchpgm->to,&r); + break; + case 'U': /* possible UN* = */ + if (search_criterion_name[1] =3D=3D 'N') = { + if (!strcmp = (search_criterion_name+2,"ANSWERED")) f =3D = php_searchpgm->searchpgm->unanswered =3D T; + else if (!strcmp = (search_criterion_name+2,"DELETED")) f =3D = php_searchpgm->searchpgm->undeleted =3D T; + else if (!strcmp = (search_criterion_name+2,"DRAFT")) f =3D = php_searchpgm->searchpgm->undraft =3D T; + else if (!strcmp = (search_criterion_name+2,"FLAGGED")) f =3D = php_searchpgm->searchpgm->unflagged =3D T; + else if (!strcmp = (search_criterion_name+2,"KEYWORD")) + f =3D = mail_criteria_string (&php_searchpgm->searchpgm->unkeyword,&r); + else if (!strcmp = (search_criterion_name+2,"SEEN")) f =3D php_searchpgm->searchpgm->unseen = =3D 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 =3D 0; + while (isdigit (**arg)) { /* found a digit? */ + *number *=3D 10; /* add a decade */ + *number +=3D *(*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; =20 =20 /* Functions */ @@ -169,6 +173,9 @@ PHP_FUNCTION(imap_thread); PHP_FUNCTION(imap_timeout); =20 #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);