Re: bug in php3_imap_reopen
| From: | Stig Venaas | Date: | Thu, 01 Jan 1970 00:00:00 +0000 |
| Subject: | Re: bug in php3_imap_reopen | ||
| References: | 1 | Groups: | php.dev |
| Request: | Send a blank email to php-dev+get-9763@lists.php.net to get a copy of this message | ||
>
> this should be a cause of the problem..
>
>
> mail_open simply returns the ame stream if you pasin a stream..
>
> are you using php3 or php4?
>
> can you give me a backtrace too?
Sorry about the missing info. It's the latest PHP3 (from CVS) with
imap-4.6.BETA c-client library. I'm trying to reopen a folder with
anonymous access. Here's a piece of the script:
$mbox = imap_open("{$server:$port}", "", "",
OP_ANONYMOUS|OP_HALFOPEN);
if ($mbox) {
$mailboxroot = "{$server:$port}#public/";
$mailboxes = imap_listmailbox($mbox, "$mailboxroot", "*");
for ($folder = reset($mailboxes); $folder; $folder = next($mailboxes)) {
if (imap_reopen($mbox, $folder, OP_ANONYMOUS|OP_READONLY)) {
I see pretty well what happens I think. Here's some of the code from
mail_open in mail.c from c-client:
if (d) { /* must have a factory */
if (options & OP_PROTOTYPE) return (*d->open) (NIL);
if (stream) { /* recycling requested? */
/* yes, recycleable stream? */
if ((stream->dtb == d) && (d->flags & DR_RECYCLE) &&
mail_usable_network_stream (stream,name)) {
mail_free_cache(stream);/* yes, clean up stream */
if (stream->mailbox) fs_give ((void **) &stream->mailbox);
/* flush user flags */
for (i = 0; i < NUSERFLAGS; i++)
if (stream->user_flags[i]) fs_give ((void **)&stream->user_flags[i]);
}
else { /* stream not recycleable, babble if net */
if (!stream->silent && stream->dtb &&
!(stream->dtb->flags&DR_LOCAL) &&
mail_valid_net_parse (stream->mailbox,&mb)) {
sprintf (tmp,"Closing connection to %.80s",mb.host);
mm_log (tmp,(long) NIL);
}
/* flush the old stream */
stream = mail_close (stream);
}
}
/* instantiate new stream if not recycling */
At the 6th line I quoted it calls mail_usable_network_stream, which
looks like this:
long mail_usable_network_stream (MAILSTREAM *stream,char *name)
{
NETMBX smb,nmb;
return (stream && stream->dtb && !(stream->dtb->flags & DR_LOCAL)
&&
mail_valid_net_parse (name,&nmb) &&
mail_valid_net_parse (stream->mailbox,&smb) &&
!strcmp (lcase (smb.host),lcase (tcp_canonical (nmb.host))) &&
!strcmp (smb.service,nmb.service) &&
(!nmb.port || (smb.port == nmb.port)) &&
(nmb.anoflag == stream->anonymous) &&
(!nmb.user[0] || !strcmp (smb.user,nmb.user))) ? LONGT : NIL;
}
It seems that all is fine until (nmb.anoflag == stream->anonymous).
With gdb I can see:
(gdb) inspect nmb.anoflag
$8 = 0
(gdb) inspect stream->anonymous
$9 = 1
A backtrace at this point gives
#0 mail_usable_network_stream (stream=0x814b1c8,
name=0x8153a80 "{tyholt:143}#public/php-dev") at mail.c:4048
#1 0x8089316 in mail_open (stream=0x814b1c8,
name=0x8153a80 "{tyholt:143}#public/php-dev", options=6) at mail.c:841
#2 0x8070ceb in php3_imap_reopen (ht=0x814ac40, return_value=0x8126510,
list=0x81379a0, plist=0x8137960) at functions/imap.c:832
#3 0x8050b44 in phpparse () at control_structures_inline.h:934
#4 0x8059b88 in php3_parse (yyin=0x8145948) at main.c:1553
#5 0x805a153 in main (argc=2, argv=0xbffffcd4) at main.c:1862
#6 0x4009bcb3 in __libc_start_main (main=0x8059c98 <main>, argc=2,
argv=0xbffffcd4, init=0x804a804 <_init>, fini=0x80d11ac <_fini>,
rtld_fini=0x4000a350 <_dl_fini>, stack_end=0xbffffccc)
at ../sysdeps/generic/libc-start.c:78
As you can see from my quote from mail_open the NIL return from
mail_usable_network_stream results in the stream being freed,
and it creates a new one. From gdb:
(gdb)
mail_open (stream=0x814b1c8, name=0x8153a80 "{tyholt:143}#public/php-dev",
options=6) at mail.c:852
852 sprintf (tmp,"Closing connection to %.80s",mb.host);
(gdb) display stream
1: stream = (MAILSTREAM *) 0x814b1c8
(gdb) next
853 mm_log (tmp,(long) NIL);
1: stream = (MAILSTREAM *) 0x814b1c8
(gdb)
854 }
1: stream = (MAILSTREAM *) 0x814b1c8
(gdb)
856 stream = mail_close (stream);
1: stream = (MAILSTREAM *) 0x814b1c8
(gdb)
857 }
1: stream = (MAILSTREAM *) 0x0
(gdb)
860 if (!stream) (*mailcache) (stream = (MAILSTREAM *)
1: stream = (MAILSTREAM *) 0x0
(gdb)
861 memset (fs_get (sizeof (MAILSTREAM)),0,
1: stream = (MAILSTREAM *) 0x0
(gdb)
862 sizeof (MAILSTREAM)),(long) 0,CH_INIT);
1: stream = (MAILSTREAM *) 0x0
(gdb) next
863 stream->dtb = d; /* set dispatch */
1: stream = (MAILSTREAM *) 0x8150410
Since evidently the stream can't always be reused, I think the reopen
function shouldn't assume that it is. It would also be nice if I
understood why it can't be reused though, that nmb.anoflag is 0
doesn't tell me much, if someone knows why, please tell me; I'll
probably save a few hours work.
Stig