IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Sep 12, 2008, 3:15:59 PM (18 years ago)
Author:
jhoblitt
Message:

update to gSOAP 2.7.11

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Nebulous/nebclient/src/stdsoap2.c

    r3017 r19542  
    11/*
    2 
    3 stdsoap2.c[pp] 2.7.0d
    4 
    5 Runtime environment.
     2        stdsoap2.c[pp] 2.7.11-upd
     3
     4        gSOAP runtime engine
    65
    76gSOAP XML Web services tools
    8 Copyright (C) 2000-2004, Robert van Engelen, Genivia, Inc., All Rights Reserved.
    9 
     7Copyright (C) 2000-2008, Robert van Engelen, Genivia Inc., All Rights Reserved.
     8This part of the software is released under ONE of the following licenses:
     9GPL, the gSOAP public license, OR Genivia's license for commercial use.
     10--------------------------------------------------------------------------------
    1011Contributors:
    1112
    12 Wind River Systems, Inc., for the following additions (marked WR[...]):
     13Wind River Systems Inc., for the following additions under gSOAP public license:
    1314  - vxWorks compatible
    14   - Support for IPv6.
    15 
    1615--------------------------------------------------------------------------------
    1716gSOAP public license.
     
    2625
    2726The Initial Developer of the Original Code is Robert A. van Engelen.
    28 Copyright (C) 2000-2004, Robert van Engelen, Genivia, Inc., All Rights Reserved.
     27Copyright (C) 2000-2008, Robert van Engelen, Genivia Inc., All Rights Reserved.
    2928--------------------------------------------------------------------------------
    3029GPL license.
     
    4544Author contact information:
    4645engelen@genivia.com / engelen@acm.org
     46
     47This program is released under the GPL with the additional exemption that
     48compiling, linking, and/or using OpenSSL is allowed.
     49--------------------------------------------------------------------------------
     50A commercial use license is available from Genivia, Inc., contact@genivia.com
    4751--------------------------------------------------------------------------------
    4852
     
    6064*/
    6165
     66#ifdef AS400
     67# pragma convert(819)   /* EBCDIC to ASCII */
     68#endif
     69
    6270#include "stdsoap2.h"
    6371
     72#ifdef __BORLANDC__
     73# pragma warn -8060
     74#else
     75# ifdef WIN32
     76#  ifdef UNDER_CE
     77#   pragma comment(lib, "winsock.lib")
     78#  else
     79#   pragma comment(lib, "wsock32.lib")
     80#  endif
     81#  pragma warning(disable : 4996) /* disable deprecation warnings */
     82# endif
     83#endif
     84
    6485#ifdef __cplusplus
    65 SOAP_SOURCE_STAMP("@(#) stdsoap2.cpp ver 2.7.0c 2004-09-27 12:00:00 GMT")
     86SOAP_SOURCE_STAMP("@(#) stdsoap2.cpp ver 2.7.11 2008-07-26 00:00:00 GMT")
    6687extern "C" {
    6788#else
    68 SOAP_SOURCE_STAMP("@(#) stdsoap2.c ver 2.7.0c 2004-09-27 12:00:00 GMT")
    69 #endif
    70 
    71 /* 8bit character representing unknown/nonrepresentable character data (e.g. not supported by current locale) */
     89SOAP_SOURCE_STAMP("@(#) stdsoap2.c ver 2.7.11 2008-07-26 00:00:00 GMT")
     90#endif
     91
     92/* 8bit character representing unknown/nonrepresentable character data (e.g. not supported by current locale with multibyte support enabled) */
    7293#ifndef SOAP_UNKNOWN_CHAR
    7394#define SOAP_UNKNOWN_CHAR (127)
     
    83104#define soap_blank(c)           ((c) >= 0 && (c) <= 32)
    84105#define soap_notblank(c)        ((c) > 32)
    85 #define soap_hash_ptr(p)        (((unsigned long)(p) >> 3) & (SOAP_PTRHASH - 1))
    86 
     106
     107#if defined(WIN32) && !defined(UNDER_CE)
     108#define soap_hash_ptr(p)        ((PtrToUlong(p) >> 3) & (SOAP_PTRHASH - 1))
     109#else
     110#define soap_hash_ptr(p)        ((size_t)(((unsigned long)(p) >> 3) & (SOAP_PTRHASH-1)))
     111#endif
     112
     113#ifdef SOAP_DEBUG
     114static void soap_init_logs(struct soap*);
     115static void soap_close_logfile(struct soap*, int);
     116static void soap_set_logfile(struct soap*, int, const char*);
     117#endif
     118
     119#ifdef SOAP_MEM_DEBUG
     120static void soap_init_mht(struct soap*);
     121static void soap_free_mht(struct soap*);
     122static void soap_track_unlink(struct soap*, const void*);
     123#endif
     124
     125#ifndef PALM_2
     126static int soap_set_error(struct soap*, const char*, const char*, const char*, const char*, int);
     127static int soap_copy_fault(struct soap*, const char*, const char*, const char*, const char*);
     128static int soap_getattrval(struct soap*, char*, size_t, soap_wchar);
     129#endif
     130
     131#ifndef PALM_1
     132static soap_wchar soap_char(struct soap*);
     133static soap_wchar soap_get_pi(struct soap*);
    87134static int soap_isxdigit(int);
    88 static soap_wchar soap_char(struct soap*);
    89 static soap_wchar soap_getchunkchar(struct soap*);
    90 static void soap_update_ptrs(struct soap*, char*, char*, long);
     135static void *fplugin(struct soap*, const char*);
     136#ifndef WITH_NOIDREF
     137static void soap_update_ptrs(struct soap*, char*, char*, char*, char*);
    91138static int soap_has_copies(struct soap*, const char*, const char*);
    92 static struct soap_ilist *soap_hlookup(struct soap*, const char*);
    93139static void soap_init_iht(struct soap*);
    94140static void soap_free_iht(struct soap*);
    95141static void soap_init_pht(struct soap*);
    96142static void soap_free_pht(struct soap*);
    97 static int soap_set_error(struct soap*, const char*, const char*, const char*, int);
     143#endif
     144#endif
     145
     146#ifndef WITH_LEAN
    98147static const char *soap_set_validation_fault(struct soap*, const char*, const char*);
    99 static int soap_copy_fault(struct soap*, const char*, const char*, const char*);
    100 static int soap_getattrval(struct soap*, char*, size_t, soap_wchar);
    101 static void soap_set_local_namespaces(struct soap*);
    102148static int soap_isnumeric(struct soap*, const char*);
    103 static void *fplugin(struct soap*, const char*);
    104 static const char *soap_decode(char*, size_t, const char*, const char*);
    105 
    106 #ifndef WITH_LEAN
    107 static time_t soap_timegm(struct tm*);
    108 #endif
    109 
    110 #ifdef SOAP_DEBUG
    111 static void soap_init_logs(struct soap*);
    112 static void soap_close_logfile(struct soap*, int);
    113 static void soap_set_logfile(struct soap*, int, const char*);
    114 #endif
    115 
    116 #ifdef WITH_FAST
    117 static int soap_append_lab(struct soap*, const char*, size_t);
     149static struct soap_nlist *soap_push_ns(struct soap *soap, const char *id, const char *ns, short utilized);
     150static void soap_pop_ns(struct soap *soap);
     151static void soap_utilize_ns(struct soap *soap, const char *tag, size_t n);
    118152#endif
    119153
    120154#ifndef WITH_LEANER
     155#ifndef PALM_1
    121156static struct soap_multipart *soap_new_multipart(struct soap*, struct soap_multipart**, struct soap_multipart**, char*, size_t);
    122157static int soap_putdimefield(struct soap*, const char*, size_t);
     
    124159static void soap_select_mime_boundary(struct soap*);
    125160static int soap_valid_mime_boundary(struct soap*);
     161static void soap_resolve_attachment(struct soap*, struct soap_multipart*);
     162#endif
    126163#endif
    127164
     
    131168
    132169#ifdef WITH_OPENSSL
     170int soap_ssl_init_done = 0;
     171
    133172static int ssl_auth_init(struct soap*);
    134173static int ssl_verify_callback(int, X509_STORE_CTX*);
     174static int ssl_verify_callback_allow_expired_certificate(int, X509_STORE_CTX*);
    135175static int ssl_password(char*, int, int, void *);
    136 static const char *ssl_error(struct soap*, int);
    137 /* This callback is included for future references. It should not be deleted
     176/* The callback below is included for future references:
    138177static DH *ssl_tmp_dh(SSL*, int, int);
    139178*/
    140179#endif
    141180
    142 static const char *soap_strerror(struct soap*);
    143 static const char *tcp_error(struct soap*);
     181#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER)
     182#ifndef PALM_1
     183static const char *soap_decode(char*, size_t, const char*, const char*);
     184#endif
     185#endif
     186
     187#ifndef WITH_NOHTTP
     188#ifndef PALM_1
     189static soap_wchar soap_getchunkchar(struct soap*);
    144190static const char *http_error(struct soap*, int);
    145191static int http_post(struct soap*, const char*, const char*, int, const char*, const char*, size_t);
    146192static int http_get(struct soap*);
     193static int http_put(struct soap*);
     194static int http_del(struct soap*);
     195static int http_head(struct soap*);
    147196static int http_send_header(struct soap*, const char*);
    148197static int http_post_header(struct soap*, const char*, const char*);
     
    150199static int http_parse(struct soap*);
    151200static int http_parse_header(struct soap*, const char*, const char*);
    152 #ifndef MAC_CARBON
     201#endif
     202#endif
     203
     204#ifndef WITH_NOIO
     205
     206#ifndef PALM_1
     207static int fsend(struct soap*, const char*, size_t);
     208static size_t frecv(struct soap*, char*, size_t);
     209static int tcp_init(struct soap*);
     210static const char *tcp_error(struct soap*);
     211#ifndef WITH_LEAN
     212static size_t frecv_stop(struct soap*, char*, size_t);
     213#endif
     214#ifndef WITH_IPV6
    153215static int tcp_gethost(struct soap*, const char *addr, struct in_addr *inaddr);
    154 static int tcp_connect(struct soap*, const char *endpoint, const char *host, int port);
    155 static int tcp_accept(struct soap*, int, struct sockaddr*, int*);
     216#endif
     217static SOAP_SOCKET tcp_connect(struct soap*, const char *endpoint, const char *host, int port);
     218static SOAP_SOCKET tcp_accept(struct soap*, SOAP_SOCKET, struct sockaddr*, int*);
    156219static int tcp_disconnect(struct soap*);
    157220static int tcp_closesocket(struct soap*, SOAP_SOCKET);
    158221static int tcp_shutdownsocket(struct soap*, SOAP_SOCKET, int);
    159 static int fsend(struct soap*, const char*, size_t);
    160 static size_t frecv(struct soap*, char*, size_t);
    161 #endif
    162 
    163 /* WR[ */
    164 #ifdef VXWORKS
    165 static int vx_nonblocking = TRUE; /* ioctl argument */
    166 #endif
    167 /* ]WR */
     222static const char *soap_strerror(struct soap*);
     223#endif
     224
     225#if defined(WIN32)
     226  #define SOAP_SOCKBLOCK(fd) \
     227  { u_long blocking = 0; \
     228    ioctlsocket(fd, FIONBIO, &blocking); \
     229  }
     230  #define SOAP_SOCKNONBLOCK(fd) \
     231  { u_long nonblocking = 1; \
     232    ioctlsocket(fd, FIONBIO, &nonblocking); \
     233  }
     234#elif defined(VXWORKS)
     235  #define SOAP_SOCKBLOCK(fd) \
     236  { u_long blocking = 0; \
     237    ioctl(fd, FIONBIO, (int)(&blocking)); \
     238  }
     239  #define SOAP_SOCKNONBLOCK(fd) \
     240  { u_long nonblocking = 1; \
     241    ioctl(fd, FIONBIO, (int)(&nonblocking)); \
     242  }
     243#elif defined(PALM)
     244  #define SOAP_SOCKBLOCK(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0)&~O_NONBLOCK);
     245  #define SOAP_SOCKNONBLOCK(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0)|O_NONBLOCK);
     246#elif defined(SYMBIAN)
     247  #define SOAP_SOCKBLOCK(fd) \
     248  { long blocking = 0; \
     249    ioctl(fd, 0/*FIONBIO*/, &blocking); \
     250  }
     251  #define SOAP_SOCKNONBLOCK(fd) \
     252  { long nonblocking = 1; \
     253    ioctl(fd, 0/*FIONBIO*/, &nonblocking); \
     254  }
     255#else
     256  #define SOAP_SOCKBLOCK(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)&~O_NONBLOCK);
     257  #define SOAP_SOCKNONBLOCK(fd) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)|O_NONBLOCK);
     258#endif
     259
     260#endif
    168261
    169262#if defined(PALM) && !defined(PALM_2)
     
    185278#endif
    186279
    187 static const char soap_padding[3] = "\0\0";
     280#ifndef WITH_LEAN
     281static const char soap_indent[11] = "\n\t\t\t\t\t\t\t\t\t";
     282/* Alternative indentation form for SOAP_XML_INDENT:
     283static const char soap_indent[21] = "\n                   ";
     284*/
     285#endif
     286
     287#ifndef SOAP_CANARY
     288# define SOAP_CANARY (0xC0DE)
     289#endif
     290
     291static const char soap_padding[4] = "\0\0\0";
    188292#define SOAP_STR_PADDING (soap_padding)
    189293#define SOAP_STR_EOS (soap_padding)
     294#define SOAP_NON_NULL (soap_padding)
    190295
    191296#ifndef WITH_LEAN
     
    291396#endif
    292397
     398#ifndef WITH_NOIO
    293399#ifndef WITH_LEAN
    294400static const struct soap_code_map h_error_codes[] =
     
    312418};
    313419#endif
    314 
     420#endif
     421
     422#ifndef WITH_NOHTTP
    315423#ifndef WITH_LEAN
    316424static const struct soap_code_map h_http_error_codes[] =
    317 { { 201, "Created" },
     425{ { 200, "OK" },
     426  { 201, "Created" },
    318427  { 202, "Accepted" },
    319428  { 203, "Non-Authoritative Information" },
     
    355464};
    356465#endif
     466#endif
    357467
    358468#ifdef WITH_OPENSSL
     
    388498#endif
    389499
    390 /******************************************************************************/
    391 #ifndef MAC_CARBON
     500#if defined(HP_UX) && defined(HAVE_GETHOSTBYNAME_R)
     501extern int h_errno;
     502#endif
     503
     504/******************************************************************************/
     505#ifndef WITH_NOIO
    392506#ifndef PALM_1
    393507static int
    394508fsend(struct soap *soap, const char *s, size_t n)
    395 { register int nwritten;
     509{ register int nwritten, err;
    396510#if defined(__cplusplus) && !defined(WITH_LEAN)
    397511  if (soap->os)
    398   { soap->os->write(s, n);
     512  { soap->os->write(s, (std::streamsize)n);
    399513    if (soap->os->good())
    400514      return SOAP_OK;
     515    soap->errnum = 0;
    401516    return SOAP_EOF;
    402517  }
     
    407522#ifndef WITH_LEAN
    408523      if (soap->send_timeout)
    409       { struct timeval timeout;
    410         fd_set fd;
    411         if (soap->send_timeout > 0)
    412         { timeout.tv_sec = soap->send_timeout;
    413           timeout.tv_usec = 0;
    414         }
    415         else
    416         { timeout.tv_sec = -soap->send_timeout/1000000;
    417           timeout.tv_usec = -soap->send_timeout%1000000;
    418         }
    419         FD_ZERO(&fd);
    420         FD_SET((SOAP_SOCKET)soap->socket, &fd);
     524      {
     525#ifndef WIN32
     526        if ((int)soap->socket >= (int)FD_SETSIZE)
     527          return SOAP_FD_EXCEEDED;      /* Hint: MUST increase FD_SETSIZE */
     528#endif
    421529        for (;;)
    422         { register int r = select((SOAP_SOCKET)(soap->socket + 1), NULL, &fd, &fd, &timeout);
     530        { struct timeval timeout;
     531          fd_set fd;
     532          register int r;
     533          if (soap->send_timeout > 0)
     534          { timeout.tv_sec = soap->send_timeout;
     535            timeout.tv_usec = 0;
     536          }
     537          else
     538          { timeout.tv_sec = -soap->send_timeout/1000000;
     539            timeout.tv_usec = -soap->send_timeout%1000000;
     540          }
     541          FD_ZERO(&fd);
     542          FD_SET(soap->socket, &fd);
     543#ifdef WITH_OPENSSL
     544          if (soap->ssl)
     545            r = select((int)soap->socket + 1, &fd, &fd, &fd, &timeout);
     546          else
     547#endif
     548          r = select((int)soap->socket + 1, NULL, &fd, &fd, &timeout);
    423549          if (r > 0)
    424550            break;
     
    427553            return SOAP_EOF;
    428554          }
    429           if (soap_socket_errno != SOAP_EINTR)
    430           { soap->errnum = soap_socket_errno;
     555          err = soap_socket_errno(soap->socket);
     556          if (err != SOAP_EINTR && err != SOAP_EAGAIN && err != SOAP_EWOULDBLOCK)
     557          { soap->errnum = err;
    431558            return SOAP_EOF;
    432559          }
     
    436563#ifdef WITH_OPENSSL
    437564      if (soap->ssl)
    438         nwritten = SSL_write(soap->ssl, s, n);
     565        nwritten = SSL_write(soap->ssl, s, (int)n);
     566      else if (soap->bio)
     567        nwritten = BIO_write(soap->bio, s, (int)n);
    439568      else
    440569#endif
    441 #ifndef PALM
    442         nwritten = send((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags);
     570#ifndef WITH_LEAN
     571      if ((soap->omode & SOAP_IO_UDP))
     572      { if (soap->peerlen)
     573          nwritten = sendto(soap->socket, s, (SOAP_WINSOCKINT)n, soap->socket_flags, (struct sockaddr*)&soap->peer, (SOAP_WINSOCKINT)soap->peerlen);
     574        else
     575          nwritten = send(soap->socket, s, (SOAP_WINSOCKINT)n, soap->socket_flags);
     576        /* retry and back-off algorithm */
     577        /* TODO: this is not very clear from specs so verify and limit conditions under which we should loop (e.g. ENOBUFS) */
     578        if (nwritten < 0)
     579        { struct timeval timeout;
     580          fd_set fd;
     581          int udp_repeat;
     582          int udp_delay;
     583#ifndef WIN32
     584          if ((int)soap->socket >= (int)FD_SETSIZE)
     585            return SOAP_FD_EXCEEDED;    /* Hint: MUST increase FD_SETSIZE */
     586#endif
     587          if ((soap->connect_flags & SO_BROADCAST))
     588            udp_repeat = 3; /* SOAP-over-UDP MULTICAST_UDP_REPEAT - 1 */
     589          else
     590            udp_repeat = 1; /* SOAP-over-UDP UNICAST_UDP_REPEAT - 1 */
     591          udp_delay = (soap_random % 201) + 50; /* UDP_MIN_DELAY .. UDP_MAX_DELAY */
     592          do
     593          { timeout.tv_sec = 0;
     594            timeout.tv_usec = 1000 * udp_delay; /* ms */
     595            FD_ZERO(&fd);
     596            FD_SET(soap->socket, &fd);
     597            select((int)soap->socket + 1, NULL, NULL, &fd, &timeout);
     598            if (soap->peerlen)
     599              nwritten = sendto(soap->socket, s, (SOAP_WINSOCKINT)n, soap->socket_flags, (struct sockaddr*)&soap->peer, (SOAP_WINSOCKINT)soap->peerlen);
     600            else
     601              nwritten = send(soap->socket, s, (SOAP_WINSOCKINT)n, soap->socket_flags);
     602            udp_delay <<= 1;
     603            if (udp_delay > 500) /* UDP_UPPER_DELAY */
     604              udp_delay = 500;
     605          }
     606          while (nwritten < 0 && --udp_repeat > 0);
     607        }
     608      }
     609      else
     610#endif
     611#if !defined(PALM) && !defined(AS400)
     612        nwritten = send(soap->socket, s, (int)n, soap->socket_flags);
    443613#else
    444         nwritten = send((SOAP_SOCKET)soap->socket, (void*)s, n, soap->socket_flags);
     614        nwritten = send(soap->socket, (void*)s, n, soap->socket_flags);
    445615#endif
    446616      if (nwritten <= 0)
    447617      {
     618#if defined(WITH_OPENSSL) || !defined(WITH_LEAN)
     619        register int r = 0;
     620#endif
     621        err = soap_socket_errno(soap->socket);
    448622#ifdef WITH_OPENSSL
    449         int err;
    450         if (soap->ssl && (err = SSL_get_error(soap->ssl, nwritten)) != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
     623        if (soap->ssl && (r = SSL_get_error(soap->ssl, nwritten)) != SSL_ERROR_NONE && r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE)
     624        { soap->errnum = err;
    451625          return SOAP_EOF;
    452 #endif
    453         if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EWOULDBLOCK && soap_socket_errno != SOAP_EAGAIN)
    454         { soap->errnum = soap_socket_errno;
     626        }
     627#endif
     628        if (err == SOAP_EWOULDBLOCK || err == SOAP_EAGAIN)
     629        {
     630#ifndef WITH_LEAN
     631          struct timeval timeout;
     632          fd_set fd;
     633#ifndef WIN32
     634          if ((int)soap->socket >= (int)FD_SETSIZE)
     635            return SOAP_FD_EXCEEDED; /* Hint: MUST increase FD_SETSIZE */
     636#endif
     637          if (soap->send_timeout > 0)
     638          { timeout.tv_sec = soap->send_timeout;
     639            timeout.tv_usec = 0;
     640          }
     641          else if (soap->send_timeout < 0)
     642          { timeout.tv_sec = -soap->send_timeout/1000000;
     643            timeout.tv_usec = -soap->send_timeout%1000000;
     644          }
     645          else
     646          { timeout.tv_sec = 0;
     647            timeout.tv_usec = 10000;
     648          }
     649          FD_ZERO(&fd);
     650          FD_SET(soap->socket, &fd);
     651#ifdef WITH_OPENSSL
     652          if (soap->ssl && r == SSL_ERROR_WANT_READ)
     653            r = select((int)soap->socket + 1, &fd, NULL, &fd, &timeout);
     654          else
     655            r = select((int)soap->socket + 1, NULL, &fd, &fd, &timeout);
     656#else
     657          r = select((int)soap->socket + 1, NULL, &fd, &fd, &timeout);
     658#endif
     659          if (r < 0 && (r = soap_socket_errno(soap->socket)) != SOAP_EINTR)
     660          { soap->errnum = r;
     661            return SOAP_EOF;
     662          }
     663#endif
     664        }
     665        else if (err && err != SOAP_EINTR)
     666        { soap->errnum = err;
    455667          return SOAP_EOF;
    456668        }
     
    467679      nwritten = fwrite(s, 1, n, soap->sendfd);
    468680#else
    469 /* WR[ */
    470681#ifdef VXWORKS
    471682#ifdef WMW_RPM_IO
    472683      if (soap->rpmreqid)
    473           {
    474           httpBlockPut(soap->rpmreqid, s, n);
    475           nwritten = n;
    476           }
     684        nwritten = (httpBlockPut(soap->rpmreqid, s, n) == 0) ? n : -1;
    477685      else
    478           {
    479           nwritten = fwrite(s, sizeof(char), n, fdopen(soap->sendfd, "w"));
    480           }
     686#endif
     687        nwritten = fwrite(s, sizeof(char), n, fdopen(soap->sendfd, "w"));
    481688#else
    482       nwritten = fwrite(s, sizeof(char), n, fdopen(soap->sendfd, "w"));
    483 #endif /* WMW_RPM_IO */
     689      nwritten = write(soap->sendfd, s, (unsigned int)n);
     690#endif
     691#endif
     692#endif
     693      if (nwritten <= 0)
     694      {
     695#ifndef WITH_FASTCGI
     696        err = soap_errno;
    484697#else
    485 /* ]WR */
    486       nwritten = write((SOAP_SOCKET)soap->sendfd, s, n);
    487 /* WR[ */
    488 #endif
    489 /* ]WR */
    490 #endif
    491 #endif
    492       if (nwritten <= 0)
    493       { if (soap_errno != SOAP_EINTR && soap_errno != SOAP_EWOULDBLOCK && soap_errno != SOAP_EAGAIN)
    494         { soap->errnum = soap_errno;
     698        err = EOF;
     699#endif
     700        if (err && err != SOAP_EINTR && err != SOAP_EWOULDBLOCK && err != SOAP_EAGAIN)
     701        { soap->errnum = err;
    495702          return SOAP_EOF;
    496703        }
     
    504711}
    505712#endif
    506 #endif
    507 
    508 /******************************************************************************/
    509 #ifndef PALM_1
    510 SOAP_FMAC1
    511 int
    512 SOAP_FMAC2
    513 soap_flush_raw(struct soap *soap, const char *s, size_t n)
    514 { if ((soap->mode & SOAP_IO) == SOAP_IO_STORE)
    515   { register char *t;
    516     if (!(t = (char*)soap_push_block(soap, n)))
    517       return soap->error = SOAP_EOM;
    518     memcpy(t, s, n);
    519     if (soap->fpreparesend)
    520       return soap->fpreparesend(soap, s, n);
    521     return SOAP_OK;
    522   }
    523   if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK)
    524   { char t[16];
    525     sprintf(t, "\r\n%lX\r\n" + (soap->chunksize ? 0 : 2), (unsigned long)n);
    526     DBGMSG(SENT, t, strlen(t));
    527     if ((soap->error = soap->fsend(soap, t, strlen(t))))
    528       return soap->error;
    529     soap->chunksize += n;
    530   }
    531   DBGMSG(SENT, s, n);
    532   return soap->error = soap->fsend(soap, s, n);
    533 }
    534 #endif
    535 
    536 /******************************************************************************/
    537 #ifndef PALM_1
    538 SOAP_FMAC1
    539 int
    540 SOAP_FMAC2
    541 soap_flush(struct soap *soap)
    542 { if (soap->bufidx)
    543   {
    544 #ifdef WITH_ZLIB
    545     if (soap->mode & SOAP_ENC_ZLIB)
    546     { soap->d_stream.next_in = (Byte*)soap->buf;
    547       soap->d_stream.avail_in = (unsigned int)soap->bufidx;
    548 #ifdef WITH_GZIP
    549       soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)soap->bufidx);
    550 #endif
    551       do
    552       { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflating %u bytes\n", soap->d_stream.avail_in));
    553         if (deflate(&soap->d_stream, Z_NO_FLUSH) != Z_OK)
    554         { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to deflate: %s\n", soap->d_stream.msg?soap->d_stream.msg:""));
    555           return soap->error = SOAP_ZLIB_ERROR;
    556         }
    557         if (!soap->d_stream.avail_out)
    558         { if (soap_flush_raw(soap, soap->z_buf, SOAP_BUFLEN))
    559             return soap->error;
    560           soap->d_stream.next_out = (Byte*)soap->z_buf;
    561           soap->d_stream.avail_out = SOAP_BUFLEN;
    562         }
    563       } while (soap->d_stream.avail_in);
    564     }
    565     else
    566 #endif
    567     if (soap_flush_raw(soap, soap->buf, soap->bufidx))
    568       return soap->error;
    569     soap->bufidx = 0;
    570   }
    571   return SOAP_OK;
    572 }
    573713#endif
    574714
     
    583723  if (soap->mode & SOAP_IO_LENGTH)
    584724  { soap->count += n;
     725#ifndef WITH_LEANER
    585726    if (soap->fpreparesend && (soap->mode & SOAP_IO) != SOAP_IO_STORE)
    586       return soap->fpreparesend(soap, s, n);
     727      return soap->error = soap->fpreparesend(soap, s, n);
     728#endif
    587729    return SOAP_OK;
    588730  }
     
    611753int
    612754SOAP_FMAC2
     755soap_flush(struct soap *soap)
     756{ register size_t n = soap->bufidx;
     757  if (n)
     758  { soap->bufidx = 0;
     759#ifdef WITH_ZLIB
     760    if (soap->mode & SOAP_ENC_ZLIB)
     761    { soap->d_stream->next_in = (Byte*)soap->buf;
     762      soap->d_stream->avail_in = (unsigned int)n;
     763#ifdef WITH_GZIP
     764      soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)n);
     765#endif
     766      do
     767      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflating %u bytes\n", soap->d_stream->avail_in));
     768        if (deflate(soap->d_stream, Z_NO_FLUSH) != Z_OK)
     769        { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to deflate: %s\n", soap->d_stream->msg?soap->d_stream->msg:SOAP_STR_EOS));
     770          return soap->error = SOAP_ZLIB_ERROR;
     771        }
     772        if (!soap->d_stream->avail_out)
     773        { if (soap_flush_raw(soap, soap->z_buf, SOAP_BUFLEN))
     774            return soap->error;
     775          soap->d_stream->next_out = (Byte*)soap->z_buf;
     776          soap->d_stream->avail_out = SOAP_BUFLEN;
     777        }
     778      } while (soap->d_stream->avail_in);
     779    }
     780    else
     781#endif
     782      return soap_flush_raw(soap, soap->buf, n);
     783  }
     784  return SOAP_OK;
     785}
     786#endif
     787
     788/******************************************************************************/
     789#ifndef PALM_1
     790SOAP_FMAC1
     791int
     792SOAP_FMAC2
     793soap_flush_raw(struct soap *soap, const char *s, size_t n)
     794{ if ((soap->mode & SOAP_IO) == SOAP_IO_STORE)
     795  { register char *t;
     796    if (!(t = (char*)soap_push_block(soap, NULL, n)))
     797      return soap->error = SOAP_EOM;
     798    memcpy(t, s, n);
     799#ifndef WITH_LEANER
     800    if (soap->fpreparesend)
     801      return soap->error = soap->fpreparesend(soap, s, n);
     802#endif
     803    return SOAP_OK;
     804  }
     805#ifndef WITH_LEANER
     806  if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK)
     807  { char t[16];
     808    sprintf(t, "\r\n%lX\r\n" + (soap->chunksize ? 0 : 2), (unsigned long)n);
     809    DBGMSG(SENT, t, strlen(t));
     810    if ((soap->error = soap->fsend(soap, t, strlen(t))))
     811      return soap->error;
     812    soap->chunksize += n;
     813  }
     814  DBGMSG(SENT, s, n);
     815#endif
     816  return soap->error = soap->fsend(soap, s, n);
     817}
     818#endif
     819
     820/******************************************************************************/
     821#ifndef PALM_1
     822SOAP_FMAC1
     823int
     824SOAP_FMAC2
    613825soap_send(struct soap *soap, const char *s)
    614826{ if (s)
     
    619831
    620832/******************************************************************************/
     833#ifndef WITH_LEANER
    621834#ifndef PALM_1
    622835SOAP_FMAC1
     
    629842}
    630843#endif
    631 
    632 /******************************************************************************/
     844#endif
     845
     846/******************************************************************************/
     847#ifndef WITH_LEANER
    633848#ifndef PALM_1
    634849SOAP_FMAC1
     
    642857}
    643858#endif
    644 
    645 /******************************************************************************/
    646 #ifndef MAC_CARBON
     859#endif
     860
     861/******************************************************************************/
     862#ifndef WITH_NOIO
    647863#ifndef PALM_1
    648864static size_t
    649865frecv(struct soap *soap, char *s, size_t n)
    650866{ register int r;
     867#ifndef WITH_LEAN
     868  register int retries = 100; /* max 100 retries with non-blocking sockets */
     869#endif
    651870  soap->errnum = 0;
    652871#if defined(__cplusplus) && !defined(WITH_LEAN)
    653872  if (soap->is)
    654873  { if (soap->is->good())
    655       return soap->is->read(s, n).gcount();
     874      return soap->is->read(s, (std::streamsize)n).gcount();
    656875    return 0;
    657876  }
     
    660879  { for (;;)
    661880    {
     881#ifdef WITH_OPENSSL
     882      register int err = 0;
     883#endif
    662884#ifndef WITH_LEAN
    663       struct timeval timeout;
    664       fd_set fd;
     885#ifdef WITH_OPENSSL
     886      if (soap->recv_timeout && !soap->ssl) /* SSL: sockets are nonblocking */
     887#else
    665888      if (soap->recv_timeout)
    666       { if (soap->recv_timeout > 0)
     889#endif
     890      {
     891#ifndef WIN32
     892        if ((int)soap->socket >= (int)FD_SETSIZE)
     893        { soap->error = SOAP_FD_EXCEEDED;
     894          return 0;     /* Hint: MUST increase FD_SETSIZE */
     895        }
     896#endif
     897        for (;;)
     898        { struct timeval timeout;
     899          fd_set fd;
     900          if (soap->recv_timeout > 0)
     901          { timeout.tv_sec = soap->recv_timeout;
     902            timeout.tv_usec = 0;
     903          }
     904          else
     905          { timeout.tv_sec = -soap->recv_timeout/1000000;
     906            timeout.tv_usec = -soap->recv_timeout%1000000;
     907          }
     908          FD_ZERO(&fd);
     909          FD_SET(soap->socket, &fd);
     910          r = select((int)soap->socket + 1, &fd, NULL, &fd, &timeout);
     911          if (r > 0)
     912            break;
     913          if (!r)
     914          { soap->errnum = 0;
     915            return 0;
     916          }
     917          r = soap_socket_errno(soap->socket);
     918          if (r != SOAP_EINTR && r != SOAP_EAGAIN && r != SOAP_EWOULDBLOCK)
     919          { soap->errnum = r;
     920            return 0;
     921          }
     922        }
     923      }
     924#endif
     925#ifdef WITH_OPENSSL
     926      if (soap->ssl)
     927      { r = SSL_read(soap->ssl, s, (int)n);
     928        if (r > 0)
     929          return (size_t)r;
     930        err = SSL_get_error(soap->ssl, r);
     931        if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
     932          return 0;
     933      }
     934      else if (soap->bio)
     935      { r = BIO_read(soap->bio, s, (int)n);
     936        if (r > 0)
     937          return (size_t)r;
     938        return 0;
     939      }
     940      else
     941#endif
     942      {
     943#ifndef WITH_LEAN
     944        if ((soap->omode & SOAP_IO_UDP))
     945        { SOAP_SOCKLEN_T k = (SOAP_SOCKLEN_T)sizeof(soap->peer);
     946          memset((void*)&soap->peer, 0, sizeof(soap->peer));
     947          r = recvfrom(soap->socket, s, (SOAP_WINSOCKINT)n, soap->socket_flags, (struct sockaddr*)&soap->peer, &k);     /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */
     948          soap->peerlen = (size_t)k;
     949#ifndef WITH_IPV6
     950          soap->ip = ntohl(soap->peer.sin_addr.s_addr);
     951#endif
     952        }
     953        else
     954#endif
     955          r = recv(soap->socket, s, (int)n, soap->socket_flags);
     956#ifdef PALM
     957        /* CycleSyncDisplay(curStatusMsg); */
     958#endif
     959        if (r >= 0)
     960          return (size_t)r;
     961        r = soap_socket_errno(soap->socket);
     962        if (r != SOAP_EINTR && r != SOAP_EAGAIN && r != SOAP_EWOULDBLOCK)
     963        { soap->errnum = r;
     964          return 0;
     965        }
     966      }
     967#ifndef WITH_LEAN
     968      { struct timeval timeout;
     969        fd_set fd;
     970        if (soap->recv_timeout > 0)
    667971        { timeout.tv_sec = soap->recv_timeout;
    668972          timeout.tv_usec = 0;
    669973        }
    670         else
     974        else if (soap->recv_timeout < 0)
    671975        { timeout.tv_sec = -soap->recv_timeout/1000000;
    672976          timeout.tv_usec = -soap->recv_timeout%1000000;
    673977        }
     978        else
     979        { timeout.tv_sec = 5;
     980          timeout.tv_usec = 0;
     981        }
     982#ifndef WIN32
     983        if ((int)soap->socket >= (int)FD_SETSIZE)
     984        { soap->error = SOAP_FD_EXCEEDED;
     985          return 0;     /* Hint: MUST increase FD_SETSIZE */
     986        }
     987#endif
    674988        FD_ZERO(&fd);
    675         FD_SET((SOAP_SOCKET)soap->socket, &fd);
    676         for (;;)
    677         { r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout);
    678           if (r > 0)
    679             break;
    680           if (r == 0)
    681             return 0;
    682           if (soap_socket_errno != SOAP_EINTR)
    683           { soap->errnum = soap_socket_errno;
     989        FD_SET(soap->socket, &fd);
     990#ifdef WITH_OPENSSL
     991        if (soap->ssl && err == SSL_ERROR_WANT_WRITE)
     992          r = select((int)soap->socket + 1, NULL, &fd, &fd, &timeout);
     993        else
     994          r = select((int)soap->socket + 1, &fd, NULL, &fd, &timeout);
     995#else
     996        r = select((int)soap->socket + 1, &fd, NULL, &fd, &timeout);
     997#endif
     998        if (!r && soap->recv_timeout)
     999        { soap->errnum = 0;
     1000          return 0;
     1001        }
     1002        if (r < 0)
     1003        { r = soap_socket_errno(soap->socket);
     1004          if (r != SOAP_EINTR && r != SOAP_EAGAIN && r != SOAP_EWOULDBLOCK)
     1005          { soap->errnum = r;
    6841006            return 0;
    6851007          }
    6861008        }
    687       }
    688 #endif
    689 #ifdef WITH_OPENSSL
    690       if (soap->ssl)
    691       { int err;
    692         r = SSL_read(soap->ssl, s, n);
    693         if ((err = SSL_get_error(soap->ssl, r)) == SSL_ERROR_NONE)
    694           return (size_t)r;
    695         if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
    696           return 0;
    697       }
    698       else
    699 #endif
    700       { r = recv((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags);
    701         if (r >= 0)
    702           return (size_t)r;
    703         if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EAGAIN)
    704         { soap->errnum = soap_socket_errno;
     1009        if (retries-- <= 0)
     1010        { soap->errnum = soap_socket_errno(soap->socket);
    7051011          return 0;
    7061012        }
    7071013      }
    708 #ifndef WITH_LEAN
    709       { struct timeval timeout;
    710         fd_set fd;
    711         timeout.tv_sec = 0;
    712         timeout.tv_usec = 10000;
    713         FD_ZERO(&fd);
    714         FD_SET((SOAP_SOCKET)soap->socket, &fd);
    715         r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout);
    716         if (r < 0 && soap_socket_errno != SOAP_EINTR)
    717         { soap->errnum = soap_socket_errno;
    718           return 0;
    719         }
     1014#endif
     1015#ifdef PALM
     1016      r = soap_socket_errno(soap->socket);
     1017      if (r != SOAP_EINTR && retries-- <= 0)
     1018      { soap->errnum = r;
     1019        return 0;
    7201020      }
    7211021#endif
     
    7281028  return fread(s, 1, n, soap->recvfd);
    7291029#else
    730 /* WR[ */
    7311030#ifdef WMW_RPM_IO
    7321031  if (soap->rpmreqid)
    7331032    r = httpBlockRead(soap->rpmreqid, s, n);
    7341033  else
    735     r = read(soap->recvfd, s, n);
    736   if (r >= 0)
    737     return r;
    738   return 0;
    739 #else
    740 /* ]WR */
    741   r = read((SOAP_SOCKET)soap->recvfd, s, n);
     1034#endif
     1035    r = read(soap->recvfd, s, (unsigned int)n);
    7421036  if (r >= 0)
    7431037    return (size_t)r;
    7441038  soap->errnum = soap_errno;
    7451039  return 0;
    746 /* WR[ */
    747 #endif
    748 /* ]WR */
    749 #endif
    750 #endif
    751 }
    752 #endif
    753 #endif
    754 
    755 /******************************************************************************/
     1040#endif
     1041#endif
     1042}
     1043#endif
     1044#endif
     1045
     1046/******************************************************************************/
     1047#ifndef WITH_LEAN
     1048#ifndef WITH_NOIO
     1049#ifndef PALM_1
     1050static size_t
     1051frecv_stop(struct soap *soap, char *s, size_t n)
     1052{ return 0;
     1053}
     1054#endif
     1055#endif
     1056#endif
     1057
     1058/******************************************************************************/
     1059#ifndef WITH_NOHTTP
    7561060#ifndef PALM_1
    7571061static soap_wchar
     
    7611065  soap->bufidx = 0;
    7621066  soap->buflen = soap->chunkbuflen = soap->frecv(soap, soap->buf, SOAP_BUFLEN);
    763   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes\n", (unsigned int)soap->buflen));
     1067  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes from socket %d\n", (unsigned int)soap->buflen, soap->socket));
    7641068  DBGMSG(RECV, soap->buf, soap->buflen);
    7651069  if (soap->buflen)
     
    7681072}
    7691073#endif
     1074#endif
    7701075
    7711076/******************************************************************************/
     
    7731078static int
    7741079soap_isxdigit(int c)
    775 { switch (c)
    776   { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
    777     case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
    778     case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
    779       return 1;
    780   }
    781   return 0;
     1080{ return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
    7821081}
    7831082#endif
     
    7921091#ifdef WITH_ZLIB
    7931092  if (soap->mode & SOAP_ENC_ZLIB)
    794   { if (soap->d_stream.next_out == Z_NULL)
     1093  { if (soap->d_stream->next_out == Z_NULL)
    7951094      return EOF;
    796     if (soap->d_stream.avail_in || !soap->d_stream.avail_out)
     1095    if (soap->d_stream->avail_in || !soap->d_stream->avail_out)
    7971096    { register int r;
    7981097      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflating\n"));
    799       soap->d_stream.next_out = (Byte*)soap->buf;
    800       soap->d_stream.avail_out = SOAP_BUFLEN;
    801       r = inflate(&soap->d_stream, Z_NO_FLUSH);
     1098      soap->d_stream->next_out = (Byte*)soap->buf;
     1099      soap->d_stream->avail_out = SOAP_BUFLEN;
     1100      r = inflate(soap->d_stream, Z_NO_FLUSH);
    8021101      if (r == Z_OK || r == Z_STREAM_END)
    8031102      { soap->bufidx = 0;
    804         soap->buflen = SOAP_BUFLEN - soap->d_stream.avail_out;
     1103        ret = soap->buflen = SOAP_BUFLEN - soap->d_stream->avail_out;
    8051104        if (soap->zlib_in == SOAP_ZLIB_GZIP)
    806           soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)soap->buflen);
     1105          soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)ret);
    8071106        if (r == Z_STREAM_END)
    808         { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %lu->%lu bytes\n", soap->d_stream.total_in, soap->d_stream.total_out));
    809           soap->z_ratio_in = (float)soap->d_stream.total_in / (float)soap->d_stream.total_out;
    810           soap->d_stream.next_out = Z_NULL;
     1107        { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %lu->%lu bytes\n", soap->d_stream->total_in, soap->d_stream->total_out));
     1108          soap->z_ratio_in = (float)soap->d_stream->total_in / (float)soap->d_stream->total_out;
     1109          soap->d_stream->next_out = Z_NULL;
    8111110        }
    812         if (soap->buflen)
    813         { soap->count += soap->buflen;
     1111        if (ret)
     1112        { soap->count += ret;
     1113          DBGLOG(RECV, SOAP_MESSAGE(fdebug, "\n---- decompressed ----\n"));
     1114          DBGMSG(RECV, soap->buf, ret);
     1115          DBGLOG(RECV, SOAP_MESSAGE(fdebug, "\n----\n"));
    8141116          return SOAP_OK;
    8151117        }
    8161118      }
    8171119      else if (r != Z_BUF_ERROR)
    818       { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflate error: %s\n", soap->d_stream.msg?soap->d_stream.msg:""));
    819         soap->d_stream.next_out = Z_NULL;
     1120      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflate error: %s\n", soap->d_stream->msg?soap->d_stream->msg:SOAP_STR_EOS));
     1121        soap->d_stream->next_out = Z_NULL;
     1122        soap->error = SOAP_ZLIB_ERROR;
    8201123        return EOF;
    8211124      }
     
    8261129      soap->buflen = soap->z_buflen;
    8271130    }
    828   }
    829 #endif
     1131    DBGLOG(RECV, SOAP_MESSAGE(fdebug, "\n---- compressed ----\n"));
     1132  }
     1133#endif
     1134#ifndef WITH_NOHTTP
    8301135  if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) /* read HTTP chunked transfer */
    831   {
    832 chunk_again:
    833     if (soap->chunksize)
    834     { soap->buflen = ret = soap->frecv(soap, soap->buf, soap->chunksize > SOAP_BUFLEN ? SOAP_BUFLEN : soap->chunksize);
    835       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Getting chunk: read %u bytes\n", (unsigned int)ret));
    836       DBGMSG(RECV, soap->buf, ret);
    837       soap->bufidx = 0;
    838       soap->chunksize -= ret;
    839     }
    840     else
     1136  { for (;;)
    8411137    { register soap_wchar c;
    8421138      char *t, tmp[8];
     1139      if (soap->chunksize)
     1140      { soap->buflen = ret = soap->frecv(soap, soap->buf, soap->chunksize > SOAP_BUFLEN ? SOAP_BUFLEN : soap->chunksize);
     1141        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Getting chunk: read %u bytes\n", (unsigned int)ret));
     1142        DBGMSG(RECV, soap->buf, ret);
     1143        soap->bufidx = 0;
     1144        soap->chunksize -= ret;
     1145        break;
     1146      }
    8431147      t = tmp;
    8441148      if (!soap->chunkbuflen)
    8451149      { soap->chunkbuflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN);
    846         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes\n", (unsigned int)ret));
     1150        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes (chunked) from socket %d\n", (unsigned int)ret, soap->socket));
    8471151        DBGMSG(RECV, soap->buf, ret);
    8481152        soap->bufidx = 0;
    8491153        if (!ret)
    850           return EOF;
     1154          return soap->ahead = EOF;
    8511155      }
    8521156      else
    8531157        soap->bufidx = soap->buflen;
    8541158      soap->buflen = soap->chunkbuflen;
    855       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Getting chunk size (%u %u)\n", (unsigned int)soap->bufidx, (unsigned int)soap->buflen));
     1159      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Getting chunk size (idx=%u len=%u)\n", (unsigned int)soap->bufidx, (unsigned int)soap->buflen));
    8561160      while (!soap_isxdigit((int)(c = soap_getchunkchar(soap))))
    857         if ((int)c == EOF)
    858           return EOF;
     1161      { if ((int)c == EOF)
     1162          return soap->ahead = EOF;
     1163      }
    8591164      do
    8601165        *t++ = (char)c;
     
    8631168        c = soap_getchunkchar(soap);
    8641169      if ((int)c == EOF)
    865         return EOF;
     1170        return soap->ahead = EOF;
    8661171      *t = '\0';
     1172      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunk size = %s (hex)\n", tmp));
    8671173      soap->chunksize = soap_strtoul(tmp, &t, 16);
    8681174      if (!soap->chunksize)
    8691175      { soap->chunkbuflen = 0;
    8701176        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of chunked message\n"));
    871         while ((int)c != EOF && c != '\n')
     1177        while ((int)c != EOF && c != '\n')
    8721178          c = soap_getchunkchar(soap);
    873         return EOF;
     1179        ret = 0;
     1180        soap->ahead = EOF;
     1181        break;
    8741182      }
    8751183      soap->buflen = soap->bufidx + soap->chunksize;
    876       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Moving buf len to %u (%u %s)\n", (unsigned int)soap->buflen, (unsigned int)soap->bufidx, tmp));
     1184      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Moving buf len to idx=%u len=%u (%s)\n", (unsigned int)soap->bufidx, (unsigned int)soap->buflen, tmp));
    8771185      if (soap->buflen > soap->chunkbuflen)
    8781186      { soap->buflen = soap->chunkbuflen;
    8791187        soap->chunksize -= soap->buflen - soap->bufidx;
    8801188        soap->chunkbuflen = 0;
    881         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Passed end of buffer for chunked HTTP (%lu bytes left)\n", (unsigned long)(soap->buflen - soap->bufidx)));
     1189        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Passed end of buffer for chunked HTTP (%u bytes left)\n", (unsigned int)(soap->buflen - soap->bufidx)));
    8821190      }
    8831191      else if (soap->chunkbuflen)
    8841192        soap->chunksize = 0;
    8851193      ret = soap->buflen - soap->bufidx;
    886       if (!ret)
    887         goto chunk_again;
     1194      if (ret)
     1195        break;
    8881196    }
    8891197  }
    8901198  else
     1199#endif
    8911200  { soap->bufidx = 0;
    8921201    soap->buflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN);
    893     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes\n", (unsigned int)ret));
     1202    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes from socket %d\n", (unsigned int)ret, soap->socket));
    8941203    DBGMSG(RECV, soap->buf, ret);
    8951204  }
     1205#ifndef WITH_LEANER
    8961206  if (soap->fpreparerecv && (soap->error = soap->fpreparerecv(soap, soap->buf, ret)))
    8971207    return soap->error;
     1208#endif
    8981209#ifdef WITH_ZLIB
    8991210  if (soap->mode & SOAP_ENC_ZLIB)
    9001211  { register int r;
    9011212    memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN);
    902     soap->d_stream.next_in = (Byte*)(soap->z_buf + soap->bufidx);
    903     soap->d_stream.avail_in = (unsigned int)ret;
    904     soap->d_stream.next_out = (Byte*)soap->buf;
    905     soap->d_stream.avail_out = SOAP_BUFLEN;
    906     r = inflate(&soap->d_stream, Z_NO_FLUSH);
     1213    soap->d_stream->next_in = (Byte*)(soap->z_buf + soap->bufidx);
     1214    soap->d_stream->avail_in = (unsigned int)ret;
     1215    soap->d_stream->next_out = (Byte*)soap->buf;
     1216    soap->d_stream->avail_out = SOAP_BUFLEN;
     1217    r = inflate(soap->d_stream, Z_NO_FLUSH);
    9071218    if (r == Z_OK || r == Z_STREAM_END)
    9081219    { soap->bufidx = 0;
    9091220      soap->z_buflen = soap->buflen;
    910       soap->buflen = ret = SOAP_BUFLEN - soap->d_stream.avail_out;
     1221      soap->buflen = SOAP_BUFLEN - soap->d_stream->avail_out;
    9111222      if (soap->zlib_in == SOAP_ZLIB_GZIP)
    9121223        soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)soap->buflen);
    913       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %u bytes\n", (unsigned int)ret));
    914       if (!ret)
     1224      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %u bytes\n", (unsigned int)soap->buflen));
     1225      if (ret && !soap->buflen)
    9151226        goto zlib_again;
     1227      ret = soap->buflen;
    9161228      if (r == Z_STREAM_END)
    917       { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %lu->%lu bytes\n", soap->d_stream.total_in, soap->d_stream.total_out));
    918         soap->z_ratio_in = (float)soap->d_stream.total_in / (float)soap->d_stream.total_out;
    919         soap->d_stream.next_out = Z_NULL;
    920       }
     1229      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated total %lu->%lu bytes\n", soap->d_stream->total_in, soap->d_stream->total_out));
     1230        soap->z_ratio_in = (float)soap->d_stream->total_in / (float)soap->d_stream->total_out;
     1231        soap->d_stream->next_out = Z_NULL;
     1232      }
     1233      DBGLOG(RECV, SOAP_MESSAGE(fdebug, "\n---- decompressed ----\n"));
     1234      DBGMSG(RECV, soap->buf, ret);
    9211235    }
    9221236    else
    923     { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to inflate: (%d) %s\n", r, soap->d_stream.msg?soap->d_stream.msg:""));
    924       soap->d_stream.next_out = Z_NULL;
     1237    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to inflate: (%d) %s\n", r, soap->d_stream->msg?soap->d_stream->msg:SOAP_STR_EOS));
     1238      soap->d_stream->next_out = Z_NULL;
     1239      soap->error = SOAP_ZLIB_ERROR;
    9251240      return EOF;
    9261241    }
     
    10121327soap_getchar(struct soap *soap)
    10131328{ register soap_wchar c;
    1014   if (soap->ahead)
    1015   { c = soap->ahead;
    1016     soap->ahead = 0;
     1329  c = soap->ahead;
     1330  if (c)
     1331  { if (c != EOF)
     1332      soap->ahead = 0;
    10171333    return c;
    10181334  }
     
    10261342const struct soap_code_map*
    10271343SOAP_FMAC2
    1028 soap_code(const struct soap_code_map *map, const char *str)
    1029 { while (map->string)
    1030   { if (!strcmp(str, map->string)) /* case sensitive */
    1031       return map;
    1032     map++;
     1344soap_code(const struct soap_code_map *code_map, const char *str)
     1345{ if (code_map && str)
     1346  { while (code_map->string)
     1347    { if (!strcmp(str, code_map->string)) /* case sensitive */
     1348        return code_map;
     1349      code_map++;
     1350    }
    10331351  }
    10341352  return NULL;
     
    10411359long
    10421360SOAP_FMAC2
    1043 soap_int_code(const struct soap_code_map *map, const char *str, long other)
    1044 { while (map->string)
    1045   { if (!soap_tag_cmp(str, map->string)) /* case insensitive */
    1046       return map->code;
    1047     map++;
     1361soap_code_int(const struct soap_code_map *code_map, const char *str, long other)
     1362{ if (code_map)
     1363  { while (code_map->string)
     1364    { if (!soap_tag_cmp(str, code_map->string)) /* case insensitive */
     1365        return code_map->code;
     1366      code_map++;
     1367    }
    10481368  }
    10491369  return other;
     
    10561376const char*
    10571377SOAP_FMAC2
    1058 soap_str_code(const struct soap_code_map *map, long code)
    1059 { while (map->code != code && map->string)
    1060     map++;
    1061   return map->string;
     1378soap_code_str(const struct soap_code_map *code_map, long code)
     1379{ if (!code_map)
     1380    return NULL;
     1381  while (code_map->code != code && code_map->string)
     1382    code_map++;
     1383  return code_map->string;
     1384}
     1385#endif
     1386
     1387/******************************************************************************/
     1388#ifndef PALM_1
     1389SOAP_FMAC1
     1390long
     1391SOAP_FMAC2
     1392soap_code_bits(const struct soap_code_map *code_map, const char *str)
     1393{ register long bits = 0;
     1394  if (code_map)
     1395  { while (str && *str)
     1396    { const struct soap_code_map *p;
     1397      for (p = code_map; p->string; p++)
     1398      { register size_t n = strlen(p->string);
     1399        if (!strncmp(p->string, str, n) && soap_blank(str[n]))
     1400        { bits |= p->code;
     1401          str += n;
     1402          while (*str > 0 && *str <= 32)
     1403            str++;
     1404          break;
     1405        }
     1406      }
     1407      if (!p->string)
     1408        return 0;
     1409    }
     1410  }
     1411  return bits;
     1412}
     1413#endif
     1414
     1415/******************************************************************************/
     1416#ifndef PALM_1
     1417SOAP_FMAC1
     1418const char*
     1419SOAP_FMAC2
     1420soap_code_list(struct soap *soap, const struct soap_code_map *code_map, long code)
     1421{ register char *t = soap->tmpbuf;
     1422  if (code_map)
     1423  { while (code_map->string)
     1424    { if (code_map->code & code)
     1425      { register const char *s = code_map->string;
     1426        if (t != soap->tmpbuf)
     1427          *t++ = ' ';
     1428        while (*s && t < soap->tmpbuf + sizeof(soap->tmpbuf) - 1)
     1429          *t++ = *s++;
     1430        if (t == soap->tmpbuf + sizeof(soap->tmpbuf) - 1)
     1431          break;
     1432      }
     1433      code_map++;
     1434    }
     1435  }
     1436  *t = '\0';
     1437  return soap->tmpbuf;
    10621438}
    10631439#endif
     
    10941470    return '\'';
    10951471#ifndef WITH_LEAN
    1096   return (soap_wchar)soap_int_code(html_entity_codes, tmp, SOAP_UNKNOWN_CHAR);
     1472  return (soap_wchar)soap_code_int(html_entity_codes, tmp, SOAP_UNKNOWN_CHAR);
    10971473#else
    10981474  return SOAP_UNKNOWN_CHAR; /* use this to represent unknown code */
    10991475#endif
    11001476}
     1477#endif
     1478
     1479/******************************************************************************/
     1480#ifdef WITH_LEAN
     1481#ifndef PALM_1
     1482soap_wchar
     1483soap_get0(struct soap *soap)
     1484{ if (soap->bufidx >= soap->buflen && soap_recv(soap))
     1485    return EOF;
     1486  return (unsigned char)soap->buf[soap->bufidx];
     1487}
     1488#endif
     1489#endif
     1490
     1491/******************************************************************************/
     1492#ifdef WITH_LEAN
     1493#ifndef PALM_1
     1494soap_wchar
     1495soap_get1(struct soap *soap)
     1496{ if (soap->bufidx >= soap->buflen && soap_recv(soap))
     1497    return EOF;
     1498  return (unsigned char)soap->buf[soap->bufidx++];
     1499}
     1500#endif
    11011501#endif
    11021502
     
    11101510  c = soap->ahead;
    11111511  if (c)
    1112     soap->ahead = 0;
     1512  { if ((int)c != EOF)
     1513      soap->ahead = 0;
     1514  }
    11131515  else
    11141516    c = soap_get1(soap);
    1115   for (;;)
     1517  while ((int)c != EOF)
    11161518  { if (soap->cdata)
    11171519    { if (c == ']')
    11181520      { c = soap_get1(soap);
    11191521        if (c == ']')
    1120         { soap->cdata = 0;
    1121           soap_get1(soap); /* skip > */
    1122           c = soap_get1(soap);
     1522        { c = soap_get0(soap);
     1523          if (c == '>')
     1524          { soap->cdata = 0;
     1525            soap_get1(soap);
     1526            c = soap_get1(soap);
     1527          }
     1528          else
     1529          { soap_unget(soap, ']');
     1530            return ']';
     1531          }
    11231532        }
    1124         else
     1533        else
    11251534        { soap_revget1(soap);
    11261535          return ']';
     
    11351544        while (soap_blank(c));
    11361545        if (c == '!' || c == '?' || c == '%')
    1137         { if (c == '!')
     1546        { register int k = 1;
     1547          if (c == '!')
    11381548          { c = soap_get1(soap);
    11391549            if (c == '[')
     
    11441554              soap->cdata = 1;
    11451555              c = soap_get1(soap);
    1146               continue;
     1556              continue;
    11471557            }
    11481558            if (c == '-' && (c = soap_get1(soap)) == '-')
     
    11541564            }
    11551565          }
    1156           while ((int)c != EOF && c != '>')
     1566          else if (c == '?')
     1567            c = soap_get_pi(soap);
     1568          while ((int)c != EOF)
     1569          { if (c == '<')
     1570              k++;
     1571            else if (c == '>')
     1572            { if (--k <= 0)
     1573                break;
     1574            }
    11571575            c = soap_get1(soap);
    1158           if ((int)c == EOF)
    1159             break;
     1576          }
     1577          if ((int)c == EOF)
     1578            break;
    11601579          c = soap_get1(soap);
    11611580          continue;
     
    11821601/******************************************************************************/
    11831602#ifndef PALM_1
    1184 SOAP_FMAC1
    1185 soap_wchar
    1186 SOAP_FMAC2
    1187 soap_advance(struct soap *soap)
    1188 { register soap_wchar c;
    1189   while ((int)((c = soap_get(soap)) != EOF) && c != SOAP_LT && c != SOAP_TT)
    1190     ;
    1191   return c;
    1192 }
    1193 #endif
    1194 
    1195 /******************************************************************************/
    1196 #ifndef PALM_1
    1197 SOAP_FMAC1
    1198 soap_wchar
    1199 SOAP_FMAC2
    1200 soap_skip(struct soap *soap)
    1201 { register soap_wchar c;
    1202   do c = soap_get(soap);
    1203   while (soap_blank(c));
     1603static soap_wchar
     1604soap_get_pi(struct soap *soap)
     1605{ char buf[64];
     1606  register char *s = buf;
     1607  register int i = sizeof(buf);
     1608  register soap_wchar c = soap_getchar(soap);
     1609  /* This is a quick way to parse XML PI and we could use a callback instead to
     1610   * enable applications to intercept processing instructions */
     1611  while ((int)c != EOF && c != '?')
     1612  { if (--i > 0)
     1613    { if (soap_blank(c))
     1614        c = ' ';
     1615      *s++ = (char)c;
     1616    }
     1617    c = soap_getchar(soap);
     1618  }
     1619  *s = '\0';
     1620  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "XML PI <?%s?>\n", buf));
     1621  if (!strncmp(buf, "xml ", 4))
     1622  { s = strstr(buf, " encoding=");
     1623    if (s && s[10])
     1624    { if (!soap_tag_cmp(s + 11, "iso-8859-1*")
     1625       || !soap_tag_cmp(s + 11, "latin1*"))
     1626      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Switching to latin1 encoding\n"));
     1627        soap->mode |= SOAP_ENC_LATIN;
     1628      }
     1629      else if (!soap_tag_cmp(s + 11, "utf-8*"))
     1630      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Switching to utf-8 encoding\n"));
     1631        soap->mode &= ~SOAP_ENC_LATIN;
     1632      }
     1633    }
     1634  }
     1635  if ((int)c != EOF)
     1636    c = soap_getchar(soap);
    12041637  return c;
    12051638}
     
    12411674soap_pututf8(struct soap *soap, register unsigned long c)
    12421675{ char tmp[16];
    1243   if (c > 0 && c < 0x80)
     1676  if (c < 0x80 && c > 0)
    12441677  { *tmp = (char)c;
    12451678    return soap_send_raw(soap, tmp, 1);
    12461679  }
    12471680#ifndef WITH_LEAN
    1248   if (soap->mode & SOAP_XML_CANONICAL)
     1681  if (c >= 0x80)
    12491682  { register char *t = tmp;
    12501683    if (c < 0x0800)
     
    12721705    *t = '\0';
    12731706  }
    1274   else
    1275 #endif
    1276     sprintf(tmp, "&#%lu;", c);
     1707#else
     1708  sprintf(tmp, "&#%lu;", c);
     1709#endif
    12771710  return soap_send(soap, tmp);
    12781711}
     
    12861719soap_getutf8(struct soap *soap)
    12871720{ register soap_wchar c, c1, c2, c3, c4;
     1721  c = soap->ahead;
     1722  if (c > 0xFF)
     1723  { soap->ahead = 0;
     1724    return c;
     1725  }
     1726again:
    12881727  c = soap_get(soap);
    12891728  if (c < 0x80 || (soap->mode & SOAP_ENC_LATIN))
    12901729    return c;
    1291   c1 = soap_get(soap);
     1730  c1 = soap_get1(soap);
    12921731  if (c1 < 0x80)
    1293   { soap_unget(soap, c1);
     1732  { soap_revget1(soap); /* doesn't look like this is UTF8 */
    12941733    return c;
    12951734  }
     
    12981737    return ((soap_wchar)(c & 0x1F) << 6) | c1;
    12991738  c2 = (soap_wchar)soap_get1(soap) & 0x3F;
     1739  if (c == 0xEF && c1 == 0x3B && c2 == 0x3F)    /* ignore UTF-8 BOM */
     1740    goto again;
    13001741  if (c < 0xF0)
    13011742    return ((soap_wchar)(c & 0x0F) << 12) | (c1 << 6) | c2;
     
    13161757SOAP_FMAC2
    13171758soap_puthex(struct soap *soap, const unsigned char *s, int n)
    1318 { /* TODO: serialize to DOM (as an option) using new soap_s2hex() */
    1319   char d[2];
     1759{ char d[2];
    13201760  register int i;
     1761#ifdef WITH_DOM
     1762  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
     1763  { if (!(soap->dom->data = soap_s2hex(soap, s, NULL, n)))
     1764      return soap->error;
     1765    return SOAP_OK;
     1766  }
     1767#endif
    13211768  for (i = 0; i < n; i++)
    13221769  { register int m = *s++;
     
    13381785soap_gethex(struct soap *soap, int *n)
    13391786{
     1787#ifdef WITH_DOM
     1788  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
     1789  { soap->dom->data = soap_string_in(soap, 0, -1, -1);
     1790    return (unsigned char*)soap_hex2s(soap, soap->dom->data, NULL, 0, n);
     1791  }
     1792#endif
    13401793#ifdef WITH_FAST
    13411794  soap->labidx = 0;
    13421795  for (;;)
    13431796  { register char *s;
    1344     register int i, k;
     1797    register size_t i, k;
    13451798    if (soap_append_lab(soap, NULL, 0))
    13461799      return NULL;
     
    13551808      { d1 = (char)c;
    13561809        c = soap_get(soap);
    1357         if (soap_isxdigit(c))
     1810        if (soap_isxdigit(c))
    13581811          d2 = (char)c;
    13591812        else
     
    13661819        soap_unget(soap, c);
    13671820        if (n)
    1368           *n = (int)(soap->lablen - k + i);
    1369         p = (unsigned char*)soap_malloc(soap, soap->lablen - k + i);
    1370         if (p)
    1371           memcpy(p, soap->labbuf, soap->lablen - k + i);
     1821          *n = (int)(soap->lablen + i - k);
     1822        p = (unsigned char*)soap_malloc(soap, soap->lablen + i - k);
     1823        if (p)
     1824          memcpy(p, soap->labbuf, soap->lablen + i - k);
    13721825        return p;
    13731826      }
     
    13761829  }
    13771830#else
    1378   if (soap_new_block(soap))
     1831  if (soap_new_block(soap) == NULL)
    13791832    return NULL;
    13801833  for (;;)
    13811834  { register int i;
    1382     register char *s = (char*)soap_push_block(soap, SOAP_BLKLEN);
     1835    register char *s = (char*)soap_push_block(soap, NULL, SOAP_BLKLEN);
    13831836    if (!s)
    1384     { soap_end_block(soap);
     1837    { soap_end_block(soap, NULL);
    13851838      return NULL;
    13861839    }
     
    13911844      { d1 = (char)c;
    13921845        c = soap_get(soap);
    1393         if (soap_isxdigit(c))
     1846        if (soap_isxdigit(c))
    13941847          d2 = (char)c;
    13951848        else
    1396         { soap_end_block(soap);
    1397           soap->error = SOAP_TYPE;
     1849        { soap_end_block(soap, NULL);
     1850          soap->error = SOAP_TYPE;
    13981851          return NULL;
    13991852        }
     
    14031856        soap_unget(soap, c);
    14041857        if (n)
    1405           *n = soap_size_block(soap, i);
     1858          *n = (int)soap_size_block(soap, NULL, i);
    14061859        p = (unsigned char*)soap_save_block(soap, NULL, 0);
    14071860        return p;
     
    14271880#ifdef WITH_DOM
    14281881  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
    1429   { if (!(soap->dom->data = soap_s2base64(soap, s, soap->dom->data, n)))
     1882  { if (!(soap->dom->data = soap_s2base64(soap, s, NULL, n)))
    14301883      return soap->error;
    14311884    return SOAP_OK;
     
    14651918soap_getbase64(struct soap *soap, int *n, int malloc_flag)
    14661919{
     1920#ifdef WITH_DOM
     1921  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
     1922  { soap->dom->data = soap_string_in(soap, 0, -1, -1);
     1923    return (unsigned char*)soap_base642s(soap, soap->dom->data, NULL, 0, n);
     1924  }
     1925#endif
    14671926#ifdef WITH_FAST
    14681927  soap->labidx = 0;
    14691928  for (;;)
    1470   { register int i, k;
     1929  { register size_t i, k;
    14711930    register char *s;
    14721931    if (soap_append_lab(soap, NULL, 2))
    14731932      return NULL;
    14741933    s = soap->labbuf + soap->labidx;
    1475     k = 3 * ((soap->lablen - soap->labidx) / 3);
     1934    k = soap->lablen - soap->labidx;
    14761935    soap->labidx = 3 * (soap->lablen / 3);
    14771936    if (!s)
    14781937      return NULL;
    1479     for (i = 0; i < k; i += 3)
    1480     { register unsigned long m = 0;
    1481       register int j = 0;
    1482       do
    1483       { register soap_wchar c = soap_get(soap);
    1484         if (c == '=' || c < 0)
    1485         { unsigned char *p;
    1486           switch (j)
    1487           { case 2:
    1488               *s++ = (char)((m >> 4) & 0xFF);
    1489               i++;
    1490               break;
    1491             case 3:
    1492               *s++ = (char)((m >> 10) & 0xFF);
    1493               *s++ = (char)((m >> 2) & 0xFF);
    1494               i += 2;
     1938    if (k > 2)
     1939    { for (i = 0; i < k - 2; i += 3)
     1940      { register unsigned long m = 0;
     1941        register int j = 0;
     1942        do
     1943        { register soap_wchar c = soap_get(soap);
     1944          if (c == '=' || c < 0)
     1945          { unsigned char *p;
     1946            switch (j)
     1947            { case 2:
     1948                *s++ = (char)((m >> 4) & 0xFF);
     1949                i++;
     1950                break;
     1951              case 3:
     1952                *s++ = (char)((m >> 10) & 0xFF);
     1953                *s++ = (char)((m >> 2) & 0xFF);
     1954                i += 2;
     1955            }
     1956            if (n)
     1957              *n = (int)(soap->lablen + i - k);
     1958            p = (unsigned char*)soap_malloc(soap, soap->lablen + i - k);
     1959            if (p)
     1960              memcpy(p, soap->labbuf, soap->lablen + i - k);
     1961            if (c >= 0)
     1962            { while ((int)((c = soap_get(soap)) != EOF) && c != SOAP_LT && c != SOAP_TT)
     1963                ;
     1964            }
     1965            soap_unget(soap, c);
     1966            return p;
    14951967          }
    1496           if (n)
    1497             *n = (int)(soap->lablen - k + i);
    1498           p = (unsigned char*)soap_malloc(soap, soap->lablen - k + i);
    1499           if (p)
    1500             memcpy(p, soap->labbuf, soap->lablen - k + i);
    1501           if (c >= 0)
    1502           { while ((int)((c = soap_get(soap)) != EOF) && c != SOAP_LT && c != SOAP_TT)
    1503               ;
    1504           }
    1505           soap_unget(soap, c);
    1506           return p;
    1507         }
    1508         c -= '+';
    1509         if (c >= 0 && c <= 79)
    1510         { m = (m << 6) + soap_base64i[c];
    1511           j++;
    1512         }
    1513       } while (j < 4);
    1514       *s++ = (char)((m >> 16) & 0xFF);
    1515       *s++ = (char)((m >> 8) & 0xFF);
    1516       *s++ = (char)(m & 0xFF);
     1968          c -= '+';
     1969          if (c >= 0 && c <= 79)
     1970          { register int b = soap_base64i[c];
     1971            if (b >= 64)
     1972            { soap->error = SOAP_TYPE;
     1973              return NULL; 
     1974            }
     1975            m = (m << 6) + b;
     1976            j++;
     1977          }
     1978          else if (!soap_blank(c + '+'))
     1979          { soap->error = SOAP_TYPE;
     1980            return NULL; 
     1981          }
     1982        } while (j < 4);
     1983        *s++ = (char)((m >> 16) & 0xFF);
     1984        *s++ = (char)((m >> 8) & 0xFF);
     1985        *s++ = (char)(m & 0xFF);
     1986      }
    15171987    }
    15181988  }
    15191989#else
    1520   if (soap_new_block(soap))
     1990  if (soap_new_block(soap) == NULL)
    15211991    return NULL;
    15221992  for (;;)
    15231993  { register int i;
    1524     register char *s = (char*)soap_push_block(soap, 3 * SOAP_BLKLEN); /* must be multiple of 3 */
     1994    register char *s = (char*)soap_push_block(soap, NULL, 3 * SOAP_BLKLEN); /* must be multiple of 3 */
    15251995    if (!s)
    1526     { soap_end_block(soap);
     1996    { soap_end_block(soap, NULL);
    15271997      return NULL;
    15281998    }
     
    15462016          }
    15472017          if (n)
    1548             *n = (int)soap_size_block(soap, i);
     2018            *n = (int)soap_size_block(soap, NULL, i);
    15492019          p = (unsigned char*)soap_save_block(soap, NULL, 0);
    15502020          if (c >= 0)
    15512021          { while ((int)((c = soap_get(soap)) != EOF) && c != SOAP_LT && c != SOAP_TT)
    15522022              ;
    1553           }
     2023          }
    15542024          soap_unget(soap, c);
    15552025          return p;
     
    15572027        c -= '+';
    15582028        if (c >= 0 && c <= 79)
    1559         { m = (m << 6) + soap_base64i[c];
     2029        { int b = soap_base64i[c];
     2030          if (b >= 64)
     2031          { soap->error = SOAP_TYPE;
     2032            return NULL; 
     2033          }
     2034          m = (m << 6) + b;
    15602035          j++;
     2036        }
     2037        else if (!soap_blank(c))
     2038        { soap->error = SOAP_TYPE;
     2039          return NULL; 
    15612040        }
    15622041      } while (j < 4);
     
    15712050
    15722051/******************************************************************************/
     2052#ifndef WITH_LEANER
     2053#ifndef PALM_1
     2054SOAP_FMAC1
     2055int
     2056SOAP_FMAC2
     2057soap_xop_forward(struct soap *soap, unsigned char **ptr, int *size, char **id, char **type, char **options)
     2058{ /* Check MTOM xop:Include element (within hex/base64Binary) */
     2059  /* TODO: this code to be obsoleted with new import/xop.h conventions */
     2060  int body = soap->body; /* should save type too? */
     2061  if (!soap_peek_element(soap))
     2062  { if (!soap_element_begin_in(soap, "xop:Include", 0, NULL) && *soap->href)
     2063    { if (soap_dime_forward(soap, ptr, size, id, type, options))
     2064        return soap->error;
     2065    }
     2066    if (soap->body && soap_element_end_in(soap, NULL))
     2067      return soap->error;
     2068  }
     2069  soap->body = body;
     2070  return SOAP_OK;
     2071}
     2072#endif
     2073#endif
     2074
     2075/******************************************************************************/
     2076#ifndef WITH_LEANER
     2077#ifndef PALM_1
     2078SOAP_FMAC1
     2079int
     2080SOAP_FMAC2
     2081soap_dime_forward(struct soap *soap, unsigned char **ptr, int *size, char **id, char **type, char **options)
     2082{ struct soap_xlist *xp;
     2083  *ptr = NULL;
     2084  *size = 0;
     2085  *id = NULL;
     2086  *type = NULL;
     2087  *options = NULL;
     2088  if (!*soap->href)
     2089    return SOAP_OK;
     2090  *id = soap_strdup(soap, soap->href);
     2091  xp = (struct soap_xlist*)SOAP_MALLOC(soap, sizeof(struct soap_xlist));
     2092  if (!xp)
     2093    return soap->error = SOAP_EOM;
     2094  xp->next = soap->xlist;
     2095  xp->ptr = ptr;
     2096  xp->size = size;
     2097  xp->id = *id;
     2098  xp->type = type;
     2099  xp->options = options;
     2100  soap->xlist = xp;
     2101  return SOAP_OK;
     2102}
     2103#endif
     2104#endif
     2105
     2106/******************************************************************************/
    15732107#ifndef PALM_1
    15742108SOAP_FMAC1
     
    15862120#ifndef PALM_1
    15872121SOAP_FMAC1
    1588 int
     2122wchar_t *
     2123SOAP_FMAC2
     2124soap_wstrdup(struct soap *soap, const wchar_t *s)
     2125{ wchar_t *t = NULL;
     2126  if (s)
     2127  { size_t n = 0;
     2128    while (s[n])
     2129      n++;
     2130    if ((t = (wchar_t*)soap_malloc(soap, sizeof(wchar_t)*(n+1))))
     2131      memcpy(t, s, sizeof(wchar_t)*(n+1));
     2132  }
     2133  return t;
     2134}
     2135#endif
     2136
     2137/******************************************************************************/
     2138#ifndef PALM_1
     2139SOAP_FMAC1
     2140struct soap_blist*
    15892141SOAP_FMAC2
    15902142soap_new_block(struct soap *soap)
    15912143{ struct soap_blist *p;
    15922144  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "New block sequence (prev=%p)\n", soap->blist));
    1593   if (!(p = (struct soap_blist*)SOAP_MALLOC(sizeof(struct soap_blist))))
    1594     return SOAP_EOM;   
     2145  if (!(p = (struct soap_blist*)SOAP_MALLOC(soap, sizeof(struct soap_blist))))
     2146  { soap->error = SOAP_EOM;   
     2147    return NULL;
     2148  }
    15952149  p->next = soap->blist;
    15962150  p->ptr = NULL;
    15972151  p->size = 0;
    15982152  soap->blist = p;
    1599   return SOAP_OK;
     2153  return p;
    16002154}
    16012155#endif
     
    16062160void*
    16072161SOAP_FMAC2
    1608 soap_push_block(struct soap *soap, size_t n)
     2162soap_push_block(struct soap *soap, struct soap_blist *b, size_t n)
    16092163{ char *p;
    1610   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push block of %u bytes (%u bytes total)\n", (unsigned int)n, (unsigned int)soap->blist->size + (unsigned int)n));
    1611   if (!(p = (char*)SOAP_MALLOC(n + sizeof(char*) + sizeof(size_t))))
     2164  if (!b)
     2165    b = soap->blist;
     2166  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push block of %u bytes (%u bytes total)\n", (unsigned int)n, (unsigned int)b->size + (unsigned int)n));
     2167  if (!(p = (char*)SOAP_MALLOC(soap, n + sizeof(char*) + sizeof(size_t))))
    16122168  { soap->error = SOAP_EOM;
    16132169    return NULL;
    16142170  }
    1615   *(char**)p = soap->blist->ptr;
     2171  *(char**)p = b->ptr;
    16162172  *(size_t*)(p + sizeof(char*)) = n;
    1617   soap->blist->ptr = p;
    1618   soap->blist->size += n;
     2173  b->ptr = p;
     2174  b->size += n;
    16192175  return p + sizeof(char*) + sizeof(size_t);
    16202176}
     
    16262182void
    16272183SOAP_FMAC2
    1628 soap_pop_block(struct soap *soap)
     2184soap_pop_block(struct soap *soap, struct soap_blist *b)
    16292185{ char *p;
    1630   if (!soap->blist->ptr)
     2186  if (!b)
     2187    b = soap->blist;
     2188  if (!b->ptr)
    16312189    return;
    16322190  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Pop block\n"));
    1633   p = soap->blist->ptr;
    1634   soap->blist->size -= *(size_t*)(p + sizeof(char*));
    1635   soap->blist->ptr = *(char**)p;
    1636   SOAP_FREE(p);
    1637 }
    1638 #endif
    1639 
    1640 /******************************************************************************/
     2191  p = b->ptr;
     2192  b->size -= *(size_t*)(p + sizeof(char*));
     2193  b->ptr = *(char**)p;
     2194  SOAP_FREE(soap, p);
     2195}
     2196#endif
     2197
     2198/******************************************************************************/
     2199#ifndef WITH_NOIDREF
    16412200#ifndef PALM_1
    16422201static void
    1643 soap_update_ptrs(struct soap *soap, char *start, char *end, long offset)
     2202soap_update_ptrs(struct soap *soap, char *start, char *end, char *p1, char *p2)
    16442203{ int i;
    1645   register struct soap_ilist *ip;
    1646   register struct soap_flist *fp;
     2204  register struct soap_ilist *ip = NULL;
     2205  register struct soap_flist *fp = NULL;
     2206#ifndef WITH_LEANER
     2207  register struct soap_xlist *xp = NULL;
     2208#endif
    16472209  register void *p, **q;
    16482210  for (i = 0; i < SOAP_IDHASH; i++)
    1649     for (ip = soap->iht[i]; ip; ip = ip->next)
     2211  { for (ip = soap->iht[i]; ip; ip = ip->next)
    16502212    { if (ip->ptr && (char*)ip->ptr >= start && (char*)ip->ptr < end)
    1651       { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update id='%s' %p -> %p\n", ip->id, ip->ptr, (char*)ip->ptr + offset));
    1652         ip->ptr = (char*)ip->ptr + offset;
     2213      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update id='%s' %p -> %p\n", ip->id, ip->ptr, (char*)ip->ptr + (p1-p2)));
     2214        ip->ptr = (char*)ip->ptr + (p1-p2);
    16532215      }
    16542216      for (q = &ip->link; q; q = (void**)p)
     
    16562218        if (p && (char*)p >= start && (char*)p < end)
    16572219        { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Link update id='%s' %p\n", ip->id, p));
    1658           *q = (char*)p + offset;
     2220          *q = (char*)p + (p1-p2);
    16592221        }
    16602222      }
     
    16632225        if (p && (char*)p >= start && (char*)p < end)
    16642226        { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy chain update id='%s' %p\n", ip->id, p));
    1665           *q = (char*)p + offset;
     2227          *q = (char*)p + (p1-p2);
    16662228        }
    16672229      }
     
    16692231      { if ((char*)fp->ptr >= start && (char*)fp->ptr < end)
    16702232        { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy list update id='%s' %p\n", ip->id, fp));
    1671           fp->ptr = (char*)fp->ptr + offset;
     2233          fp->ptr = (char*)fp->ptr + (p1-p2);
    16722234        }
    16732235      }
    16742236    }
    1675 }
    1676 #endif
    1677 
    1678 /******************************************************************************/
     2237  }
     2238#ifndef WITH_LEANER
     2239  for (xp = soap->xlist; xp; xp = xp->next)
     2240  { if (xp->ptr && (char*)xp->ptr >= start && (char*)xp->ptr < end)
     2241    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update id='%s' %p -> %p\n", xp->id?xp->id:SOAP_STR_EOS, xp->ptr, (char*)xp->ptr + (p1-p2)));
     2242      xp->ptr = (unsigned char**)((char*)xp->ptr + (p1-p2));
     2243      xp->size = (int*)((char*)xp->size + (p1-p2));
     2244      xp->type = (char**)((char*)xp->type + (p1-p2));
     2245      xp->options = (char**)((char*)xp->options + (p1-p2));
     2246    }
     2247  }
     2248#endif
     2249}
     2250#endif
     2251#endif
     2252
     2253/******************************************************************************/
     2254#ifndef WITH_NOIDREF
    16792255#ifndef PALM_1
    16802256static int
    16812257soap_has_copies(struct soap *soap, register const char *start, register const char *end)
    16822258{ register int i;
    1683   register struct soap_ilist *ip;
    1684   register struct soap_flist *fp;
     2259  register struct soap_ilist *ip = NULL;
     2260  register struct soap_flist *fp = NULL;
    16852261  register const char *p;
    16862262  for (i = 0; i < SOAP_IDHASH; i++)
     
    16912267      for (fp = ip->flist; fp; fp = fp->next)
    16922268        if ((const char*)fp->ptr >= start && (const char*)fp->ptr < end)
    1693           return SOAP_ERR;
     2269          return SOAP_ERR;
    16942270    }
    16952271  }
     
    16972273}
    16982274#endif
    1699 
    1700 /******************************************************************************/
     2275#endif
     2276
     2277/******************************************************************************/
     2278#ifndef WITH_NOIDREF
    17012279#ifndef PALM_1
    17022280SOAP_FMAC1
     
    17052283soap_resolve(struct soap *soap)
    17062284{ register int i;
    1707   register struct soap_ilist *ip;
    1708   register struct soap_flist *fp;
     2285  register struct soap_ilist *ip = NULL;
     2286  register struct soap_flist *fp = NULL;
    17092287  short flag;
    17102288  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving forwarded data\n"));
     
    17432321            do
    17442322            { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "... copy %p -> %p (%u bytes)\n", ip->ptr, q, (unsigned int)ip->size));
    1745               p = *q;
     2323              p = *q;
    17462324              memcpy(q, ip->ptr, ip->size);
    17472325              q = (void**)p;
    17482326            } while (q);
    1749             flag = 1;
    1750           }
     2327            flag = 1;
     2328          }
    17512329          for (fp = ip->flist; fp; fp = ip->flist)
    17522330          { register unsigned int k = fp->level;
    1753             register void *p = ip->ptr;
     2331            register void *p = ip->ptr;
    17542332            DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving forwarded data type=%d location=%p level=%u,%u id='%s'\n", ip->type, p, ip->level, fp->level, ip->id));
    1755             while (ip->level < k)
     2333            while (ip->level < k)
    17562334            { register void **q = (void**)soap_malloc(soap, sizeof(void*)); 
    1757               if (!q)
    1758                 return soap->error;
    1759               *q = p;
     2335              if (!q)
     2336                return soap->error;
     2337              *q = p;
    17602338              DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level, new location=%p holds=%p...\n", q, *q));
    17612339              p = (void*)q;
    17622340              k--;
    17632341            }
    1764             if (fp->fcopy)
    1765               fp->fcopy(soap, ip->type, fp->type, fp->ptr, p, ip->size);
    1766             else
    1767               soap_fcopy(soap, ip->type, fp->type, fp->ptr, p, ip->size);
    1768             ip->flist = fp->next;
    1769             SOAP_FREE(fp);
    1770             flag = 1;
    1771           }
     2342            if (fp->fcopy)
     2343              fp->fcopy(soap, ip->type, fp->type, fp->ptr, fp->len, p, ip->size);
     2344            else
     2345              soap_fcopy(soap, ip->type, fp->type, fp->ptr, fp->len, p, ip->size);
     2346            ip->flist = fp->next;
     2347            SOAP_FREE(soap, fp);
     2348            flag = 1;
     2349          }
    17722350        }
    17732351      }
     
    17872365}
    17882366#endif
     2367#endif
    17892368
    17902369/******************************************************************************/
     
    17932372size_t
    17942373SOAP_FMAC2
    1795 soap_size_block(struct soap *soap, size_t n)
    1796 { if (soap->blist->ptr)
    1797   { soap->blist->size -= *(size_t*)(soap->blist->ptr + sizeof(char*)) - n;
    1798     *(size_t*)(soap->blist->ptr + sizeof(char*)) = n;
    1799   }
    1800   return soap->blist->size;
     2374soap_size_block(struct soap *soap, struct soap_blist *b, size_t n)
     2375{ if (!b)
     2376    b = soap->blist;
     2377  if (b->ptr)
     2378  { b->size -= *(size_t*)(b->ptr + sizeof(char*)) - n;
     2379    *(size_t*)(b->ptr + sizeof(char*)) = n;
     2380  }
     2381  return b->size;
    18012382}
    18022383#endif
     
    18072388char*
    18082389SOAP_FMAC2
    1809 soap_first_block(struct soap *soap)
     2390soap_first_block(struct soap *soap, struct soap_blist *b)
    18102391{ char *p, *q, *r;
    1811   p = soap->blist->ptr;
     2392  if (!b)
     2393    b = soap->blist;
     2394  p = b->ptr;
    18122395  if (!p)
    18132396    return NULL;
     
    18202403    p = q;
    18212404  } while (p);
    1822   soap->blist->ptr = r;
     2405  b->ptr = r;
    18232406  return r + sizeof(char*) + sizeof(size_t);
    18242407}
     
    18302413char*
    18312414SOAP_FMAC2
    1832 soap_next_block(struct soap *soap)
     2415soap_next_block(struct soap *soap, struct soap_blist *b)
    18332416{ char *p;
    1834   p = soap->blist->ptr;
     2417  if (!b)
     2418    b = soap->blist;
     2419  p = b->ptr;
    18352420  if (p)
    18362421  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Next block\n"));
    1837     soap->blist->ptr = *(char**)p;
    1838     SOAP_FREE(p);
    1839     if (soap->blist->ptr)
    1840       return soap->blist->ptr + sizeof(char*) + sizeof(size_t);
     2422    b->ptr = *(char**)p;
     2423    SOAP_FREE(soap, p);
     2424    if (b->ptr)
     2425      return b->ptr + sizeof(char*) + sizeof(size_t);
    18412426  }
    18422427  return NULL;
     
    18492434size_t
    18502435SOAP_FMAC2
    1851 soap_block_size(struct soap *soap)
    1852 { return *(size_t*)(soap->blist->ptr + sizeof(char*));
     2436soap_block_size(struct soap *soap, struct soap_blist *b)
     2437{ if (!b)
     2438    b = soap->blist;
     2439  return *(size_t*)(b->ptr + sizeof(char*));
    18532440}
    18542441#endif
     
    18592446void
    18602447SOAP_FMAC2
    1861 soap_end_block(struct soap *soap)
    1862 { struct soap_blist *bp;
    1863   char *p, *q;
    1864   bp = soap->blist;
    1865   if (bp)
     2448soap_end_block(struct soap *soap, struct soap_blist *b)
     2449{ char *p, *q;
     2450  if (!b)
     2451    b = soap->blist;
     2452  if (b)
    18662453  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of block sequence, free all remaining blocks\n"));
    1867     for (p = bp->ptr; p; p = q)
     2454    for (p = b->ptr; p; p = q)
    18682455    { q = *(char**)p;
    1869       SOAP_FREE(p);
    1870     }
    1871     soap->blist = bp->next;
    1872     SOAP_FREE(bp);
     2456      SOAP_FREE(soap, p);
     2457    }
     2458    if (soap->blist == b)
     2459      soap->blist = b->next;
     2460    else
     2461    { struct soap_blist *bp;
     2462      for (bp = soap->blist; bp; bp = bp->next)
     2463      { if (bp->next == b)
     2464        { bp->next = b->next;
     2465          break;
     2466        }
     2467      }
     2468    }
     2469    SOAP_FREE(soap, b);
    18732470  }
    18742471  DBGLOG(TEST, if (soap->blist) SOAP_MESSAGE(fdebug, "Restore previous block sequence\n"));
     
    18812478char*
    18822479SOAP_FMAC2
    1883 soap_save_block(struct soap *soap, char *p, int flag)
     2480soap_save_block(struct soap *soap, struct soap_blist *b, char *p, int flag)
    18842481{ register size_t n;
    18852482  register char *q, *s;
    1886   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Save all blocks in contiguous memory space of %u bytes (%p->%p)\n", (unsigned int)soap->blist->size, soap->blist->ptr, p));
    1887   if (soap->blist->size)
     2483  if (!b)
     2484    b = soap->blist;
     2485  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Save all blocks in contiguous memory space of %u bytes (%p->%p)\n", (unsigned int)b->size, b->ptr, p));
     2486  if (b->size)
    18882487  { if (!p)
    1889       p = (char*)soap_malloc(soap, soap->blist->size);
     2488      p = (char*)soap_malloc(soap, b->size);
    18902489    if (p)
    1891     { for (s = p, q = soap_first_block(soap); q; q = soap_next_block(soap))
    1892       { n = soap_block_size(soap);
     2490    { for (s = p, q = soap_first_block(soap, b); q; q = soap_next_block(soap, b))
     2491      { n = soap_block_size(soap, b);
     2492#ifndef WITH_NOIDREF
    18932493        if (flag)
    1894           soap_update_ptrs(soap, q, q + n, (long)s - (long)q); /* pointers s and q may or may not be related */
     2494          soap_update_ptrs(soap, q, q + n, s, q);
     2495#endif
    18952496        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy %u bytes from %p to %p\n", (unsigned int)n, q, s));
    18962497        memcpy(s, q, n);
     
    19012502      soap->error = SOAP_EOM;
    19022503  }
    1903   soap_end_block(soap);
     2504  soap_end_block(soap, b);
    19042505  return p;
    19052506}
     
    20312632  if (!*attr1)
    20322633    return -1;
     2634  if (*attr1 == '[')
     2635    attr1++;
    20332636  n = 1;
    2034   do
    2035   { attr1++;
    2036     k = (int)soap_strtol(attr1, &s, 10);
     2637  for (;;)
     2638  { k = (int)soap_strtol(attr1, &s, 10);
    20372639    n *= k;
    20382640    if (k < 0 || n > SOAP_MAXARRAYSIZE || s == attr1)
     
    20502652      attr2 = s;
    20512653    }
    2052   } while (attr1 && *attr1 != ']');
     2654    if (!attr1)
     2655      break;
     2656    attr1++;
     2657  }
    20532658  return n - *j;
    20542659}
     
    20642669  if (!*attr)
    20652670    return -1;
    2066   i = strlen(attr);
     2671  i = (int)strlen(attr);
    20672672  n = 1;
    20682673  do
     
    21092714{ register struct soap_nlist *np;
    21102715  register struct Namespace *p;
    2111   np = (struct soap_nlist*)SOAP_MALLOC(sizeof(struct soap_nlist) + strlen(id));
     2716  register short i = -1;
     2717  register size_t n, k;
     2718  n = strlen(id);
     2719  k = strlen(ns) + 1;
     2720  p = soap->local_namespaces;
     2721  if (p)
     2722  { for (i = 0; p->id; p++, i++)
     2723    { if (p->ns && !strcmp(ns, p->ns))
     2724      { if (p->out)
     2725        { SOAP_FREE(soap, p->out);
     2726          p->out = NULL;
     2727        }
     2728        break;
     2729      }
     2730      if (p->out)
     2731      { if (!strcmp(ns, p->out))
     2732          break;
     2733      }
     2734      else if (p->in)
     2735      { if (!soap_tag_cmp(ns, p->in))
     2736        { if ((p->out = (char*)SOAP_MALLOC(soap, k)))
     2737            strcpy(p->out, ns);
     2738          break;
     2739        }
     2740      }
     2741    }
     2742    if (!p || !p->id)
     2743      i = -1;
     2744  }
     2745  if (i >= 0)
     2746    k = 0;
     2747  np = (struct soap_nlist*)SOAP_MALLOC(soap, sizeof(struct soap_nlist) + n + k);
    21122748  if (!np)
    21132749    return soap->error = SOAP_EOM;
    21142750  np->next = soap->nlist;
    21152751  soap->nlist = np;
     2752  np->level = soap->level;
     2753  np->index = i;
    21162754  strcpy(np->id, id);
    2117   np->level = soap->level;
    2118   np->index = -1;
    2119   np->ns = NULL;
    21202755  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push namespace binding (level=%u) '%s' '%s'\n", soap->level, id, ns));
    2121   p = soap->local_namespaces;
    2122   if (p)
    2123   { register short i = 0;
    2124     for (; p->id; p++, i++)
    2125     { if (p->ns && !strcmp(ns, p->ns))
    2126       { if (p->out)
    2127         { SOAP_FREE(p->out);
    2128           p->out = NULL;
    2129         }
    2130         break;
    2131       }
    2132       if (p->out)
    2133       { if (!SOAP_STRCMP(ns, p->out))
    2134           break;
    2135       }
    2136       else if (p->in)
    2137       { if (!soap_tag_cmp(ns, p->in))
    2138         { if ((p->out = (char*)SOAP_MALLOC(strlen(ns) + 1)))
    2139             strcpy(p->out, ns);
    2140           break;
    2141         }
    2142       }
    2143     }
    2144     if (p && p->id)
    2145     { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push OK ('%s' matches '%s' in namespace table)\n", id, p->id));
    2146       np->index = i;
    2147     }
    2148   }
    2149   if (!p || !p->id)
    2150   { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push NOT OK: no match found for '%s' in namespace mapping table (added to stack anyway)\n", ns));
    2151     np->ns = (char*)SOAP_MALLOC(strlen(ns) + 1);
    2152     if (!np->ns)
    2153       return soap->error = SOAP_EOM;
     2756  if (i < 0)
     2757  { np->ns = np->id + n + 1;
    21542758    strcpy(np->ns, ns);
     2759    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push NOT OK: no match found for '%s' in namespace mapping table (added to stack anyway)\n", ns));
     2760  }
     2761  else
     2762  { np->ns = NULL;
     2763    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push OK ('%s' matches '%s' in namespace table)\n", id, p->id));
    21552764  }
    21562765  return SOAP_OK;
     
    21642773SOAP_FMAC2
    21652774soap_pop_namespace(struct soap *soap)
    2166 { register struct soap_nlist *np;
    2167   while (soap->nlist && soap->nlist->level >= soap->level)
    2168   { np = soap->nlist->next;
    2169     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Popped namespace binding (level=%u) '%s'\n", soap->level, soap->nlist->id));
    2170     if (soap->nlist->ns)
    2171       SOAP_FREE(soap->nlist->ns);
    2172     SOAP_FREE(soap->nlist);
    2173     soap->nlist = np;
    2174   }
     2775{ register struct soap_nlist *np, *nq;
     2776  for (np = soap->nlist; np && np->level >= soap->level; np = nq)
     2777  { nq = np->next;
     2778    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Pop namespace binding (level=%u) '%s'\n", soap->level, np->id));
     2779    SOAP_FREE(soap, np);
     2780  }
     2781  soap->nlist = np;
    21752782}
    21762783#endif
     
    21812788int
    21822789SOAP_FMAC2
    2183 soap_match_namespace(struct soap *soap, const char *id1, const char *id2, int n1, int n2)
     2790soap_match_namespace(struct soap *soap, const char *id1, const char *id2, size_t n1, size_t n2)
    21842791{ register struct soap_nlist *np = soap->nlist;
    21852792  while (np && (strncmp(np->id, id1, n1) || np->id[n1]))
    21862793    np = np->next;
    21872794  if (np)
    2188   { if (np->index < 0 || (np->index >= 0 && soap->local_namespaces[np->index].id && (strncmp(soap->local_namespaces[np->index].id, id2, n2) || soap->local_namespaces[np->index].id[n2])))
     2795  { if (np->index < 0
     2796     || (soap->local_namespaces[np->index].id
     2797      && (strncmp(soap->local_namespaces[np->index].id, id2, n2)
     2798       || soap->local_namespaces[np->index].id[n2])))
    21892799      return SOAP_NAMESPACE;
    21902800    return SOAP_OK;
    21912801  }
    2192   if (n1 == 3 && n1 == n2 && !strcmp(id1, "xml") && !strcmp(id1, id2))
     2802  if (n1 == 3 && n1 == n2 && !strncmp(id1, "xml", 3) && !strncmp(id1, id2, 3))
    21932803    return SOAP_OK;
    2194   return SOAP_SYNTAX_ERROR;
     2804  return soap->error = SOAP_SYNTAX_ERROR;
     2805}
     2806#endif
     2807
     2808/******************************************************************************/
     2809#ifndef PALM_2
     2810SOAP_FMAC1
     2811const char*
     2812SOAP_FMAC2
     2813soap_current_namespace(struct soap *soap, const char *tag)
     2814{ register struct soap_nlist *np;
     2815  register const char *s;
     2816  if (!tag || !strncmp(tag, "xml", 3))
     2817    return NULL;
     2818  np = soap->nlist;
     2819  if (!(s = strchr(tag, ':')))
     2820  { while (np && *np->id) /* find default namespace, if present */
     2821      np = np->next;
     2822  }
     2823  else
     2824  { while (np && (strncmp(np->id, tag, s - tag) || np->id[s - tag]))
     2825      np = np->next;
     2826    if (!np)
     2827      soap->error = SOAP_NAMESPACE;
     2828  }
     2829  if (np)
     2830  { if (np->index >= 0)
     2831      return soap->namespaces[np->index].ns;
     2832    if (np->ns)
     2833      return soap_strdup(soap, np->ns);
     2834  }
     2835  return NULL;
    21952836}
    21962837#endif
     
    22172858      { if (c2 != '*')
    22182859          return 1;
    2219         c2 = *++t;
     2860        c2 = *++t;
    22202861        if (!c2)
    2221           return 0;
     2862          return 0;
    22222863        if (c2 >= 'A' && c2 <= 'Z')
    22232864          c2 += 'a' - 'A';
    22242865        for (;;)
    22252866        { c1 = *s;
    2226           if (!c1 || c1 == '"')
    2227             break;
    2228           if (c1 >= 'A' && c1 <= 'Z')
     2867          if (!c1 || c1 == '"')
     2868            break;
     2869          if (c1 >= 'A' && c1 <= 'Z')
    22292870            c1 += 'a' - 'A';
    2230           if (c1 == c2)
    2231             if (!soap_tag_cmp(s + 1, t + 1))
    2232               return 0;
    2233           s++;
     2871          if (c1 == c2 && !soap_tag_cmp(s + 1, t + 1))
     2872            return 0;
     2873          s++;
    22342874        }
    22352875        break;
     
    22522892soap_match_tag(struct soap *soap, const char *tag1, const char *tag2)
    22532893{ register const char *s, *t;
     2894  register int err;
    22542895  if (!tag1 || !tag2 || !*tag2)
    22552896    return SOAP_OK;
     
    22602901    { if (t[1] && SOAP_STRCMP(s + 1, t + 1))
    22612902        return SOAP_TAG_MISMATCH;
    2262       if (t != tag2 && soap_match_namespace(soap, tag1, tag2, s - tag1, t - tag2))
     2903      if (t != tag2 && (err = soap_match_namespace(soap, tag1, tag2, s - tag1, t - tag2)))
    22632904      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags '%s' and '%s' match but namespaces differ\n", tag1, tag2));
    2264         return SOAP_TAG_MISMATCH;
     2905        if (err == SOAP_NAMESPACE)
     2906          return SOAP_TAG_MISMATCH;
     2907        return err;
    22652908      }
    22662909    }
    22672910    else if (SOAP_STRCMP(tag1, t + 1))
    2268       return SOAP_TAG_MISMATCH;
    2269     else if (t != tag2 && soap_match_namespace(soap, tag1, tag2, 0, t - tag2))
     2911    { return SOAP_TAG_MISMATCH;
     2912    }
     2913    else if (t != tag2 && (err = soap_match_namespace(soap, tag1, tag2, 0, t - tag2)))
    22702914    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags '%s' and '%s' match but namespaces differ\n", tag1, tag2));
    2271       return SOAP_TAG_MISMATCH;
     2915      if (err == SOAP_NAMESPACE)
     2916        return SOAP_TAG_MISMATCH;
     2917      return err;
    22722918    }
    22732919    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags and (default) namespaces match: '%s' '%s'\n", tag1, tag2));
     
    23032949#endif
    23042950
    2305 /******************************************************************************/
     2951/******************************************************************************\
     2952 *
     2953 *      SSL
     2954 *
     2955\******************************************************************************/
    23062956
    23072957#ifdef WITH_OPENSSL
     2958/******************************************************************************/
     2959#ifndef PALM_2
     2960SOAP_FMAC1
     2961int
     2962SOAP_FMAC2
     2963soap_rand()
     2964{ unsigned char buf[4];
     2965  if (!soap_ssl_init_done)
     2966    soap_ssl_init();
     2967  RAND_pseudo_bytes(buf, 4);
     2968  return *(int*)buf;
     2969}
     2970#endif
     2971
    23082972/******************************************************************************/
    23092973#ifndef PALM_2
     
    23172981  soap->cafile = cafile;
    23182982  soap->capath = capath;
    2319   if (dhfile)
    2320   { soap->dhfile = dhfile;
    2321     soap->rsa = 0;
    2322   }
    2323   else
    2324   { soap->dhfile = NULL;
    2325     soap->rsa = 1;
    2326   }
     2983  soap->dhfile = dhfile;
    23272984  soap->randfile = randfile;
    2328   soap->require_client_auth = (flags & SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION);
     2985  soap->ssl_flags = flags | (dhfile == NULL ? SOAP_SSL_RSA : 0);
    23292986  if (!(err = soap->fsslauth(soap)))
    2330     if (sid)
    2331       SSL_CTX_set_session_id_context(soap->ctx, (unsigned char*)sid, strlen(sid));
     2987  { if (sid)
     2988      SSL_CTX_set_session_id_context(soap->ctx, (unsigned char*)sid, (unsigned int)strlen(sid));
     2989  }
    23322990  return err;
    23332991}
     
    23453003  soap->capath = capath;
    23463004  soap->dhfile = NULL;
    2347   soap->rsa = 0;
     3005  soap->ssl_flags = flags;
    23483006  soap->randfile = randfile;
    2349   soap->require_server_auth = (flags & SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION);
     3007  soap->fsslverify = (flags & SOAP_SSL_ALLOW_EXPIRED_CERTIFICATE) == 0 ? ssl_verify_callback : ssl_verify_callback_allow_expired_certificate;
    23503008  return soap->fsslauth(soap);
    23513009}
     
    23543012/******************************************************************************/
    23553013#ifndef PALM_2
    2356 static void
    2357 ssl_init()
    2358 { static int done = 0;
    2359   if (!done)
    2360   { done = 1;
     3014SOAP_FMAC1
     3015void
     3016SOAP_FMAC2
     3017soap_ssl_init()
     3018{ /* Note: for MT systems, the main program MUST call soap_ssl_init() before any threads are started */
     3019  if (!soap_ssl_init_done)
     3020  { soap_ssl_init_done = 1;
    23613021    SSL_library_init();
    23623022#ifndef WITH_LEAN
     
    23643024#endif
    23653025    if (!RAND_load_file("/dev/urandom", 1024))
    2366     { int r;
    2367 #ifdef HAVE_RAND_R
    2368       unsigned int s = (unsigned int)time(NULL);
    2369 #endif
    2370       char buf[SOAP_BUFLEN];
     3026    { char buf[1024];
    23713027      RAND_seed(buf, sizeof(buf));
    23723028      while (!RAND_status())
    2373       {
    2374 #ifdef HAVE_RAND_R
    2375         r = rand_r(&s);
    2376 #else
    2377         r = rand();
    2378 #endif
     3029      { int r = rand();
    23793030        RAND_seed(&r, sizeof(int));
    23803031      }
     
    23863037/******************************************************************************/
    23873038#ifndef PALM_1
    2388 static const char *
    2389 ssl_error(struct soap *soap, int ret)
     3039SOAP_FMAC1
     3040const char *
     3041SOAP_FMAC2
     3042soap_ssl_error(struct soap *soap, int ret)
    23903043{ int err = SSL_get_error(soap->ssl, ret);
    2391   const char *msg = soap_str_code(h_ssl_error_codes, err);
     3044  const char *msg = soap_code_str(h_ssl_error_codes, err);
    23923045  if (msg)
    23933046    strcpy(soap->msgbuf, msg);
     
    24203073{ if (num < (int)strlen((char*)userdata) + 1)
    24213074    return 0;
    2422   return strlen(strcpy(buf, (char*)userdata));
     3075  return (int)strlen(strcpy(buf, (char*)userdata));
    24233076}
    24243077#endif
     
    24583111#endif
    24593112*/
     3113
    24603114/******************************************************************************/
    24613115#ifndef PALM_1
    24623116static int
    24633117ssl_auth_init(struct soap *soap)
    2464 { ssl_init();
     3118{ long flags;
     3119  int mode;
     3120  if (!soap_ssl_init_done)
     3121    soap_ssl_init();
     3122  ERR_clear_error();
    24653123  if (!soap->ctx)
    2466     if (!(soap->ctx = SSL_CTX_new(SSLv23_method())))
     3124  { if (!(soap->ctx = SSL_CTX_new(SSLv23_method())))
    24673125      return soap_set_receiver_error(soap, "SSL error", "Can't setup context", SOAP_SSL_ERROR);
     3126    /* Alters the behavior of SSL read/write:
     3127    SSL_CTX_set_mode(soap->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_AUTO_RETRY);
     3128    */
     3129  }
    24683130  if (soap->randfile)
    24693131  { if (!RAND_load_file(soap->randfile, -1))
     
    24713133  }
    24723134  if (soap->cafile || soap->capath)
    2473     if (!SSL_CTX_load_verify_locations(soap->ctx, soap->cafile, soap->capath))
    2474       return soap_set_receiver_error(soap, "SSL error", "Can't read CA file and/or directory", SOAP_SSL_ERROR);
     3135  { if (!SSL_CTX_load_verify_locations(soap->ctx, soap->cafile, soap->capath))
     3136      return soap_set_receiver_error(soap, "SSL error", "Can't read CA file and directory", SOAP_SSL_ERROR);
     3137    if (soap->cafile && (soap->ssl_flags & SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION))
     3138      SSL_CTX_set_client_CA_list(soap->ctx, SSL_load_client_CA_file(soap->cafile));
     3139  }
    24753140  if (!SSL_CTX_set_default_verify_paths(soap->ctx))
    24763141    return soap_set_receiver_error(soap, "SSL error", "Can't read default CA file and/or directory", SOAP_SSL_ERROR);
     3142/* This code assumes a typical scenario, see alternative code below */
    24773143  if (soap->keyfile)
    24783144  { if (!SSL_CTX_use_certificate_chain_file(soap->ctx, soap->keyfile))
     
    24813147    { SSL_CTX_set_default_passwd_cb_userdata(soap->ctx, (void*)soap->password);
    24823148      SSL_CTX_set_default_passwd_cb(soap->ctx, ssl_password);
     3149    }
     3150    if (!SSL_CTX_use_PrivateKey_file(soap->ctx, soap->keyfile, SSL_FILETYPE_PEM))
     3151      return soap_set_receiver_error(soap, "SSL error", "Can't read key file", SOAP_SSL_ERROR);
     3152  }
     3153/* Suggested alternative approach to check the key file for certs (cafile=NULL):
     3154  if (soap->password)
     3155  { SSL_CTX_set_default_passwd_cb_userdata(soap->ctx, (void*)soap->password);
     3156    SSL_CTX_set_default_passwd_cb(soap->ctx, ssl_password);
     3157  }
     3158  if (!soap->cafile || !SSL_CTX_use_certificate_chain_file(soap->ctx, soap->cafile))
     3159  { if (soap->keyfile)
     3160    { if (!SSL_CTX_use_certificate_chain_file(soap->ctx, soap->keyfile))
     3161        return soap_set_receiver_error(soap, "SSL error", "Can't read certificate or key file", SOAP_SSL_ERROR);
    24833162      if (!SSL_CTX_use_PrivateKey_file(soap->ctx, soap->keyfile, SSL_FILETYPE_PEM))
    24843163        return soap_set_receiver_error(soap, "SSL error", "Can't read key file", SOAP_SSL_ERROR);
    24853164    }
    24863165  }
    2487   if (soap->rsa)
    2488   { RSA *rsa = RSA_generate_key(512, RSA_F4, NULL, NULL);
     3166*/
     3167  if ((soap->ssl_flags & SOAP_SSL_RSA))
     3168  { RSA *rsa = RSA_generate_key(1024, RSA_F4, NULL, NULL);
    24893169    if (!SSL_CTX_set_tmp_rsa(soap->ctx, rsa))
    24903170    { if (rsa)
     
    25093189    DH_free(dh);
    25103190  }
    2511   SSL_CTX_set_options(soap->ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2);
    2512   SSL_CTX_set_verify(soap->ctx, soap->require_client_auth ? (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT) : soap->require_server_auth ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, soap->fsslverify);
     3191  flags = (SSL_OP_ALL | SSL_OP_NO_SSLv2);
     3192  if ((soap->ssl_flags & SOAP_SSLv3))
     3193    flags |= SSL_OP_NO_TLSv1;
     3194  if ((soap->ssl_flags & SOAP_TLSv1))
     3195    flags |= SSL_OP_NO_SSLv3;
     3196  SSL_CTX_set_options(soap->ctx, flags);
     3197  if ((soap->ssl_flags & SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION))
     3198    mode = (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
     3199  else if ((soap->ssl_flags & SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION))
     3200    mode = SSL_VERIFY_PEER;
     3201  else
     3202    mode = SSL_VERIFY_NONE;
     3203  SSL_CTX_set_verify(soap->ctx, mode, soap->fsslverify);
    25133204#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
    25143205  SSL_CTX_set_verify_depth(soap->ctx, 1);
     
    25293220  { char data[256];
    25303221    X509 *cert = X509_STORE_CTX_get_current_cert(store);
    2531     fprintf(stderr, "SSL Verify error with certificate at depth %d: %s\n", X509_STORE_CTX_get_error_depth(store), X509_verify_cert_error_string(X509_STORE_CTX_get_error(store)));
     3222    fprintf(stderr, "SSL verify error or warning with certificate at depth %d: %s\n", X509_STORE_CTX_get_error_depth(store), X509_verify_cert_error_string(X509_STORE_CTX_get_error(store)));
    25323223    X509_NAME_oneline(X509_get_issuer_name(cert), data, sizeof(data));
    25333224    fprintf(stderr, "certificate issuer %s\n", data);
     
    25363227  }
    25373228#endif
    2538   /* return 1 to always continue, but unsafe progress will be terminated by SSL */
     3229  /* Note: return 1 to continue, but unsafe progress will be terminated by SSL */
    25393230  return ok;
    25403231}
     
    25433234/******************************************************************************/
    25443235#ifndef PALM_1
     3236static int
     3237ssl_verify_callback_allow_expired_certificate(int ok, X509_STORE_CTX *store)
     3238{ ok = ssl_verify_callback(ok, store);
     3239  if (ok == 0 && X509_STORE_CTX_get_error(store) == X509_V_ERR_CERT_HAS_EXPIRED)
     3240  {
     3241#ifdef SOAP_DEBUG
     3242    fprintf(stderr, "ignoring certificate expiration\n");
     3243#endif
     3244    X509_STORE_CTX_set_error(store, X509_V_OK);
     3245    ok = 1;
     3246  }
     3247  /* Note: return 1 to continue, but unsafe progress will be terminated by SSL */
     3248  return ok;
     3249}
     3250#endif
     3251
     3252/******************************************************************************/
     3253#ifndef PALM_1
    25453254SOAP_FMAC1
    25463255int
    25473256SOAP_FMAC2
    25483257soap_ssl_accept(struct soap *soap)
    2549 { int i, r;
     3258{ BIO *bio;
     3259  int retries, r, s;
    25503260  if (!soap_valid_socket(soap->socket))
    25513261    return soap_set_receiver_error(soap, "SSL error", "No socket in soap_ssl_accept()", SOAP_SSL_ERROR);
     3262  if (!soap->ctx && (soap->error = soap->fsslauth(soap)))
     3263    return SOAP_INVALID_SOCKET;
    25523264  if (!soap->ssl)
    25533265  { soap->ssl = SSL_new(soap->ctx);
     
    25593271  soap->imode |= SOAP_ENC_SSL;
    25603272  soap->omode |= SOAP_ENC_SSL;
    2561 #ifdef WIN32
    2562   { u_long nonblocking = 1;
    2563     ioctlsocket((SOAP_SOCKET)soap->socket, FIONBIO, &nonblocking);
    2564   }
    2565 #else
    2566   fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL)|O_NONBLOCK);
    2567 #endif
    2568   soap->bio = BIO_new_socket((SOAP_SOCKET)soap->socket, BIO_NOCLOSE);
    2569   SSL_set_bio(soap->ssl, soap->bio, soap->bio);
    2570   i = 100; /* 100 * 0.1 ms retries */
     3273  /* Set SSL sockets to non-blocking */
     3274  SOAP_SOCKNONBLOCK(soap->socket)
     3275  bio = BIO_new_socket((int)soap->socket, BIO_NOCLOSE);
     3276  SSL_set_bio(soap->ssl, bio, bio);
     3277  retries = 100; /* 10 sec retries, 100 times 0.1 sec */
    25713278  while ((r = SSL_accept(soap->ssl)) <= 0)
    25723279  { int err = SSL_get_error(soap->ssl, r);
     
    25743281    { struct timeval timeout;
    25753282      fd_set fd;
    2576       if (i-- <= 0)
    2577         break;
     3283#ifndef WIN32
     3284      if ((int)soap->socket >= (int)FD_SETSIZE)
     3285        return SOAP_FD_EXCEEDED;        /* Hint: MUST increase FD_SETSIZE */
     3286#endif
    25783287      timeout.tv_sec = 0;
    25793288      timeout.tv_usec = 100000;
    25803289      FD_ZERO(&fd);
    2581       FD_SET((SOAP_SOCKET)soap->socket, &fd);
    2582       r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout);
    2583       if (r < 0 && soap_socket_errno != SOAP_EINTR)
    2584       { soap->errnum = soap_socket_errno;
    2585         return SOAP_EOF;
     3290      FD_SET(soap->socket, &fd);
     3291      if (err == SSL_ERROR_WANT_READ)
     3292        s = select((int)soap->socket + 1, &fd, NULL, &fd, &timeout);
     3293      else
     3294        s = select((int)soap->socket + 1, NULL, &fd, &fd, &timeout);
     3295      if (s < 0 && (s = soap_socket_errno(soap->socket)) != SOAP_EINTR)
     3296      { soap->errnum = s;
     3297        break;
    25863298      }
    25873299    }
     
    25903302      break;
    25913303    }
    2592   }
    2593 #ifdef WIN32
    2594   { u_long blocking = 0;
    2595     ioctlsocket((SOAP_SOCKET)soap->socket, FIONBIO, &blocking);
    2596   }
    2597 #else
    2598   fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL)&~O_NONBLOCK);
    2599 #endif
     3304    if (retries-- <= 0)
     3305      break;
     3306  }
    26003307  if (r <= 0)
    2601   { soap_set_receiver_error(soap, ssl_error(soap, r), "SSL_accept() failed in soap_ssl_accept()", SOAP_SSL_ERROR);
     3308  { soap_set_receiver_error(soap, soap_ssl_error(soap, r), "SSL_accept() failed in soap_ssl_accept()", SOAP_SSL_ERROR);
    26023309    soap_closesock(soap);
    26033310    return SOAP_SSL_ERROR;
    26043311  }
    2605   if (soap->require_client_auth)
     3312  if ((soap->ssl_flags & SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION))
    26063313  { X509 *peer;
    26073314    int err;
     
    26253332
    26263333/******************************************************************************/
     3334#ifndef WITH_NOIO
    26273335#ifndef PALM_1
    26283336static int
     
    26423350}
    26433351#endif
     3352#endif
    26443353
    26453354/******************************************************************************/
     
    26533362  int i;
    26543363#endif
    2655   soap_free(soap);
     3364  if (soap_check_state(soap))
     3365    return;
     3366  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Done with context\n"));
     3367  soap_free_temp(soap);
    26563368  while (soap->clist)
    26573369  { struct soap_clist *p = soap->clist->next;
    2658     SOAP_FREE(soap->clist);
     3370    SOAP_FREE(soap, soap->clist);
    26593371    soap->clist = p;
    26603372  }
     
    26673379  { register struct soap_plugin *p = soap->plugins->next;
    26683380    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Removing plugin '%s'\n", soap->plugins->id));
    2669     if (soap->plugins->fcopy || !soap->copy)
     3381    if (soap->plugins->fcopy || soap->state == SOAP_INIT)
    26703382      soap->plugins->fdelete(soap, soap->plugins);
    2671     SOAP_FREE(soap->plugins);
     3383    SOAP_FREE(soap, soap->plugins);
    26723384    soap->plugins = p;
    26733385  }
    26743386  soap->fplugin = fplugin;
     3387  soap->fmalloc = NULL;
     3388#ifndef WITH_NOHTTP
    26753389  soap->fpost = http_post;
    26763390  soap->fget = http_get;
     3391  soap->fput = http_put;
     3392  soap->fdel = http_del;
     3393  soap->fhead = http_head;
     3394  soap->fform = NULL;
    26773395  soap->fposthdr = http_post_header;
    26783396  soap->fresponse = http_response;
    26793397  soap->fparse = http_parse;
    26803398  soap->fparsehdr = http_parse_header;
    2681 #ifndef MAC_CARBON
     3399#endif
     3400  soap->fheader = NULL;
     3401#ifndef WITH_NOIO
    26823402#ifndef WITH_IPV6
    26833403  soap->fresolve = tcp_gethost;
     
    26943414  soap->fpoll = soap_poll;
    26953415#else
     3416  soap->fopen = NULL;
     3417  soap->fclose = NULL;
    26963418  soap->fpoll = NULL;
    26973419#endif
     3420#ifndef WITH_LEANER
    26983421  soap->fprepareinit = NULL;
    26993422  soap->fpreparesend = NULL;
    27003423  soap->fpreparerecv = NULL;
     3424  soap->fpreparefinal = NULL;
     3425#endif
     3426  soap->fseterror = NULL;
    27013427  soap->fignore = NULL;
    27023428  soap->fserveloop = NULL;
     
    27073433  }
    27083434#endif
    2709   if (!soap->copy)
     3435  if (soap->state == SOAP_INIT)
    27103436  { if (soap_valid_socket(soap->master))
    2711     { soap->fclosesocket(soap, (SOAP_SOCKET)soap->master);
     3437    { soap->fclosesocket(soap, soap->master);
    27123438      soap->master = SOAP_INVALID_SOCKET;
    27133439    }
     3440  }
    27143441#ifdef WITH_OPENSSL
    2715     if (soap->ctx)
     3442  if (soap->ssl)
     3443  { SSL_free(soap->ssl);
     3444    soap->ssl = NULL;
     3445  }
     3446  if (soap->state == SOAP_INIT)
     3447  { if (soap->ctx)
    27163448    { SSL_CTX_free(soap->ctx);
    27173449      soap->ctx = NULL;
    27183450    }
    2719 #endif
    2720   }
     3451  }
     3452#endif
     3453#ifdef WITH_OPENSSL
     3454  ERR_remove_state(0);
     3455#endif
     3456#ifdef WITH_C_LOCALE
     3457  freelocale(soap->c_locale);
     3458#endif
     3459#ifdef WITH_ZLIB
     3460  if (soap->d_stream)
     3461  { SOAP_FREE(soap, (void*)soap->d_stream);
     3462    soap->d_stream = NULL;
     3463  }
     3464  if (soap->z_buf)
     3465  { SOAP_FREE(soap, (void*)soap->z_buf);
     3466    soap->z_buf = NULL;
     3467  }
     3468#endif
    27213469#ifdef SOAP_DEBUG
     3470  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free logfiles\n"));
    27223471  for (i = 0; i < SOAP_MAXLOGS; i++)
    2723   { soap_close_logfile(soap, i);
    2724     if (soap->logfile[i])
    2725     { SOAP_FREE((void*)soap->logfile[i]);
     3472  { if (soap->logfile[i])
     3473    { SOAP_FREE(soap, (void*)soap->logfile[i]);
    27263474      soap->logfile[i] = NULL;
    27273475    }
    2728   }
    2729 #endif
    2730 }
    2731 #endif
    2732 
    2733 /******************************************************************************/
     3476    soap_close_logfile(soap, i);
     3477  }
     3478  soap->state = SOAP_NONE;
     3479#endif
     3480#ifdef SOAP_MEM_DEBUG
     3481  soap_free_mht(soap);
     3482#endif
     3483}
     3484#endif
     3485
     3486/******************************************************************************/
     3487#ifndef WITH_NOIO
    27343488#ifndef PALM_2
    27353489SOAP_FMAC1
     
    27463500}
    27473501#endif
    2748 
    2749 /******************************************************************************/
     3502#endif
     3503
     3504/******************************************************************************/
     3505#ifndef WITH_NOIO
    27503506#ifndef PALM_1
    27513507static const char*
     
    27623518    {
    27633519#ifndef WITH_LEAN
    2764       msg = soap_str_code(h_error_codes, soap->errnum);
     3520      msg = soap_code_str(h_error_codes, soap->errnum);
    27653521      if (!msg)
    27663522#endif
    2767       { sprintf(soap->msgbuf, "TCP error %d", soap->errnum);
     3523      { sprintf(soap->msgbuf, "TCP/UDP IP error %d", soap->errnum);
    27683524        msg = soap->msgbuf;
    27693525      }
     
    27733529}
    27743530#endif
    2775 
    2776 /******************************************************************************/
     3531#endif
     3532
     3533/******************************************************************************/
     3534#ifndef WITH_NOHTTP
    27773535#ifndef PALM_1
    27783536static const char*
    27793537http_error(struct soap *soap, int status)
    2780 { register const char *msg = NULL;
     3538{ register const char *msg = SOAP_STR_EOS;
    27813539#ifndef WITH_LEAN
    2782   msg = soap_str_code(h_http_error_codes, status);
     3540  msg = soap_code_str(h_http_error_codes, status);
    27833541  if (!msg)
    2784 #endif
    2785   { sprintf(soap->msgbuf, "HTTP error %d", status);
    2786     msg = soap->msgbuf;
    2787   }
     3542    msg = SOAP_STR_EOS;
     3543#endif
    27883544  return msg;
    27893545}
    27903546#endif
    2791 
    2792 /******************************************************************************/
    2793 /* WR[ */
     3547#endif
     3548
     3549/******************************************************************************/
    27943550#ifndef WITH_IPV6
    2795 /* ]WR */
    2796 #ifndef MAC_CARBON
     3551#ifndef WITH_NOIO
    27973552#ifndef PALM_1
    27983553static int
    27993554tcp_gethost(struct soap *soap, const char *addr, struct in_addr *inaddr)
    2800 { unsigned long iadd;
     3555{ soap_int32 iadd = -1;
    28013556  struct hostent hostent, *host = &hostent;
    2802 /* WR[ */
    28033557#ifdef VXWORKS
    28043558  int hostint;
    2805   char *addrcopy = (char*)malloc(strlen(addr) + 1); /*copy of addr. */
    28063559  /* inet_addr(), and hostGetByName() expect "char *"; addr is a "const char *". */
    2807   strncpy(addrcopy, addr, strlen(addr)+1);
    2808   iadd = inet_addr(addrcopy);
     3560  iadd = inet_addr((char*)addr);
    28093561#else
    2810 /* ]WR */
    2811 #if defined(_AIXVERSION_431) || defined(TRU64)
     3562#if defined(_AIX43) || ((defined(TRU64) || defined(HP_UX)) && defined(HAVE_GETHOSTBYNAME_R))
    28123563  struct hostent_data ht_data;
    28133564#endif
     3565#ifdef AS400
     3566  iadd = inet_addr((void*)addr);
     3567#else
    28143568  iadd = inet_addr(addr);
    2815 /* WR[ */
    2816 #endif
    2817 /* ]WR */
    2818   if ((int)iadd != -1)
     3569#endif
     3570#endif
     3571  if (iadd != -1)
    28193572  { memcpy(inaddr, &iadd, sizeof(iadd));
    2820 /* WR[ */
    2821 #ifdef VXWORKS
    2822     free(addrcopy);
    2823 #endif
    2824 /* ]WR */
    28253573    return SOAP_OK;
    28263574  }
    2827 #if defined(__GLIBC__)
     3575#if defined(__GLIBC__) || (defined(HAVE_GETHOSTBYNAME_R) && (defined(FREEBSD) || defined(__FreeBSD__)))
    28283576  if (gethostbyname_r(addr, &hostent, soap->buf, SOAP_BUFLEN, &host, &soap->errnum) < 0)
    28293577    host = NULL;
    2830 #elif defined(_AIXVERSION_431) || defined(TRU64)
     3578#elif defined(_AIX43) || ((defined(TRU64) || defined(HP_UX)) && defined(HAVE_GETHOSTBYNAME_R))
    28313579  memset((void*)&ht_data, 0, sizeof(ht_data));
    28323580  if (gethostbyname_r(addr, &hostent, &ht_data) < 0)
     
    28363584#elif defined(HAVE_GETHOSTBYNAME_R)
    28373585  host = gethostbyname_r(addr, &hostent, soap->buf, SOAP_BUFLEN, &soap->errnum);
    2838 /* WR[ */
    28393586#elif defined(VXWORKS)
    28403587  /* If the DNS resolver library resolvLib has been configured in the vxWorks
    28413588   * image, a query for the host IP address is sent to the DNS server, if the
    28423589   * name was not found in the local host table. */
    2843   hostint = hostGetByName(addrcopy);
     3590  hostint = hostGetByName((char*)addr);
    28443591  if (hostint == ERROR)
    28453592  { host = NULL;
    28463593    soap->errnum = soap_errno;
    28473594  }
    2848   free(addrcopy);  /*free() is placed after the error checking to assure that
    2849                     * errno captured is that from hostGetByName() */
    2850 /* ]WR */
     3595#else
     3596#ifdef AS400
     3597  if (!(host = gethostbyname((void*)addr)))
     3598    soap->errnum = h_errno;
    28513599#else
    28523600  if (!(host = gethostbyname(addr)))
    28533601    soap->errnum = h_errno;
    28543602#endif
     3603#endif
    28553604  if (!host)
    28563605  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Host name not found\n"));
    28573606    return SOAP_ERR;
    28583607  }
    2859 /* WR[ */
    28603608#ifdef VXWORKS
    28613609  inaddr->s_addr = hostint;
    28623610#else
    2863 /* ]WR */
    28643611  memcpy(inaddr, host->h_addr, host->h_length);
    2865 /* WR[ */
    2866 #endif
    2867 /* ]WR */
     3612#endif
    28683613  return SOAP_OK;
    28693614}
    28703615#endif
    28713616#endif
    2872 /* WR[ */
    2873 #endif /* WITH_IPV6 */
    2874 /* ]WR */
    2875 
    2876 /******************************************************************************/
    2877 #ifndef MAC_CARBON
    2878 #ifndef PALM_1
    2879 static int
     3617#endif
     3618
     3619/******************************************************************************/
     3620#ifndef WITH_NOIO
     3621#ifndef PALM_1
     3622static SOAP_SOCKET
    28803623tcp_connect(struct soap *soap, const char *endpoint, const char *host, int port)
    2881 { struct sockaddr_in sockaddr;
    2882 /* WR[ */
     3624{
    28833625#ifdef WITH_IPV6
    2884   struct addrinfo *addrinfo;
    2885   struct addrinfo hints;
    2886   struct addrinfo resaddr;
    2887   struct sockaddr_storage addrstorage;
    2888   int err;
    2889 #endif /* WITH_IPV6 */
    2890 /* ]WR */
    2891   register int fd;
     3626  struct addrinfo hints, *res, *ressave;
     3627#endif
     3628  SOAP_SOCKET fd;
     3629  int err = 0;
    28923630#ifndef WITH_LEAN
     3631  int retry = 10;
    28933632  int len = SOAP_BUFLEN;
    28943633  int set = 1;
    28953634#endif
    28963635  if (soap_valid_socket(soap->socket))
    2897     soap->fclosesocket(soap, (SOAP_SOCKET)soap->socket);
     3636    soap->fclosesocket(soap, soap->socket);
    28983637  soap->socket = SOAP_INVALID_SOCKET;
    28993638  if (tcp_init(soap))
    2900   { soap_set_sender_error(soap, tcp_error(soap), "TCP initialization failed in tcp_connect()", SOAP_TCP_ERROR);
    2901     return -1;
     3639  { soap->errnum = 0;
     3640    soap_set_sender_error(soap, tcp_error(soap), "TCP init failed in tcp_connect()", SOAP_TCP_ERROR);
     3641    return SOAP_INVALID_SOCKET;
    29023642  }
    29033643  soap->errmode = 0;
    2904 /* WR[ */
    29053644#ifdef WITH_IPV6
    29063645  memset((void*)&hints, 0, sizeof(hints));
    29073646  hints.ai_family = PF_UNSPEC;
    2908   hints.ai_socktype = SOCK_STREAM;
     3647#ifndef WITH_LEAN
     3648  if ((soap->omode & SOAP_IO_UDP))
     3649    hints.ai_socktype = SOCK_DGRAM;
     3650  else
     3651#endif
     3652    hints.ai_socktype = SOCK_STREAM;
    29093653  soap->errmode = 2;
    29103654  if (soap->proxy_host)
    2911     err = getaddrinfo(soap->proxy_host, soap_int2s(soap, soap->proxy_port), &hints, &addrinfo);
     3655    err = getaddrinfo(soap->proxy_host, soap_int2s(soap, soap->proxy_port), &hints, &res);
    29123656  else
    2913     err = getaddrinfo(host, soap_int2s(soap, port), &hints, &addrinfo);
    2914   if (addrinfo)
    2915   { resaddr = *addrinfo;
    2916     addrstorage = *((struct sockaddr_storage*)addrinfo->ai_addr);
    2917     resaddr.ai_addr = (struct sockaddr*)&addrstorage;
    2918     freeaddrinfo(addrinfo);
    2919   }
     3657    err = getaddrinfo(host, soap_int2s(soap, port), &hints, &res);
    29203658  if (err)
    2921   { soap_set_sender_error(soap, gai_strerror(err),
    2922     "TCP getaddrinfo on proxy host failed in tcp_connect()", SOAP_TCP_ERROR);
    2923     return -1;
    2924   }
    2925   fd = (int)socket(resaddr.ai_family, resaddr.ai_socktype, resaddr.ai_protocol); /* modified to use fd */
     3659  { soap_set_sender_error(soap, SOAP_GAI_STRERROR(err), "getaddrinfo failed in tcp_connect()", SOAP_TCP_ERROR);
     3660    return SOAP_INVALID_SOCKET;
     3661  }
     3662  ressave = res;
     3663again:
     3664  fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    29263665  soap->errmode = 0;
    2927 #else /* WITH_IPV6 */
    2928 /* ]WR */
    2929   fd = (int)socket(AF_INET, SOCK_STREAM, 0);
    2930 /* WR[ */
    2931 #endif /* WITH_IPV6 */
    2932 /* ]WR */
    2933   if (fd < 0)
    2934   { soap->errnum = soap_socket_errno;
    2935     soap_set_sender_error(soap, tcp_error(soap), "TCP socket failed in tcp_connect()", SOAP_TCP_ERROR);
    2936     return -1;
     3666#else
     3667#ifndef WITH_LEAN
     3668again:
     3669#endif
     3670#ifndef WITH_LEAN
     3671  if ((soap->omode & SOAP_IO_UDP))
     3672    fd = socket(AF_INET, SOCK_DGRAM, 0);
     3673  else
     3674#endif
     3675    fd = socket(AF_INET, SOCK_STREAM, 0);
     3676#endif
     3677  if (!soap_valid_socket(fd))
     3678  {
     3679#ifdef WITH_IPV6
     3680    if (res->ai_next)
     3681    { res = res->ai_next;
     3682      goto again;
     3683    }
     3684#endif
     3685    soap->errnum = soap_socket_errno(fd);
     3686    soap_set_sender_error(soap, tcp_error(soap), "socket failed in tcp_connect()", SOAP_TCP_ERROR);
     3687#ifdef WITH_IPV6
     3688    freeaddrinfo(ressave);
     3689#endif
     3690    return SOAP_INVALID_SOCKET;
    29373691  }
    29383692#ifdef SOCKET_CLOSE_ON_EXEC
     
    29423696#endif
    29433697#else
    2944   fcntl (fd, F_SETFD, 1);
     3698  fcntl(fd, F_SETFD, 1);
    29453699#endif
    29463700#endif
    29473701#ifndef WITH_LEAN
    2948   if (soap->connect_flags & SO_LINGER)
     3702  if (soap->connect_flags == SO_LINGER)
    29493703  { struct linger linger;
    29503704    memset((void*)&linger, 0, sizeof(linger));
    29513705    linger.l_onoff = 1;
    2952     linger.l_linger = 0;
    2953     if (setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger)))
    2954     { soap->errnum = soap_socket_errno;
    2955       soap_set_sender_error(soap, tcp_error(soap), "TCP setsockopt SO_LINGER failed in tcp_connect()", SOAP_TCP_ERROR);
    2956       soap->fclosesocket(soap, (SOAP_SOCKET)fd);
    2957       return -1;
    2958     }
    2959   }
    2960   if ((soap->connect_flags & ~SO_LINGER) && setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, soap->connect_flags & ~SO_LINGER, (char*)&set, sizeof(int)))
    2961   { soap->errnum = soap_socket_errno;
    2962     soap_set_sender_error(soap, tcp_error(soap), "TCP setsockopt failed in tcp_connect()", SOAP_TCP_ERROR);
     3706    linger.l_linger = soap->linger_time;
     3707    if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger)))
     3708    { soap->errnum = soap_socket_errno(fd);
     3709      soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_LINGER failed in tcp_connect()", SOAP_TCP_ERROR);
     3710      soap->fclosesocket(soap, fd);
     3711#ifdef WITH_IPV6
     3712      freeaddrinfo(ressave);
     3713#endif
     3714      return SOAP_INVALID_SOCKET;
     3715    }
     3716  }
     3717  else if (soap->connect_flags && setsockopt(fd, SOL_SOCKET, soap->connect_flags, (char*)&set, sizeof(int)))
     3718  { soap->errnum = soap_socket_errno(fd);
     3719    soap_set_sender_error(soap, tcp_error(soap), "setsockopt failed in tcp_connect()", SOAP_TCP_ERROR);
     3720    soap->fclosesocket(soap, fd);
     3721#ifdef WITH_IPV6
     3722    freeaddrinfo(ressave);
     3723#endif
     3724    return SOAP_INVALID_SOCKET;
     3725  }
     3726  if ((soap->keep_alive || soap->tcp_keep_alive) && setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int)))
     3727  { soap->errnum = soap_socket_errno(fd);
     3728    soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in tcp_connect()", SOAP_TCP_ERROR);
     3729    soap->fclosesocket(soap, fd);
     3730#ifdef WITH_IPV6
     3731    freeaddrinfo(ressave);
     3732#endif
     3733    return SOAP_INVALID_SOCKET;
     3734  }
     3735  if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int)))
     3736  { soap->errnum = soap_socket_errno(fd);
     3737    soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in tcp_connect()", SOAP_TCP_ERROR);
     3738    soap->fclosesocket(soap, fd);
     3739#ifdef WITH_IPV6
     3740    freeaddrinfo(ressave);
     3741#endif
     3742    return SOAP_INVALID_SOCKET;
     3743  }
     3744  if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int)))
     3745  { soap->errnum = soap_socket_errno(fd);
     3746    soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in tcp_connect()", SOAP_TCP_ERROR);
     3747    soap->fclosesocket(soap, fd);
     3748#ifdef WITH_IPV6
     3749    freeaddrinfo(ressave);
     3750#endif
     3751    return SOAP_INVALID_SOCKET;
     3752  }
     3753#ifdef TCP_KEEPIDLE
     3754  if (soap->tcp_keep_idle && setsockopt((SOAP_SOCKET)fd, IPPROTO_TCP, TCP_KEEPIDLE, (unsigned int*)&(soap->tcp_keep_idle), sizeof(int)))
     3755  { soap->errnum = soap_socket_errno(fd);
     3756    soap_set_sender_error(soap, tcp_error(soap), "setsockopt TCP_KEEPIDLE failed in tcp_connect()", SOAP_TCP_ERROR);
    29633757    soap->fclosesocket(soap, (SOAP_SOCKET)fd);
    2964     return -1;
    2965   }
    2966   if (soap->keep_alive && setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int)))
    2967   { soap->errnum = soap_socket_errno;
    2968     soap_set_sender_error(soap, tcp_error(soap), "TCP setsockopt SO_KEEPALIVE failed in tcp_connect()", SOAP_TCP_ERROR);
     3758#ifdef WITH_IPV6
     3759    freeaddrinfo(ressave);
     3760#endif
     3761    return SOAP_INVALID_SOCKET;
     3762  }
     3763#endif
     3764#ifdef TCP_KEEPINTVL
     3765  if (soap->tcp_keep_intvl && setsockopt((SOAP_SOCKET)fd, IPPROTO_TCP, TCP_KEEPINTVL, (unsigned int*)&(soap->tcp_keep_intvl), sizeof(int)))
     3766  { soap->errnum = soap_socket_errno(fd);
     3767    soap_set_sender_error(soap, tcp_error(soap), "setsockopt TCP_KEEPINTVL failed in tcp_connect()", SOAP_TCP_ERROR);
    29693768    soap->fclosesocket(soap, (SOAP_SOCKET)fd);
    2970     return -1;
    2971   }
    2972   if (setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int)))
    2973   { soap->errnum = soap_socket_errno;
    2974     soap_set_sender_error(soap, tcp_error(soap), "TCP setsockopt SO_SNDBUF failed in tcp_connect()", SOAP_TCP_ERROR);
     3769#ifdef WITH_IPV6
     3770    freeaddrinfo(ressave);
     3771#endif
     3772    return SOAP_INVALID_SOCKET;
     3773  }
     3774#endif
     3775#ifdef TCP_KEEPCNT
     3776  if (soap->tcp_keep_cnt && setsockopt((SOAP_SOCKET)fd, IPPROTO_TCP, TCP_KEEPCNT, (unsigned int*)&(soap->tcp_keep_cnt), sizeof(int)))
     3777  { soap->errnum = soap_socket_errno(fd);
     3778    soap_set_sender_error(soap, tcp_error(soap), "setsockopt TCP_KEEPCNT failed in tcp_connect()", SOAP_TCP_ERROR);
    29753779    soap->fclosesocket(soap, (SOAP_SOCKET)fd);
    2976     return -1;
    2977   }
    2978   if (setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int)))
    2979   { soap->errnum = soap_socket_errno;
    2980     soap_set_sender_error(soap, tcp_error(soap), "TCP setsockopt SO_RCVBUF failed in tcp_connect()", SOAP_TCP_ERROR);
    2981     soap->fclosesocket(soap, (SOAP_SOCKET)fd);
    2982     return -1;
    2983   }
     3780#ifdef WITH_IPV6
     3781    freeaddrinfo(ressave);
     3782#endif
     3783    return SOAP_INVALID_SOCKET;
     3784  }
     3785#endif
    29843786#ifdef TCP_NODELAY
    2985   if (setsockopt((SOAP_SOCKET)fd, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int)))
    2986   { soap->errnum = soap_socket_errno;
    2987     soap_set_sender_error(soap, tcp_error(soap), "TCP setsockopt TCP_NODELAY failed in tcp_connect()", SOAP_TCP_ERROR);
    2988     soap->fclosesocket(soap, (SOAP_SOCKET)fd);
    2989     return -1;
    2990   }
    2991 #endif
    2992 #endif
    2993 /* WR[ */
     3787  if (!(soap->omode & SOAP_IO_UDP) && setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int)))
     3788  { soap->errnum = soap_socket_errno(fd);
     3789    soap_set_sender_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in tcp_connect()", SOAP_TCP_ERROR);
     3790    soap->fclosesocket(soap, fd);
     3791#ifdef WITH_IPV6
     3792    freeaddrinfo(ressave);
     3793#endif
     3794    return SOAP_INVALID_SOCKET;
     3795  }
     3796#endif
     3797#ifdef WITH_IPV6
     3798  if ((soap->omode & SOAP_IO_UDP) && soap->ipv6_multicast_if)
     3799  { struct sockaddr_in6 *in6addr = (struct sockaddr_in6*)res->ai_addr;
     3800    in6addr->sin6_scope_id = soap->ipv6_multicast_if;
     3801  }
     3802#else
     3803  if ((soap->omode & SOAP_IO_UDP) && soap->ipv4_multicast_if)
     3804  { if (soap->ipv4_multicast_ttl > 0)
     3805    { char ttl = (char)(soap->ipv4_multicast_ttl);
     3806      if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)))
     3807      { soap->errnum = soap_socket_errno(fd);
     3808        soap_set_sender_error(soap, tcp_error(soap), "setsockopt IP_MULTICAST_TTL failed in tcp_connect()", SOAP_TCP_ERROR);
     3809        soap->fclosesocket(soap, fd);
     3810        return SOAP_INVALID_SOCKET;
     3811      }
     3812    }
     3813#ifndef WINDOWS
     3814    if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, soap->ipv4_multicast_if, sizeof(struct in_addr)))
     3815    { soap->errnum = soap_socket_errno(fd);
     3816      soap_set_sender_error(soap, tcp_error(soap), "setsockopt IP_MULTICAST_IF failed in tcp_connect()", SOAP_TCP_ERROR);
     3817      soap->fclosesocket(soap, fd);
     3818      return SOAP_INVALID_SOCKET;
     3819    }
     3820#else
     3821#ifndef IP_MULTICAST_IF
     3822#define IP_MULTICAST_IF 2
     3823#endif
     3824    if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, soap->ipv4_multicast_if, sizeof(struct in_addr)))
     3825    { soap->errnum = soap_socket_errno(fd);
     3826      soap_set_sender_error(soap, tcp_error(soap), "setsockopt IP_MULTICAST_IF failed in tcp_connect()", SOAP_TCP_ERROR);
     3827      soap->fclosesocket(soap, fd);
     3828      return SOAP_INVALID_SOCKET;
     3829    }
     3830#endif
     3831  }
     3832#endif
     3833#endif
     3834  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Opening socket %d to host='%s' port=%d\n", fd, host, port));
    29943835#ifndef WITH_IPV6
    2995 /* ]WR */
    2996   memset((void*)&sockaddr, 0, sizeof(sockaddr));
    2997   sockaddr.sin_family = AF_INET;
    2998   DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Open socket %d to host='%s'\n", fd, host));
     3836  soap->peerlen = sizeof(soap->peer);
     3837  memset((void*)&soap->peer, 0, sizeof(soap->peer));
     3838  soap->peer.sin_family = AF_INET;
    29993839  soap->errmode = 2;
    30003840  if (soap->proxy_host)
    3001   { if (soap->fresolve(soap, soap->proxy_host, &sockaddr.sin_addr))
    3002     { soap_set_sender_error(soap, tcp_error(soap), "TCP get proxy host by name failed in tcp_connect()", SOAP_TCP_ERROR);
    3003       soap->fclosesocket(soap, (SOAP_SOCKET)fd);
    3004       return -1;
    3005     }
    3006     sockaddr.sin_port = htons((short)soap->proxy_port);
     3841  { if (soap->fresolve(soap, soap->proxy_host, &soap->peer.sin_addr))
     3842    { soap_set_sender_error(soap, tcp_error(soap), "get proxy host by name failed in tcp_connect()", SOAP_TCP_ERROR);
     3843      soap->fclosesocket(soap, fd);
     3844#ifdef WITH_IPV6
     3845      freeaddrinfo(ressave);
     3846#endif
     3847      return SOAP_INVALID_SOCKET;
     3848    }
     3849    soap->peer.sin_port = htons((short)soap->proxy_port);
    30073850  }
    30083851  else
    3009   { if (soap->fresolve(soap, host, &sockaddr.sin_addr))
    3010     { soap_set_sender_error(soap, tcp_error(soap), "TCP get host by name failed in tcp_connect()", SOAP_TCP_ERROR);
    3011       soap->fclosesocket(soap, (SOAP_SOCKET)fd);
    3012       return -1;
    3013     }
    3014     sockaddr.sin_port = htons((short)port);
     3852  { if (soap->fresolve(soap, host, &soap->peer.sin_addr))
     3853    { soap_set_sender_error(soap, tcp_error(soap), "get host by name failed in tcp_connect()", SOAP_TCP_ERROR);
     3854      soap->fclosesocket(soap, fd);
     3855#ifdef WITH_IPV6
     3856      freeaddrinfo(ressave);
     3857#endif
     3858      return SOAP_INVALID_SOCKET;
     3859    }
     3860    soap->peer.sin_port = htons((short)port);
    30153861  }
    30163862  soap->errmode = 0;
    3017 /* WR[ */
    3018 #endif /* WITH_IPV6 */
    3019 /* ]WR */
     3863#ifndef WITH_LEAN
     3864  if ((soap->omode & SOAP_IO_UDP))
     3865  {
     3866#ifdef WITH_IPV6
     3867    freeaddrinfo(ressave);
     3868#endif
     3869    return fd;
     3870  }
     3871#endif
     3872#endif
    30203873#ifndef WITH_LEAN
    30213874  if (soap->connect_timeout)
    3022 #if defined(WIN32)
    3023   { u_long nonblocking = 1;
    3024     ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &nonblocking);
    3025   }
    3026 /* WR[ */
    3027 #elif defined(VXWORKS)
    3028   { vx_nonblocking = TRUE;
    3029     ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&vx_nonblocking)); /* modified to use fd */
    3030   }
    3031 /* ]WR */
    3032 #else
    3033     fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)|O_NONBLOCK);
    3034 #endif
     3875    SOAP_SOCKNONBLOCK(fd)
    30353876  else
    3036 #if defined(WIN32)
    3037   { u_long blocking = 0;
    3038     ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &blocking);
    3039   }
    3040 /* WR[ */
    3041 #elif defined(VXWORKS)
    3042   { vx_nonblocking = FALSE;
    3043     ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&vx_nonblocking)); /* modified to use fd */
    3044   }
    3045 /* ]WR */
    3046 #else
    3047     fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)&~O_NONBLOCK);
    3048 #endif
     3877    SOAP_SOCKBLOCK(fd)
    30493878#endif
    30503879  for (;;)
    30513880  {
    3052 /* WR[ */
    30533881#ifdef WITH_IPV6
    3054     if (connect((SOAP_SOCKET)fd, resaddr.ai_addr, resaddr.ai_addrlen)) /* modified to use fd */
    3055 #else /* WITH_IPV6 */
    3056     if (connect((SOAP_SOCKET)fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr)))
    3057 #endif /* WITH_IPV6 */
    3058 /* ]WR */
    3059     {
     3882    if (connect(fd, res->ai_addr, (int)res->ai_addrlen))
     3883#else
     3884    if (connect(fd, (struct sockaddr*)&soap->peer, sizeof(soap->peer)))
     3885#endif
     3886    { err = soap_socket_errno(fd);
    30603887#ifndef WITH_LEAN
    3061       if (soap->connect_timeout && (soap_socket_errno == SOAP_EINPROGRESS || soap_socket_errno == SOAP_EWOULDBLOCK))
    3062       { struct timeval timeout;
    3063 #if defined(SOCKLEN_T)
    3064         SOCKLEN_T n = sizeof(struct sockaddr_in);
    3065 #elif defined(__socklen_t_defined) || defined(_SOCKLEN_T) || defined(CYGWIN)
    3066         socklen_t n = sizeof(struct sockaddr_in);
    3067 #elif defined(WIN32) || defined(__APPLE__) || defined(HP_UX) || defined(SUN_OS) || defined(OPENSERVER) || defined(TRU64) || defined(VXWORKS)
    3068         int n = sizeof(struct sockaddr_in);
    3069 #else
    3070         size_t n = sizeof(struct sockaddr_in);
    3071 #endif
    3072         fd_set fds;
    3073         if (soap->connect_timeout > 0)
    3074         { timeout.tv_sec = soap->connect_timeout;
    3075           timeout.tv_usec = 0;
     3888      if (err == SOAP_EADDRINUSE)
     3889      { soap->fclosesocket(soap, fd);
     3890        if (retry-- > 0)
     3891          goto again;
     3892      }
     3893      else if (soap->connect_timeout && (err == SOAP_EINPROGRESS || err == SOAP_EAGAIN || err == SOAP_EWOULDBLOCK))
     3894      {
     3895        SOAP_SOCKLEN_T k;
     3896#ifndef WIN32
     3897        if ((int)soap->socket >= (int)FD_SETSIZE)
     3898        { soap->error = SOAP_FD_EXCEEDED;
     3899#ifdef WITH_IPV6
     3900          freeaddrinfo(ressave);
     3901#endif
     3902          return SOAP_INVALID_SOCKET;   /* Hint: MUST increase FD_SETSIZE */
    30763903        }
    3077         else
    3078         { timeout.tv_sec = -soap->connect_timeout/1000000;
    3079           timeout.tv_usec = -soap->connect_timeout%1000000;
    3080         }
    3081         FD_ZERO(&fds);
    3082         FD_SET((SOAP_SOCKET)fd, &fds);
     3904#endif
    30833905        for (;;)
    3084         { int r = select((SOAP_SOCKET)(fd + 1), NULL, &fds, NULL, &timeout);
    3085           if (r > 0)
    3086             break;
    3087           if (!r)
    3088           { soap->errnum = 0;
    3089             DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connect timeout\n"));
    3090             soap_set_sender_error(soap, "Timeout", "TCP connect failed in tcp_connect()", SOAP_TCP_ERROR);
    3091             soap->fclosesocket(soap, (SOAP_SOCKET)fd);
    3092             return -1;
    3093           }
    3094           if (soap_socket_errno != SOAP_EINTR)
    3095           { soap->errnum = soap_socket_errno;
    3096             DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
    3097             soap_set_sender_error(soap, tcp_error(soap), "TCP connect failed in tcp_connect()", SOAP_TCP_ERROR);
    3098             soap->fclosesocket(soap, (SOAP_SOCKET)fd);
    3099             return -1;
    3100           }
    3101         }
    3102         n = sizeof(soap->errnum);
    3103         if (!getsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_ERROR, (char*)&soap->errnum, &n) && !soap->errnum)
    3104           break;
    3105         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
    3106         soap_set_sender_error(soap, tcp_error(soap), "TCP connect failed in tcp_connect()", SOAP_TCP_ERROR);
    3107         soap->fclosesocket(soap, (SOAP_SOCKET)fd);
    3108         return -1;
    3109       }
    3110       else
    3111 #endif
    3112       if (soap_socket_errno != SOAP_EINTR)
    3113       { soap->errnum = soap_socket_errno;
    3114         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
    3115         soap_set_sender_error(soap, tcp_error(soap), "TCP connect failed in tcp_connect()", SOAP_TCP_ERROR);
    3116         soap->fclosesocket(soap, (SOAP_SOCKET)fd);
    3117         return -1;
    3118       }
    3119     } 
    3120     else
    3121       break;
    3122   }
    3123 #ifndef WITH_LEAN
    3124   if (soap->connect_timeout)
    3125 #if defined(WIN32)
    3126   { u_long blocking = 0;
    3127     ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &blocking);
    3128   }
    3129 /* WR[ */
    3130 #elif defined(VXWORKS)
    3131   { vx_nonblocking = FALSE;
    3132     ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&vx_nonblocking)); /* modified to use fd */
    3133   }
    3134 /* ]WR */
    3135 #else
    3136     fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)&~O_NONBLOCK);
    3137 #endif
    3138 #endif
    3139   soap->socket = fd;
    3140 #ifdef WITH_OPENSSL
    3141   soap->imode &= ~SOAP_ENC_SSL;
    3142   soap->omode &= ~SOAP_ENC_SSL;
    3143   if (!strncmp(endpoint, "https:", 6))
    3144   { int r;
    3145     if (soap->proxy_host)
    3146     { unsigned int k = soap->omode; /* make sure we only parse HTTP */
    3147       size_t n = soap->count; /* save the content length */
    3148       soap->omode &= ~0xFF; /* mask IO and ENC */
    3149       soap->omode |= SOAP_IO_BUFFER;
    3150       soap_begin_send(soap);
    3151       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connecting to proxy server\n"));
    3152       sprintf(soap->tmpbuf, "CONNECT %s:%d HTTP/%s", host, port, soap->http_version);
    3153       if ((soap->error = soap->fposthdr(soap, soap->tmpbuf, NULL)))
    3154         return -1;
    3155 #ifndef WITH_LEAN
    3156       if (soap->proxy_userid && soap->proxy_passwd && strlen(soap->proxy_userid) + strlen(soap->proxy_passwd) < 761)
    3157       { sprintf(soap->tmpbuf + 262, "%s:%s", soap->proxy_userid, soap->proxy_passwd);
    3158         strcpy(soap->tmpbuf, "Basic ");
    3159         soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, strlen(soap->tmpbuf + 262));
    3160         if ((soap->error = soap->fposthdr(soap, "Proxy-Authorization", soap->tmpbuf)))
    3161           return soap->error;
    3162       }
    3163 #endif
    3164       if ((soap->error = soap->fposthdr(soap, NULL, NULL))
    3165        || soap_flush(soap))
    3166         return -1;
    3167       soap->omode = k;
    3168       k = soap->imode;
    3169       soap->imode &= ~0xFF; /* mask IO and ENC */
    3170       if (soap_begin_recv(soap))
    3171         return -1;
    3172       soap->imode = k;
    3173       soap->count = n;
    3174       soap_begin_send(soap);
    3175     }
    3176     if (!soap->ctx && (soap->error = soap->fsslauth(soap)))
    3177     { soap_set_sender_error(soap, "SSL error", "SSL authentication failed in tcp_connect(): check password, key file, and ca file.", SOAP_SSL_ERROR);
    3178       return -1;
    3179     }
    3180     soap->ssl = SSL_new(soap->ctx);
    3181     if (!soap->ssl)
    3182     { soap->error = SOAP_SSL_ERROR;
    3183       return -1;
    3184     }
    3185     if (soap->session)
    3186     { if (!strcmp(soap->session_host, host) && soap->session_port == port)
    3187         SSL_set_session(soap->ssl, soap->session);
    3188       SSL_SESSION_free(soap->session);
    3189       soap->session = NULL;
    3190     }
    3191     soap->imode |= SOAP_ENC_SSL;
    3192     soap->omode |= SOAP_ENC_SSL;
    3193     soap->bio = BIO_new_socket((SOAP_SOCKET)fd, BIO_NOCLOSE);
    3194     SSL_set_bio(soap->ssl, soap->bio, soap->bio);
    3195 #ifndef WITH_LEAN
    3196     if (soap->connect_timeout)
    3197 #ifdef WIN32
    3198     { u_long nonblocking = 1;
    3199       ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &nonblocking);
    3200     }
    3201 #else
    3202       fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)|O_NONBLOCK);
    3203 #endif
    3204 #endif
    3205     for (;;)
    3206     { if ((r = SSL_connect(soap->ssl)) <= 0)
    3207       { int err = SSL_get_error(soap->ssl, r);
    3208         if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
    3209         { soap_set_sender_error(soap, ssl_error(soap, r), "SSL connect failed in tcp_connect()", SOAP_SSL_ERROR);
    3210           return -1;
    3211         }
    3212         if (soap->connect_timeout)
    32133906        { struct timeval timeout;
    32143907          fd_set fds;
     3908          register int r;
    32153909          if (soap->connect_timeout > 0)
    32163910          { timeout.tv_sec = soap->connect_timeout;
     
    32223916          }
    32233917          FD_ZERO(&fds);
    3224           FD_SET((SOAP_SOCKET)(soap->socket), &fds);
     3918          FD_SET(fd, &fds);
     3919          r = select((int)fd + 1, NULL, &fds, NULL, &timeout);
     3920          if (r > 0)
     3921            break;
     3922          if (!r)
     3923          { soap->errnum = 0;
     3924            DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connect timeout\n"));
     3925            soap_set_sender_error(soap, "Timeout", "connect failed in tcp_connect()", SOAP_TCP_ERROR);
     3926            soap->fclosesocket(soap, fd);
     3927#ifdef WITH_IPV6
     3928            freeaddrinfo(ressave);
     3929#endif
     3930            return SOAP_INVALID_SOCKET;
     3931          }
     3932          r = soap_socket_errno(fd);
     3933          if (r != SOAP_EINTR)
     3934          { soap->errnum = r;
     3935            DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
     3936            soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR);
     3937            soap->fclosesocket(soap, fd);
     3938#ifdef WITH_IPV6
     3939            freeaddrinfo(ressave);
     3940#endif
     3941            return SOAP_INVALID_SOCKET;
     3942          }
     3943        }
     3944        k = (SOAP_SOCKLEN_T)sizeof(soap->errnum);
     3945        if (!getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&soap->errnum, &k) && !soap->errnum)   /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */
     3946          break;
     3947        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
     3948        if (!soap->errnum)
     3949          soap->errnum = soap_socket_errno(fd);
     3950        soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR);
     3951        soap->fclosesocket(soap, fd);
     3952#ifdef WITH_IPV6
     3953        freeaddrinfo(ressave);
     3954#endif
     3955        return SOAP_INVALID_SOCKET;
     3956      }
     3957#endif
     3958#ifdef WITH_IPV6
     3959      if (res->ai_next)
     3960      { res = res->ai_next;
     3961        soap->fclosesocket(soap, fd);
     3962        goto again;
     3963      }
     3964#endif
     3965      if (err && err != SOAP_EINTR)
     3966      { soap->errnum = err;
     3967        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
     3968        soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR);
     3969        soap->fclosesocket(soap, fd);
     3970#ifdef WITH_IPV6
     3971        freeaddrinfo(ressave);
     3972#endif
     3973        return SOAP_INVALID_SOCKET;
     3974      }
     3975    } 
     3976    else
     3977      break;
     3978  }
     3979#ifdef WITH_IPV6
     3980  soap->peerlen = 0; /* IPv6: already connected so use send() */
     3981  freeaddrinfo(ressave);
     3982#endif
     3983#ifndef WITH_LEAN
     3984  if (soap->recv_timeout || soap->send_timeout)
     3985    SOAP_SOCKNONBLOCK(fd)
     3986  else
     3987    SOAP_SOCKBLOCK(fd)
     3988#endif
     3989  soap->socket = fd;
     3990  soap->imode &= ~SOAP_ENC_SSL;
     3991  soap->omode &= ~SOAP_ENC_SSL;
     3992  if (!soap_tag_cmp(endpoint, "https:*"))
     3993  {
     3994#ifdef WITH_OPENSSL
     3995    BIO *bio;
     3996    int r;
     3997    if (soap->proxy_host)
     3998    { soap_mode m = soap->omode; /* make sure we only parse HTTP */
     3999      size_t n = soap->count; /* save the content length */
     4000      char *userid, *passwd;
     4001      soap->omode &= ~SOAP_ENC; /* mask IO and ENC */
     4002      soap->omode |= SOAP_IO_BUFFER;
     4003      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connecting to %s proxy server\n", soap->proxy_http_version));
     4004      sprintf(soap->tmpbuf, "CONNECT %s:%d HTTP/%s", host, port, soap->proxy_http_version);
     4005      if (soap_begin_send(soap)
     4006       || (soap->error = soap->fposthdr(soap, soap->tmpbuf, NULL)))
     4007      { soap->fclosesocket(soap, fd);
     4008        return SOAP_INVALID_SOCKET;
     4009      }
     4010#ifndef WITH_LEAN
     4011      if (soap->proxy_userid && soap->proxy_passwd && strlen(soap->proxy_userid) + strlen(soap->proxy_passwd) < 761)
     4012      { sprintf(soap->tmpbuf + 262, "%s:%s", soap->proxy_userid, soap->proxy_passwd);
     4013        strcpy(soap->tmpbuf, "Basic ");
     4014        soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, (int)strlen(soap->tmpbuf + 262));
     4015        if ((soap->error = soap->fposthdr(soap, "Proxy-Authorization", soap->tmpbuf)))
     4016        { soap->fclosesocket(soap, fd);
     4017          return soap->error;
     4018        }
     4019      }
     4020#endif
     4021      if ((soap->error = soap->fposthdr(soap, NULL, NULL))
     4022       || soap_flush(soap))
     4023      { soap->fclosesocket(soap, fd);
     4024        return SOAP_INVALID_SOCKET;
     4025      }
     4026      soap->omode = m;
     4027      m = soap->imode;
     4028      soap->imode &= ~SOAP_ENC; /* mask IO and ENC */
     4029      userid = soap->userid; /* preserve */
     4030      passwd = soap->passwd; /* preserve */
     4031      if ((soap->error = soap->fparse(soap)))
     4032      { soap->fclosesocket(soap, fd);
     4033        return SOAP_INVALID_SOCKET;
     4034      }
     4035      soap->userid = userid; /* restore */
     4036      soap->passwd = passwd; /* restore */
     4037      soap->imode = m; /* restore */
     4038      soap->count = n; /* restore */
     4039      if (soap_begin_send(soap))
     4040      { soap->fclosesocket(soap, fd);
     4041        return SOAP_INVALID_SOCKET;
     4042      }
     4043      if (endpoint)
     4044        strncpy(soap->endpoint, endpoint, sizeof(soap->endpoint)-1); /* restore */
     4045    }
     4046    if (!soap->ctx && (soap->error = soap->fsslauth(soap)))
     4047    { soap_set_sender_error(soap, "SSL error", "SSL authentication failed in tcp_connect(): check password, key file, and ca file.", SOAP_SSL_ERROR);
     4048      soap->fclosesocket(soap, fd);
     4049      return SOAP_INVALID_SOCKET;
     4050    }
     4051    if (!soap->ssl)
     4052    { soap->ssl = SSL_new(soap->ctx);
     4053      if (!soap->ssl)
     4054      { soap->fclosesocket(soap, fd);
     4055        soap->error = SOAP_SSL_ERROR;
     4056        return SOAP_INVALID_SOCKET;
     4057      }
     4058    }
     4059    else
     4060      SSL_clear(soap->ssl);
     4061    if (soap->session)
     4062    { if (!strcmp(soap->session_host, host) && soap->session_port == port)
     4063        SSL_set_session(soap->ssl, soap->session);
     4064      SSL_SESSION_free(soap->session);
     4065      soap->session = NULL;
     4066    }
     4067    soap->imode |= SOAP_ENC_SSL;
     4068    soap->omode |= SOAP_ENC_SSL;
     4069    bio = BIO_new_socket((int)fd, BIO_NOCLOSE);
     4070    SSL_set_bio(soap->ssl, bio, bio);
     4071#ifndef WITH_LEAN
     4072    /* Connect timeout: set SSL sockets to non-blocking */
     4073    if (soap->connect_timeout)
     4074      SOAP_SOCKNONBLOCK(fd)
     4075    else
     4076      SOAP_SOCKBLOCK(fd)
     4077    /* Try connecting until success or timeout */
     4078    do
     4079    { if ((r = SSL_connect(soap->ssl)) <= 0)
     4080      { int err;
     4081        if ((err = SSL_get_error(soap->ssl, r)) == SSL_ERROR_NONE)
     4082          break;
     4083        if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
     4084        { soap_set_sender_error(soap, soap_ssl_error(soap, r), "SSL connect failed in tcp_connect()", SOAP_SSL_ERROR);
     4085          soap->fclosesocket(soap, fd);
     4086          return SOAP_INVALID_SOCKET;
     4087        }
     4088        if (soap->connect_timeout)
     4089        {
     4090#ifndef WIN32
     4091          if ((int)soap->socket >= (int)FD_SETSIZE)
     4092          { soap->error = SOAP_FD_EXCEEDED;
     4093            return SOAP_INVALID_SOCKET; /* Hint: MUST increase FD_SETSIZE */
     4094          }
     4095#endif
    32254096          for (;;)
    3226           { int r = select((SOAP_SOCKET)(soap->socket + 1), &fds, NULL, &fds, &timeout);
    3227             if (r > 0)
     4097          { struct timeval timeout;
     4098            fd_set fds;
     4099            register int r;
     4100            if (soap->connect_timeout > 0)
     4101            { timeout.tv_sec = soap->connect_timeout;
     4102              timeout.tv_usec = 0;
     4103            }
     4104            else
     4105            { timeout.tv_sec = -soap->connect_timeout/1000000;
     4106              timeout.tv_usec = -soap->connect_timeout%1000000;
     4107            }
     4108            FD_ZERO(&fds);
     4109            FD_SET(fd, &fds);
     4110            if (err == SSL_ERROR_WANT_READ)
     4111              r = select((int)fd + 1, &fds, NULL, NULL, &timeout);
     4112            else
     4113              r = select((int)fd + 1, NULL, &fds, NULL, &timeout);
     4114            if (r >= 1)
     4115            { r = 1;
    32284116              break;
    3229             if (!r)
     4117            }
     4118            else
    32304119            { soap->errnum = 0;
    32314120              DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connect timeout\n"));
    3232               soap_set_sender_error(soap, "Timeout", "TCP connect failed in tcp_connect()", SOAP_TCP_ERROR);
    3233               return -1;
     4121              soap_set_sender_error(soap, "Timeout", "connect failed in tcp_connect()", SOAP_TCP_ERROR);
     4122              soap->fclosesocket(soap, fd);
     4123              return SOAP_INVALID_SOCKET;
    32344124            }
    32354125          }
    3236           continue;
     4126          continue;
    32374127        }
    32384128      }
    32394129      break;
    3240     }
    3241 #ifndef WITH_LEAN
    3242     if (soap->connect_timeout)
    3243 #ifdef WIN32
    3244     { u_long blocking = 0;
    3245       ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &blocking);
    3246     }
    3247 #else
    3248       fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)&~O_NONBLOCK);
    3249 #endif
    3250 #endif
    3251     if (soap->require_server_auth)
    3252     { X509 *peer;
    3253       int err;
     4130    } while (r == 1 && !SSL_is_init_finished(soap->ssl));
     4131    /* Set SSL sockets to nonblocking */
     4132    SOAP_SOCKNONBLOCK(fd)
     4133#endif
     4134    /* Check server credentials when required */
     4135    if ((soap->ssl_flags & SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION))
     4136    { int err;
    32544137      if ((err = SSL_get_verify_result(soap->ssl)) != X509_V_OK)
    32554138      { soap_set_sender_error(soap, X509_verify_cert_error_string(err), "SSL certificate presented by peer cannot be verified in tcp_connect()", SOAP_SSL_ERROR);
    3256         return -1;
    3257       }
    3258       peer = SSL_get_peer_certificate(soap->ssl);
    3259       if (!peer)
    3260       { soap_set_sender_error(soap, "SSL error", "No SSL certificate was presented by the peer in tcp_connect()", SOAP_SSL_ERROR);
    3261         return -1;
    3262       }
    3263       X509_NAME_get_text_by_NID(X509_get_subject_name(peer), NID_commonName, soap->msgbuf, sizeof(soap->msgbuf));
    3264       X509_free(peer);
    3265       if (soap_tag_cmp(soap->msgbuf, host))
    3266       { soap_set_sender_error(soap, "SSL error", "SSL certificate host name mismatch in tcp_connect()", SOAP_SSL_ERROR);
    3267         return -1;
    3268       }
    3269     }
    3270   }
    3271 #endif
     4139        soap->fclosesocket(soap, fd);
     4140        return SOAP_INVALID_SOCKET;
     4141      }
     4142      if (!(soap->ssl_flags & SOAP_SSL_SKIP_HOST_CHECK))
     4143      { X509_NAME *subj;
     4144        int ext_count;
     4145        int ok = 0;
     4146        X509 *peer;
     4147        peer = SSL_get_peer_certificate(soap->ssl);
     4148        if (!peer)
     4149        { soap_set_sender_error(soap, "SSL error", "No SSL certificate was presented by the peer in tcp_connect()", SOAP_SSL_ERROR);
     4150          soap->fclosesocket(soap, fd);
     4151          return SOAP_INVALID_SOCKET;
     4152        }
     4153        ext_count = X509_get_ext_count(peer);
     4154        if (ext_count > 0)
     4155        { int i;
     4156          for (i = 0; i < ext_count; i++)
     4157          { X509_EXTENSION *ext = X509_get_ext(peer, i);
     4158            const char *ext_str = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
     4159            if (ext_str && !strcmp(ext_str, "subjectAltName"))
     4160            { X509V3_EXT_METHOD *meth = X509V3_EXT_get(ext);
     4161              void *ext_data;
     4162#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
     4163              const unsigned char *data;
     4164#else
     4165              unsigned char *data;
     4166#endif
     4167              STACK_OF(CONF_VALUE) *val;
     4168              int j;
     4169              if (!meth)
     4170                break;
     4171              data = ext->value->data;
     4172#if (OPENSSL_VERSION_NUMBER > 0x00907000L)
     4173              if (meth->it)
     4174                ext_data = ASN1_item_d2i(NULL, &data, ext->value->length, ASN1_ITEM_ptr(meth->it));
     4175              else
     4176              { /* OpenSSL not perfectly portable at this point (?):
     4177                   Some compilers appear to prefer
     4178                   meth->d2i(NULL, (const unsigned char**)&data, ...
     4179                   or
     4180                   meth->d2i(NULL, &data, ext->value->length);
     4181                */
     4182                ext_data = meth->d2i(NULL, &data, ext->value->length);
     4183              }
     4184#else
     4185              ext_data = meth->d2i(NULL, &data, ext->value->length);
     4186#endif
     4187              val = meth->i2v(meth, ext_data, NULL);
     4188              for (j = 0; j < sk_CONF_VALUE_num(val); j++)
     4189              { CONF_VALUE *nval = sk_CONF_VALUE_value(val, j);
     4190                if (nval && !strcmp(nval->name, "DNS") && !strcmp(nval->value, host))
     4191                { ok = 1;
     4192                  break;
     4193                }
     4194              }
     4195            }
     4196            if (ok)
     4197              break;
     4198          }
     4199        }
     4200        if (!ok && (subj = X509_get_subject_name(peer)))
     4201        { int i = -1;
     4202          do
     4203          { ASN1_STRING *name;
     4204            i = X509_NAME_get_index_by_NID(subj, NID_commonName, i);
     4205            if (i == -1)
     4206              break;
     4207            name = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subj, i));
     4208            if (name)
     4209            { if (!soap_tag_cmp(host, (const char*)name))
     4210                ok = 1;
     4211              else
     4212              { unsigned char *tmp = NULL;
     4213                ASN1_STRING_to_UTF8(&tmp, name);
     4214                if (tmp)
     4215                { if (!soap_tag_cmp(host, (const char*)tmp))
     4216                    ok = 1;
     4217                  OPENSSL_free(tmp);
     4218                }
     4219              }
     4220            }
     4221          } while (!ok);
     4222        }
     4223        X509_free(peer);
     4224        if (!ok)
     4225        { soap_set_sender_error(soap, "SSL error", "SSL certificate host name mismatch in tcp_connect()", SOAP_SSL_ERROR);
     4226          soap->fclosesocket(soap, fd);
     4227          return SOAP_INVALID_SOCKET;
     4228        }
     4229      }
     4230    }
     4231#else
     4232    soap->fclosesocket(soap, fd);
     4233    soap->error = SOAP_SSL_ERROR;
     4234    return SOAP_INVALID_SOCKET;
     4235#endif
     4236  }
    32724237  return fd;
    32734238}
     
    32764241
    32774242/******************************************************************************/
    3278 #ifndef MAC_CARBON
    3279 #ifndef PALM_1
    3280 SOAP_FMAC1
    3281 int
     4243#ifndef WITH_NOIO
     4244#ifndef PALM_1
     4245SOAP_FMAC1
     4246SOAP_SOCKET
    32824247SOAP_FMAC2
    32834248soap_bind(struct soap *soap, const char *host, int port, int backlog)
    3284 { struct sockaddr_in sockaddr;
    3285 /* WR[ */
     4249{
    32864250#ifdef WITH_IPV6
    3287   struct addrinfo *addrinfo;
     4251  struct addrinfo *addrinfo = NULL;
    32884252  struct addrinfo hints;
    3289   struct addrinfo resaddr;
    3290   struct sockaddr_storage addrstorage;
     4253  struct addrinfo res;
    32914254  int err;
    3292 #endif /* WITH_IPV6 */
    3293 /* ]WR */
     4255#endif
    32944256#ifndef WITH_LEAN
    32954257  int len = SOAP_BUFLEN;
     
    32974259#endif
    32984260  if (soap_valid_socket(soap->master))
    3299   { soap->fclosesocket(soap, (SOAP_SOCKET)soap->master);
     4261  { soap->fclosesocket(soap, soap->master);
    33004262    soap->master = SOAP_INVALID_SOCKET;
    33014263  }
     
    33044266  if (tcp_init(soap))
    33054267  { soap_set_receiver_error(soap, tcp_error(soap), "TCP init failed in soap_bind()", SOAP_TCP_ERROR);
    3306     return -1;
    3307   }
    3308 /* WR[ */
     4268    return SOAP_INVALID_SOCKET;
     4269  }
    33094270#ifdef WITH_IPV6
    33104271  memset((void*)&hints, 0, sizeof(hints));
    33114272  hints.ai_family = PF_UNSPEC;
    3312   hints.ai_socktype = SOCK_STREAM;
     4273#ifndef WITH_LEAN
     4274  if ((soap->omode & SOAP_IO_UDP))
     4275    hints.ai_socktype = SOCK_DGRAM;
     4276  else
     4277#endif
     4278    hints.ai_socktype = SOCK_STREAM;
    33134279  hints.ai_flags = AI_PASSIVE;
    33144280  soap->errmode = 2;
    3315   if (host)
    3316     err = getaddrinfo(host, soap_int2s(soap, port), &hints, &addrinfo);
     4281  err = getaddrinfo(host, soap_int2s(soap, port), &hints, &addrinfo);
     4282  if (addrinfo)
     4283  { res = *addrinfo;
     4284    memcpy(&soap->peer, addrinfo->ai_addr, addrinfo->ai_addrlen);
     4285    soap->peerlen = addrinfo->ai_addrlen;
     4286    res.ai_addr = (struct sockaddr*)&soap->peer;
     4287    res.ai_addrlen = soap->peerlen;
     4288    freeaddrinfo(addrinfo);
     4289  }
     4290  if (err || !addrinfo)
     4291  { soap_set_receiver_error(soap, SOAP_GAI_STRERROR(err), "getaddrinfo failed in soap_bind()", SOAP_TCP_ERROR);
     4292    return SOAP_INVALID_SOCKET;
     4293  }
     4294  soap->master = (int)socket(res.ai_family, res.ai_socktype, res.ai_protocol);
     4295#else
     4296#ifndef WITH_LEAN
     4297  if ((soap->omode & SOAP_IO_UDP))
     4298    soap->master = (int)socket(AF_INET, SOCK_DGRAM, 0);
    33174299  else
    3318     err = getaddrinfo(NULL, soap_int2s(soap, port), &hints, &addrinfo);
    3319   if (NULL != addrinfo)
    3320   {
    3321     resaddr = *addrinfo;
    3322     addrstorage = *((struct sockaddr_storage *) addrinfo->ai_addr);
    3323     resaddr.ai_addr = (struct sockaddr *) &addrstorage;
    3324     freeaddrinfo(addrinfo);
    3325   }
    3326   if (err)
    3327   { soap_set_receiver_error(soap, gai_strerror(err), "TCP getaddrinfo failed in soap_bind()", SOAP_TCP_ERROR);
    3328     return -1;
    3329   }
     4300#endif
     4301    soap->master = (int)socket(AF_INET, SOCK_STREAM, 0);
     4302#endif
    33304303  soap->errmode = 0;
    3331   if ((soap->master = socket(resaddr.ai_family, resaddr.ai_socktype, resaddr.ai_protocol)) < 0)
    3332   { soap->errnum = soap_socket_errno;
    3333     soap_set_receiver_error(soap, tcp_error(soap), "TCP socket failed in soap_bind()", SOAP_TCP_ERROR);
    3334     return -1;
    3335   }
    3336 #else /* WITH_IPV6 */
    3337 /* ]WR */
    3338   soap->errmode = 0;
    3339   if ((soap->master = (int)socket(AF_INET, SOCK_STREAM, 0)) < 0)
    3340   { soap->errnum = soap_socket_errno;
    3341     soap_set_receiver_error(soap, tcp_error(soap), "TCP socket failed in soap_bind()", SOAP_TCP_ERROR);
    3342     return -1;
    3343   }
    3344 /* WR[ */
    3345 #endif /* WITH_IPV6 */
    3346 /* ]WR */
     4304  if (!soap_valid_socket(soap->master))
     4305  { soap->errnum = soap_socket_errno(soap->master);
     4306    soap_set_receiver_error(soap, tcp_error(soap), "socket failed in soap_bind()", SOAP_TCP_ERROR);
     4307    return SOAP_INVALID_SOCKET;
     4308  }
     4309#ifndef WITH_LEAN
     4310  if ((soap->omode & SOAP_IO_UDP))
     4311    soap->socket = soap->master;
     4312#endif
    33474313#ifdef SOCKET_CLOSE_ON_EXEC
    33484314#ifdef WIN32
     
    33514317#endif
    33524318#else
    3353   fcntl (soap->master, F_SETFD, 1);
     4319  fcntl(soap->master, F_SETFD, 1);
    33544320#endif
    33554321#endif
    33564322#ifndef WITH_LEAN
    3357   if (soap->bind_flags && setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, soap->bind_flags, (char*)&set, sizeof(int)))
    3358   { soap->errnum = soap_socket_errno;
    3359     soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt failed in soap_bind()", SOAP_TCP_ERROR);
    3360     return -1;
    3361   }
    3362   if (soap->keep_alive && setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int)))
    3363   { soap->errnum = soap_socket_errno;
    3364     soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt SO_KEEPALIVE failed in soap_bind()", SOAP_TCP_ERROR);
    3365     return -1;
    3366   }
    3367   if (setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int)))
    3368   { soap->errnum = soap_socket_errno;
    3369     soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt SO_SNDBUF failed in soap_bind()", SOAP_TCP_ERROR);
    3370     return -1;
    3371   }
    3372   if (setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int)))
    3373   { soap->errnum = soap_socket_errno;
    3374     soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt SO_RCVBUF failed in soap_bind()", SOAP_TCP_ERROR);
    3375     return -1;
     4323  if (soap->bind_flags && setsockopt(soap->master, SOL_SOCKET, soap->bind_flags, (char*)&set, sizeof(int)))
     4324  { soap->errnum = soap_socket_errno(soap->master);
     4325    soap_set_receiver_error(soap, tcp_error(soap), "setsockopt failed in soap_bind()", SOAP_TCP_ERROR);
     4326    return SOAP_INVALID_SOCKET;
     4327  }
     4328  if (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) && setsockopt(soap->master, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int)))
     4329  { soap->errnum = soap_socket_errno(soap->master);
     4330    soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in soap_bind()", SOAP_TCP_ERROR);
     4331    return SOAP_INVALID_SOCKET;
     4332  }
     4333  if (setsockopt(soap->master, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int)))
     4334  { soap->errnum = soap_socket_errno(soap->master);
     4335    soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in soap_bind()", SOAP_TCP_ERROR);
     4336    return SOAP_INVALID_SOCKET;
     4337  }
     4338  if (setsockopt(soap->master, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int)))
     4339  { soap->errnum = soap_socket_errno(soap->master);
     4340    soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in soap_bind()", SOAP_TCP_ERROR);
     4341    return SOAP_INVALID_SOCKET;
    33764342  }
    33774343#ifdef TCP_NODELAY
    3378   if (setsockopt((SOAP_SOCKET)soap->master, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int)))
    3379   { soap->errnum = soap_socket_errno;
    3380     soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt TCP_NODELAY failed in soap_bind()", SOAP_TCP_ERROR);
    3381     return -1;
    3382   }
    3383 #endif
    3384 #endif
    3385 /* WR[ */
     4344  if (!(soap->omode & SOAP_IO_UDP) && setsockopt(soap->master, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int)))
     4345  { soap->errnum = soap_socket_errno(soap->master);
     4346    soap_set_receiver_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in soap_bind()", SOAP_TCP_ERROR);
     4347    return SOAP_INVALID_SOCKET;
     4348  }
     4349#endif
     4350#endif
    33864351#ifdef WITH_IPV6
    33874352  soap->errmode = 0;
    3388   if (bind(soap->master, resaddr.ai_addr, resaddr.ai_addrlen) || listen(soap->master, backlog))
    3389   {
    3390     soap->errnum = soap_socket_errno;
     4353  if (bind(soap->master, res.ai_addr, (int)res.ai_addrlen))
     4354  { soap->errnum = soap_socket_errno(soap->master);
    33914355    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n"));
    33924356    soap_closesock(soap);
    3393     soap_set_receiver_error(soap, tcp_error(soap), "TCP bind failed in soap_bind()", SOAP_TCP_ERROR);
    3394     return -1;
     4357    soap_set_receiver_error(soap, tcp_error(soap), "bind failed in soap_bind()", SOAP_TCP_ERROR);
     4358    return SOAP_INVALID_SOCKET;
    33954359  } 
    3396 #else /* WITH_IPV6 */
    3397 /* ]WR */
    3398   memset((void*)&sockaddr, 0, sizeof(sockaddr));
    3399   sockaddr.sin_family = AF_INET;
     4360#else
     4361  soap->peerlen = sizeof(soap->peer);
     4362  memset((void*)&soap->peer, 0, sizeof(soap->peer));
     4363  soap->peer.sin_family = AF_INET;
    34004364  soap->errmode = 2;
    34014365  if (host)
    3402   { if (soap->fresolve(soap, host, &sockaddr.sin_addr))
    3403     { soap_set_receiver_error(soap, tcp_error(soap), "TCP get host by name failed in soap_bind()", SOAP_TCP_ERROR);
    3404       return -1;
     4366  { if (soap->fresolve(soap, host, &soap->peer.sin_addr))
     4367    { soap_set_receiver_error(soap, tcp_error(soap), "get host by name failed in soap_bind()", SOAP_TCP_ERROR);
     4368      return SOAP_INVALID_SOCKET;
    34054369    }
    34064370  }
    34074371  else
    3408     sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    3409   sockaddr.sin_port = htons((short)port);
     4372    soap->peer.sin_addr.s_addr = htonl(INADDR_ANY);
     4373  soap->peer.sin_port = htons((short)port);
    34104374  soap->errmode = 0;
    3411   if (bind((SOAP_SOCKET)soap->master, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) || listen((SOAP_SOCKET)soap->master, backlog))
    3412   { soap->errnum = soap_socket_errno;
     4375  if (bind(soap->master, (struct sockaddr*)&soap->peer, (int)soap->peerlen))
     4376  { soap->errnum = soap_socket_errno(soap->master);
    34134377    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n"));
    34144378    soap_closesock(soap);
    3415     soap_set_receiver_error(soap, tcp_error(soap), "TCP bind failed in soap_bind()", SOAP_TCP_ERROR);
    3416     return -1;
     4379    soap_set_receiver_error(soap, tcp_error(soap), "bind failed in soap_bind()", SOAP_TCP_ERROR);
     4380    return SOAP_INVALID_SOCKET;
     4381  }
     4382#endif
     4383  if (!(soap->omode & SOAP_IO_UDP) && listen(soap->master, backlog))
     4384  { soap->errnum = soap_socket_errno(soap->master);
     4385    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n"));
     4386    soap_closesock(soap);
     4387    soap_set_receiver_error(soap, tcp_error(soap), "listen failed in soap_bind()", SOAP_TCP_ERROR);
     4388    return SOAP_INVALID_SOCKET;
    34174389  } 
    3418 /* WR[ */
    3419 #endif /* WITH_IPV6 */
    3420 /* ]WR */
    3421 #ifdef WITH_OPENSSL
    3422   if (!soap->ctx && (soap->error = soap->fsslauth(soap)))
    3423     return -1;
    3424 #endif
    34254390  return soap->master;
    34264391}
     
    34294394
    34304395/******************************************************************************/
    3431 #ifndef MAC_CARBON
     4396#ifndef WITH_NOIO
    34324397#ifndef PALM_1
    34334398SOAP_FMAC1
     
    34384403#ifndef WITH_LEAN
    34394404  struct timeval timeout;
    3440   fd_set sfd,rfd;
    3441   int r;
     4405  fd_set rfd, sfd, xfd;
     4406  register int r;
     4407#ifndef WIN32
     4408  if ((int)soap->socket >= (int)FD_SETSIZE)
     4409    return SOAP_FD_EXCEEDED;    /* Hint: MUST increase FD_SETSIZE */
     4410#endif
    34424411  timeout.tv_sec = 0;
    34434412  timeout.tv_usec = 0;
    34444413  FD_ZERO(&rfd);
    34454414  FD_ZERO(&sfd);
    3446   if (soap->socket >= 0)
     4415  FD_ZERO(&xfd);
     4416  if (soap_valid_socket(soap->socket))
    34474417  { FD_SET(soap->socket, &rfd);
    34484418    FD_SET(soap->socket, &sfd);
    3449     r = select(soap->socket + 1, &rfd, &sfd, NULL, &timeout);
    3450   }
    3451   else if (soap->master >= 0)
    3452   { FD_SET(soap->master, &rfd);
    3453     r = select(soap->master + 1, &rfd, &sfd, NULL, &timeout);
     4419    FD_SET(soap->socket, &xfd);
     4420    r = select((int)soap->socket + 1, &rfd, &sfd, &xfd, &timeout);
     4421    if (r > 0 && FD_ISSET(soap->socket, &xfd))
     4422      r = -1;
     4423  }
     4424  else if (soap_valid_socket(soap->master))
     4425  { FD_SET(soap->master, &sfd);
     4426    r = select((int)soap->master + 1, NULL, &sfd, NULL, &timeout);
    34544427  }
    34554428  else
    3456   { FD_SET(soap->sendfd, &sfd);
    3457     FD_SET(soap->recvfd, &rfd);
    3458     r = select((soap->sendfd > soap->recvfd ? soap->sendfd : soap->recvfd) + 1, &rfd, &sfd, NULL, &timeout);
    3459   }
     4429    return SOAP_OK;
    34604430  if (r > 0)
    34614431  {
    34624432#ifdef WITH_OPENSSL
    3463     if (soap->ssl)
    3464     { if ((soap->socket >= 0) && FD_ISSET(soap->socket, &rfd))
    3465       { char buf = '\0';
    3466         if (SSL_peek(soap->ssl, &buf, 1) <= 0)
    3467           return SOAP_EOF;
    3468       }
    3469     }
    3470 #endif   
    3471     return SOAP_OK;
    3472   }
    3473   if (r < 0 && (soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) && soap_socket_errno != SOAP_EINTR)
    3474   { soap->errnum = soap_socket_errno;
    3475     soap_set_receiver_error(soap, tcp_error(soap), "select failed in soap_poll()", SOAP_TCP_ERROR);
    3476     return soap->error = SOAP_TCP_ERROR;
     4433    if (soap->imode & SOAP_ENC_SSL)
     4434    {
     4435      if (soap_valid_socket(soap->socket)
     4436       && FD_ISSET(soap->socket, &sfd)
     4437       && (!FD_ISSET(soap->socket, &rfd)
     4438        || SSL_peek(soap->ssl, soap->tmpbuf, 1) > 0))
     4439        return SOAP_OK;
     4440    }
     4441    else
     4442#endif
     4443      if (soap_valid_socket(soap->socket)
     4444       && FD_ISSET(soap->socket, &sfd)
     4445       && (!FD_ISSET(soap->socket, &rfd)
     4446        || recv(soap->socket, soap->tmpbuf, 1, MSG_PEEK) > 0))
     4447        return SOAP_OK;
     4448  }
     4449  else if (r < 0)
     4450  { soap->errnum = soap_socket_errno(soap->master);
     4451    if ((soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) && soap_socket_errno(soap->master) != SOAP_EINTR)
     4452    { soap_set_receiver_error(soap, tcp_error(soap), "select failed in soap_poll()", SOAP_TCP_ERROR);
     4453      return soap->error = SOAP_TCP_ERROR;
     4454    }
    34774455  }
    34784456  else
    3479     soap->errnum = soap_errno;
     4457    soap->errnum = 0;
     4458  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Polling: other end down on socket=%d select=%d\n", soap->socket, r));
    34804459  return SOAP_EOF;
    34814460#else
     
    34874466
    34884467/******************************************************************************/
    3489 #ifndef MAC_CARBON
    3490 #ifndef PALM_1
    3491 static int
    3492 tcp_accept(struct soap *soap, int s, struct sockaddr *a, int *n)
    3493 { int fd;
    3494 #if defined(SOCKLEN_T)
    3495   fd = (int)accept((SOAP_SOCKET)s, a, (SOCKLEN_T*)n);
    3496 #elif defined(__socklen_t_defined) || defined(_SOCKLEN_T) || defined(CYGWIN)
    3497   fd = (int)accept((SOAP_SOCKET)s, a, (socklen_t*)n);
    3498 #elif defined(WIN32) || defined(__APPLE__) || defined(HP_UX) || defined(SUN_OS) || defined(OPENSERVER) || defined(TRU64) || defined(VXWORKS)
    3499   fd = (int)accept((SOAP_SOCKET)s, a, n);
    3500 #else
    3501   fd = (int)accept((SOAP_SOCKET)s, a, (size_t*)n);
    3502 #endif
     4468#ifndef WITH_NOIO
     4469#ifndef PALM_1
     4470static SOAP_SOCKET
     4471tcp_accept(struct soap *soap, SOAP_SOCKET s, struct sockaddr *a, int *n)
     4472{ SOAP_SOCKET fd;
     4473  fd = accept(s, a, (SOAP_SOCKLEN_T*)n);        /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */
    35034474#ifdef SOCKET_CLOSE_ON_EXEC
    35044475#ifdef WIN32
     
    35164487
    35174488/******************************************************************************/
    3518 #ifndef MAC_CARBON
    3519 #ifndef PALM_1
    3520 SOAP_FMAC1
    3521 int
     4489#ifndef WITH_NOIO
     4490#ifndef PALM_1
     4491SOAP_FMAC1
     4492SOAP_SOCKET
    35224493SOAP_FMAC2
    35234494soap_accept(struct soap *soap)
    3524 {
    3525 /* WR[ */
    3526 #ifdef WITH_IPV6
    3527   struct sockaddr_storage sockaddr;
    3528 #else /* WITH_IPV6 */
    3529 /* ]WR */
    3530   struct sockaddr_in sockaddr;
    3531 /* WR[ */
    3532 #endif
    3533 /* ]WR */
    3534   int n = (int)sizeof(sockaddr);
     4495{ int n = (int)sizeof(soap->peer);
    35354496#ifndef WITH_LEAN
    35364497  int len = SOAP_BUFLEN;
     
    35384499#endif
    35394500  soap->error = SOAP_OK;
    3540   memset((void*)&sockaddr, 0, sizeof(sockaddr));
     4501#ifndef WITH_LEAN
     4502  if ((soap->omode & SOAP_IO_UDP))
     4503    return soap->socket = soap->master;
     4504#endif
     4505  memset((void*)&soap->peer, 0, sizeof(soap->peer));
    35414506  soap->socket = SOAP_INVALID_SOCKET;
    35424507  soap->errmode = 0;
     4508  soap->keep_alive = 0;
    35434509  if (soap_valid_socket(soap->master))
    3544   { for (;;)
     4510  { register int err;
     4511    for (;;)
    35454512    {
    35464513#ifndef WITH_LEAN
    3547       if (soap->accept_timeout)
    3548       { struct timeval timeout;
    3549         fd_set fd;
    3550         if (soap->accept_timeout > 0)
    3551         { timeout.tv_sec = soap->accept_timeout;
    3552           timeout.tv_usec = 0;
     4514      if (soap->accept_timeout || soap->send_timeout || soap->recv_timeout)
     4515      {
     4516#ifndef WIN32
     4517        if ((int)soap->socket >= (int)FD_SETSIZE)
     4518        { soap->error = SOAP_FD_EXCEEDED;
     4519          return SOAP_INVALID_SOCKET;   /* Hint: MUST increase FD_SETSIZE */
    35534520        }
    3554         else
    3555         { timeout.tv_sec = -soap->accept_timeout/1000000;
    3556           timeout.tv_usec = -soap->accept_timeout%1000000;
    3557         }
    3558         FD_ZERO(&fd);
    3559         FD_SET((SOAP_SOCKET)soap->master, &fd);
     4521#endif
    35604522        for (;;)
    3561         { int r = select((SOAP_SOCKET)(soap->master + 1), &fd, &fd, NULL, &timeout);
     4523        { struct timeval timeout;
     4524          fd_set fd;
     4525          register int r;
     4526          if (soap->accept_timeout > 0)
     4527          { timeout.tv_sec = soap->accept_timeout;
     4528            timeout.tv_usec = 0;
     4529          }
     4530          else if (soap->accept_timeout < 0)
     4531          { timeout.tv_sec = -soap->accept_timeout/1000000;
     4532            timeout.tv_usec = -soap->accept_timeout%1000000;
     4533          }
     4534          else
     4535          { timeout.tv_sec = 60;
     4536            timeout.tv_usec = 0;
     4537          }
     4538          FD_ZERO(&fd);
     4539          FD_SET(soap->master, &fd);
     4540          r = select((int)soap->master + 1, &fd, &fd, &fd, &timeout);
    35624541          if (r > 0)
    35634542            break;
    3564           if (!r)
     4543          if (!r && soap->accept_timeout)
    35654544          { soap->errnum = 0;
    3566             soap_set_receiver_error(soap, "Timeout", "TCP accept failed in soap_accept()", SOAP_TCP_ERROR);
    3567             return -1;
     4545            soap_set_receiver_error(soap, "Timeout", "accept failed in soap_accept()", SOAP_TCP_ERROR);
     4546            return SOAP_INVALID_SOCKET;
    35684547          }
    3569           if (soap_socket_errno != SOAP_EINTR)
    3570           { soap->errnum = soap_socket_errno;
    3571             soap_closesock(soap);
    3572             soap_set_sender_error(soap, tcp_error(soap), "TCP accept failed in soap_accept()", SOAP_TCP_ERROR);
    3573             return -1;
    3574           }
     4548          if (r < 0)
     4549          { r = soap_socket_errno(soap->master);
     4550            if (r != SOAP_EINTR)
     4551            { soap->errnum = r;
     4552              soap_closesock(soap);
     4553              soap_set_sender_error(soap, tcp_error(soap), "accept failed in soap_accept()", SOAP_TCP_ERROR);
     4554              return SOAP_INVALID_SOCKET;
     4555            }
     4556          }
    35754557        }
    3576 #if defined(WIN32)
    3577         { u_long nonblocking = 1;
    3578           ioctlsocket((SOAP_SOCKET)soap->master, FIONBIO, &nonblocking);
    3579         }
    3580 #elif defined(VXWORKS)
    3581         { vx_nonblocking = TRUE;
    3582           ioctl((SOAP_SOCKET)soap->master, FIONBIO, (int)(&vx_nonblocking));
    3583         }
    3584 #else
    3585         fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL)|O_NONBLOCK);
    3586 #endif
    3587       }
     4558      }
     4559      if (soap->accept_timeout || soap->send_timeout || soap->recv_timeout)
     4560        SOAP_SOCKNONBLOCK(soap->master)
    35884561      else
    3589 #if defined(WIN32)
    3590       { u_long blocking = 0;
    3591         ioctlsocket((SOAP_SOCKET)soap->master, FIONBIO, &blocking);
    3592       }
    3593 /* WR[ */
    3594 #elif defined(VXWORKS)
    3595       { vx_nonblocking = FALSE;
    3596         ioctl((SOAP_SOCKET)soap->master, FIONBIO, (int)(&vx_nonblocking));
    3597       }
    3598 /* ]WR */
    3599 #else
    3600         fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL)&~O_NONBLOCK);
    3601 #endif
    3602 #endif
    3603       if ((soap->socket = soap->faccept(soap, soap->master, (struct sockaddr*)&sockaddr, &n)) >= 0)
     4562        SOAP_SOCKBLOCK(soap->master)
     4563#endif
     4564      soap->socket = soap->faccept(soap, soap->master, (struct sockaddr*)&soap->peer, &n);
     4565      soap->peerlen = (size_t)n;
     4566      if (soap_valid_socket(soap->socket))
    36044567      {
    3605 /* WR[ */
    36064568#ifdef WITH_IPV6
    36074569/* Use soap->host to store the numeric form of the remote host */
    3608         getnameinfo((struct sockaddr*)&sockaddr, n, soap->host, sizeof(soap->host), NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV);
     4570        getnameinfo((struct sockaddr*)&soap->peer, n, soap->host, sizeof(soap->host), NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV);
    36094571        DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept socket %d from %s\n", soap->socket, soap->host));
    3610         soap->ip = 0; /* info stored in soap->host */
    3611         soap->port = 0; /* info stored in soap->host */
    3612 #else /* WITH_IPV6 */
    3613 /* ]WR */
    3614         soap->ip = ntohl(sockaddr.sin_addr.s_addr);
    3615         soap->port = (int)ntohs(sockaddr.sin_port); /* does not return port number on some systems */
     4572        soap->ip = 0; /* info stored in soap->peer and soap->host */
     4573        soap->port = 0; /* info stored in soap->peer and soap->host */
     4574#else
     4575        soap->ip = ntohl(soap->peer.sin_addr.s_addr);
     4576        soap->port = (int)ntohs(soap->peer.sin_port); /* does not return port number on some systems */
    36164577        DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept socket %d at port %d from IP %d.%d.%d.%d\n", soap->socket, soap->port, (int)(soap->ip>>24)&0xFF, (int)(soap->ip>>16)&0xFF, (int)(soap->ip>>8)&0xFF, (int)soap->ip&0xFF));
    3617 /* WR[ */
    3618 #endif /* WITH_IPV6 */
    3619 /* ]WR */
    3620         soap->keep_alive = ((soap->imode & SOAP_IO_KEEPALIVE) != 0);
     4578#endif
    36214579#ifndef WITH_LEAN
    3622         if (soap->accept_flags & SO_LINGER)
     4580        if (soap->accept_flags == SO_LINGER)
    36234581        { struct linger linger;
    36244582          memset((void*)&linger, 0, sizeof(linger));
    36254583          linger.l_onoff = 1;
    3626           linger.l_linger = 0;
    3627           if (setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger)))
    3628           { soap->errnum = soap_socket_errno;
    3629             soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt SO_LINGER failed in soap_accept()", SOAP_TCP_ERROR);
    3630             return -1;
    3631           }
     4584          linger.l_linger = soap->linger_time;
     4585          if (setsockopt(soap->socket, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger)))
     4586          { soap->errnum = soap_socket_errno(soap->socket);
     4587            soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_LINGER failed in soap_accept()", SOAP_TCP_ERROR);
     4588            soap_closesock(soap);
     4589            return SOAP_INVALID_SOCKET;
     4590          }
    36324591        }
    3633         if ((soap->accept_flags & ~SO_LINGER) && setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, soap->accept_flags & ~SO_LINGER, (char*)&set, sizeof(int)))
    3634         { soap->errnum = soap_socket_errno;
    3635           soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt failed in soap_accept()", SOAP_TCP_ERROR);
    3636           return -1;
     4592        else if (soap->accept_flags && setsockopt(soap->socket, SOL_SOCKET, soap->accept_flags, (char*)&set, sizeof(int)))
     4593        { soap->errnum = soap_socket_errno(soap->socket);
     4594          soap_set_receiver_error(soap, tcp_error(soap), "setsockopt failed in soap_accept()", SOAP_TCP_ERROR);
     4595          soap_closesock(soap);
     4596          return SOAP_INVALID_SOCKET;
    36374597        }
    3638         if (soap->keep_alive && setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int)))
    3639         { soap->errnum = soap_socket_errno;
    3640           soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt SO_KEEPALIVE failed in soap_accept()", SOAP_TCP_ERROR);
    3641           return -1;
     4598        if (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) && setsockopt(soap->socket, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int)))
     4599        { soap->errnum = soap_socket_errno(soap->socket);
     4600          soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in soap_accept()", SOAP_TCP_ERROR);
     4601          soap_closesock(soap);
     4602          return SOAP_INVALID_SOCKET;
    36424603        }
    3643         if (setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int)))
    3644         { soap->errnum = soap_socket_errno;
    3645           soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt SO_SNDBUF failed in soap_accept()", SOAP_TCP_ERROR);
    3646           return -1;
     4604        if (setsockopt(soap->socket, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int)))
     4605        { soap->errnum = soap_socket_errno(soap->socket);
     4606          soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in soap_accept()", SOAP_TCP_ERROR);
     4607          soap_closesock(soap);
     4608          return SOAP_INVALID_SOCKET;
    36474609        }
    3648         if (setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int)))
    3649         { soap->errnum = soap_socket_errno;
    3650           soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt SO_RCVBUF failed in soap_accept()", SOAP_TCP_ERROR);
    3651           return -1;
     4610        if (setsockopt(soap->socket, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int)))
     4611        { soap->errnum = soap_socket_errno(soap->socket);
     4612          soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in soap_accept()", SOAP_TCP_ERROR);
     4613          soap_closesock(soap);
     4614          return SOAP_INVALID_SOCKET;
    36524615        }
    36534616#ifdef TCP_NODELAY
    3654         if (setsockopt((SOAP_SOCKET)soap->socket, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int)))
    3655         { soap->errnum = soap_socket_errno;
    3656           soap_set_receiver_error(soap, tcp_error(soap), "TCP setsockopt TCP_NODELAY failed in soap_accept()", SOAP_TCP_ERROR);
    3657           return -1;
     4617        if (!(soap->omode & SOAP_IO_UDP) && setsockopt(soap->socket, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int)))
     4618        { soap->errnum = soap_socket_errno(soap->socket);
     4619          soap_set_receiver_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in soap_accept()", SOAP_TCP_ERROR);
     4620          soap_closesock(soap);
     4621          return SOAP_INVALID_SOCKET;
    36584622        }
    36594623#endif
    36604624#endif
    3661         if (soap->accept_timeout)
    3662         {
    3663 #if defined(WIN32)
    3664           u_long blocking = 0;
    3665           ioctlsocket((SOAP_SOCKET)soap->master, FIONBIO, &blocking);
    3666           ioctlsocket((SOAP_SOCKET)soap->socket, FIONBIO, &blocking);
    3667 /* WR[ */
    3668 #elif defined(VXWORKS)
    3669           vx_nonblocking = FALSE;
    3670           ioctl((SOAP_SOCKET)soap->master, FIONBIO, (int)(&vx_nonblocking));
    3671           ioctl((SOAP_SOCKET)soap->socket, FIONBIO, (int)(&vx_nonblocking));
    3672 /* ]WR */
    3673 #elif defined(PALM)
    3674           fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL,0)&~O_NONBLOCK);
    3675           fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL,0)&~O_NONBLOCK);
    3676 #elif defined(SYMBIAN)
    3677           long blocking = 0;
    3678           ioctl((SOAP_SOCKET)soap->master, 0/*FIONBIO*/, &blocking);
    3679 #else
    3680           fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL)&~O_NONBLOCK);
    3681           fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL)&~O_NONBLOCK);
    3682 #endif
    3683         }
     4625        soap->keep_alive = (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) != 0);
    36844626        return soap->socket;
    36854627      }
    3686       if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EAGAIN)
    3687       { soap->errnum = soap_socket_errno;
    3688         soap_set_receiver_error(soap, tcp_error(soap), "TCP accept failed in soap_accept()", SOAP_TCP_ERROR);
    3689         return -1;
     4628      err = soap_socket_errno(soap->socket);
     4629      if (err != 0 && err != SOAP_EINTR && err != SOAP_EAGAIN && err != SOAP_EWOULDBLOCK)
     4630      { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept failed from %s\n", soap->host));
     4631        soap->errnum = err;
     4632        soap_set_receiver_error(soap, tcp_error(soap), "accept failed in soap_accept()", SOAP_TCP_ERROR);
     4633        soap_closesock(soap);
     4634        return SOAP_INVALID_SOCKET;
    36904635      }
    36914636    }
    36924637  }
    36934638  else
    3694   { soap_set_receiver_error(soap, tcp_error(soap), "TCP no master socket in soap_accept()", SOAP_TCP_ERROR);
    3695     return -1;
    3696   }
    3697 }
    3698 #endif
    3699 #endif
    3700 
    3701 /******************************************************************************/
    3702 #ifndef MAC_CARBON
     4639  { soap->errnum = 0;
     4640    soap_set_receiver_error(soap, tcp_error(soap), "no master socket in soap_accept()", SOAP_TCP_ERROR);
     4641    return SOAP_INVALID_SOCKET;
     4642  }
     4643}
     4644#endif
     4645#endif
     4646
     4647/******************************************************************************/
     4648#ifndef WITH_NOIO
    37034649#ifndef PALM_1
    37044650static int
     
    37094655  { int r, s = 0;
    37104656    if (soap->session)
    3711       SSL_SESSION_free(soap->session);
     4657    { SSL_SESSION_free(soap->session);
     4658      soap->session = NULL;
     4659    }
    37124660    if (*soap->host)
    37134661    { soap->session = SSL_get1_session(soap->ssl);
     
    37184666    }
    37194667    r = SSL_shutdown(soap->ssl);
     4668    if (r == 0)
     4669    { if (soap_valid_socket(soap->socket))
     4670      { struct timeval timeout;
     4671        fd_set fd;
     4672        if (soap->fshutdownsocket(soap, soap->socket, 1))
     4673        { /*
     4674          wait up to 10 seconds for close_notify to be sent by peer (if peer not
     4675          present, this avoids calling SSL_shutdown() which has a lengthy return
     4676          timeout)
     4677          */
     4678#ifndef WIN32
     4679          if ((int)soap->socket < (int)FD_SETSIZE)
     4680          {
     4681#endif
     4682            timeout.tv_sec = 10;
     4683            timeout.tv_usec = 0;
     4684            FD_ZERO(&fd);
     4685            FD_SET(soap->socket, &fd);
     4686            r = select((int)soap->socket + 1, &fd, NULL, &fd, &timeout);
     4687            if (r <= 0 && soap_socket_errno(soap->socket) != SOAP_EINTR)
     4688            { soap->errnum = 0;
     4689              DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connection lost...\n"));
     4690              soap->fclosesocket(soap, soap->socket);
     4691              soap->socket = SOAP_INVALID_SOCKET;
     4692              ERR_remove_state(0);
     4693              return SOAP_OK;
     4694            }
     4695#ifndef WIN32
     4696          }
     4697#endif
     4698        }
     4699      }
     4700      r = SSL_shutdown(soap->ssl);
     4701    }
    37204702    if (r != 1)
    37214703    { s = ERR_get_error();
    37224704      if (s)
    3723       { if (soap_valid_socket(soap->socket))
    3724         { soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 1);
     4705      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Shutdown failed: %d\n", SSL_get_error(soap->ssl, r)));
     4706        if (soap_valid_socket(soap->socket) && !(soap->omode & SOAP_IO_UDP))
     4707        { soap->fclosesocket(soap, soap->socket);
    37254708          soap->socket = SOAP_INVALID_SOCKET;
    37264709        }
    3727         r = SSL_shutdown(soap->ssl);
    3728       }
    3729     }
    3730     DBGLOG(TEST, if (s) SOAP_MESSAGE(fdebug, "Shutdown failed: %d\n", SSL_get_error(soap->ssl, r)));
     4710      }
     4711    }
    37314712    SSL_free(soap->ssl);
    37324713    soap->ssl = NULL;
     
    37364717  }
    37374718#endif
    3738   if (soap_valid_socket(soap->socket))
    3739   { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Closing socket %d\n", soap->socket));
    3740     soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 2);
    3741     soap->fclosesocket(soap, (SOAP_SOCKET)soap->socket);
     4719  if (soap_valid_socket(soap->socket) && !(soap->omode & SOAP_IO_UDP))
     4720  { soap->fshutdownsocket(soap, soap->socket, 2);
     4721    soap->fclosesocket(soap, soap->socket);
    37424722    soap->socket = SOAP_INVALID_SOCKET;
    37434723  }
     
    37484728
    37494729/******************************************************************************/
    3750 #ifndef MAC_CARBON
     4730#ifndef WITH_NOIO
    37514731#ifndef PALM_1
    37524732static int
    37534733tcp_closesocket(struct soap *soap, SOAP_SOCKET fd)
    3754 { return closesocket(fd);
    3755 }
    3756 #endif
    3757 #endif
    3758 
    3759 /******************************************************************************/
    3760 #ifndef MAC_CARBON
     4734{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Close socket %d\n", (int)fd));
     4735  return soap_closesocket(fd);
     4736}
     4737#endif
     4738#endif
     4739
     4740/******************************************************************************/
     4741#ifndef WITH_NOIO
    37614742#ifndef PALM_1
    37624743static int
    37634744tcp_shutdownsocket(struct soap *soap, SOAP_SOCKET fd, int how)
    3764 { return shutdown(fd, how);
     4745{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Shutdown socket %d how=%d\n", (int)fd, how));
     4746  return shutdown(fd, how);
    37654747}
    37664748#endif
     
    37744756soap_closesock(struct soap *soap)
    37754757{ register int status = soap->error;
    3776 #ifndef MAC_CARBON
    37774758  if (status == SOAP_EOF || status == SOAP_TCP_ERROR || status == SOAP_SSL_ERROR || !soap->keep_alive)
    3778   { if ((soap->error = soap->fclose(soap)))
     4759  { if (soap->fclose && (soap->error = soap->fclose(soap)))
    37794760      return soap->error;
    3780     soap->socket = SOAP_INVALID_SOCKET;
    3781   }
    3782 #endif
     4761    soap->keep_alive = 0;
     4762  }
    37834763#ifdef WITH_ZLIB
    37844764  if (soap->zlib_state == SOAP_ZLIB_DEFLATE)
    3785     deflateEnd(&soap->d_stream);
     4765    deflateEnd(soap->d_stream);
    37864766  else if (soap->zlib_state == SOAP_ZLIB_INFLATE)
    3787     inflateEnd(&soap->d_stream);
     4767    inflateEnd(soap->d_stream);
    37884768  soap->zlib_state = SOAP_ZLIB_NONE;
    37894769#endif
     
    37934773
    37944774/******************************************************************************/
     4775#ifndef WITH_NOIDREF
    37954776#ifndef PALM_2
    37964777SOAP_FMAC1
     
    38044785}
    38054786#endif
    3806 
    3807 /******************************************************************************/
     4787#endif
     4788
     4789/******************************************************************************/
     4790#ifndef WITH_NOIDREF
    38084791#ifndef PALM_1
    38094792static void
     
    38114794{ register int i;
    38124795  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing pointer hashtable\n"));
     4796  soap->pblk = NULL;
     4797  soap->pidx = 0;
    38134798  for (i = 0; i < (int)SOAP_PTRHASH; i++)
    38144799    soap->pht[i] = NULL;
    38154800}
    38164801#endif
     4802#endif
    38174803
    38184804/******************************************************************************/
     
    38214807struct soap*
    38224808SOAP_FMAC2
     4809soap_new1(soap_mode mode)
     4810{ return soap_new2(mode, mode);
     4811}
     4812#endif
     4813
     4814/******************************************************************************/
     4815#ifndef PALM_1
     4816SOAP_FMAC1
     4817struct soap*
     4818SOAP_FMAC2
    38234819soap_new()
    3824 { struct soap *soap = (struct soap*)SOAP_MALLOC(sizeof(struct soap));
    3825   if (soap)
    3826     soap_init(soap);
    3827   return soap;
     4820{ return soap_new2(SOAP_IO_DEFAULT, SOAP_IO_DEFAULT);
    38284821}
    38294822#endif
     
    38344827struct soap*
    38354828SOAP_FMAC2
    3836 soap_new1(int mode)
    3837 { return soap_new2(mode, mode);
    3838 }
    3839 #endif
    3840 
    3841 /******************************************************************************/
    3842 #ifndef PALM_1
    3843 SOAP_FMAC1
    3844 struct soap*
    3845 SOAP_FMAC2
    3846 soap_new2(int imode, int omode)
    3847 { struct soap *soap = (struct soap*)SOAP_MALLOC(sizeof(struct soap));
     4829soap_new2(soap_mode imode, soap_mode omode)
     4830{ struct soap *soap = (struct soap*)malloc(sizeof(struct soap));
    38484831  if (soap)
    38494832    soap_init2(soap, imode, omode);
     
    38544837/******************************************************************************/
    38554838#ifndef PALM_1
     4839SOAP_FMAC1
     4840void
     4841SOAP_FMAC2
     4842soap_free(struct soap *soap)
     4843{ soap_done(soap);
     4844  free(soap);
     4845}
     4846#endif
     4847
     4848/******************************************************************************/
     4849#ifndef PALM_1
     4850SOAP_FMAC1
     4851void
     4852SOAP_FMAC2
     4853soap_del(struct soap *soap)
     4854{ free(soap);
     4855}
     4856#endif
     4857
     4858/******************************************************************************/
     4859#ifndef WITH_NOIDREF
     4860#ifndef PALM_1
    38564861static void
    38574862soap_free_pht(struct soap *soap)
    3858 { register struct soap_plist *pp, *next;
     4863{ register struct soap_pblk *pb, *next;
    38594864  register int i;
    38604865  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free pointer hashtable\n"));
     4866  for (pb = soap->pblk; pb; pb = next)
     4867  { next = pb->next;
     4868    SOAP_FREE(soap, pb);
     4869  }
     4870  soap->pblk = NULL;
     4871  soap->pidx = 0;
    38614872  for (i = 0; i < (int)SOAP_PTRHASH; i++)
    3862   { for (pp = soap->pht[i]; pp; pp = next)
    3863     { next = pp->next;
    3864       SOAP_FREE(pp);
    3865     }
    38664873    soap->pht[i] = NULL;
    3867   }
    3868 }
    3869 #endif
    3870 
    3871 /******************************************************************************/
     4874}
     4875#endif
     4876#endif
     4877
     4878/******************************************************************************/
     4879#ifndef WITH_NOIDREF
    38724880#ifndef PALM_2
    38734881SOAP_FMAC1
     
    38924900}
    38934901#endif
    3894 
    3895 /******************************************************************************/
     4902#endif
     4903
     4904/******************************************************************************/
     4905#ifndef WITH_NOIDREF
    38964906#ifndef PALM_2
    38974907SOAP_FMAC1
     
    39024912  *ppp = NULL;
    39034913  if (p)
    3904     for (pp = soap->pht[soap_hash_ptr(p)]; pp; pp = pp->next)
    3905       if (pp->ptr == p && pp->type == type)
     4914  { for (pp = soap->pht[soap_hash_ptr(p)]; pp; pp = pp->next)
     4915    { if (pp->ptr == p && pp->type == type)
    39064916      { *ppp = pp;
    39074917        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup location=%p type=%d id=%d\n", p, type, pp->id));
    39084918        return pp->id;
    39094919      }
     4920    }
     4921  }
    39104922  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup location=%p type=%d: not found\n", p, type));
    39114923  return 0;
    39124924}
    39134925#endif
    3914 
    3915 /******************************************************************************/
     4926#endif
     4927
     4928/******************************************************************************/
     4929#ifndef WITH_NOIDREF
    39164930#ifndef PALM_2
    39174931SOAP_FMAC1
     
    39194933SOAP_FMAC2
    39204934soap_pointer_enter(struct soap *soap, const void *p, const struct soap_array *a, int n, int type, struct soap_plist **ppp)
    3921 { register int h;
    3922   register struct soap_plist *pp = *ppp = (struct soap_plist*)SOAP_MALLOC(sizeof(struct soap_plist));
    3923   if (!pp)
    3924     return 0;
     4935{ register size_t h;
     4936  register struct soap_plist *pp;
     4937  if (!soap->pblk || soap->pidx >= SOAP_PTRBLK)
     4938  { register struct soap_pblk *pb = (struct soap_pblk*)SOAP_MALLOC(soap, sizeof(struct soap_pblk));
     4939    if (!pb)
     4940    { soap->error = SOAP_EOM;
     4941      return 0;
     4942    }
     4943    pb->next = soap->pblk;
     4944    soap->pblk = pb;
     4945    soap->pidx = 0;
     4946  }
     4947  *ppp = pp = &soap->pblk->plist[soap->pidx++];
    39254948  if (a)
    39264949    h = soap_hash_ptr(a->__ptr);
    39274950  else
    39284951    h = soap_hash_ptr(p);
    3929   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Pointer enter location=%p array=%p size=%d dim=%d type=%d id=%lu\n", p, a?a->__ptr:NULL, a?a->__size:0, n, type, soap->idnum+1));
     4952  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Pointer enter location=%p array=%p size=%d dim=%d type=%d id=%d\n", p, a?a->__ptr:NULL, a?a->__size:0, n, type, soap->idnum+1));
    39304953  pp->next = soap->pht[h];
    39314954  pp->type = type;
     
    39394962}
    39404963#endif
    3941 
    3942 /******************************************************************************/
     4964#endif
     4965
     4966/******************************************************************************/
     4967#ifndef WITH_NOIDREF
    39434968#ifndef PALM_2
    39444969SOAP_FMAC1
     
    39554980      for (i = 0; i < n; i++)
    39564981        if (((const int*)&pp->array->__size)[i] != ((const int*)&a->__size)[i])
    3957           break;
     4982          break;
    39584983      if (i == n)
    39594984      { *ppp = pp;
     
    39674992}
    39684993#endif
    3969 
    3970 /******************************************************************************/
    3971 #ifndef PALM_1
    3972 SOAP_FMAC1
    3973 void
     4994#endif
     4995
     4996/******************************************************************************/
     4997#ifndef PALM_1
     4998SOAP_FMAC1
     4999int
    39745000SOAP_FMAC2
    39755001soap_begin_count(struct soap *soap)
    3976 { soap_clr_attr(soap);
    3977   soap_set_local_namespaces(soap);
     5002{
    39785003#ifndef WITH_LEANER
    39795004  if ((soap->mode & SOAP_ENC_DIME) || (soap->omode & SOAP_ENC_DIME))
     
    39835008  { soap->mode = soap->omode;
    39845009    if ((soap->mode & SOAP_IO) == SOAP_IO_STORE
    3985      || (((soap->mode & SOAP_IO) == SOAP_IO_CHUNK || (soap->mode & SOAP_ENC_XML)) && !soap->fpreparesend))
     5010     || (((soap->mode & SOAP_IO) == SOAP_IO_CHUNK || (soap->mode & SOAP_ENC_XML))
     5011#ifndef WITH_LEANER
     5012      && !soap->fpreparesend
     5013#endif
     5014      ))
    39865015      soap->mode &= ~SOAP_IO_LENGTH;
    39875016    else
    39885017      soap->mode |= SOAP_IO_LENGTH;
    39895018  }
     5019#ifdef WITH_ZLIB
    39905020  if ((soap->mode & SOAP_ENC_ZLIB) && (soap->mode & SOAP_IO) == SOAP_IO_FLUSH)
    39915021  { if (!(soap->mode & SOAP_ENC_DIME))
     
    39965026      soap->mode |= SOAP_IO_STORE;
    39975027  }
     5028#endif
    39985029  if (!soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH))
    39995030    soap->mode |= SOAP_XML_TREE;
    40005031#ifndef WITH_LEANER
     5032  if ((soap->mode & SOAP_ENC_MTOM) && (soap->mode & SOAP_ENC_DIME))
     5033    soap->mode |= SOAP_ENC_MIME;
     5034  else
     5035    soap->mode &= ~SOAP_ENC_MTOM;
    40015036  if (soap->mode & SOAP_ENC_MIME)
    40025037    soap_select_mime_boundary(soap);
     
    40115046  soap->part = SOAP_BEGIN;
    40125047  soap->idnum = 0;
     5048  soap_clr_attr(soap);
     5049  soap_set_local_namespaces(soap);
     5050  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin count phase (socket=%d mode=0x%x count=%lu)\n", soap->socket, soap->mode, (unsigned long)soap->count));
     5051#ifndef WITH_LEANER
    40135052  soap->dime.count = 0; /* count # of attachments */
    40145053  soap->dime.size = 0; /* accumulate total size of attachments */
    4015   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin count phase (socket=%d mode=%x count=%lu)\n", soap->socket, soap->mode, (unsigned long)soap->count));
    40165054  if (soap->fprepareinit && (soap->mode & SOAP_IO) != SOAP_IO_STORE)
    4017     soap->fprepareinit(soap);   
     5055    return soap->error = soap->fprepareinit(soap);   
     5056#endif
     5057  return SOAP_OK;
    40185058}
    40195059#endif
     
    40245064int
    40255065SOAP_FMAC2
     5066soap_end_count(struct soap *soap)
     5067{
     5068#ifndef WITH_LEANER
     5069  if (soap->fpreparefinal)
     5070    return soap->error = soap->fpreparefinal(soap);
     5071#endif
     5072  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of count phase\n"));
     5073  return SOAP_OK;
     5074}
     5075#endif
     5076
     5077/******************************************************************************/
     5078#ifndef PALM_1
     5079SOAP_FMAC1
     5080int
     5081SOAP_FMAC2
    40265082soap_begin_send(struct soap *soap)
    4027 { soap->error = SOAP_OK;
    4028   soap_clr_attr(soap);
    4029   soap_set_local_namespaces(soap);
    4030   soap->mode = (soap->omode & ~SOAP_IO_LENGTH) | (soap->mode & SOAP_ENC_DIME);
     5083{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing for output\n"));
     5084  soap->error = SOAP_OK;
     5085  soap->mode = soap->omode | (soap->mode & (SOAP_IO_LENGTH | SOAP_ENC_DIME));
     5086#ifdef WITH_ZLIB
    40315087  if ((soap->mode & SOAP_ENC_ZLIB) && (soap->mode & SOAP_IO) == SOAP_IO_FLUSH)
    40325088  { if (soap->mode & SOAP_ENC_XML)
     
    40355091      soap->mode |= SOAP_IO_STORE;
    40365092  }
     5093#endif
     5094#ifndef WITH_LEAN
     5095  if ((soap->mode & SOAP_IO_UDP))
     5096  { soap->mode |= SOAP_ENC_XML;
     5097    if (soap->count > SOAP_BUFLEN)
     5098      return soap->error = SOAP_UDP_ERROR;
     5099  }
     5100#endif
    40375101  if ((soap->mode & SOAP_IO) == SOAP_IO_FLUSH && soap_valid_socket(soap->socket))
    4038   { if (soap->count || (soap->mode & SOAP_ENC_XML))
     5102  { if (soap->count || (soap->mode & SOAP_IO_LENGTH) || (soap->mode & SOAP_ENC_XML))
    40395103      soap->mode |= SOAP_IO_BUFFER;
    40405104    else
    40415105      soap->mode |= SOAP_IO_STORE;
    40425106  }
     5107  soap->mode &= ~SOAP_IO_LENGTH;
    40435108  if ((soap->mode & SOAP_IO) == SOAP_IO_STORE)
    4044     soap_new_block(soap);
     5109    if (soap_new_block(soap) == NULL)
     5110      return soap->error;
    40455111  if (!(soap->mode & SOAP_IO_KEEPALIVE))
    40465112    soap->keep_alive = 0;
     
    40485114    soap->mode |= SOAP_XML_TREE;
    40495115#ifndef WITH_LEANER
     5116  if ((soap->mode & SOAP_ENC_MTOM) && (soap->mode & SOAP_ENC_DIME))
     5117  { soap->mode |= SOAP_ENC_MIME;
     5118    soap->mode &= ~SOAP_ENC_DIME;
     5119  }
     5120  else
     5121    soap->mode &= ~SOAP_ENC_MTOM;
    40505122  if (soap->mode & SOAP_ENC_MIME)
    40515123    soap_select_mime_boundary(soap);
    4052 #endif
    40535124#ifdef WIN32
    40545125#ifndef UNDER_CE
     
    40565127  if (!soap_valid_socket(soap->socket)) /* Set win32 stdout or soap->sendfd to BINARY, e.g. to support DIME */
    40575128#ifdef __BORLANDC__
    4058     setmode((SOAP_SOCKET)soap->sendfd, O_BINARY);
     5129    setmode(soap->sendfd, O_BINARY);
    40595130#else
    4060     _setmode((SOAP_SOCKET)soap->sendfd, _O_BINARY);
     5131    _setmode(soap->sendfd, _O_BINARY);
     5132#endif
    40615133#endif
    40625134#endif
     
    40735145  soap->mustUnderstand = 0;
    40745146  soap->encoding = 0;
    4075   soap->part = SOAP_BEGIN;
    40765147  soap->idnum = 0;
    40775148  soap->level = 0;
     5149  soap_clr_attr(soap);
     5150  soap_set_local_namespaces(soap);
    40785151#ifdef WITH_ZLIB
    40795152  soap->z_ratio_out = 1.0;
    40805153  if ((soap->mode & SOAP_ENC_ZLIB) && soap->zlib_state != SOAP_ZLIB_DEFLATE)
    4081   {
     5154  { if (!soap->z_buf)
     5155      soap->z_buf = (char*)SOAP_MALLOC(soap, SOAP_BUFLEN);
     5156    soap->d_stream->next_out = (Byte*)soap->z_buf;
     5157    soap->d_stream->avail_out = SOAP_BUFLEN;
    40825158#ifdef WITH_GZIP
    4083     memcpy(soap->z_buf, "\37\213\10\0\0\0\0\0\0\377", 10);
    4084     soap->d_stream.next_out = (Byte*)soap->z_buf + 10;
    4085     soap->d_stream.avail_out = SOAP_BUFLEN - 10;
    4086     soap->z_crc = crc32(0L, NULL, 0);
    4087     if (deflateInit2(&soap->d_stream, soap->z_level, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY) != Z_OK)
    4088 #else
    4089     soap->d_stream.next_out = (Byte*)soap->z_buf;
    4090     soap->d_stream.avail_out = SOAP_BUFLEN;
    4091     if (deflateInit(&soap->d_stream, soap->z_level) != Z_OK)
    4092 #endif
     5159    if (soap->zlib_out != SOAP_ZLIB_DEFLATE)
     5160    { memcpy(soap->z_buf, "\37\213\10\0\0\0\0\0\0\377", 10);
     5161      soap->d_stream->next_out = (Byte*)soap->z_buf + 10;
     5162      soap->d_stream->avail_out = SOAP_BUFLEN - 10;
     5163      soap->z_crc = crc32(0L, NULL, 0);
     5164      soap->zlib_out = SOAP_ZLIB_GZIP;
     5165      if (deflateInit2(soap->d_stream, soap->z_level, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY) != Z_OK)
     5166        return soap->error = SOAP_ZLIB_ERROR;
     5167    }
     5168    else
     5169#endif
     5170    if (deflateInit(soap->d_stream, soap->z_level) != Z_OK)
    40935171      return soap->error = SOAP_ZLIB_ERROR;
    40945172    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflate initialized\n"));
     
    40965174  }
    40975175#endif
    4098   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin send phase (socket=%d mode=%x count=%lu)\n", soap->socket, soap->mode, (unsigned long)soap->count));
     5176#ifdef WITH_OPENSSL
     5177  if (soap->ssl)
     5178    ERR_clear_error();
     5179#endif
     5180  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin send phase (socket=%d mode=0x%x count=%lu)\n", soap->socket, soap->mode, (unsigned long)soap->count));
     5181  soap->part = SOAP_BEGIN;
     5182#ifndef WITH_LEANER
    40995183  if (soap->fprepareinit && (soap->mode & SOAP_IO) == SOAP_IO_STORE)
    41005184    soap->fprepareinit(soap);   
     5185#endif
    41015186  return SOAP_OK;
    41025187}
     
    41045189
    41055190/******************************************************************************/
     5191#ifndef WITH_NOIDREF
    41065192#ifndef PALM_2
    41075193SOAP_FMAC1
     
    41175203}
    41185204#endif
    4119 
    4120 /******************************************************************************/
     5205#endif
     5206
     5207/******************************************************************************/
     5208#ifndef WITH_NOIDREF
    41215209#ifndef PALM_2
    41225210SOAP_FMAC1
     
    41435231}
    41445232#endif
    4145 
    4146 /******************************************************************************/
     5233#endif
     5234
     5235/******************************************************************************/
     5236#ifndef WITH_NOIDREF
    41475237#ifndef PALM_2
    41485238SOAP_FMAC1
     
    41525242{ register int i;
    41535243  struct soap_plist *pp;
    4154   if (!p)
     5244  if (!p || !a->__ptr)
    41555245    return 1;
    41565246  i = soap_array_pointer_lookup(soap, p, a, n, t, &pp);
     
    41715261}
    41725262#endif
    4173 
    4174 /******************************************************************************/
     5263#endif
     5264
     5265/******************************************************************************/
     5266#ifndef WITH_NOIDREF
    41755267#ifndef PALM_2
    41765268SOAP_FMAC1
     
    41785270SOAP_FMAC2
    41795271soap_embedded_id(struct soap *soap, int id, const void *p, int t)
    4180 { struct soap_plist *pp;
    4181   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded_id %p type=%d id=%d\n", p, t, id));
     5272{ struct soap_plist *pp = NULL;
    41825273  if (soap->mode & SOAP_XML_TREE)
    41835274    return id;
     5275  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded_id %p type=%d id=%d\n", p, t, id));
    41845276  if (soap->version == 1 && soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH) && soap->part != SOAP_IN_HEADER)
    41855277  { if (id < 0)
     
    42105302}
    42115303#endif
    4212 
    4213 /******************************************************************************/
     5304#endif
     5305
     5306/******************************************************************************/
     5307#ifndef WITH_NOIDREF
    42145308#ifndef PALM_2
    42155309SOAP_FMAC1
     
    42305324}
    42315325#endif
    4232 
    4233 /******************************************************************************/
     5326#endif
     5327
     5328/******************************************************************************/
     5329#ifndef WITH_NOIDREF
    42345330#ifndef PALM_2
    42355331SOAP_FMAC1
     
    42465342}
    42475343#endif
    4248 
    4249 /******************************************************************************/
     5344#endif
     5345
     5346/******************************************************************************/
     5347#ifndef WITH_NOIDREF
    42505348#ifndef PALM_2
    42515349SOAP_FMAC1
     
    42615359}
    42625360#endif
     5361#endif
    42635362
    42645363/******************************************************************************/
     
    42685367int
    42695368SOAP_FMAC2
    4270 soap_element_dime(struct soap *soap, const char *tag, int id, const void *p, const struct soap_array *a, const char *aid, const char *atype, const char *aoptions, int n, const char *type, int t)
    4271 { struct soap_plist *pp;
     5369soap_attachment(struct soap *soap, const char *tag, int id, const void *p, const struct soap_array *a, const char *aid, const char *atype, const char *aoptions, int n, const char *type, int t)
     5370{
     5371#ifndef WITH_NOIDREF
     5372  struct soap_plist *pp;
     5373  int i;
    42725374  if (!p || !a->__ptr || (!aid && !atype))
    42735375    return soap_element_id(soap, tag, id, p, a, n, type, t);
    4274   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Attachment tag='%s' id='%s' (%d) type='%s'\n", tag, aid?aid:"", id, atype?atype:""));
    4275   if (id < 0)
    4276     id = soap_array_pointer_lookup(soap, p, a, n, t, &pp);
     5376  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Attachment tag='%s' id='%s' (%d) type='%s'\n", tag, aid?aid:SOAP_STR_EOS, id, atype?atype:SOAP_STR_EOS));
     5377  i = soap_array_pointer_lookup(soap, p, a, n, t, &pp);
     5378  if (!i)
     5379  { i = soap_pointer_enter(soap, p, a, n, t, &pp);
     5380    if (!i)
     5381    { soap->error = SOAP_EOM;
     5382      return -1;
     5383    }
     5384  }
     5385  if (id <= 0)
     5386    id = i;
    42775387  if (!aid)
    42785388  { sprintf(soap->tmpbuf, soap->dime_id_format, id);
    42795389    aid = soap_strdup(soap, soap->tmpbuf);
    42805390  }
    4281   if (soap_element_href(soap, tag, 0, "href", aid))
     5391  /* Add MTOM xop:Include element when necessary */
     5392  /* TODO: this code to be obsoleted with new import/xop.h conventions */
     5393  if ((soap->mode & SOAP_ENC_MTOM) && strcmp(tag, "xop:Include"))
     5394  { if (soap_element_begin_out(soap, tag, 0, type)
     5395     || soap_element_href(soap, "xop:Include", 0, "href", aid)
     5396     || soap_element_end_out(soap, tag))
     5397      return soap->error;
     5398  }
     5399  else if (soap_element_href(soap, tag, 0, "href", aid))
    42825400    return soap->error;
    42835401  if (soap->mode & SOAP_IO_LENGTH)
    42845402  { if (pp->mark1 != 3)
    4285     { struct soap_multipart *content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, (char*)a->__ptr, a->__size);
     5403    { struct soap_multipart *content;
     5404      if (soap->mode & SOAP_ENC_MTOM)
     5405        content = soap_new_multipart(soap, &soap->mime.first, &soap->mime.last, (char*)a->__ptr, a->__size);
     5406      else
     5407        content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, (char*)a->__ptr, a->__size);
    42865408      if (!content)
    4287         return soap->error = SOAP_EOM;
    4288       content->id = aid;
     5409      { soap->error = SOAP_EOM;
     5410        return -1;
     5411      }
     5412      if (!strncmp(aid, "cid:", 4)) /* RFC 2111 */
     5413      { if (soap->mode & SOAP_ENC_MTOM)
     5414        { char *s = (char*)soap_malloc(soap, strlen(aid) - 1);
     5415          if (s)
     5416          { *s = '<';
     5417            strcpy(s + 1, aid + 4);
     5418            strcat(s, ">");
     5419            content->id = s;
     5420          }
     5421        }
     5422        else
     5423          content->id = aid + 4;
     5424      }
     5425      else
     5426        content->id = aid;
    42895427      content->type = atype;
    42905428      content->options = aoptions;
     5429      content->encoding = SOAP_MIME_BINARY;
    42915430      pp->mark1 = 3;
    42925431    }
     
    42945433  else
    42955434    pp->mark2 = 3;
    4296   return SOAP_OK;
    4297 }
    4298 #endif
    4299 #endif
    4300 
    4301 /******************************************************************************/
     5435#endif
     5436  return -1;
     5437}
     5438#endif
     5439#endif
     5440
     5441/******************************************************************************/
     5442#ifndef WITH_NOIDREF
    43025443#ifndef PALM_1
    43035444static void
     
    43095450}
    43105451#endif
    4311 
    4312 /******************************************************************************/
     5452#endif
     5453
     5454/******************************************************************************/
     5455#ifndef WITH_NOIDREF
    43135456#ifndef PALM_1
    43145457static void
    43155458soap_free_iht(struct soap *soap)
    43165459{ register int i;
    4317   register struct soap_ilist *ip, *p;
    4318   register struct soap_flist *fp, *fq;
     5460  register struct soap_ilist *ip = NULL, *p = NULL;
     5461  register struct soap_flist *fp = NULL, *fq = NULL;
    43195462  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free ID hashtable\n"));
    43205463  for (i = 0; i < SOAP_IDHASH; i++)
     
    43225465    { for (fp = ip->flist; fp; fp = fq)
    43235466      { fq = fp->next;
    4324         SOAP_FREE(fp);
     5467        SOAP_FREE(soap, fp);
    43255468      }
    43265469      p = ip->next;
    4327       SOAP_FREE(ip);
     5470      SOAP_FREE(soap, ip);
    43285471    }
    43295472    soap->iht[i] = NULL;
     
    43315474}
    43325475#endif
    4333 
    4334 /******************************************************************************/
     5476#endif
     5477
     5478/******************************************************************************/
     5479#ifndef WITH_NOIDREF
    43355480#ifndef PALM_2
    4336 static struct soap_ilist *
    4337 soap_hlookup(struct soap *soap, const char *id)
    4338 { register struct soap_ilist *ip;
     5481SOAP_FMAC1
     5482struct soap_ilist *
     5483SOAP_FMAC2
     5484soap_lookup(struct soap *soap, const char *id)
     5485{ register struct soap_ilist *ip = NULL;
    43395486  for (ip = soap->iht[soap_hash(id)]; ip; ip = ip->next)
    43405487    if (!strcmp(ip->id, id))
     
    43435490}
    43445491#endif
    4345 
    4346 /******************************************************************************/
    4347 #ifndef PALM_2
    4348 SOAP_FMAC1
    4349 struct soap_ilist *
    4350 SOAP_FMAC2
    4351 soap_lookup(struct soap *soap, const char *id)
    4352 { register struct soap_ilist *ip;
    4353   ip = soap_hlookup(soap, id);
    4354 #ifndef WITH_LEANER
    4355   if (!ip && *id != '#' && !strchr(id, ':')) /* try content id "cid:" with DIME attachments */
    4356   { char cid[SOAP_TAGLEN];
    4357     strcpy(cid, "cid:");
    4358     strncat(cid + 4, id, sizeof(cid) - 5);
    4359     cid[sizeof(cid) - 1] = '\0';
    4360     ip = soap_hlookup(soap, cid);
    4361   }
    4362 #endif
    4363   return ip;
    4364 }
    4365 #endif
    4366 
    4367 /******************************************************************************/
     5492#endif
     5493
     5494/******************************************************************************/
     5495#ifndef WITH_NOIDREF
    43685496#ifndef PALM_2
    43695497SOAP_FMAC1
     
    43735501{ register size_t h;
    43745502  register struct soap_ilist *ip;
    4375   ip = (struct soap_ilist*)SOAP_MALLOC(sizeof(struct soap_ilist) + strlen(id));
     5503  ip = (struct soap_ilist*)SOAP_MALLOC(soap, sizeof(struct soap_ilist) + strlen(id));
    43765504  if (ip)
    43775505  { h = soap_hash(id);
     
    43795507    ip->next = soap->iht[h];
    43805508    soap->iht[h] = ip;
    4381     return ip;
    4382   }
    4383   return NULL;
    4384 }
     5509  }
     5510  return ip;
     5511}
     5512#endif
    43855513#endif
    43865514
     
    43935521{ register char *p;
    43945522  if (!n)
    4395     return NULL;
     5523    return (void*)SOAP_NON_NULL;
    43965524  if (!soap)
    4397     return SOAP_MALLOC(n);
    4398   n += (-(long)n) & 7;
    4399   if (!(p = (char*)SOAP_MALLOC(n + sizeof(void*) + sizeof(size_t))))
    4400   { soap->error = SOAP_EOM;
    4401     return NULL;
    4402   }
    4403   /* keep chain of alloced cells for later destruction */
     5525    return SOAP_MALLOC(soap, n);
     5526  if (soap->fmalloc)
     5527    p = (char*)soap->fmalloc(soap, n);
     5528  else
     5529  { n += sizeof(short);
     5530    n += (-(long)n) & (sizeof(void*)-1); /* align at 4-, 8- or 16-byte boundary */
     5531    if (!(p = (char*)SOAP_MALLOC(soap, n + sizeof(void*) + sizeof(size_t))))
     5532    { soap->error = SOAP_EOM;
     5533      return NULL;
     5534    }
     5535    /* set the canary to detect corruption */
     5536    *(short*)(p + n - sizeof(short)) = (short)SOAP_CANARY;
     5537    /* keep chain of alloced cells for destruction */
     5538    *(void**)(p + n) = soap->alist;
     5539    *(size_t*)(p + n + sizeof(void*)) = n;
     5540    soap->alist = p + n;
     5541  }
    44045542  soap->alloced = 1;
    4405   *(void**)(p + n) = soap->alist;
    4406   *(size_t*)(p + n + sizeof(void*)) = n;
    4407   soap->alist = p + n;
    4408   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Malloc %u bytes at location %p\n", (unsigned int)n, p));
    44095543  return p;
    44105544}
     
    44125546
    44135547/******************************************************************************/
     5548#ifdef SOAP_MEM_DEBUG
     5549static void
     5550soap_init_mht(struct soap *soap)
     5551{ register int i;
     5552  for (i = 0; i < (int)SOAP_PTRHASH; i++)
     5553    soap->mht[i] = NULL;
     5554}
     5555#endif
     5556
     5557/******************************************************************************/
     5558#ifdef SOAP_MEM_DEBUG
     5559static void
     5560soap_free_mht(struct soap *soap)
     5561{ register int i;
     5562  register struct soap_mlist *mp, *mq;
     5563  for (i = 0; i < (int)SOAP_PTRHASH; i++)
     5564  { for (mp = soap->mht[i]; mp; mp = mq)
     5565    { mq = mp->next;
     5566      if (mp->live)
     5567        fprintf(stderr, "%s(%d): malloc() = %p not freed (memory leak or forgot to call soap_end()?)\n", mp->file, mp->line, mp->ptr);
     5568      free(mp);
     5569    }
     5570    soap->mht[i] = NULL;
     5571  }
     5572}
     5573#endif
     5574
     5575/******************************************************************************/
     5576#ifdef SOAP_MEM_DEBUG
     5577SOAP_FMAC1
     5578void*
     5579SOAP_FMAC2
     5580soap_track_malloc(struct soap *soap, const char *file, int line, size_t size)
     5581{ register void *p = malloc(size);
     5582  if (soap)
     5583  { register size_t h = soap_hash_ptr(p);
     5584    register struct soap_mlist *mp = (struct soap_mlist*)malloc(sizeof(struct soap_mlist));
     5585    if (soap->fdebug[SOAP_INDEX_TEST])
     5586    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): malloc(%lu) = %p\n", file, line, (unsigned long)size, p));
     5587    }
     5588    mp->next = soap->mht[h];
     5589    mp->ptr = p;
     5590    mp->file = file;
     5591    mp->line = line;
     5592    mp->live = 1;
     5593    soap->mht[h] = mp;
     5594  }
     5595  return p;
     5596}
     5597#endif
     5598
     5599/******************************************************************************/
     5600#ifdef SOAP_MEM_DEBUG
     5601SOAP_FMAC1
     5602void
     5603SOAP_FMAC2
     5604soap_track_free(struct soap *soap, const char *file, int line, void *p)
     5605{ register size_t h = soap_hash_ptr(p);
     5606  register struct soap_mlist *mp;
     5607  for (mp = soap->mht[h]; mp; mp = mp->next)
     5608    if (mp->ptr == p)
     5609      break;
     5610  if (mp)
     5611  { if (mp->live)
     5612    { free(p);
     5613      if (soap->fdebug[SOAP_INDEX_TEST])
     5614      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): free(%p)\n", file, line, p));
     5615      }
     5616      mp->live = 0;
     5617    }
     5618    else
     5619      fprintf(stderr, "%s(%d): free(%p) double free of pointer malloced at %s(%d)\n", file, line, p, mp->file, mp->line);
     5620  }
     5621  else
     5622    fprintf(stderr, "%s(%d): free(%p) pointer not malloced\n", file, line, p);
     5623}
     5624#endif
     5625
     5626/******************************************************************************/
     5627#ifdef SOAP_MEM_DEBUG
     5628static void
     5629soap_track_unlink(struct soap *soap, const void *p)
     5630{ register size_t h = soap_hash_ptr(p);
     5631  register struct soap_mlist *mp;
     5632  for (mp = soap->mht[h]; mp; mp = mp->next)
     5633    if (mp->ptr == p)
     5634      break;
     5635  if (mp)
     5636    mp->live = 0;
     5637}
     5638#endif
     5639
     5640/******************************************************************************/
    44145641#ifndef PALM_2
    44155642SOAP_FMAC1
     
    44175644SOAP_FMAC2
    44185645soap_dealloc(struct soap *soap, void *p)
    4419 { if (!soap)
     5646{ if (soap_check_state(soap))
    44205647    return;
    44215648  if (p)
    44225649  { register char **q;
    44235650    for (q = (char**)&soap->alist; *q; q = *(char***)q)
    4424     { if (p == (void*)(*q - *(size_t*)(*q + sizeof(void*))))
     5651    {
     5652      if (*(short*)(char*)(*q - sizeof(short)) != (short)SOAP_CANARY)
     5653      {
     5654#ifdef SOAP_MEM_DEBUG
     5655        fprintf(stderr, "Data corruption in dynamic allocation (see logs)\n");
     5656#endif
     5657        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Data corruption:\n"));
     5658        DBGHEX(TEST, *q - 200, 200);
     5659        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n"));
     5660        soap->error = SOAP_MOE;
     5661        return;
     5662      }
     5663      if (p == (void*)(*q - *(size_t*)(*q + sizeof(void*))))
    44255664      { *q = **(char***)q;
    44265665        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Freed data at %p\n", p));
    4427         SOAP_FREE(p);
     5666        SOAP_FREE(soap, p);
    44285667        return;
    44295668      }
     
    44335672  else
    44345673  { register char *q;
     5674    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free all soap_malloc() data\n"));
    44355675    while (soap->alist)
    44365676    { q = (char*)soap->alist;
     5677      if (*(short*)(char*)(q - sizeof(short)) != (short)SOAP_CANARY)
     5678      {
     5679#ifdef SOAP_MEM_DEBUG
     5680        fprintf(stderr, "Data corruption in dynamic allocation (see logs)\n");
     5681#endif
     5682        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Data corruption:\n"));
     5683        DBGHEX(TEST, q - 200, 200);
     5684        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n"));
     5685        soap->error = SOAP_MOE;
     5686        return;
     5687      }
    44375688      soap->alist = *(void**)q;
    44385689      q -= *(size_t*)(q + sizeof(void*));
    4439       SOAP_FREE(q);
    4440     }
    4441     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Dealloc all data done\n"));
    4442   }
    4443   /* we must assume these were deallocated: */
    4444   soap->action = NULL;
    4445   soap->fault = NULL;
    4446   soap->header = NULL;
    4447   soap->authrealm = NULL;
     5690      SOAP_FREE(soap, q);
     5691    }
     5692    /* we must assume these were deallocated: */
     5693    soap->action = NULL;
     5694    soap->fault = NULL;
     5695    soap->header = NULL;
     5696    soap->userid = NULL;
     5697    soap->passwd = NULL;
     5698    soap->authrealm = NULL;
     5699    soap->http_content = NULL;
    44485700#ifndef WITH_LEANER
    4449   soap_clr_mime(soap);
    4450 #endif
     5701    soap_clr_mime(soap);
     5702#endif
     5703  }
    44515704}
    44525705#endif
     
    44585711SOAP_FMAC2
    44595712soap_delete(struct soap *soap, void *p)
    4460 { register struct soap_clist **cp = &soap->clist;
     5713{ register struct soap_clist **cp;
     5714  if (soap_check_state(soap))
     5715    return;
     5716  cp = &soap->clist;
    44615717  if (p)
    44625718  { while (*cp)
     
    44645720      { register struct soap_clist *q = *cp;
    44655721        *cp = q->next;
    4466         q->fdelete(q);
    4467         SOAP_FREE(q);
     5722        if (q->fdelete(q))
     5723        { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not dealloc data %p: deletion callback failed for object type %d\n", q->ptr, q->type));
     5724#ifdef SOAP_MEM_DEBUG
     5725          fprintf(stderr, "new(object type = %d) = %p not freed: deletion callback failed\n", q->type, q->ptr);
     5726#endif
     5727        }
     5728        SOAP_FREE(soap, q);
    44685729        return;
    44695730      }
     
    44765737    { register struct soap_clist *q = *cp;
    44775738      *cp = q->next;
    4478       if (q->ptr == (void*)soap->fault)
    4479         soap->fault = NULL; /* this was deallocated */
    4480       else if (q->ptr == (void*)soap->header)
    4481         soap->header = NULL; /* this was deallocated */
    4482       q->fdelete(q);
    4483       SOAP_FREE(q);
    4484     }
    4485   }
     5739      if (q->fdelete(q))
     5740      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not dealloc data %p: deletion callback failed for object type %d\n", q->ptr, q->type));
     5741#ifdef SOAP_MEM_DEBUG
     5742        fprintf(stderr, "new(object type = %d) = %p not freed: deletion callback failed\n", q->type, q->ptr);
     5743#endif
     5744      }
     5745      SOAP_FREE(soap, q);
     5746    }
     5747  }
     5748  soap->fault = NULL; /* this was possibly deallocated */
     5749  soap->header = NULL; /* this was possibly deallocated */
    44865750}
    44875751#endif
     
    44925756struct soap_clist *
    44935757SOAP_FMAC2
    4494 soap_link(struct soap *soap, void *p, int t, int n, void (*fdelete)(struct soap_clist*))
     5758soap_link(struct soap *soap, void *p, int t, int n, int (*fdelete)(struct soap_clist*))
    44955759{ register struct soap_clist *cp;
    4496   if ((cp = (struct soap_clist*)SOAP_MALLOC(sizeof(struct soap_clist))))
     5760  if ((cp = (struct soap_clist*)SOAP_MALLOC(soap, sizeof(struct soap_clist))))
    44975761  { cp->next = soap->clist;
    44985762    cp->type = t;
     
    45205784    { *q = **(char***)q;
    45215785      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unlinked data %p\n", p));
     5786#ifdef SOAP_MEM_DEBUG
     5787      soap_track_unlink(soap, p);
     5788#endif
    45225789      return;
    45235790    }
     
    45285795      q = (char**)*cp;
    45295796      *cp = (*cp)->next;
    4530       SOAP_FREE(q);
     5797      SOAP_FREE(soap, q);
    45315798      return;
    45325799    }
     
    45365803
    45375804/******************************************************************************/
     5805#ifndef WITH_NOIDREF
    45385806#ifndef PALM_2
    45395807SOAP_FMAC1
     
    45535821}
    45545822#endif
    4555 
    4556 /******************************************************************************/
     5823#endif
     5824
     5825/******************************************************************************/
     5826#ifndef WITH_NOIDREF
    45575827#ifndef PALM_2
    45585828SOAP_FMAC1
     
    45625832{ struct soap_ilist *ip;
    45635833  void **q;
    4564   if (!id || !*id)
     5834  if (!p || !id || !*id)
    45655835    return p;
    4566   soap->alloced = 0;
    4567   if (!p)
    4568     p = (void**)soap_malloc(soap, sizeof(void*));
    45695836  ip = soap_lookup(soap, id); /* lookup pointer to hash table entry for string id */
    45705837  if (!ip)
    4571   { ip = soap_enter(soap, id); /* new hash table entry for string id */
     5838  { if (!(ip = soap_enter(soap, id))) /* new hash table entry for string id */
     5839      return NULL;
    45725840    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding first href='%s' type=%d %p (%u bytes)\n", id, t, p, (unsigned int)n));
    45735841    ip->type = t;
     
    45855853    { strcpy(soap->id, id);
    45865854      soap->error = SOAP_HREF;
    4587       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Type incompatibility: id type=%d href type=%d\n", ip->type, t));
     5855      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Type incompatibility: href='%s' id-type=%d href-type=%d\n", id, ip->type, t));
    45885856      return NULL;
    45895857    }
     
    46065874      while (q)
    46075875      { *r = (void*)soap_malloc(soap, sizeof(void*));
     5876        if (!*r)
     5877          return NULL;
    46085878        s = *q;
    46095879        *q = *r;
     
    46255895    while (ip->level < k)
    46265896    { q = (void**)soap_malloc(soap, sizeof(void*)); 
     5897      if (!q)
     5898        return NULL;
    46275899      *p = q;
    46285900      p = q;
     
    46375909}
    46385910#endif
    4639 
    4640 /******************************************************************************/
     5911#endif
     5912
     5913/******************************************************************************/
     5914#ifndef WITH_NOIDREF
    46415915#ifndef PALM_2
    46425916SOAP_FMAC1
    46435917void*
    46445918SOAP_FMAC2
    4645 soap_id_forward(struct soap *soap, const char *href, void *p, int st, int tt, size_t n, unsigned int k, void (*fcopy)(struct soap*, int, int, void*, const void*, size_t))
     5919soap_id_forward(struct soap *soap, const char *href, void *p, size_t len, int st, int tt, size_t n, unsigned int k, void (*fcopy)(struct soap*, int, int, void*, size_t, const void*, size_t))
    46465920{ struct soap_ilist *ip;
    46475921  if (!p || !href || !*href)
     
    46495923  ip = soap_lookup(soap, href); /* lookup pointer to hash table entry for string id */
    46505924  if (!ip)
    4651   { ip = soap_enter(soap, href); /* new hash table entry for string id */
     5925  { if (!(ip = soap_enter(soap, href))) /* new hash table entry for string id */
     5926      return NULL;
    46525927    ip->type = st;
    46535928    ip->size = n;
     
    46665941  }
    46675942  if (fcopy || n < sizeof(void*) || *href != '#')
    4668   { register struct soap_flist *fp = (struct soap_flist*)SOAP_MALLOC(sizeof(struct soap_flist));
     5943  { register struct soap_flist *fp = (struct soap_flist*)SOAP_MALLOC(soap, sizeof(struct soap_flist));
    46695944    if (!fp)
    46705945    { soap->error = SOAP_EOM;
     
    46755950    fp->ptr = p;
    46765951    fp->level = k;
     5952    fp->len = len;
    46775953    if (fcopy)
    46785954      fp->fcopy = fcopy;
     
    46805956      fp->fcopy = soap_fcopy;
    46815957    ip->flist = fp;
    4682     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding type=%d (target type=%d) size=%lu location=%p level=%u href='%s'\n", st, tt, (unsigned long)n, p, k, href));
     5958    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding type=%d (target type=%d) size=%lu location=%p level=%u len=%lu href='%s'\n", st, tt, (unsigned long)n, p, k, (unsigned long)len, href));
    46835959  }
    46845960  else
     
    46905966}
    46915967#endif
     5968#endif
    46925969
    46935970/******************************************************************************/
     
    46975974SOAP_FMAC2
    46985975soap_id_enter(struct soap *soap, const char *id, void *p, int t, size_t n, unsigned int k, const char *type, const char *arrayType, void *(*finstantiate)(struct soap*, int, const char*, const char*, size_t*))
    4699 { struct soap_ilist *ip;
     5976{
     5977#ifndef WITH_NOIDREF
     5978  struct soap_ilist *ip;
     5979#endif
    47005980  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Enter id='%s' type=%d loc=%p size=%lu level=%u\n", id, t, p, (unsigned long)n, k));
    47015981  soap->alloced = 0;
     
    47085988      soap->alloced = 1;
    47095989  }
     5990#ifndef WITH_NOIDREF
    47105991  if (!id || !*id)
     5992#endif
    47115993    return p;
     5994#ifndef WITH_NOIDREF
    47125995  ip = soap_lookup(soap, id); /* lookup pointer to hash table entry for string id */
    47135996  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Lookup entry id='%s for location=%p'\n", id, p));
    47145997  if (!ip)
    4715   { ip = soap_enter(soap, id); /* new hash table entry for string id */
     5998  { if (!(ip = soap_enter(soap, id))) /* new hash table entry for string id */
     5999      return NULL;
    47166000    ip->type = t;
    47176001    ip->link = NULL;
     
    47326016  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Multiply defined id='%s'\n", id));
    47336017    strcpy(soap->id, id);
    4734     soap->error = SOAP_MULTI_ID;
     6018    soap->error = SOAP_DUPLICATE_ID;
    47356019    return NULL;
    47366020  }
     
    47426026  }
    47436027  return ip->ptr;
     6028#endif
    47446029}
    47456030#endif
     
    47506035void
    47516036SOAP_FMAC2
    4752 soap_fcopy(struct soap *soap, int st, int tt, void *p, const void *q, size_t n)
     6037soap_fcopy(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n)
    47536038{ DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Copying data type=%d (target type=%d) %p -> %p (%lu bytes)\n", st, tt, q, p, (unsigned long)n));
    47546039  memcpy(p, q, n);
     
    47866071    { if (soap->mode & SOAP_ENC_ZLIB && soap->zlib_state == SOAP_ZLIB_DEFLATE)
    47876072      { soap->zlib_state = SOAP_ZLIB_NONE;
    4788         deflateEnd(&soap->d_stream);
     6073        deflateEnd(soap->d_stream);
    47896074      }
    47906075      return soap->error;
     
    47966081    if (soap->mode & SOAP_ENC_ZLIB)
    47976082    { int r;
    4798       soap->d_stream.avail_in = 0;
     6083      soap->d_stream->avail_in = 0;
    47996084      do
    48006085      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflating remainder\n"));
    4801         r = deflate(&soap->d_stream, Z_FINISH);
    4802         if (soap->d_stream.avail_out != SOAP_BUFLEN)
    4803         { if (soap_flush_raw(soap, soap->z_buf, SOAP_BUFLEN - soap->d_stream.avail_out))
     6086        r = deflate(soap->d_stream, Z_FINISH);
     6087        if (soap->d_stream->avail_out != SOAP_BUFLEN)
     6088        { if (soap_flush_raw(soap, soap->z_buf, SOAP_BUFLEN - soap->d_stream->avail_out))
    48046089          { soap->zlib_state = SOAP_ZLIB_NONE;
    4805             deflateEnd(&soap->d_stream);
     6090            deflateEnd(soap->d_stream);
    48066091            return soap->error;
    4807           }
    4808           soap->d_stream.next_out = (Byte*)soap->z_buf;
    4809           soap->d_stream.avail_out = SOAP_BUFLEN;
     6092          }
     6093          soap->d_stream->next_out = (Byte*)soap->z_buf;
     6094          soap->d_stream->avail_out = SOAP_BUFLEN;
    48106095        }
    48116096      } while (r == Z_OK);
    4812       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflated %lu->%lu bytes\n", soap->d_stream.total_in, soap->d_stream.total_out));
    4813       soap->z_ratio_out = (float)soap->d_stream.total_out / (float)soap->d_stream.total_in;
     6097      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflated total %lu->%lu bytes\n", soap->d_stream->total_in, soap->d_stream->total_out));
     6098      soap->z_ratio_out = (float)soap->d_stream->total_out / (float)soap->d_stream->total_in;
    48146099      soap->mode &= ~SOAP_ENC_ZLIB;
    48156100      soap->zlib_state = SOAP_ZLIB_NONE;
    4816       if (deflateEnd(&soap->d_stream) != Z_OK || r != Z_STREAM_END)
    4817       { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to end deflate: %s\n", soap->d_stream.msg?soap->d_stream.msg:""));
     6101      if (deflateEnd(soap->d_stream) != Z_OK || r != Z_STREAM_END)
     6102      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to end deflate: %s\n", soap->d_stream->msg?soap->d_stream->msg:SOAP_STR_EOS));
    48186103        return soap->error = SOAP_ZLIB_ERROR;
    48196104      }
    48206105#ifdef WITH_GZIP
    4821       soap->z_buf[0] = soap->z_crc & 0xFF;
    4822       soap->z_buf[1] = (soap->z_crc >> 8) & 0xFF;
    4823       soap->z_buf[2] = (soap->z_crc >> 16) & 0xFF;
    4824       soap->z_buf[3] = (soap->z_crc >> 24) & 0xFF;
    4825       soap->z_buf[4] = soap->d_stream.total_in & 0xFF;
    4826       soap->z_buf[5] = (soap->d_stream.total_in >> 8) & 0xFF;
    4827       soap->z_buf[6] = (soap->d_stream.total_in >> 16) & 0xFF;
    4828       soap->z_buf[7] = (soap->d_stream.total_in >> 24) & 0xFF;
    4829       if (soap_flush_raw(soap, soap->z_buf, 8))
    4830         return soap->error;
    4831       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip crc32=%lu\n", (unsigned long)soap->z_crc));
     6106      if (soap->zlib_out != SOAP_ZLIB_DEFLATE)
     6107      { soap->z_buf[0] = soap->z_crc & 0xFF;
     6108        soap->z_buf[1] = (soap->z_crc >> 8) & 0xFF;
     6109        soap->z_buf[2] = (soap->z_crc >> 16) & 0xFF;
     6110        soap->z_buf[3] = (soap->z_crc >> 24) & 0xFF;
     6111        soap->z_buf[4] = soap->d_stream->total_in & 0xFF;
     6112        soap->z_buf[5] = (soap->d_stream->total_in >> 8) & 0xFF;
     6113        soap->z_buf[6] = (soap->d_stream->total_in >> 16) & 0xFF;
     6114        soap->z_buf[7] = (soap->d_stream->total_in >> 24) & 0xFF;
     6115        if (soap_flush_raw(soap, soap->z_buf, 8))
     6116          return soap->error;
     6117        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip crc32=%lu\n", (unsigned long)soap->z_crc));
     6118      }
    48326119#endif
    48336120    }
     
    48356122    if ((soap->mode & SOAP_IO) == SOAP_IO_STORE)
    48366123    { char *p;
     6124#ifndef WITH_NOHTTP
    48376125      if (!(soap->mode & SOAP_ENC_XML))
    48386126      { soap->mode--;
     
    48466134        soap->mode++;
    48476135      }
    4848       for (p = soap_first_block(soap); p; p = soap_next_block(soap))
    4849       { DBGMSG(SENT, p, soap_block_size(soap));
    4850         if ((soap->error = soap->fsend(soap, p, soap_block_size(soap))))
    4851         { soap_end_block(soap);
     6136#endif
     6137      for (p = soap_first_block(soap, NULL); p; p = soap_next_block(soap, NULL))
     6138      { DBGMSG(SENT, p, soap_block_size(soap, NULL));
     6139        if ((soap->error = soap->fsend(soap, p, soap_block_size(soap, NULL))))
     6140        { soap_end_block(soap, NULL);
    48526141          return soap->error;
    48536142        }
    48546143      }
    4855       soap_end_block(soap);
    4856     }
     6144      soap_end_block(soap, NULL);
     6145    }
     6146#ifndef WITH_LEANER
    48576147    else if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK)
    48586148    { DBGMSG(SENT, "\r\n0\r\n\r\n", 7);
     
    48606150        return soap->error;
    48616151    }
    4862   }
     6152#endif
     6153  }
     6154#ifdef WITH_TCPFIN
    48636155#ifdef WITH_OPENSSL
    4864   if (!soap->ssl && soap_valid_socket(soap->socket) && !soap->keep_alive)
    4865     soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 1); /* Send TCP FIN */
     6156  if (!soap->ssl && soap_valid_socket(soap->socket) && !soap->keep_alive && !(soap->omode & SOAP_IO_UDP))
     6157    soap->fshutdownsocket(soap, soap->socket, 1); /* Send TCP FIN */
    48666158#else
    4867   if (soap_valid_socket(soap->socket) && !soap->keep_alive)
    4868     soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 1); /* Send TCP FIN */
    4869 #endif
    4870   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of send message ok\n"));
     6159  if (soap_valid_socket(soap->socket) && !soap->keep_alive && !(soap->omode & SOAP_IO_UDP))
     6160    soap->fshutdownsocket(soap, soap->socket, 1); /* Send TCP FIN */
     6161#endif
     6162#endif
     6163  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of send phase\n"));
     6164  soap->omode &= ~SOAP_XML_SEC;
     6165  soap->count = 0;
    48716166  soap->part = SOAP_END;
    4872   soap->count = 0;
    48736167  return SOAP_OK;
    48746168}
     
    48836177{ soap->part = SOAP_END;
    48846178#ifndef WITH_LEANER
    4885   if ((soap->mode & SOAP_ENC_MIME) && soap_getmime(soap))
     6179  if ((soap->mode & SOAP_ENC_DIME) && soap_getdime(soap))
     6180  { soap->dime.first = NULL;
     6181    soap->dime.last = NULL;
    48866182    return soap->error;
     6183  }
     6184  soap->dime.list = soap->dime.first;
     6185  soap->dime.first = NULL;
     6186  soap->dime.last = NULL;
     6187  /* Check if MIME attachments and mime-post-check flag is set, if set call soap_resolve() and return */
     6188  if (soap->mode & SOAP_ENC_MIME)
     6189  {
     6190#ifndef WITH_NOIDREF
     6191    if (soap->mode & SOAP_MIME_POSTCHECK)
     6192    { soap_resolve(soap);
     6193      return SOAP_OK;
     6194    }
     6195#endif
     6196    if (soap_getmime(soap))
     6197      return soap->error;
     6198  }
    48876199  soap->mime.list = soap->mime.first;
    48886200  soap->mime.first = NULL;
    48896201  soap->mime.last = NULL;
    4890   soap->dime.list = soap->dime.first;
    4891   soap->dime.first = NULL;
    4892   soap->dime.last = NULL;
     6202  soap->mime.boundary = NULL;
     6203  if (soap->xlist)
     6204  { struct soap_multipart *content;
     6205    for (content = soap->mime.list; content; content = content->next)
     6206      soap_resolve_attachment(soap, content);
     6207  }
    48936208#endif
    48946209  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "End of receive message ok\n"));
    48956210#ifdef WITH_ZLIB
    48966211  if (soap->mode & SOAP_ENC_ZLIB)
    4897   { soap->mode &= ~SOAP_ENC_ZLIB;
     6212  { /* Make sure end of compressed content is reached */
     6213    while (soap->d_stream->next_out != Z_NULL)
     6214      if ((int)soap_get1(soap) == EOF)
     6215        break;
     6216    soap->mode &= ~SOAP_ENC_ZLIB;
    48986217    memcpy(soap->buf, soap->z_buf, SOAP_BUFLEN);
    4899     soap->bufidx = (char*)soap->d_stream.next_in - soap->z_buf;
     6218    soap->bufidx = (char*)soap->d_stream->next_in - soap->z_buf;
    49006219    soap->buflen = soap->z_buflen;
    49016220    soap->zlib_state = SOAP_ZLIB_NONE;
    4902     if (inflateEnd(&soap->d_stream) != Z_OK)
     6221    if (inflateEnd(soap->d_stream) != Z_OK)
    49036222      return soap->error = SOAP_ZLIB_ERROR;
     6223    DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Inflate end ok\n"));
    49046224#ifdef WITH_GZIP
    49056225    if (soap->zlib_in == SOAP_ZLIB_GZIP)
    49066226    { soap_wchar c;
    49076227      short i;
     6228      DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Inflate gzip crc check\n"));
    49086229      for (i = 0; i < 8; i++)
    4909       { if ((int)(c = soap_getchar(soap)) == EOF)
     6230      { if ((int)(c = soap_get1(soap)) == EOF)
    49106231          return soap->error = SOAP_EOF;
    49116232        soap->z_buf[i] = (char)c;
     
    49156236        return soap->error = SOAP_ZLIB_ERROR;
    49166237      }
    4917       if (soap->d_stream.total_out != ((uLong)(unsigned char)soap->z_buf[4] | ((uLong)(unsigned char)soap->z_buf[5] << 8) | ((uLong)(unsigned char)soap->z_buf[6] << 16) | ((uLong)(unsigned char)soap->z_buf[7] << 24)))
     6238      if (soap->d_stream->total_out != ((uLong)(unsigned char)soap->z_buf[4] | ((uLong)(unsigned char)soap->z_buf[5] << 8) | ((uLong)(unsigned char)soap->z_buf[6] << 16) | ((uLong)(unsigned char)soap->z_buf[7] << 24)))
    49186239      { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Gzip error: incorrect message length\n"));
    49196240        return soap->error = SOAP_ZLIB_ERROR;
    49206241      }
    49216242    }
     6243    soap->zlib_in = SOAP_ZLIB_NONE;
    49226244#endif
    49236245  }
     
    49286250  if (soap->fdisconnect && (soap->error = soap->fdisconnect(soap)))
    49296251    return soap->error;
    4930   return soap_resolve(soap);
     6252#ifndef WITH_NOIDREF
     6253  if (soap_resolve(soap))
     6254    return soap->error;
     6255#endif
     6256#ifndef WITH_LEANER
     6257  if (soap->xlist)
     6258  { if (soap->mode & SOAP_ENC_MTOM)
     6259      return soap->error = SOAP_MIME_HREF;
     6260    return soap->error = SOAP_DIME_HREF;
     6261  }
     6262#endif
     6263  soap_free_temp(soap);
     6264  return SOAP_OK;
    49316265}
    49326266#endif
     
    49376271void
    49386272SOAP_FMAC2
    4939 soap_free(struct soap *soap)
    4940 { register struct soap_nlist *np;
    4941   register struct soap_attribute *tp;
     6273soap_free_temp(struct soap *soap)
     6274{ register struct soap_nlist *np, *nq;
     6275  register struct soap_attribute *tp, *tq;
    49426276  register struct Namespace *ns;
    49436277  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free namespace stack\n"));
    4944   while (soap->nlist)
    4945   { np = soap->nlist->next;
    4946     if (soap->nlist->ns)
    4947       SOAP_FREE(soap->nlist->ns);
    4948     SOAP_FREE(soap->nlist);
    4949     soap->nlist = np;
    4950   }
     6278  for (np = soap->nlist; np; np = nq)
     6279  { nq = np->next;
     6280    SOAP_FREE(soap, np);
     6281  }
     6282  soap->nlist = NULL;
    49516283  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free any remaining temp blocks\n"));
    49526284  while (soap->blist)
    4953     soap_end_block(soap);
    4954   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free attributes\n"));
    4955   while (soap->attributes)
    4956   { tp = soap->attributes->next;
    4957     if (soap->attributes->value)
    4958       SOAP_FREE(soap->attributes->value);
    4959     SOAP_FREE(soap->attributes);
    4960     soap->attributes = tp;
    4961   }
     6285    soap_end_block(soap, NULL);
     6286  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free attribute storage\n"));
     6287  for (tp = soap->attributes; tp; tp = tq)
     6288  { tq = tp->next;
     6289    if (tp->value)
     6290      SOAP_FREE(soap, tp->value);
     6291    SOAP_FREE(soap, tp);
     6292  }
     6293  soap->attributes = NULL;
    49626294#ifdef WITH_FAST
    49636295  if (soap->labbuf)
    4964     SOAP_FREE(soap->labbuf);
     6296    SOAP_FREE(soap, soap->labbuf);
    49656297  soap->labbuf = NULL;
    49666298  soap->lablen = 0;
    49676299  soap->labidx = 0;
    49686300#endif
    4969   soap_free_pht(soap);
    4970   soap_free_iht(soap);
    49716301  ns = soap->local_namespaces;
    49726302  if (ns)
    49736303  { for (; ns->id; ns++)
    49746304    { if (ns->out)
    4975       { SOAP_FREE(ns->out);
    4976         if (soap->encodingStyle == ns->out)
     6305      { if (soap->encodingStyle == ns->out)
    49776306          soap->encodingStyle = SOAP_STR_EOS;
     6307        SOAP_FREE(soap, ns->out);
    49786308        ns->out = NULL;
    49796309      }
     
    49816311        soap->encodingStyle = SOAP_STR_EOS;
    49826312    }
    4983     SOAP_FREE(soap->local_namespaces);
     6313    SOAP_FREE(soap, soap->local_namespaces);
    49846314    soap->local_namespaces = NULL;
    49856315  }
     6316#ifndef WITH_LEANER
     6317  while (soap->xlist)
     6318  { struct soap_xlist *xp = soap->xlist->next;
     6319    SOAP_FREE(soap, soap->xlist);
     6320    soap->xlist = xp;
     6321  }
     6322#endif
     6323#ifndef WITH_NOIDREF
     6324  soap_free_pht(soap);
     6325  soap_free_iht(soap);
     6326#endif
    49866327}
    49876328#endif
     
    50376378static void
    50386379soap_set_logfile(struct soap *soap, int i, const char *logfile)
    5039 { char *s = NULL;
     6380{ const char *s;
     6381  char *t = NULL;
    50406382  soap_close_logfile(soap, i);
    5041   if (soap->logfile[i])
    5042     SOAP_FREE((void*)soap->logfile[i]);
     6383  s = soap->logfile[i];
     6384  soap->logfile[i] = logfile;
     6385  if (s)
     6386    SOAP_FREE(soap, (void*)s);
    50436387  if (logfile)
    5044     if ((s = (char*)SOAP_MALLOC(strlen(logfile) + 1)))
    5045       strcpy(s, logfile);
    5046   soap->logfile[i] = s;
     6388    if ((t = (char*)SOAP_MALLOC(soap, strlen(logfile) + 1)))
     6389      strcpy(t, logfile);
     6390  soap->logfile[i] = t;
    50476391}
    50486392#endif
     
    50836427struct soap*
    50846428SOAP_FMAC2
    5085 soap_copy(struct soap *soap)
    5086 { return soap_copy_context((struct soap*)SOAP_MALLOC(sizeof(struct soap)), soap);
     6429soap_copy(const struct soap *soap)
     6430{ return soap_copy_context((struct soap*)malloc(sizeof(struct soap)), soap);
    50876431}
    50886432#endif
     
    50936437struct soap*
    50946438SOAP_FMAC2
    5095 soap_copy_context(struct soap *copy, struct soap *soap)
    5096 { if (copy)
    5097   { register struct soap_plugin *p;
     6439soap_copy_context(struct soap *copy, const struct soap *soap)
     6440{ if (soap_check_state(soap))
     6441    return NULL;
     6442  if (copy)
     6443  { register struct soap_plugin *p = NULL;
     6444#ifdef __cplusplus
     6445    *copy = *soap;
     6446#else
    50986447    memcpy(copy, soap, sizeof(struct soap));
    5099     copy->copy = 1;
    5100     copy->user = NULL;
     6448#endif
     6449    copy->state = SOAP_COPY;
     6450    copy->error = SOAP_OK;
    51016451    copy->userid = NULL;
    51026452    copy->passwd = NULL;
     
    51066456    copy->alist = NULL;
    51076457    copy->attributes = NULL;
     6458    copy->labbuf = NULL;
     6459    copy->lablen = 0;
     6460    copy->labidx = 0;
     6461#ifdef SOAP_MEM_DEBUG
     6462    soap_init_mht(copy);
     6463#endif
     6464#ifdef SOAP_DEBUG
     6465    soap_init_logs(copy);
     6466    soap_set_recv_logfile(copy, soap->logfile[SOAP_INDEX_RECV]);
     6467    soap_set_sent_logfile(copy, soap->logfile[SOAP_INDEX_SENT]);
     6468    soap_set_test_logfile(copy, soap->logfile[SOAP_INDEX_TEST]);
     6469#endif
     6470#ifdef WITH_C_LOCALE
     6471    copy->c_locale = duplocale(soap->c_locale);
     6472#else
     6473    copy->c_locale = NULL;
     6474#endif
     6475#ifdef WITH_OPENSSL
     6476    copy->bio = NULL;
     6477    copy->ssl = NULL;
     6478#endif
     6479#ifdef WITH_ZLIB
     6480    copy->d_stream = (z_stream*)SOAP_MALLOC(copy, sizeof(z_stream));
     6481    copy->d_stream->zalloc = Z_NULL;
     6482    copy->d_stream->zfree = Z_NULL;
     6483    copy->d_stream->opaque = Z_NULL;
     6484    copy->z_buf = NULL;
     6485#endif
    51086486    copy->local_namespaces = NULL;
    5109     soap_set_local_namespaces(copy);
     6487#ifndef WITH_NOIDREF
    51106488    soap_init_iht(copy);
    51116489    soap_init_pht(copy);
     6490#endif
    51126491    copy->header = NULL;
    51136492    copy->fault = NULL;
    51146493    copy->action = NULL;
    5115     *copy->host = '\0';
    51166494#ifndef WITH_LEAN
    51176495#ifdef WITH_COOKIES
    5118     copy->cookies = soap_copy_cookies(soap);
     6496    copy->cookies = soap_copy_cookies(copy, soap);
    51196497#else
    51206498    copy->cookies = NULL;
    51216499#endif
    51226500#endif
    5123 #ifdef SOAP_DEBUG
    5124     soap_init_logs(copy);
    5125     soap_set_recv_logfile(copy, "RECV.log");
    5126     soap_set_sent_logfile(copy, "SENT.log");
    5127     soap_set_test_logfile(copy, "TEST.log");
    5128 #endif
    51296501    copy->plugins = NULL;
    51306502    for (p = soap->plugins; p; p = p->next)
    5131     { register struct soap_plugin *q = (struct soap_plugin*)SOAP_MALLOC(sizeof(struct soap_plugin));
     6503    { register struct soap_plugin *q = (struct soap_plugin*)SOAP_MALLOC(copy, sizeof(struct soap_plugin));
    51326504      if (!q)
    51336505        return NULL;
    51346506      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying plugin '%s'\n", p->id));
    51356507      *q = *p;
    5136       if (p->fcopy && (soap->error = p->fcopy(soap, q, p)))
    5137       { SOAP_FREE(q);
     6508      if (p->fcopy && p->fcopy(copy, q, p))
     6509      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not copy plugin '%s'\n", p->id));
     6510        SOAP_FREE(copy, q);
    51386511        return NULL;
    51396512      }
     
    51426515    }
    51436516  }
    5144   else
    5145     soap->error = SOAP_EOM;
    51466517  return copy;
    51476518}
     
    51536524void
    51546525SOAP_FMAC2
     6526soap_copy_stream(struct soap *copy, struct soap *soap)
     6527{ copy->mode = soap->mode;
     6528  copy->imode = soap->imode;
     6529  copy->omode = soap->omode;
     6530  copy->socket = soap->socket;
     6531  copy->recv_timeout = soap->recv_timeout;
     6532  copy->send_timeout = soap->send_timeout;
     6533#if defined(__cplusplus) && !defined(WITH_LEAN)
     6534  copy->os = soap->os;
     6535  copy->is = soap->is;
     6536#endif
     6537  copy->sendfd = soap->sendfd;
     6538  copy->recvfd = soap->recvfd;
     6539  copy->bufidx = soap->bufidx;
     6540  copy->buflen = soap->buflen;
     6541  copy->ahead = soap->ahead;
     6542  copy->cdata = soap->cdata;
     6543  copy->chunksize = soap->chunksize;
     6544  copy->chunkbuflen = soap->chunkbuflen;
     6545  copy->keep_alive = soap->keep_alive;
     6546  copy->tcp_keep_alive = soap->tcp_keep_alive;
     6547  copy->tcp_keep_idle = soap->tcp_keep_idle;
     6548  copy->tcp_keep_intvl = soap->tcp_keep_intvl;
     6549  copy->tcp_keep_cnt = soap->tcp_keep_cnt;
     6550  copy->max_keep_alive = soap->max_keep_alive;
     6551#ifndef WITH_NOIO
     6552  copy->peer = soap->peer;
     6553  copy->peerlen = soap->peerlen;
     6554#endif
     6555#ifdef WITH_OPENSSL
     6556  copy->bio = soap->bio;
     6557  copy->ssl = soap->ssl;
     6558  copy->ctx = soap->ctx;
     6559#endif
     6560#ifdef WITH_ZLIB
     6561  copy->zlib_state = soap->zlib_state;
     6562  copy->zlib_in = soap->zlib_in;
     6563  copy->zlib_out = soap->zlib_out;
     6564  copy->d_stream = (z_stream*)SOAP_MALLOC(copy, sizeof(z_stream));
     6565  memcpy(copy->d_stream, soap->d_stream, sizeof(z_stream));
     6566  copy->z_crc = soap->z_crc;
     6567  copy->z_ratio_in = soap->z_ratio_in;
     6568  copy->z_ratio_out = soap->z_ratio_out;
     6569  copy->z_buf = NULL;
     6570  copy->z_buflen = soap->z_buflen;
     6571  copy->z_level = soap->z_level;
     6572  if (soap->z_buf && soap->zlib_state != SOAP_ZLIB_NONE)
     6573  { copy->z_buf = (char*)SOAP_MALLOC(copy, SOAP_BUFLEN);
     6574    memcpy(copy->z_buf, soap->z_buf, sizeof(soap->z_buf));
     6575  }
     6576#endif
     6577  memcpy(copy->buf, soap->buf, sizeof(soap->buf));
     6578}
     6579#endif
     6580
     6581/******************************************************************************/
     6582#ifndef PALM_1
     6583SOAP_FMAC1
     6584void
     6585SOAP_FMAC2
    51556586soap_init(struct soap *soap)
    5156 { soap->version = 0;
     6587{ soap->state = SOAP_INIT;
     6588#ifdef SOAP_MEM_DEBUG
     6589  soap_init_mht(soap);
     6590#endif
     6591#ifdef SOAP_DEBUG
     6592  soap_init_logs(soap);
     6593  soap_set_recv_logfile(soap, "RECV.log");
     6594  soap_set_sent_logfile(soap, "SENT.log");
     6595  soap_set_test_logfile(soap, "TEST.log");
     6596  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing context\n"));
     6597#endif
     6598  soap->version = 0;
    51576599  soap_imode(soap, SOAP_IO_DEFAULT);
    51586600  soap_omode(soap, SOAP_IO_DEFAULT);
    5159   soap->copy = 0;
    51606601  soap->plugins = NULL;
    51616602  soap->user = NULL;
    51626603  soap->userid = NULL;
    51636604  soap->passwd = NULL;
     6605#ifndef WITH_NOHTTP
    51646606  soap->fpost = http_post;
    51656607  soap->fget = http_get;
     6608  soap->fput = http_put;
     6609  soap->fdel = http_del;
     6610  soap->fhead = http_head;
     6611  soap->fform = NULL;
    51666612  soap->fposthdr = http_post_header;
    51676613  soap->fresponse = http_response;
    51686614  soap->fparse = http_parse;
    51696615  soap->fparsehdr = http_parse_header;
     6616#endif
     6617  soap->fheader = NULL;
    51706618  soap->fconnect = NULL;
    51716619  soap->fdisconnect = NULL;
    5172 #ifndef MAC_CARBON
     6620#ifndef WITH_NOIO
     6621  soap->ipv6_multicast_if = 0;
     6622  soap->ipv4_multicast_if = NULL;
    51736623#ifndef WITH_IPV6
    51746624  soap->fresolve = tcp_gethost;
     
    51856635  soap->fpoll = soap_poll;
    51866636#else
     6637  soap->fopen = NULL;
     6638  soap->fclose = NULL;
    51876639  soap->fpoll = NULL;
    51886640#endif
     6641  soap->fseterror = NULL;
     6642  soap->fignore = NULL;
     6643  soap->fserveloop = NULL;
     6644  soap->fplugin = fplugin;
     6645  soap->fmalloc = NULL;
     6646#ifndef WITH_LEANER
    51896647  soap->fprepareinit = NULL;
    51906648  soap->fpreparesend = NULL;
    51916649  soap->fpreparerecv = NULL;
    5192   soap->fignore = NULL;
    5193   soap->fserveloop = NULL;
    5194   soap->fplugin = fplugin;
     6650  soap->fpreparefinal = NULL;
    51956651  soap->fdimereadopen = NULL;
    51966652  soap->fdimewriteopen = NULL;
     
    51996655  soap->fdimeread = NULL;
    52006656  soap->fdimewrite = NULL;
    5201   soap->float_format = "%.8g"; /* .8 preserves single FP precision as much as possible, but might not be very efficient */
    5202   soap->double_format = "%.17lg"; /* .17 preserves double FP precision as much as possible, but might not be very efficient */
     6657  soap->fmimereadopen = NULL;
     6658  soap->fmimewriteopen = NULL;
     6659  soap->fmimereadclose = NULL;
     6660  soap->fmimewriteclose = NULL;
     6661  soap->fmimeread = NULL;
     6662  soap->fmimewrite = NULL;
     6663#endif
     6664  soap->float_format = "%.9G"; /* Alternative: use "%G" */
     6665  soap->double_format = "%.17lG"; /* Alternative: use "%lG" */
    52036666  soap->dime_id_format = "cid:id%d"; /* default DIME id format */
    52046667  soap->http_version = "1.1";
     6668  soap->proxy_http_version = "1.0";
     6669  soap->http_content = NULL;
    52056670  soap->actor = NULL;
     6671  soap->lang = "en";
     6672  soap->keep_alive = 0;
     6673  soap->tcp_keep_alive = 0;
     6674  soap->tcp_keep_idle = 0;
     6675  soap->tcp_keep_intvl = 0;
     6676  soap->tcp_keep_cnt = 0;
    52066677  soap->max_keep_alive = SOAP_MAXKEEPALIVE;
    5207   soap->keep_alive = 0;
    52086678  soap->recv_timeout = 0;
    52096679  soap->send_timeout = 0;
     
    52146684  soap->bind_flags = 0;
    52156685  soap->accept_flags = 0;
     6686  soap->linger_time = 0;
    52166687  soap->ip = 0;
    52176688  soap->labbuf = NULL;
     
    52366707  soap->os = NULL;
    52376708  soap->is = NULL;
     6709#ifndef WITH_LEANER
    52386710  soap->dom = NULL;
    52396711  soap->dime.list = NULL;
     
    52456717  soap->mime.boundary = NULL;
    52466718  soap->mime.start = NULL;
     6719  soap->xlist = NULL;
     6720#endif
    52476721#ifndef UNDER_CE
    52486722  soap->recvfd = 0;
     
    52616735  soap->authrealm = NULL;
    52626736  soap->prolog = NULL;
     6737#ifdef WITH_ZLIB
     6738  soap->zlib_state = SOAP_ZLIB_NONE;
     6739  soap->zlib_in = SOAP_ZLIB_NONE;
     6740  soap->zlib_out = SOAP_ZLIB_NONE;
     6741  soap->d_stream = (z_stream*)SOAP_MALLOC(soap, sizeof(z_stream));
     6742  soap->d_stream->zalloc = Z_NULL;
     6743  soap->d_stream->zfree = Z_NULL;
     6744  soap->d_stream->opaque = Z_NULL;
     6745  soap->z_buf = NULL;
     6746  soap->z_level = 6;
     6747#endif
     6748#ifndef WITH_LEAN
     6749  soap->c14ninclude = NULL;
     6750  soap->c14nexclude = NULL;
     6751  soap->cookies = NULL;
     6752  soap->cookie_domain = NULL;
     6753  soap->cookie_path = NULL;
     6754  soap->cookie_max = 32;
     6755#endif
     6756#ifdef WMW_RPM_IO
     6757  soap->rpmreqid = NULL;
     6758#endif
     6759#ifdef PALM
     6760  palmNetLibOpen();
     6761#endif
     6762#ifndef WITH_NOIDREF
     6763  soap_init_iht(soap);
     6764  soap_init_pht(soap);
     6765#endif
    52636766#ifdef WITH_OPENSSL
     6767  if (!soap_ssl_init_done)
     6768  { soap_ssl_init();
     6769    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing OpenSSL, version=%ld\n", (long)OPENSSL_VERSION_NUMBER));
     6770  }
    52646771  soap->fsslauth = ssl_auth_init;
    52656772  soap->fsslverify = ssl_verify_callback;
     
    52676774  soap->ssl = NULL;
    52686775  soap->ctx = NULL;
    5269   soap->require_server_auth = 0;
    5270   soap->require_client_auth = 0;
    5271   soap->rsa = 0;
     6776  soap->ssl_flags = SOAP_SSL_DEFAULT;
    52726777  soap->keyfile = NULL;
    52736778  soap->password = NULL;
     
    52756780  soap->cafile = NULL;
    52766781  soap->capath = NULL;
     6782  soap->crlfile = NULL;
    52776783  soap->randfile = NULL;
    52786784  soap->session = NULL;
    52796785#endif
    5280 #ifdef WITH_ZLIB
    5281   soap->zlib_state = SOAP_ZLIB_NONE;
    5282   soap->zlib_in = SOAP_ZLIB_NONE;
    5283   soap->zlib_out = SOAP_ZLIB_NONE;
    5284   soap->d_stream.zalloc = NULL;
    5285   soap->d_stream.zfree = NULL;
    5286   soap->d_stream.opaque = NULL;
    5287   soap->z_level = 6;
    5288 #endif
    5289 #ifndef WITH_LEAN
    5290   soap->cookies = NULL;
    5291   soap->cookie_domain = NULL;
    5292   soap->cookie_path = NULL;
    5293   soap->cookie_max = 32;
    5294 #endif
    5295 #ifdef SOAP_DEBUG
    5296   soap_init_logs(soap);
    5297   soap_set_recv_logfile(soap, "RECV.log");
    5298   soap_set_sent_logfile(soap, "SENT.log");
    5299   soap_set_test_logfile(soap, NULL);
    5300 #endif
    5301 /* WR[ */
    5302 #ifdef WMW_RPM_IO
    5303   soap->rpmreqid = NULL;
    5304 #endif /* WMW_RPM_IO */
    5305 /* ]WR */
    5306 #ifdef PALM
    5307   palmNetLibOpen();
    5308 #endif
    5309   soap_init_iht(soap);
    5310   soap_init_pht(soap);
     6786#ifdef WITH_C_LOCALE
     6787  soap->c_locale = newlocale(LC_ALL_MASK, "C", NULL);
     6788#else
     6789  soap->c_locale = NULL;
     6790#endif
    53116791  soap_begin(soap);
    5312 #ifdef SOAP_DEBUG
    5313   soap_set_test_logfile(soap, "TEST.log");
    5314 #endif
    53156792}
    53166793#endif
     
    53216798void
    53226799SOAP_FMAC2
    5323 soap_init1(struct soap *soap, int mode)
     6800soap_init1(struct soap *soap, soap_mode mode)
    53246801{ soap_init2(soap, mode, mode);
    53256802}
     
    53316808void
    53326809SOAP_FMAC2
    5333 soap_init2(struct soap *soap, int imode, int omode)
     6810soap_init2(struct soap *soap, soap_mode imode, soap_mode omode)
    53346811{ soap_init(soap);
    53356812  soap_imode(soap, imode);
     
    53446821SOAP_FMAC2
    53456822soap_begin(struct soap *soap)
    5346 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing\n"));
     6823{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Reinitializing context\n"));
    53476824  if (!soap->keep_alive)
    53486825  { soap->buflen = 0;
     
    53566833  soap->mode = 0;
    53576834  soap->ns = 0;
    5358   soap->part = SOAP_BEGIN;
     6835  soap->part = SOAP_END;
    53596836  soap->alloced = 0;
    53606837  soap->count = 0;
     
    53676844  soap->level = 0;
    53686845  soap->endpoint[0] = '\0';
     6846#ifndef WITH_LEANER
    53696847  soap->dime.chunksize = 0;
    53706848  soap->dime.buflen = 0;
    5371   soap_free(soap);
     6849#endif
     6850  soap_free_temp(soap);
    53726851}
    53736852#endif
     
    53796858SOAP_FMAC2
    53806859soap_end(struct soap *soap)
    5381 { register struct soap_clist *cp;
    5382   soap_free(soap);
     6860{ if (soap_check_state(soap))
     6861    return;
     6862  soap_free_temp(soap);
    53836863  soap_dealloc(soap, NULL);
    53846864  while (soap->clist)
    5385   { cp = soap->clist->next;
    5386     SOAP_FREE(soap->clist);
     6865  { register struct soap_clist *cp = soap->clist->next;
     6866    SOAP_FREE(soap, soap->clist);
    53876867    soap->clist = cp;
    53886868  }
     
    54026882int
    54036883SOAP_FMAC2
    5404 soap_set_namespaces(struct soap *soap, struct Namespace *p)
    5405 { struct Namespace *ns = soap->local_namespaces;
    5406   struct soap_nlist *np, *nq, *nr;
    5407   unsigned int level = soap->level;
     6884soap_set_namespaces(struct soap *soap, const struct Namespace *p)
     6885{ register struct Namespace *ns = soap->local_namespaces;
     6886  register struct soap_nlist *np, *nq, *nr;
     6887  register unsigned int level = soap->level;
    54086888  soap->namespaces = p;
    54096889  soap->local_namespaces = NULL;
    54106890  soap_set_local_namespaces(soap);
    5411   /* reverse the list */
     6891  /* reverse the namespace list */
    54126892  np = soap->nlist;
    54136893  soap->nlist = NULL;
     
    54226902    }
    54236903  }
     6904  /* then push on new stack */
    54246905  while (np)
    5425   { soap->level = np->level; /* preserve element nesting level */
    5426     if (np->ns)
    5427     { if (soap_push_namespace(soap, np->id, np->ns))
    5428         return soap->error;
    5429     }
    5430     else if (np->index >= 0 && ns)
    5431     { if (ns[np->index].out)
    5432       { if (soap_push_namespace(soap, np->id, ns[np->index].out))
    5433           return soap->error;
    5434       }
    5435       else if (soap_push_namespace(soap, np->id, ns[np->index].ns))
    5436         return soap->error;
    5437     }
    5438     if (np->ns)
    5439       SOAP_FREE(np->ns);
     6906  { register const char *s;
     6907    soap->level = np->level; /* preserve element nesting level */
     6908    s = np->ns;
     6909    if (!s && np->index >= 0 && ns)
     6910    { s = ns[np->index].out;
     6911      if (!s)
     6912        s = ns[np->index].ns;
     6913    }
     6914    if (s && soap_push_namespace(soap, np->id, s))
     6915      return soap->error;
    54406916    nq = np;
    54416917    np = np->next;
    5442     SOAP_FREE(nq);
     6918    SOAP_FREE(soap, nq);
    54436919  }
    54446920  if (ns)
    5445   { int i;
     6921  { register int i;
    54466922    for (i = 0; ns[i].id; i++)
    54476923    { if (ns[i].out)
    5448       { SOAP_FREE(ns[i].out);
     6924      { SOAP_FREE(soap, ns[i].out);
    54496925        ns[i].out = NULL;
    54506926      }
    54516927    }
    5452     SOAP_FREE(ns);
     6928    SOAP_FREE(soap, ns);
    54536929  }
    54546930  soap->level = level; /* restore level */
     
    54596935/******************************************************************************/
    54606936#ifndef PALM_1
    5461 static void
     6937SOAP_FMAC1
     6938void
     6939SOAP_FMAC2
    54626940soap_set_local_namespaces(struct soap *soap)
    54636941{ if (soap->namespaces && !soap->local_namespaces)
     
    54676945    for (ns1 = soap->namespaces; ns1->id; ns1++)
    54686946      n++;
    5469     if (n > 3)
    5470     { n *= sizeof(struct Namespace);
    5471       ns2 = (struct Namespace*)SOAP_MALLOC(n);
    5472       if (ns2)
    5473       { memcpy(ns2, soap->namespaces, n);
    5474         ns2[0].id = "SOAP-ENV";
    5475         ns2[1].id = "SOAP-ENC";
    5476         ns2[2].id = "xsi";
    5477         if (ns2[0].ns)
    5478         { if (!strcmp(ns2[0].ns, soap_env1))
    5479             soap->version = 1;
    5480           else
    5481             soap->version = 2;
    5482         }
    5483         soap->local_namespaces = ns2;
    5484       }
    5485     }
    5486   }
     6947    n *= sizeof(struct Namespace);
     6948    ns2 = (struct Namespace*)SOAP_MALLOC(soap, n);
     6949    if (ns2)
     6950    { memcpy(ns2, soap->namespaces, n);
     6951      if (ns2[0].ns)
     6952      { if (!strcmp(ns2[0].ns, soap_env1))
     6953          soap->version = 1;
     6954        else
     6955          soap->version = 2;
     6956      }
     6957      soap->local_namespaces = ns2;
     6958    }
     6959  }
     6960}
     6961#endif
     6962
     6963/******************************************************************************/
     6964#ifndef WITH_LEAN
     6965#ifndef PALM_1
     6966SOAP_FMAC1
     6967const char *
     6968SOAP_FMAC2
     6969soap_strsearch(const char *big, const char *little)
     6970{ size_t n = strlen(little);
     6971  const char *s = big;
     6972  while (s)
     6973  { if (!strncmp(s, little, n) && (s[n] == '\0' || s[n] == ' '))
     6974      return s;
     6975    s = strchr(s, ' ');
     6976    if (s)
     6977      s++;
     6978  }
     6979  return NULL;
     6980}
     6981#endif
     6982#endif
     6983
     6984/******************************************************************************/
     6985#ifndef WITH_LEAN
     6986#ifndef PALM_1
     6987SOAP_FMAC1
     6988struct soap_nlist *
     6989SOAP_FMAC2
     6990soap_lookup_ns(struct soap *soap, const char *tag, size_t n)
     6991{ register struct soap_nlist *np;
     6992  for (np = soap->nlist; np; np = np->next)
     6993  { if (!strncmp(np->id, tag, n) && !np->id[n])
     6994      return np;
     6995  }
     6996  return NULL;
     6997}
     6998#endif
     6999#endif
     7000
     7001/******************************************************************************/
     7002#ifndef WITH_LEAN
     7003static struct soap_nlist *
     7004soap_push_ns(struct soap *soap, const char *id, const char *ns, short utilized)
     7005{ register struct soap_nlist *np;
     7006  size_t n, k;
     7007  if (soap_strsearch(soap->c14nexclude, id))
     7008    return NULL;
     7009  if (!utilized)
     7010  { for (np = soap->nlist; np; np = np->next)
     7011    { if (!strcmp(np->id, id) && (!np->ns || !strcmp(np->ns, ns)))
     7012        break;
     7013    }
     7014    if (np)
     7015    { if ((np->level < soap->level || !np->ns) && np->index == 1)
     7016        utilized = 1;
     7017      else
     7018        return NULL;
     7019    }
     7020  }
     7021  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Adding namespace binding (level=%u) '%s' '%s' utilized=%d\n", soap->level, id, ns?ns:"(null)", utilized));
     7022  n = strlen(id);
     7023  if (ns)
     7024    k = strlen(ns);
     7025  else
     7026    k = 0;
     7027  np = (struct soap_nlist*)SOAP_MALLOC(soap, sizeof(struct soap_nlist) + n + k + 1);
     7028  if (!np)
     7029  { soap->error = SOAP_EOM;
     7030    return NULL;
     7031  }
     7032  np->next = soap->nlist;
     7033  soap->nlist = np;
     7034  strcpy(np->id, id);
     7035  if (ns)
     7036  { np->ns = np->id + n + 1;
     7037    strcpy(np->ns, ns);
     7038  }
     7039  else
     7040    np->ns = NULL;
     7041  np->level = soap->level;
     7042  np->index = utilized;
     7043  return np;
     7044}
     7045#endif
     7046
     7047/******************************************************************************/
     7048#ifndef WITH_LEAN
     7049static void
     7050soap_utilize_ns(struct soap *soap, const char *tag, size_t n)
     7051{ register struct soap_nlist *np = soap_lookup_ns(soap, tag, n);
     7052  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Utilizing namespace of '%s'\n", tag));
     7053  if (np)
     7054  { if (np->index == 0)
     7055      soap_push_ns(soap, np->id, np->ns, 1);
     7056  }
     7057  else if (strncmp(tag, "xml", 3))
     7058  { strncpy(soap->tmpbuf, tag, n);
     7059    soap->tmpbuf[n] = '\0';
     7060    soap_push_ns(soap, soap->tmpbuf, NULL, 1);
     7061  }
     7062}
     7063#endif
     7064
     7065/******************************************************************************/
     7066#ifndef WITH_LEAN
     7067static void
     7068soap_pop_ns(struct soap *soap)
     7069{ soap_pop_namespace(soap);
    54877070}
    54887071#endif
     
    54947077SOAP_FMAC2
    54957078soap_element(struct soap *soap, const char *tag, int id, const char *type)
    5496 { struct Namespace *ns = soap->local_namespaces;
    5497   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element begin tag='%s' id='%d' type='%s'\n", tag, id, type?type:""));
    5498 /**/
     7079{
     7080#ifdef WITH_XMLNS
     7081  register const char *s;
     7082#endif
     7083  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element begin tag='%s' id='%d' type='%s'\n", tag, id, type?type:SOAP_STR_EOS));
    54997084#ifdef WITH_DOM
     7085  if (soap->part == SOAP_BEGIN_SECURITY && (soap->mode & SOAP_XML_CANONICAL) && !(soap->mode & SOAP_DOM_ASIS))
     7086  { register struct soap_nlist *np;
     7087    /* wsu:Id found: clear xmlns renderings, so re-emit them for exc-c14n */
     7088    for (np = soap->nlist; np; np = np->next)
     7089    { if (np->index == 2)
     7090        np->index = 0;
     7091    }
     7092  }
    55007093  if (soap->mode & SOAP_XML_DOM)
    5501   { register struct soap_dom_element *p, *e = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element));
    5502     e->next = NULL;
    5503     e->prnt = soap->dom;
    5504     e->nstr = NULL;
    5505     e->name = soap_strdup(soap, tag); /* check EOM? */
    5506     e->data = NULL;
    5507     e->type = 0;
    5508     e->node = NULL;
    5509     e->elts = NULL;
    5510     e->atts = NULL;
     7094  { register struct soap_dom_element *elt = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element));
     7095    if (!elt)
     7096      return soap->error;
     7097    elt->soap = soap;
     7098    elt->next = NULL;
     7099    elt->prnt = soap->dom;
     7100    elt->name = soap_strdup(soap, tag);
     7101    elt->elts = NULL;
     7102    elt->atts = NULL;
     7103    elt->nstr = NULL;
     7104    elt->data = NULL;
     7105    elt->wide = NULL;
     7106    elt->node = NULL;
     7107    elt->type = 0;
     7108    elt->head = NULL;
     7109    elt->tail = NULL;
    55117110    if (soap->dom)
    5512     { p = soap->dom->elts;
     7111    { struct soap_dom_element *p = soap->dom->elts;
    55137112      if (p)
    55147113      { while (p->next)
    55157114          p = p->next;
    5516         p->next = e;
     7115        p->next = elt;
    55177116      }
    55187117      else
    5519         soap->dom->elts = e;
    5520     }
    5521     soap->dom = e;
     7118        soap->dom->elts = elt;
     7119    }
     7120    soap->dom = elt;
    55227121  }
    55237122  else
    5524 #endif
    5525 {
    5526   soap->level++;
    5527   if (!soap->ns && !(soap->mode & SOAP_XML_CANONICAL))
    5528     if (soap_send(soap, soap->prolog ? soap->prolog : "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"))
     7123  {
     7124#endif
     7125    soap->level++;
     7126#ifndef WITH_LEAN
     7127    if (!soap->ns)
     7128    { if (!(soap->mode & SOAP_XML_CANONICAL)
     7129       && soap_send(soap, soap->prolog ? soap->prolog : "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"))
     7130        return soap->error;
     7131    }
     7132    else if (soap->mode & SOAP_XML_INDENT)
     7133    { if (soap->ns == 1 && soap_send_raw(soap, soap_indent, soap->level < sizeof(soap_indent) ? soap->level : sizeof(soap_indent) - 1))
     7134        return soap->error;
     7135      soap->body = 1;
     7136    }
     7137#endif
     7138#ifdef WITH_XMLNS
     7139    s = strchr(tag, ':');
     7140    if (s && strncmp(tag, "SOAP-ENV", s - tag))
     7141    { struct Namespace *ns = soap->local_namespaces;
     7142      size_t n = s - tag;
     7143      if (soap_send_raw(soap, "<", 1)
     7144       || soap_send(soap, s + 1))
     7145        return soap->error;
     7146      if (soap->nlist && !strncmp(soap->nlist->id, tag, n) && !soap->nlist->id[n])
     7147        ns = NULL;
     7148      for (; ns && ns->id; ns++)
     7149      { if (*ns->id && (ns->out || ns->ns) && !strncmp(ns->id, tag, n) && !ns->id[n])
     7150        { soap_push_ns(soap, ns->id, ns->out ? ns->out : ns->ns, 0);
     7151          if (soap_attribute(soap, "xmlns", ns->out ? ns->out : ns->ns))
     7152            return soap->error;
     7153          break;
     7154        }
     7155      }   
     7156    }
     7157    else
     7158#endif
     7159    if (soap_send_raw(soap, "<", 1)
     7160     || soap_send(soap, tag))
    55297161      return soap->error;
    5530   if (soap_send_raw(soap, "<", 1)
    5531    || soap_send(soap, tag))
    5532     return soap->error;
    5533 }
    5534 /**/
     7162#ifdef WITH_DOM
     7163  }
     7164#endif
    55357165  if (!soap->ns)
    5536   { for (ns = soap->local_namespaces; ns && ns->id; ns++)
     7166  { struct Namespace *ns;
     7167    for (ns = soap->local_namespaces; ns && ns->id; ns++)
    55377168    { if (*ns->id && (ns->out || ns->ns))
    55387169      { sprintf(soap->tmpbuf, "xmlns:%s", ns->id);
     
    55417172      }
    55427173    }   
    5543     soap->ns = 1;
    5544   }
     7174  }
     7175  soap->ns = 1; /* namespace table control: ns = 0 or 2 to start, then 1 to stop dumping the table  */
     7176#ifndef WITH_LEAN
     7177  if (soap->mode & SOAP_XML_CANONICAL)
     7178  { const char *t = strchr(tag, ':');
     7179    if (t)
     7180      soap_utilize_ns(soap, tag, t - tag);
     7181  }
     7182#endif
    55457183  if (id > 0)
    55467184  { sprintf(soap->tmpbuf, "_%d", id);
     
    55487186      return soap->error;
    55497187  }
    5550   if (type && *type)
     7188  if (type && *type && (!(soap->mode & SOAP_XML_SEC) || soap->part == SOAP_IN_BODY))
    55517189  { if (soap_attribute(soap, "xsi:type", type))
    55527190      return soap->error;
     7191#ifndef WITH_LEAN
     7192    if (soap->mode & SOAP_XML_CANONICAL)
     7193    { const char *t = strchr(type, ':');
     7194      if (t)
     7195        soap_utilize_ns(soap, type, t - type);
     7196    }
     7197#endif
    55537198  }
    55547199  if (soap->null && soap->position > 0)
    5555   { int i;
     7200  { register int i;
    55567201    sprintf(soap->tmpbuf, "[%d", soap->positions[0]);
    55577202    for (i = 1; i < soap->position; i++)
     
    55857230  soap->null = 0;
    55867231  soap->position = 0;
     7232  if (soap->part == SOAP_BEGIN_SECURITY && (soap->mode & SOAP_XML_CANONICAL))
     7233    soap->part = SOAP_IN_SECURITY;
    55877234  return SOAP_OK;
    55887235}
     
    56397286      s++;
    56407287    while ((c = *s) && c >= '0' && c <= '9')
    5641     { if (n > 214748364)
     7288    { if (n >= 214748364 && (n > 214748364 || c >= '8'))
    56427289        break;
    56437290      n *= 10;
     
    56857332      s++;
    56867333    while ((c = *s) && c >= '0' && c <= '9')
    5687     { if (n > 429496729)
     7334    { if (n >= 429496729 && (n > 429496729 || c >= '6'))
    56887335        break;
    56897336      n *= 10;
     
    57407387      return soap->error;
    57417388  }
     7389#ifndef WITH_LEAN
     7390  if (type && *type && (soap->mode & SOAP_XML_CANONICAL))
     7391  { const char *s = strchr(type, ':');
     7392    if (s)
     7393      soap_utilize_ns(soap, type, s - type);
     7394  }
     7395#endif
    57427396  return soap_element_start_end_out(soap, NULL);
    57437397}
     
    57517405soap_element_start_end_out(struct soap *soap, const char *tag)
    57527406{ register struct soap_attribute *tp;
    5753 /**/
     7407#ifndef WITH_LEAN
     7408  if (soap->mode & SOAP_XML_CANONICAL)
     7409  { struct soap_nlist *np;
     7410    for (tp = soap->attributes; tp; tp = tp->next)
     7411    { if (tp->visible && tp->name)
     7412      { const char *s = strchr(tp->name, ':');
     7413        if (s)
     7414          soap_utilize_ns(soap, tp->name, s - tp->name);
     7415      }
     7416    }
     7417    for (np = soap->nlist; np; np = np->next)
     7418    { if (np->index == 1 && np->ns)
     7419      { sprintf(soap->tmpbuf, "xmlns:%s", np->id);
     7420        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Enabling utilized binding (level=%u) %s='%s'\n", np->level, soap->tmpbuf, np->ns));
     7421        soap_set_attr(soap, soap->tmpbuf, np->ns);
     7422        np->index = 2;
     7423      }
     7424    }
     7425  }
     7426#endif
    57547427#ifdef WITH_DOM
    57557428  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
    5756   { for (tp = soap->attributes; tp; tp = tp->next)
     7429  { register struct soap_dom_attribute **att;
     7430    att = &soap->dom->atts;
     7431    for (tp = soap->attributes; tp; tp = tp->next)
    57577432    { if (tp->visible)
    5758       { register struct soap_dom_attribute *a = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute));
    5759         a->next = soap->dom->atts;
    5760         a->nstr = NULL;
    5761         a->name = soap_strdup(soap, tp->name); /* check EOM */
    5762         a->data = soap_strdup(soap, tp->value); /* check EOM */
    5763         a->wide = NULL;
    5764         soap->dom->atts = a;
     7433      { *att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute));
     7434        if (!*att)
     7435          return soap->error;
     7436        (*att)->next = NULL;
     7437        (*att)->nstr = NULL;
     7438        (*att)->name = soap_strdup(soap, tp->name);
     7439        (*att)->data = soap_strdup(soap, tp->value);
     7440        (*att)->wide = NULL;
     7441        (*att)->soap = soap;
     7442        att = &(*att)->next;
    57657443        tp->visible = 0;
    57667444      }
     
    57697447  }
    57707448#endif
    5771 /**/
    57727449  for (tp = soap->attributes; tp; tp = tp->next)
    57737450  { if (tp->visible)
    5774     { if (soap_send2(soap, " ", tp->name))
     7451    {
     7452#ifdef WITH_XMLNS
     7453      const char *s = strchr(tp->name, ':');
     7454      if (s)
     7455      { size_t n = s - tp->name;
     7456        if (soap->nlist && !strncmp(soap->nlist->id, tp->name, n) && !soap->nlist->id[n])
     7457          s++;
     7458        else
     7459          s = tp->name;
     7460        if (soap_send(soap, " ") || soap_send(soap, s))
     7461          return soap->error;
     7462      }
     7463      else
     7464#endif
     7465      if (soap_send(soap, " ") || soap_send(soap, tp->name))
    57757466        return soap->error;
    57767467      if (tp->visible == 2 && tp->value)
    57777468        if (soap_send_raw(soap, "=\"", 2)
    5778         || soap_string_out(soap, tp->value, 1)
    5779         || soap_send_raw(soap, "\"", 1))
     7469        || soap_string_out(soap, tp->value, 1)
     7470        || soap_send_raw(soap, "\"", 1))
    57807471          return soap->error;
    57817472      tp->visible = 0;
     
    57837474  }
    57847475  if (tag)
    5785   { soap->level--;
     7476  {
    57867477#ifndef WITH_LEAN
    57877478    if (soap->mode & SOAP_XML_CANONICAL)
     
    57927483    }
    57937484#endif
    5794     return soap_send_raw(soap, "/>", 2);
     7485    soap->level--;      /* decrement level just before /> */
     7486    if (soap_send_raw(soap, "/>", 2))
     7487      return soap->error;
     7488    return SOAP_OK;
    57957489  }
    57967490  return soap_send_raw(soap, ">", 1);
     
    58077501    return SOAP_OK;
    58087502  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element ending tag='%s'\n", tag));
    5809 /**/
    58107503#ifdef WITH_DOM
    58117504  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
     
    58157508  }
    58167509#endif
    5817 /**/
    5818   soap->level--;
     7510#ifndef WITH_LEAN
     7511  if (soap->mode & SOAP_XML_CANONICAL)
     7512    soap_pop_ns(soap);
     7513  if (soap->mode & SOAP_XML_INDENT)
     7514  { if (!soap->body)
     7515    { if (soap_send_raw(soap, soap_indent, soap->level < sizeof(soap_indent) ? soap->level : sizeof(soap_indent) - 1))
     7516        return soap->error;
     7517    }
     7518    soap->body = 0;
     7519  }
     7520#endif
     7521#ifdef WITH_XMLNS
     7522  { const char *s = strchr(tag, ':');
     7523    if (s && strncmp(tag, "SOAP-ENV", s - tag))
     7524    { soap_pop_ns(soap);
     7525      tag = s + 1;
     7526    }
     7527  }
     7528#endif
    58197529  if (soap_send_raw(soap, "</", 2)
    58207530   || soap_send(soap, tag))
    58217531    return soap->error;
     7532  soap->level--;        /* decrement level just before > */
    58227533  return soap_send_raw(soap, ">", 1);
    58237534}
     
    58317542soap_element_ref(struct soap *soap, const char *tag, int id, int href)
    58327543{ register int n = 0;
     7544  const char *s = "href";
    58337545  if (soap->version == 2)
     7546  { s = "SOAP-ENC:ref";
    58347547    n = 1;
     7548  }
    58357549  sprintf(soap->href, "#_%d", href);
    5836   return soap_element_href(soap, tag, id, "href" + n, soap->href + n);
     7550  return soap_element_href(soap, tag, id, s, soap->href + n);
    58377551}
    58387552#endif
     
    58667580  { if (soap_element(soap, tag, id, type))
    58677581      return soap->error;
    5868     if (soap->part != SOAP_IN_HEADER && soap->encodingStyle)
    5869       if (soap_attribute(soap, "xsi:nil", "true"))
    5870         return soap->error;
     7582    if (!tp && soap_attribute(soap, "xsi:nil", "true"))
     7583      return soap->error;
    58717584    return soap_element_start_end_out(soap, tag);
    58727585  }
     
    58847597SOAP_FMAC2
    58857598soap_element_id(struct soap *soap, const char *tag, int id, const void *p, const struct soap_array *a, int n, const char *type, int t)
    5886 { struct soap_plist *pp;
    5887   if (!p || (a && !a->__ptr))
     7599{ if (!p || (a && !a->__ptr))
    58887600  { soap_element_null(soap, tag, id, type);
    58897601    return -1;
    58907602  }
     7603#ifndef WITH_NOIDREF
    58917604  if (soap->mode & SOAP_XML_TREE)
    58927605    return 0;
    58937606  if (id < 0)
    5894   { if (a)
     7607  { struct soap_plist *pp;
     7608    if (a)
    58957609      id = soap_array_pointer_lookup(soap, p, a, n, t, &pp);
    58967610    else
     
    59077621  }
    59087622  return id;
     7623#else
     7624  return 0;
     7625#endif
    59097626}
    59107627#endif
     
    59177634soap_element_result(struct soap *soap, const char *tag)
    59187635{ if (soap->version == 2 && soap->encodingStyle)
    5919     if (soap_element(soap, "SOAP-RPC:result", 0, NULL)
     7636  { if (soap_element(soap, "SOAP-RPC:result", 0, NULL)
    59207637     || soap_attribute(soap, "xmlns:SOAP-RPC", soap_rpc)
    59217638     || soap_element_start_end_out(soap, NULL)
     
    59237640     || soap_element_end_out(soap, "SOAP-RPC:result"))
    59247641      return soap->error;
     7642  }
    59257643  return SOAP_OK;
     7644}
     7645#endif
     7646
     7647/******************************************************************************/
     7648#ifndef PALM_1
     7649SOAP_FMAC1
     7650void
     7651SOAP_FMAC2
     7652soap_check_result(struct soap *soap, const char *tag)
     7653{ if (soap->version == 2 && soap->encodingStyle)
     7654  { soap_instring(soap, ":result", NULL, NULL, 0, 2, -1, -1);
     7655    /* just ignore content for compliance reasons, but should compare tag to element's QName value? */
     7656  }
    59267657}
    59277658#endif
     
    59347665soap_attribute(struct soap *soap, const char *name, const char *value)
    59357666{
    5936 /**/
    59377667#ifdef WITH_DOM
    5938   if ((soap->mode & SOAP_XML_DOM) && soap->dom)
     7668  if ((soap->mode & SOAP_XML_DOM) && !(soap->mode & SOAP_XML_CANONICAL) && soap->dom)
    59397669  { register struct soap_dom_attribute *a = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute));
     7670    if (!a)
     7671      return soap->error;
    59407672    a->next = soap->dom->atts;
    59417673    a->nstr = NULL;
    5942     a->name = soap_strdup(soap, name); /* check EOM */
    5943     a->data = soap_strdup(soap, value); /* check EOM */
     7674    a->name = soap_strdup(soap, name);
     7675    a->data = soap_strdup(soap, value);
    59447676    a->wide = NULL;
     7677    a->soap = soap;
    59457678    soap->dom->atts = a;
    59467679    return SOAP_OK;
    59477680  }
    59487681#endif
    5949 /**/
    59507682#ifndef WITH_LEAN
    59517683  if (soap->mode & SOAP_XML_CANONICAL)
    5952   { if (soap_set_attr(soap, name, value))
     7684  { /* TODO: consider using this code to handle default namespace bindings
     7685    if (!strncmp(name, "xmlns", 5) && (name[5] == ':' || name[5] == '\0'))
     7686    { if (name[5] == ':')
     7687        soap_push_ns(soap, name + 6, value, 0);
     7688      else
     7689        soap_push_ns(soap, "", value, 0);
     7690    }
     7691    */
     7692    if (!strncmp(name, "xmlns:", 6))
     7693      soap_push_ns(soap, name + 6, value, 0);
     7694    else if (soap_set_attr(soap, name, value))
    59537695      return soap->error;
    59547696  }
    59557697  else
    59567698#endif
    5957   { if (soap_send2(soap, " ", name))
     7699  { if (soap_send(soap, " ") || soap_send(soap, name))
    59587700      return soap->error;
    59597701    if (value)
     
    59727714int
    59737715SOAP_FMAC2
    5974 soap_element_begin_in(struct soap *soap, const char *tag, int nillable)
     7716soap_element_begin_in(struct soap *soap, const char *tag, int nillable, const char *type)
    59757717{ if (!soap_peek_element(soap))
    59767718  { if (soap->other)
     
    59807722    if (!(soap->error = soap_match_tag(soap, soap->tag, tag)))
    59817723    { soap->peeked = 0;
     7724      if (type && *soap->type && soap_match_tag(soap, soap->type, type))
     7725        return soap->error = SOAP_TYPE;
     7726      if (!nillable && soap->null && (soap->mode & SOAP_XML_STRICT))
     7727        return soap->error = SOAP_NULL;
    59827728      if (soap->body)
    59837729        soap->level++;
    5984       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag?tag:"" ));
    5985       if (!nillable && soap->null && (soap->mode & SOAP_XML_STRICT))
    5986         return soap->error = SOAP_NULL;
    5987     }
    5988   }
     7730      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag?tag:SOAP_STR_EOS ));
     7731    }
     7732  }
     7733  else if (soap->error == SOAP_NO_TAG && tag && *tag == '-')
     7734    soap->error = SOAP_OK;
    59897735  return soap->error;
    59907736}
     
    59997745{ register soap_wchar c;
    60007746  register char *s;
    6001   register const char *t;
     7747  register int n = 0;
    60027748  if (tag && *tag == '-')
    60037749    return SOAP_OK;
    6004   soap->level--;
    6005   soap_pop_namespace(soap);
     7750  if (soap->error == SOAP_NO_TAG)
     7751    soap->error = SOAP_OK;
     7752#ifdef WITH_DOM
     7753  /* this whitespace or mixed content is not insignificant for DOM */
     7754  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
     7755  { if (!soap->peeked && !soap_string_in(soap, 3, -1, -1))
     7756      return soap->error;
     7757    if (soap->dom->prnt)
     7758      soap->dom = soap->dom->prnt;
     7759  }
     7760#endif
    60067761  if (soap->peeked)
    6007   { if (*soap->tag == '\0')
    6008     { soap->peeked = 0;
    6009       if (soap->error == SOAP_NO_TAG || soap->error == SOAP_TAG_END)
    6010         soap->error = SOAP_OK;
    6011     }
    6012     else
    6013       return soap->error = SOAP_TAG_END;
    6014   }
    6015   else
     7762  { if (*soap->tag)
     7763      n++;
     7764    soap->peeked = 0;
     7765  }
     7766  do
    60167767  { while (((c = soap_get(soap)) != SOAP_TT))
    60177768    { if ((int)c == EOF)
    60187769        return soap->error = SOAP_EOF;
    60197770      if (c == SOAP_LT)
    6020         return soap->error = SOAP_TAG_END;
    6021     }
    6022   }
     7771        n++;
     7772      else if (c == '/')
     7773      { c = soap_get(soap);
     7774        if (c == SOAP_GT)
     7775          n--;
     7776        else
     7777          soap_unget(soap, c);
     7778      }
     7779    }
     7780  } while (n--);
    60237781  s = soap->tag;
    6024   do c = soap_get(soap);
    6025   while (soap_blank(c));
    6026   do
    6027   { *s++ = (char)c;
    6028     c = soap_get(soap);
    6029   } while (soap_notblank(c));
     7782  n = sizeof(soap->tag);
     7783  while (soap_notblank(c = soap_get(soap)))
     7784  { if (--n > 0)
     7785      *s++ = (char)c;
     7786  }
    60307787  *s = '\0';
    60317788  if ((int)c == EOF)
     
    60357792  if (c != SOAP_GT)
    60367793    return soap->error = SOAP_SYNTAX_ERROR;
    6037   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag?tag:""));
    6038   if (!tag)
    6039     return SOAP_OK;
    6040   if ((s = strchr(soap->tag, ':')))
    6041     s++;
    6042   else
    6043     s = soap->tag;
    6044   if ((t = strchr(tag, ':')))
    6045     t++;
    6046   else
    6047     t = tag;
    6048   if (!SOAP_STRCMP(s, t))
    6049     return SOAP_OK;
    6050   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element tag name does not match\n"));
    6051   return soap->error = SOAP_SYNTAX_ERROR;
     7794  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag?tag:SOAP_STR_EOS));
     7795#ifndef WITH_LEAN
     7796  if (tag && (soap->mode & SOAP_XML_STRICT))
     7797  { soap_pop_namespace(soap);
     7798    if (soap_match_tag(soap, soap->tag, tag))
     7799    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element tag name does not match\n"));
     7800      return soap->error = SOAP_SYNTAX_ERROR;
     7801    }
     7802  }
     7803#endif
     7804  soap->level--;
     7805  return SOAP_OK;
    60527806}
    60537807#endif
     
    60607814soap_attr_value(struct soap *soap, const char *name, int flag)
    60617815{ register struct soap_attribute *tp;
     7816  if (*name == '-')
     7817    return SOAP_STR_EOS;
    60627818  for (tp = soap->attributes; tp; tp = tp->next)
    6063     if (!soap_match_tag(soap, tp->name, name))
     7819  { if (tp->visible && !soap_match_tag(soap, tp->name, name))
    60647820      break;
    6065   if (tp && tp->visible == 2)
     7821  }
     7822  if (tp)
    60667823  { if (flag == 2 && (soap->mode & SOAP_XML_STRICT))
    60677824      soap->error = SOAP_PROHIBITED;
     
    60827839soap_set_attr(struct soap *soap, const char *name, const char *value)
    60837840{ register struct soap_attribute *tp;
    6084   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set attribute %s='%s'\n", name, value?value:""));
     7841  if (*name == '-')
     7842    return SOAP_OK;
     7843  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set attribute %s='%s'\n", name, value?value:SOAP_STR_EOS));
    60857844  for (tp = soap->attributes; tp; tp = tp->next)
    6086     if (!strcmp(tp->name, name))
     7845  { if (!strcmp(tp->name, name))
    60877846      break;
     7847  }
    60887848  if (!tp)
    60897849  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Allocate attribute %s\n", name));
    6090     if (!(tp = (struct soap_attribute*)SOAP_MALLOC(sizeof(struct soap_attribute) + strlen(name))))
     7850    if (!(tp = (struct soap_attribute*)SOAP_MALLOC(soap, sizeof(struct soap_attribute) + strlen(name))))
    60917851      return soap->error = SOAP_EOM;
    60927852    tp->ns = NULL;
     
    60957855    { struct soap_attribute **tpp = &soap->attributes;
    60967856      const char *s = strchr(name, ':');
     7857      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inserting attribute %s for c14n\n", name))
    60977858      if (!strncmp(name, "xmlns", 5))
    60987859      { for (; *tpp; tpp = &(*tpp)->next)
     
    61087869      { int k;
    61097870        for (; *tpp; tpp = &(*tpp)->next)
    6110         { if (!strncmp((*tpp)->name, "xmlns:", 6) && !strncmp((*tpp)->name + 6, name, s - name) && !(*tpp)->name[6 + s - name])
    6111           { if (!tp->ns)
    6112             { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Canonicalization: prefix %s=%p(%s)\n", name, (*tpp)->ns, (*tpp)->ns));
    6113               tp->ns = (*tpp)->ns;
    6114             }
    6115           }
     7871        { if (!strncmp((*tpp)->name, "xmlns:", 6) && !strncmp((*tpp)->name + 6, name, s - name) && !(*tpp)->name[6 + s - name])
     7872          { if (!tp->ns)
     7873            { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Canonicalization: prefix %s=%p (%s)\n", name, (*tpp)->ns, (*tpp)->ns));
     7874              tp->ns = (*tpp)->ns;
     7875            }
     7876          }
    61167877          else if (strncmp((*tpp)->name, "xmlns", 5) && (*tpp)->ns && tp->ns && ((k = strcmp((*tpp)->ns, tp->ns)) > 0 || (!k && strcmp((*tpp)->name, name) > 0)))
    61177878            break;
     
    61297890    tp->value = NULL;
    61307891  }
     7892  else if (tp->visible)
     7893  { return SOAP_OK;
     7894  }
    61317895  else if (value && tp->value && tp->size <= strlen(value))
    61327896  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free attribute value of %s (free %p)\n", name, tp->value));
    6133     SOAP_FREE(tp->value);
     7897    SOAP_FREE(soap, tp->value);
    61347898    tp->value = NULL;
    61357899    tp->ns = NULL;
     
    61387902  { if (!tp->value)
    61397903    { tp->size = strlen(value) + 1;
    6140       if (!(tp->value = (char*)SOAP_MALLOC(tp->size)))
     7904      if (!(tp->value = (char*)SOAP_MALLOC(soap, tp->size)))
    61417905        return soap->error = SOAP_EOM;
    6142       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Allocate attribute value of %s (%p)\n", tp->name, tp->value));
     7906      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Allocate attribute value for %s (%p)\n", tp->name, tp->value));
    61437907    }
    61447908    strcpy(tp->value, value);
     
    61467910      tp->ns = tp->value;
    61477911    tp->visible = 2;
     7912#ifndef WITH_LEAN
     7913    if (!strcmp(name, "wsu:Id"))
     7914    { soap->part = SOAP_BEGIN_SECURITY;
     7915      strncpy(soap->id, value, sizeof(soap->id));
     7916      soap->id[sizeof(soap->id)-1] = '\0';
     7917    }
     7918#endif
    61487919  }
    61497920  else
     
    61617932{ register struct soap_attribute *tp;
    61627933#ifndef WITH_LEAN
    6163   if (soap->mode & SOAP_XML_CANONICAL)
     7934  if ((soap->mode & SOAP_XML_CANONICAL))
    61647935  { while (soap->attributes)
    61657936    { tp = soap->attributes->next;
    6166       SOAP_FREE(soap->attributes->value);
    6167       SOAP_FREE(soap->attributes);
     7937      if (soap->attributes->value)
     7938        SOAP_FREE(soap, soap->attributes->value);
     7939      SOAP_FREE(soap, soap->attributes);
    61687940      soap->attributes = tp;
    61697941    }
     
    61817953static int
    61827954soap_getattrval(struct soap *soap, char *s, size_t n, soap_wchar d)
    6183 { size_t i;
    6184   soap_wchar c;
     7955{ register size_t i;
    61857956  for (i = 0; i < n; i++)
    6186   { c = soap_getutf8(soap);
     7957  { register soap_wchar c = soap_get(soap);
    61877958    switch (c)
    61887959    {
     
    62398010#ifdef WITH_FAST
    62408011#ifndef PALM_2
    6241 static int
     8012SOAP_FMAC1
     8013int
     8014SOAP_FMAC2
     8015soap_store_lab(struct soap *soap, const char *s, size_t n)
     8016{ soap->labidx = 0;
     8017  return soap_append_lab(soap, s, n);
     8018}
     8019#endif
     8020#endif
     8021
     8022/******************************************************************************/
     8023#ifdef WITH_FAST
     8024#ifndef PALM_2
     8025SOAP_FMAC1
     8026int
     8027SOAP_FMAC2
    62428028soap_append_lab(struct soap *soap, const char *s, size_t n)
    62438029{ if (soap->labidx + n >= soap->lablen)
     
    62498035      soap->lablen <<= 1;
    62508036    DBGLOG(TEST, SOAP_MESSAGE(fdebug, ", new size=%lu\n", (unsigned long)soap->lablen));
    6251     soap->labbuf = (char*)SOAP_MALLOC(soap->lablen);
     8037    soap->labbuf = (char*)SOAP_MALLOC(soap, soap->lablen);
    62528038    if (!soap->labbuf)
    62538039    { if (t)
    6254         free(t);
     8040        SOAP_FREE(soap, t);
    62558041      return soap->error = SOAP_EOM;
    62568042    }
    6257     if (t && soap->labidx)
     8043    if (t)
    62588044    { memcpy(soap->labbuf, t, soap->labidx);
    6259       free(t);
     8045      SOAP_FREE(soap, t);
    62608046    }
    62618047  }
     
    62758061SOAP_FMAC2
    62768062soap_peek_element(struct soap *soap)
    6277 { register struct soap_attribute *tp;
     8063{
     8064#ifdef WITH_DOM
     8065  register struct soap_dom_attribute **att = NULL;
     8066  register char *lead = NULL;
     8067#endif
     8068  register struct soap_attribute *tp, *tq = NULL;
    62788069  const char *t;
    62798070  register char *s;
    62808071  register soap_wchar c;
    62818072  register int i;
    6282   if (soap->error == SOAP_NO_TAG || soap->error == SOAP_TAG_END || soap->error == SOAP_TAG_MISMATCH)
    6283     soap->error = SOAP_OK;      /* retry */
    62848073  if (soap->peeked)
    6285   { if (*soap->tag == '\0')
     8074  { if (!*soap->tag)
    62868075      return soap->error = SOAP_NO_TAG;
    62878076    return SOAP_OK;
    62888077  }
    62898078  soap->peeked = 1;
    6290   for (;;)
    6291   { while (((c = soap_getutf8(soap)) != SOAP_LT) && c != SOAP_TT)
    6292     { if ((int)c == EOF)
    6293         return soap->error = SOAP_EOF;
    6294     }
    6295     if (c == SOAP_TT)
    6296     { *soap->tag = '\0';
    6297       return soap->error = SOAP_NO_TAG; /* ending tag found */
    6298     }
    6299     s = soap->tag;
    6300     do c = soap_get(soap);
    6301     while (soap_blank(c));
    6302     i = sizeof(soap->tag);
    6303     while (c != '/' && soap_notblank(c))
    6304     { if (--i > 0)
    6305         *s++ = (char)c;
    6306       c = soap_get(soap);
    6307     }
    6308     while (soap_blank(c))
    6309       c = soap_get(soap);
    6310     *s = '\0';
    6311     if (*soap->tag != '?')
    6312       break;
    6313     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "XML PI <%s?>\n", soap->tag));
    6314     while ((int)c != EOF && c != SOAP_GT && c != '?')
    6315     { s = soap->tmpbuf;
    6316       i = sizeof(soap->tmpbuf) - 2;
    6317       while (c != '=' && c != SOAP_GT && c != '?' && soap_notblank(c))
    6318       { if (--i > 0)
    6319           *s++ = (char)c;
    6320         c = soap_get(soap);
    6321       }
    6322       while (soap_blank(c))
    6323         c = soap_get(soap);
    6324       if (c == '=')
    6325       { *s++ = '=';
    6326         do c = soap_get(soap);
    6327         while (soap_blank(c));
    6328         if (c != SOAP_QT && c != SOAP_AP)
    6329         { soap_unget(soap, c);
    6330           c = ' '; /* blank delimiter */
    6331         }
    6332         if (soap_getattrval(soap, s, i, c) == SOAP_EOM)
    6333           while (soap_getattrval(soap, soap->tmpbuf, sizeof(soap->tmpbuf), c) == SOAP_EOM)
    6334             ;
    6335         else if (!strcmp(soap->tag, "?xml") && (!soap_tag_cmp(soap->tmpbuf, "encoding=iso-8859-1") || !soap_tag_cmp(soap->tmpbuf, "encoding=latin1")))
    6336         { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "XML latin1 encoding\n"));
    6337           soap->mode |= SOAP_ENC_LATIN;
    6338         }
    6339       }
    6340       do c = soap_get(soap);
    6341       while (soap_blank(c));
    6342     }
    6343   }
    63448079  soap->id[0] = '\0';
    63458080  soap->href[0] = '\0';
     
    63538088  soap->null = 0;
    63548089  soap->mustUnderstand = 0;
    6355   soap_clr_attr(soap);
    6356   while ((int)c != EOF && c != SOAP_GT && c != '/')
     8090  c = soap_getutf8(soap);
     8091#ifdef WITH_DOM
     8092  /* whitespace leading to start tag is not insignificant for DOM */
     8093  if (soap_blank(c))
     8094  { soap->labidx = 0;
     8095    do
     8096    { if (soap_append_lab(soap, NULL, 0))
     8097        return SOAP_EOM;
     8098      s = soap->labbuf + soap->labidx;
     8099      i = soap->lablen - soap->labidx;
     8100      soap->labidx = soap->lablen;
     8101      while (soap_blank(c) && i--)
     8102      { *s++ = c;
     8103        c = soap_getutf8(soap);
     8104      }
     8105    }
     8106    while (soap_blank(c));
     8107    *s = '\0';
     8108    lead = soap_strdup(soap, soap->labbuf);
     8109  }
     8110#else
     8111  while (soap_blank(c))
     8112    c = soap_getutf8(soap);
     8113#endif
     8114  if (c != SOAP_LT)
     8115  { *soap->tag = '\0';
     8116    if ((int)c == EOF)
     8117      return soap->error = SOAP_EOF;
     8118    soap_unget(soap, c);
     8119#ifdef WITH_DOM
     8120    /* whitespace leading to end tag is not insignificant for DOM */
     8121    if ((soap->mode & SOAP_XML_DOM) && soap->dom)
     8122      soap->dom->tail = soap_strdup(soap, lead);
     8123#endif
     8124    return soap->error = SOAP_NO_TAG;
     8125  }
     8126  s = soap->tag;
     8127  do c = soap_get1(soap);
     8128  while (soap_blank(c));
     8129  i = sizeof(soap->tag);
     8130  while (c != '>' && c != '/' && soap_notblank(c) && (int)c != EOF)
     8131  { if (--i > 0)
     8132      *s++ = (char)c;
     8133    c = soap_get1(soap);
     8134  }
     8135  while (soap_blank(c))
     8136    c = soap_get1(soap);
     8137  *s = '\0';
     8138#ifdef WITH_DOM
     8139  if (soap->mode & SOAP_XML_DOM)
     8140  { register struct soap_dom_element *elt;
     8141    elt = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element));
     8142    if (!elt)
     8143      return soap->error;
     8144    elt->next = NULL;
     8145    elt->nstr = NULL;
     8146    elt->name = soap_strdup(soap, soap->tag);
     8147    elt->prnt = soap->dom;
     8148    elt->elts = NULL;
     8149    elt->atts = NULL;
     8150    elt->data = NULL;
     8151    elt->wide = NULL;
     8152    elt->type = 0;
     8153    elt->node = NULL;
     8154    elt->head = lead;
     8155    elt->tail = NULL;
     8156    elt->soap = soap;
     8157    if (soap->dom)
     8158    { struct soap_dom_element *p = soap->dom->elts;
     8159      if (p)
     8160      { while (p->next)
     8161          p = p->next;
     8162        p->next = elt;
     8163      }
     8164      else
     8165        soap->dom->elts = elt;
     8166    }
     8167    soap->dom = elt;
     8168    att = &elt->atts;
     8169  }
     8170#endif
     8171  soap_pop_namespace(soap);
     8172  for (tp = soap->attributes; tp; tp = tp->next)
     8173    tp->visible = 0;
     8174  while ((int)c != EOF && c != '>' && c != '/')
    63578175  { s = soap->tmpbuf;
    63588176    i = sizeof(soap->tmpbuf);
    6359     while (c != '=' && c != '/' && soap_notblank(c))
     8177    while (c != '=' && c != '>' && c != '/' && soap_notblank(c) && (int)c != EOF)
    63608178    { if (--i > 0)
    63618179        *s++ = (char)c;
    6362       c = soap_get(soap);
     8180      c = soap_get1(soap);
    63638181    }
    63648182    *s = '\0';
    63658183    if (i == sizeof(soap->tmpbuf))
    63668184      return soap->error = SOAP_SYNTAX_ERROR;
    6367     if (!strncmp(soap->tmpbuf, "xmlns:", 6))
    6368     { soap->tmpbuf[5] = '\0';
    6369       t = soap->tmpbuf + 6;
    6370     }
    6371     else if (!strcmp(soap->tmpbuf, "xmlns"))
    6372       t = SOAP_STR_EOS;
     8185#ifdef WITH_DOM
     8186    /* add attribute name to dom */
     8187    if (att)
     8188    { *att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute));
     8189       if (!*att)
     8190         return soap->error;
     8191       (*att)->next = NULL;
     8192       (*att)->nstr = NULL;
     8193       (*att)->name = soap_strdup(soap, soap->tmpbuf);
     8194       (*att)->data = NULL;
     8195       (*att)->wide = NULL;
     8196       (*att)->soap = soap;
     8197    }
     8198#endif
     8199    if (!strncmp(soap->tmpbuf, "xmlns", 5))
     8200    { if (soap->tmpbuf[5] == ':')
     8201        t = soap->tmpbuf + 6;
     8202      else if (soap->tmpbuf[5])
     8203        t = NULL;
     8204      else
     8205        t = SOAP_STR_EOS;
     8206    }
    63738207    else
    63748208      t = NULL;
    6375     for (tp = soap->attributes; tp; tp = tp->next)
    6376       if (!SOAP_STRCMP(tp->name, soap->tmpbuf))
     8209    tq = NULL;
     8210    for (tp = soap->attributes; tp; tq = tp, tp = tp->next)
     8211    { if (!SOAP_STRCMP(tp->name, soap->tmpbuf))
    63778212        break;
     8213    }
    63788214    if (!tp)
    6379     { tp = (struct soap_attribute*)SOAP_MALLOC(sizeof(struct soap_attribute) + strlen(soap->tmpbuf));
     8215    { tp = (struct soap_attribute*)SOAP_MALLOC(soap, sizeof(struct soap_attribute) + strlen(soap->tmpbuf));
    63808216      if (!tp)
    63818217        return soap->error = SOAP_EOM;
     
    63838219      tp->value = NULL;
    63848220      tp->size = 0;
    6385       tp->next = soap->attributes;
    6386       soap->attributes = tp;
     8221      /* if attribute name is qualified, append it to the end of the list */
     8222      if (tq && strchr(soap->tmpbuf, ':'))
     8223      { tq->next = tp;
     8224        tp->next = NULL;
     8225      }
     8226      else
     8227      { tp->next = soap->attributes;
     8228        soap->attributes = tp;
     8229      }
    63878230    }
    63888231    while (soap_blank(c))
    6389       c = soap_get(soap);
     8232      c = soap_get1(soap);
    63908233    if (c == '=')
    6391     { do c = soap_get(soap);
     8234    { do c = soap_getutf8(soap);
    63928235      while (soap_blank(c));
    63938236      if (c != SOAP_QT && c != SOAP_AP)
     
    64018244          return soap->error;
    64028245        soap->error = SOAP_OK;
    6403         soap->labidx = 0;
    6404         if (soap_append_lab(soap, tp->value, tp->size))
    6405           return soap->error;
    6406         SOAP_FREE(tp->value);
    6407         for (;;)
    6408         { if (soap_getattrval(soap, soap->labbuf + soap->labidx, soap->lablen - soap->labidx, c))
    6409           { if (soap->error != SOAP_EOM)
    6410               return soap->error;
     8246        if (soap_store_lab(soap, tp->value, tp->size))
     8247          return soap->error;
     8248        if (tp->value)
     8249          SOAP_FREE(soap, tp->value);
     8250        for (;;)
     8251        { if (soap_getattrval(soap, soap->labbuf + soap->labidx, soap->lablen - soap->labidx, c))
     8252          { if (soap->error != SOAP_EOM)
     8253              return soap->error;
    64118254            soap->error = SOAP_OK;
    6412             soap->labidx = soap->lablen;
    6413             if (soap_append_lab(soap, NULL, 0))
    6414               return soap->error;
    6415           }
    6416           else
    6417             break;
    6418         }
    6419         tp->size = soap->lablen;
    6420         if (!(tp->value = (char*)SOAP_MALLOC(tp->size)))
    6421           return soap->error = SOAP_EOM;
    6422         memcpy(tp->value, soap->labbuf, soap->lablen);
     8255            soap->labidx = soap->lablen;
     8256            if (soap_append_lab(soap, NULL, 0))
     8257              return soap->error;
     8258          }
     8259          else
     8260            break;
     8261        }
     8262        if (soap->labidx)
     8263          tp->size = soap->lablen;
     8264        else
     8265        { tp->size = strlen(soap->labbuf) + 1;
     8266          if (tp->size < SOAP_LABLEN)
     8267            tp->size = SOAP_LABLEN;
     8268        }
     8269        if (!(tp->value = (char*)SOAP_MALLOC(soap, tp->size)))
     8270          return soap->error = SOAP_EOM;
     8271        strcpy(tp->value, soap->labbuf);
    64238272#else
    6424         size_t n;
     8273        size_t n;
    64258274        if (soap->error != SOAP_EOM)
    64268275          return soap->error;
    64278276        soap->error = SOAP_OK;
    6428         if (soap_new_block(soap))
     8277        if (soap_new_block(soap) == NULL)
    64298278          return soap->error;
    64308279        for (;;)
    6431         { if (!(s = (char*)soap_push_block(soap, SOAP_BLKLEN)))
     8280        { if (!(s = (char*)soap_push_block(soap, NULL, SOAP_BLKLEN)))
    64328281            return soap->error;
    64338282          if (soap_getattrval(soap, s, SOAP_BLKLEN, c))
     
    64398288            break;
    64408289        }
    6441         n = tp->size + soap->blist->size;
    6442         if (!(s = (char*)SOAP_MALLOC(n)))
     8290        n = tp->size + soap->blist->size;
     8291        if (!(s = (char*)SOAP_MALLOC(soap, n)))
    64438292          return soap->error = SOAP_EOM;
    64448293        if (tp->value)
    64458294        { memcpy(s, tp->value, tp->size);
    6446           SOAP_FREE(tp->value);
     8295          SOAP_FREE(soap, tp->value);
    64478296        }
    6448         soap_save_block(soap, s + tp->size, 0);
     8297        soap_save_block(soap, NULL, s + tp->size, 0);
    64498298        tp->value = s;
    64508299        tp->size = n;
    64518300#endif
    64528301      }
    6453       do c = soap_get(soap);
     8302      do c = soap_get1(soap);
    64548303      while (soap_blank(c));
    64558304      tp->visible = 2; /* seen this attribute w/ value */
     8305#ifdef WITH_DOM
     8306      if (att)
     8307        (*att)->data = soap_strdup(soap, tp->value);
     8308#endif
    64568309    }
    64578310    else
    64588311      tp->visible = 1; /* seen this attribute w/o value */
     8312#ifdef WITH_DOM
     8313    if (att)
     8314      att = &(*att)->next;
     8315#endif
    64598316    if (t && tp->value)
    64608317    { if (soap_push_namespace(soap, t, tp->value))
    64618318        return soap->error;
    6462       tp->visible = 0;
    6463     }
    6464   }
     8319    }
     8320  }
     8321#ifdef WITH_DOM
     8322  if (att)
     8323  { soap->dom->nstr = soap_current_namespace(soap, soap->tag);
     8324    for (att = &soap->dom->atts; *att; att = &(*att)->next)
     8325      (*att)->nstr = soap_current_namespace(soap, (*att)->name);
     8326  }
     8327#endif
    64658328  if ((int)c == EOF)
    64668329    return soap->error = SOAP_EOF;
     8330  if (!(soap->body = (c != '/')))
     8331    do c = soap_get1(soap);
     8332    while (soap_blank(c));
     8333#ifdef WITH_DOM
     8334  if (soap->mode & SOAP_XML_DOM)
     8335  { if (!soap->body && soap->dom->prnt)
     8336      soap->dom = soap->dom->prnt;
     8337  }
     8338#endif
    64678339  for (tp = soap->attributes; tp; tp = tp->next)
    64688340  { if (tp->visible && tp->value)
    6469     { if (!strcmp(tp->name, "id"))
    6470       { *soap->id = '#';
    6471         strncpy(soap->id + 1, tp->value, sizeof(soap->id) - 2);
    6472         soap->id[sizeof(soap->id)-1] = '\0';
     8341    {
     8342#ifndef WITH_NOIDREF
     8343      if (!strcmp(tp->name, "id"))
     8344      { if ((soap->version > 0 && !(soap->mode & SOAP_XML_TREE))
     8345         || (soap->mode & SOAP_XML_GRAPH))
     8346        { *soap->id = '#';
     8347          strncpy(soap->id + 1, tp->value, sizeof(soap->id) - 2);
     8348          soap->id[sizeof(soap->id)-1] = '\0';
     8349        }
    64738350      }
    64748351      else if (!strcmp(tp->name, "href"))
    6475       { strncpy(soap->href, tp->value, sizeof(soap->href) - 1);
    6476         soap->href[sizeof(soap->href)-1] = '\0';
    6477       }
    6478       else if ((soap->version == 2 || (soap->mode & SOAP_XML_GRAPH)) && !strcmp(tp->name, "ref"))
    6479       { *soap->href = '#';
    6480         strncpy(soap->href + 1, tp->value, sizeof(soap->href) - 2);
    6481         soap->href[sizeof(soap->href)-1] = '\0';
    6482       }
    6483       else if (!soap_match_tag(soap, tp->name, "xsi:type"))
     8352      { if (soap->version == 1
     8353         || (soap->mode & SOAP_XML_GRAPH)
     8354         || (soap->mode & SOAP_ENC_MTOM))
     8355        { strncpy(soap->href, tp->value, sizeof(soap->href) - 1);
     8356          soap->href[sizeof(soap->href)-1] = '\0';
     8357        }
     8358      }
     8359      else
     8360#endif
     8361      if (!soap_match_tag(soap, tp->name, "xsi:type"))
    64848362      { strncpy(soap->type, tp->value, sizeof(soap->type) - 1);
    64858363        soap->type[sizeof(soap->type)-1] = '\0';
    64868364      }
    6487       else if (soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENC:arrayType"))
    6488       { s = soap_strrchr(tp->value, '[');
    6489         if (s && (size_t)(s - tp->value) < sizeof(soap->arrayType))
    6490         { strncpy(soap->arrayType, tp->value, s - tp->value);
    6491           soap->arrayType[s - tp->value] = '\0';
    6492           strncpy(soap->arraySize, s, sizeof(soap->arraySize) - 1);
    6493         }
    6494         else
    6495           strncpy(soap->arrayType, tp->value, sizeof(soap->arrayType) - 1);
    6496         soap->arraySize[sizeof(soap->arrayType)-1] = '\0';
    6497         soap->arrayType[sizeof(soap->arrayType)-1] = '\0';
    6498       }
    6499       else if (soap->version == 2 && !soap_match_tag(soap, tp->name, "SOAP-ENC:itemType"))
    6500         strncpy(soap->arrayType, tp->value, sizeof(soap->arrayType) - 1);
    6501       else if (soap->version == 2 && !soap_match_tag(soap, tp->name, "SOAP-ENC:arraySize"))
    6502         strncpy(soap->arraySize, tp->value, sizeof(soap->arraySize) - 1);
    6503       else if (soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENC:offset"))
    6504         strncpy(soap->arrayOffset, tp->value, sizeof(soap->arrayOffset));
    6505       else if (soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENC:position"))
    6506         soap->position = soap_getposition(tp->value, soap->positions);
    6507       else if (soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENC:root"))
    6508         soap->root = ((!strcmp(tp->value, "1") || !strcmp(tp->value, "true")));
    6509       else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:actor")
    6510             || !soap_match_tag(soap, tp->name, "SOAP-ENV:role"))
    6511       { if ((!soap->actor || strcmp(soap->actor, tp->value))
    6512          && strcmp(tp->value, "http://schemas.xmlsoap.org/soap/actor/next")
    6513          && strcmp(tp->value, "http://www.w3.org/2003/05/soap-envelope/role/next"))
    6514           soap->other = 1;
    6515       }
    6516       else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:mustUnderstand")
    6517             && (!strcmp(tp->value, "1") || !strcmp(tp->value, "true")))
    6518         soap->mustUnderstand = 1;
    65198365      else if ((!soap_match_tag(soap, tp->name, "xsi:null")
    65208366             || !soap_match_tag(soap, tp->name, "xsi:nil"))
    65218367            && (!strcmp(tp->value, "1")
    65228368             || !strcmp(tp->value, "true")))
    6523         soap->null = 1;
    6524     }
    6525   }
    6526   if (!(soap->body = (c != '/')))
    6527     do c = soap_get(soap);
    6528     while (soap_blank(c));
    6529   return SOAP_OK;
     8369      { soap->null = 1;
     8370      }
     8371      else if (soap->version == 1)
     8372      { if (!soap_match_tag(soap, tp->name, "SOAP-ENC:arrayType"))
     8373        { s = soap_strrchr(tp->value, '[');
     8374          if (s && (size_t)(s - tp->value) < sizeof(soap->arrayType))
     8375          { strncpy(soap->arrayType, tp->value, s - tp->value);
     8376            soap->arrayType[s - tp->value] = '\0';
     8377            strncpy(soap->arraySize, s, sizeof(soap->arraySize) - 1);
     8378          }
     8379          else
     8380            strncpy(soap->arrayType, tp->value, sizeof(soap->arrayType) - 1);
     8381          soap->arraySize[sizeof(soap->arrayType)-1] = '\0';
     8382          soap->arrayType[sizeof(soap->arrayType)-1] = '\0';
     8383        }
     8384        else if (!soap_match_tag(soap, tp->name, "SOAP-ENC:offset"))
     8385          strncpy(soap->arrayOffset, tp->value, sizeof(soap->arrayOffset));
     8386        else if (!soap_match_tag(soap, tp->name, "SOAP-ENC:position"))
     8387          soap->position = soap_getposition(tp->value, soap->positions);
     8388        else if (!soap_match_tag(soap, tp->name, "SOAP-ENC:root"))
     8389          soap->root = ((!strcmp(tp->value, "1") || !strcmp(tp->value, "true")));
     8390        else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:mustUnderstand")
     8391              && (!strcmp(tp->value, "1") || !strcmp(tp->value, "true")))
     8392          soap->mustUnderstand = 1;
     8393        else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:actor"))
     8394        { if ((!soap->actor || strcmp(soap->actor, tp->value))
     8395           && strcmp(tp->value, "http://schemas.xmlsoap.org/soap/actor/next"))
     8396            soap->other = 1;
     8397        }
     8398      }
     8399      else if (soap->version == 2)
     8400      {
     8401#ifndef WITH_NOIDREF
     8402        if (!strcmp(tp->name, "ref")
     8403         || !soap_match_tag(soap, tp->name, "SOAP-ENC:ref"))
     8404        { *soap->href = '#';
     8405          strncpy(soap->href + 1, tp->value, sizeof(soap->href) - 2);
     8406          soap->href[sizeof(soap->href)-1] = '\0';
     8407        }
     8408        else
     8409#endif
     8410        if (!soap_match_tag(soap, tp->name, "SOAP-ENC:itemType"))
     8411          strncpy(soap->arrayType, tp->value, sizeof(soap->arrayType) - 1);
     8412        else if (!soap_match_tag(soap, tp->name, "SOAP-ENC:arraySize"))
     8413          strncpy(soap->arraySize, tp->value, sizeof(soap->arraySize) - 1);
     8414        else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:mustUnderstand")
     8415              && (!strcmp(tp->value, "1") || !strcmp(tp->value, "true")))
     8416          soap->mustUnderstand = 1;
     8417        else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:role"))
     8418        { if ((!soap->actor || strcmp(soap->actor, tp->value))
     8419           && strcmp(tp->value, "http://www.w3.org/2003/05/soap-envelope/role/next"))
     8420            soap->other = 1;
     8421        }
     8422      }
     8423    }
     8424  }
     8425  return soap->error = SOAP_OK;
    65308426}
    65318427#endif
     
    65378433SOAP_FMAC2
    65388434soap_retry(struct soap *soap)
    6539 { soap->peeked = 1;
    6540   soap->error = SOAP_OK;
     8435{ soap->error = SOAP_OK;
     8436  soap_revert(soap);
    65418437}
    65428438#endif
     
    65658461{ register const char *t;
    65668462  register soap_wchar c;
    6567   register soap_wchar mask = 0x80000000;
     8463  register soap_wchar mask = (soap_wchar)0xFFFFFF80UL;
    65688464#ifdef WITH_DOM
    65698465  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
    6570   { soap->dom->data = soap_strdup(soap, s); /* check EOM */
     8466  { soap->dom->data = soap_strdup(soap, s);
    65718467    return SOAP_OK;
    65728468  }
     
    65788474  { switch (c)
    65798475    {
    6580     case 9:
     8476    case 0x09:
    65818477      if (flag)
    65828478      { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&#x9;", 5))
    6583           return soap->error;
     8479          return soap->error;
    65848480        s = t;
    65858481      }
    65868482      break;
    6587     case 10:
     8483    case 0x0A:
    65888484      if (flag || !(soap->mode & SOAP_XML_CANONICAL))
    65898485      { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&#xA;", 5))
    6590           return soap->error;
     8486          return soap->error;
    65918487        s = t;
    65928488      }
    65938489      break;
    6594     case 13:
     8490    case 0x0D:
    65958491      if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&#xD;", 5))
    65968492        return soap->error;
     
    66108506      if (!flag)
    66118507      { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&gt;", 4))
    6612           return soap->error;
     8508          return soap->error;
    66138509        s = t;
    66148510      }
     
    66178513      if (flag)
    66188514      { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&quot;", 6))
    6619           return soap->error;
     8515          return soap->error;
    66208516        s = t;
    66218517      }
    66228518      break;
    66238519    default:
     8520#ifndef WITH_LEANER
    66248521#ifdef HAVE_MBTOWC
    66258522      if (soap->mode & SOAP_C_MBSTRING)
     
    66298526        { if (soap_send_raw(soap, s, t - s - 1) || soap_pututf8(soap, wc))
    66308527            return soap->error;
    6631           s = t + m - 1;
    6632           continue;
     8528          s = t += m - 1;
     8529          continue;
    66338530        }
    66348531      }
    66358532#endif
    6636       if (c & mask)
     8533#endif
     8534#ifndef WITH_NOSTRINGTOUTF8
     8535      if ((c & mask) || !(c & 0xFFFFFFE0UL))
    66378536      { if (soap_send_raw(soap, s, t - s - 1) || soap_pututf8(soap, (unsigned char)c))
    66388537          return soap->error;
    66398538        s = t;
    66408539      }
     8540#endif
    66418541    }
    66428542  }
     
    66558555  register size_t i;
    66568556  register long l = 0;
    6657   register int n = 0;
    6658   register int m = 0;
     8557  register int n = 0, f = 0, m = 0;
    66598558  register soap_wchar c;
    6660 #ifdef HAVE_WCTOMB
     8559#if !defined(WITH_LEANER) && defined(HAVE_WCTOMB)
    66618560  char buf[MB_LEN_MAX > 8 ? MB_LEN_MAX : 8];
    66628561#else
    66638562  char buf[8];
    66648563#endif
     8564  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Reading string content\n"));
     8565  if (soap->peeked)
     8566  { if (*soap->tag)
     8567    {
     8568#ifndef WITH_LEAN
     8569      struct soap_attribute *tp;
     8570      t = soap->tmpbuf;
     8571      *t = '<';
     8572      t[sizeof(soap->tmpbuf)-1] = '\0';
     8573      strncpy(t + 1, soap->tag, sizeof(soap->tmpbuf) - 2);
     8574      t += strlen(t);
     8575      for (tp = soap->attributes; tp; tp = tp->next)
     8576      { if (tp->visible)
     8577        { if (t >= soap->tmpbuf + sizeof(soap->tmpbuf) - 2)
     8578            break;
     8579          *t++ = ' ';
     8580          strcpy(t, tp->name);
     8581          t += strlen(t);
     8582          if (t >= soap->tmpbuf + sizeof(soap->tmpbuf) - 2)
     8583            break; /* too many or large attribute values */
     8584          if (tp->value)
     8585          { *t++ = '=';
     8586            *t++ = '"';
     8587            strcpy(t, tp->value);
     8588            t += strlen(t);
     8589            *t++ = '"';
     8590          }
     8591        }
     8592      }
     8593      if (!soap->body)
     8594        *t++ = '/';
     8595      *t++ = '>';
     8596      *t = '\0';
     8597      t = soap->tmpbuf;
     8598      m = (int)strlen(soap->tmpbuf);
     8599#endif
     8600      if (soap->body)
     8601        n = 1;
     8602      f = 1;
     8603      soap->peeked = 0;
     8604    }
     8605  }
    66658606#ifdef WITH_CDATA
    66668607  if (!flag)
     
    66698610    soap->labidx = 0;                   /* use look-aside buffer */
    66708611#else
    6671     if (soap_new_block(soap))
     8612    if (soap_new_block(soap) == NULL)
    66728613      return NULL;
    66738614#endif
     
    66838624#else
    66848625      register size_t k = SOAP_BLKLEN;
    6685       if (!(s = (char*)soap_push_block(soap, k)))
     8626      if (!(s = (char*)soap_push_block(soap, NULL, k)))
    66868627        return NULL;
    66878628#endif
     
    66898630      { if (m > 0)
    66908631        { *s++ = *t++;  /* copy multibyte characters */
    6691           m--;
     8632          m--;
    66928633          continue;
    66938634        }
    66948635        c = soap_getchar(soap);
    6695         if ((int)c == EOF)
     8636        if ((int)c == EOF)
    66968637          goto end;
    6697         if (c >= 0x80 && !(soap->mode & SOAP_ENC_LATIN))
     8638        if (c >= 0x80 && state != 1 && !(soap->mode & SOAP_ENC_LATIN))
    66988639        { soap_unget(soap, c);
    6699           c = soap_getutf8(soap);
    6700           if (soap->mode & SOAP_C_UTFSTRING)
     8640          c = soap_getutf8(soap);
     8641          if (soap->mode & SOAP_C_UTFSTRING)
    67018642          { if ((c & 0x80000000) && c >= -0x7FFFFF80 && c < SOAP_AP)
    67028643            { c &= 0x7FFFFFFF;
     
    67248665              }
    67258666              *t++ = (char)(0x80 | (c & 0x3F));
    6726               m = (int)(t - buf) - 1;
     8667              m = (int)(t - buf) - 1;
    67278668              t = buf;
    67288669              *s++ = *t++;
    67298670              continue;
    6730             }
     8671            }
    67318672          }
    67328673        }
    6733         switch (state)
     8674        switch (state)
    67348675        { case 1:
    67358676            if (c == ']')
    6736               state = 4;
    6737             *s++ = c;
    6738             continue;
    6739           case 2:
    6740             if (c == '-')
     8677              state = 4;
     8678            *s++ = c;
     8679            continue;
     8680          case 2:
     8681            if (c == '-')
    67418682              state = 6;
    6742             *s++ = c;
    6743             continue;
    6744           case 3:
    6745             if (c == '?')
    6746               state = 8;
    6747             *s++ = c;
    6748             continue;
     8683            *s++ = c;
     8684            continue;
     8685          case 3:
     8686            if (c == '?')
     8687              state = 8;
     8688            *s++ = c;
     8689            continue;
    67498690          /* CDATA */
    6750           case 4:
    6751             if (c == ']')
     8691          case 4:
     8692            if (c == ']')
    67528693              state = 5;
    6753             else
    6754               state = 1;
    6755             *s++ = c;
    6756             continue;
    6757           case 5:
    6758             if (c == '>')
    6759               state = 0;
    6760             else
    6761               state = 1;
    6762             *s++ = c;
    6763             continue;
     8694            else
     8695              state = 1;
     8696            *s++ = c;
     8697            continue;
     8698          case 5:
     8699            if (c == '>')
     8700              state = 0;
     8701            else
     8702              state = 1;
     8703            *s++ = c;
     8704            continue;
    67648705          /* comment */
    67658706          case 6:
    67668707            if (c == '-')
    6767               state = 7;
    6768             else
    6769               state = 2;
    6770             *s++ = c;
    6771             continue;
     8708              state = 7;
     8709            else
     8710              state = 2;
     8711            *s++ = c;
     8712            continue;
    67728713          case 7:
    67738714            if (c == '>')
    6774               state = 0;
    6775             else
    6776               state = 2;
    6777             *s++ = c;
    6778             continue;
     8715              state = 0;
     8716            else
     8717              state = 2;
     8718            *s++ = c;
     8719            continue;
    67798720          /* PI */
    6780           case 8:
     8721          case 8:
    67818722            if (c == '>')
    6782               state = 0;
    6783             else
    6784               state = 3;
    6785             *s++ = c;
    6786             continue;
     8723              state = 0;
     8724            else
     8725              state = 3;
     8726            *s++ = c;
     8727            continue;
    67878728        }
    67888729        switch (c)
     
    67988739          break;
    67998740        case '<':
    6800           c = soap_getchar(soap);
    6801           if (c == '/')
    6802           { if (n == 0)
    6803             { c = SOAP_TT;
    6804               goto end;
    6805             }
    6806             n--;
    6807           }
    6808           else if (c == '!')
    6809           { c = soap_getchar(soap);
    6810             if (c == '[')
     8741          c = soap_getchar(soap);
     8742          if (c == '/')
     8743          { if (n == 0)
     8744            { c = SOAP_TT;
     8745              goto end;
     8746            }
     8747            n--;
     8748          }
     8749          else if (c == '!')
     8750          { c = soap_getchar(soap);
     8751            if (c == '[')
    68118752            { do c = soap_getchar(soap);
    68128753              while ((int)c != EOF && c != '[');
    68138754              if ((int)c == EOF)
    68148755                 goto end;
    6815               t = (char*)"![CDATA[";
    6816               m = 8;
    6817               state = 1;
    6818             }
     8756              t = (char*)"![CDATA[";
     8757              m = 8;
     8758              state = 1;
     8759            }
    68198760            else if (c == '-')
    6820             { if ((c = soap_getchar(soap)) == '-')
    6821                 state = 2;
    6822               t = (char*)"!-";
    6823               m = 2;
    6824               soap_unget(soap, c);
    6825             }
    6826             else
    6827             { t = (char*)"!";
    6828               m = 1;
    6829               soap_unget(soap, c);
    6830             }
    6831             *s++ = '<';
    6832             break;
    6833           }
    6834           else if (c == '?')
    6835             state = 3;
    6836           else
    6837             n++;
     8761            { if ((c = soap_getchar(soap)) == '-')
     8762                state = 2;
     8763              t = (char*)"!-";
     8764              m = 2;
     8765              soap_unget(soap, c);
     8766            }
     8767            else
     8768            { t = (char*)"!";
     8769              m = 1;
     8770              soap_unget(soap, c);
     8771            }
     8772            *s++ = '<';
     8773            break;
     8774          }
     8775          else if (c == '?')
     8776            state = 3;
     8777          else
     8778            n++;
    68388779          soap_unget(soap, c);
    68398780          *s++ = '<';
     
    68468787          break;
    68478788        default:
     8789#ifndef WITH_LEANER
    68488790#ifdef HAVE_WCTOMB
    68498791          if (soap->mode & SOAP_C_MBSTRING)
    68508792          { m = wctomb(buf, c & 0x7FFFFFFF);
    6851             if (m >= 1)
     8793            if (m >= 1 && m <= (int)MB_CUR_MAX)
    68528794            { t = buf;
    68538795              *s++ = *t++;
     
    68558797            }
    68568798            else
    6857               *s++ = SOAP_UNKNOWN_CHAR;
     8799            { *s++ = SOAP_UNKNOWN_CHAR;
     8800              m = 0;
     8801            }
    68588802          }
    68598803          else
    68608804#endif
     8805#endif
    68618806            *s++ = (char)(c & 0xFF);
    68628807        }
    6863         l++;
     8808        l++;
    68648809        if ((soap->mode & SOAP_XML_STRICT) && maxlen >= 0 && l > maxlen)
    68658810        { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen));
     
    68748819  soap->labidx = 0;                     /* use look-aside buffer */
    68758820#else
    6876   if (soap_new_block(soap))
     8821  if (soap_new_block(soap) == NULL)
    68778822    return NULL;
    68788823#endif
     
    68888833#else
    68898834    register size_t k = SOAP_BLKLEN;
    6890     if (!(s = (char*)soap_push_block(soap, k)))
     8835    if (!(s = (char*)soap_push_block(soap, NULL, k)))
    68918836      return NULL;
    68928837#endif
     
    69238868          }
    69248869          *t++ = (char)(0x80 | (c & 0x3F));
    6925           m = (int)(t - buf) - 1;
     8870          m = (int)(t - buf) - 1;
    69268871          t = buf;
    69278872          *s++ = *t++;
     
    69398884        *s++ = '<';
    69408885        t = (char*)"/";
    6941         m = 1;
     8886        m = 1;
    69428887        break;
    69438888      case SOAP_LT:
     8889        if (f && n == 0)
     8890          goto end;
    69448891        n++;
    69458892        *s++ = '<';
     
    69638910        *s++ = '/';
    69648911        break;
    6965       case '<' | 0x80000000:
     8912      case (soap_wchar)('<' | 0x80000000):
    69668913        if (flag)
    69678914          *s++ = '<';
     
    69698916        { *s++ = '&';
    69708917          t = (char*)"lt;";
    6971           m = 3;
     8918          m = 3;
    69728919        }
    69738920        break;
    6974       case '>' | 0x80000000:
     8921      case (soap_wchar)('>' | 0x80000000):
    69758922        if (flag)
    69768923          *s++ = '>';
     
    69788925        { *s++ = '&';
    69798926          t = (char*)"gt;";
    6980           m = 3;
     8927          m = 3;
    69818928        }
    69828929        break;
    6983       case '"' | 0x80000000:
     8930      case (soap_wchar)('&' | 0x80000000):
     8931        if (flag)
     8932          *s++ = '&';
     8933        else
     8934        { *s++ = '&';
     8935          t = (char*)"amp;";
     8936          m = 4;
     8937        }
     8938        break;
     8939      case (soap_wchar)('"' | 0x80000000):
    69848940        if (flag)
    69858941          *s++ = '"';
     
    69878943        { *s++ = '&';
    69888944          t = (char*)"quot;";
    6989           m = 5;
     8945          m = 5;
    69908946        }
    69918947        break;
    6992       case '\'' | 0x80000000:
     8948      case (soap_wchar)('\'' | 0x80000000):
    69938949        if (flag)
    69948950          *s++ = '\'';
     
    69968952        { *s++ = '&';
    69978953          t = (char*)"apos;";
    6998           m = 5;
     8954          m = 5;
    69998955        }
    70008956        break;
     
    70028958        if ((int)c == EOF)
    70038959          goto end;
     8960#ifndef WITH_LEANER
    70048961#ifdef HAVE_WCTOMB
    70058962        if (soap->mode & SOAP_C_MBSTRING)
    70068963        { m = wctomb(buf, c & 0x7FFFFFFF);
    7007           if (m >= 1)
     8964          if (m >= 1 && m <= (int)MB_CUR_MAX)
    70088965          { t = buf;
    70098966            *s++ = *t++;
     
    70118968          }
    70128969          else
    7013             *s++ = SOAP_UNKNOWN_CHAR;
     8970          { *s++ = SOAP_UNKNOWN_CHAR;
     8971            m = 0;
     8972          }
    70148973        }
    70158974        else
     8975#endif
    70168976#endif
    70178977          *s++ = (char)(c & 0xFF);
     
    70318991  t = soap_strdup(soap, soap->labbuf);
    70328992#else
    7033   soap_size_block(soap, i+1);
     8993  soap_size_block(soap, NULL, i+1);
    70348994  t = soap_save_block(soap, NULL, 0);
    70358995#endif
     
    70398999    return NULL;
    70409000  }
     9001#ifdef WITH_DOM
     9002  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
     9003  { if (flag == 3)
     9004      soap->dom->tail = t;
     9005    else
     9006      soap->dom->data = t;
     9007  }
     9008#endif
    70419009  if (flag == 2)
    70429010    if (soap_s2QName(soap, t, &t))
     
    70479015
    70489016/******************************************************************************/
     9017#ifndef WITH_LEANER
    70499018#ifndef PALM_2
    70509019SOAP_FMAC1
     
    70579026#ifdef WITH_DOM
    70589027  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
    7059   { soap->dom->wide = NULL; /* soap_malloc() ??? */
     9028  { wchar_t *r = (wchar_t*)s;
     9029    int n = 1;
     9030    while (*r++)
     9031      n++;
     9032    soap->dom->wide = r = (wchar_t*)soap_malloc(soap, n * sizeof(wchar_t));
     9033    while (n--)
     9034      *r++ = *s++;
    70609035    return SOAP_OK;
    70619036  }
     
    70649039  { switch (c)
    70659040    {
    7066     case 9:
     9041    case 0x09:
    70679042      if (flag)
    70689043        t = "&#x9;";
     
    70709045        t = "\t";
    70719046      break;
    7072     case 10:
     9047    case 0x0A:
    70739048      if (flag || !(soap->mode & SOAP_XML_CANONICAL))
    70749049        t = "&#xA;";
     
    70769051        t = "\n";
    70779052      break;
    7078     case 13:
     9053    case 0x0D:
    70799054      t = "&#xD;";
    70809055      break;
     
    70899064        t = ">";
    70909065      else
    7091         t = "&gt;";
     9066        t = "&gt;";
    70929067      break;
    70939068    case '"':
     
    70989073      break;
    70999074    default:
    7100       if (c > 0 && c < 0x80)
     9075      if (c >= 0x20 && c < 0x80)
    71019076      { tmp = (char)c;
    71029077        if (soap_send_raw(soap, &tmp, 1))
     
    71139088}
    71149089#endif
    7115 
    7116 /******************************************************************************/
     9090#endif
     9091
     9092/******************************************************************************/
     9093#ifndef WITH_LEANER
    71179094#ifndef PALM_2
    71189095SOAP_FMAC1
     
    71219098soap_wstring_in(struct soap *soap, int flag, long minlen, long maxlen)
    71229099{ wchar_t *s;
    7123   register int i, n = 0;
     9100  register int i, n = 0, f = 0;
    71249101  register long l = 0;
    71259102  register soap_wchar c;
    7126   const char *t = NULL;
    7127   if (soap_new_block(soap))
     9103  char *t = NULL;
     9104  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Reading wide string content\n"));
     9105  if (soap->peeked)
     9106  { if (*soap->tag)
     9107    {
     9108#ifndef WITH_LEAN
     9109      struct soap_attribute *tp;
     9110      t = soap->tmpbuf;
     9111      *t = '<';
     9112      t[sizeof(soap->tmpbuf)-1] = '\0';
     9113      strncpy(t + 1, soap->tag, sizeof(soap->tmpbuf) - 2);
     9114      t += strlen(t);
     9115      for (tp = soap->attributes; tp; tp = tp->next)
     9116      { if (tp->visible)
     9117        { if (t >= soap->tmpbuf + sizeof(soap->tmpbuf) - 2)
     9118            break;
     9119          *t++ = ' ';
     9120          strcpy(t, tp->name);
     9121          t += strlen(t);
     9122          if (t >= soap->tmpbuf + sizeof(soap->tmpbuf) - 2)
     9123            break;
     9124          if (tp->value)
     9125          { *t++ = '=';
     9126            *t++ = '"';
     9127            strcpy(t, tp->value);
     9128            t += strlen(t);
     9129            *t++ = '"';
     9130          }
     9131        }
     9132      }
     9133      if (!soap->body)
     9134        *t++ = '/';
     9135      *t++ = '>';
     9136      *t = '\0';
     9137      t = soap->tmpbuf;
     9138#endif
     9139      if (soap->body)
     9140        n = 1;
     9141      f = 1;
     9142      soap->peeked = 0;
     9143    }
     9144  }
     9145  if (soap_new_block(soap) == NULL)
    71289146    return NULL;
    71299147  for (;;)
    7130   { if (!(s = (wchar_t*)soap_push_block(soap, sizeof(wchar_t)*SOAP_BLKLEN)))
     9148  { if (!(s = (wchar_t*)soap_push_block(soap, NULL, sizeof(wchar_t)*SOAP_BLKLEN)))
    71319149      return NULL;
    71329150    for (i = 0; i < SOAP_BLKLEN; i++)
     
    71489166        break;
    71499167      case SOAP_LT:
     9168        if (f && n == 0)
     9169          goto end;
    71509170        n++;
    71519171        *s++ = '<';
     
    71749194        else
    71759195        { *s++ = (soap_wchar)'&';
    7176           t = "lt;";
     9196          t = (char*)"lt;";
    71779197        }
    71789198        break;
     
    71829202        else
    71839203        { *s++ = (soap_wchar)'&';
    7184           t = "gt;";
     9204          t = (char*)"gt;";
    71859205        }
    71869206        break;
     
    71909210        else
    71919211        { *s++ = (soap_wchar)'&';
    7192           t = "quot;";
     9212          t = (char*)"quot;";
    71939213        }
    71949214        break;
     
    72099229  soap_unget(soap, c);
    72109230  *s = '\0';
    7211   soap_size_block(soap, sizeof(wchar_t) * (i + 1));
     9231  soap_size_block(soap, NULL, sizeof(wchar_t) * (i + 1));
    72129232  if ((soap->mode & SOAP_XML_STRICT) && l < minlen)
    72139233  { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too short: %ld chars, minlen=%ld\n", l, minlen));
     
    72159235    return NULL;
    72169236  }
    7217   return (wchar_t*)soap_save_block(soap, NULL, 0);
    7218 }
     9237  s = (wchar_t*)soap_save_block(soap, NULL, NULL, 0);
     9238#ifdef WITH_DOM
     9239  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
     9240    soap->dom->wide = s;
     9241#endif
     9242  return s;
     9243}
     9244#endif
    72199245#endif
    72209246
     
    72509276{ if (s)
    72519277  { char *r;
     9278#ifndef WITH_NOIO
     9279#ifndef WITH_LEAN
     9280    soap_reset_errno;
     9281#endif
     9282#endif
    72529283    *p = (int)soap_strtol(s, &r, 10);
    7253     if (*r)
     9284    if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
     9285#ifndef WITH_NOIO
     9286#ifndef WITH_LEAN
     9287     || soap_errno == SOAP_ERANGE
     9288#endif
     9289#endif
     9290    )
    72549291      soap->error = SOAP_TYPE;
    72559292  }
     
    72649301SOAP_FMAC2
    72659302soap_inint(struct soap *soap, const char *tag, int *p, const char *type, int t)
    7266 { if (soap_element_begin_in(soap, tag, 0))
     9303{ if (soap_element_begin_in(soap, tag, 0, NULL))
    72679304    return NULL;
    72689305#ifndef WITH_LEAN
     
    72789315#endif
    72799316  p = (int*)soap_id_enter(soap, soap->id, p, t, sizeof(int), 0, NULL, NULL, NULL);
    7280   if (p)
     9317  if (*soap->href)
     9318    p = (int*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(int), 0, NULL);
     9319  else if (p)
    72819320  { if (soap_s2int(soap, soap_value(soap), p))
    72829321      return NULL;
    72839322  }
    7284   p = (int*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(int), 0, NULL);
    72859323  if (soap->body && soap_element_end_in(soap, tag))
    72869324    return NULL;
     
    73219359{ if (s)
    73229360  { char *r;
     9361#ifndef WITH_NOIO
     9362#ifndef WITH_LEAN
     9363    soap_reset_errno;
     9364#endif
     9365#endif
    73239366    *p = soap_strtol(s, &r, 10);
    7324     if (*r)
     9367    if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
     9368#ifndef WITH_NOIO
     9369#ifndef WITH_LEAN
     9370     || soap_errno == SOAP_ERANGE
     9371#endif
     9372#endif
     9373    )
    73259374      soap->error = SOAP_TYPE;
    73269375  }
     
    73359384SOAP_FMAC2
    73369385soap_inlong(struct soap *soap, const char *tag, long *p, const char *type, int t)
    7337 { if (soap_element_begin_in(soap, tag, 0))
     9386{ if (soap_element_begin_in(soap, tag, 0, NULL))
    73389387    return NULL;
    73399388#ifndef WITH_LEAN
     
    73499398#endif
    73509399  p = (long*)soap_id_enter(soap, soap->id, p, t, sizeof(long), 0, NULL, NULL, NULL);
    7351   if (p)
     9400  if (*soap->href)
     9401    p = (long*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(long), 0, NULL);
     9402  else if (p)
    73529403  { if (soap_s2long(soap, soap_value(soap), p))
    73539404      return NULL;
    73549405  }
    7355   p = (long*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(long), 0, NULL);
    73569406  if (soap->body && soap_element_end_in(soap, tag))
    73579407    return NULL;
     
    73909440SOAP_FMAC2
    73919441soap_s2LONG64(struct soap *soap, const char *s, LONG64 *p)
    7392 { if (s && sscanf(s, SOAP_LONG_FORMAT, p) != 1)
    7393     soap->error = SOAP_TYPE;
     9442{ if (s)
     9443  {
     9444#ifdef HAVE_STRTOLL
     9445    char *r;
     9446#ifndef WITH_NOIO
     9447#ifndef WITH_LEAN
     9448    soap_reset_errno;
     9449#endif
     9450#endif
     9451    *p = strtoll(s, &r, 10);
     9452    if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
     9453#ifndef WITH_NOIO
     9454#ifndef WITH_LEAN
     9455       || soap_errno == SOAP_ERANGE
     9456#endif
     9457#endif
     9458      )
     9459#else
     9460# ifdef HAVE_SSCANF
     9461    if (sscanf(s, SOAP_LONG_FORMAT, p) != 1)
     9462# endif
     9463#endif
     9464      soap->error = SOAP_TYPE;
     9465  }
    73949466  return soap->error;
    73959467}
     
    74029474SOAP_FMAC2
    74039475soap_inLONG64(struct soap *soap, const char *tag, LONG64 *p, const char *type, int t)
    7404 { if (soap_element_begin_in(soap, tag, 0))
     9476{ if (soap_element_begin_in(soap, tag, 0, NULL))
    74059477    return NULL;
    74069478#ifndef WITH_LEAN
     
    74229494#endif
    74239495  p = (LONG64*)soap_id_enter(soap, soap->id, p, t, sizeof(LONG64), 0, NULL, NULL, NULL);
    7424   if (p)
     9496  if (*soap->href)
     9497    p = (LONG64*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(LONG64), 0, NULL);
     9498  else if (p)
    74259499  { if (soap_s2LONG64(soap, soap_value(soap), p))
    74269500      return NULL;
    74279501  }
    7428   p = (LONG64*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(LONG64), 0, NULL);
    74299502  if (soap->body && soap_element_end_in(soap, tag))
    74309503    return NULL;
     
    74669539    char *r;
    74679540    n = soap_strtol(s, &r, 10);
    7468     if (*r || n < -128 || n > 127)
     9541    if (s == r || *r || n < -128 || n > 127)
    74699542      soap->error = SOAP_TYPE;
    74709543    *p = (char)n;
     
    74809553SOAP_FMAC2
    74819554soap_inbyte(struct soap *soap, const char *tag, char *p, const char *type, int t)
    7482 { if (soap_element_begin_in(soap, tag, 0))
     9555{ if (soap_element_begin_in(soap, tag, 0, NULL))
    74839556    return NULL;
    74849557#ifndef WITH_LEAN
     
    74929565#endif
    74939566  p = (char*)soap_id_enter(soap, soap->id, p, t, sizeof(char), 0, NULL, NULL, NULL);
    7494   if (p)
     9567  if (*soap->href)
     9568    p = (char*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(char), 0, NULL);
     9569  else if (p)
    74959570  { if (soap_s2byte(soap, soap_value(soap), p))
    74969571      return NULL;
    74979572  }
    7498   p = (char*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(char), 0, NULL);
    74999573  if (soap->body && soap_element_end_in(soap, tag))
    75009574    return NULL;
     
    75369610    char *r;
    75379611    n = soap_strtol(s, &r, 10);
    7538     if (*r || n < -32768 || n > 32767)
     9612    if (s == r || *r || n < -32768 || n > 32767)
    75399613      soap->error = SOAP_TYPE;
    75409614    *p = (short)n;
     
    75509624SOAP_FMAC2
    75519625soap_inshort(struct soap *soap, const char *tag, short *p, const char *type, int t)
    7552 { if (soap_element_begin_in(soap, tag, 0))
     9626{ if (soap_element_begin_in(soap, tag, 0, NULL))
    75539627    return NULL;
    75549628#ifndef WITH_LEAN
     
    75639637#endif
    75649638  p = (short*)soap_id_enter(soap, soap->id, p, t, sizeof(short), 0, NULL, NULL, NULL);
    7565   if (p)
     9639  if (*soap->href)
     9640    p = (short*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(short), 0, NULL);
     9641  else if (p)
    75669642  { if (soap_s2short(soap, soap_value(soap), p))
    75679643      return NULL;
    75689644  }
    7569   p = (short*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(short), 0, NULL);
    75709645  if (soap->body && soap_element_end_in(soap, tag))
    75719646    return NULL;
     
    75809655SOAP_FMAC2
    75819656soap_float2s(struct soap *soap, float n)
    7582 { const char *s;
     9657{ char *s;
    75839658  if (soap_isnan((double)n))
    7584     s = "NaN";
    7585   else if (soap_ispinff(n))
    7586     s = "INF";
    7587   else if (soap_isninff(n))
    7588     s = "-INF";
    7589   else
    7590   { sprintf(soap->tmpbuf, soap->float_format, n);
    7591     s = soap->tmpbuf;
    7592   }
    7593   return s;
     9659    return "NaN";
     9660  if (soap_ispinff(n))
     9661    return "INF";
     9662  if (soap_isninff(n))
     9663    return "-INF";
     9664  s = soap->tmpbuf;
     9665#if defined(HAVE_SPRINTF_L)
     9666  sprintf_l(s, soap->c_locale, soap->float_format, n);
     9667#else
     9668  sprintf(s, soap->float_format, n);
     9669  s = strchr(s, ',');   /* convert decimal comma to DP */
     9670  if (s)
     9671    *s = '.';
     9672#endif
     9673  return soap->tmpbuf;
    75949674}
    75959675#endif
     
    76159695soap_s2float(struct soap *soap, const char *s, float *p)
    76169696{ if (s)
    7617   { if (!soap_tag_cmp(s, "INF"))
     9697  { if (!*s)
     9698      return soap->error = SOAP_TYPE;
     9699    if (!soap_tag_cmp(s, "INF"))
    76189700      *p = FLT_PINFTY;
    76199701    else if (!soap_tag_cmp(s, "+INF"))
     
    76259707    else
    76269708    {
    7627 #ifdef HAVE_STRTOD
     9709/* On some systems, strtof appears to be broken or doesn't link: use with caution */
     9710#if defined(HAVE_STRTOF_L)
     9711      char *r;
     9712      *p = strtof_l((char*)s, &r, soap->c_locale);
     9713      if (*r)
     9714#elif defined(HAVE_STRTOD_L)
     9715      char *r;
     9716      *p = (float)strtod_l(s, &r, soap->c_locale);
     9717      if (*r)
     9718#elif defined(HAVE_STRTOF)
     9719      char *r;
     9720      *p = strtof((char*)s, &r);
     9721      if (*r)
     9722#elif defined(HAVE_STRTOD)
    76289723      char *r;
    76299724      *p = (float)strtod(s, &r);
    76309725      if (*r)
    76319726#endif
    7632 #ifdef HAVE_SSCANF
    7633         if (sscanf(s, soap->float_format, p) != 1)
     9727      {
     9728#if defined(HAVE_SSCANF_L) && !defined(HAVE_STRTOF_L) && !defined(HAVE_STRTOD_L)
     9729        if (sscanf_l(s, soap->c_locale, "%g", p) != 1)
     9730          soap->error = SOAP_TYPE;
     9731#elif defined(HAVE_SSCANF)
     9732        if (sscanf(s, "%g", p) != 1)
    76349733          soap->error = SOAP_TYPE;
    76359734#else
    76369735        soap->error = SOAP_TYPE;
    76379736#endif
     9737      }
    76389738    }
    76399739  }
     
    76769776SOAP_FMAC2
    76779777soap_infloat(struct soap *soap, const char *tag, float *p, const char *type, int t)
    7678 { if (soap_element_begin_in(soap, tag, 0))
     9778{ if (soap_element_begin_in(soap, tag, 0, NULL))
    76799779    return NULL;
    76809780#ifndef WITH_LEAN
     
    76839783#endif
    76849784  p = (float*)soap_id_enter(soap, soap->id, p, t, sizeof(float), 0, NULL, NULL, NULL);
    7685   if (p)
     9785  if (*soap->href)
     9786    p = (float*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(float), 0, NULL);
     9787  else if (p)
    76869788  { if (soap_s2float(soap, soap_value(soap), p))
    76879789      return NULL;
    76889790  }
    7689   p = (float*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(float), 0, NULL);
    76909791  if (soap->body && soap_element_end_in(soap, tag))
    76919792    return NULL;
     
    77009801SOAP_FMAC2
    77019802soap_double2s(struct soap *soap, double n)
    7702 { const char *s;
     9803{ char *s;
    77039804  if (soap_isnan(n))
    7704     s = "NaN";
    7705   else if (soap_ispinfd(n))
    7706     s = "INF";
    7707   else if (soap_isninfd(n))
    7708     s = "-INF";
    7709   else
    7710   { sprintf(soap->tmpbuf, soap->double_format, n);
    7711     s = soap->tmpbuf;
    7712   }
    7713   return s;
     9805    return "NaN";
     9806  if (soap_ispinfd(n))
     9807    return "INF";
     9808  if (soap_isninfd(n))
     9809    return "-INF";
     9810  s = soap->tmpbuf;
     9811#if defined(HAVE_SPRINTF_L)
     9812  sprintf_l(s, soap->c_locale, soap->double_format, n);
     9813#else
     9814  sprintf(s, soap->double_format, n);
     9815  s = strchr(s, ',');   /* convert decimal comma to DP */
     9816  if (s)
     9817    *s = '.';
     9818#endif
     9819  return soap->tmpbuf;
    77149820}
    77159821#endif
     
    77359841soap_s2double(struct soap *soap, const char *s, double *p)
    77369842{ if (s)
    7737   { if (!soap_tag_cmp(s, "INF"))
     9843  { if (!*s)
     9844      return soap->error = SOAP_TYPE;
     9845    if (!soap_tag_cmp(s, "INF"))
    77389846      *p = DBL_PINFTY;
    77399847    else if (!soap_tag_cmp(s, "+INF"))
     
    77459853    else
    77469854    {
    7747 #ifdef HAVE_STRTOD
     9855#if defined(HAVE_STRTOD_L)
     9856      char *r;
     9857      *p = strtod_l(s, &r, soap->c_locale);
     9858      if (*r)
     9859#elif defined(HAVE_STRTOD)
    77489860      char *r;
    77499861      *p = strtod(s, &r);
    77509862      if (*r)
    77519863#endif
    7752 #ifdef HAVE_SSCANF
    7753         if (sscanf(s, soap->double_format, p) != 1)
     9864      {
     9865#if defined(HAVE_SSCANF_L) && !defined(HAVE_STRTOF_L) && !defined(HAVE_STRTOD_L)
     9866        if (sscanf_l(s, soap->c_locale, "%lg", p) != 1)
     9867          soap->error = SOAP_TYPE;
     9868#elif defined(HAVE_SSCANF)
     9869        if (sscanf(s, "%lg", p) != 1)
    77549870          soap->error = SOAP_TYPE;
    77559871#else
    77569872        soap->error = SOAP_TYPE;
    77579873#endif
     9874      }
    77589875    }
    77599876  }
     
    77689885SOAP_FMAC2
    77699886soap_indouble(struct soap *soap, const char *tag, double *p, const char *type, int t)
    7770 { if (soap_element_begin_in(soap, tag, 0))
     9887{ if (soap_element_begin_in(soap, tag, 0, NULL))
    77719888    return NULL;
    77729889#ifndef WITH_LEAN
     
    77759892#endif
    77769893  p = (double*)soap_id_enter(soap, soap->id, p, t, sizeof(double), 0, NULL, NULL, NULL);
    7777   if (p)
     9894  if (*soap->href)
     9895    p = (double*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(double), 0, NULL);
     9896  else if (p)
    77789897  { if (soap_s2double(soap, soap_value(soap), p))
    77799898      return NULL;
    77809899  }
    7781   p = (double*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(double), 0, NULL);
    77829900  if (soap->body && soap_element_end_in(soap, tag))
    77839901    return NULL;
     
    78199937    char *r;
    78209938    n = soap_strtoul(s, &r, 10);
    7821     if (*r || n > 255)
     9939    if (s == r || *r || n > 255)
    78229940      soap->error = SOAP_TYPE;
    78239941    *p = (unsigned char)n;
     
    78339951SOAP_FMAC2
    78349952soap_inunsignedByte(struct soap *soap, const char *tag, unsigned char *p, const char *type, int t)
    7835 { if (soap_element_begin_in(soap, tag, 0))
     9953{ if (soap_element_begin_in(soap, tag, 0, NULL))
    78369954    return NULL;
    78379955#ifndef WITH_LEAN
     
    78459963#endif
    78469964  p = (unsigned char*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned char), 0, NULL, NULL, NULL);
    7847   if (p)
     9965  if (*soap->href)
     9966    p = (unsigned char*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(unsigned char), 0, NULL);
     9967  else if (p)
    78489968  { if (soap_s2unsignedByte(soap, soap_value(soap), p))
    78499969      return NULL;
    78509970  }
    7851   p = (unsigned char*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(unsigned char), 0, NULL);
    78529971  if (soap->body && soap_element_end_in(soap, tag))
    78539972    return NULL;
     
    78579976
    78589977/******************************************************************************/
    7859 #ifndef WITH_LEAN
     9978#ifndef PALM_2
    78609979SOAP_FMAC1
    78619980const char*
     
    78679986
    78689987/******************************************************************************/
    7869 #ifndef WITH_LEAN
     9988#ifndef PALM_2
    78709989SOAP_FMAC1
    78719990int
     
    78809999
    788110000/******************************************************************************/
    7882 #ifndef WITH_LEAN
     10001#ifndef PALM_2
    788310002SOAP_FMAC1
    788410003int
     
    788910008    char *r;
    789010009    n = soap_strtoul(s, &r, 10);
    7891     if (*r || n > 65535)
     10010    if (s == r || *r || n > 65535)
    789210011      soap->error = SOAP_TYPE;
    789310012    *p = (unsigned short)n;
     
    789810017
    789910018/******************************************************************************/
    7900 #ifndef WITH_LEAN
     10019#ifndef PALM_2
    790110020SOAP_FMAC1
    790210021unsigned short *
    790310022SOAP_FMAC2
    790410023soap_inunsignedShort(struct soap *soap, const char *tag, unsigned short *p, const char *type, int t)
    7905 { if (soap_element_begin_in(soap, tag, 0))
     10024{ if (soap_element_begin_in(soap, tag, 0, NULL))
    790610025    return NULL;
    790710026#ifndef WITH_LEAN
     
    791610035#endif
    791710036  p = (unsigned short*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned short), 0, NULL, NULL, NULL);
    7918   if (p)
     10037  if (*soap->href)
     10038    p = (unsigned short*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(unsigned short), 0, NULL);
     10039  else if (p)
    791910040  { if (soap_s2unsignedShort(soap, soap_value(soap), p))
    792010041      return NULL;
    792110042  }
    7922   p = (unsigned short*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(unsigned short), 0, NULL);
    792310043  if (soap->body && soap_element_end_in(soap, tag))
    792410044    return NULL;
     
    795810078{ if (s)
    795910079  { char *r;
     10080#ifndef WITH_NOIO
     10081#ifndef WITH_LEAN
     10082    soap_reset_errno;
     10083#endif
     10084#endif
    796010085    *p = (unsigned int)soap_strtoul(s, &r, 10);
    7961     if (*r)
     10086    if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
     10087#ifndef WITH_NOIO
     10088#ifndef WITH_LEAN
     10089     || soap_errno == SOAP_ERANGE
     10090#endif
     10091#endif
     10092    )
    796210093      soap->error = SOAP_TYPE;
    796310094  }
     
    797210103SOAP_FMAC2
    797310104soap_inunsignedInt(struct soap *soap, const char *tag, unsigned int *p, const char *type, int t)
    7974 { if (soap_element_begin_in(soap, tag, 0))
     10105{ if (soap_element_begin_in(soap, tag, 0, NULL))
    797510106    return NULL;
    797610107#ifndef WITH_LEAN
     
    798610117#endif
    798710118  p = (unsigned int*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned int), 0, NULL, NULL, NULL);
    7988   if (p)
     10119  if (*soap->href)
     10120    p = (unsigned int*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(unsigned int), 0, NULL);
     10121  else if (p)
    798910122  { if (soap_s2unsignedInt(soap, soap_value(soap), p))
    799010123      return NULL;
    799110124  }
    7992   p = (unsigned int*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(unsigned int), 0, NULL);
    799310125  if (soap->body && soap_element_end_in(soap, tag))
    799410126    return NULL;
     
    802910161{ if (s)
    803010162  { char *r;
     10163#ifndef WITH_NOIO
     10164#ifndef WITH_LEAN
     10165    soap_reset_errno;
     10166#endif
     10167#endif
    803110168    *p = soap_strtoul(s, &r, 10);
    8032     if (*r)
     10169    if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
     10170#ifndef WITH_NOIO
     10171#ifndef WITH_LEAN
     10172     || soap_errno == SOAP_ERANGE
     10173#endif
     10174#endif
     10175    )
    803310176      soap->error = SOAP_TYPE;
    803410177  }
     
    804310186SOAP_FMAC2
    804410187soap_inunsignedLong(struct soap *soap, const char *tag, unsigned long *p, const char *type, int t)
    8045 { if (soap_element_begin_in(soap, tag, 0))
     10188{ if (soap_element_begin_in(soap, tag, 0, NULL))
    804610189    return NULL;
    804710190#ifndef WITH_LEAN
     
    805710200#endif
    805810201  p = (unsigned long*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned long), 0, NULL, NULL, NULL);
    8059   if (p)
     10202  if (*soap->href)
     10203    p = (unsigned long*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(unsigned long), 0, NULL);
     10204  else if (p)
    806010205  { if (soap_s2unsignedLong(soap, soap_value(soap), p))
    806110206      return NULL;
    806210207  }
    8063   p = (unsigned long*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(unsigned long), 0, NULL);
    806410208  if (soap->body && soap_element_end_in(soap, tag))
    806510209    return NULL;
     
    809810242SOAP_FMAC2
    809910243soap_s2ULONG64(struct soap *soap, const char *s, ULONG64 *p)
    8100 { if (s && sscanf(s, SOAP_ULONG_FORMAT, p) != 1)
    8101     soap->error = SOAP_TYPE;
     10244{ if (s)
     10245  {
     10246#ifdef HAVE_STRTOULL
     10247    char *r;
     10248#ifndef WITH_NOIO
     10249#ifndef WITH_LEAN
     10250    soap_reset_errno;
     10251#endif
     10252#endif
     10253    *p = strtoull(s, &r, 10);
     10254    if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
     10255#ifndef WITH_NOIO
     10256#ifndef WITH_LEAN
     10257       || soap_errno == SOAP_ERANGE
     10258#endif
     10259#endif
     10260      )
     10261#else
     10262#ifdef HAVE_SSCANF
     10263    if (sscanf(s, SOAP_ULONG_FORMAT, p) != 1)
     10264#endif
     10265#endif
     10266      soap->error = SOAP_TYPE;
     10267  }
    810210268  return soap->error;
    810310269}
     
    811010276SOAP_FMAC2
    811110277soap_inULONG64(struct soap *soap, const char *tag, ULONG64 *p, const char *type, int t)
    8112 { if (soap_element_begin_in(soap, tag, 0))
     10278{ if (soap_element_begin_in(soap, tag, 0, NULL))
    811310279    return NULL;
    811410280  if (*soap->type
     
    812510291  }
    812610292  p = (ULONG64*)soap_id_enter(soap, soap->id, p, t, sizeof(ULONG64), 0, NULL, NULL, NULL);
    8127   if (p)
     10293  if (*soap->href)
     10294    p = (ULONG64*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(ULONG64), 0, NULL);
     10295  else if (p)
    812810296  { if (soap_s2ULONG64(soap, soap_value(soap), p))
    812910297      return NULL;
    813010298  }
    8131   p = (ULONG64*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(ULONG64), 0, NULL);
    813210299  if (soap->body && soap_element_end_in(soap, tag))
    813310300    return NULL;
     
    814210309SOAP_FMAC2
    814310310soap_s2string(struct soap *soap, const char *s, char **t)
    8144 { *t = NULL;
    8145   if (s && !(*t = soap_strdup(soap, s)))
    8146     soap->error = SOAP_EOM;
     10311{ if (s)
     10312  { if (!(*t = soap_strdup(soap, s)))
     10313      return soap->error = SOAP_EOM;
     10314    if (!(soap->mode & (SOAP_ENC_LATIN | SOAP_C_UTFSTRING)))
     10315    { /* TODO: consider truncating UTF8 to ASCII for regular XML attribute strings? */
     10316    }
     10317  }
    814710318  return soap->error;
    814810319}
     
    815610327soap_s2QName(struct soap *soap, const char *s, char **t)
    815710328{ if (s)
    8158   { struct soap_nlist *np;
    8159     const char *p;
    8160     if (!strncmp(s, "xml:", 4))
    8161     { *t = soap_strdup(soap, s);
    8162       return SOAP_OK;
    8163     }
    8164     np = soap->nlist;
    8165     p = strchr(s, ':');
    8166     if (p)
    8167     { register int n = p - s;
    8168       while (np && (strncmp(np->id, s, n) || np->id[n]))
    8169         np = np->next;
    8170       p++;
     10329  { soap->labidx = 0;
     10330    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Normalized namespace(s) of QNames '%s'", s));
     10331    /* convert (by prefix normalize prefix) all QNames in s */
     10332    for (;;)
     10333    { size_t n;
     10334      struct soap_nlist *np;
     10335      register const char *p;
     10336      /* skip blanks */
     10337      while (*s && soap_blank(*s))
     10338        s++;
     10339      if (!*s)
     10340        break;
     10341      /* find next QName */
     10342      n = 1;
     10343      while (s[n] && !soap_blank(s[n]))
     10344        n++;
     10345      np = soap->nlist;
     10346      /* if there is no namespace stack, or prefix is "xml" then copy string */
     10347      if (!np || !strncmp(s, "xml:", 4))
     10348      { soap_append_lab(soap, s, n);
     10349      }
     10350      else /* we normalize the QName by replacing its prefix */
     10351      { p = strchr(s, ':');
     10352        if (p)
     10353        { size_t k = p - s;
     10354          while (np && (strncmp(np->id, s, k) || np->id[k]))
     10355            np = np->next;
     10356          p++;
     10357        }
     10358        else
     10359        { while (np && *np->id)
     10360            np = np->next;
     10361          p = s;
     10362        }
     10363        /* replace prefix */
     10364        if (np)
     10365        { if (np->index >= 0 && soap->local_namespaces)
     10366          { const char *q = soap->local_namespaces[np->index].id;
     10367            if (q)
     10368              soap_append_lab(soap, q, strlen(q));
     10369          }
     10370          else if (np->ns)
     10371          { soap_append_lab(soap, "\"", 1);
     10372            soap_append_lab(soap, np->ns, strlen(np->ns));
     10373            soap_append_lab(soap, "\"", 1);
     10374          }
     10375          else
     10376          { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\nNamespace prefix of '%s' not defined (index=%d, URI=%s)\n", s, np->index, np->ns?np->ns:SOAP_STR_EOS));
     10377            return soap->error = SOAP_NAMESPACE;
     10378          }
     10379        }
     10380        else /* no namespace: assume default "" namespace */
     10381        { soap_append_lab(soap, "\"\"", 2);
     10382        }
     10383        soap_append_lab(soap, ":", 1);
     10384        soap_append_lab(soap, p, n - (p-s));
     10385      }
     10386      /* advance to next and add spacing */
     10387      s += n;
     10388      if (*s)
     10389        soap_append_lab(soap, " ", 1);
     10390    }
     10391    soap_append_lab(soap, SOAP_STR_EOS, 1);
     10392    *t = soap_strdup(soap, soap->labbuf);
     10393    DBGLOG(TEST, SOAP_MESSAGE(fdebug, " into '%s'\n", *t));
     10394  }
     10395  return soap->error;
     10396}
     10397#endif
     10398
     10399/******************************************************************************/
     10400#ifndef PALM_2
     10401SOAP_FMAC1
     10402const char*
     10403SOAP_FMAC2
     10404soap_QName2s(struct soap *soap, const char *s)
     10405{ const char *t = NULL;
     10406  if (s)
     10407  { soap->labidx = 0;
     10408    for (;;)
     10409    { size_t n;
     10410      /* skip blanks */
     10411      while (*s && soap_blank(*s))
     10412        s++;
     10413      if (!*s)
     10414        break;
     10415      /* find next QName */
     10416      n = 1;
     10417      while (s[n] && !soap_blank(s[n]))
     10418        n++;
     10419      /* normal prefix: pass string as is */
     10420      if (*s != '"')
     10421      { soap_append_lab(soap, s, n);
     10422#ifndef WITH_LEAN
     10423        if ((soap->mode & SOAP_XML_CANONICAL))
     10424        { const char *r = strchr(s, ':');
     10425          if (r)
     10426            soap_utilize_ns(soap, s, r - s);
     10427        }
     10428#endif
     10429      }
     10430      else /* URL-based string prefix */
     10431      { const char *q;
     10432        s++;
     10433        q = strchr(s, '"');
     10434        if (q)
     10435        { struct Namespace *p = soap->local_namespaces;
     10436          if (p)
     10437          { for (; p->id; p++)
     10438            { if (p->ns)
     10439                if (!soap_tag_cmp(s, p->ns))
     10440                  break;
     10441              if (p->in)
     10442                if (!soap_tag_cmp(s, p->in))
     10443                  break;
     10444            }
     10445          }
     10446          /* URL is in the namespace table? */
     10447          if (p && p->id)
     10448          { soap_append_lab(soap, p->id, strlen(p->id));
     10449          }
     10450          else /* not in namespace table: create xmlns binding */
     10451          { char *r = soap_strdup(soap, s);
     10452            r[q-s] = '\0';
     10453            sprintf(soap->tmpbuf, "xmlns:_%d", soap->idnum++);
     10454            soap_set_attr(soap, soap->tmpbuf, r);
     10455            soap_append_lab(soap, soap->tmpbuf + 6, strlen(soap->tmpbuf + 6));
     10456          }
     10457          soap_append_lab(soap, q + 1, n - (q-s) - 1);
     10458        }
     10459      }
     10460      /* advance to next and add spacing */
     10461      s += n;
     10462      if (*s)
     10463        soap_append_lab(soap, " ", 1);
     10464    }
     10465    soap_append_lab(soap, SOAP_STR_EOS, 1);
     10466    t = soap_strdup(soap, soap->labbuf);
     10467  }
     10468  return t;
     10469}
     10470#endif
     10471
     10472/******************************************************************************/
     10473#ifndef WITH_LEAN
     10474SOAP_FMAC1
     10475int
     10476SOAP_FMAC2
     10477soap_s2wchar(struct soap *soap, const char *s, wchar_t **t)
     10478{ if (s)
     10479  { wchar_t *r;
     10480    *t = r = (wchar_t*)soap_malloc(soap, sizeof(wchar_t) * (strlen(s) + 1));
     10481    if (!r)
     10482      return soap->error;
     10483    if (soap->mode & SOAP_ENC_LATIN)
     10484    { while (*s)
     10485        *r++ = (wchar_t)*s++;
    817110486    }
    817210487    else
    8173     { while (np && *np->id)
    8174         np = np->next;
    8175       p = s;
    8176     }
    8177     if (np)
    8178     { if (np->index >= 0 && soap->local_namespaces)
    8179       { register const char *q = soap->local_namespaces[np->index].id;
    8180         if (q)
    8181         { if ((*t = (char*)soap_malloc(soap, strlen(p) + strlen(q) + 2)))
    8182             sprintf(*t, "%s:%s", q, p);
    8183           return SOAP_OK;
     10488    { /* Convert UTF8 to wchar */
     10489      while (*s)
     10490      { register soap_wchar c, c1, c2, c3, c4;
     10491        c = (unsigned char)*s++;
     10492        if (c < 0x80)
     10493          *r++ = (wchar_t)c;
     10494        else
     10495        { c1 = (soap_wchar)*s++ & 0x3F;
     10496          if (c < 0xE0)
     10497            *r++ = (wchar_t)(((soap_wchar)(c & 0x1F) << 6) | c1);
     10498          else
     10499          { c2 = (soap_wchar)*s++ & 0x3F;
     10500            if (c < 0xF0)
     10501              *r++ = (wchar_t)(((soap_wchar)(c & 0x0F) << 12) | (c1 << 6) | c2);
     10502            else
     10503            { c3 = (soap_wchar)*s++ & 0x3F;
     10504              if (c < 0xF8)
     10505                *r++ = (wchar_t)(((soap_wchar)(c & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3);
     10506              else
     10507              { c4 = (soap_wchar)*s++ & 0x3F;
     10508                if (c < 0xFC)
     10509                  *r++ = (wchar_t)(((soap_wchar)(c & 0x03) << 24) | (c1 << 18) | (c2 << 12) | (c3 << 6) | c4);
     10510                else
     10511                  *r++ = (wchar_t)(((soap_wchar)(c & 0x01) << 30) | (c1 << 24) | (c2 << 18) | (c3 << 12) | (c4 << 6) | (soap_wchar)(*s++ & 0x3F));
     10512              }
     10513            }
     10514          }
    818410515        }
    818510516      }
    8186       if (np->ns)
    8187       { if ((*t = (char*)soap_malloc(soap, strlen(p) + strlen(np->ns) + 4)))
    8188           sprintf(*t, "\"%s\":%s", np->ns, p);
    8189         return SOAP_OK;
    8190       }
    8191       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Namespace prefix of '%s' not defined (index=%d, URI=%s)\n", s, np->index, np->ns?np->ns:""));
    8192       return soap->error = SOAP_NAMESPACE;
    8193     }
    8194     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Namespace prefix of '%s' not defined, assuming empty namespace\n", s));
    8195     if ((*t = (char*)soap_malloc(soap, strlen(p) + 4)))
    8196       sprintf(*t, "\"\":%s", p);
    8197   }
    8198   return soap->error;
    8199 }
    8200 #endif
    8201 
    8202 /******************************************************************************/
    8203 #ifndef PALM_2
     10517    }
     10518    *r = L'\0';
     10519  }
     10520  return SOAP_OK;
     10521}
     10522#endif
     10523
     10524/******************************************************************************/
     10525#ifndef WITH_LEAN
    820410526SOAP_FMAC1
    820510527const char*
    820610528SOAP_FMAC2
    8207 soap_QName2s(struct soap *soap, const char *s)
    8208 { struct Namespace *p;
    8209   char *t;
    8210   int n;
    8211   if (!s || *s != '"')
    8212     return s;
    8213   s++;
    8214   if ((p = soap->local_namespaces))
    8215   { for (; p->id; p++)
    8216     { if (p->ns)
    8217         if (!soap_tag_cmp(s, p->ns))
    8218           break;
    8219       if (p->in)
    8220         if (!soap_tag_cmp(s, p->in))
    8221           break;
    8222     }
    8223     if (p && p->id)
    8224     { s = strchr(s, '"');
    8225       if (s)
    8226       { t = (char*)soap_malloc(soap, strlen(p->id) + strlen(s));
    8227         strcpy(t, p->id);
    8228         strcat(t, s + 1);
    8229         return t;
    8230       }
    8231     }
    8232   }
    8233   t = (char*)strchr(s, '"');
    8234   if (t)
    8235     n = t - s;
    8236   else
    8237     n = 0;
    8238   t = soap_strdup(soap, s);
    8239   t[n] = '\0';
    8240   sprintf(soap->tmpbuf, "xmlns:_%lu", soap->idnum++);
    8241   soap_set_attr(soap, soap->tmpbuf, t);
    8242   s = strchr(s, '"');
    8243   if (s)
    8244   { t = (char*)soap_malloc(soap, strlen(soap->tmpbuf) + strlen(s) - 6);
    8245     strcpy(t, soap->tmpbuf + 6);
    8246     strcat(t, s + 1);
    8247   }
    8248   return t;
     10529soap_wchar2s(struct soap *soap, const wchar_t *s)
     10530{ register soap_wchar c;
     10531  register char *r, *t;
     10532  const wchar_t *q = s;
     10533  size_t n = 0;
     10534  while ((c = *q++))
     10535  { if (c > 0 && c < 0x80)
     10536      n++;
     10537    else
     10538      n += 6;
     10539  }
     10540  r = t = (char*)soap_malloc(soap, n + 1);
     10541  if (r)
     10542  { /* Convert wchar to UTF8 */
     10543    while ((c = *s++))
     10544    { if (c > 0 && c < 0x80)
     10545        *t++ = (char)c;
     10546      else
     10547      { if (c < 0x0800)
     10548          *t++ = (char)(0xC0 | ((c >> 6) & 0x1F));
     10549        else
     10550        { if (c < 0x010000)
     10551            *t++ = (char)(0xE0 | ((c >> 12) & 0x0F));
     10552          else
     10553          { if (c < 0x200000)
     10554              *t++ = (char)(0xF0 | ((c >> 18) & 0x07));
     10555            else
     10556            { if (c < 0x04000000)
     10557                *t++ = (char)(0xF8 | ((c >> 24) & 0x03));
     10558              else
     10559              { *t++ = (char)(0xFC | ((c >> 30) & 0x01));
     10560                *t++ = (char)(0x80 | ((c >> 24) & 0x3F));
     10561              }
     10562              *t++ = (char)(0x80 | ((c >> 18) & 0x3F));
     10563            }     
     10564            *t++ = (char)(0x80 | ((c >> 12) & 0x3F));
     10565          }
     10566          *t++ = (char)(0x80 | ((c >> 6) & 0x3F));
     10567        }
     10568        *t++ = (char)(0x80 | (c & 0x3F));
     10569      }
     10570    }
     10571    *t = '\0';
     10572  }
     10573  return r;
    824910574}
    825010575#endif
     
    825710582soap_outstring(struct soap *soap, const char *tag, int id, char *const*p, const char *type, int n)
    825810583{ id = soap_element_id(soap, tag, id, *p, NULL, 0, type, n);
    8259   if (id < 0
    8260    || soap_element_begin_out(soap, tag, id, type)
     10584  if (id < 0)
     10585    return soap->error;
     10586  if (!**p && (soap->mode & SOAP_C_NILSTRING))
     10587    return soap_element_null(soap, tag, id, type);
     10588  if (soap_element_begin_out(soap, tag, id, type)
    826110589   || soap_string_out(soap, *p, 0)
    826210590   || soap_element_end_out(soap, tag))
     
    827210600SOAP_FMAC2
    827310601soap_instring(struct soap *soap, const char *tag, char **p, const char *type, int t, int flag, long minlen, long maxlen)
    8274 { if (soap_element_begin_in(soap, tag, 1))
    8275     return NULL;
     10602{ if (soap_element_begin_in(soap, tag, 1, NULL))
     10603  { if (!tag || *tag != '-' || soap->error != SOAP_NO_TAG)
     10604      return NULL;
     10605    soap->error = SOAP_OK;
     10606  }
    827610607  if (!p)
    8277     if (!(p = (char**)soap_malloc(soap, sizeof(char*))))
     10608  { if (!(p = (char**)soap_malloc(soap, sizeof(char*))))
    827810609      return NULL;
     10610  }
    827910611  if (soap->body)
    828010612  { *p = soap_string_in(soap, flag, minlen, maxlen);
    828110613    if (!*p || !(char*)soap_id_enter(soap, soap->id, *p, t, sizeof(char*), 0, NULL, NULL, NULL))
    828210614      return NULL;
    8283   }
     10615    if (!**p && tag && *tag == '-')
     10616    { soap->error = SOAP_NO_TAG;
     10617      return NULL;
     10618    }
     10619  }
     10620  else if (tag && *tag == '-')
     10621  { soap->error = SOAP_NO_TAG;
     10622    return NULL;
     10623  }
     10624  else if (soap->null)
     10625    *p = NULL;
    828410626  else
    8285     *p = NULL;
    8286   p = (char**)soap_id_lookup(soap, soap->href, (void**)p, t, sizeof(char**), 0);
     10627    *p = soap_strdup(soap, SOAP_STR_EOS);
     10628  if (*soap->href)
     10629    p = (char**)soap_id_lookup(soap, soap->href, (void**)p, t, sizeof(char**), 0);
    828710630  if (soap->body && soap_element_end_in(soap, tag))
    828810631    return NULL;
     
    829210635
    829310636/******************************************************************************/
     10637#ifndef WITH_LEANER
    829410638#ifndef PALM_2
    829510639SOAP_FMAC1
     
    829810642soap_outwstring(struct soap *soap, const char *tag, int id, wchar_t *const*p, const char *type, int n)
    829910643{ id = soap_element_id(soap, tag, id, *p, NULL, 0, type, n);
    8300   if (id < 0
    8301    || soap_element_begin_out(soap, tag, id, type)
     10644  if (id < 0)
     10645    return soap->error;
     10646  if (!**p && (soap->mode & SOAP_C_NILSTRING))
     10647    return soap_element_null(soap, tag, id, type);
     10648  if (soap_element_begin_out(soap, tag, id, type)
    830210649   || soap_wstring_out(soap, *p, 0)
    830310650   || soap_element_end_out(soap, tag))
     
    830610653}
    830710654#endif
    8308 
    8309 /******************************************************************************/
     10655#endif
     10656
     10657/******************************************************************************/
     10658#ifndef WITH_LEANER
    831010659#ifndef PALM_2
    831110660SOAP_FMAC1
     
    831310662SOAP_FMAC2
    831410663soap_inwstring(struct soap *soap, const char *tag, wchar_t **p, const char *type, int t, long minlen, long maxlen)
    8315 { if (soap_element_begin_in(soap, tag, 1))
    8316     return NULL;
     10664{ if (soap_element_begin_in(soap, tag, 1, NULL))
     10665  { if (!tag || *tag != '-' || soap->error != SOAP_NO_TAG)
     10666      return NULL;
     10667    soap->error = SOAP_OK;
     10668  }
    831710669  if (!p)
    8318     if (!(p = (wchar_t**)soap_malloc(soap, sizeof(wchar_t*))))
     10670  { if (!(p = (wchar_t**)soap_malloc(soap, sizeof(wchar_t*))))
    831910671      return NULL;
     10672  }
    832010673  if (soap->body)
    832110674  { *p = soap_wstring_in(soap, 1, minlen, maxlen);
    832210675    if (!*p || !(wchar_t*)soap_id_enter(soap, soap->id, *p, t, sizeof(wchar_t*), 0, NULL, NULL, NULL))
    832310676      return NULL;
    8324   }
     10677    if (!**p && tag && *tag == '-')
     10678    { soap->error = SOAP_NO_TAG;
     10679      return NULL;
     10680    }
     10681  }
     10682  else if (tag && *tag == '-')
     10683  { soap->error = SOAP_NO_TAG;
     10684    return NULL;
     10685  }
     10686  else if (soap->null)
     10687    *p = NULL;
    832510688  else
    8326     *p = NULL;
    8327   p = (wchar_t**)soap_id_lookup(soap, soap->href, (void**)p, t, sizeof(wchar_t**), 0);
     10689    *p = soap_wstrdup(soap, (wchar_t*)SOAP_STR_EOS);
     10690  if (*soap->href)
     10691    p = (wchar_t**)soap_id_lookup(soap, soap->href, (void**)p, t, sizeof(wchar_t**), 0);
    832810692  if (soap->body && soap_element_end_in(soap, tag))
    832910693    return NULL;
     
    833110695}
    833210696#endif
     10697#endif
    833310698
    833410699/******************************************************************************/
    833510700#ifndef WITH_LEAN
    8336 static time_t
     10701SOAP_FMAC1
     10702time_t
     10703SOAP_FMAC2
    833710704soap_timegm(struct tm *T)
    833810705{
    833910706#if defined(HAVE_TIMEGM)
    834010707  return timegm(T);
    8341 #elif defined(HAVE_GETTIMEOFDAY)
    8342   struct timezone t;
    8343   struct timeval tv;
    8344   memset((void*)&t, 0, sizeof(t));
    8345   gettimeofday(&tv, &t);
    8346   T->tm_min -= t.tz_minuteswest - (t.tz_dsttime != 0)*60;
    8347   T->tm_isdst = 0;
    8348   return mktime(T);
    8349 /* WR[ */
    8350   /* The following define was added for VxWorks*/
    8351 #elif defined(HAVE_MKTIME)
    8352   /* FOR VXWORKS:
    8353   vxWorks does not seem to have any variable representation of time zones, but
    8354   timezone information can be set in INSTALL_DIR/target/h/private/timeP.h header
    8355   file, by setting the ZONEBUFFER define.  The ZONEBUFFER define follows this
    8356   format:
    8357     name_of_zone:<(unused)>:time_in_minutes_from_UTC:daylight_start:daylight_end
    8358   To calculate local time, the value of time_in_minutes_from_UTC is subtracted
    8359   from UTC; time_in_minutes_from_UTC must be positive. Daylight information is
    8360   expressed as mmddhh (month-day-hour), for example:
    8361     UTC::0:040102:100102
    8362   */
    8363   return mktime(T);
    8364 /* ]WR */
    8365 #elif defined(HAVE_FTIME)
    8366   struct timeb t;
    8367   memset((void*)&t, 0, sizeof(t));
    8368   t.timezone = 0;
    8369   t.dstflag = -1;
    8370   ftime(&t);
    8371   T->tm_min -= t.timezone - (t.dstflag != 0)*60;
    8372   T->tm_isdst = 0;
    8373   return mktime(T);
    837410708#else
    8375 #warning "time_t (de)serialization is not MT safe on this platform"
    8376   time_t t;
    8377   char *tz = getenv("TZ");
    8378   putenv("TZ=UTC");
    8379   tzset();
     10709  time_t t, g, z;
     10710  struct tm tm;
    838010711  t = mktime(T);
    8381   if (tz)
    8382   { char tmp[16];
    8383     strcpy(tmp, "TZ=");
    8384     strncat(tmp, tz, 12);
    8385     tmp[15] = '\0';
    8386     putenv(tmp);
    8387   }
    8388   else
    8389     putenv("TZ=");
    8390   tzset();
    8391   return t;
     10712  if (t == (time_t)-1)
     10713    return (time_t)-1;
     10714#ifdef HAVE_GMTIME_R
     10715  gmtime_r(&t, &tm);
     10716#else
     10717  tm = *gmtime(&t);
     10718#endif
     10719  tm.tm_isdst = 0;
     10720  g = mktime(&tm);
     10721  if (g == (time_t)-1)
     10722    return (time_t)-1;
     10723  z = g - t;
     10724  return t - z;
    839210725#endif
    839310726}
     
    840010733SOAP_FMAC2
    840110734soap_dateTime2s(struct soap *soap, time_t n)
    8402 { struct tm T;
    8403   struct tm *pT = &T;
     10735{ struct tm T, *pT = &T;
    840410736#if defined(HAVE_GMTIME_R)
    840510737  if (gmtime_r(&n, pT))
    840610738    strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT);
    8407 /* WR[ */
    8408   /* The following defines were added for VxWorks*/
    8409 #elif defined(HAVE_PGMTIME_R)
    8410   if (gmtime_r(&n, pT))
    8411     strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT);
    8412 #elif defined(HAVE_PGMTIME)
    8413   if (gmtime(&n, pT))
    8414     strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT);
    8415 /* ]WR */
    841610739#elif defined(HAVE_GMTIME)
    841710740  if ((pT = gmtime(&n)))
     
    842510748    gettimeofday(&tv, &tz);
    842610749    strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
    8427     sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -tz.tz_minuteswest/60+(tz.tz_dsttime!=0), abs(tz.tz_minuteswest)%60);
     10750    sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -tz.tz_minuteswest/60+(pT->tm_isdst!=0), abs(tz.tz_minuteswest)%60);
    842810751  }
    842910752#else
     
    843210755    gettimeofday(&tv, &tz);
    843310756    strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
    8434     sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -tz.tz_minuteswest/60+(tz.tz_dsttime!=0), abs(tz.tz_minuteswest)%60);
     10757    sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -tz.tz_minuteswest/60+(pT->tm_isdst!=0), abs(tz.tz_minuteswest)%60);
    843510758  }
    843610759#endif
     
    844010763#if defined(HAVE_LOCALTIME_R)
    844110764  if (localtime_r(&n, pT))
    8442   { ftime(&t);
     10765  {
     10766#ifdef __BORLANDC__
     10767    ::ftime(&t);
     10768#else
     10769    ftime(&t);
     10770#endif
    844310771    strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
    8444     sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -t.timezone/60+(t.dstflag!=0), abs(t.timezone)%60);
    8445   }
    8446 /* WR[ */
    8447   /* The following defines were added for VxWorks*/
    8448 #elif defined(HAVE_PLOCALTIME_R)
    8449   if (localtime_r(&n, pT))
    8450   { strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
    8451     sprintf(soap->tmpbuf+strlen(soap->tmpbuf), "%+03d:%02d", t.timezone/60, abs(t.timezone)%60);
    8452   }
    8453 /* ]WR */
     10772    sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -t.timezone/60+(pT->tm_isdst!=0), abs(t.timezone)%60);
     10773  }
    845410774#else
    845510775  if ((pT = localtime(&n)))
    8456   { ftime(&t);
     10776  {
     10777#ifdef __BORLANDC__
     10778    ::ftime(&t);
     10779#else
     10780    ftime(&t);
     10781#endif
    845710782    strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
    8458     sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -t.timezone/60+(t.dstflag!=0), abs(t.timezone)%60);
     10783    sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -t.timezone/60+(pT->tm_isdst!=0), abs(t.timezone)%60);
    845910784  }
    846010785#endif
     
    846210787  if (localtime_r(&n, pT))
    846310788    strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
    8464 /* WR[ */
    8465   /* The following defines were added for VxWorks*/
    8466 #elif defined(HAVE_PLOCALTIME_R)
    8467   if (localtime_r(&n, pT))
    8468     strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
    8469 /* ]WR */
    847010789#else
    847110790  if ((pT = localtime(&n)))
     
    849810817soap_s2dateTime(struct soap *soap, const char *s, time_t *p)
    849910818{ if (s)
    8500   { struct tm T;
    8501     char zone[16];
     10819  { char zone[32];
     10820    struct tm T;
     10821    const char *t;
     10822    *zone = '\0';
    850210823    memset((void*)&T, 0, sizeof(T));
    8503     zone[sizeof(zone)-1] = '\0';
    8504     sscanf(s, "%d-%d-%dT%d:%d:%d%15s", &T.tm_year, &T.tm_mon, &T.tm_mday, &T.tm_hour, &T.tm_min, &T.tm_sec, zone);
     10824    if (strchr(s, '-'))
     10825      t = "%d-%d-%dT%d:%d:%d%31s";
     10826    else if (strchr(s, ':'))
     10827      t = "%4d%2d%2dT%d:%d:%d%31s";
     10828    else /* parse non-XSD-standard alternative ISO 8601 format */
     10829      t = "%4d%2d%2dT%2d%2d%2d%31s";
     10830    if (sscanf(s, t, &T.tm_year, &T.tm_mon, &T.tm_mday, &T.tm_hour, &T.tm_min, &T.tm_sec, zone) < 6)
     10831      return soap->error = SOAP_TYPE;
    850510832    if (T.tm_year == 1)
    850610833      T.tm_year = 70;
     
    850810835      T.tm_year -= 1900;
    850910836    T.tm_mon--;
    8510     if (*zone)
    8511     { if (*zone == '.')
    8512       { for (s = zone + 1; *s; s++)
    8513           if (*s < '0' || *s > '9')
    8514             break;
    8515       }
    8516       else
    8517         s = zone;
    8518       if (*s != 'Z')
     10837    if (*zone == '.')
     10838    { for (s = zone + 1; *s; s++)
     10839        if (*s < '0' || *s > '9')
     10840          break;
     10841    }
     10842    else
     10843      s = zone;
     10844    if (*s)
     10845    {
     10846#ifndef WITH_NOZONE
     10847      if (*s == '+' || *s == '-')
    851910848      { int h = 0, m = 0;
    8520         sscanf(s, "%d:%d", &h, &m);
    8521         T.tm_hour -= h;
    8522         if (h >= 0)
    8523           T.tm_min -= m;
    8524         else
    8525           T.tm_min += m;
    8526       }
     10849        if (s[3] == ':')
     10850        { /* +hh:mm */
     10851          sscanf(s, "%d:%d", &h, &m);
     10852          if (h < 0)
     10853            m = -m;
     10854        }
     10855        else /* +hhmm */
     10856        { m = (int)atol(s);
     10857          h = m / 100;
     10858          m = m % 100;
     10859        }
     10860        T.tm_min -= m;
     10861        T.tm_hour -= h;
     10862        /* put hour and min in range */
     10863        T.tm_hour += T.tm_min / 60;
     10864        T.tm_min %= 60;
     10865        if (T.tm_min < 0)
     10866          T.tm_min += 60;
     10867        T.tm_mday += T.tm_hour / 24;
     10868        T.tm_hour %= 24;
     10869        if (T.tm_hour < 0)
     10870          T.tm_hour += 24;
     10871        /* note: day of the month may be out of range, timegm() handles it */
     10872      }
     10873#endif
    852710874      *p = soap_timegm(&T);
    852810875    }
    852910876    else
    8530       *p = mktime(&T); /* no time zone: suppose it is localtime? */
     10877      *p = mktime(&T);
    853110878  }
    853210879  return soap->error;
     
    853910886time_t *
    854010887SOAP_FMAC2
    8541 soap_indateTime(struct soap *soap, const char *tag, time_t *p, const char * type, int t)
    8542 { if (soap_element_begin_in(soap, tag, 0))
     10888soap_indateTime(struct soap *soap, const char *tag, time_t *p, const char *type, int t)
     10889{ if (soap_element_begin_in(soap, tag, 0, NULL))
    854310890    return NULL;
    854410891  if (*soap->type
     
    855010897  }
    855110898  p = (time_t*)soap_id_enter(soap, soap->id, p, t, sizeof(time_t), 0, NULL, NULL, NULL);
    8552   if (p)
     10899  if (*soap->href)
     10900    p = (time_t*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(time_t), 0, NULL);
     10901  else if (p)
    855310902  { if (soap_s2dateTime(soap, soap_value(soap), p))
    855410903      return NULL;
    855510904  }
    8556   p = (time_t*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(time_t), 0, NULL);
    855710905  if (soap->body && soap_element_end_in(soap, tag))
    855810906    return NULL;
     
    856610914int
    856710915SOAP_FMAC2
    8568 soap_outliteral(struct soap *soap, const char *tag, char *const*p)
     10916soap_outliteral(struct soap *soap, const char *tag, char *const*p, const char *type)
    856910917{ int i;
    857010918  const char *t = NULL;
    857110919  if (tag && *tag != '-')
    8572   { if ((t = strchr(tag, ':')))
     10920  { if (soap->local_namespaces && (t = strchr(tag, ':')))
    857310921    { strncpy(soap->tmpbuf, tag, t-tag);
    857410922      soap->tmpbuf[t-tag] = '\0';
     
    857710925          break;
    857810926      t++;
    8579       sprintf(soap->tmpbuf, "<%s xmlns=\"%s\">", t, soap->local_namespaces[i].ns ? soap->local_namespaces[i].ns : SOAP_STR_EOS);
     10927      if (soap_element(soap, t, 0, type)
     10928       || soap_attribute(soap, "xmlns", soap->local_namespaces[i].ns ? soap->local_namespaces[i].ns : SOAP_STR_EOS)
     10929       || soap_element_start_end_out(soap, NULL))
     10930        return soap->error;
    858010931    }
    858110932    else
    858210933    { t = tag;
    8583       sprintf(soap->tmpbuf, "<%s>", tag);
    8584     }
    8585     if (soap_send(soap, soap->tmpbuf))
    8586       return soap->error;
     10934      if (soap_element_begin_out(soap, t, 0, type))
     10935        return soap->error;
     10936    }
    858710937  }
    858810938  if (p && *p)
     
    859110941  }
    859210942  if (t)
    8593   { sprintf(soap->tmpbuf, "</%s>", t);
    8594     return soap_send(soap, soap->tmpbuf);
    8595   }
     10943    return soap_element_end_out(soap, t);
    859610944  return SOAP_OK;
    859710945}
     
    860410952SOAP_FMAC2
    860510953soap_inliteral(struct soap *soap, const char *tag, char **p)
    8606 { if (soap_element_begin_in(soap, tag, 1))
    8607     return NULL;
     10954{ if (soap_element_begin_in(soap, tag, 1, NULL))
     10955  { if (soap->error != SOAP_NO_TAG || soap_unget(soap, soap_get(soap)) == SOAP_TT)
     10956      return NULL;
     10957    soap->error = SOAP_OK;
     10958  }
    860810959  if (!p)
    8609     if (!(p = (char**)soap_malloc(soap, sizeof(char*))))
     10960  { if (!(p = (char**)soap_malloc(soap, sizeof(char*))))
    861010961      return NULL;
    8611   if (soap->null)
     10962  }
     10963  if (soap->body || (tag && *tag == '-'))
     10964  { *p = soap_string_in(soap, 0, -1, -1);
     10965    if (!*p)
     10966      return NULL;
     10967    if (!**p && tag && *tag == '-')
     10968    { soap->error = SOAP_NO_TAG;
     10969      return NULL;
     10970    }
     10971  }
     10972  else if (soap->null)
    861210973    *p = NULL;
    8613   else if (soap->body)
    8614     *p = soap_string_in(soap, 0, -1, -1);
    861510974  else
    8616     *p = NULL;
     10975    *p = soap_strdup(soap, SOAP_STR_EOS);
    861710976  if (soap->body && soap_element_end_in(soap, tag))
    861810977    return NULL;
     
    862210981
    862310982/******************************************************************************/
     10983#ifndef WITH_LEANER
    862410984#ifndef PALM_2
    862510985SOAP_FMAC1
    862610986int
    862710987SOAP_FMAC2
    8628 soap_outwliteral(struct soap *soap, const char *tag, wchar_t *const*p)
     10988soap_outwliteral(struct soap *soap, const char *tag, wchar_t *const*p, const char *type)
    862910989{ int i;
    863010990  const char *t = NULL;
    8631   wchar_t c;
    8632   const wchar_t *s;
    863310991  if (tag && *tag != '-')
    8634   { if (tag && (t = strchr(tag, ':')))
     10992  { if (soap->local_namespaces && (t = strchr(tag, ':')))
    863510993    { strncpy(soap->tmpbuf, tag, t-tag);
    863610994      soap->tmpbuf[t-tag] = '\0';
     
    863910997          break;
    864010998      t++;
    8641       sprintf(soap->tmpbuf, "<%s xmlns=\"%s\">", t, soap->local_namespaces[i].ns ? soap->local_namespaces[i].ns : SOAP_STR_EOS);
     10999      if (soap_element(soap, t, 0, type)
     11000       || soap_attribute(soap, "xmlns", soap->local_namespaces[i].ns ? soap->local_namespaces[i].ns : SOAP_STR_EOS)
     11001       || soap_element_start_end_out(soap, NULL))
     11002        return soap->error;
    864211003    }
    864311004    else
    864411005    { t = tag;
    8645       sprintf(soap->tmpbuf, "<%s>", tag);
     11006      if (soap_element_begin_out(soap, t, 0, type))
     11007        return soap->error;
    864611008    }
    864711009    if (soap_send(soap, soap->tmpbuf))
     
    864911011  }
    865011012  if (p)
    8651   { s = *p;
     11013  { wchar_t c;
     11014    const wchar_t *s = *p;
    865211015    while ((c = *s++))
    8653       if (soap_pututf8(soap, (unsigned char)c))
     11016    { if (soap_pututf8(soap, (unsigned long)c))
    865411017        return soap->error;
     11018    }
    865511019  }
    865611020  if (t)
    8657   { sprintf(soap->tmpbuf, "</%s>", t);
    8658     return soap_send(soap, soap->tmpbuf);
    8659   }
     11021    return soap_element_end_out(soap, t);
    866011022  return SOAP_OK;
    866111023}
    866211024#endif
    8663 
    8664 /******************************************************************************/
     11025#endif
     11026
     11027/******************************************************************************/
     11028#ifndef WITH_LEANER
    866511029#ifndef PALM_2
    866611030SOAP_FMAC1
     
    866811032SOAP_FMAC2
    866911033soap_inwliteral(struct soap *soap, const char *tag, wchar_t **p)
    8670 { if (soap_element_begin_in(soap, tag, 1))
     11034{ if (soap_element_begin_in(soap, tag, 1, NULL))
     11035  { if (soap->error != SOAP_NO_TAG || soap_unget(soap, soap_get(soap)) == SOAP_TT)
     11036      return NULL;
     11037    soap->error = SOAP_OK;
     11038  }
     11039  if (!p)
     11040  { if (!(p = (wchar_t**)soap_malloc(soap, sizeof(wchar_t*))))
     11041      return NULL;
     11042  }
     11043  if (soap->body)
     11044  { *p = soap_wstring_in(soap, 0, -1, -1);
     11045    if (!*p)
     11046      return NULL;
     11047    if (!**p && tag && *tag == '-')
     11048    { soap->error = SOAP_NO_TAG;
     11049      return NULL;
     11050    }
     11051  }
     11052  else if (tag && *tag == '-')
     11053  { soap->error = SOAP_NO_TAG;
    867111054    return NULL;
    8672   if (!p)
    8673     if (!(p = (wchar_t**)soap_malloc(soap, sizeof(wchar_t*))))
    8674       return NULL;
    8675   if (soap->null)
     11055  }
     11056  else if (soap->null)
    867611057    *p = NULL;
    8677   else if (soap->body)
    8678     *p = soap_wstring_in(soap, 0, -1, -1);
    867911058  else
    8680     *p = NULL;
     11059    *p = soap_wstrdup(soap, (wchar_t*)SOAP_STR_EOS);
    868111060  if (soap->body && soap_element_end_in(soap, tag))
    868211061    return NULL;
     
    868411063}
    868511064#endif
     11065#endif
    868611066
    868711067/******************************************************************************/
     
    869111071SOAP_FMAC2
    869211072soap_value(struct soap *soap)
    8693 { size_t i;
    8694   soap_wchar c = 0;
    8695   char *s = soap->tmpbuf;
     11073{ register size_t i;
     11074  register soap_wchar c = 0;
     11075  register char *s = soap->tmpbuf;
    869611076  if (!soap->body)
    869711077    return SOAP_STR_EOS;
     11078  do c = soap_get(soap);
     11079  while (soap_blank(c));
    869811080  for (i = 0; i < sizeof(soap->tmpbuf) - 1; i++)
    8699   { c = soap_get(soap);
    8700     if (c == SOAP_TT || (int)c == EOF || soap_blank(c))
     11081  { if (c == SOAP_TT || (int)c == EOF)
    870111082      break;
    870211083    *s++ = (char)c;
    8703   }
     11084    c = soap_get(soap);
     11085  }
     11086  for (s--; i > 0; i--, s--)
     11087  { if (!soap_blank(*s))
     11088      break;
     11089  }
     11090  s[1] = '\0';
    870411091  if ((int)c == EOF || c == SOAP_TT)
    870511092    soap_unget(soap, c);
    8706   *s = '\0';
     11093  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element content value='%s'\n", soap->tmpbuf));
     11094#ifdef WITH_DOM
     11095  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
     11096    soap->dom->data = soap_strdup(soap, soap->tmpbuf);
     11097#endif
    870711098  return soap->tmpbuf; /* return non-null pointer */
    870811099}
     
    871011101
    871111102/******************************************************************************/
     11103#if !defined(WITH_LEANER) || !defined(WITH_NOHTTP)
    871211104#ifndef PALM_2
    871311105SOAP_FMAC1
     
    872011112  { while (--i > 0)
    872111113    { c = soap_getchar(soap);
    8722       if (c == '\r')
     11114      if (c == '\r' || c == '\n')
    872311115        break;
    872411116      if ((int)c == EOF)
     
    872611118      *s++ = (char)c;
    872711119    }
    8728     c = soap_getchar(soap);
     11120    if (c != '\n')
     11121      c = soap_getchar(soap); /* got \r or something else, now get \n */
    872911122    if (c == '\n')
    873011123    { *s = '\0';
    8731       if (i+1 == len) /* empty line: end of HTTP header */
     11124      if (i+1 == len) /* empty line: end of HTTP/MIME header */
    873211125        break;
    8733       c = soap_unget(soap, soap_getchar(soap));
     11126      c = soap_get0(soap);
    873411127      if (c != ' ' && c != '\t') /* HTTP line continuation? */
    873511128        break;
     
    873811131      return soap->error = SOAP_EOF;
    873911132  }
     11133  if (i < 0)
     11134    return soap->error = SOAP_HDR;
    874011135  return SOAP_OK;
    874111136}
     11137#endif
    874211138#endif
    874311139
     
    875011146  register struct soap_multipart *content;
    875111147  register size_t count = soap->count;
    8752   if (soap->mode & SOAP_ENC_DIME)
     11148  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the message size with attachments, current count=%lu\n", (unsigned long)count));
     11149  if ((soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM))
    875311150  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the size of DIME attachments\n"));
    875411151    for (content = soap->dime.first; content; content = content->next)
     
    876011157      if (content->options)
    876111158        count += ((((unsigned char)content->options[2] << 8) | ((unsigned char)content->options[3]))+7)&(~3);
    8762       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Size of DIME attachment %lu bytes\n", (unsigned long)content->size));
     11159      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Size of DIME attachment content is %lu bytes\n", (unsigned long)content->size));
    876311160    }
    876411161  }
     
    877311170      if (content->type)
    877411171        count += 16 + strlen(content->type);
    8775       s = soap_str_code(mime_codes, content->encoding);
    877611172      /* count Content-Transfer-Encoding: ...\r\n */
     11173      s = soap_code_str(mime_codes, content->encoding);
    877711174      if (s)
    877811175        count += 29 + strlen(s);
     
    878511182      /* count Content-Description: ...\r\n */
    878611183      if (content->description)
    8787         count += 23 + strlen(content->location);
     11184        count += 23 + strlen(content->description);
    878811185      /* count \r\n...content */
    878911186      count += 2 + content->size;
    8790       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Size of MIME attachment %lu bytes\n", (unsigned long)content->size));
    8791     }
    8792     /* count \r\n--boundary--\r\n */
    8793     count += 8 + n;
    8794   }
     11187      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Size of MIME attachment content is %lu bytes\n", (unsigned long)content->size));
     11188    }
     11189    /* count \r\n--boundary-- */
     11190    count += 6 + n;
     11191  }
     11192  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "New count is %lu bytes\n", (unsigned long)count));
    879511193  return count;
    879611194#else
     
    882511223    s = (char*)soap_malloc(soap, n + 5);
    882611224    if (s)
    8827     { s[0] = optype >> 8;
    8828       s[1] = optype & 0xFF;
    8829       s[2] = n >> 8;
    8830       s[3] = n & 0xFF;
     11225    { s[0] = (char)(optype >> 8);
     11226      s[1] = (char)(optype & 0xFF);
     11227      s[2] = (char)(n >> 8);
     11228      s[3] = (char)(n & 0xFF);
    883111229      strcpy(s + 4, option);
    883211230    }
     
    884611244{ unsigned char tmp[12];
    884711245  size_t optlen = 0, idlen = 0, typelen = 0;
    8848   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Put DIME header id='%s'\n", soap->dime.id?soap->dime.id:""));
     11246  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Put DIME header id='%s'\n", soap->dime.id?soap->dime.id:SOAP_STR_EOS));
    884911247  if (soap->dime.options)
    885011248    optlen = (((unsigned char)soap->dime.options[2] << 8) | ((unsigned char)soap->dime.options[3])) + 4;
    885111249  if (soap->dime.id)
    8852     idlen = strlen(soap->dime.id);
     11250  { idlen = strlen(soap->dime.id);
     11251    if (idlen > 0x0000FFFF)
     11252      idlen = 0x0000FFFF;
     11253  }
    885311254  if (soap->dime.type)
    8854     typelen = strlen(soap->dime.type);
     11255  { typelen = strlen(soap->dime.type);
     11256    if (typelen > 0x0000FFFF)
     11257      typelen = 0x0000FFFF;
     11258  }
    885511259  tmp[0] = SOAP_DIME_VERSION | (soap->dime.flags & 0x7);
    885611260  tmp[1] = soap->dime.flags & 0xF0;
    8857   tmp[2] = optlen >> 8;
    8858   tmp[3] = optlen & 0xFF;
    8859   tmp[4] = idlen >> 8;
    8860   tmp[5] = idlen & 0xFF;
    8861   tmp[6] = typelen >> 8;
    8862   tmp[7] = typelen & 0xFF;
    8863   tmp[8] = soap->dime.size >> 24;
    8864   tmp[9] = (soap->dime.size >> 16) & 0xFF;
    8865   tmp[10] = (soap->dime.size >> 8) & 0xFF;
    8866   tmp[11] = soap->dime.size & 0xFF;
     11261  tmp[2] = (char)(optlen >> 8);
     11262  tmp[3] = (char)(optlen & 0xFF);
     11263  tmp[4] = (char)(idlen >> 8);
     11264  tmp[5] = (char)(idlen & 0xFF);
     11265  tmp[6] = (char)(typelen >> 8);
     11266  tmp[7] = (char)(typelen & 0xFF);
     11267  tmp[8] = (char)(soap->dime.size >> 24);
     11268  tmp[9] = (char)((soap->dime.size >> 16) & 0xFF);
     11269  tmp[10] = (char)((soap->dime.size >> 8) & 0xFF);
     11270  tmp[11] = (char)(soap->dime.size & 0xFF);
    886711271  if (soap_send_raw(soap, (char*)tmp, 12)
    886811272   || soap_putdimefield(soap, soap->dime.options, optlen)
     
    889811302        return soap->error;
    889911303      }
    8900       if (!content->size && ((soap->mode & SOAP_ENC_XML) || (soap->mode & SOAP_IO) == SOAP_IO_CHUNK || (soap->mode & SOAP_IO) == SOAP_IO_STORE))
     11304      if (!size && ((soap->mode & SOAP_ENC_XML) || (soap->mode & SOAP_IO) == SOAP_IO_CHUNK || (soap->mode & SOAP_IO) == SOAP_IO_STORE))
    890111305      { size_t chunksize = sizeof(soap->tmpbuf);
    890211306        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunked streaming DIME\n"));
     
    890511309          DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimeread returned %lu bytes\n", (unsigned long)size));
    890611310          if (size < chunksize)
    8907           { soap->dime.flags &= ~SOAP_DIME_CF;
     11311          { soap->dime.flags &= ~SOAP_DIME_CF;
    890811312            if (!content->next)
    890911313              soap->dime.flags |= SOAP_DIME_ME;
    8910           }
     11314          }
    891111315          else
    891211316            soap->dime.flags |= SOAP_DIME_CF;
    8913           soap->dime.size = size;
     11317          soap->dime.size = size;
    891411318          if (soap_putdimehdr(soap)
    8915            || soap_putdimefield(soap, soap->tmpbuf, size))
     11319           || soap_putdimefield(soap, soap->tmpbuf, size))
    891611320            break;
    891711321          if (soap->dime.id)
    8918           { soap->dime.flags &= ~(SOAP_DIME_MB | SOAP_DIME_MEDIA);
     11322          { soap->dime.flags &= ~(SOAP_DIME_MB | SOAP_DIME_MEDIA);
    891911323            soap->dime.id = NULL;
    892011324            soap->dime.type = NULL;
     
    893011334        do
    893111335        { size_t bufsize;
    8932           if (size < sizeof(soap->tmpbuf))
     11336          if (size < sizeof(soap->tmpbuf))
    893311337            bufsize = size;
    893411338          else
    893511339            bufsize = sizeof(soap->tmpbuf);
    893611340          if (!(bufsize = soap->fdimeread(soap, handle, soap->tmpbuf, bufsize)))
    8937           { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimeread failed: insufficient data (%lu bytes remaining from %lu bytes)\n", (unsigned long)size, (unsigned long)soap->dime.size));
     11341          { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimeread failed: insufficient data (%lu bytes remaining from %lu bytes)\n", (unsigned long)size, (unsigned long)content->size));
    893811342            soap->error = SOAP_EOF;
    8939             break;
     11343            break;
    894011344          }
    894111345          if (soap_send_raw(soap, soap->tmpbuf, bufsize))
     
    896911373soap_getdimefield(struct soap *soap, size_t n)
    897011374{ register soap_wchar c;
    8971   register int i;
     11375  register size_t i;
    897211376  register char *s;
    8973   char *p = NULL;
     11377  register char *p = NULL;
    897411378  if (n)
    897511379  { p = (char*)soap_malloc(soap, n + 1);
     
    903711441  if (!(soap->dime.type = soap_getdimefield(soap, typelen)) && soap->error)
    903811442    return soap->error;
    9039   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME id=%s, type=%s, options=%s\n", soap->dime.id?soap->dime.id:"", soap->dime.type?soap->dime.type:"", soap->dime.options?soap->dime.options+4:""));
     11443  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME id=%s, type=%s, options=%s\n", soap->dime.id?soap->dime.id:SOAP_STR_EOS, soap->dime.type?soap->dime.type:"", soap->dime.options?soap->dime.options+4:SOAP_STR_EOS));
    904011444  if (soap->dime.flags & SOAP_DIME_ME)
    904111445    soap->mode &= ~SOAP_ENC_DIME;
     
    905211456SOAP_FMAC2
    905311457soap_getdime(struct soap *soap)
    9054 { struct soap_multipart *content;
    9055   if (soap_getdimehdr(soap))
     11458{ while (soap->dime.flags & SOAP_DIME_CF)
     11459  { if (soap_getdimehdr(soap))
     11460      return soap->error;
     11461    if (soap_move(soap, (long)soap->dime.size))
     11462      return soap->error = SOAP_EOF;
     11463  }
     11464  if (soap_move(soap, (long)(((soap->dime.size+3)&(~3))-soap_tell(soap))))
     11465    return soap->error = SOAP_EOF;
     11466  for (;;)
     11467  { register struct soap_multipart *content;
     11468    if (soap_getdimehdr(soap))
     11469      break;
     11470    if (soap->fdimewriteopen && ((soap->dime.ptr = (char*)soap->fdimewriteopen(soap, soap->dime.id, soap->dime.type, soap->dime.options)) || soap->error))
     11471    { const char *id, *type, *options;
     11472      size_t size, n;
     11473      if (!soap->dime.ptr)
     11474        return soap->error;
     11475      id = soap->dime.id;
     11476      type = soap->dime.type;
     11477      options = soap->dime.options;
     11478      for (;;)
     11479      { size = soap->dime.size;
     11480        for (;;)
     11481        { n = soap->buflen - soap->bufidx;
     11482          if (size < n)
     11483            n = size;
     11484          if ((soap->error = soap->fdimewrite(soap, (void*)soap->dime.ptr, soap->buf + soap->bufidx, n)))
     11485            break;
     11486          size -= n;
     11487          if (!size)
     11488          { soap->bufidx += n;
     11489            break;
     11490          }
     11491          if (soap_recv(soap))
     11492          { soap->error = SOAP_EOF;
     11493            goto end;
     11494          }
     11495        }
     11496        if (soap_move(soap, -(long)soap->dime.size&3))
     11497        { soap->error = SOAP_EOF;
     11498          break;
     11499        }
     11500        if (!(soap->dime.flags & SOAP_DIME_CF))
     11501          break;
     11502        if (soap_getdimehdr(soap))
     11503          break;
     11504      }
     11505end:
     11506      if (soap->fdimewriteclose)
     11507        soap->fdimewriteclose(soap, (void*)soap->dime.ptr);
     11508      soap->dime.size = 0;
     11509      soap->dime.id = id;
     11510      soap->dime.type = type;
     11511      soap->dime.options = options;
     11512    }
     11513    else if (soap->dime.flags & SOAP_DIME_CF)
     11514    { const char *id, *type, *options;
     11515      id = soap->dime.id;
     11516      type = soap->dime.type;
     11517      options = soap->dime.options;
     11518      if (soap_new_block(soap) == NULL)
     11519        return SOAP_EOM;
     11520      for (;;)
     11521      { register soap_wchar c;
     11522        register size_t i;
     11523        register char *s;
     11524        s = (char*)soap_push_block(soap, NULL, soap->dime.size);
     11525        if (!s)
     11526          return soap->error = SOAP_EOM;
     11527        for (i = soap->dime.size; i > 0; i--)
     11528        { if ((int)(c = soap_get1(soap)) == EOF)
     11529            return soap->error = SOAP_EOF;
     11530          *s++ = (char)c;
     11531        }
     11532        if (soap_move(soap, -(long)soap->dime.size&3))
     11533          return soap->error = SOAP_EOF;
     11534        if (!(soap->dime.flags & SOAP_DIME_CF))
     11535          break;
     11536        if (soap_getdimehdr(soap))
     11537          return soap->error;
     11538      }
     11539      soap->dime.size = soap->blist->size++; /* allocate one more for '\0' */
     11540      if (!(soap->dime.ptr = soap_save_block(soap, NULL, NULL, 0)))
     11541        return soap->error;
     11542      soap->dime.ptr[soap->dime.size] = '\0'; /* force 0-terminated */
     11543      soap->dime.id = id;
     11544      soap->dime.type = type;
     11545      soap->dime.options = options;
     11546    }
     11547    else
     11548      soap->dime.ptr = soap_getdimefield(soap, soap->dime.size);
     11549    content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, soap->dime.ptr, soap->dime.size);
     11550    if (!content)
     11551      return soap->error = SOAP_EOM;
     11552    content->id = soap->dime.id;
     11553    content->type = soap->dime.type;
     11554    content->options = soap->dime.options;
     11555    if (soap->error)
     11556      return soap->error;
     11557    soap_resolve_attachment(soap, content);
     11558  }
     11559  if (soap->error != SOAP_DIME_END)
    905611560    return soap->error;
    9057   if (soap->fdimewriteopen && ((soap->dime.ptr = (char*)soap->fdimewriteopen(soap, soap->dime.id, soap->dime.type, soap->dime.options)) || soap->error))
    9058   { const char *id, *type, *options;
    9059     size_t size, n;
    9060     if (!soap->dime.ptr)
    9061       return soap->error;
    9062     id = soap->dime.id;
    9063     type = soap->dime.type;
    9064     options = soap->dime.options;
    9065     for (;;)
    9066     { size = soap->dime.size;
    9067       for (;;)
    9068       { n = soap->buflen - soap->bufidx;
    9069         if (size < n)
    9070           n = size;
    9071         if ((soap->error = soap->fdimewrite(soap, (void*)soap->dime.ptr, soap->buf + soap->bufidx, n)))
    9072           break;
    9073         size -= n;
    9074         if (!size)
    9075         { soap->bufidx += n;
    9076           break;
    9077         }
    9078         if (soap_recv(soap))
    9079         { soap->error = SOAP_EOF;
    9080           goto end;
    9081         }
    9082       }
    9083       if (soap_move(soap, -(long)soap->dime.size&3))
    9084       { soap->error = SOAP_EOF;
    9085         break;
    9086       }
    9087       if (!(soap->dime.flags & SOAP_DIME_CF))
    9088         break;
    9089       if (soap_getdimehdr(soap))
    9090         break;
    9091     }
    9092 end:
    9093     if (soap->fdimewriteclose)
    9094       soap->fdimewriteclose(soap, (void*)soap->dime.ptr);
    9095     soap->dime.size = 0;
    9096     soap->dime.id = id;
    9097     soap->dime.type = type;
    9098     soap->dime.options = options;
    9099   }
    9100   else if (soap->dime.flags & SOAP_DIME_CF)
    9101   { const char *id, *type, *options;
    9102     register soap_wchar c;
    9103     register char *s;
    9104     register int i;
    9105     id = soap->dime.id;
    9106     type = soap->dime.type;
    9107     options = soap->dime.options;
    9108     if (soap_new_block(soap))
    9109       return SOAP_EOM;
    9110     for (;;)
    9111     { s = (char*)soap_push_block(soap, soap->dime.size);
    9112       if (!s)
    9113         return soap->error = SOAP_EOM;
    9114       for (i = soap->dime.size; i > 0; i--)
    9115       { if ((int)(c = soap_get1(soap)) == EOF)
    9116           return soap->error = SOAP_EOF;
    9117         *s++ = (char)c;
    9118       }
    9119       if (soap_move(soap, -(long)soap->dime.size&3))
    9120         return soap->error = SOAP_EOF;
    9121       if (!(soap->dime.flags & SOAP_DIME_CF))
    9122         break;
    9123       if (soap_getdimehdr(soap))
    9124         return soap->error;
    9125     }
    9126     soap->dime.size = soap->blist->size++; /* allocate one more for '\0' */
    9127     if (!(soap->dime.ptr = soap_save_block(soap, NULL, 0)))
    9128       return soap->error;
    9129     soap->dime.ptr[soap->dime.size] = '\0'; /* force 0-terminated */
    9130     soap->dime.id = id;
    9131     soap->dime.type = type;
    9132     soap->dime.options = options;
    9133   }
    9134   else
    9135     soap->dime.ptr = soap_getdimefield(soap, soap->dime.size);
    9136   content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, soap->dime.ptr, soap->dime.size);
    9137   if (!content)
    9138     return soap->error = SOAP_EOM;
    9139   content->id = soap->dime.id;
    9140   content->type = soap->dime.type;
    9141   content->options = soap->dime.options;
    9142   return soap->error;
     11561  return soap->error = SOAP_OK;
    914311562}
    914411563#endif
     
    919111610      else if (!soap_tag_cmp(key, "Content-Location"))
    919211611        content->location = soap_strdup(soap, val);
     11612      else if (!soap_tag_cmp(key, "Content-Disposition"))
     11613        content->id = soap_strdup(soap, soap_get_header_attribute(soap, val, "name"));
    919311614      else if (!soap_tag_cmp(key, "Content-Type"))
    919411615        content->type = soap_strdup(soap, val);
     
    919611617        content->description = soap_strdup(soap, val);
    919711618      else if (!soap_tag_cmp(key, "Content-Transfer-Encoding"))
    9198         content->encoding = (enum soap_mime_encoding)soap_int_code(mime_codes, val, (long)SOAP_MIME_NONE);
     11619        content->encoding = (enum soap_mime_encoding)soap_code_int(mime_codes, val, (long)SOAP_MIME_NONE);
    919911620    }
    920011621    if (soap_getline(soap, key, sizeof(soap->msgbuf)))
     
    921311634SOAP_FMAC2
    921411635soap_getmime(struct soap *soap)
    9215 { register soap_wchar c;
    9216   if (!soap->mime.last)
    9217     return SOAP_OK;
     11636{ while (soap_get_mime_attachment(soap, NULL))
     11637    ;
     11638  return soap->error;
     11639}
     11640#endif
     11641#endif
     11642
     11643/******************************************************************************/
     11644#ifndef WITH_LEANER
     11645#ifndef PALM_1
     11646SOAP_FMAC1
     11647void
     11648SOAP_FMAC2
     11649soap_post_check_mime_attachments(struct soap *soap)
     11650{ soap->imode |= SOAP_MIME_POSTCHECK;
     11651}
     11652#endif
     11653#endif
     11654
     11655/******************************************************************************/
     11656#ifndef WITH_LEANER
     11657#ifndef PALM_1
     11658SOAP_FMAC1
     11659int
     11660SOAP_FMAC2
     11661soap_check_mime_attachments(struct soap *soap)
     11662{ if (soap->mode & SOAP_MIME_POSTCHECK)
     11663    return soap_get_mime_attachment(soap, NULL) != NULL;
     11664  return 0;
     11665}
     11666#endif
     11667#endif
     11668
     11669/******************************************************************************/
     11670#ifndef WITH_LEANER
     11671#ifndef PALM_1
     11672SOAP_FMAC1
     11673struct soap_multipart *
     11674SOAP_FMAC2
     11675soap_get_mime_attachment(struct soap *soap, void *handle)
     11676{ register soap_wchar c = 0;
     11677  register size_t i, m = 0;
     11678  register char *s, *t = NULL;
     11679  register struct soap_multipart *content;
     11680  register short flag = 0;
     11681  if (!(soap->mode & SOAP_ENC_MIME))
     11682    return NULL;
     11683  content = soap->mime.last;
     11684  if (!content)
     11685  { if (soap_getmimehdr(soap))
     11686      return NULL;
     11687    content = soap->mime.last;
     11688  }
     11689  else if (content != soap->mime.first)
     11690  { if (soap->fmimewriteopen && ((content->ptr = (char*)soap->fmimewriteopen(soap, (void*)handle, content->id, content->type, content->description, content->encoding)) || soap->error))
     11691    { if (!content->ptr)
     11692        return NULL;
     11693    }
     11694  }
     11695  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Parsing MIME content id=%s type=%s\n", content->id?content->id:SOAP_STR_EOS, content->type?content->type:SOAP_STR_EOS));
     11696  if (!content->ptr && soap_new_block(soap) == NULL)
     11697  { soap->error = SOAP_EOM;
     11698    return NULL;
     11699  }
    921811700  for (;;)
    9219   { register size_t i, m = 0;
    9220     register char *s;
    9221     struct soap_multipart *content = soap->mime.last;
    9222     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Parsing MIME content id=%s type=%s\n", content->id?content->id:"", content->type?content->type:""));
    9223     if (soap_new_block(soap))
    9224       return soap->error = SOAP_EOM;
    9225     for (;;)
    9226     { register char *t = NULL;
    9227       if (!(s = (char*)soap_push_block(soap, SOAP_BLKLEN)))
    9228         return soap->error = SOAP_EOM;
    9229       for (i = 0; i < SOAP_BLKLEN; i++)
    9230       { if (m > 0)
    9231         { *s++ = *t++;
    9232           m--;
    9233         }
    9234         else
     11701  { if (content->ptr)
     11702      s = soap->tmpbuf;
     11703    else if (!(s = (char*)soap_push_block(soap, NULL, sizeof(soap->tmpbuf))))
     11704    { soap->error = SOAP_EOM;
     11705      return NULL;
     11706    }
     11707    for (i = 0; i < sizeof(soap->tmpbuf); i++)
     11708    { if (m > 0)
     11709      { *s++ = *t++;
     11710        m--;
     11711      }
     11712      else
     11713      { if (!flag)
    923511714        { c = soap_get1(soap);
    9236           if ((int)c == EOF)
    9237             return soap->error = SOAP_EOF;
    9238           if (c == '\r')
    9239           { t = soap->tmpbuf;
    9240             strcpy(t, "\n--");
    9241             strncat(t, soap->mime.boundary, sizeof(soap->tmpbuf)-3);
    9242             t[sizeof(soap->tmpbuf)-1] = '\0';
    9243             do c = soap_getchar(soap);
    9244             while (c == *t++);
    9245             if ((int)c == EOF)
    9246               return soap->error = SOAP_EOF;
    9247             if (!*--t)
    9248               goto end;
    9249             *t = (char)c;
    9250             m = t - soap->tmpbuf + 1;
    9251             t = soap->tmpbuf;
    9252             c = '\r';
    9253           }
    9254           *s++ = (char)c;
     11715          if ((int)c == EOF)
     11716          { soap->error = SOAP_EOF;
     11717            return NULL;
     11718          }
    925511719        }
    9256       }
    9257     }
     11720        if (flag || c == '\r')
     11721        { t = soap->msgbuf;
     11722          memset(t, 0, sizeof(soap->msgbuf));
     11723          strcpy(t, "\n--");
     11724          if (soap->mime.boundary)
     11725            strncat(t, soap->mime.boundary, sizeof(soap->msgbuf)-4);
     11726          do c = soap_getchar(soap);
     11727          while (c == *t++);
     11728          if ((int)c == EOF)
     11729          { soap->error = SOAP_EOF;
     11730            return NULL;
     11731          }
     11732          if (!*--t)
     11733            goto end;
     11734          *t = (char)c;
     11735          flag = (c == '\r');
     11736          m = t - soap->msgbuf + 1 - flag;
     11737          t = soap->msgbuf;
     11738          c = '\r';
     11739        }
     11740        *s++ = (char)c;
     11741      }
     11742    }
     11743    if (content->ptr && soap->fmimewrite)
     11744    { if ((soap->error = soap->fmimewrite(soap, (void*)content->ptr, soap->tmpbuf, i)))
     11745        break;
     11746    }
     11747  }
    925811748end:
    9259     *s = '\0'; /* force 0-terminated */
    9260     content->size = soap_size_block(soap, i+1)-1;
    9261     content->ptr = soap_save_block(soap, NULL, 0);
    9262     if (c == '-' && soap_getchar(soap) == '-')
    9263       break;
    9264     while (c != '\r' && (int)c != EOF && soap_blank(c))
     11749  *s = '\0'; /* force 0-terminated */
     11750  if (content->ptr)
     11751  { if (!soap->error && soap->fmimewrite)
     11752      soap->error = soap->fmimewrite(soap, (void*)content->ptr, soap->tmpbuf, i);
     11753    if (soap->fmimewriteclose)
     11754      soap->fmimewriteclose(soap, (void*)content->ptr);
     11755    if (soap->error)
     11756      return NULL;
     11757  }
     11758  else
     11759  { content->size = soap_size_block(soap, NULL, i+1)-1;
     11760    content->ptr = soap_save_block(soap, NULL, NULL, 0);
     11761  }
     11762  soap_resolve_attachment(soap, content);
     11763  if (c == '-' && soap_getchar(soap) == '-')
     11764  { soap->mode &= ~SOAP_ENC_MIME;
     11765    if ((soap->mode & SOAP_MIME_POSTCHECK) && soap_end_recv(soap))
     11766      return NULL;
     11767  }
     11768  else
     11769  { while (c != '\r' && (int)c != EOF && soap_blank(c))
    926511770      c = soap_getchar(soap);
    926611771    if (c != '\r' || soap_getchar(soap) != '\n')
    9267       return soap->error = SOAP_MIME_ERROR;
     11772    { soap->error = SOAP_MIME_ERROR;
     11773      return NULL;
     11774    }
    926811775    if (soap_getmimehdr(soap))
    9269       return soap->error;
    9270   }
    9271   do c = soap_getchar(soap);
    9272   while ((int)c != EOF && c != '\r');
    9273   if ((int)c == EOF)
    9274     return soap->error = SOAP_EOF;
    9275   if (soap_getchar(soap) != '\n')
    9276     return soap->error = SOAP_MIME_ERROR;
    9277   return SOAP_OK;
     11776      return NULL;
     11777  }
     11778  return content;
     11779}
     11780#endif
     11781#endif
     11782
     11783/******************************************************************************/
     11784#ifndef WITH_LEANER
     11785#ifndef PALM_1
     11786SOAP_FMAC1
     11787int
     11788SOAP_FMAC2
     11789soap_match_cid(struct soap *soap, const char *s, const char *t)
     11790{ register size_t n;
     11791  if (!s)
     11792    return 1;
     11793  if (!strcmp(s, t))
     11794    return 0;
     11795  if (!strncmp(s, "cid:", 4))
     11796    s += 4;
     11797  n = strlen(t);
     11798  if (*t == '<')
     11799  { t++;
     11800    n -= 2;
     11801  }
     11802  if (!strncmp(s, t, n) && !s[n])
     11803    return 0;
     11804  soap_decode(soap->tmpbuf, sizeof(soap->tmpbuf), s, SOAP_STR_EOS);
     11805  if (!strncmp(soap->tmpbuf, t, n) && !soap->tmpbuf[n])
     11806    return 0;
     11807  return 1;
     11808}
     11809#endif
     11810#endif
     11811
     11812/******************************************************************************/
     11813#ifndef WITH_LEANER
     11814#ifndef PALM_1
     11815static void
     11816soap_resolve_attachment(struct soap *soap, struct soap_multipart *content)
     11817{ if (content->id)
     11818  { register struct soap_xlist **xp = &soap->xlist;
     11819    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving attachment data for id=%s\n", content->id));
     11820    while (*xp)
     11821    { register struct soap_xlist *xq = *xp;
     11822      if (!soap_match_cid(soap, xq->id, content->id))
     11823      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Found matching attachment %s for content id=%s\n", xq->id, content->id));
     11824        *xp = xq->next;
     11825        *xq->ptr = (unsigned char*)content->ptr;
     11826        *xq->size = (int)content->size;
     11827        *xq->type = (char*)content->type;
     11828        if (content->options)
     11829          *xq->options = (char*)content->options;
     11830        else
     11831          *xq->options = (char*)content->description;
     11832        SOAP_FREE(soap, xq);
     11833      }
     11834      else
     11835        xp = &(*xp)->next;
     11836    }
     11837  }
    927811838}
    927911839#endif
     
    928811848soap_putmimehdr(struct soap *soap, struct soap_multipart *content)
    928911849{ const char *s;
    9290   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "MIME attachment type=%s\n", content->type?content->type:""));
     11850  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "MIME attachment type=%s\n", content->type?content->type:SOAP_STR_EOS));
    929111851  if (soap_send3(soap, "\r\n--", soap->mime.boundary, "\r\n"))
    929211852    return soap->error;
    929311853  if (content->type && soap_send3(soap, "Content-Type: ", content->type, "\r\n"))
    929411854    return soap->error;
    9295   s = soap_str_code(mime_codes, content->encoding);
     11855  s = soap_code_str(mime_codes, content->encoding);
    929611856  if (s && soap_send3(soap, "Content-Transfer-Encoding: ", s, "\r\n"))
    929711857    return soap->error;
     
    931911879  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Sending MIME attachments\n"));
    932011880  for (content = soap->mime.first; content; content = content->next)
    9321     if (soap_putmimehdr(soap, content)
    9322      || soap_send_raw(soap, content->ptr, content->size))
    9323       return soap->error;
    9324   return soap_send3(soap, "\r\n--", soap->mime.boundary, "--\r\n");
     11881  { void *handle;
     11882    if (soap->fmimereadopen && ((handle = soap->fmimereadopen(soap, (void*)content->ptr, content->id, content->type, content->description)) || soap->error))
     11883    { size_t size = content->size;
     11884      if (!handle)
     11885      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fmimereadopen failed\n"));
     11886        return soap->error;
     11887      }
     11888      if (soap_putmimehdr(soap, content))
     11889        return soap->error;
     11890      if (!size)
     11891      { if ((soap->mode & SOAP_ENC_XML) || (soap->mode & SOAP_IO) == SOAP_IO_CHUNK || (soap->mode & SOAP_IO) == SOAP_IO_STORE)
     11892        { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunked streaming MIME\n"));
     11893          do
     11894          { size = soap->fmimeread(soap, handle, soap->tmpbuf, sizeof(soap->tmpbuf));
     11895            DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fmimeread returned %lu bytes\n", (unsigned long)size));
     11896            if (soap_send_raw(soap, soap->tmpbuf, size))
     11897              break;
     11898          } while (size);
     11899        }
     11900        else
     11901        { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error: cannot chunk streaming MIME (no HTTP chunking)\n"));
     11902        }
     11903      }
     11904      else
     11905      { do
     11906        { size_t bufsize;
     11907          if (size < sizeof(soap->tmpbuf))
     11908            bufsize = size;
     11909          else
     11910            bufsize = sizeof(soap->tmpbuf);
     11911          if (!(bufsize = soap->fmimeread(soap, handle, soap->tmpbuf, bufsize)))
     11912          { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fmimeread failed: insufficient data (%lu bytes remaining from %lu bytes)\n", (unsigned long)size, (unsigned long)content->size));
     11913            soap->error = SOAP_EOF;
     11914            break;
     11915          }
     11916          if (soap_send_raw(soap, soap->tmpbuf, bufsize))
     11917            break;
     11918          size -= bufsize;
     11919        } while (size);
     11920      }
     11921      if (soap->fmimereadclose)
     11922        soap->fmimereadclose(soap, handle);
     11923    }
     11924    else
     11925    { if (soap_putmimehdr(soap, content)
     11926       || soap_send_raw(soap, content->ptr, content->size))
     11927        return soap->error;
     11928    }
     11929  }
     11930  return soap_send3(soap, "\r\n--", soap->mime.boundary, "--");
    932511931}
    932611932#endif
     
    947812084      n = strlen(s);
    947912085    if (n < 16)
    9480     { n = 72;
    9481       s = soap->mime.boundary = (char*)soap_malloc(soap, n);
     12086    { n = 64;
     12087      s = soap->mime.boundary = (char*)soap_malloc(soap, n + 1);
    948212088      if (!s)
    948312089        return;
    948412090    }
    9485     strcpy(s, "<>");
     12091    strcpy(s, "==");
    948612092    s += 2;
    948712093    n -= 4;
    948812094    while (n)
    9489     { *s++ = soap_base64o[rand()&0x3F];
     12095    { *s++ = soap_base64o[soap_random & 0x3F];
    949012096      n--;
    949112097    }
    9492     *s = '\0';
    9493     strcat(s, "<>");
     12098    strcpy(s, "==");
    949412099  }
    949512100  if (!soap->mime.start)
     
    950512110soap_valid_mime_boundary(struct soap *soap)
    950612111{ register struct soap_multipart *content;
    9507   register size_t k = strlen(soap->mime.boundary);
     12112  register size_t k;
     12113  if (soap->fmimeread)
     12114    return SOAP_OK;
     12115  k = strlen(soap->mime.boundary);
    950812116  for (content = soap->mime.first; content; content = content->next)
    950912117  { if (content->ptr && content->size >= k)
     
    951112119      register size_t i;
    951212120      for (i = 0; i < content->size - k; i++, p++)
    9513         if (!strncmp(p, soap->mime.boundary, k))
     12121      { if (!strncmp(p, soap->mime.boundary, k))
    951412122          return SOAP_ERR;
     12123      }
    951512124    }
    951612125  }
     
    952012129#endif
    952112130
    9522 /******************************************************************************/
     12131/******************************************************************************\
     12132 *
     12133 *      HTTP cookie handling
     12134 *
     12135\******************************************************************************/
    952312136
    952412137#ifdef WITH_COOKIES
     
    953112144  register size_t n = len;
    953212145  while ((c = *s++) && --n > 0)
    9533   { if (c > ' ' && c < 128 && c != ';' && c != ',')
     12146  { if (c > ' ' && c < 128 && !strchr("()<>@,;:\\\"/[]?={}", c))
    953412147      *t++ = c;
    953512148    else if (n > 2)
     
    955812171  if (!path)
    955912172    path = soap->cookie_path;
    9560   if (*path == '/')
     12173  if (!path)
     12174    path = SOAP_STR_EOS;
     12175  else if (*path == '/')
    956112176    path++;
    956212177  n = strlen(path);
     12178  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Search cookie %s domain=%s path=%s\n", name, domain?domain:"(null)", path?path:"(null)"));
    956312179  for (p = soap->cookies; p; p = p->next)
     12180  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie in database: %s=%s domain=%s path=%s env=%hd\n", p->name, p->value?p->value:"(null)", p->domain?p->domain:"(null)", p->path?p->path:"(null)", p->env));
    956412181    if (!strcmp(p->name, name)
    9565      && domain
    956612182     && p->domain
     12183     && p->path
    956712184     && !strcmp(p->domain, domain)
    956812185     && !strncmp(p->path, path, n))
    956912186      break;
     12187  }
    957012188  return p;
    957112189}
     
    957812196{ struct soap_cookie **p, *q;
    957912197  int n;
    9580   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set cookie: %s=%s domain=%s path=%s\n", name, value?value:"", domain?domain:"", path?path:""));
    958112198  if (!domain)
    958212199    domain = soap->cookie_domain;
     
    958412201    path = soap->cookie_path;
    958512202  if (!path)
    9586   { soap_set_receiver_error(soap, "Cookie path not set", NULL, SOAP_HTTP_ERROR);
    9587     return NULL;
    9588   }
    9589   if (*path == '/')
     12203    path = SOAP_STR_EOS;
     12204  else if (*path == '/')
    959012205    path++;
    959112206  q = soap_cookie(soap, name, domain, path);
     12207  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set %scookie: %s=%s domain=%s path=%s\n", q ? SOAP_STR_EOS : "new ", name, value?value:"(null)", domain?domain:"(null)", path?path:"(null)"));
    959212208  if (!q)
    9593   { if ((q = (struct soap_cookie*)SOAP_MALLOC(sizeof(struct soap_cookie))))
    9594     { if ((q->name = (char*)SOAP_MALLOC(strlen(name)+1)))
     12209  { if ((q = (struct soap_cookie*)SOAP_MALLOC(soap, sizeof(struct soap_cookie))))
     12210    { if ((q->name = (char*)SOAP_MALLOC(soap, strlen(name)+1)))
    959512211        strcpy(q->name, name);
    959612212      q->value = NULL;
    959712213      q->domain = NULL;
    959812214      q->path = NULL;
    9599       q->expire = -1;
    9600       q->version = 0;
     12215      q->expire = 0;
     12216      q->maxage = -1;
     12217      q->version = 1;
    960112218      q->secure = 0;
    9602       q->env = 0;
    960312219      q->modified = 0;
    960412220      for (p = &soap->cookies, n = soap->cookie_max; *p && n; p = &(*p)->next, n--)
    9605         if (!strcmp((*p)->name, name) && (*p)->path && strcmp((*p)->path, path) < 0)
     12221        if (!strcmp((*p)->name, name) && (*p)->path && path && strcmp((*p)->path, path) < 0)
    960612222          break;
    960712223      if (n)
     
    961012226      }
    961112227      else
    9612       { SOAP_FREE(q->name);
    9613         SOAP_FREE(q);
     12228      { SOAP_FREE(soap, q->name);
     12229        SOAP_FREE(soap, q);
    961412230        q = NULL;
    961512231      }
     
    962012236  if (q)
    962112237  { if (q->value)
    9622     { SOAP_FREE(q->value);
     12238    { SOAP_FREE(soap, q->value);
    962312239      q->value = NULL;
    962412240    }
    962512241    if (q->domain)
    9626     { SOAP_FREE(q->domain);
     12242    { SOAP_FREE(soap, q->domain);
    962712243      q->domain = NULL;
    962812244    }
    962912245    if (q->path)
    9630     { SOAP_FREE(q->path);
     12246    { SOAP_FREE(soap, q->path);
    963112247      q->path = NULL;
    963212248    }
    9633     if (value && *value && (q->value = (char*)SOAP_MALLOC(strlen(value)+1)))
     12249    if (value && *value && (q->value = (char*)SOAP_MALLOC(soap, strlen(value)+1)))
    963412250      strcpy(q->value, value);
    9635     if (domain && *domain && (q->domain = (char*)SOAP_MALLOC(strlen(domain)+1)))
     12251    if (domain && (q->domain = (char*)SOAP_MALLOC(soap, strlen(domain)+1)))
    963612252      strcpy(q->domain, domain);
    9637     if (path && *path && (q->path = (char*)SOAP_MALLOC(strlen(path)+1)))
     12253    if (path && (q->path = (char*)SOAP_MALLOC(soap, strlen(path)+1)))
    963812254      strcpy(q->path, path);
    963912255    q->session = 1;
     12256    q->env = 0;
    964012257  }
    964112258  return q;
     
    965112268    domain = soap->cookie_domain;
    965212269  if (!domain)
    9653   { soap_set_receiver_error(soap, "Cookie domain not set", SOAP_STR_EOS, SOAP_HTTP_ERROR);
     12270  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error in clear cookie %s: cookie domain not set\n", name?name:"(null)"));
    965412271    return;
    965512272  }
     
    965712274    path = soap->cookie_path;
    965812275  if (!path)
    9659   { soap_set_receiver_error(soap, "Cookie path not set", SOAP_STR_EOS, SOAP_HTTP_ERROR);
     12276  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error in clear cookie %s: cookie path not set\n", name?name:"(null)"));
    966012277    return;
    966112278  }
     
    966312280    path++;
    966412281  for (p = &soap->cookies, q = *p; q; q = *p)
    9665     if (!strcmp(q->name, name) && !strcmp(q->domain, domain) && !strncmp(q->path, path, strlen(q->path)))
     12282  { if (!strcmp(q->name, name) && !strcmp(q->domain, domain) && !strncmp(q->path, path, strlen(q->path)))
    966612283    { if (q->value)
    9667         SOAP_FREE(q->value);
     12284        SOAP_FREE(soap, q->value);
    966812285      if (q->domain)
    9669         SOAP_FREE(q->domain);
     12286        SOAP_FREE(soap, q->domain);
    967012287      if (q->path)
    9671         SOAP_FREE(q->path);
     12288        SOAP_FREE(soap, q->path);
    967212289      *p = q->next;
    9673       SOAP_FREE(q);
     12290      SOAP_FREE(soap, q);
    967412291    }
    967512292    else
    967612293      p = &q->next;
     12294  }
    967712295}
    967812296
     
    969012308/******************************************************************************/
    969112309SOAP_FMAC1
    9692 long
     12310char *
     12311SOAP_FMAC2
     12312soap_env_cookie_value(struct soap *soap, const char *name, const char *domain, const char *path)
     12313{ struct soap_cookie *p;
     12314  if ((p = soap_cookie(soap, name, domain, path)) && p->env)
     12315    return p->value;
     12316  return NULL;
     12317}
     12318
     12319/******************************************************************************/
     12320SOAP_FMAC1
     12321time_t
    969312322SOAP_FMAC2
    969412323soap_cookie_expire(struct soap *soap, const char *name, const char *domain, const char *path)
     
    970512334soap_set_cookie_expire(struct soap *soap, const char *name, long expire, const char *domain, const char *path)
    970612335{ struct soap_cookie *p;
     12336  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set cookie expiration max-age %ld: %s domain=%s path=%s\n", expire, name, domain?domain:"(null)", path?path:"(null)"));
    970712337  if ((p = soap_cookie(soap, name, domain, path)))
    9708   { p->expire = expire;
     12338  { p->maxage = expire;
    970912339    p->modified = 1;
    971012340    return SOAP_OK;
     
    975012380  const char *t;
    975112381  for (p = soap->cookies; p; p = p->next)
    9752   { if (p->modified || !p->env)
     12382  {
     12383    if (p->modified
     12384#ifdef WITH_OPENSSL
     12385     || (!p->env && !soap->ssl == !p->secure)
     12386#endif
     12387       )
    975312388    { s = tmp;
    975412389      if (p->name)
     
    975912394      }
    976012395      if (p->domain && (int)strlen(p->domain) < tmp-s+4064)
    9761         sprintf(s, ";Domain=%s", p->domain);
     12396      { strcpy(s, ";Domain=");
     12397        strcat(s, p->domain);
     12398      }
    976212399      else if (soap->cookie_domain && (int)strlen(soap->cookie_domain) < tmp-s+4064)
    9763         sprintf(s, ";Domain=%s", soap->cookie_domain);
     12400      { strcpy(s, ";Domain=");
     12401        strcat(s, soap->cookie_domain);
     12402      }
    976412403      strcat(s, ";Path=/");
     12404      s += strlen(s);
    976512405      if (p->path)
    976612406        t = p->path;
     
    977112411          t++;
    977212412        if ((int)strlen(t) < tmp-s+4064)
    9773           strcat(s, t);
    9774       }
    9775       s += strlen(s);
    9776       if (p->version > 0)
    9777         sprintf(s, ";Version=%u", p->version);
    9778       if (p->expire >= 0)
    9779         sprintf(s, ";Max-Age=%ld", p->expire);
    9780       if (p->secure)
    9781         strcat(s, ";Secure");
     12413        { if (strchr(t, '%'))   /* already URL encoded? */
     12414          { strcpy(s, t);
     12415            s += strlen(s);
     12416          }
     12417          else
     12418            s += soap_encode_cookie(t, s, tmp-s+4064);
     12419        }
     12420      }
     12421      if (p->version > 0 && s-tmp < 4060)
     12422      { sprintf(s, ";Version=%u", p->version);
     12423        s += strlen(s);
     12424      }
     12425      if (p->maxage >= 0 && s-tmp < 4060)
     12426      { sprintf(s, ";Max-Age=%ld", p->maxage);
     12427        s += strlen(s);
     12428      }
     12429      if (s-tmp < 4073
     12430       && (p->secure
     12431#ifdef WITH_OPENSSL
     12432       || soap->ssl
     12433#endif
     12434         ))
     12435        strcpy(s, ";Secure");
    978212436      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set-Cookie: %s\n", tmp));
    9783       if (soap->fposthdr(soap, "Set-Cookie", tmp))
     12437      if ((soap->error = soap->fposthdr(soap, "Set-Cookie", tmp)))
    978412438        return soap->error;
    978512439    }
     
    979812452  char *s, tmp[4096];
    979912453  p = &soap->cookies;
     12454  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Sending cookies for domain=%s path=%s\n", domain, path));
     12455  if (*path == '/')
     12456    path++;
    980012457  while ((q = *p))
    980112458  { if (q->expire && now > q->expire)
    980212459    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie %s expired\n", q->name));
    9803       SOAP_FREE(q->name);
     12460      SOAP_FREE(soap, q->name);
    980412461      if (q->value)
    9805         SOAP_FREE(q->value);
     12462        SOAP_FREE(soap, q->value);
    980612463      if (q->domain)
    9807         SOAP_FREE(q->domain);
     12464        SOAP_FREE(soap, q->domain);
    980812465      if (q->path)
    9809         SOAP_FREE(q->path);
     12466        SOAP_FREE(soap, q->path);
    981012467      *p = q->next;
    9811       SOAP_FREE(q);
    9812     }
    9813     else if ((!q->domain || !strcmp(q->domain, domain))
     12468      SOAP_FREE(soap, q);
     12469    }
     12470    else
     12471    { int flag;
     12472      char *t = q->domain;
     12473      size_t n = 0;
     12474      if (!t)
     12475        flag = 1;
     12476      else
     12477      { const char *r = strchr(t, ':');
     12478        if (r)
     12479          n = r - t;
     12480        else
     12481          n = strlen(t);
     12482        flag = !strncmp(t, domain, n);
     12483      }
     12484      /* domain-level cookies, cannot compile when WITH_NOIO set */
     12485#ifndef WITH_NOIO
     12486      if (!flag)
     12487      { struct hostent *hostent = gethostbyname((char*)domain);
     12488        if (hostent)
     12489        { const char *r = strchr(hostent->h_name, '.');
     12490          if (!r)
     12491            r = hostent->h_name;
     12492          flag = !strncmp(t, r, n);
     12493        }
     12494      }
     12495#endif
     12496      if (flag
    981412497          && (!q->path || !strncmp(q->path, path, strlen(q->path)))
    981512498          && (!q->secure || secure))
    9816     { s = tmp;
    9817       if (q->version != version)
    9818       { sprintf(s, "$Version=%u;", q->version);
    9819         version = q->version;
    9820       }
    9821       if (q->name)
    9822         s += soap_encode_cookie(q->name, s, tmp-s+4080);
    9823       if (q->value && *q->value)
    9824       { *s++ = '=';
    9825         s += soap_encode_cookie(q->value, s, tmp-s+4080);
    9826       }
    9827       if (q->path && (int)strlen(q->path) < tmp-s+4080)
    9828       { sprintf(s, ";$Path=/%s", q->path);
    9829         s += strlen(s);
    9830       }
    9831       if (q->domain && (int)strlen(q->domain) < tmp-s+4080)
    9832         sprintf(s, ";$Domain=%s", q->domain);
    9833       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie: %s\n", tmp));
    9834       if (soap->fposthdr(soap, "Cookie", tmp))
    9835         return soap->error;
     12499      { s = tmp;
     12500        if (q->version != version)
     12501        { sprintf(s, "$Version=%u;", q->version);
     12502          version = q->version;
     12503        }
     12504        if (q->name)
     12505          s += soap_encode_cookie(q->name, s, tmp-s+4080);
     12506        if (q->value && *q->value)
     12507        { *s++ = '=';
     12508          s += soap_encode_cookie(q->value, s, tmp-s+4080);
     12509        }
     12510        if (q->path && *q->path && (int)strlen(q->path) < tmp-s+4080)
     12511        { sprintf(s, ";$Path=\"/%s\"", (*q->path == '/' ? q->path + 1 : q->path));
     12512          s += strlen(s);
     12513        }
     12514        if (q->domain && (int)strlen(q->domain) < tmp-s+4080)
     12515          sprintf(s, ";$Domain=\"%s\"", q->domain);
     12516        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie: %s\n", tmp));
     12517        if ((soap->error = soap->fposthdr(soap, "Cookie", tmp)))
     12518          return soap->error;
     12519      }
    983612520      p = &q->next;
    983712521    }
    9838     else
    9839       p = &q->next;
    984012522  }
    984112523  return SOAP_OK;
     
    987012552    { s = soap_decode_val(tmp, sizeof(tmp), s);
    987112553      if (*tmp)
    9872       { if ((t = (char*)SOAP_MALLOC(strlen(tmp)+1)))
     12554      { if ((t = (char*)SOAP_MALLOC(soap, strlen(tmp)+1)))
    987312555          strcpy(t, tmp);
    987412556      }
     
    987712559      if (p)
    987812560      { if (p->path)
    9879           SOAP_FREE(p->path);
     12561          SOAP_FREE(soap, p->path);
    988012562        p->path = t;
    988112563      }
    988212564      else
    988312565      { if (path)
    9884           SOAP_FREE(path);
     12566          SOAP_FREE(soap, path);
    988512567        path = t;
    988612568      }
     
    988912571    { s = soap_decode_val(tmp, sizeof(tmp), s);
    989012572      if (*tmp)
    9891       { if ((t = (char*)SOAP_MALLOC(strlen(tmp)+1)))
     12573      { if ((t = (char*)SOAP_MALLOC(soap, strlen(tmp)+1)))
    989212574          strcpy(t, tmp);
    989312575      }
     
    989612578      if (p)
    989712579      { if (p->domain)
    9898           SOAP_FREE(p->domain);
    9899         p->domain = t;
     12580          SOAP_FREE(soap, p->domain);
     12581        p->domain = t;
    990012582      }
    990112583      else
    990212584      { if (domain)
    9903           SOAP_FREE(domain);
     12585          SOAP_FREE(soap, domain);
    990412586        domain = t;
    990512587      }
     
    990712589    else if (p && !soap_tag_cmp(tmp, "Path"))
    990812590    { if (p->path)
    9909         SOAP_FREE(p->path);
     12591        SOAP_FREE(soap, p->path);
    991012592      s = soap_decode_val(tmp, sizeof(tmp), s);
    991112593      if (*tmp)
    9912       { if ((p->path = (char*)SOAP_MALLOC(strlen(tmp)+1)))
     12594      { if ((p->path = (char*)SOAP_MALLOC(soap, strlen(tmp)+1)))
    991312595          strcpy(p->path, tmp);
    991412596      }
     
    991812600    else if (p && !soap_tag_cmp(tmp, "Domain"))
    991912601    { if (p->domain)
    9920         SOAP_FREE(p->domain);
     12602        SOAP_FREE(soap, p->domain);
    992112603      s = soap_decode_val(tmp, sizeof(tmp), s);
    992212604      if (*tmp)
    9923       { if ((p->domain = (char*)SOAP_MALLOC(strlen(tmp)+1)))
     12605      { if ((p->domain = (char*)SOAP_MALLOC(soap, strlen(tmp)+1)))
    992412606          strcpy(p->domain, tmp);
    992512607      }
     
    994812630        a[0] = tmp[8];
    994912631        a[1] = tmp[9];
    9950         T.tm_mon = (strstr(mns, a) - mns) / 2;
     12632        T.tm_mon = (int)(strstr(mns, a) - mns) / 2;
    995112633        a[0] = tmp[11];
    995212634        a[1] = tmp[12];
     
    996812650    else
    996912651    { if (p)
    9970       { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Got environment cookie %s=%s domain=%s path=%s expire=%ld secure=%d\n", p->name, p->value?p->value:"", p->domain?p->domain:"", p->path?p->path:"", p->expire, p->secure));
     12652      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Got environment cookie %s=%s domain=%s path=%s expire=%ld secure=%d\n", p->name, p->value?p->value:"(null)", p->domain?p->domain:"(null)", p->path?p->path:"(null)", p->expire, p->secure));
    997112653        if ((q = soap_set_cookie(soap, p->name, p->value, p->domain, p->path)))
    997212654        { q->version = p->version;
     
    997612658        }
    997712659        if (p->name)
    9978           SOAP_FREE(p->name);
     12660          SOAP_FREE(soap, p->name);
    997912661        if (p->value)
    9980           SOAP_FREE(p->value);
     12662          SOAP_FREE(soap, p->value);
    998112663        if (p->domain)
    9982           SOAP_FREE(p->domain);
     12664          SOAP_FREE(soap, p->domain);
    998312665        if (p->path)
    9984           SOAP_FREE(p->path);
    9985         SOAP_FREE(p);
    9986       }
    9987       if ((p = (struct soap_cookie*)SOAP_MALLOC(sizeof(struct soap_cookie))))
    9988       { p->name = (char*)SOAP_MALLOC(strlen(tmp)+1);
     12666          SOAP_FREE(soap, p->path);
     12667        SOAP_FREE(soap, p);
     12668      }
     12669      if ((p = (struct soap_cookie*)SOAP_MALLOC(soap, sizeof(struct soap_cookie))))
     12670      { p->name = (char*)SOAP_MALLOC(soap, strlen(tmp)+1);
    998912671        strcpy(p->name, tmp);
    999012672        s = soap_decode_val(tmp, sizeof(tmp), s);
    999112673        if (*tmp)
    9992         { p->value = (char*)SOAP_MALLOC(strlen(tmp)+1);
     12674        { p->value = (char*)SOAP_MALLOC(soap, strlen(tmp)+1);
    999312675          strcpy(p->value, tmp);
    999412676        }
    999512677        else
    999612678          p->value = NULL;
    9997         p->domain = domain;
    9998         p->path = path;
     12679        if (domain)
     12680          p->domain = domain;
     12681        else if (*soap->host)
     12682        { p->domain = (char*)SOAP_MALLOC(soap, strlen(soap->host)+1);
     12683          strcpy(p->domain, soap->host);
     12684        }
     12685        else
     12686          p->domain = NULL;
     12687        if (path)
     12688          p->path = path;
     12689        else if (soap->path && *soap->path)
     12690        { p->path = (char*)SOAP_MALLOC(soap, strlen(soap->path)+1);
     12691          strcpy(p->path, soap->path);
     12692        }
     12693        else
     12694        { p->path = (char*)SOAP_MALLOC(soap, 2);
     12695          strcpy(p->path, "/");
     12696        }
    999912697        p->expire = 0;
    1000012698        p->secure = 0;
     
    1000412702  }
    1000512703  if (p)
    10006   { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Got cookie %s=%s domain=%s path=%s expire=%ld secure=%d\n", p->name, p->value?p->value:"", p->domain?p->domain:"", p->path?p->path:"", p->expire, p->secure));
     12704  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Got environment cookie %s=%s domain=%s path=%s expire=%ld secure=%d\n", p->name, p->value?p->value:"(null)", p->domain?p->domain:"(null)", p->path?p->path:"(null)", p->expire, p->secure));
    1000712705    if ((q = soap_set_cookie(soap, p->name, p->value, p->domain, p->path)))
    1000812706    { q->version = p->version;
    1000912707      q->expire = p->expire;
    1001012708      q->secure = p->secure;
     12709      q->env = 1;
    1001112710    }
    1001212711    if (p->name)
    10013       SOAP_FREE(p->name);
     12712      SOAP_FREE(soap, p->name);
    1001412713    if (p->value)
    10015       SOAP_FREE(p->value);
     12714      SOAP_FREE(soap, p->value);
    1001612715    if (p->domain)
    10017       SOAP_FREE(p->domain);
     12716      SOAP_FREE(soap, p->domain);
    1001812717    if (p->path)
    10019       SOAP_FREE(p->path);
    10020     SOAP_FREE(p);
     12718      SOAP_FREE(soap, p->path);
     12719    SOAP_FREE(soap, p);
    1002112720  }
    1002212721  if (domain)
    10023     SOAP_FREE(domain);
     12722    SOAP_FREE(soap, domain);
    1002412723  if (path)
    10025     SOAP_FREE(path);
     12724    SOAP_FREE(soap, path);
    1002612725}
    1002712726
     
    1005012749struct soap_cookie*
    1005112750SOAP_FMAC2
    10052 soap_copy_cookies(struct soap *soap)
     12751soap_copy_cookies(struct soap *copy, const struct soap *soap)
    1005312752{ struct soap_cookie *p, **q, *r;
    1005412753  q = &r;
    1005512754  for (p = soap->cookies; p; p = p->next)
    10056   { if (!(*q = (struct soap_cookie*)SOAP_MALLOC(sizeof(struct soap_cookie))))
     12755  { if (!(*q = (struct soap_cookie*)SOAP_MALLOC(copy, sizeof(struct soap_cookie))))
    1005712756      return r;
    1005812757    **q = *p;
    1005912758    if (p->name)
    10060     { if (((*q)->name = (char*)SOAP_MALLOC(strlen(p->name)+1)))
     12759    { if (((*q)->name = (char*)SOAP_MALLOC(copy, strlen(p->name)+1)))
    1006112760        strcpy((*q)->name, p->name);
    1006212761    }
    1006312762    if (p->value)
    10064     { if (((*q)->value = (char*)SOAP_MALLOC(strlen(p->value)+1)))
     12763    { if (((*q)->value = (char*)SOAP_MALLOC(copy, strlen(p->value)+1)))
    1006512764        strcpy((*q)->value, p->value);
    1006612765    }
    1006712766    if (p->domain)
    10068     { if (((*q)->domain = (char*)SOAP_MALLOC(strlen(p->domain)+1)))
     12767    { if (((*q)->domain = (char*)SOAP_MALLOC(copy, strlen(p->domain)+1)))
    1006912768        strcpy((*q)->domain, p->domain);
    1007012769    }
    1007112770    if (p->path)
    10072     { if (((*q)->path = (char*)SOAP_MALLOC(strlen(p->path)+1)))
     12771    { if (((*q)->path = (char*)SOAP_MALLOC(copy, strlen(p->path)+1)))
    1007312772        strcpy((*q)->path, p->path);
    1007412773    }
     
    1008712786  for (p = soap->cookies; p; p = soap->cookies)
    1008812787  { soap->cookies = p->next;
    10089     SOAP_FREE(p->name);
     12788    SOAP_FREE(soap, p->name);
    1009012789    if (p->value)
    10091       SOAP_FREE(p->value);
     12790      SOAP_FREE(soap, p->value);
    1009212791    if (p->domain)
    10093       SOAP_FREE(p->domain);
     12792      SOAP_FREE(soap, p->domain);
    1009412793    if (p->path)
    10095       SOAP_FREE(p->path);
    10096     SOAP_FREE(p);
     12794      SOAP_FREE(soap, p->path);
     12795    SOAP_FREE(soap, p);
    1009712796  }
    1009812797}
     
    1010712806soap_getgziphdr(struct soap *soap)
    1010812807{ int i;
    10109   soap_wchar c, f = 0;
     12808  soap_wchar c = 0, f = 0;
    1011012809  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get gzip header\n"));
    1011112810  for (i = 0; i < 9; i++)
     
    1011712816  if (f & 0x04) /* FEXTRA */
    1011812817  { for (i = soap_get1(soap) | (soap_get1(soap) << 8); i; i--)
    10119       if ((int)soap_get1(soap) == EOF)
     12818    { if ((int)soap_get1(soap) == EOF)
    1012012819        return soap->error = SOAP_EOF;
     12820    }
    1012112821  }
    1012212822  if (f & 0x08) /* FNAME */
    10123     do
     12823  { do
    1012412824      c = soap_get1(soap);
    1012512825    while (c && (int)c != EOF);
     12826  }
    1012612827  if ((int)c != EOF && (f & 0x10)) /* FCOMMENT */
    10127     do
     12828  { do
    1012812829      c = soap_get1(soap);
    10129     while (c && (int)f != EOF);
     12830    while (c && (int)c != EOF);
     12831  }
    1013012832  if ((int)c != EOF && (f & 0x01)) /* FHCRC */
    1013112833  { if ((int)(c = soap_get1(soap)) != EOF)
     
    1014612848soap_begin_recv(struct soap *soap)
    1014712849{ soap_wchar c;
     12850  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing for input\n"));
    1014812851  soap->error = SOAP_OK;
    10149   soap_free(soap);
     12852  soap_free_temp(soap);
    1015012853  soap_set_local_namespaces(soap);
    1015112854  soap->version = 0;    /* don't assume we're parsing SOAP content by default */
     12855#ifndef WITH_NOIDREF
    1015212856  soap_free_iht(soap);
     12857#endif
    1015312858  if ((soap->imode & SOAP_IO) == SOAP_IO_CHUNK)
    1015412859    soap->omode |= SOAP_IO_CHUNK;
     
    1017012875  soap->cdata = 0;
    1017112876  *soap->endpoint = '\0';
    10172   soap->userid = NULL;
    10173   soap->passwd = NULL;
    1017412877  soap->action = NULL;
    10175   soap->authrealm = NULL;
     12878  soap->header = NULL;
     12879  soap->fault = NULL;
     12880  soap->status = 0;
     12881#ifndef WITH_LEANER
     12882  soap->dom = NULL;
    1017612883  soap->dime.chunksize = 0;
    1017712884  soap->dime.buflen = 0;
     
    1018412891  soap->mime.boundary = NULL;
    1018512892  soap->mime.start = NULL;
     12893  soap->xlist = NULL;
     12894#endif
    1018612895#ifdef WIN32
    1018712896#ifndef UNDER_CE
     
    1018912898  if (!soap_valid_socket(soap->socket))
    1019012899#ifdef __BORLANDC__
    10191     setmode((SOAP_SOCKET)soap->recvfd, O_BINARY);
     12900    setmode(soap->recvfd, O_BINARY);
    1019212901#else
    10193     _setmode((SOAP_SOCKET)soap->recvfd, _O_BINARY);
     12902    _setmode(soap->recvfd, _O_BINARY);
    1019412903#endif
    1019512904#endif
     
    1020012909  soap->zlib_in = SOAP_ZLIB_NONE;
    1020112910  soap->zlib_out = SOAP_ZLIB_NONE;
    10202   soap->d_stream.next_in = Z_NULL;
    10203   soap->d_stream.avail_in = 0;
    10204   soap->d_stream.next_out = (Byte*)soap->buf;
    10205   soap->d_stream.avail_out = SOAP_BUFLEN;
     12911  soap->d_stream->next_in = Z_NULL;
     12912  soap->d_stream->avail_in = 0;
     12913  soap->d_stream->next_out = (Byte*)soap->buf;
     12914  soap->d_stream->avail_out = SOAP_BUFLEN;
    1020612915  soap->z_ratio_in = 1.0;
     12916#endif
     12917#ifdef WITH_OPENSSL
     12918  if (soap->ssl)
     12919    ERR_clear_error();
     12920#endif
     12921#ifndef WITH_LEANER
    1020712922  if (soap->fprepareinit)
    1020812923    soap->fprepareinit(soap);
     
    1021312928  { if (soap_getgziphdr(soap))
    1021412929      return soap->error;
    10215     if (inflateInit2(&soap->d_stream, -MAX_WBITS) != Z_OK)
     12930    if (inflateInit2(soap->d_stream, -MAX_WBITS) != Z_OK)
    1021612931      return soap->error = SOAP_ZLIB_ERROR;
    1021712932    soap->zlib_state = SOAP_ZLIB_INFLATE;
     
    1022012935    soap->z_crc = crc32(0L, NULL, 0);
    1022112936    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip initialized\n"));
     12937    if (!soap->z_buf)
     12938      soap->z_buf = (char*)SOAP_MALLOC(soap, SOAP_BUFLEN);
    1022212939    memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN);
    1022312940    /* should not chunk over plain transport, so why bother to check? */
     
    1022512942    /*   soap->z_buflen = soap->bufidx; */
    1022612943    /* else */
    10227     soap->d_stream.next_in = (Byte*)(soap->z_buf + soap->bufidx);
    10228     soap->d_stream.avail_in = soap->buflen - soap->bufidx;
     12944    soap->d_stream->next_in = (Byte*)(soap->z_buf + soap->bufidx);
     12945    soap->d_stream->avail_in = soap->buflen - soap->bufidx;
    1022912946    soap->z_buflen = soap->buflen;
    1023012947    soap->buflen = soap->bufidx;
     
    1023212949  } 
    1023312950#endif
     12951#ifndef WITH_LEANER
    1023412952  if (c == '-' && soap_get0(soap) == '-')
    1023512953    soap->mode |= SOAP_ENC_MIME;
     
    1023712955    soap->mode |= SOAP_ENC_DIME;
    1023812956  else
     12957#endif
    1023912958  { while (soap_blank(c))
    1024012959      c = soap_getchar(soap);
     
    1024312962    return soap->error = SOAP_EOF;
    1024412963  soap_unget(soap, c);
    10245   if (c != '<' && !(soap->mode & (SOAP_ENC_DIME | SOAP_ENC_ZLIB)))
     12964#ifndef WITH_NOHTTP
     12965  /* if not XML or (start of)BOM or MIME/DIME/ZLIB, assume HTTP header */
     12966  if (c != '<' && c != 0xEF && !(soap->mode & (SOAP_ENC_MIME | SOAP_ENC_DIME | SOAP_ENC_ZLIB)))
    1024612967  { soap->mode &= ~SOAP_IO;
    10247     if ((soap->error = soap->fparse(soap)))
     12968    soap->error = soap->fparse(soap);
     12969    if (soap->error && soap->error < SOAP_STOP)
    1024812970    { soap->keep_alive = 0; /* force close later */
    1024912971      return soap->error;
    1025012972    }
     12973    if (soap->error == SOAP_STOP)
     12974      return soap->error;
     12975    soap->mode = soap->imode; /* if imode is changed, copy */
    1025112976    if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK)
    1025212977    { soap->chunkbuflen = soap->buflen;
     
    1025412979      soap->chunksize = 0;
    1025512980    }
     12981#ifndef WITH_LEANER
    1025612982    else if (soap->fpreparerecv && soap->buflen != soap->bufidx)
    1025712983      soap->fpreparerecv(soap, soap->buf + soap->bufidx, soap->buflen - soap->bufidx);
     12984#endif
     12985    /* Note: fparse should not use soap_unget to push back last char */
     12986    if (soap_get0(soap) == (int)EOF)
     12987    { if (soap->status == 200)
     12988        return soap->error = SOAP_NO_DATA;
     12989      return soap->error = soap->status;
     12990    }
    1025812991#ifdef WITH_ZLIB
    10259     if (soap->zlib_in)
    10260     { /* fparse should not use soap_unget to push back last char */
     12992    if (soap->zlib_in != SOAP_ZLIB_NONE)
     12993    {
    1026112994#ifdef WITH_GZIP
    10262       c = soap_get1(soap);
    10263       if (c == 0x1F)
    10264       { if (soap_getgziphdr(soap))
    10265           return soap->error;
    10266         if (inflateInit2(&soap->d_stream, -MAX_WBITS) != Z_OK)
    10267           return soap->error = SOAP_ZLIB_ERROR;
    10268         soap->zlib_state = SOAP_ZLIB_INFLATE;
    10269         soap->z_crc = crc32(0L, NULL, 0);
    10270         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip initialized\n"));
     12995      if (soap->zlib_in != SOAP_ZLIB_DEFLATE)
     12996      { c = soap_get1(soap);
     12997        if (c == 0x1F)
     12998        { if (soap_getgziphdr(soap))
     12999            return soap->error;
     13000          if (inflateInit2(soap->d_stream, -MAX_WBITS) != Z_OK)
     13001            return soap->error = SOAP_ZLIB_ERROR;
     13002          soap->z_crc = crc32(0L, NULL, 0);
     13003          DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip initialized\n"));
     13004        }
     13005        else
     13006        { soap_revget1(soap);
     13007          if (inflateInit(soap->d_stream) != Z_OK)
     13008            return soap->error = SOAP_ZLIB_ERROR;
     13009          soap->zlib_in = SOAP_ZLIB_DEFLATE;
     13010        }
    1027113011      }
    1027213012      else
    10273       { soap_revget1(soap);
    10274 #else
    10275       {
    10276 #endif
    10277         if (inflateInit(&soap->d_stream) != Z_OK)
    10278           return soap->error = SOAP_ZLIB_ERROR;
    10279         soap->zlib_state = SOAP_ZLIB_INFLATE;
    10280         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflate initialized\n"));
    10281       }
     13013#endif
     13014      if (inflateInit(soap->d_stream) != Z_OK)
     13015        return soap->error = SOAP_ZLIB_ERROR;
     13016      soap->zlib_state = SOAP_ZLIB_INFLATE;
     13017      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflate initialized\n"));
    1028213018      soap->mode |= SOAP_ENC_ZLIB;
     13019      if (!soap->z_buf)
     13020        soap->z_buf = (char*)SOAP_MALLOC(soap, SOAP_BUFLEN);
    1028313021      memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN);
    10284       soap->d_stream.next_in = (Byte*)(soap->z_buf + soap->bufidx);
    10285       soap->d_stream.avail_in = soap->buflen - soap->bufidx;
     13022      soap->d_stream->next_in = (Byte*)(soap->z_buf + soap->bufidx);
     13023      soap->d_stream->avail_in = soap->buflen - soap->bufidx;
    1028613024      soap->z_buflen = soap->buflen;
    1028713025      soap->buflen = soap->bufidx;
    1028813026    }
    1028913027#endif
    10290   }
     13028    if (soap->error)
     13029    { if (soap->error == SOAP_FORM && soap->fform)
     13030      { soap->error = soap->fform(soap);
     13031        if (soap->error == SOAP_OK)
     13032          soap->error = SOAP_STOP; /* prevents further processing */
     13033      }
     13034      return soap->error;
     13035    }
     13036  }
     13037#endif
    1029113038#ifndef WITH_LEANER
    1029213039  if (soap->mode & SOAP_ENC_MIME)
    1029313040  { if (soap_getmimehdr(soap))
    1029413041      return soap->error;
     13042    if (soap->mime.start)
     13043    { do
     13044      { if (!soap->mime.last->id)
     13045          break;
     13046        if (!soap_match_cid(soap, soap->mime.start, soap->mime.last->id))
     13047          break;
     13048      } while (soap_get_mime_attachment(soap, NULL));
     13049    }
    1029513050    if (soap_get_header_attribute(soap, soap->mime.first->type, "application/dime"))
    1029613051      soap->mode |= SOAP_ENC_DIME;
     
    1031713072
    1031813073/******************************************************************************/
     13074#ifndef WITH_NOHTTP
    1031913075#ifndef PALM_1
    1032013076static int
    1032113077http_parse(struct soap *soap)
    1032213078{ char header[SOAP_HDRLEN], *s;
    10323   unsigned short g = 0, k;
    10324   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Waiting for response...\n"));
     13079  unsigned short httpcmd = 0, status = 0, k = 0;
     13080  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Waiting for HTTP request/response...\n"));
    1032513081  *soap->endpoint = '\0';
    1032613082  soap->length = 0;
     13083  soap->userid = NULL;
     13084  soap->passwd = NULL;
     13085  soap->action = NULL;
     13086  soap->authrealm = NULL;
     13087  soap->proxy_from = NULL;
     13088  soap->http_content = NULL;
     13089  soap->status = 0;
    1032713090  do
    1032813091  { if (soap_getline(soap, soap->msgbuf, sizeof(soap->msgbuf)))
    10329       return soap->error;
     13092    { if (soap->error == SOAP_EOF)
     13093        return SOAP_EOF;
     13094      return soap->error = 414;
     13095    }
    1033013096    DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP status: %s\n", soap->msgbuf));
    1033113097    for (;;)
    1033213098    { if (soap_getline(soap, header, SOAP_HDRLEN))
     13099      { if (soap->error == SOAP_EOF)
     13100        { soap->error = SOAP_OK;
     13101          DBGLOG(TEST,SOAP_MESSAGE(fdebug, "EOF in HTTP header, continue anyway\n"));
     13102          break;
     13103        }
    1033313104        return soap->error;
     13105      }
    1033413106      if (!*header)
    1033513107        break;
     
    1033713109      s = strchr(header, ':');
    1033813110      if (s)
    10339       { *s = '\0';
     13111      { char *t;
     13112        *s = '\0';
    1034013113        do s++;
    1034113114        while (*s && *s <= 32);
     13115        if (*s == '"')
     13116          s++;
     13117        t = s + strlen(s) - 1;
     13118        while (t > s && *t <= 32)
     13119          t--;
     13120        if (t >= s && *t == '"')
     13121          t--;
     13122        t[1] = '\0';
    1034213123        if ((soap->error = soap->fparsehdr(soap, header, s)))
    10343           return soap->error;
     13124        { if (soap->error < SOAP_STOP)
     13125            return soap->error;
     13126          status = soap->error;
     13127          soap->error = SOAP_OK;
     13128        }
    1034413129      }
    1034513130    }
    1034613131    if ((s = strchr(soap->msgbuf, ' ')))
    10347       k = (unsigned short)soap_strtoul(s, NULL, 10);
     13132    { k = (unsigned short)soap_strtoul(s, &s, 10);
     13133      if (!soap_blank(*s))
     13134        k = 0;
     13135    }
    1034813136    else
    1034913137      k = 0;
    1035013138  } while (k == 100);
    10351   DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Finished HTTP header parsing\n"));
     13139  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Finished HTTP header parsing, status = %d\n", k));
    1035213140  s = strstr(soap->msgbuf, "HTTP/");
    1035313141  if (s && s[7] != '1')
     
    1036213150    soap->keep_alive = 1;
    1036313151  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Keep alive connection = %d\n", soap->keep_alive));
    10364   if (s && (((g = !strncmp(soap->msgbuf, "GET ", 4))) || !strncmp(soap->msgbuf, "POST ", 5)))
    10365   { size_t m = strlen(soap->endpoint);
    10366     size_t n = m + (s - soap->msgbuf) - 5 - (!g);
    10367     if (n >= sizeof(soap->endpoint))
    10368       n = sizeof(soap->endpoint) - 1;
    10369     strncpy(soap->path, soap->msgbuf + 4 + (!g), n - m);
    10370     soap->path[n - m] = '\0';
    10371     strcat(soap->endpoint, soap->path);
    10372     DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Target endpoint='%s'\n", soap->endpoint));
    10373     if (g)
    10374     { soap->error = soap->fget(soap);
    10375       if (soap->error == SOAP_OK)
    10376         soap->error = SOAP_STOP; /* prevents further processing */
    10377       return soap->error;
    10378     }
     13152  if (k == 0)
     13153  { size_t l = 0;
     13154    if (s)
     13155    { if (!strncmp(soap->msgbuf, "POST ", l = 5))
     13156        httpcmd = 1;
     13157      else if (!strncmp(soap->msgbuf, "GET ", l = 4))
     13158        httpcmd = 2;
     13159      else if (!strncmp(soap->msgbuf, "PUT ", l = 4))
     13160        httpcmd = 3;
     13161      else if (!strncmp(soap->msgbuf, "DELETE ", l = 7))
     13162        httpcmd = 4;
     13163      else if (!strncmp(soap->msgbuf, "HEAD ", l = 5))
     13164        httpcmd = 5;
     13165    }
     13166    if (s && httpcmd)
     13167    { size_t m = strlen(soap->endpoint);
     13168      size_t n = m + (s - soap->msgbuf) - l - 1;
     13169      if (m > n)
     13170        m = n;
     13171      if (n >= sizeof(soap->endpoint))
     13172        n = sizeof(soap->endpoint) - 1;
     13173      strncpy(soap->path, soap->msgbuf + l, n - m);
     13174      soap->path[n - m] = '\0';
     13175      strcat(soap->endpoint, soap->path);
     13176      DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Target endpoint='%s'\n", soap->endpoint));
     13177      if (httpcmd > 1)
     13178      { switch (httpcmd)
     13179        { case  2: soap->error = soap->fget(soap); break;
     13180          case  3: soap->error = soap->fput(soap); break;
     13181          case  4: soap->error = soap->fdel(soap); break;
     13182          case  5: soap->error = soap->fhead(soap); break;
     13183          default: soap->error = SOAP_HTTP_METHOD; break;
     13184        }
     13185        if (soap->error == SOAP_OK)
     13186          soap->error = SOAP_STOP; /* prevents further processing */
     13187        return soap->error;
     13188      }
     13189      if (status)
     13190        return soap->error = status;
     13191    }
     13192    else if (status)
     13193      return soap->error = status;
     13194    else if (s)
     13195      return soap->error = 405;
     13196  }
     13197  soap->status = k;
     13198  /* Status OK (HTTP 200) */
     13199  if (k == 0 || k == 200)
    1037913200    return SOAP_OK;
    10380   }
    10381   if (k == 0 || (k >= 200 && k <= 299) || k == 400 || k == 500)
     13201  /* Status 201 (Created), 202 (Accepted), ... and HTTP 400 and 500 errors.
     13202     Only keep parsing HTTP body when content-length>0 or chunked is set.
     13203  */
     13204  if (((k > 200 && k <= 299) || k == 400 || k == 500) && (soap->length > 0 || (soap->imode & SOAP_IO) == SOAP_IO_CHUNK))
    1038213205    return SOAP_OK;
    10383   return soap_set_receiver_error(soap, "HTTP error", soap->msgbuf, k);
    10384 }
    10385 #endif
    10386 
    10387 /******************************************************************************/
     13206  /* HTTP 400 and 500 headers are supposed to set content-length or chunked.
     13207     For those that don't we keep parsing the body only if content type is
     13208     given and connection closes.
     13209  */
     13210  if ((k == 400 || k == 500) && (soap->http_content || soap->keep_alive == 0))
     13211    return SOAP_OK;
     13212  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP error %d\n", k));
     13213  return soap_set_receiver_error(soap, "HTTP Error", soap->msgbuf, k);
     13214}
     13215#endif
     13216#endif
     13217
     13218/******************************************************************************/
     13219#ifndef WITH_NOHTTP
    1038813220#ifndef PALM_1
    1038913221static int
     
    1040213234#ifndef WITH_LEANER
    1040313235  else if (!soap_tag_cmp(key, "Content-Type"))
    10404   { if (soap_get_header_attribute(soap, val, "application/dime"))
    10405       soap->mode |= SOAP_ENC_DIME;
    10406     else if (soap_get_header_attribute(soap, val, "multipart/related"))
     13236  { const char *action;
     13237    soap->http_content = soap_strdup(soap, val);
     13238    if (soap_get_header_attribute(soap, val, "application/dime"))
     13239      soap->imode |= SOAP_ENC_DIME;
     13240    else if (soap_get_header_attribute(soap, val, "multipart/related")
     13241          || soap_get_header_attribute(soap, val, "multipart/form-data"))
    1040713242    { soap->mime.boundary = soap_strdup(soap, soap_get_header_attribute(soap, val, "boundary"));
    1040813243      soap->mime.start = soap_strdup(soap, soap_get_header_attribute(soap, val, "start"));
    10409       soap->mode |= SOAP_ENC_MIME;
     13244      soap->imode |= SOAP_ENC_MIME;
     13245    }
     13246    action = soap_get_header_attribute(soap, val, "action");
     13247    if (action)
     13248    { if (*action == '"')
     13249      { soap->action = soap_strdup(soap, action + 1);
     13250        soap->action[strlen(soap->action) - 1] = '\0';
     13251      }
     13252      else
     13253        soap->action = soap_strdup(soap, action);
    1041013254    }
    1041113255  }
    1041213256#endif
    1041313257  else if (!soap_tag_cmp(key, "Content-Length"))
    10414     soap->length = soap_strtoul(val, NULL, 10);
     13258  { soap->length = soap_strtoul(val, NULL, 10);
     13259  }
    1041513260  else if (!soap_tag_cmp(key, "Content-Encoding"))
    1041613261  { if (!soap_tag_cmp(val, "deflate"))
     
    1044213287#endif
    1044313288  else if (!soap_tag_cmp(key, "Transfer-Encoding"))
    10444   { soap->mode &= ~SOAP_IO;
     13289  { soap->imode &= ~SOAP_IO;
    1044513290    if (!soap_tag_cmp(val, "chunked"))
    10446       soap->mode |= SOAP_IO_CHUNK;
     13291      soap->imode |= SOAP_IO_CHUNK;
    1044713292  }
    1044813293  else if (!soap_tag_cmp(key, "Connection"))
     
    1045513300  else if (!soap_tag_cmp(key, "Authorization"))
    1045613301  { if (!soap_tag_cmp(val, "Basic *"))
    10457     { size_t n;
     13302    { int n;
    1045813303      char *s;
    1045913304      soap_base642s(soap, val + 6, soap->tmpbuf, sizeof(soap->tmpbuf) - 1, &n);
     
    1046113306      if ((s = strchr(soap->tmpbuf, ':')))
    1046213307      { *s = '\0';
    10463         soap->userid = soap_strdup(soap, soap->tmpbuf);
    10464         soap->passwd = soap_strdup(soap, s + 1);
     13308        soap->userid = soap_strdup(soap, soap->tmpbuf);
     13309        soap->passwd = soap_strdup(soap, s + 1);
    1046513310      }
    1046613311    }
    1046713312  }
    1046813313  else if (!soap_tag_cmp(key, "WWW-Authenticate"))
    10469     soap->authrealm = soap_strdup(soap, soap_get_header_attribute(soap, val+6, "realm"));
     13314  { soap->authrealm = soap_strdup(soap, soap_get_header_attribute(soap, val + 6, "realm"));
     13315  }
    1047013316  else if (!soap_tag_cmp(key, "Expect"))
    1047113317  { if (!soap_tag_cmp(val, "100-continue"))
     
    1047713323#endif
    1047813324  else if (!soap_tag_cmp(key, "SOAPAction"))
    10479   { if (val[0] && val[1])
     13325  { if (*val == '"')
    1048013326    { soap->action = soap_strdup(soap, val + 1);
    1048113327      soap->action[strlen(soap->action) - 1] = '\0';
    1048213328    }
     13329    else
     13330      soap->action = soap_strdup(soap, val);
    1048313331  }
    1048413332  else if (!soap_tag_cmp(key, "Location"))
     
    1048613334    soap->endpoint[sizeof(soap->endpoint) - 1] = '\0';
    1048713335  }
     13336  else if (!soap_tag_cmp(key, "X-Forwarded-For"))
     13337  { soap->proxy_from = soap_strdup(soap, val);
     13338  }
    1048813339#ifdef WITH_COOKIES
    10489   else if (!soap_tag_cmp(key, "Cookie") || !soap_tag_cmp(key, "Set-Cookie"))
    10490     soap_getcookies(soap, val);
     13340  else if (!soap_tag_cmp(key, "Cookie")
     13341   || !soap_tag_cmp(key, "Cookie2")
     13342   || !soap_tag_cmp(key, "Set-Cookie")
     13343   || !soap_tag_cmp(key, "Set-Cookie2"))
     13344  { soap_getcookies(soap, val);
     13345  }
    1049113346#endif
    1049213347  return SOAP_OK;
    1049313348}
    1049413349#endif
    10495 
    10496 /******************************************************************************/
     13350#endif
     13351
     13352/******************************************************************************/
     13353#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER)
    1049713354#ifndef PALM_1
    1049813355SOAP_FMAC1
     
    1051413371}
    1051513372#endif
    10516 
    10517 /******************************************************************************/
     13373#endif
     13374
     13375/******************************************************************************/
     13376#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER)
    1051813377#ifndef PALM_1
    1051913378SOAP_FMAC1
     
    1052413383}
    1052513384#endif
    10526 
    10527 /******************************************************************************/
     13385#endif
     13386
     13387/******************************************************************************/
     13388#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER)
    1052813389#ifndef PALM_1
    1052913390SOAP_FMAC1
     
    1053813399}
    1053913400#endif
    10540 
    10541 /******************************************************************************/
     13401#endif
     13402
     13403/******************************************************************************/
     13404#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER)
    1054213405#ifndef PALM_1
    1054313406static const char*
     
    1055413417  }
    1055513418  else
    10556   { while (soap_notblank(*s) && !strchr(sep, *s) && --len)
     13419  { while (*s && !soap_blank(*s) && !strchr(sep, *s) && --len)
    1055713420    { if (*s == '%')
    1055813421      { *t++ = ((s[1] >= 'A' ? (s[1] & 0x7) + 9 : s[1] - '0') << 4)
     
    1057013433}
    1057113434#endif
     13435#endif
    1057213436
    1057313437/******************************************************************************/
     
    1058013444#ifndef WITH_LEANER
    1058113445  size_t n = 0;
    10582   if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary && soap->mime.start)
     13446  if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary && soap->mime.start && strlen(soap->mime.boundary) + strlen(soap->mime.start) < sizeof(soap->tmpbuf) - 80 )
    1058313447  { const char *s;
    10584     if (soap->mode & SOAP_ENC_DIME)
     13448    if ((soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM))
    1058513449      s = "application/dime";
    1058613450    else if (soap->version == 2)
    10587       s = "application/soap+xml; charset=utf-8";
     13451    { if (soap->mode & SOAP_ENC_MTOM)
     13452        s = "application/xop+xml; charset=utf-8; type=\"application/soap+xml\"";
     13453      else
     13454        s = "application/soap+xml; charset=utf-8";
     13455    }
     13456    else if (soap->mode & SOAP_ENC_MTOM)
     13457      s = "application/xop+xml; text/xml; charset=utf-8";
    1058813458    else
    1058913459      s = "text/xml; charset=utf-8";
     
    1061413484    return soap->error;
    1061513485#ifndef WITH_LEANER
    10616   if ((soap->mode & SOAP_IO_LENGTH) && (soap->mode & SOAP_ENC_DIME))
     13486  if ((soap->mode & SOAP_IO_LENGTH) && (soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM))
    1061713487  { soap->dime.size = soap->count - soap->dime.size;    /* DIME in MIME correction */
    1061813488    sprintf(soap->id, soap->dime_id_format, 0);
     
    1062813498    if (!soap->dime.first)
    1062913499      soap->dime.flags |= SOAP_DIME_ME;
    10630     soap->count += 12 + ((strlen(soap->dime.id)+3)&(~3)) + ((strlen(soap->dime.type)+3)&(~3));
    10631   }
    10632   if (soap->mode & SOAP_ENC_DIME)
     13500    soap->count += 12 + ((strlen(soap->dime.id)+3)&(~3)) + (soap->dime.type ? ((strlen(soap->dime.type)+3)&(~3)) : 0);
     13501  }
     13502  if ((soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM))
    1063313503    return soap_send_raw(soap, SOAP_STR_PADDING, -(long)soap->dime.size&3);
    1063413504#endif
     
    1064613516{ register struct Namespace *p;
    1064713517  soap->part = SOAP_IN_ENVELOPE;
    10648   if (soap_element_begin_in(soap, "SOAP-ENV:Envelope", 0))
    10649     return soap->error = SOAP_VERSIONMISMATCH;
     13518  if (soap_element_begin_in(soap, "SOAP-ENV:Envelope", 0, NULL))
     13519  {
     13520#ifndef WITH_LEAN
     13521    if (soap->error == SOAP_TAG_MISMATCH && !soap_element_begin_in(soap, "html", 0, NULL))
     13522    { /* get HTML from buffer, stop receiving to avoid HTML parsing issues */
     13523      char *s;
     13524#ifndef WITH_NOIO
     13525      size_t (*f)(struct soap*, char*, size_t) = soap->frecv;
     13526      soap->frecv = frecv_stop;
     13527#endif
     13528      soap_revert(soap);
     13529      s = soap_string_in(soap, 1, -1, -1);
     13530#ifndef WITH_NOIO
     13531      soap->frecv = f;
     13532#endif
     13533      return soap_set_receiver_error(soap, "HTTP Error", s, SOAP_HTTP_ERROR);
     13534    }
     13535#endif
     13536    if (soap->error == SOAP_TAG_MISMATCH)
     13537      return soap->error = SOAP_VERSIONMISMATCH;
     13538    return soap->error;
     13539  }
    1065013540  p = soap->local_namespaces;
    1065113541  if (p)
     
    1065613546    { soap->version = 1; /* make sure we use SOAP 1.1 */
    1065713547      if (p[1].out)
    10658         SOAP_FREE(p[1].out);
    10659       if ((p[1].out = (char*)SOAP_MALLOC(sizeof(soap_enc1))))
     13548        SOAP_FREE(soap, p[1].out);
     13549      if ((p[1].out = (char*)SOAP_MALLOC(soap, sizeof(soap_enc1))))
    1066013550        strcpy(p[1].out, soap_enc1);
    1066113551    }
     
    1066313553    { soap->version = 2; /* make sure we use SOAP 1.2 */
    1066413554      if (p[1].out)
    10665         SOAP_FREE(p[1].out);
    10666       if ((p[1].out = (char*)SOAP_MALLOC(sizeof(soap_enc2))))
     13555        SOAP_FREE(soap, p[1].out);
     13556      if ((p[1].out = (char*)SOAP_MALLOC(soap, sizeof(soap_enc2))))
    1066713557        strcpy(p[1].out, soap_enc2);
    1066813558    }
     
    1067813568SOAP_FMAC2
    1067913569soap_envelope_end_in(struct soap *soap)
    10680 { if (soap_element_end_in(soap, "SOAP-ENV:Envelope"))
    10681     return soap->error;
    10682   soap->part = SOAP_END_ENVELOPE;
    10683   return SOAP_OK;
     13570{ soap->part = SOAP_END_ENVELOPE;
     13571  return soap_element_end_in(soap, "SOAP-ENV:Envelope");
    1068413572}
    1068513573#endif
     
    1069413582  if (soap->version == 1)
    1069513583    soap->encoding = 1;
     13584#ifndef WITH_LEAN
     13585  if ((soap->mode & SOAP_XML_SEC) && soap_set_attr(soap, "wsu:Id", "Body"))
     13586    return soap->error;
     13587#endif
    1069613588  if (soap_element(soap, "SOAP-ENV:Body", 0, NULL))
    10697     return soap->error;
    10698   if ((soap->mode & SOAP_XML_SEC) && soap_attribute(soap, "id", "_0"))
    1069913589    return soap->error;
    1070013590  return soap_element_start_end_out(soap, NULL);
     
    1071013600{ if (soap_element_end_out(soap, "SOAP-ENV:Body"))
    1071113601    return soap->error;
    10712   soap->part = SOAP_IN_BODY;
     13602  soap->part = SOAP_END_BODY;
    1071313603  return SOAP_OK;
    1071413604}
     
    1072213612soap_body_begin_in(struct soap *soap)
    1072313613{ soap->part = SOAP_IN_BODY;
    10724   return soap_element_begin_in(soap, "SOAP-ENV:Body", 0);
     13614  if (soap_element_begin_in(soap, "SOAP-ENV:Body", 0, NULL))
     13615    return soap->error;
     13616  if (!soap->body)
     13617    soap->part = SOAP_NO_BODY;
     13618  return SOAP_OK;
    1072513619}
    1072613620#endif
     
    1073213626SOAP_FMAC2
    1073313627soap_body_end_in(struct soap *soap)
    10734 { if (soap_element_end_in(soap, "SOAP-ENV:Body"))
    10735     return soap->error;
     13628{ if (soap->part == SOAP_NO_BODY)
     13629    return SOAP_OK;
    1073613630  soap->part = SOAP_END_BODY;
    10737   return SOAP_OK;
     13631  return soap_element_end_in(soap, "SOAP-ENV:Body");
    1073813632}
    1073913633#endif
     
    1074713641{ if (soap_getheader(soap) && soap->error == SOAP_TAG_MISMATCH)
    1074813642    soap->error = SOAP_OK;
     13643  else if (soap->error == SOAP_OK && soap->fheader)
     13644    soap->error = soap->fheader(soap);
    1074913645  return soap->error;
    1075013646}
     
    1075913655{ register const char *s;
    1076013656  register size_t i, n;
    10761   *soap->endpoint = '\0';
    10762   *soap->host = '\0';
    10763   *soap->path = '\0';
     13657  soap->endpoint[0] = '\0';
     13658  soap->host[0] = '\0';
     13659  soap->path[0] = '/';
     13660  soap->path[1] = '\0';
    1076413661  soap->port = 80;
    1076513662  if (!endpoint || !*endpoint)
    1076613663    return;
    1076713664#ifdef WITH_OPENSSL
    10768   if (!strncmp(endpoint, "https:", 6))
     13665  if (!soap_tag_cmp(endpoint, "https:*"))
    1076913666    soap->port = 443;
    1077013667#endif
    1077113668  strncpy(soap->endpoint, endpoint, sizeof(soap->endpoint) - 1);
     13669  soap->endpoint[sizeof(soap->endpoint) - 1] = '\0';
    1077213670  s = strchr(endpoint, ':');
    1077313671  if (s && s[1] == '/' && s[2] == '/')
     
    1077813676  if (n >= sizeof(soap->host))
    1077913677    n = sizeof(soap->host) - 1;
    10780 /* WR[ */
    1078113678#ifdef WITH_IPV6
    10782   if ('[' == s[0])
     13679  if (s[0] == '[')
    1078313680  { s++;
    1078413681    for (i = 0; i < n; i++)
    10785     { soap->host[i] = s[i];
    10786       if (']' == s[i])
    10787       {
    10788         s++;
     13682    { if (s[i] == ']')
     13683      { s++;
     13684        --n;
    1078913685        break;
    1079013686      }
     13687      soap->host[i] = s[i];
    1079113688    }
    1079213689  }
     
    1079813695    }
    1079913696  }
    10800 #else /* WITH_IPV6 */
    10801 /* ]WR */
     13697#else
    1080213698  for (i = 0; i < n; i++)
    1080313699  { soap->host[i] = s[i];
     
    1080513701      break;
    1080613702  }
    10807 /* WR[ */
    10808 #endif /* WITH_IPV6 */
    10809 /* ]WR */
     13703#endif
    1081013704  soap->host[i] = '\0';
    1081113705  if (s[i] == ':')
     
    1081513709        break;
    1081613710  }
    10817   if (s[i])
    10818   { strncpy(soap->path, s + i + 1, sizeof(soap->path));
     13711  if (i < n && s[i])
     13712  { strncpy(soap->path, s + i, sizeof(soap->path));
    1081913713    soap->path[sizeof(soap->path) - 1] = '\0';
    1082013714  }
     
    1084213736  size_t count;
    1084313737  soap->error = SOAP_OK;
    10844   strcpy(host, soap->host); /* save to compare */
    10845   port = soap->port; /* save to compare */
     13738  strcpy(host, soap->host); /* save previous host name to compare */
     13739  port = soap->port; /* save previous port to compare */
     13740  soap->status = http_command;
    1084613741  soap_set_endpoint(soap, endpoint);
    10847   if (action)
    10848     soap->action = soap_strdup(soap, action);
     13742#ifndef WITH_LEANER
    1084913743  if (soap->fconnect)
    10850     if ((soap->error = soap->fconnect(soap, endpoint, soap->host, soap->port)))
     13744  { if ((soap->error = soap->fconnect(soap, endpoint, soap->host, soap->port)))
    1085113745      return soap->error;
    10852   if (*soap->host)
    10853   { soap->status = http_command;
    10854     if (!soap_valid_socket(soap->socket) || strcmp(soap->host, host) || soap->port != port)
    10855     { soap->keep_alive = 0; /* force close */
     13746  }
     13747  else
     13748#endif
     13749  if (soap->fopen && *soap->host)
     13750  { if (!soap->keep_alive || !soap_valid_socket(soap->socket) || strcmp(soap->host, host) || soap->port != port || !soap->fpoll || soap->fpoll(soap))
     13751    { soap->keep_alive = 0; /* to force close */
     13752      soap->omode &= ~SOAP_IO_UDP; /* to force close */
    1085613753      soap_closesock(soap);
    10857       DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Connect to host='%s' path='%s' port=%d\n", soap->host, soap->path, soap->port));
     13754      DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Connect/reconnect to host='%s' path='%s' port=%d\n", soap->host, soap->path, soap->port));
     13755#ifndef WITH_LEAN
     13756      if (!strncmp(endpoint, "soap.udp:", 9))
     13757        soap->omode |= SOAP_IO_UDP;
     13758#endif
    1085813759      soap->socket = soap->fopen(soap, endpoint, soap->host, soap->port);
    1085913760      if (soap->error)
     
    1086113762      soap->keep_alive = ((soap->omode & SOAP_IO_KEEPALIVE) != 0);
    1086213763    }
    10863     else if (!soap->keep_alive || !soap->fpoll || soap->fpoll(soap))
    10864     { soap->keep_alive = 0; /* force close */
    10865       soap_closesock(soap);
    10866       DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Reconnect to host='%s' path='%s' port=%d\n", soap->host, soap->path, soap->port));
    10867       soap->socket = soap->fopen(soap, endpoint, soap->host, soap->port);
    10868       if (soap->error)
    10869         return soap->error;
    10870     }
    10871   }
     13764  }
     13765  count = soap_count_attachments(soap);
    1087213766  if (soap_begin_send(soap))
    1087313767    return soap->error;
    10874   count = soap_count_attachments(soap);
     13768  if (http_command != SOAP_POST)
     13769  { soap->mode &= ~SOAP_IO;
     13770    soap->mode |= SOAP_IO_BUFFER;
     13771  }
     13772#ifndef WITH_NOHTTP
     13773  soap->action = soap_strdup(soap, action);
    1087513774  if ((soap->mode & SOAP_IO) != SOAP_IO_STORE && !(soap->mode & SOAP_ENC_XML) && endpoint)
    1087613775  { unsigned int k = soap->mode;
     
    1088013779    if ((soap->error = soap->fpost(soap, endpoint, soap->host, soap->port, soap->path, action, count)))
    1088113780      return soap->error;
     13781#ifndef WITH_LEANER
    1088213782    if ((k & SOAP_IO) == SOAP_IO_CHUNK)
    1088313783    { if (soap_flush(soap))
    1088413784        return soap->error;
    1088513785    }
     13786#endif
    1088613787    soap->mode = k;
    1088713788  }
    1088813789  if (http_command != SOAP_POST)
    1088913790    return soap_end_send(soap);
     13791#endif
    1089013792  return SOAP_OK;
    1089113793}
     
    1089713799char*
    1089813800SOAP_FMAC2
    10899 soap_s2base64(struct soap *soap, const unsigned char *s, char *t, size_t n)
    10900 { register size_t i;
     13801soap_s2base64(struct soap *soap, const unsigned char *s, char *t, int n)
     13802{ register int i;
    1090113803  register unsigned long m;
    1090213804  register char *p;
     
    1090413806    t = (char*)soap_malloc(soap, (n + 2) / 3 * 4 + 1);
    1090513807  if (!t)
    10906   { soap->error = SOAP_EOM;
    1090713808    return NULL;
    10908   }
    1090913809  p = t;
    1091013810  t[0] = '\0';
     
    1094113841const char*
    1094213842SOAP_FMAC2
    10943 soap_base642s(struct soap *soap, const char *s, char *t, size_t l, size_t *n)
     13843soap_base642s(struct soap *soap, const char *s, char *t, size_t l, int *n)
    1094413844{ register int i, j, c;
    1094513845  register unsigned long m;
    10946   char *p = t;
     13846  register const char *p;
     13847  if (!s || !*s)
     13848  { if (n)
     13849      *n = 0;
     13850    if (soap->error)
     13851      return NULL;
     13852    return SOAP_NON_NULL;
     13853  }
     13854  if (!t)
     13855  { l = (strlen(s) + 3) / 4 * 3;
     13856    t = (char*)soap_malloc(soap, l);
     13857  }
     13858  if (!t)
     13859    return NULL;
     13860  p = t;
    1094713861  if (n)
    1094813862    *n = 0;
     
    1096613880          }
    1096713881          if (n)
    10968             *n += i;
     13882            *n += i;
    1096913883          return p;
    1097013884        }
    1097113885        c -= '+';
    1097213886        if (c >= 0 && c <= 79)
    10973         { m = (m << 6) + soap_base64i[c];
     13887        { int b = soap_base64i[c];
     13888          if (b >= 64)
     13889          { soap->error = SOAP_TYPE;
     13890            return NULL; 
     13891          }
     13892          m = (m << 6) + b;
    1097413893          j++;
     13894        }
     13895        else if (!soap_blank(c + '+'))
     13896        { soap->error = SOAP_TYPE;
     13897          return NULL; 
    1097513898        }
    1097613899      }
     
    1098013903      if (l < 3)
    1098113904      { if (n)
    10982           *n += i;
     13905          *n += i;
    1098313906        return p;
    1098413907      }
     
    1099213915
    1099313916/******************************************************************************/
     13917#ifndef WITH_LEAN
     13918SOAP_FMAC1
     13919char*
     13920SOAP_FMAC2
     13921soap_s2hex(struct soap *soap, const unsigned char *s, char *t, int n)
     13922{ register char *p;
     13923  if (!t)
     13924    t = (char*)soap_malloc(soap, 2 * n + 1);
     13925  if (!t)
     13926    return NULL;
     13927  p = t;
     13928  t[0] = '\0';
     13929  if (s)
     13930  { for (; n > 0; n--)
     13931    { register int m = *s++;
     13932      *t++ = (char)((m >> 4) + (m > 159 ? 'a' - 10 : '0'));
     13933      m &= 0x0F;
     13934      *t++ = (char)(m + (m > 9 ? 'a' - 10 : '0'));
     13935    }
     13936  }
     13937  *t++ = '\0';
     13938  return p;
     13939}
     13940#endif
     13941
     13942/******************************************************************************/
     13943#ifndef WITH_LEAN
     13944SOAP_FMAC1
     13945const char*
     13946SOAP_FMAC2
     13947soap_hex2s(struct soap *soap, const char *s, char *t, size_t l, int *n)
     13948{ register const char *p;
     13949  if (!s || !*s)
     13950  { if (n)
     13951      *n = 0;
     13952    if (soap->error)
     13953      return NULL;
     13954    return SOAP_NON_NULL;
     13955  }
     13956  if (!t)
     13957  { l = strlen(s) / 2;
     13958    t = (char*)soap_malloc(soap, l);
     13959  }
     13960  if (!t)
     13961    return NULL;
     13962  p = t;
     13963  while (l)
     13964  { register int d1, d2;
     13965    d1 = *s++;
     13966    if (!d1)
     13967      break;
     13968    d2 = *s++;
     13969    if (!d2)
     13970      break;
     13971    *t++ = ((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0');
     13972    l--;
     13973  }
     13974  if (n)
     13975    *n = (int)(t - p);
     13976  return p;
     13977}
     13978#endif
     13979
     13980/******************************************************************************/
     13981#ifndef WITH_NOHTTP
    1099413982#ifndef PALM_1
    1099513983SOAP_FMAC1
     
    1099713985SOAP_FMAC2
    1099813986soap_puthttphdr(struct soap *soap, int status, size_t count)
    10999 { register const char *s;
    11000   register int err;
    11001   if (status == SOAP_FILE)
    11002     s = soap->http_content;
    11003   else if (status == SOAP_HTML)
    11004     s = "text/html; charset=utf-8";
     13987{ if (soap->status != SOAP_GET)
     13988  { register const char *s = "text/xml; charset=utf-8";
     13989    register int err = SOAP_OK;
    1100513990#ifndef WITH_LEANER
    11006   else if (soap->mode & SOAP_ENC_DIME)
    11007     s = "application/dime";
    11008 #endif
    11009   else if (soap->version == 2)
    11010     s = "application/soap+xml; charset=utf-8";
    11011   else
    11012     s = "text/xml; charset=utf-8";
     13991    register const char *r = NULL;
     13992#endif
     13993    if (status == SOAP_FILE && soap->http_content)
     13994      s = soap->http_content;
     13995    else if (status == SOAP_HTML)
     13996      s = "text/html; charset=utf-8";
     13997    else if (count || ((soap->omode & SOAP_IO) == SOAP_IO_CHUNK))
     13998    { if (soap->version == 2)
     13999        s = "application/soap+xml; charset=utf-8";
     14000    }
    1101314001#ifndef WITH_LEANER
    11014   if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary && soap->mime.start && soap->status != SOAP_GET)
    11015   { sprintf(soap->tmpbuf, "multipart/related; boundary=\"%s\"; type=%s; start=\"%s\"", soap->mime.boundary, s, soap->mime.start);
    11016     s = soap->tmpbuf;
    11017   }
    11018 #endif
    11019   if ((err = soap->fposthdr(soap, "Content-Type", s)))
    11020     return err;
     14002    if (soap->mode & (SOAP_ENC_DIME | SOAP_ENC_MTOM))
     14003    { if (soap->mode & SOAP_ENC_MTOM)
     14004      { r = s;
     14005        s = "application/xop+xml; charset=utf-8";
     14006      }
     14007      else
     14008        s = "application/dime";
     14009    }
     14010    if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary && strlen(soap->mime.boundary) + strlen(soap->mime.start ? soap->mime.start : SOAP_STR_EOS) < sizeof(soap->tmpbuf) - 80)
     14011    { register const char *t = strchr(s, ';');
     14012      sprintf(soap->tmpbuf, "multipart/related; boundary=\"%s\"; type=\"", soap->mime.boundary);
     14013      if (t)
     14014      { strncat(soap->tmpbuf, s, t - s);
     14015        soap->tmpbuf[sizeof(soap->tmpbuf)-1] = '\0';
     14016      }
     14017      else
     14018        strcat(soap->tmpbuf, s);
     14019      if (soap->mime.start)
     14020      { strcat(soap->tmpbuf, "\"; start=\"");
     14021        strcat(soap->tmpbuf, soap->mime.start);
     14022      }
     14023      strcat(soap->tmpbuf, "\"");
     14024      if (r)
     14025      { strcat(soap->tmpbuf, "; start-info=\"");
     14026        strcat(soap->tmpbuf, r);
     14027        strcat(soap->tmpbuf, "\"");
     14028      }
     14029      s = soap->tmpbuf;
     14030    }
     14031#endif
     14032    if (s && (err = soap->fposthdr(soap, "Content-Type", s)))
     14033      return err;
    1102114034#ifdef WITH_ZLIB
    11022   if (soap->omode & SOAP_ENC_ZLIB)
    11023   {
     14035    if ((soap->omode & SOAP_ENC_ZLIB))
     14036    {
    1102414037#ifdef WITH_GZIP
    11025     err = soap->fposthdr(soap, "Content-Encoding", "gzip");
     14038      err = soap->fposthdr(soap, "Content-Encoding", soap->zlib_out == SOAP_ZLIB_DEFLATE ? "deflate" : "gzip");
    1102614039#else
    11027     err = soap->fposthdr(soap, "Content-Encoding", "deflate");
    11028 #endif
     14040      err = soap->fposthdr(soap, "Content-Encoding", "deflate");
     14041#endif
     14042      if (err)
     14043        return err;
     14044    }
     14045#endif
     14046#ifndef WITH_LEANER
     14047    if ((soap->omode & SOAP_IO) == SOAP_IO_CHUNK)
     14048      err = soap->fposthdr(soap, "Transfer-Encoding", "chunked");
     14049    else
     14050#endif
     14051    if (s)
     14052    { sprintf(soap->tmpbuf, "%lu", (unsigned long)count);
     14053      err = soap->fposthdr(soap, "Content-Length", soap->tmpbuf);
     14054    }
    1102914055    if (err)
    1103014056      return err;
    1103114057  }
    11032 #endif
    11033   if ((soap->omode & SOAP_IO) == SOAP_IO_CHUNK)
    11034     err = soap->fposthdr(soap, "Transfer-Encoding", "chunked");
    11035   else if (count > 0)
    11036   { sprintf(soap->tmpbuf, "%lu", (unsigned long)count);
    11037     err = soap->fposthdr(soap, "Content-Length", soap->tmpbuf);
    11038   }
    11039   if (err)
    11040     return err;
    1104114058  return soap->fposthdr(soap, "Connection", soap->keep_alive ? "keep-alive" : "close");
    1104214059}
    1104314060#endif
    11044 
    11045 /******************************************************************************/
     14061#endif
     14062
     14063/******************************************************************************/
     14064#ifndef WITH_NOHTTP
    1104614065#ifndef PALM_1
    1104714066static int
     
    1105014069}
    1105114070#endif
    11052 
    11053 /******************************************************************************/
     14071#endif
     14072
     14073/******************************************************************************/
     14074#ifndef WITH_NOHTTP
     14075#ifndef PALM_1
     14076static int
     14077http_put(struct soap *soap)
     14078{ return SOAP_PUT_METHOD;
     14079}
     14080#endif
     14081#endif
     14082
     14083/******************************************************************************/
     14084#ifndef WITH_NOHTTP
     14085#ifndef PALM_1
     14086static int
     14087http_del(struct soap *soap)
     14088{ return SOAP_DEL_METHOD;
     14089}
     14090#endif
     14091#endif
     14092
     14093/******************************************************************************/
     14094#ifndef WITH_NOHTTP
     14095#ifndef PALM_1
     14096static int
     14097http_head(struct soap *soap)
     14098{ return SOAP_HEAD_METHOD;
     14099}
     14100#endif
     14101#endif
     14102
     14103/******************************************************************************/
     14104#ifndef WITH_NOHTTP
    1105414105#ifndef PALM_1
    1105514106static int
     
    1105814109  register int err;
    1105914110  if (soap->status == SOAP_GET)
    11060   { s = "GET";
    11061     count = 0;
    11062   }
     14111    s = "GET";
    1106314112  else
    1106414113    s = "POST";
    1106514114#ifdef PALM
    11066   if (!endpoint || (strncmp(endpoint, "http:", 5) && strncmp(endpoint, "https:", 6) && strncmp(endpoint, "httpg:", 6)) && strncmp(endpoint, "_beam:", 6) && strncmp(endpoint, "_local:", 7) && strncmp(endpoint, "_btobex:", 8))
     14115  if (!endpoint || (soap_tag_cmp(endpoint, "http:*") && soap_tag_cmp(endpoint, "https:*") && strncmp(endpoint, "httpg:", 6)) && strncmp(endpoint, "_beam:", 6) && strncmp(endpoint, "_local:", 7) && strncmp(endpoint, "_btobex:", 8))
    1106714116#else
    11068   if (!endpoint || (strncmp(endpoint, "http:", 5) && strncmp(endpoint, "https:", 6) && strncmp(endpoint, "httpg:", 6)))
     14117  if (!endpoint || (soap_tag_cmp(endpoint, "http:*") && soap_tag_cmp(endpoint, "https:*") && strncmp(endpoint, "httpg:", 6)))
    1106914118#endif
    1107014119    return SOAP_OK;
    11071   if (soap->proxy_host && strncmp(endpoint, "https:", 6))
     14120  if (strlen(endpoint) + strlen(soap->http_version) > sizeof(soap->tmpbuf) - 80)
     14121    return soap->error = SOAP_EOM;
     14122  if (soap->proxy_host && soap_tag_cmp(endpoint, "https:*"))
    1107214123    sprintf(soap->tmpbuf, "%s %s HTTP/%s", s, endpoint, soap->http_version);
    1107314124  else
    11074     sprintf(soap->tmpbuf, "%s /%s HTTP/%s", s, path, soap->http_version);
     14125    sprintf(soap->tmpbuf, "%s /%s HTTP/%s", s, (*path == '/' ? path + 1 : path), soap->http_version);
    1107514126  if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL)))
    1107614127    return err;
     14128#ifdef WITH_OPENSSL
     14129  if ((soap->ssl && soap->port != 443) || (!soap->ssl && soap->port != 80))
     14130    sprintf(soap->tmpbuf, "%s:%d", host, port);
     14131  else
     14132    strcpy(soap->tmpbuf, host);
     14133#else
    1107714134  if (port != 80)
    1107814135    sprintf(soap->tmpbuf, "%s:%d", host, port);
    1107914136  else
    1108014137    strcpy(soap->tmpbuf, host);
     14138#endif
    1108114139  if ((err = soap->fposthdr(soap, "Host", soap->tmpbuf))
    1108214140   || (err = soap->fposthdr(soap, "User-Agent", "gSOAP/2.7"))
     
    1109514153  { sprintf(soap->tmpbuf + 262, "%s:%s", soap->userid, soap->passwd);
    1109614154    strcpy(soap->tmpbuf, "Basic ");
    11097     soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, strlen(soap->tmpbuf + 262));
     14155    soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, (int)strlen(soap->tmpbuf + 262));
    1109814156    if ((err = soap->fposthdr(soap, "Authorization", soap->tmpbuf)))
    1109914157      return err;
     
    1110214160  { sprintf(soap->tmpbuf + 262, "%s:%s", soap->proxy_userid, soap->proxy_passwd);
    1110314161    strcpy(soap->tmpbuf, "Basic ");
    11104     soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, strlen(soap->tmpbuf + 262));
     14162    soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, (int)strlen(soap->tmpbuf + 262));
    1110514163    if ((err = soap->fposthdr(soap, "Proxy-Authorization", soap->tmpbuf)))
    1110614164      return err;
     
    1111614174#endif
    1111714175#endif
    11118   if (action && soap->version == 1)
    11119   { sprintf(soap->tmpbuf, "\"%s\"", action);
     14176  if (soap->status != SOAP_GET && (soap->version == 1 || (action && *action)))
     14177  { sprintf(soap->tmpbuf, "\"%s\"", action && strlen(action) < sizeof(soap->tmpbuf) - 3 ? action : SOAP_STR_EOS);
    1112014178    if ((err = soap->fposthdr(soap, "SOAPAction", soap->tmpbuf)))
    1112114179      return err;
     
    1112414182}
    1112514183#endif
    11126 
    11127 /******************************************************************************/
     14184#endif
     14185
     14186/******************************************************************************/
     14187#ifndef WITH_NOHTTP
    1112814188#ifndef PALM_1
    1112914189static int
     
    1114114201}
    1114214202#endif
    11143 
    11144 /******************************************************************************/
     14203#endif
     14204
     14205/******************************************************************************/
     14206#ifndef WITH_NOHTTP
    1114514207#ifndef PALM_1
    1114614208static int
     
    1115514217}
    1115614218#endif
    11157 
    11158 /******************************************************************************/
     14219#endif
     14220
     14221/******************************************************************************/
     14222#ifndef WITH_NOHTTP
    1115914223#ifndef PALM_1
    1116014224static int
    1116114225http_response(struct soap *soap, int status, size_t count)
    1116214226{ register int err;
    11163 /* WR[ */
    1116414227#ifdef WMW_RPM_IO
    1116514228  if (soap->rpmreqid)
    1116614229    httpOutputEnable(soap->rpmreqid);
    11167 #endif  /* WMW_RPM_IO */
    11168 /* ]WR */
     14230#endif
     14231  if (strlen(soap->http_version) > 4)
     14232    return soap->error = SOAP_EOM;
    1116914233  if (!status || status == SOAP_HTML || status == SOAP_FILE)
    11170   { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "OK 200\n"));
    11171 /* WR[ */
     14234  { const char *s;
     14235    if (count || ((soap->omode & SOAP_IO) == SOAP_IO_CHUNK))
     14236      s = "200 OK";
     14237    else
     14238      s = "202 ACCEPTED";
     14239    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Status = %s\n", s));
    1117214240#ifdef WMW_RPM_IO
    1117314241    if (soap->rpmreqid || soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* RPM behaves as if standalone */
    1117414242#else
    11175 /* ]WR */
    1117614243    if (soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* standalone application */
    11177 /* WR[ */
    11178 #endif /* WMW_RPM_IO */
    11179 /* ]WR */
    11180     { sprintf(soap->tmpbuf, "HTTP/%s 200 OK", soap->http_version);
     14244#endif
     14245    { sprintf(soap->tmpbuf, "HTTP/%s %s", soap->http_version, s);
    1118114246      if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL)))
    1118214247        return err;
    1118314248    }
    11184     else if ((err = soap->fposthdr(soap, "Status", "200 OK")))
     14249    else if ((err = soap->fposthdr(soap, "Status", s)))
    1118514250      return err;
    1118614251  }
    11187   else if (status > 200 && status < 600)
     14252  else if (status >= 200 && status < 600)
    1118814253  { sprintf(soap->tmpbuf, "HTTP/%s %d %s", soap->http_version, status, http_error(soap, status));
    1118914254    if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL)))
    1119014255      return err;
     14256#ifndef WITH_LEAN
    1119114257    if (status == 401)
    11192     { sprintf(soap->tmpbuf, "Basic realm=\"%s\"", soap->authrealm ? soap->authrealm : "gSOAP Web Service");
     14258    { sprintf(soap->tmpbuf, "Basic realm=\"%s\"", (soap->authrealm && strlen(soap->authrealm) < sizeof(soap->tmpbuf) - 14) ? soap->authrealm : "gSOAP Web Service");
    1119314259      if ((err = soap->fposthdr(soap, "WWW-Authenticate", soap->tmpbuf)))
    1119414260        return err;
     
    1119814264        return err;
    1119914265    }
     14266#endif
    1120014267  }
    1120114268  else
    1120214269  { const char *s = *soap_faultcode(soap);
    11203     if (soap->version == 2 && !strcmp(s, "SOAP-ENV:Sender"))
     14270    if (soap->version == 2 && (!s || !strcmp(s, "SOAP-ENV:Sender")))
    1120414271      s = "400 Bad Request";
    1120514272    else
    1120614273      s = "500 Internal Server Error";
    1120714274    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error %s (status=%d)\n", s, status));
    11208 /* WR[ */
    1120914275#ifdef WMW_RPM_IO
    1121014276    if (soap->rpmreqid || soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* RPM behaves as if standalone */
    1121114277#else
    11212 /* ]WR */
    1121314278    if (soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* standalone application */
    11214 /* WR[ */
    11215 #endif /* WMW_RPM_IO */
    11216 /* ]WR */
     14279#endif
    1121714280    { sprintf(soap->tmpbuf, "HTTP/%s %s", soap->http_version, s);
    1121814281      if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL)))
    1121914282        return err;
    1122014283    }
    11221     else if ((err = soap->fposthdr(soap, "Status", s)))
     14284    else if ((err = soap->fposthdr(soap, "Status", s))) /* CGI */
    1122214285      return err;
    1122314286  }
     
    1123214295}
    1123314296#endif
     14297#endif
    1123414298
    1123514299/******************************************************************************/
     
    1124214306  if (!(soap->omode & (SOAP_ENC_XML | SOAP_IO_STORE /* this tests for chunking too */))
    1124314307   && (status == SOAP_HTML || status == SOAP_FILE))
    11244   { soap->omode &= ~SOAP_IO;
    11245     soap->omode |= SOAP_IO_STORE;
    11246   }
     14308    soap->omode = (soap->omode & ~SOAP_IO) | SOAP_IO_STORE;
    1124714309  soap->status = status;
    1124814310  count = soap_count_attachments(soap);
    1124914311  if (soap_begin_send(soap))
    1125014312    return soap->error;
     14313#ifndef WITH_NOHTTP
    1125114314  if ((soap->mode & SOAP_IO) != SOAP_IO_STORE && !(soap->mode & SOAP_ENC_XML))
    1125214315  { register int n = soap->mode;
     
    1125614319    if ((soap->error = soap->fresponse(soap, status, count)))
    1125714320      return soap->error;
     14321#ifndef WITH_LEANER
    1125814322    if ((n & SOAP_IO) == SOAP_IO_CHUNK)
    1125914323    { if (soap_flush(soap))
    1126014324        return soap->error;
    1126114325    }
     14326#endif
    1126214327    soap->mode = n;
    1126314328  }
     14329#endif
    1126414330  return SOAP_OK;
    1126514331}
     
    1127014336static const char*
    1127114337soap_set_validation_fault(struct soap *soap, const char *s, const char *t)
    11272 { sprintf(soap->msgbuf, "Validation constraint violation: %s%s in element <%s>", s, t?t:SOAP_STR_EOS, soap->tag);
     14338{ if (*soap->tag)
     14339    sprintf(soap->msgbuf, "Validation constraint violation: %s%s in element <%s>", s, t?t:SOAP_STR_EOS, soap->tag);
     14340  else
     14341    sprintf(soap->msgbuf, "Validation constraint violation: %s%s", s, t?t:SOAP_STR_EOS);
    1127314342  return soap->msgbuf;
    1127414343}
     
    1128314352{ const char **c = soap_faultcode(soap);
    1128414353  const char **s = soap_faultstring(soap);
     14354  if (soap->fseterror)
     14355    soap->fseterror(soap, c, s);
    1128514356  if (!*c)
    1128614357  { if (soap->version == 2)
     
    1130314374      *s = soap_set_validation_fault(soap, "tag name or namespace mismatch", NULL);
    1130414375      break;
    11305     case SOAP_TAG_END:
    11306       *s = soap_set_validation_fault(soap, "incorrect end tag", NULL);
    11307       break;
    1130814376    case SOAP_TYPE:
    1130914377      *s = soap_set_validation_fault(soap, "data type mismatch ", soap->type);
    1131014378      break;
    1131114379    case SOAP_SYNTAX_ERROR:
    11312       *s = "Well-formedness constraint violation";
     14380      *s = "Well-formedness violation";
    1131314381      break;
    1131414382    case SOAP_NO_TAG:
    11315       *s = "No XML element tag found";
     14383      *s = "No XML element tag";
    1131614384      break;
    1131714385    case SOAP_MUSTUNDERSTAND:
     
    1132214390    case SOAP_VERSIONMISMATCH:
    1132314391      *c = "SOAP-ENV:VersionMismatch";
    11324       *s = "SOAP version mismatch or invalid SOAP message";
     14392      *s = "Invalid SOAP message or SOAP version mismatch";
    1132514393      break;
    1132614394    case SOAP_DATAENCODINGUNKNOWN:
     
    1132914397      break;
    1133014398    case SOAP_NAMESPACE:
    11331       *s = soap_set_validation_fault(soap, "namespace mismatch", NULL);
     14399      *s = soap_set_validation_fault(soap, "namespace error", NULL);
     14400      break;
     14401    case SOAP_USER_ERROR:
     14402      *s = "User error";
    1133214403      break;
    1133314404    case SOAP_FATAL_ERROR:
     
    1133814409      *s = soap->msgbuf;
    1133914410      break;
     14411    case SOAP_NO_DATA:
     14412      *s = "Data required for operation";
     14413      break;
    1134014414    case SOAP_GET_METHOD:
    1134114415      *s = "HTTP GET method not implemented";
    1134214416      break;
     14417    case SOAP_PUT_METHOD:
     14418      *s = "HTTP PUT method not implemented";
     14419      break;
     14420    case SOAP_HEAD_METHOD:
     14421      *s = "HTTP HEAD method not implemented";
     14422      break;
     14423    case SOAP_HTTP_METHOD:
     14424      *s = "HTTP method not implemented";
     14425      break;
    1134314426    case SOAP_EOM:
    1134414427      *s = "Out of memory";
     14428      break;
     14429    case SOAP_MOE:
     14430      *s = "Memory overflow or memory corruption error";
     14431      break;
     14432    case SOAP_HDR:
     14433      *s = "Header line too long";
    1134514434      break;
    1134614435    case SOAP_IOB:
     
    1135014439      *s = soap_set_validation_fault(soap, "nil not allowed", NULL);
    1135114440      break;
    11352     case SOAP_MULTI_ID:
     14441    case SOAP_DUPLICATE_ID:
    1135314442      *s = soap_set_validation_fault(soap, "multiple definitions of id ", soap->id);
     14443      if (soap->version == 2)
     14444        *soap_faultsubcode(soap) = "SOAP-ENC:DuplicateID";
    1135414445      break;
    1135514446    case SOAP_MISSING_ID:
    1135614447      *s = soap_set_validation_fault(soap, "missing id for ref ", soap->id);
     14448      if (soap->version == 2)
     14449        *soap_faultsubcode(soap) = "SOAP-ENC:MissingID";
    1135714450      break;
    1135814451    case SOAP_HREF:
    11359       *s = soap_set_validation_fault(soap, "incompatible object ref ", soap->id);
     14452      *s = soap_set_validation_fault(soap, "incompatible object type ref/id pair ", soap->id);
    1136014453      break;
    1136114454    case SOAP_FAULT:
     14455      break;
     14456#ifndef WITH_NOIO
     14457    case SOAP_UDP_ERROR:
     14458      *s = "Message too large for UDP packet";
    1136214459      break;
    1136314460    case SOAP_TCP_ERROR:
    1136414461      *s = tcp_error(soap);
    1136514462      break;
     14463#endif
    1136614464    case SOAP_HTTP_ERROR:
    11367       *s = "HTTP error";
     14465      *s = "An HTTP processing error occurred";
    1136814466      break;
    1136914467    case SOAP_SSL_ERROR:
     14468#ifdef WITH_OPENSSL
    1137014469      *s = "SSL error";
     14470#else
     14471      *s = "OpenSSL not installed: recompile with -DWITH_OPENSSL";
     14472#endif
    1137114473      break;
    1137214474    case SOAP_PLUGIN_ERROR:
    1137314475      *s = "Plugin registry error";
     14476      break;
     14477    case SOAP_DIME_ERROR:
     14478      *s = "DIME format error";
     14479      break;
     14480    case SOAP_DIME_HREF:
     14481      *s = "DIME href to missing attachment";
    1137414482      break;
    1137514483    case SOAP_DIME_MISMATCH:
     
    1137914487      *s = "End of DIME error";
    1138014488      break;
    11381     case SOAP_DIME_ERROR:
    11382       *s = "DIME format error";
    11383       break;
    1138414489    case SOAP_MIME_ERROR:
    1138514490      *s = "MIME format error";
    1138614491      break;
     14492    case SOAP_MIME_HREF:
     14493      *s = "MIME href to missing attachment";
     14494      break;
     14495    case SOAP_MIME_END:
     14496      *s = "End of MIME error";
     14497      break;
    1138714498    case SOAP_ZLIB_ERROR:
    1138814499#ifdef WITH_ZLIB
    11389       sprintf(soap->msgbuf, "Zlib/gzip error: '%s'", soap->d_stream.msg?soap->d_stream.msg:"");
     14500      sprintf(soap->msgbuf, "Zlib/gzip error: '%s'", soap->d_stream->msg?soap->d_stream->msg:SOAP_STR_EOS);
    1139014501      *s = soap->msgbuf;
    1139114502#else
    11392       *s = "Zlib not installed for required message (de)compression";
     14503      *s = "Zlib/gzip not installed for (de)compression: recompile with -DWITH_GZIP";
    1139314504#endif
    1139414505      break;
     
    1140014511      break;
    1140114512    case SOAP_OCCURS:
    11402       *s = soap_set_validation_fault(soap, "a min/maxOccurs violation was detected", NULL);
     14513      *s = soap_set_validation_fault(soap, "occurrence violation", NULL);
    1140314514      break;
    1140414515    case SOAP_LENGTH:
    1140514516      *s = soap_set_validation_fault(soap, "content length violation", NULL);
    1140614517      break;
     14518    case SOAP_FD_EXCEEDED:
     14519      *s = "Maximum number of open connections was reached";
     14520      break;
     14521    case SOAP_STOP:
     14522      *s = "Stopped: no response sent";
     14523      break;
    1140714524#endif
    1140814525    case SOAP_EOF:
    11409       sprintf(soap->msgbuf, "End of file or no input: '%s'", soap_strerror(soap));
     14526#ifndef WITH_NOIO
     14527      strcpy(soap->msgbuf, soap_strerror(soap));
     14528#ifndef WITH_LEAN
     14529      if (strlen(soap->msgbuf) + 25 < sizeof(soap->msgbuf))
     14530      { memmove(soap->msgbuf + 25, soap->msgbuf, strlen(soap->msgbuf) + 1);
     14531        memcpy(soap->msgbuf, "End of file or no input: ", 25);
     14532      }
     14533#endif
    1141014534      *s = soap->msgbuf;
    1141114535      break;
     14536#else
     14537      *s = "End of file or no input";
     14538      break;
     14539#endif
    1141214540    default:
     14541#ifndef WITH_NOHTTP
     14542#ifndef WITH_LEAN
    1141314543      if (soap->error > 200 && soap->error < 600)
    11414       { sprintf(soap->msgbuf, "HTTP Error: '%s'", http_error(soap, soap->error));
     14544      { sprintf(soap->msgbuf, "HTTP Error: %d %s", soap->error, http_error(soap, soap->error));
    1141514545        *s = soap->msgbuf;
    1141614546      }
    1141714547      else
    11418       { sprintf(soap->msgbuf, "Error code %d", soap->error);
     14548#endif
     14549#endif
     14550      { sprintf(soap->msgbuf, "Error %d", soap->error);
    1141914551        *s = soap->msgbuf;
    1142014552      }
     
    1143014562soap_send_fault(struct soap *soap)
    1143114563{ register int status = soap->error;
     14564  int r = 1;
    1143214565  if (status == SOAP_STOP)
    1143314566    return status;
     
    1143514568  soap->keep_alive = 0; /* to terminate connection */
    1143614569  soap_set_fault(soap);
    11437   if ((status != SOAP_EOF || (!soap->recv_timeout && !soap->send_timeout)) && (!soap->fpoll || soap->fpoll(soap) == SOAP_OK))
     14570#ifndef WITH_NOIO
     14571#ifndef WITH_LEAN
     14572  if (soap_valid_socket(soap->socket))
     14573  { struct timeval timeout;
     14574    fd_set rfd, sfd;
     14575    timeout.tv_sec = 0;
     14576    timeout.tv_usec = 0;
     14577    FD_ZERO(&rfd);
     14578    FD_ZERO(&sfd);
     14579    FD_SET(soap->socket, &rfd);
     14580    FD_SET(soap->socket, &sfd);
     14581    r = select((int)soap->socket + 1, &rfd, &sfd, NULL, &timeout);
     14582    if (r > 0)
     14583    { if (!FD_ISSET(soap->socket, &sfd)
     14584       || (FD_ISSET(soap->socket, &rfd)
     14585        && recv(soap->socket, soap->tmpbuf, 1, MSG_PEEK) < 0))
     14586        r = 0;
     14587    }
     14588  }
     14589#endif
     14590#endif
     14591  if ((status != SOAP_EOF || (!soap->recv_timeout && !soap->send_timeout)) && r > 0)
    1143814592  { soap->error = SOAP_OK;
    1143914593    soap_serializeheader(soap);
     
    1144814602      soap_envelope_end_out(soap);
    1144914603    }
     14604    soap_end_count(soap);
    1145014605    if (soap_response(soap, status)
    1145114606     || soap_envelope_begin_out(soap)
     
    1150314658
    1150414659/******************************************************************************/
     14660#ifndef WITH_NOHTTP
     14661#ifndef PALM_1
     14662SOAP_FMAC1
     14663int
     14664SOAP_FMAC2
     14665soap_send_empty_response(struct soap *soap, int httpstatuscode)
     14666{ register soap_mode m = soap->omode;
     14667  soap->count = 0;
     14668  if ((m & SOAP_IO) == SOAP_IO_CHUNK)
     14669    soap->omode = (m & ~SOAP_IO) | SOAP_IO_BUFFER;
     14670  if (soap_response(soap, httpstatuscode) || soap_end_send(soap))
     14671  { soap->omode = m;
     14672    return soap_closesock(soap);
     14673  }
     14674  soap->omode = m;
     14675  return SOAP_OK;
     14676}
     14677#endif
     14678#endif
     14679
     14680/******************************************************************************/
     14681#ifndef WITH_NOHTTP
     14682#ifndef PALM_1
     14683SOAP_FMAC1
     14684int
     14685SOAP_FMAC2
     14686soap_recv_empty_response(struct soap *soap)
     14687{ if (soap_begin_recv(soap) || soap_end_recv(soap))
     14688  { if (soap->error != 202)
     14689      return soap_closesock(soap);
     14690    soap->error = SOAP_OK;
     14691  }
     14692  return SOAP_OK;
     14693}
     14694#endif
     14695#endif
     14696
     14697/******************************************************************************/
     14698#ifndef WITH_NOIO
    1150514699#ifndef PALM_1
    1150614700static const char*
    1150714701soap_strerror(struct soap *soap)
    11508 { int err = soap->errnum;
    11509   if (!err)
    11510     err = soap_errno;
     14702{ register int err = soap->errnum;
    1151114703  if (err)
    1151214704  {
    11513 #ifndef UNDER_CE
     14705#ifndef WIN32
    1151414706    return strerror(err);
    1151514707#else
    11516     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, 0, (LPTSTR)&soap->werrorstr, sizeof(soap->werrorstr), NULL);
    11517     wcstombs(soap->errorstr, soap->werrorstr, sizeof(soap->errorstr));
    11518     return soap->errorstr;
    11519 #endif
    11520   }
     14708#ifndef UNDER_CE
     14709    DWORD len;
     14710    *soap->msgbuf = '\0';
     14711    len = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)soap->msgbuf, (DWORD)sizeof(soap->msgbuf), NULL);
     14712#else
     14713    DWORD i, len;
     14714    *soap->msgbuf = '\0';
     14715    len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, 0, (LPTSTR)soap->msgbuf, (DWORD)(sizeof(soap->msgbuf)/sizeof(TCHAR)), NULL);
     14716    for (i = 0; i <= len; i++)
     14717    { if (((TCHAR*)soap->msgbuf)[i] < 0x80)
     14718        soap->msgbuf[i] = (char)((TCHAR*)soap->msgbuf)[i];
     14719      else
     14720        soap->msgbuf[i] = '?';
     14721    }
     14722#endif
     14723    return soap->msgbuf;
     14724#endif
     14725  }
     14726#ifndef WITH_LEAN
     14727  if (soap->recv_timeout > 0)
     14728  { if (soap->send_timeout > 0)
     14729      sprintf(soap->msgbuf, "Operation interrupted or timed out after %ds send or %ds receive delay", soap->send_timeout, soap->recv_timeout);
     14730    else
     14731      sprintf(soap->msgbuf, "Operation interrupted or timed out after %ds receive delay", soap->recv_timeout);
     14732    return soap->msgbuf;
     14733  }
     14734#endif
    1152114735  return "Operation interrupted or timed out";
    1152214736}
    1152314737#endif
     14738#endif
    1152414739
    1152514740/******************************************************************************/
    1152614741#ifndef PALM_2
    1152714742static int
    11528 soap_set_error(struct soap *soap, const char *faultcode, const char *faultstring, const char *faultdetail, int soaperror)
     14743soap_set_error(struct soap *soap, const char *faultcode, const char *faultsubcodeQName, const char *faultstring, const char *faultdetailXML, int soaperror)
    1152914744{ *soap_faultcode(soap) = faultcode;
     14745  if (faultsubcodeQName)
     14746    *soap_faultsubcode(soap) = faultsubcodeQName;
    1153014747  *soap_faultstring(soap) = faultstring;
    11531   if (faultdetail && *faultdetail)
     14748  if (faultdetailXML && *faultdetailXML)
    1153214749  { register const char **s = soap_faultdetail(soap);
    1153314750    if (s)
    11534       *s = faultdetail;
     14751      *s = faultdetailXML;
    1153514752  }
    1153614753  return soap->error = soaperror;
     
    1154314760int
    1154414761SOAP_FMAC2
    11545 soap_set_sender_error(struct soap *soap, const char *faultstring, const char *faultdetail, int soaperror)
    11546 { return soap_set_error(soap, soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client", faultstring, faultdetail, soaperror);
     14762soap_set_sender_error(struct soap *soap, const char *faultstring, const char *faultdetailXML, int soaperror)
     14763{ return soap_set_error(soap, soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client", NULL, faultstring, faultdetailXML, soaperror);
    1154714764}
    1154814765#endif
     
    1155314770int
    1155414771SOAP_FMAC2
    11555 soap_set_receiver_error(struct soap *soap, const char *faultstring, const char *faultdetail, int soaperror)
    11556 { return soap_set_error(soap, soap->version == 2 ? "SOAP-ENV:Receiver" : "SOAP-ENV:Server", faultstring, faultdetail, soaperror);
     14772soap_set_receiver_error(struct soap *soap, const char *faultstring, const char *faultdetailXML, int soaperror)
     14773{ return soap_set_error(soap, soap->version == 2 ? "SOAP-ENV:Receiver" : "SOAP-ENV:Server", NULL, faultstring, faultdetailXML, soaperror);
    1155714774}
    1155814775#endif
     
    1156114778#ifndef PALM_2
    1156214779static int
    11563 soap_copy_fault(struct soap *soap, const char *faultcode, const char *faultstring, const char *faultdetail)
    11564 { char *s = NULL, *t = NULL;
     14780soap_copy_fault(struct soap *soap, const char *faultcode, const char *faultsubcodeQName, const char *faultstring, const char *faultdetailXML)
     14781{ char *r = NULL, *s = NULL, *t = NULL;
     14782  if (faultsubcodeQName)
     14783    r = soap_strdup(soap, faultsubcodeQName);
    1156514784  if (faultstring)
    1156614785    s = soap_strdup(soap, faultstring);
    11567   if (faultdetail)
    11568     t = soap_strdup(soap, faultdetail);
    11569   return soap_set_error(soap, faultcode, s, t, SOAP_FAULT);
     14786  if (faultdetailXML)
     14787    t = soap_strdup(soap, faultdetailXML);
     14788  return soap_set_error(soap, faultcode, r, s, t, SOAP_FAULT);
    1157014789}
    1157114790#endif
     
    1157614795int
    1157714796SOAP_FMAC2
    11578 soap_sender_fault(struct soap *soap, const char *faultstring, const char *faultdetail)
    11579 { return soap_copy_fault(soap, soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client", faultstring, faultdetail);
     14797soap_sender_fault(struct soap *soap, const char *faultstring, const char *faultdetailXML)
     14798{ return soap_sender_fault_subcode(soap, NULL, faultstring, faultdetailXML);
    1158014799}
    1158114800#endif
     
    1158614805int
    1158714806SOAP_FMAC2
    11588 soap_receiver_fault(struct soap *soap, const char *faultstring, const char *faultdetail)
    11589 { return soap_copy_fault(soap, soap->version == 2 ? "SOAP-ENV:Receiver" : "SOAP-ENV:Server", faultstring, faultdetail);
     14807soap_sender_fault_subcode(struct soap *soap, const char *faultsubcodeQName, const char *faultstring, const char *faultdetailXML)
     14808{ return soap_copy_fault(soap, soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client", faultsubcodeQName, faultstring, faultdetailXML);
    1159014809}
    1159114810#endif
     
    1159414813#ifndef PALM_2
    1159514814SOAP_FMAC1
     14815int
     14816SOAP_FMAC2
     14817soap_receiver_fault(struct soap *soap, const char *faultstring, const char *faultdetailXML)
     14818{ return soap_receiver_fault_subcode(soap, NULL, faultstring, faultdetailXML);
     14819}
     14820#endif
     14821
     14822/******************************************************************************/
     14823#ifndef PALM_2
     14824SOAP_FMAC1
     14825int
     14826SOAP_FMAC2
     14827soap_receiver_fault_subcode(struct soap *soap, const char *faultsubcodeQName, const char *faultstring, const char *faultdetailXML)
     14828{ return soap_copy_fault(soap, soap->version == 2 ? "SOAP-ENV:Receiver" : "SOAP-ENV:Server", faultsubcodeQName, faultstring, faultdetailXML);
     14829}
     14830#endif
     14831
     14832/******************************************************************************/
     14833#ifndef PALM_2
     14834#ifndef WITH_NOSTDLIB
     14835SOAP_FMAC1
    1159614836void
    1159714837SOAP_FMAC2
    1159814838soap_print_fault(struct soap *soap, FILE *fd)
    11599 { if (soap->error)
    11600   { const char **s;
    11601     if (!*soap_faultcode(soap))
     14839{ if (soap_check_state(soap))
     14840    fprintf(fd, "Error: soap struct state not initialized\n");
     14841  else if (soap->error)
     14842  { const char *c, *v = NULL, *s, **d;
     14843    d = soap_faultcode(soap);
     14844    if (!*d)
    1160214845      soap_set_fault(soap);
    11603     fprintf(fd, "SOAP FAULT: %s\n\"%s\"\n", *soap_faultcode(soap), *soap_faultstring(soap));
    11604     s = soap_faultdetail(soap);
    11605     if (s && *s)
    11606       fprintf(fd, "Detail: %s\n", *s);
    11607   }
    11608 }
     14846    c = *d;
     14847    if (soap->version == 2)
     14848      v = *soap_faultsubcode(soap);
     14849    s = *soap_faultstring(soap);
     14850    d = soap_faultdetail(soap);
     14851    fprintf(fd, "%s%d fault: %s [%s]\n\"%s\"\nDetail: %s\n", soap->version ? "SOAP 1." : "Error ", soap->version ? (int)soap->version : soap->error, c, v ? v : "no subcode", s ? s : "[no reason]", d && *d ? *d : "[no detail]");
     14852  }
     14853}
     14854#endif
    1160914855#endif
    1161014856 
    1161114857/******************************************************************************/
    11612 #ifndef PALM_1
     14858#ifdef __cplusplus
     14859#ifndef WITH_LEAN
     14860#ifndef WITH_NOSTDLIB
     14861SOAP_FMAC1
     14862void
     14863SOAP_FMAC2
     14864soap_stream_fault(struct soap *soap, std::ostream& os)
     14865{ if (soap_check_state(soap))
     14866    os << "Error: soap struct state not initialized\n";
     14867  else if (soap->error)
     14868  { const char *c, *v = NULL, *s, **d;
     14869    d = soap_faultcode(soap);
     14870    if (!*d)
     14871      soap_set_fault(soap);
     14872    c = *d;
     14873    if (soap->version == 2)
     14874      v = *soap_faultsubcode(soap);
     14875    s = *soap_faultstring(soap);
     14876    d = soap_faultdetail(soap);
     14877    os << (soap->version ? "SOAP 1." : "Error ")
     14878       << (soap->version ? (int)soap->version : soap->error)
     14879       << " fault: " << c
     14880       << "[" << (v ? v : "no subcode") << "]"
     14881       << std::endl
     14882       << "\"" << (s ? s : "[no reason]") << "\""
     14883       << std::endl
     14884       << "Detail: " << (d && *d ? *d : "[no detail]")
     14885       << std::endl;
     14886  }
     14887}
     14888#endif
     14889#endif
     14890#endif
     14891 
     14892/******************************************************************************/
     14893#ifndef WITH_LEAN
     14894#ifndef WITH_NOSTDLIB
     14895SOAP_FMAC1
     14896char*
     14897SOAP_FMAC2
     14898soap_sprint_fault(struct soap *soap, char *buf, size_t len)
     14899{ if (soap_check_state(soap))
     14900    strncpy(buf, "Error: soap struct not initialized", len);
     14901  else if (soap->error)
     14902  { const char *c, *v = NULL, *s, **d;
     14903    d = soap_faultcode(soap);
     14904    if (!*d)
     14905      soap_set_fault(soap);
     14906    c = *d;
     14907    if (soap->version == 2)
     14908      v = *soap_faultsubcode(soap);
     14909    s = *soap_faultstring(soap);
     14910    d = soap_faultdetail(soap);
     14911#ifdef WIN32
     14912    _snprintf
     14913#else
     14914    snprintf
     14915#endif
     14916      (buf, len, "%s%d fault: %s [%s]\n\"%s\"\nDetail: %s\n", soap->version ? "SOAP 1." : "Error ", soap->version ? (int)soap->version : soap->error, c, v ? v : "no subcode", s ? s : "[no reason]", d && *d ? *d : "[no detail]");
     14917  }
     14918  return buf;
     14919}
     14920#endif
     14921#endif
     14922 
     14923/******************************************************************************/
     14924#ifndef PALM_1
     14925#ifndef WITH_NOSTDLIB
    1161314926SOAP_FMAC1
    1161414927void
     
    1161714930{
    1161814931#ifndef WITH_LEAN
    11619   int c;
    11620   if (soap->error && soap->buflen > 0)
    11621   { if (soap->bufidx == 0)
    11622       soap->bufidx = 1;
    11623     c = soap->buf[soap->bufidx - 1];
    11624     soap->buf[soap->bufidx - 1] = '\0';
    11625     if (soap->buflen - soap->bufidx > 1024)
    11626       soap->buf[soap->bufidx + 1024] = '\0';
     14932  int i, j, c1, c2;
     14933  if (soap->error && soap->bufidx <= soap->buflen && soap->buflen > 0 && soap->buflen <= SOAP_BUFLEN)
     14934  { i = (int)soap->bufidx - 1;
     14935    if (i <= 0)
     14936      i = 0;
     14937    c1 = soap->buf[i];
     14938    soap->buf[i] = '\0';
     14939    if ((int)soap->buflen >= i + 1024)
     14940      j = i + 1023;
    1162714941    else
    11628       soap->buf[soap->buflen - 1] = '\0';
    11629     fprintf(fd, "%s%c\n** HERE **\n", soap->buf, c);
     14942      j = (int)soap->buflen - 1;
     14943    c2 = soap->buf[j];
     14944    soap->buf[j] = '\0';
     14945    fprintf(fd, "%s%c\n<!-- ** HERE ** -->\n", soap->buf, c1);
    1163014946    if (soap->bufidx < soap->buflen)
    1163114947      fprintf(fd, "%s\n", soap->buf + soap->bufidx);
    11632   }
    11633 #endif
    11634 }
     14948    soap->buf[i] = c1;
     14949    soap->buf[j] = c2;
     14950  }
     14951#endif
     14952}
     14953#endif
    1163514954#endif
    1163614955 
     
    1164314962{ register struct soap_plugin *p;
    1164414963  register int r;
    11645   if (!(p = (struct soap_plugin*)SOAP_MALLOC(sizeof(struct soap_plugin))))
     14964  if (!(p = (struct soap_plugin*)SOAP_MALLOC(soap, sizeof(struct soap_plugin))))
    1164614965    return soap->error = SOAP_EOM;
    1164714966  p->id = NULL;
     
    1165714976  }
    1165814977  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not register plugin '%s': plugin returned error %d (or fdelete callback not set)\n", p->id?p->id:"?", r));
    11659   SOAP_FREE(p);
     14978  SOAP_FREE(soap, p);
    1166014979  return r;
    1166114980}
     
    1168915008#endif
    1169015009
     15010/******************************************************************************\
     15011 *
     15012 *      C++ soap struct methods
     15013 *
     15014\******************************************************************************/
     15015
     15016#ifdef __cplusplus
     15017soap::soap()
     15018{ soap_init(this);
     15019}
     15020#endif
     15021
     15022/******************************************************************************/
     15023#ifdef __cplusplus
     15024soap::soap(soap_mode m)
     15025{ soap_init1(this, m);
     15026}
     15027#endif
     15028
     15029/******************************************************************************/
     15030#ifdef __cplusplus
     15031soap::soap(soap_mode im, soap_mode om)
     15032{ soap_init2(this, im, om);
     15033}
     15034#endif
     15035
     15036/******************************************************************************/
     15037#ifdef __cplusplus
     15038soap::soap(struct soap& soap)
     15039{ soap_copy_context(this, &soap);
     15040}
     15041#endif
     15042
     15043/******************************************************************************/
     15044#ifdef __cplusplus
     15045soap::~soap()
     15046{ soap_destroy(this);
     15047  soap_end(this);
     15048  soap_done(this);
     15049}
     15050#endif
     15051
     15052/******************************************************************************/
Note: See TracChangeset for help on using the changeset viewer.