xref: /PHP-7.4/ext/standard/fsock.c (revision e188e417)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 7                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 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(zerrno)
57 		Z_PARAM_ZVAL(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 	stream = php_stream_xport_create(hostname, hostname_len, REPORT_ERRORS,
83 			STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT, hashkey, &tv, NULL, &errstr, &err);
84 
85 	if (port > 0) {
86 		efree(hostname);
87 	}
88 	if (stream == NULL) {
89 		php_error_docref(NULL, E_WARNING, "unable to connect to %s:" ZEND_LONG_FMT " (%s)", host, port, errstr == NULL ? "Unknown error" : ZSTR_VAL(errstr));
90 	}
91 
92 	if (hashkey) {
93 		efree(hashkey);
94 	}
95 
96 	if (stream == NULL) {
97 		if (zerrno) {
98 			ZEND_TRY_ASSIGN_REF_LONG(zerrno, err);
99 		}
100 		if (errstr) {
101 			if (zerrstr) {
102 				ZEND_TRY_ASSIGN_REF_STR(zerrstr, errstr);
103 			} else {
104 				zend_string_release(errstr);
105 			}
106 		}
107 
108 		RETURN_FALSE;
109 	}
110 
111 	if (zerrno) {
112 		ZEND_TRY_ASSIGN_REF_LONG(zerrno, 0);
113 	}
114 	if (zerrstr) {
115 		ZEND_TRY_ASSIGN_REF_EMPTY_STRING(zerrstr);
116 	}
117 
118 	if (errstr) {
119 		zend_string_release_ex(errstr, 0);
120 	}
121 
122 	php_stream_to_zval(stream, return_value);
123 }
124 
125 /* }}} */
126 
127 /* {{{ proto resource fsockopen(string hostname, int port [, int errno [, string errstr [, float timeout]]])
128    Open Internet or Unix domain socket connection */
PHP_FUNCTION(fsockopen)129 PHP_FUNCTION(fsockopen)
130 {
131 	php_fsockopen_stream(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
132 }
133 /* }}} */
134 
135 /* {{{ proto resource pfsockopen(string hostname, int port [, int errno [, string errstr [, float timeout]]])
136    Open persistent Internet or Unix domain socket connection */
PHP_FUNCTION(pfsockopen)137 PHP_FUNCTION(pfsockopen)
138 {
139 	php_fsockopen_stream(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
140 }
141 /* }}} */
142