xref: /PHP-7.3/ext/standard/fsock.c (revision 8d3f8ca1)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 7                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2018 The PHP Group                                |
6    +----------------------------------------------------------------------+
7    | This source file is subject to version 3.01 of the PHP license,      |
8    | that is bundled with this package in the file LICENSE, and is        |
9    | available through the world-wide-web at the following url:           |
10    | http://www.php.net/license/3_01.txt                                  |
11    | If you did not receive a copy of the PHP license and are unable to   |
12    | obtain it through the world-wide-web, please send a note to          |
13    | license@php.net so we can mail you a copy immediately.               |
14    +----------------------------------------------------------------------+
15    | Authors: Paul Panotzki - Bunyip Information Systems                  |
16    |          Jim Winstead <jimw@php.net>                                 |
17    |          Sascha Schumann <sascha@schumann.cx>                        |
18    +----------------------------------------------------------------------+
19 */
20 
21 #include "php.h"
22 #include "php_globals.h"
23 #include <stdlib.h>
24 #include <stddef.h>
25 #include "php_network.h"
26 #include "file.h"
27 
28 /* {{{ php_fsockopen() */
29 
php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS,int persistent)30 static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent)
31 {
32 	char *host;
33 	size_t host_len;
34 	zend_long port = -1;
35 	zval *zerrno = NULL, *zerrstr = NULL;
36 	double timeout = (double)FG(default_socket_timeout);
37 #ifndef PHP_WIN32
38 	time_t conv;
39 #else
40 	long conv;
41 #endif
42 	struct timeval tv;
43 	char *hashkey = NULL;
44 	php_stream *stream = NULL;
45 	int err;
46 	char *hostname = NULL;
47 	size_t hostname_len;
48 	zend_string *errstr = NULL;
49 
50 	RETVAL_FALSE;
51 
52 	ZEND_PARSE_PARAMETERS_START(1, 5)
53 		Z_PARAM_STRING(host, host_len)
54 		Z_PARAM_OPTIONAL
55 		Z_PARAM_LONG(port)
56 		Z_PARAM_ZVAL_DEREF(zerrno)
57 		Z_PARAM_ZVAL_DEREF(zerrstr)
58 		Z_PARAM_DOUBLE(timeout)
59 	ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
60 
61 	if (persistent) {
62 		spprintf(&hashkey, 0, "pfsockopen__%s:" ZEND_LONG_FMT, host, port);
63 	}
64 
65 	if (port > 0) {
66 		hostname_len = spprintf(&hostname, 0, "%s:" ZEND_LONG_FMT, host, port);
67 	} else {
68 		hostname_len = host_len;
69 		hostname = host;
70 	}
71 
72 	/* prepare the timeout value for use */
73 #ifndef PHP_WIN32
74 	conv = (time_t) (timeout * 1000000.0);
75 	tv.tv_sec = conv / 1000000;
76 #else
77 	conv = (long) (timeout * 1000000.0);
78 	tv.tv_sec = conv / 1000000;
79 #endif
80 	tv.tv_usec = conv % 1000000;
81 
82 	if (zerrno)	{
83 		zval_ptr_dtor(zerrno);
84 		ZVAL_LONG(zerrno, 0);
85 	}
86 	if (zerrstr) {
87 		zval_ptr_dtor(zerrstr);
88 		ZVAL_EMPTY_STRING(zerrstr);
89 	}
90 
91 	stream = php_stream_xport_create(hostname, hostname_len, REPORT_ERRORS,
92 			STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT, hashkey, &tv, NULL, &errstr, &err);
93 
94 	if (port > 0) {
95 		efree(hostname);
96 	}
97 	if (stream == NULL) {
98 		php_error_docref(NULL, E_WARNING, "unable to connect to %s:" ZEND_LONG_FMT " (%s)", host, port, errstr == NULL ? "Unknown error" : ZSTR_VAL(errstr));
99 	}
100 
101 	if (hashkey) {
102 		efree(hashkey);
103 	}
104 
105 	if (stream == NULL)	{
106 		if (zerrno) {
107 			zval_ptr_dtor(zerrno);
108 			ZVAL_LONG(zerrno, err);
109 		}
110 		if (zerrstr && errstr) {
111 			/* no need to dup; we need to efree buf anyway */
112 			zval_ptr_dtor(zerrstr);
113 			ZVAL_STR(zerrstr, errstr);
114 		} else if (!zerrstr && errstr) {
115 			zend_string_release_ex(errstr, 0);
116 		}
117 
118 		RETURN_FALSE;
119 	}
120 
121 	if (errstr) {
122 		zend_string_release_ex(errstr, 0);
123 	}
124 
125 	php_stream_to_zval(stream, return_value);
126 }
127 
128 /* }}} */
129 
130 /* {{{ proto resource fsockopen(string hostname, int port [, int errno [, string errstr [, float timeout]]])
131    Open Internet or Unix domain socket connection */
PHP_FUNCTION(fsockopen)132 PHP_FUNCTION(fsockopen)
133 {
134 	php_fsockopen_stream(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
135 }
136 /* }}} */
137 
138 /* {{{ proto resource pfsockopen(string hostname, int port [, int errno [, string errstr [, float timeout]]])
139    Open persistent Internet or Unix domain socket connection */
PHP_FUNCTION(pfsockopen)140 PHP_FUNCTION(pfsockopen)
141 {
142 	php_fsockopen_stream(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
143 }
144 /* }}} */
145 
146 /*
147  * Local variables:
148  * tab-width: 4
149  * c-basic-offset: 4
150  * End:
151  * vim600: sw=4 ts=4 fdm=marker
152  * vim<600: sw=4 ts=4
153  */
154