Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:30418 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 53137 invoked by uid 1010); 3 Jul 2007 10:35:16 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 53122 invoked from network); 3 Jul 2007 10:35:16 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 3 Jul 2007 10:35:16 -0000 Authentication-Results: pb1.pair.com smtp.mail=dmitry@zend.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=dmitry@zend.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain zend.com designates 212.25.124.162 as permitted sender) X-PHP-List-Original-Sender: dmitry@zend.com X-Host-Fingerprint: 212.25.124.162 mail.zend.com Linux 2.5 (sometimes 2.4) (4) Received: from [212.25.124.162] ([212.25.124.162:33800] helo=mail.zend.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 40/D0-41468-E562A864 for ; Tue, 03 Jul 2007 06:35:14 -0400 Received: (qmail 3168 invoked from network); 3 Jul 2007 10:35:07 -0000 Received: from internal.zend.office (HELO thinkpad) (10.1.1.1) by internal.zend.office with SMTP; 3 Jul 2007 10:35:07 -0000 To: Cc: "Ilia Alshanetsky" , "Stanislav Malyshev" Date: Tue, 3 Jul 2007 14:34:52 +0400 Message-ID: <000a01c7bd5d$cc6110b0$087a81d4@thinkpad> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_000B_01C7BD7F.5372B0B0" X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook, Build 10.0.6626 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3138 Importance: Normal Subject: FW: [PHP-CVS] cvs: php-src /ext/standard basic_functions.c streamsfuncs.c streamsfuncs.h /ext/standard/tests/file include_userstream_001.phpt include_userstream_002.phpt /main main.c php_globals.h php_streams.h /main/streams streams.c userspa From: dmitry@zend.com ("Dmitry Stogov") ------=_NextPart_000_000B_01C7BD7F.5372B0B0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Hi, I am going to commit the same patch to PHP_5_2. It looks like it breaks binary compatibility but really it doesn't. Any objections? Thanks. Dmitry. > -----Original Message----- > From: Dmitry Stogov [mailto:dmitry@php.net] > Sent: Tuesday, July 03, 2007 2:23 PM > To: php-cvs@lists.php.net > Subject: [PHP-CVS] cvs: php-src /ext/standard > basic_functions.c streamsfuncs.c streamsfuncs.h > /ext/standard/tests/file include_userstream_001.phpt > include_userstream_002.phpt /main main.c php_globals.h > php_streams.h /main/streams streams.c userspa > > > dmitry Tue Jul 3 10:22:56 2007 UTC > > Added files: > /php-src/ext/standard/tests/file include_userstream_001.phpt > include_userstream_002.phpt > > Modified files: > /php-src/main main.c php_globals.h php_streams.h > /php-src/main/streams streams.c userspace.c > /php-src/ext/standard basic_functions.c streamsfuncs.c > streamsfuncs.h > Log: > Added ability to create local or remote (URL) user streams > Local user streams must not be able to open(), URLs if > allow_url_include is off > Implemented new function stream_is_local() > [ > - stream_wrapper_register() extended with additional > optional argument "flags" > of type long. This time only one flag is implemented - > STREAM_IS_URL, that > means that userstream wrapper is remote (URL). By default > stream is local. > - stream_is_local() is a new function that accepts stream > and tell if this > stream is local or remote (URL) > ] > > > ------=_NextPart_000_000B_01C7BD7F.5372B0B0 Content-Type: text/plain; name="dmitry-20070703102256.txt" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="dmitry-20070703102256.txt" http://cvs.php.net/viewvc.cgi/php-src/main/main.c?r1=3D1.732&r2=3D1.733&d= iff_format=3Du Index: php-src/main/main.c diff -u php-src/main/main.c:1.732 php-src/main/main.c:1.733 --- php-src/main/main.c:1.732 Fri Jun 15 09:20:53 2007 +++ php-src/main/main.c Tue Jul 3 10:22:55 2007 @@ -18,7 +18,7 @@ = +----------------------------------------------------------------------+ */ =20 -/* $Id: main.c,v 1.732 2007/06/15 09:20:53 dmitry Exp $ */ +/* $Id: main.c,v 1.733 2007/07/03 10:22:55 dmitry Exp $ */ =20 /* {{{ includes */ @@ -1232,6 +1232,7 @@ PG(modules_activated) =3D 0; PG(header_is_being_sent) =3D 0; PG(connection_status) =3D PHP_CONNECTION_NORMAL; + PG(in_user_include) =3D 0; =20 zend_activate(TSRMLS_C); sapi_activate(TSRMLS_C); http://cvs.php.net/viewvc.cgi/php-src/main/php_globals.h?r1=3D1.111&r2=3D= 1.112&diff_format=3Du Index: php-src/main/php_globals.h diff -u php-src/main/php_globals.h:1.111 = php-src/main/php_globals.h:1.112 --- php-src/main/php_globals.h:1.111 Fri Mar 2 22:04:46 2007 +++ php-src/main/php_globals.h Tue Jul 3 10:22:55 2007 @@ -16,7 +16,7 @@ = +----------------------------------------------------------------------+ */ =20 -/* $Id: php_globals.h,v 1.111 2007/03/02 22:04:46 stas Exp $ */ +/* $Id: php_globals.h,v 1.112 2007/07/03 10:22:55 dmitry Exp $ */ =20 #ifndef PHP_GLOBALS_H #define PHP_GLOBALS_H @@ -142,6 +142,7 @@ zend_bool com_initialized; #endif long max_input_nesting_level; + zend_bool in_user_include; }; =20 =20 http://cvs.php.net/viewvc.cgi/php-src/main/php_streams.h?r1=3D1.128&r2=3D= 1.129&diff_format=3Du Index: php-src/main/php_streams.h diff -u php-src/main/php_streams.h:1.128 = php-src/main/php_streams.h:1.129 --- php-src/main/php_streams.h:1.128 Sat Mar 3 22:30:07 2007 +++ php-src/main/php_streams.h Tue Jul 3 10:22:55 2007 @@ -16,7 +16,7 @@ = +----------------------------------------------------------------------+ */ =20 -/* $Id: php_streams.h,v 1.128 2007/03/03 22:30:07 helly Exp $ */ +/* $Id: php_streams.h,v 1.129 2007/07/03 10:22:55 dmitry Exp $ */ =20 #ifndef PHP_STREAMS_H #define PHP_STREAMS_H @@ -619,6 +619,9 @@ /* use glob stream for directory open in plain files stream */ #define STREAM_USE_GLOB_DIR_OPEN 0x00001000 =20 +/* use glob stream for directory open in plain files stream */ +#define STREAM_DISABLE_URL_PROTECTION 0x00002000 + /* Antique - no longer has meaning */ #define IGNORE_URL_WIN 0 =20 @@ -669,7 +672,7 @@ =20 PHP_INI_MH(OnUpdateAllowUrl); PHPAPI int php_stream_wrapper_is_allowed(const char *wrapper, int = wrapper_len, const char *setting TSRMLS_DC); -#define php_stream_allow_url_fopen(wrapper, wrapper_len) = php_stream_wrapper_is_allowed((wrapper), (wrapper_len), = PG(allow_url_fopen_list) TSRMLS_CC) +#define php_stream_allow_url_fopen(wrapper, wrapper_len) = php_stream_wrapper_is_allowed((wrapper), (wrapper_len), = PG(in_user_include)?PG(allow_url_include_list):PG(allow_url_fopen_list) = TSRMLS_CC) #define php_stream_allow_url_include(wrapper, wrapper_len) = php_stream_wrapper_is_allowed((wrapper), (wrapper_len), = PG(allow_url_include_list) TSRMLS_CC) =20 /* Give other modules access to the url_stream_wrappers_hash and = stream_filters_hash */ @@ -683,6 +686,8 @@ END_EXTERN_C() #endif =20 +/* Definitions for user streams */ +#define PHP_STREAM_IS_URL 1 /* * Local variables: * tab-width: 4 http://cvs.php.net/viewvc.cgi/php-src/main/streams/streams.c?r1=3D1.151&r= 2=3D1.152&diff_format=3Du Index: php-src/main/streams/streams.c diff -u php-src/main/streams/streams.c:1.151 = php-src/main/streams/streams.c:1.152 --- php-src/main/streams/streams.c:1.151 Tue May 8 12:08:41 2007 +++ php-src/main/streams/streams.c Tue Jul 3 10:22:55 2007 @@ -19,7 +19,7 @@ = +----------------------------------------------------------------------+ */ =20 -/* $Id: streams.c,v 1.151 2007/05/08 12:08:41 dmitry Exp $ */ +/* $Id: streams.c,v 1.152 2007/07/03 10:22:55 dmitry Exp $ */ =20 #define _GNU_SOURCE #include "php.h" @@ -2163,8 +2163,9 @@ return plain_files_wrapper; } =20 - if (!php_stream_allow_url_fopen(protocol, n) || - ((options & STREAM_OPEN_FOR_INCLUDE) && = !php_stream_allow_url_include(protocol, n)) ) { + if (((options & STREAM_DISABLE_URL_PROTECTION) =3D=3D 0) && + (!php_stream_allow_url_fopen(protocol, n) || + ((options & STREAM_OPEN_FOR_INCLUDE) && = !php_stream_allow_url_include(protocol, n)))) { if (options & REPORT_ERRORS) { /* protocol[n] probably isn't '\0' */ char *protocol_dup =3D estrndup(protocol, n); @@ -2797,7 +2798,7 @@ =20 return FAILURE; } - wrapper =3D php_stream_locate_url_wrapper(scheme, NULL, options = TSRMLS_CC); + wrapper =3D php_stream_locate_url_wrapper(scheme, NULL, options | = STREAM_DISABLE_URL_PROTECTION TSRMLS_CC); efree(scheme); if (!wrapper) { *pathenc =3D NULL; http://cvs.php.net/viewvc.cgi/php-src/main/streams/userspace.c?r1=3D1.42&= r2=3D1.43&diff_format=3Du Index: php-src/main/streams/userspace.c diff -u php-src/main/streams/userspace.c:1.42 = php-src/main/streams/userspace.c:1.43 --- php-src/main/streams/userspace.c:1.42 Tue May 15 13:01:47 2007 +++ php-src/main/streams/userspace.c Tue Jul 3 10:22:55 2007 @@ -17,7 +17,7 @@ = +----------------------------------------------------------------------+ */ =20 -/* $Id: userspace.c,v 1.42 2007/05/15 13:01:47 scottmac Exp $ */ +/* $Id: userspace.c,v 1.43 2007/07/03 10:22:55 dmitry Exp $ */ =20 #include "php.h" #include "php_globals.h" @@ -81,6 +81,7 @@ REGISTER_LONG_CONSTANT("STREAM_URL_STAT_QUIET", = PHP_STREAM_URL_STAT_QUIET, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("STREAM_MKDIR_RECURSIVE", = PHP_STREAM_MKDIR_RECURSIVE, CONST_CS|CONST_PERSISTENT); =20 + REGISTER_LONG_CONSTANT("STREAM_IS_URL", PHP_STREAM_IS_URL, = CONST_CS|CONST_PERSISTENT); return SUCCESS; } =20 @@ -215,6 +216,7 @@ int call_result; php_stream *stream =3D NULL; zval *zcontext =3D NULL; + zend_bool old_in_user_include; =20 /* Try to catch bad usage without preventing flexibility */ if (FG(user_stream_current_filename) !=3D NULL && strcmp(filename, = FG(user_stream_current_filename)) =3D=3D 0) { @@ -223,6 +225,17 @@ } FG(user_stream_current_filename) =3D filename; =09 + /* if the user stream was registered as local and we are in include = context, + we add allow_url_include restrictions to allow_url_fopen ones */ + /* we need only is_url =3D=3D 0 here since if is_url =3D=3D 1 and = remote wrappers + were restricted we wouldn't get here */ + old_in_user_include =3D PG(in_user_include); + if(uwrap->wrapper.is_url =3D=3D 0 &&=20 + (options & STREAM_OPEN_FOR_INCLUDE) &&=20 + (PG(allow_url_include_list) =3D=3D NULL || = strlen(PG(allow_url_include_list)) !=3D1 || = PG(allow_url_include_list)[0] !=3D '*')) { + PG(in_user_include) =3D 1; + } + us =3D emalloc(sizeof(*us)); us->wrapper =3D uwrap;=09 =20 @@ -258,6 +271,7 @@ FREE_ZVAL(us->object); efree(us); FG(user_stream_current_filename) =3D NULL; + PG(in_user_include) =3D old_in_user_include; return NULL; } else { if (retval_ptr) { @@ -338,7 +352,8 @@ zval_ptr_dtor(&zfilename); =20 FG(user_stream_current_filename) =3D NULL; - =09 + + PG(in_user_include) =3D old_in_user_include; return stream; } =20 @@ -436,8 +451,9 @@ int protocol_len, classname_len; struct php_user_stream_wrapper * uwrap; int rsrc_id; + long flags =3D 0; =09 - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &protocol, = &protocol_len, &classname, &classname_len) =3D=3D FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", = &protocol, &protocol_len, &classname, &classname_len, &flags) =3D=3D = FAILURE) { RETURN_FALSE; } =09 @@ -446,6 +462,7 @@ uwrap->classname =3D estrndup(classname, classname_len); uwrap->wrapper.wops =3D &user_stream_wops; uwrap->wrapper.abstract =3D uwrap; + uwrap->wrapper.is_url =3D ((flags & PHP_STREAM_IS_URL) !=3D 0); =20 rsrc_id =3D ZEND_REGISTER_RESOURCE(NULL, uwrap, le_protocols); =20 http://cvs.php.net/viewvc.cgi/php-src/ext/standard/basic_functions.c?r1=3D= 1.861&r2=3D1.862&diff_format=3Du Index: php-src/ext/standard/basic_functions.c diff -u php-src/ext/standard/basic_functions.c:1.861 = php-src/ext/standard/basic_functions.c:1.862 --- php-src/ext/standard/basic_functions.c:1.861 Tue Jun 26 21:29:32 = 2007 +++ php-src/ext/standard/basic_functions.c Tue Jul 3 10:22:55 2007 @@ -17,7 +17,7 @@ = +----------------------------------------------------------------------+ */ =20 -/* $Id: basic_functions.c,v 1.861 2007/06/26 21:29:32 tony2001 Exp $ */ +/* $Id: basic_functions.c,v 1.862 2007/07/03 10:22:55 dmitry Exp $ */ =20 #include "php.h" #include "php_streams.h" @@ -205,9 +205,10 @@ /* }}} */ /* {{{ main/streams/userspace.c */ static -ZEND_BEGIN_ARG_INFO(arginfo_stream_wrapper_register, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_stream_wrapper_register, 0, 0, 2) ZEND_ARG_INFO(0, protocol) ZEND_ARG_INFO(0, classname) + ZEND_ARG_INFO(0, flags) ZEND_END_ARG_INFO() =20 static @@ -2347,6 +2348,11 @@ ZEND_END_ARG_INFO() =20 static +ZEND_BEGIN_ARG_INFO(arginfo_stream_is_local, 0) + ZEND_ARG_INFO(0, stream) +ZEND_END_ARG_INFO() + +static ZEND_BEGIN_ARG_INFO_EX(arginfo_stream_select, 0, 0, 4) ZEND_ARG_INFO(1, read_streams) /* ARRAY_INFO(1, read_streams, 1) */ ZEND_ARG_INFO(1, write_streams) /* ARRAY_INFO(1, write_streams, 1) */ @@ -3596,6 +3602,7 @@ PHP_FE(stream_wrapper_restore, = arginfo_stream_wrapper_restore) PHP_FE(stream_get_wrappers, arginfo_stream_get_wrappers) PHP_FE(stream_get_transports, arginfo_stream_get_transports) + PHP_FE(stream_is_local, arginfo_stream_is_local) PHP_FE(get_headers, arginfo_get_headers) =20 #if HAVE_SYS_TIME_H || defined(PHP_WIN32) http://cvs.php.net/viewvc.cgi/php-src/ext/standard/streamsfuncs.c?r1=3D1.= 103&r2=3D1.104&diff_format=3Du Index: php-src/ext/standard/streamsfuncs.c diff -u php-src/ext/standard/streamsfuncs.c:1.103 = php-src/ext/standard/streamsfuncs.c:1.104 --- php-src/ext/standard/streamsfuncs.c:1.103 Thu Apr 12 13:15:17 2007 +++ php-src/ext/standard/streamsfuncs.c Tue Jul 3 10:22:55 2007 @@ -17,7 +17,7 @@ = +----------------------------------------------------------------------+ */ =20 -/* $Id: streamsfuncs.c,v 1.103 2007/04/12 13:15:17 tony2001 Exp $ */ +/* $Id: streamsfuncs.c,v 1.104 2007/07/03 10:22:55 dmitry Exp $ */ =20 #include "php.h" #include "php_globals.h" @@ -1647,6 +1647,37 @@ } /* }}} */ =20 +/* {{{ proto bool stream_is_local(resource stream|string url) U +*/ +PHP_FUNCTION(stream_is_local) +{ + zval *zstream; + php_stream *stream =3D NULL; + php_stream_wrapper *wrapper =3D NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zstream) = =3D=3D FAILURE) { + RETURN_FALSE; + } + + if(Z_TYPE_P(zstream) =3D=3D IS_RESOURCE) { + php_stream_from_zval(stream, &zstream); + if(stream =3D=3D NULL) { + RETURN_FALSE; + } + wrapper =3D stream->wrapper; + } else { + convert_to_string_ex(&zstream); + wrapper =3D php_stream_locate_url_wrapper(Z_STRVAL_P(zstream), NULL, = STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC); + } + + if(!wrapper) { + RETURN_FALSE; + } + + RETURN_BOOL(wrapper->is_url=3D=3D0); +} +/* }}} */ + #ifdef HAVE_SHUTDOWN /* {{{ proto int stream_socket_shutdown(resource stream, int how) U causes all or part of a full-duplex connection on the socket = associated http://cvs.php.net/viewvc.cgi/php-src/ext/standard/streamsfuncs.h?r1=3D1.= 19&r2=3D1.20&diff_format=3Du Index: php-src/ext/standard/streamsfuncs.h diff -u php-src/ext/standard/streamsfuncs.h:1.19 = php-src/ext/standard/streamsfuncs.h:1.20 --- php-src/ext/standard/streamsfuncs.h:1.19 Mon Jan 1 09:29:32 2007 +++ php-src/ext/standard/streamsfuncs.h Tue Jul 3 10:22:55 2007 @@ -16,7 +16,7 @@ = +----------------------------------------------------------------------+ */ =20 -/* $Id: streamsfuncs.h,v 1.19 2007/01/01 09:29:32 sebastian Exp $ */ +/* $Id: streamsfuncs.h,v 1.20 2007/07/03 10:22:55 dmitry Exp $ */ =20 /* Flags for stream_socket_client */ #define PHP_STREAM_CLIENT_PERSISTENT 1 @@ -57,6 +57,7 @@ PHP_FUNCTION(stream_socket_shutdown); PHP_FUNCTION(stream_socket_pair); PHP_FUNCTION(stream_resolve_include_path); +PHP_FUNCTION(stream_is_local); =20 /* * Local variables: http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/file/include_use= rstream_001.phpt?view=3Dmarkup&rev=3D1.1 Index: php-src/ext/standard/tests/file/include_userstream_001.phpt +++ php-src/ext/standard/tests/file/include_userstream_001.phpt --TEST-- User streams and include() --INI-- allow_url_fopen=3D1 allow_url_include=3D0 --FILE-- '; private $pos; function stream_open($path, $mode, $options, &$opened_path) { if (strchr($mode, 'a')) $this->pos =3D strlen($this->data); else $this->po =3D 0; =09 return true; } function stream_read($count) { $ret =3D substr($this->data, $this->pos, $count); $this->pos +=3D strlen($ret); return $ret; } function stream_tell() { return $this->pos; } function stream_eof() { return $this->pos >=3D strlen($this->data); } function stream_seek($offset, $whence) { switch($whence) { case SEEK_SET: if ($offset < $this->data && $offset >=3D 0) { $this->pos =3D $offset; return true; } else { return false; } break; case SEEK_CUR: if ($offset >=3D 0) { $this->pos +=3D $offset; return true; } else { return false; } break; case SEEK_END: if (strlen($this->data) + $offset >=3D 0) { $this->pos =3D strlen($this->data) + $offset; return true; } else { return false; } break; default: return false; } } } stream_register_wrapper("test1", "test", STREAM_IS_URL); stream_register_wrapper("test2", "test"); echo @file_get_contents("test1://hello"),"\n"; @include "test1://hello"; echo @file_get_contents("test2://hello"),"\n"; @include "test2://hello"; --EXPECT-- Hello World http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/file/include_use= rstream_002.phpt?view=3Dmarkup&rev=3D1.1 Index: php-src/ext/standard/tests/file/include_userstream_002.phpt +++ php-src/ext/standard/tests/file/include_userstream_002.phpt --TEST-- local user streams must not be able to open() url's --INI-- allow_url_fopen=3D1 allow_url_include=3D0 --FILE-- '; private $pos; private $stream =3D null; function stream_open($path, $mode, $options, &$opened_path) { if (strpos($path, "test2://") =3D=3D=3D 0) { $this->stream =3D fopen("test1://".substr($path, 8), $mode); return !empty($this->stream); } if (strchr($mode, 'a')) $this->pos =3D strlen($this->data); else $this->po =3D 0; =09 return true; } function stream_read($count) { if (!empty($this->stream)) { return fread($this->stream, $count); } $ret =3D substr($this->data, $this->pos, $count); $this->pos +=3D strlen($ret); return $ret; } function stream_tell() { if (!empty($this->stream)) { return ftell($this->stream); } return $this->pos; } function stream_eof() { if (!empty($this->stream)) { return feof($this->stream); } return $this->pos >=3D strlen($this->data); } function stream_seek($offset, $whence) { if (!empty($this->stream)) { return fseek($this->stream, $offset, $whence); } switch($whence) { case SEEK_SET: if ($offset < $this->data && $offset >=3D 0) { $this->pos =3D $offset; return true; } else { return false; } break; case SEEK_CUR: if ($offset >=3D 0) { $this->pos +=3D $offset; return true; } else { return false; } break; case SEEK_END: if (strlen($this->data) + $offset >=3D 0) { $this->pos =3D strlen($this->data) + $offset; return true; } else { return false; } break; default: return false; } } } stream_register_wrapper("test1", "test", STREAM_IS_URL); stream_register_wrapper("test2", "test"); echo @file_get_contents("test1://hello"),"\n"; @include "test1://hello"; echo @file_get_contents("test2://hello"),"\n"; include "test2://hello"; --EXPECTF-- Warning: fopen(): test1:// wrapper is disabled in the server = configuration in %sinclude_userstream_002.php on line 10 Warning: fopen(test1://hello): failed to open stream: no suitable = wrapper could be found in %sinclude_userstream_002.php on line 10 Warning: include(test2://hello): failed to open stream: = "test::stream_open" call failed in %sinclude_userstream_002.php on line = 89 Warning: include(): Failed opening 'test2://hello' for inclusion = (include_path=3D'%s') in %sinclude_userstream_002.php on line 89 ------=_NextPart_000_000B_01C7BD7F.5372B0B0 Content-Type: text/plain; name="ATT00004.txt" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="ATT00004.txt" -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php ------=_NextPart_000_000B_01C7BD7F.5372B0B0--