/*
* Converts a host name to an IP address.
+ * TODO: This looks like unused code suitable for nuking.
*/
PHPAPI int php_lookup_hostname(const char *addr, struct in_addr *in)
{
struct timeval tv;
char *hashkey = NULL;
php_stream *stream = NULL;
-#ifdef PHP_WIN32
int err;
-#endif
RETVAL_FALSE;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lzzd", &host, &host_len, &port, &zerrno, &zerrstr, &timeout) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lzzd", &host, &host_len, &port, &zerrno, &zerrstr, &timeout) == FAILURE) {
RETURN_FALSE;
}
int socktype = SOCK_STREAM;
int i;
- for (i = 0; sockmodes[i].proto != NULL; i++) {
- if (strncmp(host, sockmodes[i].proto, sockmodes[i].protolen) == 0) {
+ 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;
}
}
#if !HAVE_OPENSSL_EXT
- if (ssl_flags != php_ssl_none) {
+ 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);
-#ifdef PHP_WIN32
/* Preserve error */
- err = WSAGetLastError();
-#endif
+ err = php_socket_errno();
if (stream == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to connect to %s:%d", host, port);
}
#if HAVE_OPENSSL_EXT
- if (stream && ssl_flags != php_ssl_none) {
+ if (stream && ssl_flags != php_ssl_none) {
int ssl_ret = FAILURE;
switch(ssl_flags) {
case php_ssl_v23:
}
#endif
- } else
+ } 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);
-#ifndef PHP_WIN32
- ZVAL_LONG(zerrno, errno);
-#else
ZVAL_LONG(zerrno, err);
-#endif
}
-#ifndef PHP_WIN32
if (zerrstr) {
- zval_dtor(zerrstr);
- ZVAL_STRING(zerrstr, strerror(errno), 1);
- }
-#else
- if (zerrstr) {
- char *buf;
+ char *buf = php_socket_strerror(err, NULL, 0);
- if (! FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
- Z_LVAL_P(zerrno), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buf, 0, NULL)) {
- RETURN_FALSE;
- }
-
- ZVAL_STRING(zerrstr, buf, 1);
- LocalFree(buf);
+ /* no need to dup; we would only need to efree buf anyway */
+ ZVAL_STRING(zerrstr, buf, 0);
}
-#endif
RETURN_FALSE;
}
}
/* }}} */
+PHPAPI char *php_socket_strerror(long err, char *buf, size_t bufsize)
+{
+#ifndef PHP_WIN32
+ char *errstr;
+
+ errstr = strerror(err);
+ if (buf == NULL) {
+ buf = estrdup(errstr);
+ } else {
+ strncpy(buf, errstr, bufsize);
+ }
+ return buf;
+#else
+ char *sysbuf;
+ int free_it = 1;
+
+ if (!FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ err,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)&sysbuf,
+ 0,
+ NULL)) {
+ free_it = 0;
+ sysbuf = "Unknown Error";
+ }
+
+ if (buf == NULL) {
+ buf = estrdup(sysbuf);
+ } else {
+ strncpy(buf, sysbuf, bufsize);
+ }
+
+ if (free_it) {
+ LocalFree(sysbuf);
+ }
+
+ return buf;
+#endif
+}
+
PHPAPI php_stream *_php_stream_sock_open_from_socket(int socket, const char *persistent_id STREAMS_DC TSRMLS_DC)
{
php_stream *stream;
size_t didwrite;
#if HAVE_OPENSSL_EXT
- if (sock->ssl_active)
+ if (sock->ssl_active) {
didwrite = SSL_write(sock->ssl_handle, buf, count);
- else
+ } else
#endif
- didwrite = send(sock->socket, buf, count, 0);
+ {
+ didwrite = send(sock->socket, buf, count, 0);
+
+ if (didwrite <= 0) {
+ char *estr = php_socket_strerror(php_socket_errno(), NULL, 0);
+
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "send of %d bytes failed with errno=%d %s",
+ count, php_socket_errno(), estr);
+ efree(estr);
+ }
+ }
php_stream_notify_progress_increment(stream->context, didwrite, 0);
php_stream_notify_progress_increment(stream->context, nr_bytes, 0);
- if(nr_bytes == 0 || (nr_bytes < 0 && streams_socket_errno != EWOULDBLOCK)) {
+ if(nr_bytes == 0 || (nr_bytes < 0 && php_socket_errno() != EWOULDBLOCK)) {
stream->eof = 1;
}
#endif /* defined(PHP_WIN32) */
#ifdef PHP_WIN32
-#define streams_socket_errno WSAGetLastError()
+#define php_socket_errno() WSAGetLastError()
#else
-#define streams_socket_errno errno
+#define php_socket_errno() errno
#endif
+/* like strerror, but caller must efree the returned string,
+ * unless buf is not NULL.
+ * Also works sensibly for win32 */
+PHPAPI char *php_socket_strerror(long err, char *buf, size_t bufsize);
+
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif