aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Monnerat <patrick@monnerat.net>2019-08-11 17:22:45 +0200
committerPatrick Monnerat <patrick@monnerat.net>2019-09-24 13:39:22 +0200
commit3e0a8e539c57b9bed8265b38c2c3007cab6040e3 (patch)
treeb8fd78fe050087e8ebe25c97c356f6cf241d8328
parent4a778f75c526e638b2fe1e2f627eb6649638b570 (diff)
os400: getpeername() and getsockname() return ebcdic AF_UNIX sockaddr,
As libcurl now uses these 2 system functions, wrappers are needed on os400 to convert returned AF_UNIX sockaddrs to ascii. This is a follow-up to commit 7fb54ef. See also #4037. Closes #4214
-rw-r--r--lib/setup-os400.h6
-rw-r--r--packages/OS400/os400sys.c156
2 files changed, 107 insertions, 55 deletions
diff --git a/lib/setup-os400.h b/lib/setup-os400.h
index a3c2a7bdc..629fd94c4 100644
--- a/lib/setup-os400.h
+++ b/lib/setup-os400.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -206,11 +206,15 @@ extern int Curl_os400_sendto(int sd, char *buffer, int buflen, int flags,
struct sockaddr * dstaddr, int addrlen);
extern int Curl_os400_recvfrom(int sd, char *buffer, int buflen, int flags,
struct sockaddr *fromaddr, int *addrlen);
+extern int Curl_os400_getpeername(int sd, struct sockaddr *addr, int *addrlen);
+extern int Curl_os400_getsockname(int sd, struct sockaddr *addr, int *addrlen);
#define connect Curl_os400_connect
#define bind Curl_os400_bind
#define sendto Curl_os400_sendto
#define recvfrom Curl_os400_recvfrom
+#define getpeername Curl_os400_getpeername
+#define getsockname Curl_os400_getsockname
#ifdef HAVE_LIBZ
#define zlibVersion Curl_os400_zlibVersion
diff --git a/packages/OS400/os400sys.c b/packages/OS400/os400sys.c
index 67b34a84c..3490fc779 100644
--- a/packages/OS400/os400sys.c
+++ b/packages/OS400/os400sys.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -195,7 +195,7 @@ buffer_threaded(localkey_t key, long size)
/* Allocate buffer descriptors for the current thread. */
- bufs = calloc((size_t) LK_LAST, sizeof *bufs);
+ bufs = calloc((size_t) LK_LAST, sizeof(*bufs));
if(!bufs)
return (char *) NULL;
@@ -224,7 +224,7 @@ buffer_undef(localkey_t key, long size)
if(Curl_thread_buffer == buffer_undef) { /* If unchanged during lock. */
if(!pthread_key_create(&thdkey, thdbufdestroy))
Curl_thread_buffer = buffer_threaded;
- else if(!(locbufs = calloc((size_t) LK_LAST, sizeof *locbufs))) {
+ else if(!(locbufs = calloc((size_t) LK_LAST, sizeof(*locbufs)))) {
pthread_mutex_unlock(&mutex);
return (char *) NULL;
}
@@ -390,7 +390,7 @@ Curl_gsk_environment_open(gsk_handle * my_env_handle)
if(!my_env_handle)
return GSK_OS400_ERROR_INVALID_POINTER;
- p = (struct Curl_gsk_descriptor *) malloc(sizeof *p);
+ p = (struct Curl_gsk_descriptor *) malloc(sizeof(*p));
if(!p)
return GSK_INSUFFICIENT_STORAGE;
p->strlist = (struct gskstrlist *) NULL;
@@ -417,7 +417,7 @@ Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
if(!my_session_handle)
return GSK_OS400_ERROR_INVALID_POINTER;
h = ((struct Curl_gsk_descriptor *) my_env_handle)->h;
- p = (struct Curl_gsk_descriptor *) malloc(sizeof *p);
+ p = (struct Curl_gsk_descriptor *) malloc(sizeof(*p));
if(!p)
return GSK_INSUFFICIENT_STORAGE;
p->strlist = (struct gskstrlist *) NULL;
@@ -598,7 +598,7 @@ cachestring(struct Curl_gsk_descriptor * p,
if(sp->ebcdicstr == ebcdicbuf)
break;
if(!sp) {
- sp = (struct gskstrlist *) malloc(sizeof *sp);
+ sp = (struct gskstrlist *) malloc(sizeof(*sp));
if(!sp)
return GSK_INSUFFICIENT_STORAGE;
asciibuf = malloc(bufsize + 1);
@@ -800,7 +800,7 @@ Curl_gss_import_name_a(OM_uint32 * minor_status, gss_buffer_t in_name,
if(!in_name || !in_name->value || !in_name->length)
return gss_import_name(minor_status, in_name, in_name_type, out_name);
- memcpy((char *) &in, (char *) in_name, sizeof in);
+ memcpy((char *) &in, (char *) in_name, sizeof(in));
i = in.length;
in.value = malloc(i + 1);
@@ -1048,7 +1048,7 @@ Curl_ldap_search_s_a(void * ld, char * base, int scope, char * filter,
for(i = 0; attrs[i++];)
;
- eattrs = calloc(i, sizeof *eattrs);
+ eattrs = calloc(i, sizeof(*eattrs));
if(!eattrs)
status = LDAP_NO_MEMORY;
else {
@@ -1227,19 +1227,18 @@ Curl_ldap_next_attribute_a(void * ld,
static int
-convert_sockaddr(struct sockaddr_storage * dstaddr,
- const struct sockaddr * srcaddr, int srclen)
-
+sockaddr2ebcdic(struct sockaddr_storage *dstaddr,
+ const struct sockaddr *srcaddr, int srclen)
{
- const struct sockaddr_un * srcu;
- struct sockaddr_un * dstu;
+ const struct sockaddr_un *srcu;
+ struct sockaddr_un *dstu;
unsigned int i;
unsigned int dstsize;
- /* Convert a socket address into job CCSID, if needed. */
+ /* Convert a socket address to job CCSID, if needed. */
if(!srcaddr || srclen < offsetof(struct sockaddr, sa_family) +
- sizeof srcaddr->sa_family || srclen > sizeof *dstaddr) {
+ sizeof(srcaddr->sa_family) || srclen > sizeof(*dstaddr)) {
errno = EINVAL;
return -1;
}
@@ -1251,26 +1250,67 @@ convert_sockaddr(struct sockaddr_storage * dstaddr,
case AF_UNIX:
srcu = (const struct sockaddr_un *) srcaddr;
dstu = (struct sockaddr_un *) dstaddr;
- dstsize = sizeof *dstaddr - offsetof(struct sockaddr_un, sun_path);
+ dstsize = sizeof(*dstaddr) - offsetof(struct sockaddr_un, sun_path);
srclen -= offsetof(struct sockaddr_un, sun_path);
i = QadrtConvertA2E(dstu->sun_path, srcu->sun_path, dstsize - 1, srclen);
dstu->sun_path[i] = '\0';
- i += offsetof(struct sockaddr_un, sun_path);
- srclen = i;
+ srclen = i + offsetof(struct sockaddr_un, sun_path);
+ }
+
+ return srclen;
+}
+
+
+static int
+sockaddr2ascii(struct sockaddr *dstaddr, int dstlen,
+ const struct sockaddr_storage *srcaddr, int srclen)
+{
+ const struct sockaddr_un *srcu;
+ struct sockaddr_un *dstu;
+ unsigned int dstsize;
+
+ /* Convert a socket address to ASCII, if needed. */
+
+ if(!srclen)
+ return 0;
+ if(srclen > dstlen)
+ srclen = dstlen;
+ if(!srcaddr || srclen < 0) {
+ errno = EINVAL;
+ return -1;
}
+ memcpy((char *) dstaddr, (char *) srcaddr, srclen);
+
+ if(srclen >= offsetof(struct sockaddr_storage, ss_family) +
+ sizeof(srcaddr->ss_family)) {
+ switch (srcaddr->ss_family) {
+
+ case AF_UNIX:
+ srcu = (const struct sockaddr_un *) srcaddr;
+ dstu = (struct sockaddr_un *) dstaddr;
+ dstsize = dstlen - offsetof(struct sockaddr_un, sun_path);
+ srclen -= offsetof(struct sockaddr_un, sun_path);
+ if(dstsize > 0 && srclen > 0) {
+ srclen = QadrtConvertE2A(dstu->sun_path, srcu->sun_path,
+ dstsize - 1, srclen);
+ dstu->sun_path[srclen] = '\0';
+ }
+ srclen += offsetof(struct sockaddr_un, sun_path);
+ }
+ }
+
return srclen;
}
int
Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen)
-
{
int i;
struct sockaddr_storage laddr;
- i = convert_sockaddr(&laddr, destaddr, addrlen);
+ i = sockaddr2ebcdic(&laddr, destaddr, addrlen);
if(i < 0)
return -1;
@@ -1281,12 +1321,11 @@ Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen)
int
Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen)
-
{
int i;
struct sockaddr_storage laddr;
- i = convert_sockaddr(&laddr, localaddr, addrlen);
+ i = sockaddr2ebcdic(&laddr, localaddr, addrlen);
if(i < 0)
return -1;
@@ -1298,12 +1337,11 @@ Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen)
int
Curl_os400_sendto(int sd, char * buffer, int buflen, int flags,
struct sockaddr * dstaddr, int addrlen)
-
{
int i;
struct sockaddr_storage laddr;
- i = convert_sockaddr(&laddr, dstaddr, addrlen);
+ i = sockaddr2ebcdic(&laddr, dstaddr, addrlen);
if(i < 0)
return -1;
@@ -1315,19 +1353,14 @@ Curl_os400_sendto(int sd, char * buffer, int buflen, int flags,
int
Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
struct sockaddr * fromaddr, int * addrlen)
-
{
- int i;
int rcvlen;
- int laddrlen;
- const struct sockaddr_un * srcu;
- struct sockaddr_un * dstu;
struct sockaddr_storage laddr;
+ int laddrlen = sizeof(laddr);
if(!fromaddr || !addrlen || *addrlen <= 0)
return recvfrom(sd, buffer, buflen, flags, fromaddr, addrlen);
- laddrlen = sizeof laddr;
laddr.ss_family = AF_UNSPEC; /* To detect if unused. */
rcvlen = recvfrom(sd, buffer, buflen, flags,
(struct sockaddr *) &laddr, &laddrlen);
@@ -1335,36 +1368,51 @@ Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags,
if(rcvlen < 0)
return rcvlen;
- switch (laddr.ss_family) {
-
- case AF_UNIX:
- srcu = (const struct sockaddr_un *) &laddr;
- dstu = (struct sockaddr_un *) fromaddr;
- i = *addrlen - offsetof(struct sockaddr_un, sun_path);
- laddrlen -= offsetof(struct sockaddr_un, sun_path);
- i = QadrtConvertE2A(dstu->sun_path, srcu->sun_path, i, laddrlen);
- laddrlen = i + offsetof(struct sockaddr_un, sun_path);
-
- if(laddrlen < *addrlen)
- dstu->sun_path[i] = '\0';
+ if(laddr.ss_family == AF_UNSPEC)
+ laddrlen = 0;
+ else {
+ laddrlen = sockaddr2ascii(fromaddr, *addrlen, &laddr, laddrlen);
+ if(laddrlen < 0)
+ return laddrlen;
+ }
+ *addrlen = laddrlen;
+ return rcvlen;
+}
- break;
- case AF_UNSPEC:
- break;
+int
+Curl_os400_getpeername(int sd, struct sockaddr *addr, int *addrlen)
+{
+ struct sockaddr_storage laddr;
+ int laddrlen = sizeof(laddr);
+ int retcode = getpeername(sd, (struct sockaddr *) &laddr, &laddrlen);
+
+ if(!retcode) {
+ laddrlen = sockaddr2ascii(addr, *addrlen, &laddr, laddrlen);
+ if(laddrlen < 0)
+ return laddrlen;
+ *addrlen = laddrlen;
+ }
- default:
- if(laddrlen > *addrlen)
- laddrlen = *addrlen;
+ return retcode;
+}
- if(laddrlen)
- memcpy((char *) fromaddr, (char *) &laddr, laddrlen);
- break;
- }
+int
+Curl_os400_getsockname(int sd, struct sockaddr *addr, int *addrlen)
+{
+ struct sockaddr_storage laddr;
+ int laddrlen = sizeof(laddr);
+ int retcode = getsockname(sd, (struct sockaddr *) &laddr, &laddrlen);
+
+ if(!retcode) {
+ laddrlen = sockaddr2ascii(addr, *addrlen, &laddr, laddrlen);
+ if(laddrlen < 0)
+ return laddrlen;
+ *addrlen = laddrlen;
+ }
- *addrlen = laddrlen;
- return rcvlen;
+ return retcode;
}