mirror of
https://github.com/curl/curl.git
synced 2025-04-12 16:20:35 +08:00
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
This commit is contained in:
parent
4a778f75c5
commit
3e0a8e539c
@ -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
|
||||
|
@ -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,39 +1368,54 @@ 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';
|
||||
|
||||
break;
|
||||
|
||||
case AF_UNSPEC:
|
||||
break;
|
||||
|
||||
default:
|
||||
if(laddrlen > *addrlen)
|
||||
laddrlen = *addrlen;
|
||||
|
||||
if(laddrlen)
|
||||
memcpy((char *) fromaddr, (char *) &laddr, laddrlen);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if(laddr.ss_family == AF_UNSPEC)
|
||||
laddrlen = 0;
|
||||
else {
|
||||
laddrlen = sockaddr2ascii(fromaddr, *addrlen, &laddr, laddrlen);
|
||||
if(laddrlen < 0)
|
||||
return laddrlen;
|
||||
}
|
||||
*addrlen = laddrlen;
|
||||
return rcvlen;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
const char *
|
||||
Curl_os400_zlibVersion(void)
|
||||
|
Loading…
x
Reference in New Issue
Block a user