1/*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2015 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/* $Id$ */
22
23#include "php.h"
24#include "php_globals.h"
25#include <stdlib.h>
26#include <stddef.h>
27#include "php_network.h"
28#include "file.h"
29
30/* {{{ php_fsockopen() */
31
32static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent)
33{
34 char *host;
35 int host_len;
36 long port = -1;
37 zval *zerrno = NULL, *zerrstr = NULL;
38 double timeout = FG(default_socket_timeout);
39 unsigned long conv;
40 struct timeval tv;
41 char *hashkey = NULL;
42 php_stream *stream = NULL;
43 int err;
44 char *hostname = NULL;
45 long hostname_len;
46 char *errstr = NULL;
47
48 RETVAL_FALSE;
49
50 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lzzd", &host, &host_len, &port, &zerrno, &zerrstr, &timeout) == FAILURE) {
51 RETURN_FALSE;
52 }
53
54 if (persistent) {
55 spprintf(&hashkey, 0, "pfsockopen__%s:%ld", host, port);
56 }
57
58 if (port > 0) {
59 hostname_len = spprintf(&hostname, 0, "%s:%ld", host, port);
60 } else {
61 hostname_len = host_len;
62 hostname = host;
63 }
64
65 /* prepare the timeout value for use */
66 conv = (unsigned long) (timeout * 1000000.0);
67 tv.tv_sec = conv / 1000000;
68 tv.tv_usec = conv % 1000000;
69
70 if (zerrno) {
71 zval_dtor(zerrno);
72 ZVAL_LONG(zerrno, 0);
73 }
74 if (zerrstr) {
75 zval_dtor(zerrstr);
76 ZVAL_STRING(zerrstr, "", 1);
77 }
78
79 stream = php_stream_xport_create(hostname, hostname_len, REPORT_ERRORS,
80 STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT, hashkey, &tv, NULL, &errstr, &err);
81
82 if (port > 0) {
83 efree(hostname);
84 }
85 if (stream == NULL) {
86 php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to connect to %s:%ld (%s)", host, port, errstr == NULL ? "Unknown error" : errstr);
87 }
88
89 if (hashkey) {
90 efree(hashkey);
91 }
92
93 if (stream == NULL) {
94 if (zerrno) {
95 zval_dtor(zerrno);
96 ZVAL_LONG(zerrno, err);
97 }
98 if (zerrstr && errstr) {
99 /* no need to dup; we need to efree buf anyway */
100 zval_dtor(zerrstr);
101 ZVAL_STRING(zerrstr, errstr, 0);
102 }
103 else if (!zerrstr && errstr) {
104 efree(errstr);
105 }
106
107 RETURN_FALSE;
108 }
109
110 if (errstr) {
111 efree(errstr);
112 }
113
114 php_stream_to_zval(stream, return_value);
115}
116
117/* }}} */
118
119/* {{{ proto resource fsockopen(string hostname, int port [, int errno [, string errstr [, float timeout]]])
120 Open Internet or Unix domain socket connection */
121PHP_FUNCTION(fsockopen)
122{
123 php_fsockopen_stream(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
124}
125/* }}} */
126/* {{{ proto resource pfsockopen(string hostname, int port [, int errno [, string errstr [, float timeout]]])
127 Open persistent Internet or Unix domain socket connection */
128PHP_FUNCTION(pfsockopen)
129{
130 php_fsockopen_stream(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
131}
132/* }}} */
133
134/*
135 * Local variables:
136 * tab-width: 4
137 * c-basic-offset: 4
138 * End:
139 * vim600: sw=4 ts=4 fdm=marker
140 * vim<600: sw=4 ts=4
141 */
142