Beispiel #1
0
/* {{{ dba_close
 */
static void dba_close(dba_info *info)
{
	if (info->hnd) {
		info->hnd->close(info);
	}
	if (info->path) {
		pefree(info->path, info->flags&DBA_PERSISTENT);
	}
	if (info->fp && info->fp != info->lock.fp) {
		if (info->flags & DBA_PERSISTENT) {
			php_stream_pclose(info->fp);
		} else {
			php_stream_close(info->fp);
		}
	}
	if (info->lock.fp) {
		if (info->flags & DBA_PERSISTENT) {
			php_stream_pclose(info->lock.fp);
		} else {
			php_stream_close(info->lock.fp);
		}
	}
	if (info->lock.name) {
		pefree(info->lock.name, info->flags&DBA_PERSISTENT);
	}
	pefree(info, info->flags&DBA_PERSISTENT);
}
Beispiel #2
0
static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent)
{
	char *host;
	int host_len;
	long port = -1;
	zval *zerrno = NULL, *zerrstr = NULL, *zcontext = NULL;
	double timeout = FG(default_socket_timeout);
	unsigned long conv;
	struct timeval tv;
	char *hashkey = NULL;
	php_stream *stream = NULL;
	php_stream_context *context = NULL;
	int err;

	RETVAL_FALSE;
	
	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lzzdr", &host, &host_len, &port, &zerrno, &zerrstr, &timeout, &zcontext) == FAILURE) {
		RETURN_FALSE;
	}
	if (zcontext) {
		ZEND_FETCH_RESOURCE(context, php_stream_context*, &zcontext, -1, "stream-context", php_le_stream_context());
	}

	if (persistent) {
		spprintf(&hashkey, 0, "pfsockopen__%s:%ld", host, port);

		switch(php_stream_from_persistent_id(hashkey, &stream TSRMLS_CC)) {
			case PHP_STREAM_PERSISTENT_SUCCESS:
				if (_php_network_is_stream_alive(stream TSRMLS_CC)) {
					php_stream_to_zval(stream, return_value);
				} else {
					/* it died; we need to replace it */
					php_stream_pclose(stream);
					break;
				}
				
				/* fall through */
			case PHP_STREAM_PERSISTENT_FAILURE:
				efree(hashkey);
				return;
		}
	}

	/* prepare the timeout value for use */
	conv = (unsigned long) (timeout * 1000000.0);
	tv.tv_sec = conv / 1000000;
	tv.tv_usec = conv % 1000000;

	if (zerrno)	{
		zval_dtor(zerrno);
		ZVAL_LONG(zerrno, 0);
	}
	if (zerrstr) {
		zval_dtor(zerrstr);
		ZVAL_STRING(zerrstr, "", 1);
	}

	if (port > 0)	{ /* connect to a host */
		enum php_sslflags_t { php_ssl_none, php_ssl_v23, php_ssl_tls };
		enum php_sslflags_t ssl_flags = php_ssl_none;
		struct {
			char *proto;
			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;

		for (i = 0; sockmodes[i].proto != NULL; i++) {
			if (strncmp(host, sockmodes[i].proto, sockmodes[i].protolen) == 0) {
				ssl_flags = sockmodes[i].ssl_flags;		
				socktype = sockmodes[i].socktype;
				host += sockmodes[i].protolen;
				break;
			}
		}
#ifndef HAVE_OPENSSL_EXT
		if (ssl_flags != php_ssl_none) {
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "no SSL support in this build");
		}
		else
#endif
		stream = php_stream_sock_open_host(host, (unsigned short)port, socktype, &tv, hashkey);

		/* Preserve error */
		err = php_socket_errno();

		if (stream == NULL) {
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to connect to %s:%ld", host, port);
		} else if (context) {
			php_stream_context_set(stream, context);
		}
		
#ifdef HAVE_OPENSSL_EXT
		if (stream && ssl_flags != php_ssl_none) {
			int ssl_ret = FAILURE;
			switch(ssl_flags)	{
				case php_ssl_v23:
					ssl_ret = php_stream_sock_ssl_activate_with_method(stream, 1, SSLv23_client_method(), NULL TSRMLS_CC);
					break;
				case php_ssl_tls:
					ssl_ret = php_stream_sock_ssl_activate_with_method(stream, 1, TLSv1_client_method(), NULL TSRMLS_CC);
					break;
				default:
					/* unknown ?? */
					break;
			}
			if (ssl_ret == FAILURE) {
				php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to activate SSL mode %d", ssl_flags);
				php_stream_close(stream);
				stream = NULL;
			}
		}
#endif
		
	} else {
		/* FIXME: Win32 - this probably does not return sensible errno and errstr */
		stream = php_stream_sock_open_unix(host, host_len, hashkey, &tv);
		err = php_socket_errno();
	}

	if (hashkey)
		efree(hashkey);
	
	if (stream == NULL)	{
		if (zerrno) {
			zval_dtor(zerrno);
			ZVAL_LONG(zerrno, err);
		}
		if (zerrstr) {
			char *buf = php_socket_strerror(err, NULL, 0);

			/* no need to dup; we would only need to efree buf anyway */
			zval_dtor(zerrstr);
			ZVAL_STRING(zerrstr, buf, 0);
		}
		RETURN_FALSE;
	}
	
	if (zcontext) {
		zend_list_addref(Z_RESVAL_P(zcontext));
	}
	php_stream_to_zval(stream, return_value);
}