cvs: php4 /ext/sockets sockets.c
| From: | Chris Vandomelen | Date: | Wed, 23 Aug 2000 06:41:52 +0000 |
| Subject: | cvs: php4 /ext/sockets sockets.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-1334@lists.php.net to get a copy of this message | ||
chrisv Tue Aug 22 23:41:52 2000 EDT
Modified files:
/php4/ext/sockets sockets.c
Log:
Corrected bugs in php_if_connect() to make it work properly -- needed to
run htons() on the port number provided, and needed to perform DNS lookups
properly and store the results as expected.
Index: php4/ext/sockets/sockets.c
diff -u php4/ext/sockets/sockets.c:1.6 php4/ext/sockets/sockets.c:1.7
--- php4/ext/sockets/sockets.c:1.6 Sun Aug 20 12:48:42 2000
+++ php4/ext/sockets/sockets.c Tue Aug 22 23:41:51 2000
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: sockets.c,v 1.6 2000/08/20 19:48:42 chrisv Exp $ */
+/* $Id: sockets.c,v 1.7 2000/08/23 06:41:51 chrisv Exp $ */
#include "php.h"
@@ -99,11 +99,11 @@
*/
PHP_FE(signal, NULL)
#endif
-#if 0
/*
* These are defined elsewhere..
* would these be more appropriate?
*/
+#if 0
PHP_FE(gethostbyname, second_arg_force_ref) /* OK */
PHP_FE(gethostbyaddr, second_arg_force_ref) /* OK */
#endif
@@ -656,10 +656,10 @@
}
/* }}} */
-#if 0
/* {{{ proto int gethostbyname(string name, string &addr)
Given a hostname, sets addr to be a human-readable version of the host's address */
+#if 0
/* Another lock to prevent multiple threads from grabbing gethostbyname() */
volatile int gethostbyname_lock = 0;
@@ -669,6 +669,7 @@
int ret;
char *tmp, *addr_string;
struct hostent *host_struct;
+ struct in_addr a;
if (ZEND_NUM_ARGS() != 2 ||
zend_get_parameters_ex(2, &name, &addr) == FAILURE) {
@@ -692,7 +693,8 @@
while (inet_ntoa_lock == 1);
inet_ntoa_lock = 1;
- addr_string = inet_ntoa((struct in_addr) host_struct->h_addr);
+ a.s_addr = (int) (*(host_struct->h_addr_list[0]));
+ addr_string = inet_ntoa(a);
tmp = emalloc(strlen(addr_string) + 1);
strncpy(tmp, addr_string, strlen(addr_string));
@@ -751,10 +753,10 @@
}
/* }}} */
-#if 0
/* {{{ proto int gethostbyaddr(string addr, string &name)
Given a human-readable address, sets name to be the host's name */
+#if 0
/* Another lock to prevent multiple threads from grabbing gethostbyname() */
volatile int gethostbyaddr_lock = 0;
@@ -782,7 +784,7 @@
while (gethostbyaddr_lock == 1);
gethostbyaddr_lock = 1;
- host_struct = gethostbyname((char *)&addr_buf, sizeof(addr_buf), AF_INET);
+ host_struct = gethostbyaddr((char *)&addr_buf, sizeof(addr_buf), AF_INET);
if (!host_struct) {
gethostbyaddr_lock = 0;
@@ -837,39 +839,75 @@
}
/* }}} */
-/* {{{ proto int connect(int sockfd, string addr, int port)
+/* {{{ proto int connect(int sockfd, string addr [, int port])
Opens a connection to addr:port on the socket specified by sockfd */
PHP_FUNCTION(connect)
{
zval **sockfd, **addr, **port;
- struct sockaddr_in sa;
+ struct sockaddr sa;
+ struct sockaddr_in *sin;
+ struct sockaddr_un *sun;
int salen = sizeof(sa);
int ret;
struct in_addr addr_buf;
struct hostent *host_struct;
+ int args;
- if (ZEND_NUM_ARGS() != 3 ||
- zend_get_parameters_ex(3, &sockfd, &addr, &port) == FAILURE) {
+ args = ZEND_NUM_ARGS();
+
+ if (args < 2) {
WRONG_PARAM_COUNT;
}
- v_convert_to_long_ex(2, sockfd, port);
+
+ ret = zend_get_parameters_ex(args, &sockfd, &addr, &port);
+ if (ret == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ convert_to_long_ex(sockfd)
convert_to_string_ex(addr);
+ if (args > 2) {
+ convert_to_long_ex(port);
+ }
bzero(&sa, sizeof(sa));
- sa.sin_port = Z_LVAL_PP(port);
- if (inet_aton(Z_STRVAL_PP(addr), &addr_buf) == 0) {
- sa.sin_addr.s_addr = addr_buf.s_addr;
- } else {
- host_struct = gethostbyname(Z_STRVAL_PP(addr));
- if (host_struct->h_addrtype != AF_INET) {
- RETURN_LONG(-EINVAL);
- }
- sa.sin_addr.s_addr = (int) *(host_struct->h_addr_list[0]);
+ ret = getsockname(Z_LVAL_PP(sockfd), &sa, &salen);
+ if (ret < 0) {
+ RETURN_LONG(-errno);
}
- ret = connect(Z_LVAL_PP(sockfd), (struct sockaddr *)&sa, salen);
+ switch(sa.sa_family) {
+ case AF_INET: {
+ sin = &sa;
+ sin->sin_port = htons((unsigned short int) Z_LVAL_PP(port));
+ if (inet_aton(Z_STRVAL_PP(addr), &addr_buf) == 0) {
+ sin->sin_addr.s_addr = addr_buf.s_addr;
+ } else {
+ char *q = (char *) &(sin->sin_addr.s_addr);
+ host_struct = gethostbyname(Z_STRVAL_PP(addr));
+ if (host_struct->h_addrtype != AF_INET) {
+ RETURN_LONG(-EINVAL);
+ }
+ q[0] = host_struct->h_addr_list[0][0];
+ q[1] = host_struct->h_addr_list[0][1];
+ q[2] = host_struct->h_addr_list[0][2];
+ q[3] = host_struct->h_addr_list[0][3];
+ }
+ ret = connect(Z_LVAL_PP(sockfd), (struct sockaddr *) sin, salen);
+ break;
+ }
+ case AF_UNIX: {
+ sun = &sa;
+ snprintf(sun->sun_path, 108, "%s", Z_STRVAL_PP(addr));
+ ret = connect(Z_LVAL_PP(sockfd), (struct sockaddr *) sun, SUN_LEN(sun));
+ break;
+ }
+ default:
+ ret = -1;
+ errno = EINVAL;
+ }
RETURN_LONG(((ret < 0) ? -errno : ret));
}
/* }}} */