Re: updated IMAP patch

From: Date: Thu, 01 Jul 1999 20:55:51 +0000
Subject: Re: updated IMAP patch
References: 1  Groups: php.dev 
Request: Send a blank email to php-dev+get-7955@lists.php.net to get a copy of this message
Quoting Chuck Hagenbuch <chagenbu@wso.williams.edu>: > Ok, I went ahead and did the errors as a list, because it turned out to be > fairly easy. Attached is the latest version of my patches to imap.c and > imap.h. They include: Sigh. I'm a complete ninny. Here they are. -chuck -- Charles Hagenbuch, <chagenbu@wso.williams.edu>

--- php3.orig/functions/imap.c Tue Mar 30 06:25:04 1999 +++ php3/functions/imap.c Thu Jul 1 16:39:23 1999 @@ -82,10 +82,9 @@ #define PHP_EXPUNGE 32768 -/* - * this array should be set up as: - * {"PHPScriptFunctionName",dllFunctionName,1} - */ +/* constants for whether or not to use php3_imap_list_full */ +#define USE_FOLDER_OBJECT_LIST 1 +#define USE_FOLDER_ARRAY_LIST 0 /* type casts left out, put here to remove warnings in msvc @@ -104,8 +103,26 @@ long flags; } pils; +typedef struct php3_imap_mailbox_struct { + SIZEDTEXT text; + DTYPE delimiter; + long attributes; + struct php3_imap_mailbox_struct *next; +} FOBJECTLIST; + +typedef struct php3_imap_error_struct { + SIZEDTEXT text; + long errflg; + struct php3_imap_error_struct *next; +} ERRORLIST; + MAILSTREAM *mail_close_it (pils *imap_le_struct); +/* + * this array should be set up as: + * {"PHPScriptFunctionName",dllFunctionName,1} + */ + function_entry imap_functions[] = { {"imap_open", php3_imap_open, NULL}, {"imap_reopen", php3_imap_reopen, NULL}, @@ -128,8 +145,10 @@ {"imap_renamemailbox", php3_imap_renamemailbox, NULL}, {"imap_deletemailbox", php3_imap_deletemailbox, NULL}, {"imap_listmailbox", php3_imap_list, NULL}, + {"imap_getmailboxes", php3_imap_list_full, NULL}, {"imap_scanmailbox", php3_imap_listscan, NULL}, {"imap_listsubscribed", php3_imap_lsub, NULL}, + {"imap_getsubscribed", php3_imap_lsub_full, NULL}, {"imap_subscribe", php3_imap_subscribe, NULL}, {"imap_unsubscribe", php3_imap_unsubscribe, NULL}, {"imap_append", php3_imap_append, NULL}, @@ -157,12 +176,15 @@ {"imap_bodystruct", php3_imap_bodystruct, NULL}, {"imap_fetch_overview", php3_imap_fetch_overview, NULL}, {"imap_mail_compose", php3_imap_mail_compose, NULL}, + {"imap_alerts", php3_imap_alerts, NULL}, + {"imap_errors", php3_imap_errors, NULL}, + {"imap_last_error", php3_imap_last_error, NULL}, {NULL, NULL, NULL} }; php3_module_entry php3_imap_module_entry = { - IMAPVER, imap_functions, imap_init, NULL, NULL, NULL,imap_info, 0, 0, 0, NULL + IMAPVER, imap_functions, imap_init, NULL, imap_init_request, imap_end_request, imap_info, 0, 0, 0, NULL }; @@ -180,6 +202,11 @@ char imap_password[80]=""; STRINGLIST *imap_folders=NIL; STRINGLIST *imap_sfolders=NIL; +STRINGLIST *imap_alertstack=NIL; +ERRORLIST *imap_errorstack=NIL; +FOBJECTLIST *imap_folder_objects=NIL; +FOBJECTLIST *imap_sfolder_objects=NIL; +int use_folder_object_list=USE_FOLDER_ARRAY_LIST; long status_flags; unsigned long status_messages; unsigned long status_recent; @@ -206,6 +233,86 @@ } +/* Mail instantiate FOBJECTLIST + * Returns: new FOBJECTLIST list + */ + +FOBJECTLIST *mail_newfolderobjectlist (void) { + return (FOBJECTLIST *) memset(fs_get(sizeof(FOBJECTLIST)),0, + sizeof(FOBJECTLIST)); +} + + +/* Mail garbage collect FOBJECTLIST + * Accepts: pointer to FOBJECTLIST pointer + */ + +void mail_free_foblist (FOBJECTLIST **foblist) +{ + if (*foblist) { /* only free if exists */ + if ((*foblist)->text.data) fs_give ((void **) &(*foblist)->text.data); + mail_free_foblist (&(*foblist)->next); + fs_give ((void **) foblist); /* return string to free storage */ + } +} + + +/* Mail instantiate ERRORLIST + * Returns: new ERRORLIST list + */ + +ERRORLIST *mail_newerrorlist (void) { + return (ERRORLIST *) memset(fs_get(sizeof(ERRORLIST)),0, + sizeof(ERRORLIST)); +} + +/* Mail garbage collect FOBJECTLIST + * Accepts: pointer to FOBJECTLIST pointer + */ + +void mail_free_errorlist (ERRORLIST **errlist) +{ + if (*errlist) { /* only free if exists */ + if ((*errlist)->text.data) fs_give ((void **) &(*errlist)->text.data); + mail_free_errorlist (&(*errlist)->next); + fs_give ((void **) errlist); /* return string to free storage */ + } +} + + +int imap_init_request (INIT_FUNC_ARGS) { + imap_errorstack = NIL; + imap_alertstack = NIL; + return SUCCESS; +} + +int imap_end_request () { + ERRORLIST *ecur = NIL; + STRINGLIST *acur = NIL; + + if (imap_errorstack != NIL) { + /* output any remaining errors at their original error level */ + ecur = imap_errorstack; + while (ecur != NIL) { + php3_error(ecur->errflg, ecur->LTEXT); + ecur = ecur->next; + } + mail_free_errorlist(&imap_errorstack); + } + + if (imap_alertstack != NIL) { + /* output any remaining alerts at E_NOTICE level */ + acur = imap_alertstack; + while (acur != NIL) { + php3_error(E_NOTICE, acur->LTEXT); + acur = acur->next; + } + mail_free_stringlist(&imap_alertstack); + } + + return SUCCESS; +} + void imap_info(void) { php3_printf("Imap Support enabled<br>"); @@ -342,8 +449,9 @@ /* next UID to be assigned */ REGISTER_MAIN_LONG_CONSTANT("SA_UIDVALIDITY",SA_UIDVALIDITY , CONST_PERSISTENT | CONST_CS); /* UID validity value */ - - + REGISTER_MAIN_LONG_CONSTANT("SA_ALL", SA_MESSAGES | SA_RECENT | SA_UNSEEN | SA_UIDNEXT | SA_UIDVALIDITY, CONST_PERSISTENT | CONST_CS); + /* get all status information */ + /* Bits for mm_list() and mm_lsub() */ REGISTER_MAIN_LONG_CONSTANT("LATT_NOINFERIORS",LATT_NOINFERIORS , CONST_PERSISTENT | CONST_CS); @@ -716,6 +824,7 @@ tmp[2] = cache->flagged ? 'F' : ' '; tmp[3] = cache->answered ? 'A' : ' '; tmp[4] = cache->deleted ? 'D' : ' '; + tmp[5] = cache->draft ? 'X' : ' '; sprintf (tmp+5,"%4ld) ",cache->msgno); mail_date (tmp+11,cache); tmp[17] = ' '; @@ -969,7 +1078,10 @@ int ind, ind_type; pils *imap_le_struct; STRINGLIST *cur=NIL; - + + /* set flag for normal, old mailbox list */ + use_folder_object_list = USE_FOLDER_ARRAY_LIST; + if (ARG_COUNT(ht)!=3 || getParameters(ht,3,&streamind,&ref,&pat) == FAILURE) { WRONG_PARAM_COUNT; @@ -1001,6 +1113,67 @@ } /* }}} */ + +/* {{{ proto array imap_getmailboxes(int stream_id, string ref, string pattern) + Reads the list of mailboxes and returns a full array of objects containing name, attributes, and delimiter. */ +void php3_imap_list_full(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *streamind, *ref, *pat, mboxob; + int ind, ind_type; + pils *imap_le_struct; + FOBJECTLIST *cur=NIL; + char *delim=NIL; + + + /* set flag for new, improved array of objects mailbox list */ + use_folder_object_list = USE_FOLDER_OBJECT_LIST; + + if (ARG_COUNT(ht)!=3 + || getParameters(ht,3,&streamind,&ref,&pat) == FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_long(streamind); + convert_to_string(ref); + convert_to_string(pat); + + ind = streamind->value.lval; + + imap_le_struct = (pils *)php3_list_find(ind, &ind_type); + if (!imap_le_struct || ind_type != le_imap) { + php3_error(E_WARNING, "Unable to find stream pointer"); + RETURN_FALSE; + } + + imap_folder_objects = NIL; + mail_list(imap_le_struct->imap_stream,ref->value.str.val,pat->value.str.val); + if (imap_folder_objects == NIL) { + RETURN_FALSE; + } + array_init(return_value); + delim = emalloc(2 * sizeof(char)); + cur=imap_folder_objects; + while (cur != NIL ) { + object_init(&mboxob); + add_property_string(&mboxob, "name", cur->LTEXT,1); + add_property_long(&mboxob, "attributes", cur->attributes); +#ifdef IMAP41 + delim[0] = (char)cur->delimiter; + delim[1] = 0; + add_property_string(&mboxob, "delimiter", delim, 1); +#else + add_property_string(&mboxob, "delimiter", cur->delimiter, 1); +#endif + add_next_index_object(return_value, mboxob); + cur=cur->next; + } + mail_free_foblist(&imap_folder_objects); + efree(delim); + use_folder_object_list = USE_FOLDER_ARRAY_LIST; // reset to default +} +/* }}} */ + + /* {{{ proto array imap_scanmailbox(int stream_id, string ref, string pattern, string content) An alias for imap_scan */ /* }}} */ @@ -1486,6 +1659,7 @@ add_property_string(return_value,"Flagged",cache->flagged ? "F" : " ",1); add_property_string(return_value,"Answered",cache->answered ? "A" : " ",1); add_property_string(return_value,"Deleted",cache->deleted ? "D" : " ",1); + add_property_string(return_value,"Draft",cache->draft ? "X" : " ",1); sprintf (dummy,"%4ld",cache->msgno); add_property_string(return_value,"Msgno",dummy,1); mail_date (dummy,cache); @@ -1523,6 +1697,9 @@ pils *imap_le_struct; STRINGLIST *cur=NIL; + /* set flag for normal, old mailbox list */ + use_folder_object_list = USE_FOLDER_ARRAY_LIST; + if (ARG_COUNT(ht)!=3 || getParameters(ht,3,&streamind,&ref,&pat) == FAILURE) { WRONG_PARAM_COUNT; } @@ -1553,6 +1730,66 @@ } /* }}} */ + +/* {{{ proto array imap_getsubscribed(int stream_id, string ref, string pattern) + Return a list of subscribed mailboxes */ +void php3_imap_lsub_full(INTERNAL_FUNCTION_PARAMETERS) +{ + pval *streamind, *ref, *pat, mboxob; + int ind, ind_type; + pils *imap_le_struct; + FOBJECTLIST *cur=NIL; + char *delim=NIL; + + delim = emalloc(2 * sizeof(char)); + + /* set flag for new, improved array of objects list */ + use_folder_object_list = USE_FOLDER_OBJECT_LIST; + + if (ARG_COUNT(ht)!=3 || getParameters(ht,3,&streamind,&ref,&pat) == FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_long(streamind); + convert_to_string(ref); + convert_to_string(pat); + + ind = streamind->value.lval; + + imap_le_struct = (pils *)php3_list_find(ind, &ind_type); + if (!imap_le_struct || ind_type != le_imap) { + php3_error(E_WARNING, "Unable to find stream pointer"); + RETURN_FALSE; + } + + imap_sfolder_objects = NIL; + mail_lsub(imap_le_struct->imap_stream,ref->value.str.val,pat->value.str.val); + if (imap_sfolder_objects == NIL) { + RETURN_FALSE; + } + array_init(return_value); + cur=imap_sfolder_objects; + while (cur != NIL ) { + object_init(&mboxob); + add_property_string(&mboxob, "name", cur->LTEXT, 1); + add_property_long(&mboxob, "attributes", cur->attributes); +#ifdef IMAP41 + delim[0] = (char)cur->delimiter; + delim[1] = 0; + add_property_string(&mboxob, "delimiter", delim, 1); +#else + add_property_string(&mboxob, "delimiter", cur->delimiter, 1); +#endif + add_next_index_object(return_value, mboxob); + cur=cur->next; + } + mail_free_foblist (&imap_sfolder_objects); + efree(delim); + use_folder_object_list = USE_FOLDER_ARRAY_LIST; // reset to default +} +/* }}} */ + + /* {{{ proto int imap_subscribe(int stream_id, string mailbox) Subscribe to a mailbox */ void php3_imap_subscribe(INTERNAL_FUNCTION_PARAMETERS) @@ -2349,6 +2586,7 @@ add_property_long(&myoverview,"answered",elt->answered); add_property_long(&myoverview,"deleted",elt->deleted); add_property_long(&myoverview,"seen",elt->seen); + add_property_long(&myoverview,"draft",elt->draft); add_next_index_object(return_value,myoverview); } } @@ -2571,6 +2809,95 @@ /* }}} */ +/* {{{ proto string imap_alerts() + Returns an array of all IMAP alerts that have been generated either + since the last page load, or since the last imap_alerts() call, + whichever came last. The alert stack is cleared after imap_alerts() + is called. */ +void php3_imap_alerts(INTERNAL_FUNCTION_PARAMETERS) +{ + STRINGLIST *cur=NIL; + + int arg_count = ARG_COUNT(ht); + + if (arg_count > 0) { + WRONG_PARAM_COUNT; + } + + if (imap_alertstack == NIL) { + RETURN_FALSE; + } + + array_init(return_value); + cur = imap_alertstack; + while (cur != NIL) { + add_next_index_string(return_value,cur->LTEXT,1); + cur = cur->next; + } + mail_free_stringlist(&imap_alertstack); + imap_alertstack = NIL; +} +/* }}} */ + + +/* {{{ proto string imap_errors() + Returns an array of all IMAP errors generated either since the last + page load, or since the last imap_errors() call, whichever came + last. The error stack is cleared after imap_errors() is called. */ +void php3_imap_errors(INTERNAL_FUNCTION_PARAMETERS) +{ + ERRORLIST *cur=NIL; + + int arg_count = ARG_COUNT(ht); + + if (arg_count > 0) { + WRONG_PARAM_COUNT; + } + + if (imap_errorstack == NIL) { + RETURN_FALSE; + } + + array_init(return_value); + cur = imap_errorstack; + while (cur != NIL) { + add_next_index_string(return_value,cur->LTEXT,1); + cur = cur->next; + } + mail_free_errorlist(&imap_errorstack); + imap_errorstack = NIL; +} +/* }}} */ + + +/* {{{ proto string imap_last_error() Returns the last error that was + generated by an IMAP function. The error stack is NOT cleared after + this call. */ +void php3_imap_last_error(INTERNAL_FUNCTION_PARAMETERS) +{ + ERRORLIST *cur=NIL; + + int arg_count = ARG_COUNT(ht); + + if (arg_count > 0) { + WRONG_PARAM_COUNT; + } + + if (imap_errorstack == NIL) { + RETURN_FALSE; + } + + cur = imap_errorstack; + while (cur != NIL) { + if (cur->next == NIL) { + RETURN_STRING(cur->LTEXT, 1); + } + cur = cur->next; + } +} +/* }}} */ + + /* Interfaces to C-client */ @@ -2595,27 +2922,71 @@ } -void mm_notify (MAILSTREAM *stream,char *string,long errflg) +void mm_notify (MAILSTREAM *stream,char *string, long errflg) { + STRINGLIST *cur = NIL; + + if (strncmp(string, "[ALERT] ", 8) == 0) { + if (imap_alertstack == NIL) { + imap_alertstack = mail_newstringlist(); + imap_alertstack->LSIZE = strlen(imap_alertstack->LTEXT = cpystr(string)); + imap_alertstack->next = NIL; + } else { + cur = imap_alertstack; + while (cur->next != NIL ) { + cur = cur->next; + } + cur->next = mail_newstringlist (); + cur = cur->next; + cur->LSIZE = strlen(cur->LTEXT = cpystr(string)); + cur->next = NIL; + } + } } void mm_list (MAILSTREAM *stream,DTYPE delimiter,char *mailbox,long attributes) { STRINGLIST *cur=NIL; - if(!(attributes & LATT_NOSELECT)) { - if (imap_folders == NIL) { - imap_folders=mail_newstringlist(); - imap_folders->LSIZE=strlen(imap_folders->LTEXT=cpystr(mailbox)); - imap_folders->next=NIL; + FOBJECTLIST *ocur=NIL; + + if (use_folder_object_list) { + /* build up a the new array of objects */ + if (imap_folder_objects == NIL) { + imap_folder_objects = mail_newfolderobjectlist(); + imap_folder_objects->LSIZE=strlen(imap_folder_objects->LTEXT=cpystr(mailbox)); + imap_folder_objects->delimiter = delimiter; + imap_folder_objects->attributes = attributes; + imap_folder_objects->next = NIL; } else { - cur=imap_folders; - while (cur->next != NIL ) { + ocur=imap_folder_objects; + while (ocur->next != NIL) { + ocur=ocur->next; + } + ocur->next=mail_newfolderobjectlist(); + ocur=ocur->next; + ocur->LSIZE = strlen(ocur->LTEXT = cpystr(mailbox)); + ocur->delimiter = delimiter; + ocur->attributes = attributes; + ocur->next = NIL; + } + + } else { + /* build the old imap_folders variable to allow old imap_listmailbox() to work */ + if (!(attributes & LATT_NOSELECT)) { + if (imap_folders == NIL) { + imap_folders=mail_newstringlist(); + imap_folders->LSIZE=strlen(imap_folders->LTEXT=cpystr(mailbox)); + imap_folders->next=NIL; + } else { + cur=imap_folders; + while (cur->next != NIL ) { + cur=cur->next; + } + cur->next=mail_newstringlist (); cur=cur->next; + cur->LSIZE = strlen (cur->LTEXT = cpystr (mailbox)); + cur->next = NIL; } - cur->next=mail_newstringlist (); - cur=cur->next; - cur->LSIZE = strlen (cur->LTEXT = cpystr (mailbox)); - cur->next = NIL; } } } @@ -2623,19 +2994,45 @@ void mm_lsub (MAILSTREAM *stream,DTYPE delimiter,char *mailbox,long attributes) { STRINGLIST *cur=NIL; - if (imap_sfolders == NIL) { - imap_sfolders=mail_newstringlist(); - imap_sfolders->LSIZE=strlen(imap_sfolders->LTEXT=cpystr(mailbox)); - imap_sfolders->next=NIL; + FOBJECTLIST *ocur=NIL; + + if (use_folder_object_list) { + /* build the array of objects */ + if (imap_sfolder_objects == NIL) { + imap_sfolder_objects = mail_newfolderobjectlist(); + imap_sfolder_objects->LSIZE=strlen(imap_sfolder_objects->LTEXT=cpystr(mailbox)); + imap_sfolder_objects->delimiter = delimiter; + imap_sfolder_objects->attributes = attributes; + imap_sfolder_objects->next = NIL; + } else { + ocur=imap_sfolder_objects; + while (ocur->next != NIL) { + ocur=ocur->next; + } + ocur->next=mail_newfolderobjectlist(); + ocur=ocur->next; + ocur->LSIZE=strlen(ocur->LTEXT = cpystr(mailbox)); + ocur->delimiter = delimiter; + ocur->attributes = attributes; + ocur->next = NIL; + } + } else { - cur=imap_sfolders; - while (cur->next != NIL ) { + /* build the old simple array for imap_listsubscribed() */ + if (imap_sfolders == NIL) { + imap_sfolders=mail_newstringlist(); + imap_sfolders->LSIZE=strlen(imap_sfolders->LTEXT=cpystr(mailbox)); + imap_sfolders->next=NIL; + } else { + cur=imap_sfolders; + while (cur->next != NIL ) { + cur=cur->next; + } + cur->next=mail_newstringlist (); cur=cur->next; + cur->LSIZE = strlen (cur->LTEXT = cpystr (mailbox)); + cur->next = NIL; } - cur->next=mail_newstringlist (); - cur=cur->next; - cur->LSIZE = strlen (cur->LTEXT = cpystr (mailbox)); - cur->next = NIL; } } @@ -2652,23 +3049,33 @@ void mm_log (char *string,long errflg) { - switch ((short) errflg) { - case NIL: - /* php3_error(E_NOTICE,string); messages */ - break; - case PARSE: - case WARN: - php3_error(E_WARNING,string); /* warnings */ - break; - case ERROR: - php3_error(E_NOTICE,string); /* errors */ - break; - } + ERRORLIST *cur = NIL; + + if (errflg != NIL) { /* CJH: maybe put these into a more comprehensive log for debugging purposes? */ + if (imap_errorstack == NIL) { + imap_errorstack = mail_newerrorlist(); + imap_errorstack->LSIZE = strlen(imap_errorstack->LTEXT = cpystr(string)); + imap_errorstack->errflg = errflg; + imap_errorstack->next = NIL; + } else { + cur = imap_errorstack; + while (cur->next != NIL ) { + cur = cur->next; + } + cur->next = mail_newerrorlist (); + cur = cur->next; + cur->LSIZE = strlen(cur->LTEXT = cpystr(string)); + cur->errflg = errflg; + cur->next = NIL; + } + } } void mm_dlog (char *string) { - php3_error(E_NOTICE,string); + /* CJH: this is for debugging; it might be useful to allow setting + the stream to debug mode and capturing this somewhere - syslog? + php debugger? */ } void mm_login (NETMBX *mb,char *user,char *pwd,long trial) --- php3.orig/functions/imap.h Mon Dec 28 04:43:58 1998 +++ php3/functions/imap.h Thu Jul 1 14:46:51 1999 @@ -22,6 +22,8 @@ #define php3_imap_module_ptr &php3_imap_module_entry extern int imap_init(INIT_FUNC_ARGS); +extern int imap_init_request(INIT_FUNC_ARGS); +extern int imap_end_request(void); extern void imap_info(void); void php3_imap_open(INTERNAL_FUNCTION_PARAMETERS); void php3_imap_reopen(INTERNAL_FUNCTION_PARAMETERS); @@ -40,8 +42,10 @@ void php3_imap_renamemailbox(INTERNAL_FUNCTION_PARAMETERS); void php3_imap_deletemailbox(INTERNAL_FUNCTION_PARAMETERS); void php3_imap_list(INTERNAL_FUNCTION_PARAMETERS); +void php3_imap_list_full(INTERNAL_FUNCTION_PARAMETERS); void php3_imap_listscan(INTERNAL_FUNCTION_PARAMETERS); void php3_imap_lsub(INTERNAL_FUNCTION_PARAMETERS); +void php3_imap_lsub_full(INTERNAL_FUNCTION_PARAMETERS); void php3_imap_subscribe(INTERNAL_FUNCTION_PARAMETERS); void php3_imap_unsubscribe(INTERNAL_FUNCTION_PARAMETERS); void php3_imap_num_recent(INTERNAL_FUNCTION_PARAMETERS); @@ -68,24 +72,12 @@ void php3_imap_bodystruct(INTERNAL_FUNCTION_PARAMETERS); void php3_imap_fetch_overview(INTERNAL_FUNCTION_PARAMETERS); void php3_imap_mail_compose(INTERNAL_FUNCTION_PARAMETERS); +void php3_imap_alerts(INTERNAL_FUNCTION_PARAMETERS); +void php3_imap_errors(INTERNAL_FUNCTION_PARAMETERS); +void php3_imap_last_error(INTERNAL_FUNCTION_PARAMETERS); #else #define php3_imap_module_ptr NULL #endif /* HAVE_IMAP */ #endif - - - - - - - - - - - - - - -
« previous php.dev (#7955) next »