1999-04-17 08:37:12 +08:00
|
|
|
/*
|
|
|
|
+----------------------------------------------------------------------+
|
2001-12-11 23:32:16 +08:00
|
|
|
| PHP Version 4 |
|
1999-04-17 08:37:12 +08:00
|
|
|
+----------------------------------------------------------------------+
|
2001-12-11 23:32:16 +08:00
|
|
|
| Copyright (c) 1997-2002 The PHP Group |
|
1999-04-17 08:37:12 +08:00
|
|
|
+----------------------------------------------------------------------+
|
2000-05-18 23:34:45 +08:00
|
|
|
| This source file is subject to version 2.02 of the PHP license, |
|
1999-07-16 21:13:16 +08:00
|
|
|
| that is bundled with this package in the file LICENSE, and is |
|
|
|
|
| available at through the world-wide-web at |
|
2000-05-18 23:34:45 +08:00
|
|
|
| http://www.php.net/license/2_02.txt. |
|
1999-07-16 21:13:16 +08:00
|
|
|
| If you did not receive a copy of the PHP license and are unable to |
|
|
|
|
| obtain it through the world-wide-web, please send a note to |
|
|
|
|
| license@php.net so we can mail you a copy immediately. |
|
1999-04-17 08:37:12 +08:00
|
|
|
+----------------------------------------------------------------------+
|
|
|
|
| Authors: Paul Panotzki - Bunyip Information Systems |
|
2001-04-26 21:47:17 +08:00
|
|
|
| Jim Winstead <jimw@php.net> |
|
1999-12-02 01:07:25 +08:00
|
|
|
| Sascha Schumann <sascha@schumann.cx> |
|
1999-04-17 08:37:12 +08:00
|
|
|
+----------------------------------------------------------------------+
|
|
|
|
*/
|
1999-06-18 21:42:21 +08:00
|
|
|
|
1999-04-17 08:37:12 +08:00
|
|
|
/* $Id$ */
|
1999-06-16 05:51:00 +08:00
|
|
|
|
2002-03-16 05:03:08 +08:00
|
|
|
/* converted to PHP Streams and moved much code to main/network.c [wez] */
|
|
|
|
|
1999-12-18 12:01:20 +08:00
|
|
|
/* Synced with php 3.0 revision 1.121 1999-06-18 [ssb] */
|
|
|
|
/* Synced with php 3.0 revision 1.133 1999-07-21 [sas] */
|
1999-06-18 21:42:21 +08:00
|
|
|
|
1999-04-17 08:37:12 +08:00
|
|
|
#include "php.h"
|
* fixed some #if/#ifdef issues
* hand-patched in php3 changes from 3.0.6 to HEAD in these files:
fopen-wrappers.[ch] ext/standard/file.[ch] ext/standard/fsock.[ch]
ext/standard/php3_string.h ext/standard/string.c
* added some new file/socket macros for more readable code:
FP_FGETS(buf,len,sock,fp,issock)
FP_FREAD(buf,len,sock,fp,issock)
FP_FEOF(sock,fp,issock)
FP_FGETC(sock,fp,issock)
1999-06-17 01:06:53 +08:00
|
|
|
#include "php_globals.h"
|
1999-04-17 08:37:12 +08:00
|
|
|
#include <stdlib.h>
|
* fixed some #if/#ifdef issues
* hand-patched in php3 changes from 3.0.6 to HEAD in these files:
fopen-wrappers.[ch] ext/standard/file.[ch] ext/standard/fsock.[ch]
ext/standard/php3_string.h ext/standard/string.c
* added some new file/socket macros for more readable code:
FP_FGETS(buf,len,sock,fp,issock)
FP_FREAD(buf,len,sock,fp,issock)
FP_FEOF(sock,fp,issock)
FP_FGETC(sock,fp,issock)
1999-06-17 01:06:53 +08:00
|
|
|
#include <stddef.h>
|
|
|
|
#ifdef HAVE_UNISTD_H
|
1999-04-17 08:37:12 +08:00
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
* fixed some #if/#ifdef issues
* hand-patched in php3 changes from 3.0.6 to HEAD in these files:
fopen-wrappers.[ch] ext/standard/file.[ch] ext/standard/fsock.[ch]
ext/standard/php3_string.h ext/standard/string.c
* added some new file/socket macros for more readable code:
FP_FGETS(buf,len,sock,fp,issock)
FP_FREAD(buf,len,sock,fp,issock)
FP_FEOF(sock,fp,issock)
FP_FGETC(sock,fp,issock)
1999-06-17 01:06:53 +08:00
|
|
|
#ifdef HAVE_FCNTL_H
|
|
|
|
# include <fcntl.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_TIME_H
|
|
|
|
# include <sys/time.h>
|
|
|
|
#endif
|
|
|
|
|
1999-04-17 08:37:12 +08:00
|
|
|
#include <sys/types.h>
|
* fixed some #if/#ifdef issues
* hand-patched in php3 changes from 3.0.6 to HEAD in these files:
fopen-wrappers.[ch] ext/standard/file.[ch] ext/standard/fsock.[ch]
ext/standard/php3_string.h ext/standard/string.c
* added some new file/socket macros for more readable code:
FP_FGETS(buf,len,sock,fp,issock)
FP_FREAD(buf,len,sock,fp,issock)
FP_FEOF(sock,fp,issock)
FP_FGETC(sock,fp,issock)
1999-06-17 01:06:53 +08:00
|
|
|
#ifdef HAVE_SYS_SOCKET_H
|
1999-04-17 08:37:12 +08:00
|
|
|
#include <sys/socket.h>
|
|
|
|
#endif
|
2000-02-11 23:59:30 +08:00
|
|
|
#ifdef PHP_WIN32
|
1999-04-17 08:37:12 +08:00
|
|
|
#include <winsock.h>
|
2002-09-05 22:25:07 +08:00
|
|
|
#elif defined(NETWARE)
|
|
|
|
#ifdef NEW_LIBC
|
|
|
|
#ifdef USE_WINSOCK
|
|
|
|
#include <novsock2.h>
|
|
|
|
#else
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <netdb.h>
|
|
|
|
/*#include <sys/socket.h>*/
|
|
|
|
#include <sys/select.h>
|
|
|
|
/*#else
|
|
|
|
#include <sys/socket.h>*/
|
|
|
|
#endif
|
|
|
|
#endif
|
1999-04-17 08:37:12 +08:00
|
|
|
#else
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <netdb.h>
|
2001-01-22 01:29:15 +08:00
|
|
|
#if HAVE_ARPA_INET_H
|
1999-04-17 08:37:12 +08:00
|
|
|
#include <arpa/inet.h>
|
|
|
|
#endif
|
2001-01-22 01:29:15 +08:00
|
|
|
#endif
|
2002-09-05 22:25:07 +08:00
|
|
|
#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
|
1999-04-17 08:37:12 +08:00
|
|
|
#undef AF_UNIX
|
|
|
|
#endif
|
|
|
|
#if defined(AF_UNIX)
|
|
|
|
#include <sys/un.h>
|
|
|
|
#endif
|
1999-08-03 03:59:04 +08:00
|
|
|
#ifdef HAVE_SYS_SELECT_H
|
|
|
|
#include <sys/select.h>
|
|
|
|
#endif
|
1999-04-17 08:37:12 +08:00
|
|
|
|
2001-08-17 14:53:26 +08:00
|
|
|
#ifndef PF_INET
|
|
|
|
#define PF_INET AF_INET
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef PF_UNIX
|
|
|
|
#define PF_UNIX AF_UNIX
|
|
|
|
#endif
|
|
|
|
|
1999-04-17 08:37:12 +08:00
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#include "base64.h"
|
|
|
|
#include "file.h"
|
|
|
|
#include "url.h"
|
|
|
|
#include "fsock.h"
|
|
|
|
|
2001-05-06 02:36:22 +08:00
|
|
|
#include "php_network.h"
|
|
|
|
|
1999-12-02 01:07:25 +08:00
|
|
|
#ifdef ZTS
|
|
|
|
static int fsock_globals_id;
|
1999-04-17 08:37:12 +08:00
|
|
|
#endif
|
|
|
|
|
2000-02-11 23:59:30 +08:00
|
|
|
#ifdef PHP_WIN32
|
1999-04-17 08:37:12 +08:00
|
|
|
#define EWOULDBLOCK WSAEWOULDBLOCK
|
2002-09-05 22:25:07 +08:00
|
|
|
#elif defined(NETWARE)
|
|
|
|
#ifdef USE_WINSOCK
|
|
|
|
#define EWOULDBLOCK WSAEWOULDBLOCK
|
|
|
|
#endif
|
1999-04-17 08:37:12 +08:00
|
|
|
#endif
|
|
|
|
|
2001-02-21 04:52:53 +08:00
|
|
|
/* {{{ php_lookup_hostname */
|
1999-04-17 08:37:12 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Converts a host name to an IP address.
|
2002-10-14 06:01:40 +08:00
|
|
|
* TODO: This looks like unused code suitable for nuking.
|
1999-04-17 08:37:12 +08:00
|
|
|
*/
|
2001-02-21 04:52:53 +08:00
|
|
|
PHPAPI int php_lookup_hostname(const char *addr, struct in_addr *in)
|
1999-04-17 08:37:12 +08:00
|
|
|
{
|
|
|
|
struct hostent *host_info;
|
|
|
|
|
* fixed some #if/#ifdef issues
* hand-patched in php3 changes from 3.0.6 to HEAD in these files:
fopen-wrappers.[ch] ext/standard/file.[ch] ext/standard/fsock.[ch]
ext/standard/php3_string.h ext/standard/string.c
* added some new file/socket macros for more readable code:
FP_FGETS(buf,len,sock,fp,issock)
FP_FREAD(buf,len,sock,fp,issock)
FP_FEOF(sock,fp,issock)
FP_FGETC(sock,fp,issock)
1999-06-17 01:06:53 +08:00
|
|
|
if (!inet_aton(addr, in)) {
|
1999-09-08 02:46:25 +08:00
|
|
|
/* XXX NOT THREAD SAFE */
|
1999-04-17 08:37:12 +08:00
|
|
|
host_info = gethostbyname(addr);
|
|
|
|
if (host_info == 0) {
|
|
|
|
/* Error: unknown host */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
*in = *((struct in_addr *) host_info->h_addr);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* }}} */
|
|
|
|
|
1999-12-18 12:01:20 +08:00
|
|
|
/* {{{ php_fsockopen() */
|
1999-06-16 05:51:00 +08:00
|
|
|
|
2002-03-16 05:03:08 +08:00
|
|
|
static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent)
|
|
|
|
{
|
2002-03-16 09:34:52 +08:00
|
|
|
char *host;
|
2002-03-16 05:03:08 +08:00
|
|
|
int host_len;
|
|
|
|
int port = -1;
|
2002-03-16 09:34:52 +08:00
|
|
|
zval *zerrno = NULL, *zerrstr = NULL;
|
2002-09-25 23:25:12 +08:00
|
|
|
double timeout = FG(default_socket_timeout);
|
1999-07-22 00:12:13 +08:00
|
|
|
unsigned long conv;
|
2002-03-16 05:03:08 +08:00
|
|
|
struct timeval tv;
|
2002-03-16 09:34:52 +08:00
|
|
|
char *hashkey = NULL;
|
|
|
|
php_stream *stream = NULL;
|
2002-07-13 17:26:36 +08:00
|
|
|
int err;
|
2002-09-25 23:25:12 +08:00
|
|
|
|
|
|
|
RETVAL_FALSE;
|
2002-03-16 05:03:08 +08:00
|
|
|
|
2002-10-14 06:01:40 +08:00
|
|
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lzzd", &host, &host_len, &port, &zerrno, &zerrstr, &timeout) == FAILURE) {
|
2002-03-16 05:03:08 +08:00
|
|
|
RETURN_FALSE;
|
1999-04-17 08:37:12 +08:00
|
|
|
}
|
2002-03-16 05:03:08 +08:00
|
|
|
|
|
|
|
|
2002-09-25 23:25:12 +08:00
|
|
|
if (persistent) {
|
|
|
|
spprintf(&hashkey, 0, "pfsockopen__%s:%d", host, port);
|
|
|
|
|
|
|
|
switch(php_stream_from_persistent_id(hashkey, &stream TSRMLS_CC)) {
|
|
|
|
case PHP_STREAM_PERSISTENT_SUCCESS:
|
|
|
|
/* TODO: could check if the socket is still alive here */
|
|
|
|
php_stream_to_zval(stream, return_value);
|
|
|
|
|
|
|
|
/* fall through */
|
|
|
|
case PHP_STREAM_PERSISTENT_FAILURE:
|
|
|
|
efree(hashkey);
|
|
|
|
return;
|
|
|
|
}
|
1999-04-17 08:37:12 +08:00
|
|
|
}
|
2001-04-18 01:06:06 +08:00
|
|
|
|
2002-03-16 05:03:08 +08:00
|
|
|
/* prepare the timeout value for use */
|
|
|
|
conv = (unsigned long) (timeout * 1000000.0);
|
|
|
|
tv.tv_sec = conv / 1000000;
|
|
|
|
tv.tv_usec = conv % 1000000;
|
1999-04-17 08:37:12 +08:00
|
|
|
|
2002-03-16 05:03:08 +08:00
|
|
|
if (zerrno) {
|
|
|
|
zval_dtor(zerrno);
|
|
|
|
ZVAL_LONG(zerrno, 0);
|
|
|
|
}
|
2002-06-11 11:55:28 +08:00
|
|
|
if (zerrstr) {
|
2002-03-16 05:03:08 +08:00
|
|
|
zval_dtor(zerrstr);
|
|
|
|
ZVAL_STRING(zerrno, "", 1);
|
|
|
|
}
|
2001-04-18 01:06:06 +08:00
|
|
|
|
2002-03-17 02:42:42 +08:00
|
|
|
if (port > 0) { /* connect to a host */
|
2002-03-16 05:03:08 +08:00
|
|
|
enum php_sslflags_t { php_ssl_none, php_ssl_v23, php_ssl_tls };
|
2002-03-17 09:58:42 +08:00
|
|
|
enum php_sslflags_t ssl_flags = php_ssl_none;
|
2002-03-16 05:03:08 +08:00
|
|
|
struct {
|
2002-03-16 09:34:52 +08:00
|
|
|
char *proto;
|
2002-03-16 05:03:08 +08:00
|
|
|
int protolen;
|
|
|
|
int socktype;
|
|
|
|
enum php_sslflags_t ssl_flags;
|
|
|
|
/* more flags to be added here */
|
|
|
|
} sockmodes[] = {
|
|
|
|
{ "udp://", 6, SOCK_DGRAM, php_ssl_none },
|
|
|
|
{ "tcp://", 6, SOCK_STREAM, php_ssl_none },
|
|
|
|
{ "ssl://", 6, SOCK_STREAM, php_ssl_v23 },
|
|
|
|
{ "tls://", 6, SOCK_STREAM, php_ssl_tls },
|
|
|
|
/* more modes to be added here */
|
|
|
|
{ NULL, 0, 0 }
|
|
|
|
};
|
|
|
|
int socktype = SOCK_STREAM;
|
|
|
|
int i;
|
|
|
|
|
2002-10-14 06:01:40 +08:00
|
|
|
for (i = 0; sockmodes[i].proto != NULL; i++) {
|
|
|
|
if (strncmp(host, sockmodes[i].proto, sockmodes[i].protolen) == 0) {
|
2002-03-16 05:03:08 +08:00
|
|
|
ssl_flags = sockmodes[i].ssl_flags;
|
|
|
|
socktype = sockmodes[i].socktype;
|
|
|
|
host += sockmodes[i].protolen;
|
|
|
|
break;
|
|
|
|
}
|
1999-04-17 08:37:12 +08:00
|
|
|
}
|
2002-03-16 05:03:08 +08:00
|
|
|
#if !HAVE_OPENSSL_EXT
|
2002-10-14 06:01:40 +08:00
|
|
|
if (ssl_flags != php_ssl_none) {
|
2002-08-24 09:19:28 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "no SSL support in this build");
|
1999-04-17 08:37:12 +08:00
|
|
|
}
|
2002-03-16 05:03:08 +08:00
|
|
|
else
|
|
|
|
#endif
|
2002-09-25 23:25:12 +08:00
|
|
|
stream = php_stream_sock_open_host(host, (unsigned short)port, socktype, &tv, hashkey);
|
2002-07-13 15:10:59 +08:00
|
|
|
|
2002-07-13 17:26:36 +08:00
|
|
|
/* Preserve error */
|
2002-10-14 06:01:40 +08:00
|
|
|
err = php_socket_errno();
|
2002-03-16 05:03:08 +08:00
|
|
|
|
2002-03-17 02:42:42 +08:00
|
|
|
if (stream == NULL) {
|
2002-08-24 09:19:28 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to connect to %s:%d", host, port);
|
2002-03-17 02:42:42 +08:00
|
|
|
}
|
|
|
|
|
2002-03-16 05:03:08 +08:00
|
|
|
#if HAVE_OPENSSL_EXT
|
2002-10-14 06:01:40 +08:00
|
|
|
if (stream && ssl_flags != php_ssl_none) {
|
2002-03-16 05:03:08 +08:00
|
|
|
int ssl_ret = FAILURE;
|
|
|
|
switch(ssl_flags) {
|
|
|
|
case php_ssl_v23:
|
2002-09-13 05:52:09 +08:00
|
|
|
ssl_ret = php_stream_sock_ssl_activate_with_method(stream, 1, SSLv23_client_method(), NULL TSRMLS_CC);
|
2002-03-16 05:03:08 +08:00
|
|
|
break;
|
|
|
|
case php_ssl_tls:
|
2002-09-13 05:52:09 +08:00
|
|
|
ssl_ret = php_stream_sock_ssl_activate_with_method(stream, 1, TLSv1_client_method(), NULL TSRMLS_CC);
|
2002-03-16 05:03:08 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* unknown ?? */
|
2002-08-20 19:18:18 +08:00
|
|
|
break;
|
1999-04-17 08:37:12 +08:00
|
|
|
}
|
2002-03-16 05:03:08 +08:00
|
|
|
if (ssl_ret == FAILURE)
|
2002-08-24 09:19:28 +08:00
|
|
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to activate SSL mode %d", ssl_flags);
|
1999-04-17 08:37:12 +08:00
|
|
|
}
|
2002-03-16 05:03:08 +08:00
|
|
|
#endif
|
|
|
|
|
2002-10-14 06:01:40 +08:00
|
|
|
} else {
|
|
|
|
/* FIXME: Win32 - this probably does not return sensible errno and errstr */
|
2002-09-25 23:25:12 +08:00
|
|
|
stream = php_stream_sock_open_unix(host, host_len, hashkey, &tv);
|
2002-10-14 06:01:40 +08:00
|
|
|
err = php_socket_errno();
|
|
|
|
}
|
2001-04-18 01:06:06 +08:00
|
|
|
|
2002-09-25 23:25:12 +08:00
|
|
|
if (hashkey)
|
|
|
|
efree(hashkey);
|
2002-03-16 05:03:08 +08:00
|
|
|
|
|
|
|
if (stream == NULL) {
|
2002-06-11 11:55:28 +08:00
|
|
|
if (zerrno) {
|
2002-03-16 05:03:08 +08:00
|
|
|
zval_dtor(zerrno);
|
2002-06-11 11:55:28 +08:00
|
|
|
ZVAL_LONG(zerrno, err);
|
2002-03-16 05:03:08 +08:00
|
|
|
}
|
2002-06-11 11:55:28 +08:00
|
|
|
if (zerrstr) {
|
2002-10-14 06:01:40 +08:00
|
|
|
char *buf = php_socket_strerror(err, NULL, 0);
|
1999-04-17 08:37:12 +08:00
|
|
|
|
2002-10-14 06:01:40 +08:00
|
|
|
/* no need to dup; we would only need to efree buf anyway */
|
|
|
|
ZVAL_STRING(zerrstr, buf, 0);
|
2002-06-11 11:55:28 +08:00
|
|
|
}
|
2002-03-16 05:03:08 +08:00
|
|
|
RETURN_FALSE;
|
1999-04-17 08:37:12 +08:00
|
|
|
}
|
2002-03-16 05:03:08 +08:00
|
|
|
|
2002-03-20 22:21:30 +08:00
|
|
|
php_stream_to_zval(stream, return_value);
|
1999-04-17 08:37:12 +08:00
|
|
|
}
|
2002-03-16 05:03:08 +08:00
|
|
|
|
1999-04-17 08:37:12 +08:00
|
|
|
/* }}} */
|
|
|
|
|
2001-09-22 05:59:27 +08:00
|
|
|
/* {{{ proto int fsockopen(string hostname, int port [, int errno [, string errstr [, float timeout]]])
|
1999-04-17 08:37:12 +08:00
|
|
|
Open Internet or Unix domain socket connection */
|
2001-04-18 01:06:06 +08:00
|
|
|
PHP_FUNCTION(fsockopen)
|
1999-04-17 08:37:12 +08:00
|
|
|
{
|
2002-03-16 05:03:08 +08:00
|
|
|
php_fsockopen_stream(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
|
1999-04-17 08:37:12 +08:00
|
|
|
}
|
|
|
|
/* }}} */
|
2001-09-22 05:59:27 +08:00
|
|
|
/* {{{ proto int pfsockopen(string hostname, int port [, int errno [, string errstr [, float timeout]]])
|
1999-04-17 08:37:12 +08:00
|
|
|
Open persistent Internet or Unix domain socket connection */
|
2001-04-18 01:06:06 +08:00
|
|
|
PHP_FUNCTION(pfsockopen)
|
1999-04-17 08:37:12 +08:00
|
|
|
{
|
2002-03-16 05:03:08 +08:00
|
|
|
php_fsockopen_stream(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
|
2001-04-18 01:06:06 +08:00
|
|
|
}
|
|
|
|
/* }}} */
|
2001-06-06 21:06:12 +08:00
|
|
|
|
2002-03-16 05:03:08 +08:00
|
|
|
/* {{{ RSHUTDOWN_FUNCTION(fsock) */
|
1999-07-27 04:09:08 +08:00
|
|
|
PHP_RSHUTDOWN_FUNCTION(fsock)
|
1999-04-17 08:37:12 +08:00
|
|
|
{
|
|
|
|
return SUCCESS;
|
|
|
|
}
|
2001-05-06 02:36:22 +08:00
|
|
|
/* }}} */
|
1999-04-17 08:37:12 +08:00
|
|
|
/*
|
|
|
|
* Local variables:
|
|
|
|
* tab-width: 4
|
|
|
|
* c-basic-offset: 4
|
|
|
|
* End:
|
2001-09-09 21:29:31 +08:00
|
|
|
* vim600: sw=4 ts=4 fdm=marker
|
|
|
|
* vim<600: sw=4 ts=4
|
1999-04-17 08:37:12 +08:00
|
|
|
*/
|