📄 os400sys.c
字号:
/*************************************************************************** * _ _ ____ _ * Project ___| | | | _ \| | * / __| | | | |_) | | * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * * Copyright (C) 1998 - 2008, 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 * are also available at http://curl.haxx.se/docs/copyright.html. * * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is * furnished to do so, under the terms of the COPYING file. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * * $Id: os400sys.c,v 1.3 2008-01-16 16:04:47 patrickm Exp $ * ***************************************************************************//* OS/400 additional support. */#include "config-os400.h" /* Not setup.h: we only need some defines. */#include <sys/types.h>#include <sys/socket.h>#include <stdlib.h>#include <string.h>#include <pthread.h>#include <netdb.h>#include <qadrt.h>#include <errno.h>#ifdef USE_QSOSSL#include <qsossl.h>#endif#ifdef HAVE_GSSAPI#include <gssapi.h>#endif#ifndef CURL_DISABLE_LDAP#include <ldap.h>#endif#include <netinet/in.h>#include <arpa/inet.h>#include "os400sys.h"/***** QADRT OS/400 ASCII runtime defines only the most used procedures, but*** but a lot of them are not supported. This module implements*** ASCII wrappers for those that are used by libcurl, but not*** defined by QADRT.**/#pragma convert(0) /* Restore EBCDIC. */#define MIN_BYTE_GAIN 1024 /* Minimum gain when shortening a buffer. */typedef struct { unsigned long size; /* Buffer size. */ char * buf; /* Buffer address. */} buffer_t;static char * buffer_undef(localkey_t key, long size);static char * buffer_threaded(localkey_t key, long size);static char * buffer_unthreaded(localkey_t key, long size);static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;static pthread_key_t thdkey;static buffer_t * locbufs;char * (* Curl_thread_buffer)(localkey_t key, long size) = buffer_undef;static voidthdbufdestroy(void * private){ localkey_t i; buffer_t * p; if (private) { p = (buffer_t *) private; for (i = (localkey_t) 0; i < LK_LAST; i++) { if (p->buf) free(p->buf); p++; } free(private); }}static voidterminate(void){ if (Curl_thread_buffer == buffer_threaded) { locbufs = pthread_getspecific(thdkey); pthread_setspecific(thdkey, (void *) NULL); pthread_key_delete(thdkey); } if (Curl_thread_buffer != buffer_undef) { thdbufdestroy((void *) locbufs); locbufs = (buffer_t *) NULL; } Curl_thread_buffer = buffer_undef;}static char *get_buffer(buffer_t * buf, long size){ char * cp; /* If `size' >= 0, make sure buffer at `buf' is at least `size'-byte long. Return the buffer address. */ if (size < 0) return buf->buf; if (!buf->buf) { if ((buf->buf = malloc(size))) buf->size = size; return buf->buf; } if ((unsigned long) size <= buf->size) { /* Shorten the buffer only if it frees a significant byte count. This avoids some realloc() overhead. */ if (buf->size - size < MIN_BYTE_GAIN) return buf->buf; } /* Resize the buffer. */ if ((cp = realloc(buf->buf, size))) { buf->buf = cp; buf->size = size; } else if (size <= buf->size) cp = buf->buf; return cp;}static char *buffer_unthreaded(localkey_t key, long size){ return get_buffer(locbufs + key, size);}static char *buffer_threaded(localkey_t key, long size){ buffer_t * bufs; /* Get the buffer for the given local key in the current thread, and make sure it is at least `size'-byte long. Set `size' to < 0 to get its address only. */ bufs = (buffer_t *) pthread_getspecific(thdkey); if (!bufs) { if (size < 0) return (char *) NULL; /* No buffer yet. */ /* Allocate buffer descriptors for the current thread. */ if (!(bufs = (buffer_t *) calloc((size_t) LK_LAST, sizeof *bufs))) return (char *) NULL; if (pthread_setspecific(thdkey, (void *) bufs)) { free(bufs); return (char *) NULL; } } return get_buffer(bufs + key, size);}static char *buffer_undef(localkey_t key, long size){ /* Define the buffer system, get the buffer for the given local key in the current thread, and make sure it is at least `size'-byte long. Set `size' to < 0 to get its address only. */ pthread_mutex_lock(&mutex); /* Determine if we can use pthread-specific data. */ if (Curl_thread_buffer == buffer_undef) { /* If unchanged during lock. */ if (!pthread_key_create(&thdkey, thdbufdestroy)) Curl_thread_buffer = buffer_threaded; else if (!(locbufs = (buffer_t *) calloc((size_t) LK_LAST, sizeof *locbufs))) { pthread_mutex_unlock(&mutex); return (char *) NULL; } else Curl_thread_buffer = buffer_unthreaded; atexit(terminate); } pthread_mutex_unlock(&mutex); return Curl_thread_buffer(key, size);}intCurl_getnameinfo_a(const struct sockaddr * sa, socklen_t salen, char * nodename, socklen_t nodenamelen, char * servname, socklen_t servnamelen, int flags){ char * enodename; char * eservname; int status; int i; enodename = (char *) NULL; eservname = (char *) NULL; if (nodename && nodenamelen) if (!(enodename = malloc(nodenamelen))) return EAI_MEMORY; if (servname && servnamelen) if (!(eservname = malloc(servnamelen))) { if (enodename) free(enodename); return EAI_MEMORY; } status = getnameinfo(sa, salen, enodename, nodenamelen, eservname, servnamelen, flags); if (!status) { if (enodename) { i = QadrtConvertE2A(nodename, enodename, nodenamelen - 1, strlen(enodename)); nodename[i] = '\0'; } if (eservname) { i = QadrtConvertE2A(servname, eservname, servnamelen - 1, strlen(eservname)); servname[i] = '\0'; } } if (enodename) free(enodename); if (eservname) free(eservname); return status;}intCurl_getaddrinfo_a(const char * nodename, const char * servname, const struct addrinfo * hints, struct addrinfo * * res){ char * enodename; char * eservname; int status; int i; enodename = (char *) NULL; eservname = (char *) NULL; if (nodename) { i = strlen(nodename); if (!(enodename = malloc(i + 1))) return EAI_MEMORY; i = QadrtConvertA2E(enodename, nodename, i, i); enodename[i] = '\0'; } if (servname) { i = strlen(servname); if (!(eservname = malloc(i + 1))) { if (enodename) free(enodename); return EAI_MEMORY; } QadrtConvertA2E(eservname, servname, i, i); eservname[i] = '\0'; } status = getaddrinfo(enodename, eservname, hints, res); if (enodename) free(enodename); if (eservname) free(eservname); return status;}intCurl_inet_ntoa_r_a(struct in_addr internet_address, char * output_buffer, int output_buffer_length){ int rc; int i; char * cp; if (!output_buffer || output_buffer_length < 16) return inet_ntoa_r(internet_address, output_buffer, output_buffer_length); if (!(cp = malloc(output_buffer_length + 1))) return -1; rc = inet_ntoa_r(internet_address, cp, output_buffer_length); if (rc) { free(cp); return rc; } cp[output_buffer_length - 1] = '\0'; i = strlen(cp); QadrtConvertE2A(output_buffer, cp, i, i); output_buffer[i] = '\0'; free(cp); return rc;}#ifdef USE_QSOSSL/* ASCII wrappers for the SSL procedures. */intCurl_SSL_Init_Application_a(SSLInitApp * init_app){ int rc; unsigned int i; SSLInitApp ia; if (!init_app || !init_app->applicationID || !init_app->applicationIDLen) return SSL_Init_Application(init_app); memcpy((char *) &ia, (char *) init_app, sizeof ia); i = ia.applicationIDLen; if (!(ia.applicationID = malloc(i + 1))) { errno = ENOMEM; return SSL_ERROR_IO; } QadrtConvertA2E(ia.applicationID, init_app->applicationID, i, i); ia.applicationID[i] = '\0'; rc = SSL_Init_Application(&ia); free(ia.applicationID); init_app->localCertificateLen = ia.localCertificateLen; init_app->sessionType = ia.sessionType; return rc;}intCurl_SSL_Init_a(SSLInit * init){ int rc; unsigned int i; SSLInit ia; if (!init || (!init->keyringFileName && !init->keyringPassword)) return SSL_Init(init); memcpy((char *) &ia, (char *) init, sizeof ia); if (ia.keyringFileName) { i = strlen(ia.keyringFileName); if (!(ia.keyringFileName = malloc(i + 1))) { errno = ENOMEM; return SSL_ERROR_IO; } QadrtConvertA2E(ia.keyringFileName, init->keyringFileName, i, i); ia.keyringFileName[i] = '\0'; } if (ia.keyringPassword) { i = strlen(ia.keyringPassword); if (!(ia.keyringPassword = malloc(i + 1))) { if (ia.keyringFileName) free(ia.keyringFileName); errno = ENOMEM; return SSL_ERROR_IO; } QadrtConvertA2E(ia.keyringPassword, init->keyringPassword, i, i); ia.keyringPassword[i] = '\0'; } rc = SSL_Init(&ia); if (ia.keyringFileName) free(ia.keyringFileName); if (ia.keyringPassword) free(ia.keyringPassword); return rc;}char *Curl_SSL_Strerror_a(int sslreturnvalue, SSLErrorMsg * serrmsgp){ int i; char * cp; char * cp2; cp = SSL_Strerror(sslreturnvalue, serrmsgp); if (!cp) return cp; i = strlen(cp); if (!(cp2 = Curl_thread_buffer(LK_SSL_ERROR, MAX_CONV_EXPANSION * i + 1))) return cp2; i = QadrtConvertE2A(cp2, cp, MAX_CONV_EXPANSION * i, i); cp2[i] = '\0'; return cp2;}#endif /* USE_QSOSSL */#ifdef HAVE_GSSAPI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -