hti/PC_Tools/HTIGateway/stdsoap/stdsoap2.cpp
branchRCL_3
changeset 59 8ad140f3dd41
parent 0 a03f92240627
equal deleted inserted replaced
49:7fdc9a71d314 59:8ad140f3dd41
       
     1 /*
       
     2 
       
     3 stdsoap2.c[pp] 2.7.6b
       
     4 
       
     5 gSOAP runtime
       
     6 
       
     7 gSOAP XML Web services tools
       
     8 Copyright (C) 2000-2005, Robert van Engelen, Genivia Inc., All Rights Reserved.
       
     9 This part of the software is released under one of the following licenses:
       
    10 GPL, the gSOAP public license, or Genivia's license for commercial use.
       
    11 --------------------------------------------------------------------------------
       
    12 Contributors:
       
    13 
       
    14 Wind River Systems, Inc., for the following additions:
       
    15   - vxWorks compatible
       
    16 --------------------------------------------------------------------------------
       
    17 gSOAP public license.
       
    18 
       
    19 The contents of this file are subject to the gSOAP Public License Version 1.3
       
    20 (the "License"); you may not use this file except in compliance with the
       
    21 License. You may obtain a copy of the License at
       
    22 http://www.cs.fsu.edu/~engelen/soaplicense.html
       
    23 Software distributed under the License is distributed on an "AS IS" basis,
       
    24 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
       
    25 for the specific language governing rights and limitations under the License.
       
    26 
       
    27 The Initial Developer of the Original Code is Robert A. van Engelen.
       
    28 Copyright (C) 2000-2005, Robert van Engelen, Genivia Inc., All Rights Reserved.
       
    29 --------------------------------------------------------------------------------
       
    30 GPL license.
       
    31 
       
    32 This program is free software; you can redistribute it and/or modify it under
       
    33 the terms of the GNU General Public License as published by the Free Software
       
    34 Foundation; either version 2 of the License, or (at your option) any later
       
    35 version.
       
    36 
       
    37 This program is distributed in the hope that it will be useful, but WITHOUT ANY
       
    38 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
       
    39 PARTICULAR PURPOSE. See the GNU General Public License for more details.
       
    40 
       
    41 You should have received a copy of the GNU General Public License along with
       
    42 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
       
    43 Place, Suite 330, Boston, MA 02111-1307 USA
       
    44 
       
    45 Author contact information:
       
    46 engelen@genivia.com / engelen@acm.org
       
    47 --------------------------------------------------------------------------------
       
    48 A commercial use license is available from Genivia, Inc., contact@genivia.com
       
    49 --------------------------------------------------------------------------------
       
    50 
       
    51 Installation note:
       
    52 
       
    53 Win32 build needs winsock.dll (Visual C++ "wsock32.lib")
       
    54 To do this in Visual C++ 6.0, go to "Project", "settings", select the "Link"
       
    55 tab (the project file needs to be selected in the file view) and add
       
    56 "wsock32.lib" to the "Object/library modules" entry
       
    57 
       
    58 On Mac OS X with gcc (GCC) 3.1 20020420 (prerelease) you MUST compile with
       
    59 -fstack_check when using -O2 because gcc 3.1 has a bug that smashes the stack
       
    60 when locally allocated data exceeds 64K.
       
    61 
       
    62 */
       
    63 
       
    64 #include "stdsoap2.h"
       
    65 
       
    66 #ifdef __cplusplus
       
    67 SOAP_SOURCE_STAMP("@(#) stdsoap2.cpp ver 2.7.6b 2005-08-26 12:00:00 GMT")
       
    68 extern "C" {
       
    69 #else
       
    70 SOAP_SOURCE_STAMP("@(#) stdsoap2.c ver 2.7.6b 2005-08-26 12:00:00 GMT")
       
    71 #endif
       
    72 
       
    73 /* 8bit character representing unknown/nonrepresentable character data (e.g. not supported by current locale with multibyte support enabled) */
       
    74 #ifndef SOAP_UNKNOWN_CHAR
       
    75 #define SOAP_UNKNOWN_CHAR (127)
       
    76 #endif
       
    77 
       
    78 /*      EOF=-1 */
       
    79 #define SOAP_LT (soap_wchar)(-2) /* XML character '<' */
       
    80 #define SOAP_TT (soap_wchar)(-3) /* XML character '</' */
       
    81 #define SOAP_GT (soap_wchar)(-4) /* XML character '>' */
       
    82 #define SOAP_QT (soap_wchar)(-5) /* XML character '"' */
       
    83 #define SOAP_AP (soap_wchar)(-6) /* XML character ''' */
       
    84 
       
    85 #define SOAP_BOM (soap_wchar)(0xFEFF) /* UTF BOM is Unicode FEFF */
       
    86 
       
    87 #define soap_blank(c)		((c) >= 0 && (c) <= 32)
       
    88 #define soap_notblank(c)	((c) > 32)
       
    89 #define soap_hash_ptr(p)	(((unsigned long)(p) >> 3) & (SOAP_PTRHASH - 1))
       
    90 
       
    91 static int soap_isxdigit(int);
       
    92 static soap_wchar soap_char(struct soap*);
       
    93 
       
    94 #ifndef WITH_NOIDREF
       
    95 static void soap_update_ptrs(struct soap*, char*, char*, long);
       
    96 static int soap_has_copies(struct soap*, const char*, const char*);
       
    97 static void soap_init_iht(struct soap*);
       
    98 static void soap_free_iht(struct soap*);
       
    99 static void soap_init_pht(struct soap*);
       
   100 static void soap_free_pht(struct soap*);
       
   101 #endif
       
   102 
       
   103 #ifdef SOAP_DEBUG
       
   104 static void soap_init_logs(struct soap*);
       
   105 static void soap_close_logfile(struct soap*, int);
       
   106 static void soap_set_logfile(struct soap*, int, const char*);
       
   107 static void soap_free_mht(struct soap*);
       
   108 static void soap_track_unlink(struct soap*, const void*);
       
   109 #endif
       
   110 
       
   111 static int soap_set_error(struct soap*, const char*, const char*, const char*, const char*, int);
       
   112 static int soap_copy_fault(struct soap*, const char*, const char*, const char*, const char*);
       
   113 static int soap_getattrval(struct soap*, char*, size_t, soap_wchar);
       
   114 static void *fplugin(struct soap*, const char*);
       
   115 
       
   116 #ifndef WITH_LEAN
       
   117 static const char *soap_set_validation_fault(struct soap*, const char*, const char*);
       
   118 static int soap_isnumeric(struct soap*, const char*);
       
   119 static time_t soap_timegm(struct tm*);
       
   120 static struct soap_nlist *soap_lookup_ns(struct soap *soap, const char *tag, size_t n);
       
   121 static struct soap_nlist *soap_push_ns(struct soap *soap, const char *id, const char *ns, short utilized);
       
   122 static void soap_pop_ns(struct soap *soap);
       
   123 static void soap_utilize_ns(struct soap *soap, const char *tag, size_t n);
       
   124 #endif
       
   125 
       
   126 #ifndef WITH_LEANER
       
   127 static struct soap_multipart *soap_new_multipart(struct soap*, struct soap_multipart**, struct soap_multipart**, char*, size_t);
       
   128 static int soap_putdimefield(struct soap*, const char*, size_t);
       
   129 static char *soap_getdimefield(struct soap*, size_t);
       
   130 static void soap_select_mime_boundary(struct soap*);
       
   131 static int soap_valid_mime_boundary(struct soap*);
       
   132 static int soap_match_cid(const char*, const char*);
       
   133 static void soap_resolve_attachment(struct soap*, struct soap_multipart*);
       
   134 #endif
       
   135 
       
   136 #ifdef WITH_GZIP
       
   137 static int soap_getgziphdr(struct soap*);
       
   138 #endif
       
   139 
       
   140 #ifdef WITH_OPENSSL
       
   141 static void ssl_init();
       
   142 static int ssl_auth_init(struct soap*);
       
   143 static int ssl_verify_callback(int, X509_STORE_CTX*);
       
   144 static int ssl_password(char*, int, int, void *);
       
   145 static const char *ssl_error(struct soap*, int);
       
   146 /* This callback is included for future references. It should not be deleted
       
   147 static DH *ssl_tmp_dh(SSL*, int, int);
       
   148 */
       
   149 #endif
       
   150 
       
   151 #if !defined(WITH_NOHTTP) || !defined(WITH_LEANER)
       
   152 static const char *soap_decode(char*, size_t, const char*, const char*);
       
   153 #endif
       
   154 
       
   155 #ifndef WITH_NOHTTP
       
   156 static soap_wchar soap_getchunkchar(struct soap*);
       
   157 static const char *http_error(struct soap*, int);
       
   158 static int http_post(struct soap*, const char*, const char*, int, const char*, const char*, size_t);
       
   159 static int http_get(struct soap*);
       
   160 static int http_send_header(struct soap*, const char*);
       
   161 static int http_post_header(struct soap*, const char*, const char*);
       
   162 static int http_response(struct soap*, int, size_t);
       
   163 static int http_parse(struct soap*);
       
   164 static int http_parse_header(struct soap*, const char*, const char*);
       
   165 #endif
       
   166 
       
   167 #ifndef WITH_NOIO
       
   168 static int fsend(struct soap*, const char*, size_t);
       
   169 static size_t frecv(struct soap*, char*, size_t);
       
   170 static int tcp_init(struct soap*);
       
   171 static const char *tcp_error(struct soap*);
       
   172 #ifndef WITH_IPV6
       
   173 static int tcp_gethost(struct soap*, const char *addr, struct in_addr *inaddr);
       
   174 #endif
       
   175 static int tcp_connect(struct soap*, const char *endpoint, const char *host, int port);
       
   176 static int tcp_accept(struct soap*, int, struct sockaddr*, int*);
       
   177 static int tcp_disconnect(struct soap*);
       
   178 static int tcp_closesocket(struct soap*, SOAP_SOCKET);
       
   179 static int tcp_shutdownsocket(struct soap*, SOAP_SOCKET, int);
       
   180 static const char *soap_strerror(struct soap*);
       
   181 #endif
       
   182 
       
   183 #ifdef VXWORKS
       
   184 static int vx_nonblocking = TRUE; /* ioctl argument */
       
   185 #endif
       
   186 
       
   187 #if defined(PALM) && !defined(PALM_2)
       
   188 unsigned short errno;
       
   189 #endif
       
   190 
       
   191 #ifndef PALM_1
       
   192 static const char soap_env1[42] = "http://schemas.xmlsoap.org/soap/envelope/";
       
   193 static const char soap_enc1[42] = "http://schemas.xmlsoap.org/soap/encoding/";
       
   194 static const char soap_env2[40] = "http://www.w3.org/2003/05/soap-envelope";
       
   195 static const char soap_enc2[40] = "http://www.w3.org/2003/05/soap-encoding";
       
   196 static const char soap_rpc[35] = "http://www.w3.org/2003/05/soap-rpc";
       
   197 #endif
       
   198 
       
   199 #ifndef PALM_1
       
   200 const struct soap_double_nan soap_double_nan = {0xFFFFFFFF, 0xFFFFFFFF};
       
   201 static const char soap_base64o[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
       
   202 static const char soap_base64i[81] = "\76XXX\77\64\65\66\67\70\71\72\73\74\75XXXXXXX\00\01\02\03\04\05\06\07\10\11\12\13\14\15\16\17\20\21\22\23\24\25\26\27\30\31XXXXXX\32\33\34\35\36\37\40\41\42\43\44\45\46\47\50\51\52\53\54\55\56\57\60\61\62\63";
       
   203 #endif
       
   204 
       
   205 #ifndef WITH_LEAN
       
   206 static const char soap_indent[11] = "\n\t\t\t\t\t\t\t\t\t";
       
   207 /* Alternative indentation form for SOAP_XML_INDENT:
       
   208 static const char soap_indent[21] = "\n                   ";
       
   209 */
       
   210 #endif
       
   211 
       
   212 static const char soap_padding[3] = "\0\0";
       
   213 #define SOAP_STR_PADDING (soap_padding)
       
   214 #define SOAP_STR_EOS (soap_padding)
       
   215 #define SOAP_NON_NULL (soap_padding)
       
   216 
       
   217 #ifndef WITH_LEAN
       
   218 static const struct soap_code_map html_entity_codes[] = /* entities for XHTML parsing */
       
   219 { { 160, "nbsp" },
       
   220   { 161, "iexcl" },
       
   221   { 162, "cent" },
       
   222   { 163, "pound" },
       
   223   { 164, "curren" },
       
   224   { 165, "yen" },
       
   225   { 166, "brvbar" },
       
   226   { 167, "sect" },
       
   227   { 168, "uml" },
       
   228   { 169, "copy" },
       
   229   { 170, "ordf" },
       
   230   { 171, "laquo" },
       
   231   { 172, "not" },
       
   232   { 173, "shy" },
       
   233   { 174, "reg" },
       
   234   { 175, "macr" },
       
   235   { 176, "deg" },
       
   236   { 177, "plusmn" },
       
   237   { 178, "sup2" },
       
   238   { 179, "sup3" },
       
   239   { 180, "acute" },
       
   240   { 181, "micro" },
       
   241   { 182, "para" },
       
   242   { 183, "middot" },
       
   243   { 184, "cedil" },
       
   244   { 185, "sup1" },
       
   245   { 186, "ordm" },
       
   246   { 187, "raquo" },
       
   247   { 188, "frac14" },
       
   248   { 189, "frac12" },
       
   249   { 190, "frac34" },
       
   250   { 191, "iquest" },
       
   251   { 192, "Agrave" },
       
   252   { 193, "Aacute" },
       
   253   { 194, "Acirc" },
       
   254   { 195, "Atilde" },
       
   255   { 196, "Auml" },
       
   256   { 197, "Aring" },
       
   257   { 198, "AElig" },
       
   258   { 199, "Ccedil" },
       
   259   { 200, "Egrave" },
       
   260   { 201, "Eacute" },
       
   261   { 202, "Ecirc" },
       
   262   { 203, "Euml" },
       
   263   { 204, "Igrave" },
       
   264   { 205, "Iacute" },
       
   265   { 206, "Icirc" },
       
   266   { 207, "Iuml" },
       
   267   { 208, "ETH" },
       
   268   { 209, "Ntilde" },
       
   269   { 210, "Ograve" },
       
   270   { 211, "Oacute" },
       
   271   { 212, "Ocirc" },
       
   272   { 213, "Otilde" },
       
   273   { 214, "Ouml" },
       
   274   { 215, "times" },
       
   275   { 216, "Oslash" },
       
   276   { 217, "Ugrave" },
       
   277   { 218, "Uacute" },
       
   278   { 219, "Ucirc" },
       
   279   { 220, "Uuml" },
       
   280   { 221, "Yacute" },
       
   281   { 222, "THORN" },
       
   282   { 223, "szlig" },
       
   283   { 224, "agrave" },
       
   284   { 225, "aacute" },
       
   285   { 226, "acirc" },
       
   286   { 227, "atilde" },
       
   287   { 228, "auml" },
       
   288   { 229, "aring" },
       
   289   { 230, "aelig" },
       
   290   { 231, "ccedil" },
       
   291   { 232, "egrave" },
       
   292   { 233, "eacute" },
       
   293   { 234, "ecirc" },
       
   294   { 235, "euml" },
       
   295   { 236, "igrave" },
       
   296   { 237, "iacute" },
       
   297   { 238, "icirc" },
       
   298   { 239, "iuml" },
       
   299   { 240, "eth" },
       
   300   { 241, "ntilde" },
       
   301   { 242, "ograve" },
       
   302   { 243, "oacute" },
       
   303   { 244, "ocirc" },
       
   304   { 245, "otilde" },
       
   305   { 246, "ouml" },
       
   306   { 247, "divide" },
       
   307   { 248, "oslash" },
       
   308   { 249, "ugrave" },
       
   309   { 250, "uacute" },
       
   310   { 251, "ucirc" },
       
   311   { 252, "uuml" },
       
   312   { 253, "yacute" },
       
   313   { 254, "thorn" },
       
   314   { 255, "yuml" },
       
   315   {   0, NULL }
       
   316 };
       
   317 #endif
       
   318 
       
   319 #ifndef WITH_NOIO
       
   320 #ifndef WITH_LEAN
       
   321 static const struct soap_code_map h_error_codes[] =
       
   322 {
       
   323 #ifdef HOST_NOT_FOUND   
       
   324   { HOST_NOT_FOUND, "Host not found" },
       
   325 #endif
       
   326 #ifdef TRY_AGAIN
       
   327   { TRY_AGAIN, "Try Again" },
       
   328 #endif
       
   329 #ifdef NO_RECOVERY  
       
   330   { NO_RECOVERY, "No Recovery" },
       
   331 #endif
       
   332 #ifdef NO_DATA
       
   333   { NO_DATA, "No Data" },
       
   334 #endif
       
   335 #ifdef NO_ADDRESS
       
   336   { NO_ADDRESS, "No Address" },
       
   337 #endif
       
   338   { 0, NULL }
       
   339 };
       
   340 #endif
       
   341 #endif
       
   342 
       
   343 #ifndef WITH_NOHTTP
       
   344 #ifndef WITH_LEAN
       
   345 static const struct soap_code_map h_http_error_codes[] =
       
   346 { { 201, "Created" },
       
   347   { 202, "Accepted" },
       
   348   { 203, "Non-Authoritative Information" },
       
   349   { 204, "No Content" },
       
   350   { 205, "Reset Content" },
       
   351   { 206, "Partial Content" },
       
   352   { 300, "Multiple Choices" },
       
   353   { 301, "Moved Permanently" },
       
   354   { 302, "Found" },
       
   355   { 303, "See Other" },
       
   356   { 304, "Not Modified" },
       
   357   { 305, "Use Proxy" },
       
   358   { 307, "Temporary Redirect" },
       
   359   { 400, "Bad Request" },
       
   360   { 401, "Unauthorized" },
       
   361   { 402, "Payment Required" },
       
   362   { 403, "Forbidden" },
       
   363   { 404, "Not Found" },
       
   364   { 405, "Method Not Allowed" },
       
   365   { 406, "Not Acceptable" },
       
   366   { 407, "Proxy Authentication Required" },
       
   367   { 408, "Request Time-out" },
       
   368   { 409, "Conflict" },
       
   369   { 410, "Gone" },
       
   370   { 411, "Length Required" },
       
   371   { 412, "Precondition Failed" },
       
   372   { 413, "Request Entity Too Large" },
       
   373   { 414, "Request-URI Too Large" },
       
   374   { 415, "Unsupported Media Type" },
       
   375   { 416, "Requested range not satisfiable" },
       
   376   { 417, "Expectation Failed" },
       
   377   { 500, "Internal Server Error" },
       
   378   { 501, "Not Implemented" },
       
   379   { 502, "Bad Gateway" },
       
   380   { 503, "Service Unavailable" },
       
   381   { 504, "Gateway Time-out" },
       
   382   { 505, "HTTP Version not supported" },
       
   383   {   0, NULL }
       
   384 };
       
   385 #endif
       
   386 #endif
       
   387 
       
   388 #ifdef WITH_OPENSSL
       
   389 static const struct soap_code_map h_ssl_error_codes[] =
       
   390 {
       
   391 #define _SSL_ERROR(e) { e, #e }
       
   392   _SSL_ERROR(SSL_ERROR_SSL),
       
   393   _SSL_ERROR(SSL_ERROR_ZERO_RETURN),
       
   394   _SSL_ERROR(SSL_ERROR_WANT_READ),
       
   395   _SSL_ERROR(SSL_ERROR_WANT_WRITE),
       
   396   _SSL_ERROR(SSL_ERROR_WANT_CONNECT),
       
   397   _SSL_ERROR(SSL_ERROR_WANT_X509_LOOKUP),
       
   398   _SSL_ERROR(SSL_ERROR_SYSCALL),
       
   399   { 0, NULL }
       
   400 };
       
   401 #endif
       
   402 
       
   403 #ifndef WITH_LEANER
       
   404 static const struct soap_code_map mime_codes[] =
       
   405 { { SOAP_MIME_7BIT,		"7bit" },
       
   406   { SOAP_MIME_8BIT,		"8bit" },
       
   407   { SOAP_MIME_BINARY,		"binary" },
       
   408   { SOAP_MIME_QUOTED_PRINTABLE, "quoted-printable" },
       
   409   { SOAP_MIME_BASE64,		"base64" },
       
   410   { SOAP_MIME_IETF_TOKEN,	"ietf-token" },
       
   411   { SOAP_MIME_X_TOKEN,		"x-token" },
       
   412   { 0,				NULL }
       
   413 };
       
   414 #endif
       
   415 
       
   416 #ifdef WIN32
       
   417 static int tcp_done = 0;
       
   418 #endif
       
   419 
       
   420 /******************************************************************************/
       
   421 #ifndef WITH_NOIO
       
   422 #ifndef PALM_1
       
   423 static int
       
   424 fsend(struct soap *soap, const char *s, size_t n)
       
   425 { register int nwritten;
       
   426 #if defined(__cplusplus) && !defined(WITH_LEAN)
       
   427   if (soap->os)
       
   428   { soap->os->write(s, n);
       
   429     if (soap->os->good())
       
   430       return SOAP_OK;
       
   431     return SOAP_EOF;
       
   432   }
       
   433 #endif
       
   434   while (n)
       
   435   { if (soap_valid_socket(soap->socket))
       
   436     { 
       
   437 #ifndef WITH_LEAN
       
   438       if (soap->send_timeout)
       
   439       { struct timeval timeout;
       
   440         fd_set fd;
       
   441         if (soap->send_timeout > 0)
       
   442         { timeout.tv_sec = soap->send_timeout;
       
   443           timeout.tv_usec = 0;
       
   444         }
       
   445         else
       
   446         { timeout.tv_sec = -soap->send_timeout/1000000;
       
   447           timeout.tv_usec = -soap->send_timeout%1000000;
       
   448         }
       
   449         FD_ZERO(&fd);
       
   450         FD_SET((SOAP_SOCKET)soap->socket, &fd);
       
   451         for (;;)
       
   452         { register int r = select((SOAP_SOCKET)(soap->socket + 1), NULL, &fd, &fd, &timeout);
       
   453           if (r > 0)
       
   454             break;
       
   455           if (!r)
       
   456           { soap->errnum = 0;
       
   457             return SOAP_EOF;
       
   458           }
       
   459           if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EAGAIN)
       
   460           { soap->errnum = soap_socket_errno;
       
   461             return SOAP_EOF;
       
   462           }
       
   463         }
       
   464       }
       
   465 #endif
       
   466 #ifdef WITH_OPENSSL
       
   467       if (soap->ssl)
       
   468         nwritten = SSL_write(soap->ssl, s, n);
       
   469       else if (soap->bio)
       
   470         nwritten = BIO_write(soap->bio, s, n);
       
   471       else
       
   472 #endif
       
   473 #ifdef WITH_UDP
       
   474       if ((soap->omode & SOAP_IO_UDP))
       
   475       { if (soap->peerlen)
       
   476 	  nwritten = sendto((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags, (struct sockaddr*)&soap->peer, soap->peerlen);
       
   477         else
       
   478 	  nwritten = send((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags);
       
   479 	/* retry and back-off algorithm */
       
   480 	/* TODO: this is not very clear from specs so verify and limit conditions under which we should loop (e.g. ENOBUFS) */
       
   481 	if (nwritten < 0)
       
   482         { struct timeval timeout;
       
   483           fd_set fd;
       
   484 	  int udp_repeat;
       
   485 	  int udp_delay;
       
   486           if ((soap->connect_flags & SO_BROADCAST))
       
   487 	    udp_repeat = 3; /* SOAP-over-UDP MULTICAST_UDP_REPEAT - 1 */
       
   488           else
       
   489 	    udp_repeat = 1; /* SOAP-over-UDP UNICAST_UDP_REPEAT - 1 */
       
   490 	  udp_delay = (soap_random % 201) + 50; /* UDP_MIN_DELAY .. UDP_MAX_DELAY */
       
   491 	  do
       
   492           { timeout.tv_sec = 0;
       
   493             timeout.tv_usec = 1000 * udp_delay; /* ms */
       
   494             FD_ZERO(&fd);
       
   495             FD_SET((SOAP_SOCKET)soap->socket, &fd);
       
   496             select((SOAP_SOCKET)(soap->socket + 1), NULL, NULL, &fd, &timeout);
       
   497 	    if (soap->peerlen)
       
   498 	      nwritten = sendto((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags, (struct sockaddr*)&soap->peer, soap->peerlen);
       
   499             else
       
   500 	      nwritten = send((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags);
       
   501 	    udp_delay <<= 1;
       
   502 	    if (udp_delay > 500) /* UDP_UPPER_DELAY */
       
   503 	      udp_delay = 500;
       
   504 	  }
       
   505 	  while (nwritten < 0 && --udp_repeat > 0);
       
   506 	}
       
   507       }
       
   508       else
       
   509 #endif
       
   510 #ifndef PALM
       
   511         nwritten = send((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags);
       
   512 #else
       
   513         nwritten = send((SOAP_SOCKET)soap->socket, (void*)s, n, soap->socket_flags);
       
   514 #endif
       
   515       if (nwritten <= 0)
       
   516       {
       
   517 #ifdef WITH_OPENSSL
       
   518 	int err;
       
   519         if (soap->ssl && (err = SSL_get_error(soap->ssl, nwritten)) != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
       
   520           return SOAP_EOF;
       
   521 #endif
       
   522         if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EWOULDBLOCK && soap_socket_errno != SOAP_EAGAIN)
       
   523         { soap->errnum = soap_socket_errno;
       
   524           return SOAP_EOF;
       
   525         }
       
   526         nwritten = 0; /* and call write() again */
       
   527       }
       
   528     }
       
   529     else
       
   530     {
       
   531 #ifdef WITH_FASTCGI
       
   532       nwritten = fwrite((void*)s, 1, n, stdout);
       
   533       fflush(stdout);
       
   534 #else
       
   535 #ifdef UNDER_CE
       
   536       nwritten = fwrite(s, 1, n, soap->sendfd);
       
   537 #else
       
   538 #ifdef VXWORKS
       
   539 #ifdef WMW_RPM_IO
       
   540       if (soap->rpmreqid)
       
   541         nwritten = (httpBlockPut(soap->rpmreqid, s, n) == 0) ? n : -1; 
       
   542       else
       
   543         nwritten = fwrite(s, sizeof(char), n, fdopen(soap->sendfd, "w"));
       
   544 #else
       
   545       nwritten = fwrite(s, sizeof(char), n, fdopen(soap->sendfd, "w"));
       
   546 #endif /* WMW_RPM_IO */
       
   547 #else
       
   548       nwritten = write((SOAP_SOCKET)soap->sendfd, s, n);
       
   549 #endif
       
   550 #endif
       
   551 #endif
       
   552       if (nwritten <= 0)
       
   553       { if (soap_errno != SOAP_EINTR && soap_errno != SOAP_EWOULDBLOCK && soap_errno != SOAP_EAGAIN)
       
   554         { soap->errnum = soap_errno;
       
   555           return SOAP_EOF;
       
   556         }
       
   557         nwritten = 0; /* and call write() again */
       
   558       }
       
   559     }
       
   560     n -= nwritten;
       
   561     s += nwritten;
       
   562   }
       
   563   return SOAP_OK;
       
   564 }
       
   565 #endif
       
   566 #endif
       
   567 
       
   568 /******************************************************************************/
       
   569 #ifndef PALM_1
       
   570 SOAP_FMAC1
       
   571 int
       
   572 SOAP_FMAC2
       
   573 soap_send_raw(struct soap *soap, const char *s, size_t n)
       
   574 { if (!n)
       
   575     return SOAP_OK;
       
   576   if (soap->mode & SOAP_IO_LENGTH)
       
   577   { soap->count += n;
       
   578 #ifndef WITH_LEANER
       
   579     if (soap->fpreparesend && (soap->mode & SOAP_IO) != SOAP_IO_STORE)
       
   580       return soap->error = soap->fpreparesend(soap, s, n);
       
   581 #endif
       
   582     return SOAP_OK;
       
   583   }
       
   584   if (soap->mode & SOAP_IO)
       
   585   { register size_t i = SOAP_BUFLEN - soap->bufidx;
       
   586     while (n >= i)
       
   587     { memcpy(soap->buf + soap->bufidx, s, i);
       
   588       soap->bufidx = SOAP_BUFLEN;
       
   589       if (soap_flush(soap))
       
   590         return soap->error;
       
   591       s += i;
       
   592       n -= i;
       
   593       i = SOAP_BUFLEN;
       
   594     }
       
   595     memcpy(soap->buf + soap->bufidx, s, n);
       
   596     soap->bufidx += n;
       
   597     return SOAP_OK;
       
   598   }
       
   599   return soap_flush_raw(soap, s, n);
       
   600 }
       
   601 #endif
       
   602 
       
   603 /******************************************************************************/
       
   604 #ifndef PALM_1
       
   605 SOAP_FMAC1
       
   606 int
       
   607 SOAP_FMAC2
       
   608 soap_flush(struct soap *soap)
       
   609 { register int n = soap->bufidx;
       
   610   if (n)
       
   611   { soap->bufidx = 0;
       
   612 #ifdef WITH_ZLIB
       
   613     if (soap->mode & SOAP_ENC_ZLIB)
       
   614     { soap->d_stream.next_in = (Byte*)soap->buf;
       
   615       soap->d_stream.avail_in = (unsigned int)n;
       
   616 #ifdef WITH_GZIP
       
   617       soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)n);
       
   618 #endif
       
   619       do
       
   620       { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflating %u bytes\n", soap->d_stream.avail_in));
       
   621         if (deflate(&soap->d_stream, Z_NO_FLUSH) != Z_OK)
       
   622         { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to deflate: %s\n", soap->d_stream.msg?soap->d_stream.msg:""));
       
   623           return soap->error = SOAP_ZLIB_ERROR;
       
   624         }
       
   625         if (!soap->d_stream.avail_out)
       
   626         { if (soap_flush_raw(soap, soap->z_buf, SOAP_BUFLEN))
       
   627             return soap->error;
       
   628           soap->d_stream.next_out = (Byte*)soap->z_buf;
       
   629           soap->d_stream.avail_out = SOAP_BUFLEN;
       
   630         }
       
   631       } while (soap->d_stream.avail_in);
       
   632     }
       
   633     else
       
   634 #endif
       
   635       return soap_flush_raw(soap, soap->buf, n);
       
   636   }
       
   637   return SOAP_OK;
       
   638 }
       
   639 #endif
       
   640 
       
   641 /******************************************************************************/
       
   642 #ifndef PALM_1
       
   643 SOAP_FMAC1
       
   644 int
       
   645 SOAP_FMAC2
       
   646 soap_flush_raw(struct soap *soap, const char *s, size_t n)
       
   647 { if ((soap->mode & SOAP_IO) == SOAP_IO_STORE)
       
   648   { register char *t;
       
   649     if (!(t = (char*)soap_push_block(soap, n)))
       
   650       return soap->error = SOAP_EOM;
       
   651     memcpy(t, s, n);
       
   652 #ifndef WITH_LEANER
       
   653     if (soap->fpreparesend)
       
   654       return soap->error = soap->fpreparesend(soap, s, n);
       
   655 #endif
       
   656     return SOAP_OK;
       
   657   }
       
   658 #ifndef WITH_LEANER
       
   659   if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK)
       
   660   { char t[16];
       
   661     sprintf(t, "\r\n%lX\r\n" + (soap->chunksize ? 0 : 2), (unsigned long)n);
       
   662     DBGMSG(SENT, t, strlen(t));
       
   663     if ((soap->error = soap->fsend(soap, t, strlen(t))))
       
   664       return soap->error;
       
   665     soap->chunksize += n;
       
   666   }
       
   667   DBGMSG(SENT, s, n);
       
   668 #endif
       
   669   return soap->error = soap->fsend(soap, s, n);
       
   670 }
       
   671 #endif
       
   672 
       
   673 /******************************************************************************/
       
   674 #ifndef PALM_1
       
   675 SOAP_FMAC1
       
   676 int
       
   677 SOAP_FMAC2
       
   678 soap_send(struct soap *soap, const char *s)
       
   679 { if (s)
       
   680     return soap_send_raw(soap, s, strlen(s));
       
   681   return SOAP_OK;
       
   682 }
       
   683 #endif
       
   684 
       
   685 /******************************************************************************/
       
   686 #ifndef WITH_LEANER
       
   687 #ifndef PALM_1
       
   688 SOAP_FMAC1
       
   689 int
       
   690 SOAP_FMAC2
       
   691 soap_send2(struct soap *soap, const char *s1, const char *s2)
       
   692 { if (soap_send(soap, s1))
       
   693     return soap->error;
       
   694   return soap_send(soap, s2);
       
   695 }
       
   696 #endif
       
   697 #endif
       
   698 
       
   699 /******************************************************************************/
       
   700 #ifndef WITH_LEANER
       
   701 #ifndef PALM_1
       
   702 SOAP_FMAC1
       
   703 int
       
   704 SOAP_FMAC2
       
   705 soap_send3(struct soap *soap, const char *s1, const char *s2, const char *s3)
       
   706 { if (soap_send(soap, s1)
       
   707    || soap_send(soap, s2))
       
   708     return soap->error;
       
   709   return soap_send(soap, s3);
       
   710 }
       
   711 #endif
       
   712 #endif
       
   713 
       
   714 /******************************************************************************/
       
   715 #ifndef WITH_NOIO
       
   716 #ifndef PALM_1
       
   717 static size_t
       
   718 frecv(struct soap *soap, char *s, size_t n)
       
   719 { register int r;
       
   720   soap->errnum = 0;
       
   721   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "frecv\n"));
       
   722 #if defined(__cplusplus) && !defined(WITH_LEAN)
       
   723   if (soap->is)
       
   724   { if (soap->is->good())
       
   725       return soap->is->read(s, n).gcount();
       
   726     return 0;
       
   727   }
       
   728 #endif
       
   729   if (soap_valid_socket(soap->socket))
       
   730   { for (;;)
       
   731     { 
       
   732 #ifndef WITH_LEAN
       
   733       if (soap->recv_timeout)
       
   734       { struct timeval timeout;
       
   735         fd_set fd;
       
   736         if (soap->recv_timeout > 0)
       
   737         { timeout.tv_sec = soap->recv_timeout;
       
   738           timeout.tv_usec = 0;
       
   739         }
       
   740         else
       
   741         { timeout.tv_sec = -soap->recv_timeout/1000000;
       
   742           timeout.tv_usec = -soap->recv_timeout%1000000;
       
   743         }
       
   744         FD_ZERO(&fd);
       
   745         FD_SET((SOAP_SOCKET)soap->socket, &fd);
       
   746 		DBGLOG(TEST, SOAP_MESSAGE(fdebug, "select\n"));
       
   747         for (;;)
       
   748         { r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout);
       
   749 		DBGLOG(TEST, SOAP_MESSAGE(fdebug, "r=%d\n", r));
       
   750           if (r > 0)
       
   751             break;
       
   752           if (!r)
       
   753 	  { soap->errnum = 0;
       
   754             return 0;
       
   755           }
       
   756 	  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Socket err %d\n", soap_socket_errno));
       
   757           if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EAGAIN)
       
   758 	  { soap->errnum = soap_socket_errno;
       
   759             return 0;
       
   760           }
       
   761         }
       
   762 		DBGLOG(TEST, SOAP_MESSAGE(fdebug, "select end\n"));
       
   763       }
       
   764 #endif
       
   765 #ifdef WITH_OPENSSL
       
   766       if (soap->ssl)
       
   767       { int err;
       
   768 	r = SSL_read(soap->ssl, s, n);
       
   769         if (r > 0)
       
   770           return (size_t)r;
       
   771 	err = SSL_get_error(soap->ssl, r);
       
   772 	if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
       
   773           return 0;
       
   774       }
       
   775       else if (soap->bio)
       
   776       { r = BIO_read(soap->bio, s, n);
       
   777         if (r > 0)
       
   778           return (size_t)r;
       
   779         return 0;
       
   780       }
       
   781       else
       
   782 #endif
       
   783       { 
       
   784 #ifdef WITH_UDP
       
   785         if ((soap->omode & SOAP_IO_UDP))
       
   786         { SOAP_SOCKLEN_T k = (SOAP_SOCKLEN_T)sizeof(soap->peer);
       
   787 	  memset((void*)&soap->peer, 0, sizeof(soap->peer));
       
   788           r = recvfrom((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags, (struct sockaddr*)&soap->peer, &k);	/* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */
       
   789 	  soap->peerlen = (size_t)k;
       
   790 #ifndef WITH_IPV6
       
   791           soap->ip = ntohl(soap->peer.sin_addr.s_addr);
       
   792           soap->port = (int)ntohs(soap->peer.sin_port);
       
   793 #endif
       
   794         }
       
   795 	else
       
   796 #endif
       
   797 		DBGLOG(TEST, SOAP_MESSAGE(fdebug, "recv\n"));
       
   798           r = recv((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags);
       
   799 		  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "r=%d\n", r));
       
   800         if (r >= 0)
       
   801           return (size_t)r;
       
   802 		DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Socket err %d\n", soap_socket_errno));
       
   803         if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EAGAIN && soap_socket_errno != SOAP_EWOULDBLOCK)
       
   804         { soap->errnum = soap_socket_errno;
       
   805           return 0;
       
   806         }
       
   807       }
       
   808 #ifndef WITH_LEAN
       
   809       { struct timeval timeout;
       
   810         fd_set fd;
       
   811         timeout.tv_sec = 0;
       
   812         timeout.tv_usec = 10000;
       
   813         FD_ZERO(&fd);
       
   814         FD_SET((SOAP_SOCKET)soap->socket, &fd);
       
   815 #ifdef WITH_OPENSSL
       
   816         if (soap->ssl && SSL_get_error(soap->ssl, r) == SSL_ERROR_WANT_WRITE)
       
   817           r = select((SOAP_SOCKET)(soap->socket + 1), NULL, &fd, &fd, &timeout);
       
   818         else
       
   819           r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout);
       
   820 #else
       
   821         r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout);
       
   822 #endif
       
   823         if (r < 0 && soap_socket_errno != SOAP_EINTR)
       
   824         { soap->errnum = soap_socket_errno;
       
   825           return 0;
       
   826         }
       
   827       }
       
   828 #endif
       
   829     }
       
   830   }
       
   831 #ifdef WITH_FASTCGI
       
   832   return fread(s, 1, n, stdin);
       
   833 #else
       
   834 #ifdef UNDER_CE
       
   835   return fread(s, 1, n, soap->recvfd);
       
   836 #else
       
   837 #ifdef WMW_RPM_IO
       
   838   if (soap->rpmreqid)
       
   839     r = httpBlockRead(soap->rpmreqid, s, n);
       
   840 #endif
       
   841   r = read((SOAP_SOCKET)soap->recvfd, s, n);
       
   842   if (r >= 0)
       
   843     return (size_t)r;
       
   844   soap->errnum = soap_errno;
       
   845   return 0;
       
   846 #endif
       
   847 #endif
       
   848 }
       
   849 #endif
       
   850 #endif
       
   851 
       
   852 /******************************************************************************/
       
   853 #ifndef WITH_NOHTTP
       
   854 #ifndef PALM_1
       
   855 static soap_wchar
       
   856 soap_getchunkchar(struct soap *soap)
       
   857 { if (soap->bufidx < soap->buflen)
       
   858     return soap->buf[soap->bufidx++];
       
   859   soap->bufidx = 0;
       
   860   soap->buflen = soap->chunkbuflen = soap->frecv(soap, soap->buf, SOAP_BUFLEN);
       
   861   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes from socket %d\n", (unsigned int)soap->buflen, soap->socket));
       
   862   DBGMSG(RECV, soap->buf, soap->buflen);
       
   863   if (soap->buflen)
       
   864     return soap->buf[soap->bufidx++];
       
   865   return EOF;
       
   866 }
       
   867 #endif
       
   868 #endif
       
   869 
       
   870 /******************************************************************************/
       
   871 #ifndef PALM_1
       
   872 static int
       
   873 soap_isxdigit(int c)
       
   874 { return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
       
   875 }
       
   876 #endif
       
   877 
       
   878 /******************************************************************************/
       
   879 #ifndef PALM_1
       
   880 SOAP_FMAC1
       
   881 int
       
   882 SOAP_FMAC2
       
   883 soap_recv_raw(struct soap *soap)
       
   884 { register size_t ret;
       
   885 #ifdef WITH_ZLIB
       
   886   if (soap->mode & SOAP_ENC_ZLIB)
       
   887   { if (soap->d_stream.next_out == Z_NULL)
       
   888       return EOF;
       
   889     if (soap->d_stream.avail_in || !soap->d_stream.avail_out)
       
   890     { register int r;
       
   891       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflating\n"));
       
   892       soap->d_stream.next_out = (Byte*)soap->buf;
       
   893       soap->d_stream.avail_out = SOAP_BUFLEN;
       
   894       r = inflate(&soap->d_stream, Z_NO_FLUSH);
       
   895       if (r == Z_OK || r == Z_STREAM_END)
       
   896       { soap->bufidx = 0;
       
   897         soap->buflen = SOAP_BUFLEN - soap->d_stream.avail_out;
       
   898         if (soap->zlib_in == SOAP_ZLIB_GZIP)
       
   899           soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)soap->buflen);
       
   900         if (r == Z_STREAM_END)
       
   901         { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %lu->%lu bytes\n", soap->d_stream.total_in, soap->d_stream.total_out));
       
   902           soap->z_ratio_in = (float)soap->d_stream.total_in / (float)soap->d_stream.total_out;
       
   903           soap->d_stream.next_out = Z_NULL;
       
   904         }
       
   905         if (soap->buflen)
       
   906         { soap->count += soap->buflen;
       
   907           return SOAP_OK;
       
   908         }
       
   909       }
       
   910       else if (r != Z_BUF_ERROR)
       
   911       { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflate error: %s\n", soap->d_stream.msg?soap->d_stream.msg:""));
       
   912         soap->d_stream.next_out = Z_NULL;
       
   913 	soap->error = SOAP_ZLIB_ERROR;
       
   914         return EOF;
       
   915       }
       
   916     }
       
   917 zlib_again:
       
   918     if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK && !soap->chunksize)
       
   919     { memcpy(soap->buf, soap->z_buf, SOAP_BUFLEN);
       
   920       soap->buflen = soap->z_buflen;
       
   921     }
       
   922   }
       
   923 #endif
       
   924 #ifndef WITH_NOHTTP
       
   925   if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) /* read HTTP chunked transfer */
       
   926   { 
       
   927 chunk_again:
       
   928     if (soap->chunksize)
       
   929     { soap->buflen = ret = soap->frecv(soap, soap->buf, soap->chunksize > SOAP_BUFLEN ? SOAP_BUFLEN : soap->chunksize);
       
   930       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Getting chunk: read %u bytes\n", (unsigned int)ret));
       
   931       DBGMSG(RECV, soap->buf, ret);
       
   932       soap->bufidx = 0;
       
   933       soap->chunksize -= ret;
       
   934     }
       
   935     else
       
   936     { register soap_wchar c;
       
   937       char *t, tmp[8];
       
   938       t = tmp;
       
   939       if (!soap->chunkbuflen)
       
   940       { soap->chunkbuflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN);
       
   941         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes (chunked) from socket %d\n", (unsigned int)ret, soap->socket));
       
   942         DBGMSG(RECV, soap->buf, ret);
       
   943         soap->bufidx = 0;
       
   944         if (!ret)
       
   945           return soap->ahead = EOF;
       
   946       }
       
   947       else
       
   948         soap->bufidx = soap->buflen;
       
   949       soap->buflen = soap->chunkbuflen;
       
   950       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Getting chunk size (idx=%u len=%u)\n", (unsigned int)soap->bufidx, (unsigned int)soap->buflen));
       
   951       while (!soap_isxdigit((int)(c = soap_getchunkchar(soap))))
       
   952         if ((int)c == EOF)
       
   953 	  return soap->ahead = EOF;
       
   954       do
       
   955         *t++ = (char)c;
       
   956       while (soap_isxdigit((int)(c = soap_getchunkchar(soap))) && t - tmp < 7);
       
   957       while ((int)c != EOF && c != '\n')
       
   958         c = soap_getchunkchar(soap);
       
   959       if ((int)c == EOF)
       
   960         return soap->ahead = EOF;
       
   961       *t = '\0';
       
   962       soap->chunksize = soap_strtoul(tmp, &t, 16);
       
   963       if (!soap->chunksize)
       
   964       { soap->chunkbuflen = 0;
       
   965         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of chunked message\n"));
       
   966 	while ((int)c != EOF && c != '\n')
       
   967           c = soap_getchunkchar(soap);
       
   968         return soap->ahead = EOF;
       
   969       }
       
   970       soap->buflen = soap->bufidx + soap->chunksize;
       
   971       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Moving buf len to idx=%u len=%u (%s)\n", (unsigned int)soap->bufidx, (unsigned int)soap->buflen, tmp));
       
   972       if (soap->buflen > soap->chunkbuflen)
       
   973       { soap->buflen = soap->chunkbuflen;
       
   974         soap->chunksize -= soap->buflen - soap->bufidx;
       
   975         soap->chunkbuflen = 0;
       
   976         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Passed end of buffer for chunked HTTP (%u bytes left)\n", (unsigned int)(soap->buflen - soap->bufidx)));
       
   977       }
       
   978       else if (soap->chunkbuflen)
       
   979         soap->chunksize = 0;
       
   980       ret = soap->buflen - soap->bufidx;
       
   981       if (!ret)
       
   982         goto chunk_again;
       
   983     }
       
   984   }
       
   985   else
       
   986 #endif
       
   987   { soap->bufidx = 0;
       
   988     soap->buflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN);
       
   989     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes from socket %d\n", (unsigned int)ret, soap->socket));
       
   990     DBGMSG(RECV, soap->buf, ret);
       
   991   }
       
   992 #ifndef WITH_LEANER
       
   993   if (soap->fpreparerecv && (soap->error = soap->fpreparerecv(soap, soap->buf, ret)))
       
   994     return soap->error;
       
   995 #endif
       
   996 #ifdef WITH_ZLIB
       
   997   if (soap->mode & SOAP_ENC_ZLIB)
       
   998   { register int r;
       
   999     memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN);
       
  1000     soap->d_stream.next_in = (Byte*)(soap->z_buf + soap->bufidx);
       
  1001     soap->d_stream.avail_in = (unsigned int)ret;
       
  1002     soap->d_stream.next_out = (Byte*)soap->buf;
       
  1003     soap->d_stream.avail_out = SOAP_BUFLEN;
       
  1004     r = inflate(&soap->d_stream, Z_NO_FLUSH);
       
  1005     if (r == Z_OK || r == Z_STREAM_END)
       
  1006     { soap->bufidx = 0;
       
  1007       soap->z_buflen = soap->buflen;
       
  1008       soap->buflen = ret = SOAP_BUFLEN - soap->d_stream.avail_out;
       
  1009       if (soap->zlib_in == SOAP_ZLIB_GZIP)
       
  1010         soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)soap->buflen);
       
  1011       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %u bytes\n", (unsigned int)ret));
       
  1012       if (!ret)
       
  1013         goto zlib_again;
       
  1014       if (r == Z_STREAM_END)
       
  1015       { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %lu->%lu bytes\n", soap->d_stream.total_in, soap->d_stream.total_out));
       
  1016         soap->z_ratio_in = (float)soap->d_stream.total_in / (float)soap->d_stream.total_out;
       
  1017         soap->d_stream.next_out = Z_NULL;
       
  1018       }
       
  1019     }
       
  1020     else
       
  1021     { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to inflate: (%d) %s\n", r, soap->d_stream.msg?soap->d_stream.msg:""));
       
  1022       soap->d_stream.next_out = Z_NULL;
       
  1023       soap->error = SOAP_ZLIB_ERROR;
       
  1024       return EOF;
       
  1025     }
       
  1026   }
       
  1027 #endif
       
  1028   soap->count += ret;
       
  1029   return !ret;
       
  1030 }
       
  1031 #endif
       
  1032 
       
  1033 /******************************************************************************/
       
  1034 #ifndef PALM_1
       
  1035 SOAP_FMAC1
       
  1036 int
       
  1037 SOAP_FMAC2
       
  1038 soap_recv(struct soap *soap)
       
  1039 { 
       
  1040 #ifndef WITH_LEANER
       
  1041   if (soap->mode & SOAP_ENC_DIME)
       
  1042   { if (soap->dime.buflen)
       
  1043     { char *s;
       
  1044       int i;
       
  1045       unsigned char tmp[12];
       
  1046       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME hdr for chunked DIME is in buffer\n"));
       
  1047       soap->count += soap->dime.buflen - soap->buflen;
       
  1048       soap->buflen = soap->dime.buflen;
       
  1049       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Skip padding (%ld bytes)\n", -(long)soap->dime.size&3));
       
  1050       for (i = -(long)soap->dime.size&3; i > 0; i--)
       
  1051       { soap->bufidx++;
       
  1052         if (soap->bufidx >= soap->buflen)
       
  1053           if (soap_recv_raw(soap))
       
  1054             return EOF;
       
  1055       }
       
  1056       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME hdr for next chunk\n"));
       
  1057       s = (char*)tmp;
       
  1058       for (i = 12; i > 0; i--)
       
  1059       { *s++ = soap->buf[soap->bufidx++];
       
  1060         if (soap->bufidx >= soap->buflen)
       
  1061           if (soap_recv_raw(soap))
       
  1062             return EOF;
       
  1063       }
       
  1064       soap->dime.flags = tmp[0] & 0x7;
       
  1065       soap->dime.size = ((size_t)tmp[8] << 24) | ((size_t)tmp[9] << 16) | ((size_t)tmp[10] << 8) | ((size_t)tmp[11]);
       
  1066       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME chunk (%u bytes)\n", (unsigned int)soap->dime.size));
       
  1067       if (soap->dime.flags & SOAP_DIME_CF)
       
  1068       { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "More chunking\n"));
       
  1069         soap->dime.chunksize = soap->dime.size;
       
  1070         if (soap->buflen - soap->bufidx >= soap->dime.size)
       
  1071         { soap->dime.buflen = soap->buflen;
       
  1072           soap->buflen = soap->bufidx + soap->dime.chunksize;
       
  1073         }
       
  1074         else
       
  1075           soap->dime.chunksize -= soap->buflen - soap->bufidx;
       
  1076       }
       
  1077       else
       
  1078       { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Last chunk\n"));
       
  1079         soap->dime.buflen = 0;
       
  1080         soap->dime.chunksize = 0;
       
  1081       }
       
  1082       soap->count = soap->buflen - soap->bufidx;
       
  1083       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%u bytes remaining\n", (unsigned int)soap->count));
       
  1084       return SOAP_OK;
       
  1085     }
       
  1086     if (soap->dime.chunksize)
       
  1087     { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get next DIME hdr for chunked DIME (%u bytes chunk)\n", (unsigned int)soap->dime.chunksize));
       
  1088       if (soap_recv_raw(soap))
       
  1089         return EOF;
       
  1090       if (soap->buflen - soap->bufidx >= soap->dime.chunksize)
       
  1091       { soap->dime.buflen = soap->buflen;
       
  1092         soap->count -= soap->buflen - soap->bufidx - soap->dime.chunksize;
       
  1093         soap->buflen = soap->bufidx + soap->dime.chunksize;
       
  1094       }
       
  1095       else
       
  1096         soap->dime.chunksize -= soap->buflen - soap->bufidx;
       
  1097       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%lu bytes remaining, count=%u\n", (unsigned long)(soap->buflen-soap->bufidx), (unsigned int)soap->count));
       
  1098       return SOAP_OK;
       
  1099     }
       
  1100   }
       
  1101 #endif
       
  1102   return soap_recv_raw(soap);
       
  1103 }
       
  1104 #endif
       
  1105 
       
  1106 /******************************************************************************/
       
  1107 #ifndef PALM_1
       
  1108 SOAP_FMAC1
       
  1109 soap_wchar
       
  1110 SOAP_FMAC2
       
  1111 soap_getchar(struct soap *soap)
       
  1112 { register soap_wchar c;
       
  1113   c = soap->ahead;
       
  1114   if (c)
       
  1115   { if (c != EOF)
       
  1116       soap->ahead = 0;
       
  1117     return c;
       
  1118   }
       
  1119   return soap_get1(soap);
       
  1120 }
       
  1121 #endif
       
  1122 
       
  1123 /******************************************************************************/
       
  1124 #ifndef PALM_1
       
  1125 SOAP_FMAC1
       
  1126 const struct soap_code_map*
       
  1127 SOAP_FMAC2
       
  1128 soap_code(const struct soap_code_map *map, const char *str)
       
  1129 { if (str)
       
  1130   { while (map->string)
       
  1131     { if (!strcmp(str, map->string)) /* case sensitive */
       
  1132         return map;
       
  1133       map++;
       
  1134     }
       
  1135   }
       
  1136   return NULL;
       
  1137 }
       
  1138 #endif
       
  1139 
       
  1140 /******************************************************************************/
       
  1141 #ifndef PALM_1
       
  1142 SOAP_FMAC1
       
  1143 long
       
  1144 SOAP_FMAC2
       
  1145 soap_int_code(const struct soap_code_map *map, const char *str, long other)
       
  1146 { while (map->string)
       
  1147   { if (!soap_tag_cmp(str, map->string)) /* case insensitive */
       
  1148       return map->code;
       
  1149     map++;
       
  1150   }
       
  1151   return other;
       
  1152 }
       
  1153 #endif
       
  1154 
       
  1155 /******************************************************************************/
       
  1156 #ifndef PALM_1
       
  1157 SOAP_FMAC1
       
  1158 const char*
       
  1159 SOAP_FMAC2
       
  1160 soap_str_code(const struct soap_code_map *map, long code)
       
  1161 { while (map->code != code && map->string)
       
  1162     map++;
       
  1163   return map->string;
       
  1164 }
       
  1165 #endif
       
  1166 
       
  1167 /******************************************************************************/
       
  1168 #ifndef PALM_1
       
  1169 static soap_wchar
       
  1170 soap_char(struct soap *soap)
       
  1171 { char tmp[8];
       
  1172   register int i;
       
  1173   register soap_wchar c;
       
  1174   register char *s = tmp;
       
  1175   for (i = 0; i < 7; i++)
       
  1176   { c = soap_get1(soap);
       
  1177     if (c == ';' || (int)c == EOF)
       
  1178       break;
       
  1179     *s++ = (char)c;
       
  1180   }
       
  1181   *s = '\0';
       
  1182   if (*tmp == '#')
       
  1183   { if (tmp[1] == 'x' || tmp[1] == 'X')
       
  1184       return soap_strtol(tmp + 2, NULL, 16);
       
  1185     return atol(tmp + 1);
       
  1186   }
       
  1187   if (!strcmp(tmp, "lt"))
       
  1188     return '<';
       
  1189   if (!strcmp(tmp, "gt"))
       
  1190     return '>';
       
  1191   if (!strcmp(tmp, "amp"))
       
  1192     return '&';
       
  1193   if (!strcmp(tmp, "quot"))
       
  1194     return '"';
       
  1195   if (!strcmp(tmp, "apos"))
       
  1196     return '\'';
       
  1197 #ifndef WITH_LEAN
       
  1198   return (soap_wchar)soap_int_code(html_entity_codes, tmp, SOAP_UNKNOWN_CHAR);
       
  1199 #else
       
  1200   return SOAP_UNKNOWN_CHAR; /* use this to represent unknown code */
       
  1201 #endif
       
  1202 }
       
  1203 #endif
       
  1204 
       
  1205 /******************************************************************************/
       
  1206 #ifdef WITH_LEAN
       
  1207 soap_wchar
       
  1208 soap_get0(struct soap *soap)
       
  1209 { if (soap->bufidx >= soap->buflen && soap_recv(soap))
       
  1210     return EOF;
       
  1211   return (unsigned char)soap->buf[soap->bufidx];
       
  1212 }
       
  1213 #endif
       
  1214 
       
  1215 /******************************************************************************/
       
  1216 #ifdef WITH_LEAN
       
  1217 soap_wchar
       
  1218 soap_get1(struct soap *soap)
       
  1219 { if (soap->bufidx >= soap->buflen && soap_recv(soap))
       
  1220     return EOF;
       
  1221   return (unsigned char)soap->buf[soap->bufidx++];
       
  1222 }
       
  1223 #endif
       
  1224 
       
  1225 /******************************************************************************/
       
  1226 #ifndef PALM_1
       
  1227 SOAP_FMAC1
       
  1228 soap_wchar
       
  1229 SOAP_FMAC2
       
  1230 soap_get(struct soap *soap)
       
  1231 { register soap_wchar c;
       
  1232   c = soap->ahead;
       
  1233   if (c)
       
  1234   { if (c != EOF)
       
  1235       soap->ahead = 0;
       
  1236   }
       
  1237   else
       
  1238     c = soap_get1(soap);
       
  1239   for (;;)
       
  1240   { if (soap->cdata)
       
  1241     { if (c == ']')
       
  1242       { c = soap_get1(soap);
       
  1243         if (c == ']')
       
  1244         { soap->cdata = 0;
       
  1245           soap_get1(soap); /* skip > */
       
  1246           c = soap_get1(soap);
       
  1247         }
       
  1248 	else
       
  1249         { soap_revget1(soap);
       
  1250           return ']';
       
  1251         }
       
  1252       }
       
  1253       else
       
  1254         return c;
       
  1255     }
       
  1256     switch (c)
       
  1257     { case '<':
       
  1258         do c = soap_get1(soap);
       
  1259         while (soap_blank(c));
       
  1260         if (c == '!' || c == '?' || c == '%')
       
  1261         { register int k = 1;
       
  1262 	  if (c == '!')
       
  1263           { c = soap_get1(soap);
       
  1264             if (c == '[')
       
  1265             { do c = soap_get1(soap);
       
  1266               while ((int)c != EOF && c != '[');
       
  1267               if ((int)c == EOF)
       
  1268                 break;
       
  1269               soap->cdata = 1;
       
  1270               c = soap_get1(soap);
       
  1271 	      continue;
       
  1272             }
       
  1273             if (c == '-' && (c = soap_get1(soap)) == '-')
       
  1274             { do
       
  1275               { c = soap_get1(soap);
       
  1276                 if (c == '-' && (c = soap_get1(soap)) == '-')
       
  1277                   break;
       
  1278               } while ((int)c != EOF);
       
  1279             }
       
  1280           }
       
  1281           while ((int)c != EOF)
       
  1282           { if (c == '<')
       
  1283 	      k++;
       
  1284 	    else if (c == '>')
       
  1285 	    { if (--k <= 0)
       
  1286 	        break;
       
  1287 	    }
       
  1288 	    c = soap_get1(soap);
       
  1289 	  }
       
  1290 	  if ((int)c == EOF)
       
  1291 	    break;
       
  1292           c = soap_get1(soap);
       
  1293           continue;
       
  1294         }
       
  1295         if (c == '/')
       
  1296           return SOAP_TT;
       
  1297         soap_revget1(soap);
       
  1298         return SOAP_LT;
       
  1299       case '>':
       
  1300         return SOAP_GT;
       
  1301       case '"':
       
  1302         return SOAP_QT;
       
  1303       case '\'':
       
  1304         return SOAP_AP;
       
  1305       case '&':
       
  1306         return soap_char(soap) | 0x80000000;
       
  1307     }
       
  1308     break;
       
  1309   }
       
  1310   return c;
       
  1311 }
       
  1312 #endif
       
  1313 
       
  1314 /******************************************************************************/
       
  1315 #ifndef WITH_LEANER
       
  1316 #ifndef PALM_1
       
  1317 SOAP_FMAC1
       
  1318 int
       
  1319 SOAP_FMAC2
       
  1320 soap_move(struct soap *soap, long n)
       
  1321 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Moving %ld bytes forward\n", (long)n));
       
  1322   for (; n > 0; n--)
       
  1323     if ((int)soap_getchar(soap) == EOF)
       
  1324       return SOAP_EOF;
       
  1325   return SOAP_OK;
       
  1326 }
       
  1327 #endif
       
  1328 #endif
       
  1329 
       
  1330 /******************************************************************************/
       
  1331 #ifndef WITH_LEANER
       
  1332 #ifndef PALM_1
       
  1333 SOAP_FMAC1
       
  1334 size_t
       
  1335 SOAP_FMAC2
       
  1336 soap_tell(struct soap *soap)
       
  1337 { return soap->count - soap->buflen + soap->bufidx - (soap->ahead != 0);
       
  1338 }
       
  1339 #endif
       
  1340 #endif
       
  1341 
       
  1342 /******************************************************************************/
       
  1343 #ifndef PALM_1
       
  1344 SOAP_FMAC1
       
  1345 int
       
  1346 SOAP_FMAC2
       
  1347 soap_pututf8(struct soap *soap, register unsigned long c)
       
  1348 { char tmp[16];
       
  1349   if (c > 0 && c < 0x80)
       
  1350   { *tmp = (char)c;
       
  1351     return soap_send_raw(soap, tmp, 1);
       
  1352   }
       
  1353 #ifndef WITH_LEAN
       
  1354   if (soap->mode & SOAP_XML_CANONICAL)
       
  1355   { register char *t = tmp;
       
  1356     if (c < 0x0800)
       
  1357       *t++ = (char)(0xC0 | ((c >> 6) & 0x1F));
       
  1358     else
       
  1359     { if (c < 0x010000)
       
  1360         *t++ = (char)(0xE0 | ((c >> 12) & 0x0F));
       
  1361       else
       
  1362       { if (c < 0x200000)
       
  1363           *t++ = (char)(0xF0 | ((c >> 18) & 0x07));
       
  1364         else
       
  1365         { if (c < 0x04000000)
       
  1366             *t++ = (char)(0xF8 | ((c >> 24) & 0x03));
       
  1367           else
       
  1368           { *t++ = (char)(0xFC | ((c >> 30) & 0x01));
       
  1369             *t++ = (char)(0x80 | ((c >> 24) & 0x3F));
       
  1370           }
       
  1371           *t++ = (char)(0x80 | ((c >> 18) & 0x3F));
       
  1372         }     
       
  1373         *t++ = (char)(0x80 | ((c >> 12) & 0x3F));
       
  1374       }
       
  1375       *t++ = (char)(0x80 | ((c >> 6) & 0x3F));
       
  1376     }
       
  1377     *t++ = (char)(0x80 | (c & 0x3F));
       
  1378     *t = '\0';
       
  1379   }
       
  1380   else
       
  1381 #endif
       
  1382     sprintf(tmp, "&#%lu;", c);
       
  1383   return soap_send(soap, tmp);
       
  1384 }
       
  1385 #endif
       
  1386 
       
  1387 /******************************************************************************/
       
  1388 #ifndef PALM_1
       
  1389 SOAP_FMAC1
       
  1390 soap_wchar
       
  1391 SOAP_FMAC2
       
  1392 soap_getutf8(struct soap *soap)
       
  1393 { register soap_wchar c, c1, c2, c3, c4;
       
  1394   c = soap_get(soap);
       
  1395   if (c < 0x80 || (soap->mode & SOAP_ENC_LATIN))
       
  1396     return c;
       
  1397   c1 = soap_get(soap);
       
  1398   if (c1 < 0x80)
       
  1399   { soap_unget(soap, c1);
       
  1400     return c;
       
  1401   }
       
  1402   c1 &= 0x3F;
       
  1403   if (c < 0xE0)
       
  1404     return ((soap_wchar)(c & 0x1F) << 6) | c1;
       
  1405   c2 = (soap_wchar)soap_get1(soap) & 0x3F;
       
  1406   if (c < 0xF0)
       
  1407     return ((soap_wchar)(c & 0x0F) << 12) | (c1 << 6) | c2;
       
  1408   c3 = (soap_wchar)soap_get1(soap) & 0x3F;
       
  1409   if (c < 0xF8)
       
  1410     return ((soap_wchar)(c & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3;
       
  1411   c4 = (soap_wchar)soap_get1(soap) & 0x3F;
       
  1412   if (c < 0xFC)
       
  1413     return ((soap_wchar)(c & 0x03) << 24) | (c1 << 18) | (c2 << 12) | (c3 << 6) | c4;
       
  1414   return ((soap_wchar)(c & 0x01) << 30) | (c1 << 24) | (c2 << 18) | (c3 << 12) | (c4 << 6) | (soap_wchar)(soap_get1(soap) & 0x3F);
       
  1415 }
       
  1416 #endif
       
  1417 
       
  1418 /******************************************************************************/
       
  1419 #ifndef PALM_1
       
  1420 SOAP_FMAC1
       
  1421 int
       
  1422 SOAP_FMAC2
       
  1423 soap_puthex(struct soap *soap, const unsigned char *s, int n)
       
  1424 { char d[2];
       
  1425   register int i;
       
  1426 #ifdef WITH_DOM
       
  1427   if ((soap->mode & SOAP_XML_DOM) && soap->dom)
       
  1428   { if (!(soap->dom->data = soap_s2hex(soap, s, NULL, n)))
       
  1429       return soap->error;
       
  1430     return SOAP_OK;
       
  1431   }
       
  1432 #endif
       
  1433   for (i = 0; i < n; i++)
       
  1434   { register int m = *s++;
       
  1435     d[0] = (char)((m >> 4) + (m > 159 ? '7' : '0'));
       
  1436     m &= 0x0F;
       
  1437     d[1] = (char)(m + (m > 9 ? '7' : '0'));
       
  1438     if (soap_send_raw(soap, d, 2))
       
  1439       return soap->error;
       
  1440   }
       
  1441   return SOAP_OK;
       
  1442 }
       
  1443 #endif
       
  1444 
       
  1445 /******************************************************************************/
       
  1446 #ifndef PALM_1
       
  1447 SOAP_FMAC1
       
  1448 unsigned char*
       
  1449 SOAP_FMAC2
       
  1450 soap_gethex(struct soap *soap, int *n)
       
  1451 {
       
  1452 #ifdef WITH_DOM
       
  1453   if ((soap->mode & SOAP_XML_DOM) && soap->dom)
       
  1454   { soap->dom->data = soap_string_in(soap, 0, -1, -1);
       
  1455     return (unsigned char*)soap_hex2s(soap, soap->dom->data, NULL, 0, n);
       
  1456   }
       
  1457 #endif
       
  1458 #ifdef WITH_FAST
       
  1459   soap->labidx = 0;
       
  1460   for (;;)
       
  1461   { register char *s;
       
  1462     register int i, k;
       
  1463     if (soap_append_lab(soap, NULL, 0))
       
  1464       return NULL;
       
  1465     s = soap->labbuf + soap->labidx;
       
  1466     k = soap->lablen - soap->labidx;
       
  1467     soap->labidx = soap->lablen;
       
  1468     for (i = 0; i < k; i++)
       
  1469     { register char d1, d2;
       
  1470       register soap_wchar c;
       
  1471       c = soap_get(soap);
       
  1472       if (soap_isxdigit(c))
       
  1473       { d1 = (char)c;
       
  1474         c = soap_get(soap); 
       
  1475 	if (soap_isxdigit(c))
       
  1476           d2 = (char)c;
       
  1477         else 
       
  1478         { soap->error = SOAP_TYPE;
       
  1479           return NULL;
       
  1480         }
       
  1481       }
       
  1482       else
       
  1483       { unsigned char *p;
       
  1484         soap_unget(soap, c);
       
  1485         if (n)
       
  1486           *n = (int)(soap->lablen - k + i);
       
  1487         p = (unsigned char*)soap_malloc(soap, soap->lablen - k + i);
       
  1488 	if (p)
       
  1489 	  memcpy(p, soap->labbuf, soap->lablen - k + i);
       
  1490         return p;
       
  1491       }
       
  1492       *s++ = ((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0');
       
  1493     }
       
  1494   }
       
  1495 #else
       
  1496   if (soap_new_block(soap))
       
  1497     return NULL;
       
  1498   for (;;)
       
  1499   { register int i;
       
  1500     register char *s = (char*)soap_push_block(soap, SOAP_BLKLEN);
       
  1501     if (!s)
       
  1502     { soap_end_block(soap);
       
  1503       return NULL;
       
  1504     }
       
  1505     for (i = 0; i < SOAP_BLKLEN; i++)
       
  1506     { register char d1, d2;
       
  1507       register soap_wchar c = soap_get(soap);
       
  1508       if (soap_isxdigit(c))
       
  1509       { d1 = (char)c;
       
  1510         c = soap_get(soap); 
       
  1511 	if (soap_isxdigit(c))
       
  1512           d2 = (char)c;
       
  1513         else 
       
  1514         { soap_end_block(soap);
       
  1515 	  soap->error = SOAP_TYPE;
       
  1516           return NULL;
       
  1517         }
       
  1518       }
       
  1519       else
       
  1520       { unsigned char *p;
       
  1521         soap_unget(soap, c);
       
  1522         if (n)
       
  1523           *n = soap_size_block(soap, i);
       
  1524         p = (unsigned char*)soap_save_block(soap, NULL, 0);
       
  1525         return p;
       
  1526       }
       
  1527       *s++ = ((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0');
       
  1528     }
       
  1529   }
       
  1530 #endif
       
  1531 }
       
  1532 #endif
       
  1533 
       
  1534 /******************************************************************************/
       
  1535 #ifndef PALM_1
       
  1536 SOAP_FMAC1
       
  1537 int
       
  1538 SOAP_FMAC2
       
  1539 soap_putbase64(struct soap *soap, const unsigned char *s, int n)
       
  1540 { register int i;
       
  1541   register unsigned long m;
       
  1542   char d[4];
       
  1543   if (!s)
       
  1544     return SOAP_OK;
       
  1545 #ifdef WITH_DOM
       
  1546   if ((soap->mode & SOAP_XML_DOM) && soap->dom)
       
  1547   { if (!(soap->dom->data = soap_s2base64(soap, s, NULL, n)))
       
  1548       return soap->error;
       
  1549     return SOAP_OK;
       
  1550   }
       
  1551 #endif
       
  1552   for (; n > 2; n -= 3, s += 3)
       
  1553   { m = s[0];
       
  1554     m = (m << 8) | s[1];
       
  1555     m = (m << 8) | s[2];
       
  1556     for (i = 4; i > 0; m >>= 6)
       
  1557       d[--i] = soap_base64o[m & 0x3F];
       
  1558     if (soap_send_raw(soap, d, 4))
       
  1559       return soap->error;
       
  1560   }
       
  1561   if (n > 0)
       
  1562   { m = 0;
       
  1563     for (i = 0; i < n; i++)
       
  1564       m = (m << 8) | *s++;
       
  1565     for (; i < 3; i++)
       
  1566       m <<= 8;
       
  1567     for (i++; i > 0; m >>= 6)
       
  1568       d[--i] = soap_base64o[m & 0x3F];
       
  1569     for (i = 3; i > n; i--)
       
  1570       d[i] = '=';
       
  1571     if (soap_send_raw(soap, d, 4))
       
  1572       return soap->error;
       
  1573   }
       
  1574   return SOAP_OK;
       
  1575 }
       
  1576 #endif
       
  1577 
       
  1578 /******************************************************************************/
       
  1579 #ifndef PALM_1
       
  1580 SOAP_FMAC1
       
  1581 unsigned char*
       
  1582 SOAP_FMAC2
       
  1583 soap_getbase64(struct soap *soap, int *n, int malloc_flag)
       
  1584 { 
       
  1585 #ifdef WITH_DOM
       
  1586   if ((soap->mode & SOAP_XML_DOM) && soap->dom)
       
  1587   { soap->dom->data = soap_string_in(soap, 0, -1, -1);
       
  1588     return (unsigned char*)soap_base642s(soap, soap->dom->data, NULL, 0, n);
       
  1589   }
       
  1590 #endif
       
  1591 #ifdef WITH_FAST
       
  1592   soap->labidx = 0;
       
  1593   for (;;)
       
  1594   { register int i, k;
       
  1595     register char *s;
       
  1596     if (soap_append_lab(soap, NULL, 2))
       
  1597       return NULL;
       
  1598     s = soap->labbuf + soap->labidx;
       
  1599     k = 3 * ((soap->lablen - soap->labidx) / 3);
       
  1600     soap->labidx = 3 * (soap->lablen / 3);
       
  1601     if (!s)
       
  1602       return NULL;
       
  1603     for (i = 0; i < k; i += 3)
       
  1604     { register unsigned long m = 0;
       
  1605       register int j = 0;
       
  1606       do
       
  1607       { register soap_wchar c = soap_get(soap);
       
  1608         if (c == '=' || c < 0)
       
  1609         { unsigned char *p;
       
  1610           switch (j)
       
  1611           { case 2:
       
  1612               *s++ = (char)((m >> 4) & 0xFF);
       
  1613               i++;
       
  1614               break;
       
  1615             case 3:
       
  1616               *s++ = (char)((m >> 10) & 0xFF);
       
  1617               *s++ = (char)((m >> 2) & 0xFF);
       
  1618               i += 2;
       
  1619           }
       
  1620           if (n)
       
  1621             *n = (int)(soap->lablen - k + i - 1);
       
  1622           p = (unsigned char*)soap_malloc(soap, soap->lablen - k + i - 1);
       
  1623 	  if (p)
       
  1624 	    memcpy(p, soap->labbuf, soap->lablen - k + i - 1);
       
  1625           if (c >= 0)
       
  1626           { while ((int)((c = soap_get(soap)) != EOF) && c != SOAP_LT && c != SOAP_TT)
       
  1627               ;
       
  1628 	  }
       
  1629           soap_unget(soap, c);
       
  1630           return p;
       
  1631         }
       
  1632         c -= '+';
       
  1633         if (c >= 0 && c <= 79)
       
  1634         { m = (m << 6) + soap_base64i[c];
       
  1635           j++;
       
  1636         }
       
  1637       } while (j < 4);
       
  1638       *s++ = (char)((m >> 16) & 0xFF);
       
  1639       *s++ = (char)((m >> 8) & 0xFF);
       
  1640       *s++ = (char)(m & 0xFF);
       
  1641     }
       
  1642   }
       
  1643 #else
       
  1644   if (soap_new_block(soap))
       
  1645     return NULL;
       
  1646   for (;;)
       
  1647   { register int i;
       
  1648     register char *s = (char*)soap_push_block(soap, 3 * SOAP_BLKLEN); /* must be multiple of 3 */
       
  1649     if (!s)
       
  1650     { soap_end_block(soap);
       
  1651       return NULL;
       
  1652     }
       
  1653     for (i = 0; i < SOAP_BLKLEN; i++)
       
  1654     { register unsigned long m = 0;
       
  1655       register int j = 0;
       
  1656       do
       
  1657       { register soap_wchar c = soap_get(soap);
       
  1658         if (c == '=' || c < 0)
       
  1659         { unsigned char *p;
       
  1660           i *= 3;
       
  1661           switch (j)
       
  1662           { case 2:
       
  1663               *s++ = (char)((m >> 4) & 0xFF);
       
  1664               i++;
       
  1665               break;
       
  1666             case 3:
       
  1667               *s++ = (char)((m >> 10) & 0xFF);
       
  1668               *s++ = (char)((m >> 2) & 0xFF);
       
  1669               i += 2;
       
  1670           }
       
  1671           if (n)
       
  1672 	    *n = (int)soap_size_block(soap, i);
       
  1673           p = (unsigned char*)soap_save_block(soap, NULL, 0);
       
  1674           if (c >= 0)
       
  1675           { while ((int)((c = soap_get(soap)) != EOF) && c != SOAP_LT && c != SOAP_TT)
       
  1676               ;
       
  1677 	  }
       
  1678           soap_unget(soap, c);
       
  1679           return p;
       
  1680         }
       
  1681         c -= '+';
       
  1682         if (c >= 0 && c <= 79)
       
  1683         { m = (m << 6) + soap_base64i[c];
       
  1684           j++;
       
  1685         }
       
  1686       } while (j < 4);
       
  1687       *s++ = (char)((m >> 16) & 0xFF);
       
  1688       *s++ = (char)((m >> 8) & 0xFF);
       
  1689       *s++ = (char)(m & 0xFF);
       
  1690     }
       
  1691   }
       
  1692 #endif
       
  1693 }
       
  1694 #endif
       
  1695 
       
  1696 /******************************************************************************/
       
  1697 #ifndef WITH_LEANER
       
  1698 #ifndef PALM_1
       
  1699 SOAP_FMAC1
       
  1700 int
       
  1701 SOAP_FMAC2
       
  1702 soap_xop_forward(struct soap *soap, unsigned char **ptr, int *size, char **id, char **type, char **options)
       
  1703 { /* Check MTOM xop:Include element (within hex/base64Binary) */
       
  1704   /* TODO: this code to be obsoleted with new import/xop.h conventions */
       
  1705   int body = soap->body; /* should save type too? */
       
  1706   if (!soap_peek_element(soap))
       
  1707   { if (!soap_element_begin_in(soap, "xop:Include", 0) && *soap->href)
       
  1708     { if (soap_dime_forward(soap, ptr, size, id, type, options))
       
  1709         return soap->error;
       
  1710     }
       
  1711     if (soap->body && soap_element_end_in(soap, NULL))
       
  1712       return soap->error;
       
  1713   }
       
  1714   soap->body = body;
       
  1715   return SOAP_OK;
       
  1716 }
       
  1717 #endif
       
  1718 #endif
       
  1719 
       
  1720 /******************************************************************************/
       
  1721 #ifndef WITH_LEANER
       
  1722 #ifndef PALM_1
       
  1723 SOAP_FMAC1
       
  1724 int
       
  1725 SOAP_FMAC2
       
  1726 soap_dime_forward(struct soap *soap, unsigned char **ptr, int *size, char **id, char **type, char **options)
       
  1727 { struct soap_xlist *xp = (struct soap_xlist*)SOAP_MALLOC(soap, sizeof(struct soap_xlist));
       
  1728   *ptr = NULL;
       
  1729   *size = 0;
       
  1730   *id = soap_strdup(soap, soap->href);
       
  1731   *type = NULL;
       
  1732   *options = NULL;
       
  1733   if (!xp)
       
  1734     return soap->error = SOAP_EOM;
       
  1735   xp->next = soap->xlist;
       
  1736   xp->ptr = ptr;
       
  1737   xp->size = size;
       
  1738   xp->id = *id;
       
  1739   xp->type = type;
       
  1740   xp->options = options;
       
  1741   soap->xlist = xp;
       
  1742   return SOAP_OK;
       
  1743 }
       
  1744 #endif
       
  1745 #endif
       
  1746 
       
  1747 /******************************************************************************/
       
  1748 #ifndef PALM_1
       
  1749 SOAP_FMAC1
       
  1750 char *
       
  1751 SOAP_FMAC2
       
  1752 soap_strdup(struct soap *soap, const char *s)
       
  1753 { char *t = NULL;
       
  1754   if (s && (t = (char*)soap_malloc(soap, strlen(s) + 1)))
       
  1755     strcpy(t, s);
       
  1756   return t;
       
  1757 }
       
  1758 #endif
       
  1759 
       
  1760 /******************************************************************************/
       
  1761 #ifndef PALM_1
       
  1762 SOAP_FMAC1
       
  1763 int
       
  1764 SOAP_FMAC2
       
  1765 soap_new_block(struct soap *soap)
       
  1766 { struct soap_blist *p;
       
  1767   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "New block sequence (prev=%p)\n", soap->blist));
       
  1768   if (!(p = (struct soap_blist*)SOAP_MALLOC(soap, sizeof(struct soap_blist))))
       
  1769     return SOAP_EOM;   
       
  1770   p->next = soap->blist; 
       
  1771   p->ptr = NULL;
       
  1772   p->size = 0;
       
  1773   soap->blist = p;
       
  1774   return SOAP_OK;
       
  1775 }
       
  1776 #endif
       
  1777 
       
  1778 /******************************************************************************/
       
  1779 #ifndef PALM_1
       
  1780 SOAP_FMAC1
       
  1781 void*
       
  1782 SOAP_FMAC2
       
  1783 soap_push_block(struct soap *soap, size_t n)
       
  1784 { char *p;
       
  1785   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));
       
  1786   if (!(p = (char*)SOAP_MALLOC(soap, n + sizeof(char*) + sizeof(size_t))))
       
  1787   { soap->error = SOAP_EOM;
       
  1788     return NULL;
       
  1789   }
       
  1790   *(char**)p = soap->blist->ptr;
       
  1791   *(size_t*)(p + sizeof(char*)) = n;
       
  1792   soap->blist->ptr = p;
       
  1793   soap->blist->size += n;
       
  1794   return p + sizeof(char*) + sizeof(size_t);
       
  1795 }
       
  1796 #endif
       
  1797 
       
  1798 /******************************************************************************/
       
  1799 #ifndef PALM_1
       
  1800 SOAP_FMAC1
       
  1801 void
       
  1802 SOAP_FMAC2
       
  1803 soap_pop_block(struct soap *soap)
       
  1804 { char *p;
       
  1805   if (!soap->blist->ptr)
       
  1806     return;
       
  1807   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Pop block\n"));
       
  1808   p = soap->blist->ptr;
       
  1809   soap->blist->size -= *(size_t*)(p + sizeof(char*));
       
  1810   soap->blist->ptr = *(char**)p;
       
  1811   SOAP_FREE(soap, p);
       
  1812 }
       
  1813 #endif
       
  1814 
       
  1815 /******************************************************************************/
       
  1816 #ifndef WITH_NOIDREF
       
  1817 #ifndef PALM_1
       
  1818 static void
       
  1819 soap_update_ptrs(struct soap *soap, char *start, char *end, long offset)
       
  1820 { int i;
       
  1821   register struct soap_ilist *ip;
       
  1822   register struct soap_flist *fp;
       
  1823 #ifndef WITH_LEANER
       
  1824   register struct soap_xlist *xp;
       
  1825 #endif
       
  1826   register void *p, **q;
       
  1827   for (i = 0; i < SOAP_IDHASH; i++)
       
  1828   { for (ip = soap->iht[i]; ip; ip = ip->next)
       
  1829     { if (ip->ptr && (char*)ip->ptr >= start && (char*)ip->ptr < end)
       
  1830       { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update id='%s' %p -> %p\n", ip->id, ip->ptr, (char*)ip->ptr + offset));
       
  1831         ip->ptr = (char*)ip->ptr + offset;
       
  1832       }
       
  1833       for (q = &ip->link; q; q = (void**)p)
       
  1834       { p = *q;
       
  1835         if (p && (char*)p >= start && (char*)p < end)
       
  1836         { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Link update id='%s' %p\n", ip->id, p));
       
  1837           *q = (char*)p + offset;
       
  1838         }
       
  1839       }
       
  1840       for (q = &ip->copy; q; q = (void**)p)
       
  1841       { p = *q;
       
  1842         if (p && (char*)p >= start && (char*)p < end)
       
  1843         { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy chain update id='%s' %p\n", ip->id, p));
       
  1844           *q = (char*)p + offset;
       
  1845         }
       
  1846       }
       
  1847       for (fp = ip->flist; fp; fp = fp->next)
       
  1848       { if ((char*)fp->ptr >= start && (char*)fp->ptr < end)
       
  1849         { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy list update id='%s' %p\n", ip->id, fp));
       
  1850           fp->ptr = (char*)fp->ptr + offset;
       
  1851         }
       
  1852       }
       
  1853     }
       
  1854   }
       
  1855 #ifndef WITH_LEANER
       
  1856   for (xp = soap->xlist; xp; xp = xp->next)
       
  1857   { if (xp->ptr && (char*)xp->ptr >= start && (char*)xp->ptr < end)
       
  1858     { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update id='%s' %p -> %p\n", xp->id?xp->id:"", xp->ptr, (char*)xp->ptr + offset));
       
  1859       xp->ptr = (unsigned char**)((char*)xp->ptr + offset);
       
  1860       xp->size = (int*)((char*)xp->size + offset);
       
  1861       xp->type = (char**)((char*)xp->type + offset);
       
  1862       xp->options = (char**)((char*)xp->options + offset);
       
  1863     }
       
  1864   }
       
  1865 #endif
       
  1866 }
       
  1867 #endif
       
  1868 #endif
       
  1869 
       
  1870 /******************************************************************************/
       
  1871 #ifndef WITH_NOIDREF
       
  1872 #ifndef PALM_1
       
  1873 static int
       
  1874 soap_has_copies(struct soap *soap, register const char *start, register const char *end)
       
  1875 { register int i;
       
  1876   register struct soap_ilist *ip;
       
  1877   register struct soap_flist *fp;
       
  1878   register const char *p;
       
  1879   for (i = 0; i < SOAP_IDHASH; i++)
       
  1880   { for (ip = soap->iht[i]; ip; ip = ip->next)
       
  1881     { for (p = (const char*)ip->copy; p; p = *(const char**)p)
       
  1882         if (p >= start && p < end)
       
  1883           return SOAP_ERR;
       
  1884       for (fp = ip->flist; fp; fp = fp->next)
       
  1885         if ((const char*)fp->ptr >= start && (const char*)fp->ptr < end)
       
  1886 	  return SOAP_ERR;
       
  1887     }
       
  1888   }
       
  1889   return SOAP_OK;
       
  1890 }
       
  1891 #endif
       
  1892 #endif
       
  1893 
       
  1894 /******************************************************************************/
       
  1895 #ifndef WITH_NOIDREF
       
  1896 #ifndef PALM_1
       
  1897 SOAP_FMAC1
       
  1898 int
       
  1899 SOAP_FMAC2
       
  1900 soap_resolve(struct soap *soap)
       
  1901 { register int i;
       
  1902   register struct soap_ilist *ip;
       
  1903   register struct soap_flist *fp;
       
  1904   short flag;
       
  1905   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving forwarded data\n"));
       
  1906   for (i = 0; i < SOAP_IDHASH; i++)
       
  1907   { for (ip = soap->iht[i]; ip; ip = ip->next)
       
  1908     { if (ip->ptr)
       
  1909       { register void *p, **q, *r;
       
  1910         q = (void**)ip->link;
       
  1911         ip->link = NULL;
       
  1912         r = ip->ptr;
       
  1913         DBGLOG(TEST, if (q) SOAP_MESSAGE(fdebug, "Traversing link chain to resolve id='%s'\n", ip->id));
       
  1914         while (q)
       
  1915         { p = *q;
       
  1916           *q = r;
       
  1917           DBGLOG(TEST,SOAP_MESSAGE(fdebug, "... link %p -> %p\n", q, r));
       
  1918           q = (void**)p;
       
  1919         }
       
  1920       }
       
  1921       else if (*ip->id == '#')
       
  1922       { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Missing data for id='%s'\n", ip->id));
       
  1923         strcpy(soap->id, ip->id + 1);
       
  1924         return soap->error = SOAP_MISSING_ID;
       
  1925       }
       
  1926     }
       
  1927   }
       
  1928   do
       
  1929   { flag = 0;
       
  1930     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolution phase\n"));
       
  1931     for (i = 0; i < SOAP_IDHASH; i++)
       
  1932     { for (ip = soap->iht[i]; ip; ip = ip->next)
       
  1933       { if (ip->ptr && !soap_has_copies(soap, (const char*)ip->ptr, (const char*)ip->ptr + ip->size))
       
  1934         { if (ip->copy)
       
  1935           { register void *p, **q = (void**)ip->copy;
       
  1936             DBGLOG(TEST, if (q) SOAP_MESSAGE(fdebug, "Traversing copy chain to resolve id='%s'\n", ip->id));
       
  1937             ip->copy = NULL;
       
  1938             do
       
  1939             { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "... copy %p -> %p (%u bytes)\n", ip->ptr, q, (unsigned int)ip->size));
       
  1940 	      p = *q;
       
  1941               memcpy(q, ip->ptr, ip->size);
       
  1942               q = (void**)p;
       
  1943             } while (q);
       
  1944 	    flag = 1;
       
  1945 	  }
       
  1946           for (fp = ip->flist; fp; fp = ip->flist)
       
  1947           { register unsigned int k = fp->level;
       
  1948 	    register void *p = ip->ptr;
       
  1949             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));
       
  1950 	    while (ip->level < k)
       
  1951             { register void **q = (void**)soap_malloc(soap, sizeof(void*));  
       
  1952 	      if (!q)
       
  1953 	        return soap->error;
       
  1954 	      *q = p;
       
  1955               DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level, new location=%p holds=%p...\n", q, *q));
       
  1956               p = (void*)q;
       
  1957               k--;
       
  1958             }
       
  1959 	    if (fp->fcopy)
       
  1960 	      fp->fcopy(soap, ip->type, fp->type, fp->ptr, p, ip->size);
       
  1961 	    else
       
  1962 	      soap_fcopy(soap, ip->type, fp->type, fp->ptr, p, ip->size);
       
  1963 	    ip->flist = fp->next;
       
  1964 	    SOAP_FREE(soap, fp);
       
  1965 	    flag = 1;
       
  1966 	  }
       
  1967         }
       
  1968       }
       
  1969     }
       
  1970   } while (flag);
       
  1971 #ifdef SOAP_DEBUG
       
  1972   for (i = 0; i < SOAP_IDHASH; i++)
       
  1973   { for (ip = soap->iht[i]; ip; ip = ip->next)
       
  1974     { if (ip->copy || ip->flist)
       
  1975       { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolution error: forwarded data for id='%s' could not be propagated, please report this problem to the developers\n", ip->id));
       
  1976       }
       
  1977     }
       
  1978   }
       
  1979 #endif
       
  1980   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolution done\n"));
       
  1981   return SOAP_OK;
       
  1982 }
       
  1983 #endif
       
  1984 #endif
       
  1985 
       
  1986 /******************************************************************************/
       
  1987 #ifndef PALM_1
       
  1988 SOAP_FMAC1
       
  1989 size_t
       
  1990 SOAP_FMAC2
       
  1991 soap_size_block(struct soap *soap, size_t n)
       
  1992 { if (soap->blist->ptr)
       
  1993   { soap->blist->size -= *(size_t*)(soap->blist->ptr + sizeof(char*)) - n;
       
  1994     *(size_t*)(soap->blist->ptr + sizeof(char*)) = n;
       
  1995   }
       
  1996   return soap->blist->size;
       
  1997 }
       
  1998 #endif
       
  1999 
       
  2000 /******************************************************************************/
       
  2001 #ifndef PALM_1
       
  2002 SOAP_FMAC1
       
  2003 char*
       
  2004 SOAP_FMAC2
       
  2005 soap_first_block(struct soap *soap)
       
  2006 { char *p, *q, *r;
       
  2007   p = soap->blist->ptr;
       
  2008   if (!p)
       
  2009     return NULL;
       
  2010   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "First block\n"));
       
  2011   r = NULL;
       
  2012   do
       
  2013   { q = *(char**)p;
       
  2014     *(char**)p = r;
       
  2015     r = p;
       
  2016     p = q;
       
  2017   } while (p);
       
  2018   soap->blist->ptr = r;
       
  2019   return r + sizeof(char*) + sizeof(size_t);
       
  2020 }
       
  2021 #endif
       
  2022 
       
  2023 /******************************************************************************/
       
  2024 #ifndef PALM_1
       
  2025 SOAP_FMAC1
       
  2026 char*
       
  2027 SOAP_FMAC2
       
  2028 soap_next_block(struct soap *soap)
       
  2029 { char *p;
       
  2030   p = soap->blist->ptr;
       
  2031   if (p)
       
  2032   { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Next block\n"));
       
  2033     soap->blist->ptr = *(char**)p;
       
  2034     SOAP_FREE(soap, p);
       
  2035     if (soap->blist->ptr)
       
  2036       return soap->blist->ptr + sizeof(char*) + sizeof(size_t);
       
  2037   }
       
  2038   return NULL;
       
  2039 }
       
  2040 #endif
       
  2041 
       
  2042 /******************************************************************************/
       
  2043 #ifndef PALM_1
       
  2044 SOAP_FMAC1
       
  2045 size_t
       
  2046 SOAP_FMAC2
       
  2047 soap_block_size(struct soap *soap)
       
  2048 { return *(size_t*)(soap->blist->ptr + sizeof(char*));
       
  2049 }
       
  2050 #endif
       
  2051 
       
  2052 /******************************************************************************/
       
  2053 #ifndef PALM_1
       
  2054 SOAP_FMAC1
       
  2055 void
       
  2056 SOAP_FMAC2
       
  2057 soap_end_block(struct soap *soap)
       
  2058 { struct soap_blist *bp;
       
  2059   char *p, *q;
       
  2060   bp = soap->blist;
       
  2061   if (bp)
       
  2062   { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of block sequence, free all remaining blocks\n"));
       
  2063     for (p = bp->ptr; p; p = q)
       
  2064     { q = *(char**)p;
       
  2065       SOAP_FREE(soap, p);
       
  2066     }
       
  2067     soap->blist = bp->next;
       
  2068     SOAP_FREE(soap, bp);
       
  2069   }
       
  2070   DBGLOG(TEST, if (soap->blist) SOAP_MESSAGE(fdebug, "Restore previous block sequence\n"));
       
  2071 }
       
  2072 #endif
       
  2073 
       
  2074 /******************************************************************************/
       
  2075 #ifndef PALM_1
       
  2076 SOAP_FMAC1
       
  2077 char*
       
  2078 SOAP_FMAC2
       
  2079 soap_save_block(struct soap *soap, char *p, int flag)
       
  2080 { register size_t n;
       
  2081   register char *q, *s;
       
  2082   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));
       
  2083   if (soap->blist->size)
       
  2084   { if (!p)
       
  2085       p = (char*)soap_malloc(soap, soap->blist->size);
       
  2086     if (p)
       
  2087     { for (s = p, q = soap_first_block(soap); q; q = soap_next_block(soap))
       
  2088       { n = soap_block_size(soap);
       
  2089 #ifndef WITH_NOIDREF
       
  2090         if (flag)
       
  2091 	  soap_update_ptrs(soap, q, q + n, (long)s - (long)q); /* pointers s and q may or may not be related */
       
  2092 #endif
       
  2093         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy %u bytes from %p to %p\n", (unsigned int)n, q, s));
       
  2094         memcpy(s, q, n);
       
  2095         s += n;
       
  2096       }
       
  2097     }
       
  2098     else
       
  2099       soap->error = SOAP_EOM;
       
  2100   }
       
  2101   soap_end_block(soap);
       
  2102   return p;
       
  2103 }
       
  2104 #endif
       
  2105 
       
  2106 /******************************************************************************/
       
  2107 #ifndef PALM_2
       
  2108 SOAP_FMAC1
       
  2109 char *
       
  2110 SOAP_FMAC2
       
  2111 soap_putsize(struct soap *soap, const char *type, int size)
       
  2112 { return soap_putsizes(soap, type, &size, 1);
       
  2113 }
       
  2114 #endif
       
  2115 
       
  2116 /******************************************************************************/
       
  2117 #ifndef PALM_2
       
  2118 SOAP_FMAC1
       
  2119 char *
       
  2120 SOAP_FMAC2
       
  2121 soap_putsizes(struct soap *soap, const char *type, const int *size, int dim)
       
  2122 { return soap_putsizesoffsets(soap, type, size, NULL, dim);
       
  2123 }
       
  2124 #endif
       
  2125 
       
  2126 /******************************************************************************/
       
  2127 #ifndef PALM_2
       
  2128 SOAP_FMAC1
       
  2129 char *
       
  2130 SOAP_FMAC2
       
  2131 soap_putsizesoffsets(struct soap *soap, const char *type, const int *size, const int *offset, int dim)
       
  2132 { int i;
       
  2133   if (!type)
       
  2134     return NULL;
       
  2135   if (soap->version == 2)
       
  2136   { sprintf(soap->type, "%s[%d", type, size[0]);
       
  2137     for (i = 1; i < dim; i++)
       
  2138       sprintf(soap->type + strlen(soap->type), " %d", size[i]);
       
  2139   }
       
  2140   else
       
  2141   { if (offset)
       
  2142     { sprintf(soap->type, "%s[%d", type, size[0] + offset[0]);
       
  2143       for (i = 1; i < dim; i++)
       
  2144         sprintf(soap->type + strlen(soap->type), ",%d", size[i] + offset[i]);
       
  2145     }
       
  2146     else
       
  2147     { sprintf(soap->type, "%s[%d", type, size[0]);
       
  2148       for (i = 1; i < dim; i++)
       
  2149         sprintf(soap->type + strlen(soap->type), ",%d", size[i]);
       
  2150     }
       
  2151     strcat(soap->type, "]");
       
  2152   }
       
  2153   return soap->type;
       
  2154 }
       
  2155 #endif
       
  2156 
       
  2157 /******************************************************************************/
       
  2158 #ifndef PALM_2
       
  2159 SOAP_FMAC1
       
  2160 char *
       
  2161 SOAP_FMAC2
       
  2162 soap_putoffset(struct soap *soap, int offset)
       
  2163 { return soap_putoffsets(soap, &offset, 1);
       
  2164 }
       
  2165 #endif
       
  2166 
       
  2167 /******************************************************************************/
       
  2168 #ifndef PALM_2
       
  2169 SOAP_FMAC1
       
  2170 char *
       
  2171 SOAP_FMAC2
       
  2172 soap_putoffsets(struct soap *soap, const int *offset, int dim)
       
  2173 { register int i;
       
  2174   sprintf(soap->arrayOffset, "[%d", offset[0]);
       
  2175   for (i = 1; i < dim; i++)
       
  2176     sprintf(soap->arrayOffset + strlen(soap->arrayOffset), ",%d", offset[i]);
       
  2177   strcat(soap->arrayOffset, "]");
       
  2178   return soap->arrayOffset;
       
  2179 }
       
  2180 #endif
       
  2181 
       
  2182 /******************************************************************************/
       
  2183 #ifndef PALM_2
       
  2184 SOAP_FMAC1
       
  2185 int
       
  2186 SOAP_FMAC2
       
  2187 soap_size(const int *size, int dim)
       
  2188 { register int i, n = size[0];
       
  2189   for (i = 1; i < dim; i++)
       
  2190     n *= size[i];
       
  2191   return n;
       
  2192 }
       
  2193 #endif
       
  2194 
       
  2195 /******************************************************************************/
       
  2196 #ifndef PALM_2
       
  2197 SOAP_FMAC1
       
  2198 int
       
  2199 SOAP_FMAC2
       
  2200 soap_getoffsets(const char *attr, const int *size, int *offset, int dim)
       
  2201 { register int i, j = 0;
       
  2202   if (offset)
       
  2203     for (i = 0; i < dim && attr && *attr; i++)
       
  2204     { attr++;
       
  2205       j *= size[i];
       
  2206       j += offset[i] = (int)atol(attr);
       
  2207       attr = strchr(attr, ',');
       
  2208     }
       
  2209   else
       
  2210     for (i = 0; i < dim && attr && *attr; i++)
       
  2211     { attr++;
       
  2212       j *= size[i];
       
  2213       j += (int)atol(attr);
       
  2214       attr = strchr(attr, ',');
       
  2215     }
       
  2216   return j;
       
  2217 }
       
  2218 #endif
       
  2219 
       
  2220 /******************************************************************************/
       
  2221 #ifndef PALM_2
       
  2222 SOAP_FMAC1
       
  2223 int
       
  2224 SOAP_FMAC2
       
  2225 soap_getsize(const char *attr1, const char *attr2, int *j)
       
  2226 { register int n, k;
       
  2227   char *s;
       
  2228   *j = 0;
       
  2229   if (!*attr1)
       
  2230     return -1;
       
  2231   if (*attr1 == '[')
       
  2232     attr1++;
       
  2233   n = 1;
       
  2234   for (;;)
       
  2235   { k = (int)soap_strtol(attr1, &s, 10);
       
  2236     n *= k;
       
  2237     if (k < 0 || n > SOAP_MAXARRAYSIZE || s == attr1)
       
  2238       return -1;
       
  2239     attr1 = strchr(s, ',');
       
  2240     if (!attr1)
       
  2241       attr1 = strchr(s, ' ');
       
  2242     if (attr2 && *attr2)
       
  2243     { attr2++;
       
  2244       *j *= k;
       
  2245       k = (int)soap_strtol(attr2, &s, 10);
       
  2246       *j += k;
       
  2247       if (k < 0)
       
  2248         return -1;
       
  2249       attr2 = s;
       
  2250     }
       
  2251     if (!attr1)
       
  2252       break;
       
  2253     attr1++;
       
  2254   }
       
  2255   return n - *j;
       
  2256 }
       
  2257 #endif
       
  2258 
       
  2259 /******************************************************************************/
       
  2260 #ifndef PALM_2
       
  2261 SOAP_FMAC1
       
  2262 int
       
  2263 SOAP_FMAC2
       
  2264 soap_getsizes(const char *attr, int *size, int dim)
       
  2265 { register int i, k, n;
       
  2266   if (!*attr)
       
  2267     return -1;
       
  2268   i = strlen(attr);
       
  2269   n = 1;
       
  2270   do
       
  2271   { for (i = i-1; i >= 0; i--)
       
  2272       if (attr[i] == '[' || attr[i] == ',' || attr[i] == ' ')
       
  2273         break;
       
  2274     k = (int)atol(attr + i + 1);
       
  2275     n *= size[--dim] = k;
       
  2276     if (k < 0 || n > SOAP_MAXARRAYSIZE)
       
  2277       return -1;
       
  2278   } while (i >= 0 && attr[i] != '[');
       
  2279   return n;
       
  2280 }
       
  2281 #endif
       
  2282 
       
  2283 /******************************************************************************/
       
  2284 #ifndef PALM_2
       
  2285 SOAP_FMAC1
       
  2286 int
       
  2287 SOAP_FMAC2
       
  2288 soap_getposition(const char *attr, int *pos)
       
  2289 { register int i, n;
       
  2290   if (!*attr)
       
  2291     return -1;
       
  2292   n = 0;
       
  2293   i = 1;
       
  2294   do
       
  2295   { pos[n++] = (int)atol(attr + i);
       
  2296     while (attr[i] && attr[i] != ',' && attr[i] != ']')
       
  2297       i++;
       
  2298     if (attr[i] == ',')
       
  2299       i++;
       
  2300   } while (n < SOAP_MAXDIMS && attr[i] && attr[i] != ']');
       
  2301   return n;
       
  2302 }
       
  2303 #endif
       
  2304 
       
  2305 /******************************************************************************/
       
  2306 #ifndef PALM_2
       
  2307 SOAP_FMAC1
       
  2308 int
       
  2309 SOAP_FMAC2
       
  2310 soap_push_namespace(struct soap *soap, const char *id, const char *ns)
       
  2311 { register struct soap_nlist *np;
       
  2312   register struct Namespace *p;
       
  2313   register short i = -1;
       
  2314   register size_t n, k;
       
  2315   n = strlen(id);
       
  2316   k = strlen(ns) + 1;
       
  2317   p = soap->local_namespaces;
       
  2318   if (p)
       
  2319   { for (i = 0; p->id; p++, i++)
       
  2320     { if (p->ns && !strcmp(ns, p->ns))
       
  2321       { if (p->out)
       
  2322         { SOAP_FREE(soap, p->out);
       
  2323           p->out = NULL;
       
  2324         }
       
  2325         break;
       
  2326       }
       
  2327       if (p->out)
       
  2328       { if (!strcmp(ns, p->out))
       
  2329           break;
       
  2330       }
       
  2331       else if (p->in)
       
  2332       { if (!soap_tag_cmp(ns, p->in))
       
  2333         { if ((p->out = (char*)SOAP_MALLOC(soap, k)))
       
  2334             strcpy(p->out, ns);
       
  2335           break;
       
  2336         }
       
  2337       }
       
  2338     }
       
  2339     if (!p || !p->id)
       
  2340       i = -1;
       
  2341   }
       
  2342   if (i >= 0)
       
  2343     k = 0;
       
  2344   np = (struct soap_nlist*)SOAP_MALLOC(soap, sizeof(struct soap_nlist) + n + k);
       
  2345   if (!np)
       
  2346     return soap->error = SOAP_EOM;
       
  2347   np->next = soap->nlist;
       
  2348   soap->nlist = np;
       
  2349   np->level = soap->level;
       
  2350   np->index = i;
       
  2351   strcpy(np->id, id);
       
  2352   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push namespace binding (level=%u) '%s' '%s'\n", soap->level, id, ns));
       
  2353   if (i < 0)
       
  2354   { np->ns = np->id + n + 1;
       
  2355     strcpy(np->ns, ns);
       
  2356     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push NOT OK: no match found for '%s' in namespace mapping table (added to stack anyway)\n", ns));
       
  2357   }
       
  2358   else
       
  2359   { np->ns = NULL;
       
  2360     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push OK ('%s' matches '%s' in namespace table)\n", id, p->id));
       
  2361   }
       
  2362   return SOAP_OK;
       
  2363 }
       
  2364 #endif
       
  2365 
       
  2366 /******************************************************************************/
       
  2367 #ifndef PALM_2
       
  2368 SOAP_FMAC1
       
  2369 void
       
  2370 SOAP_FMAC2
       
  2371 soap_pop_namespace(struct soap *soap)
       
  2372 { register struct soap_nlist *np;
       
  2373   while (soap->nlist && soap->nlist->level >= soap->level)
       
  2374   { np = soap->nlist->next;
       
  2375     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Popped namespace binding (level=%u) '%s'\n", soap->level, soap->nlist->id));
       
  2376     SOAP_FREE(soap, soap->nlist);
       
  2377     soap->nlist = np;
       
  2378   }
       
  2379 }
       
  2380 #endif
       
  2381 
       
  2382 /******************************************************************************/
       
  2383 #ifndef PALM_2
       
  2384 SOAP_FMAC1
       
  2385 int
       
  2386 SOAP_FMAC2
       
  2387 soap_match_namespace(struct soap *soap, const char *id1, const char *id2, int n1, int n2) 
       
  2388 { register struct soap_nlist *np = soap->nlist;
       
  2389   while (np && (strncmp(np->id, id1, n1) || np->id[n1]))
       
  2390     np = np->next;
       
  2391   if (np)
       
  2392   { if (np->index < 0
       
  2393      || (soap->local_namespaces[np->index].id
       
  2394       && (strncmp(soap->local_namespaces[np->index].id, id2, n2)
       
  2395        || soap->local_namespaces[np->index].id[n2])))
       
  2396       return SOAP_NAMESPACE;
       
  2397     return SOAP_OK;
       
  2398   }
       
  2399   if (n1 == 3 && n1 == n2 && !strcmp(id1, "xml") && !strcmp(id1, id2))
       
  2400     return SOAP_OK;
       
  2401   return SOAP_SYNTAX_ERROR; 
       
  2402 }
       
  2403 #endif
       
  2404 
       
  2405 /******************************************************************************/
       
  2406 #ifndef PALM_2
       
  2407 SOAP_FMAC1
       
  2408 int
       
  2409 SOAP_FMAC2
       
  2410 soap_tag_cmp(const char *s, const char *t)
       
  2411 { for (;;)
       
  2412   { register int c1 = *s;
       
  2413     register int c2 = *t;
       
  2414     if (!c1 || c1 == '"')
       
  2415       break;
       
  2416     if (c2 != '-')
       
  2417     { if (c1 != c2)
       
  2418       { if (c1 >= 'A' && c1 <= 'Z')
       
  2419           c1 += 'a' - 'A';
       
  2420         if (c2 >= 'A' && c2 <= 'Z')
       
  2421           c2 += 'a' - 'A';
       
  2422       }
       
  2423       if (c1 != c2)
       
  2424       { if (c2 != '*')
       
  2425           return 1;
       
  2426 	c2 = *++t;
       
  2427         if (!c2)
       
  2428 	  return 0;
       
  2429         if (c2 >= 'A' && c2 <= 'Z')
       
  2430           c2 += 'a' - 'A';
       
  2431         for (;;)
       
  2432         { c1 = *s;
       
  2433 	  if (!c1 || c1 == '"')
       
  2434 	    break;
       
  2435 	  if (c1 >= 'A' && c1 <= 'Z')
       
  2436             c1 += 'a' - 'A';
       
  2437           if (c1 == c2 && !soap_tag_cmp(s + 1, t + 1))
       
  2438             return 0;
       
  2439 	  s++;
       
  2440         }
       
  2441         break;
       
  2442       }
       
  2443     }
       
  2444     s++;
       
  2445     t++;
       
  2446   }
       
  2447   if (*t == '*' && !t[1])
       
  2448     return 0;
       
  2449   return *t;
       
  2450 }
       
  2451 #endif
       
  2452 
       
  2453 /******************************************************************************/
       
  2454 #ifndef PALM_2
       
  2455 SOAP_FMAC1
       
  2456 int
       
  2457 SOAP_FMAC2
       
  2458 soap_match_tag(struct soap *soap, const char *tag1, const char *tag2)
       
  2459 { register const char *s, *t;
       
  2460   if (!tag1 || !tag2 || !*tag2)
       
  2461     return SOAP_OK;
       
  2462   s = strchr(tag1, ':');
       
  2463   t = strchr(tag2, ':');
       
  2464   if (t)
       
  2465   { if (s)
       
  2466     { if (t[1] && SOAP_STRCMP(s + 1, t + 1))
       
  2467         return SOAP_TAG_MISMATCH;
       
  2468       if (t != tag2 && soap_match_namespace(soap, tag1, tag2, s - tag1, t - tag2))
       
  2469       { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags '%s' and '%s' match but namespaces differ\n", tag1, tag2));
       
  2470         return SOAP_TAG_MISMATCH;
       
  2471       }
       
  2472     } 
       
  2473     else if (SOAP_STRCMP(tag1, t + 1))
       
  2474       return SOAP_TAG_MISMATCH;
       
  2475     else if (t != tag2 && soap_match_namespace(soap, tag1, tag2, 0, t - tag2))
       
  2476     { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags '%s' and '%s' match but namespaces differ\n", tag1, tag2));
       
  2477       return SOAP_TAG_MISMATCH;
       
  2478     }
       
  2479     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags and (default) namespaces match: '%s' '%s'\n", tag1, tag2));
       
  2480     return SOAP_OK;
       
  2481   }
       
  2482   if (s)
       
  2483   { if (SOAP_STRCMP(s + 1, tag2))
       
  2484       return SOAP_TAG_MISMATCH;
       
  2485   }
       
  2486   else if (SOAP_STRCMP(tag1, tag2))
       
  2487     return SOAP_TAG_MISMATCH;
       
  2488   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags match: '%s' '%s'\n", tag1, tag2));
       
  2489   return SOAP_OK;
       
  2490 }
       
  2491 #endif
       
  2492 
       
  2493 /******************************************************************************/
       
  2494 #ifndef PALM_2
       
  2495 SOAP_FMAC1
       
  2496 int
       
  2497 SOAP_FMAC2
       
  2498 soap_match_array(struct soap *soap, const char *type)
       
  2499 { if (*soap->arrayType)
       
  2500     if (soap_match_tag(soap, soap->arrayType, type)
       
  2501      && soap_match_tag(soap, soap->arrayType, "xsd:anyType")
       
  2502      && soap_match_tag(soap, soap->arrayType, "xsd:ur-type")
       
  2503     )
       
  2504     { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array type mismatch: '%s' '%s'\n", soap->arrayType, type));
       
  2505       return SOAP_TAG_MISMATCH;
       
  2506     }
       
  2507   return SOAP_OK;
       
  2508 }
       
  2509 #endif
       
  2510 
       
  2511 /******************************************************************************/
       
  2512 
       
  2513 #ifdef WITH_OPENSSL
       
  2514 /******************************************************************************/
       
  2515 #ifndef PALM_2
       
  2516 SOAP_FMAC1
       
  2517 int
       
  2518 SOAP_FMAC2
       
  2519 soap_rand()
       
  2520 { unsigned char buf[4];
       
  2521   ssl_init();
       
  2522   RAND_pseudo_bytes(buf, 4);
       
  2523   return *(int*)buf;
       
  2524 }
       
  2525 #endif
       
  2526 
       
  2527 /******************************************************************************/
       
  2528 #ifndef PALM_2
       
  2529 SOAP_FMAC1
       
  2530 int
       
  2531 SOAP_FMAC2
       
  2532 soap_ssl_server_context(struct soap *soap, unsigned short flags, const char *keyfile, const char *password, const char *cafile, const char *capath, const char *dhfile, const char *randfile, const char *sid)
       
  2533 { int err;
       
  2534   soap->keyfile = keyfile;
       
  2535   soap->password = password;
       
  2536   soap->cafile = cafile;
       
  2537   soap->capath = capath;
       
  2538   if (dhfile)
       
  2539   { soap->dhfile = dhfile;
       
  2540     soap->rsa = 0;
       
  2541   }
       
  2542   else
       
  2543   { soap->dhfile = NULL;
       
  2544     soap->rsa = 1;
       
  2545   }
       
  2546   soap->randfile = randfile;
       
  2547   soap->require_client_auth = (flags & SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION);
       
  2548   if (!(err = soap->fsslauth(soap)))
       
  2549     if (sid)
       
  2550       SSL_CTX_set_session_id_context(soap->ctx, (unsigned char*)sid, strlen(sid));
       
  2551   return err; 
       
  2552 }
       
  2553 #endif
       
  2554 
       
  2555 /******************************************************************************/
       
  2556 #ifndef PALM_2
       
  2557 SOAP_FMAC1
       
  2558 int
       
  2559 SOAP_FMAC2
       
  2560 soap_ssl_client_context(struct soap *soap, unsigned short flags, const char *keyfile, const char *password, const char *cafile, const char *capath, const char *randfile)
       
  2561 { soap->keyfile = keyfile;
       
  2562   soap->password = password;
       
  2563   soap->cafile = cafile;
       
  2564   soap->capath = capath;
       
  2565   soap->dhfile = NULL;
       
  2566   soap->rsa = 0;
       
  2567   soap->randfile = randfile;
       
  2568   soap->require_server_auth = (flags & SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION);
       
  2569   return soap->fsslauth(soap);
       
  2570 }
       
  2571 #endif
       
  2572 
       
  2573 /******************************************************************************/
       
  2574 #ifndef PALM_2
       
  2575 static void
       
  2576 ssl_init()
       
  2577 { static int done = 0;
       
  2578   if (!done)
       
  2579   { done = 1;
       
  2580     SSL_library_init();
       
  2581 #ifndef WITH_LEAN
       
  2582     SSL_load_error_strings();
       
  2583 #endif
       
  2584     if (!RAND_load_file("/dev/urandom", 1024))
       
  2585     { char buf[1024];
       
  2586       RAND_seed(buf, sizeof(buf));
       
  2587       while (!RAND_status())
       
  2588       { int r = rand();
       
  2589         RAND_seed(&r, sizeof(int));
       
  2590       }
       
  2591     }
       
  2592   }
       
  2593 }
       
  2594 #endif
       
  2595 
       
  2596 /******************************************************************************/
       
  2597 #ifndef PALM_1
       
  2598 static const char *
       
  2599 ssl_error(struct soap *soap, int ret)
       
  2600 { int err = SSL_get_error(soap->ssl, ret);
       
  2601   const char *msg = soap_str_code(h_ssl_error_codes, err);
       
  2602   if (msg)
       
  2603     strcpy(soap->msgbuf, msg);
       
  2604   else
       
  2605     return ERR_error_string(err, soap->msgbuf);
       
  2606   if (ERR_peek_error())
       
  2607   { unsigned long r;
       
  2608     strcat(soap->msgbuf, "\n");
       
  2609     while ((r = ERR_get_error()))
       
  2610       ERR_error_string_n(r, soap->msgbuf + strlen(soap->msgbuf), sizeof(soap->msgbuf) - strlen(soap->msgbuf));
       
  2611   } 
       
  2612   else
       
  2613   { switch (ret)
       
  2614     { case 0:
       
  2615         strcpy(soap->msgbuf, "EOF was observed that violates the protocol. The client probably provided invalid authentication information.");
       
  2616         break;
       
  2617       case -1:
       
  2618         sprintf(soap->msgbuf, "Error observed by underlying BIO: %s", strerror(errno));  
       
  2619         break;
       
  2620     }
       
  2621   }
       
  2622   return soap->msgbuf;
       
  2623 }
       
  2624 #endif
       
  2625 
       
  2626 /******************************************************************************/
       
  2627 #ifndef PALM_1
       
  2628 static int
       
  2629 ssl_password(char *buf, int num, int rwflag, void *userdata)
       
  2630 { if (num < (int)strlen((char*)userdata) + 1)
       
  2631     return 0;
       
  2632   return strlen(strcpy(buf, (char*)userdata));
       
  2633 }
       
  2634 #endif
       
  2635 
       
  2636 /******************************************************************************/
       
  2637 /* This callback is included for future references. It should not be deleted
       
  2638 #ifndef PALM_2
       
  2639 static DH *
       
  2640 ssl_tmp_dh(SSL *ssl, int is_export, int keylength)
       
  2641 { static DH *dh512 = NULL;
       
  2642   static DH *dh1024 = NULL;
       
  2643   DH *dh;
       
  2644   switch (keylength)
       
  2645   { case 512:
       
  2646       if (!dh512)
       
  2647       { BIO *bio = BIO_new_file("dh512.pem", "r");
       
  2648         if (bio)
       
  2649         { dh512 = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
       
  2650           BIO_free(bio);
       
  2651           return dh512;
       
  2652         }
       
  2653       }
       
  2654       else
       
  2655         return dh512;
       
  2656     default:
       
  2657       if (!dh1024)
       
  2658       { BIO *bio = BIO_new_file("dh1024.pem", "r");
       
  2659         if (bio)
       
  2660         { dh1024 = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
       
  2661           BIO_free(bio);
       
  2662         }
       
  2663       }
       
  2664       dh = dh1024;
       
  2665   }
       
  2666   return dh;
       
  2667 }
       
  2668 #endif
       
  2669 */
       
  2670 
       
  2671 /******************************************************************************/
       
  2672 #ifndef PALM_1
       
  2673 static int
       
  2674 ssl_auth_init(struct soap *soap)
       
  2675 { ssl_init();
       
  2676   if (!soap->ctx)
       
  2677   { if (!(soap->ctx = SSL_CTX_new(SSLv23_method())))
       
  2678       return soap_set_receiver_error(soap, "SSL error", "Can't setup context", SOAP_SSL_ERROR);
       
  2679   }
       
  2680   if (soap->randfile)
       
  2681   { if (!RAND_load_file(soap->randfile, -1))
       
  2682       return soap_set_receiver_error(soap, "SSL error", "Can't load randomness", SOAP_SSL_ERROR);
       
  2683   }
       
  2684   if (soap->cafile || soap->capath)
       
  2685   { if (!SSL_CTX_load_verify_locations(soap->ctx, soap->cafile, soap->capath))
       
  2686       return soap_set_receiver_error(soap, "SSL error", "Can't read CA file and directory", SOAP_SSL_ERROR);
       
  2687   }
       
  2688   if (!SSL_CTX_set_default_verify_paths(soap->ctx))
       
  2689     return soap_set_receiver_error(soap, "SSL error", "Can't read default CA file and/or directory", SOAP_SSL_ERROR);
       
  2690 /* See below */
       
  2691   if (soap->keyfile)
       
  2692   { if (!SSL_CTX_use_certificate_chain_file(soap->ctx, soap->keyfile))
       
  2693       return soap_set_receiver_error(soap, "SSL error", "Can't read certificate key file", SOAP_SSL_ERROR);
       
  2694     if (soap->password)
       
  2695     { SSL_CTX_set_default_passwd_cb_userdata(soap->ctx, (void*)soap->password);
       
  2696       SSL_CTX_set_default_passwd_cb(soap->ctx, ssl_password);
       
  2697     }
       
  2698     if (!SSL_CTX_use_PrivateKey_file(soap->ctx, soap->keyfile, SSL_FILETYPE_PEM))
       
  2699       return soap_set_receiver_error(soap, "SSL error", "Can't read key file", SOAP_SSL_ERROR);
       
  2700   }
       
  2701 /* Suggested alternative approach to check cafile first before the key file:
       
  2702   if (soap->password)
       
  2703   { SSL_CTX_set_default_passwd_cb_userdata(soap->ctx, (void*)soap->password);
       
  2704     SSL_CTX_set_default_passwd_cb(soap->ctx, ssl_password);
       
  2705   }
       
  2706   if (!soap->cafile || !SSL_CTX_use_certificate_chain_file(soap->ctx, soap->cafile))
       
  2707   { if (soap->keyfile)
       
  2708     { if (!SSL_CTX_use_certificate_chain_file(soap->ctx, soap->keyfile))
       
  2709         return soap_set_receiver_error(soap, "SSL error", "Can't read certificate or key file", SOAP_SSL_ERROR);
       
  2710       if (!SSL_CTX_use_PrivateKey_file(soap->ctx, soap->keyfile, SSL_FILETYPE_PEM))
       
  2711         return soap_set_receiver_error(soap, "SSL error", "Can't read key file", SOAP_SSL_ERROR);
       
  2712     }
       
  2713   }
       
  2714 */
       
  2715   if (soap->rsa)
       
  2716   { RSA *rsa = RSA_generate_key(512, RSA_F4, NULL, NULL);
       
  2717     if (!SSL_CTX_set_tmp_rsa(soap->ctx, rsa))
       
  2718     { if (rsa)
       
  2719         RSA_free(rsa);
       
  2720       return soap_set_receiver_error(soap, "SSL error", "Can't set RSA key", SOAP_SSL_ERROR);
       
  2721     }
       
  2722     RSA_free(rsa);
       
  2723   }
       
  2724   else if (soap->dhfile)
       
  2725   { DH *dh = 0;
       
  2726     BIO *bio;
       
  2727     bio = BIO_new_file(soap->dhfile, "r");
       
  2728     if (!bio)
       
  2729       return soap_set_receiver_error(soap, "SSL error", "Can't read DH file", SOAP_SSL_ERROR);
       
  2730     dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
       
  2731     BIO_free(bio);
       
  2732     if (SSL_CTX_set_tmp_dh(soap->ctx, dh) < 0)
       
  2733     { if (dh)
       
  2734         DH_free(dh);
       
  2735       return soap_set_receiver_error(soap, "SSL error", "Can't set DH parameters", SOAP_SSL_ERROR);
       
  2736     }
       
  2737     DH_free(dh);
       
  2738   }
       
  2739   SSL_CTX_set_options(soap->ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2);
       
  2740   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);
       
  2741 #if (OPENSSL_VERSION_NUMBER < 0x00905100L)
       
  2742   SSL_CTX_set_verify_depth(soap->ctx, 1); 
       
  2743 #else
       
  2744   SSL_CTX_set_verify_depth(soap->ctx, 9); 
       
  2745 #endif  
       
  2746   return SOAP_OK;
       
  2747 }
       
  2748 #endif
       
  2749 
       
  2750 /******************************************************************************/
       
  2751 #ifndef PALM_1
       
  2752 static int
       
  2753 ssl_verify_callback(int ok, X509_STORE_CTX *store)
       
  2754 {
       
  2755 #ifdef SOAP_DEBUG
       
  2756   if (!ok) 
       
  2757   { char data[256];
       
  2758     X509 *cert = X509_STORE_CTX_get_current_cert(store);
       
  2759     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)));
       
  2760     X509_NAME_oneline(X509_get_issuer_name(cert), data, sizeof(data));
       
  2761     fprintf(stderr, "certificate issuer %s\n", data);
       
  2762     X509_NAME_oneline(X509_get_subject_name(cert), data, sizeof(data));
       
  2763     fprintf(stderr, "certificate subject %s\n", data);
       
  2764   }
       
  2765 #endif
       
  2766   /* Note: return 1 to continue, but unsafe progress will be terminated by SSL */
       
  2767   return ok;
       
  2768 }
       
  2769 #endif
       
  2770 
       
  2771 /******************************************************************************/
       
  2772 #ifndef PALM_1
       
  2773 SOAP_FMAC1
       
  2774 int
       
  2775 SOAP_FMAC2
       
  2776 soap_ssl_accept(struct soap *soap)
       
  2777 { BIO *bio;
       
  2778   int i, r;
       
  2779   if (!soap_valid_socket(soap->socket))
       
  2780     return soap_set_receiver_error(soap, "SSL error", "No socket in soap_ssl_accept()", SOAP_SSL_ERROR);
       
  2781   if (!soap->ctx && (soap->error = soap->fsslauth(soap)))
       
  2782     return SOAP_INVALID_SOCKET;
       
  2783   if (!soap->ssl)
       
  2784   { soap->ssl = SSL_new(soap->ctx);
       
  2785     if (!soap->ssl)
       
  2786       return soap_set_receiver_error(soap, "SSL error", "SSL_new() failed in soap_ssl_accept()", SOAP_SSL_ERROR);
       
  2787   }
       
  2788   else
       
  2789     SSL_clear(soap->ssl);
       
  2790   soap->imode |= SOAP_ENC_SSL;
       
  2791   soap->omode |= SOAP_ENC_SSL;
       
  2792 #ifdef WIN32
       
  2793   { u_long nonblocking = 1;
       
  2794     ioctlsocket((SOAP_SOCKET)soap->socket, FIONBIO, &nonblocking);
       
  2795   }
       
  2796 #else
       
  2797   fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL)|O_NONBLOCK);
       
  2798 #endif
       
  2799   bio = BIO_new_socket((SOAP_SOCKET)soap->socket, BIO_NOCLOSE);
       
  2800   SSL_set_bio(soap->ssl, bio, bio);
       
  2801   i = 100; /* 100 * 0.1 ms retries */
       
  2802   while ((r = SSL_accept(soap->ssl)) <= 0)
       
  2803   { int err = SSL_get_error(soap->ssl, r);
       
  2804     if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
       
  2805     { struct timeval timeout;
       
  2806       fd_set fd;
       
  2807       if (i-- <= 0)
       
  2808         break;
       
  2809       timeout.tv_sec = 0;
       
  2810       timeout.tv_usec = 100000;
       
  2811       FD_ZERO(&fd);
       
  2812       FD_SET((SOAP_SOCKET)soap->socket, &fd);
       
  2813       r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout);
       
  2814       if (r < 0 && soap_socket_errno != SOAP_EINTR)
       
  2815       { soap->errnum = soap_socket_errno;
       
  2816         return SOAP_EOF;
       
  2817       }
       
  2818     }
       
  2819     else
       
  2820     { soap->errnum = err;
       
  2821       break;
       
  2822     }
       
  2823   }
       
  2824 #ifdef WIN32
       
  2825   { u_long blocking = 0;
       
  2826     ioctlsocket((SOAP_SOCKET)soap->socket, FIONBIO, &blocking);
       
  2827   }
       
  2828 #else
       
  2829   fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL)&~O_NONBLOCK);
       
  2830 #endif
       
  2831   if (r <= 0)
       
  2832   { soap_set_receiver_error(soap, ssl_error(soap, r), "SSL_accept() failed in soap_ssl_accept()", SOAP_SSL_ERROR);
       
  2833     soap_closesock(soap);
       
  2834     return SOAP_SSL_ERROR;
       
  2835   }
       
  2836   if (soap->require_client_auth)
       
  2837   { X509 *peer;
       
  2838     int err;
       
  2839     if ((err = SSL_get_verify_result(soap->ssl)) != X509_V_OK)
       
  2840     { soap_closesock(soap);
       
  2841       return soap_set_sender_error(soap, X509_verify_cert_error_string(err), "SSL certificate presented by peer cannot be verified in soap_ssl_accept()", SOAP_SSL_ERROR);
       
  2842     }
       
  2843     peer = SSL_get_peer_certificate(soap->ssl);
       
  2844     if (!peer)
       
  2845     { soap_closesock(soap);
       
  2846       return soap_set_sender_error(soap, "SSL error", "No SSL certificate was presented by the peer in soap_ssl_accept()", SOAP_SSL_ERROR);
       
  2847     }
       
  2848     X509_free(peer);
       
  2849   }
       
  2850   return SOAP_OK;
       
  2851 }
       
  2852 #endif
       
  2853 
       
  2854 /******************************************************************************/
       
  2855 #endif /* WITH_OPENSSL */
       
  2856 
       
  2857 /******************************************************************************/
       
  2858 #ifndef WITH_NOIO
       
  2859 #ifndef PALM_1
       
  2860 static int
       
  2861 tcp_init(struct soap *soap)
       
  2862 { soap->errmode = 1;
       
  2863 #ifdef WIN32
       
  2864   if (tcp_done)
       
  2865     return 0;
       
  2866   else
       
  2867   { WSADATA w;
       
  2868     if (WSAStartup(MAKEWORD(1, 1), &w))
       
  2869       return -1;
       
  2870     tcp_done = 1;
       
  2871   }
       
  2872 #endif
       
  2873   return 0;
       
  2874 }
       
  2875 #endif
       
  2876 #endif
       
  2877 
       
  2878 /******************************************************************************/
       
  2879 #ifndef PALM_1
       
  2880 SOAP_FMAC1
       
  2881 void
       
  2882 SOAP_FMAC2
       
  2883 soap_done(struct soap *soap)
       
  2884 { 
       
  2885 #ifdef SOAP_DEBUG
       
  2886   int i;
       
  2887 #endif
       
  2888   soap_free(soap);
       
  2889   while (soap->clist)
       
  2890   { struct soap_clist *p = soap->clist->next;
       
  2891     SOAP_FREE(soap, soap->clist);
       
  2892     soap->clist = p;
       
  2893   }
       
  2894   soap->keep_alive = 0; /* to force close the socket */
       
  2895   soap_closesock(soap);
       
  2896 #ifdef WITH_COOKIES
       
  2897   soap_free_cookies(soap);
       
  2898 #endif
       
  2899   while (soap->plugins)
       
  2900   { register struct soap_plugin *p = soap->plugins->next;
       
  2901     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Removing plugin '%s'\n", soap->plugins->id));
       
  2902     if (soap->plugins->fcopy || !soap->copy)
       
  2903       soap->plugins->fdelete(soap, soap->plugins);
       
  2904     SOAP_FREE(soap, soap->plugins);
       
  2905     soap->plugins = p;
       
  2906   }
       
  2907   soap->fplugin = fplugin;
       
  2908 #ifndef WITH_NOHTTP
       
  2909   soap->fpost = http_post;
       
  2910   soap->fget = http_get;
       
  2911   soap->fform = NULL;
       
  2912   soap->fposthdr = http_post_header;
       
  2913   soap->fresponse = http_response;
       
  2914   soap->fparse = http_parse;
       
  2915   soap->fparsehdr = http_parse_header;
       
  2916 #endif
       
  2917 #ifndef WITH_NOIO
       
  2918 #ifndef WITH_IPV6
       
  2919   soap->fresolve = tcp_gethost;
       
  2920 #else
       
  2921   soap->fresolve = NULL;
       
  2922 #endif
       
  2923   soap->faccept = tcp_accept;
       
  2924   soap->fopen = tcp_connect;
       
  2925   soap->fclose = tcp_disconnect;
       
  2926   soap->fclosesocket = tcp_closesocket;
       
  2927   soap->fshutdownsocket = tcp_shutdownsocket;
       
  2928   soap->fsend = fsend;
       
  2929   soap->frecv = frecv;
       
  2930   soap->fpoll = soap_poll;
       
  2931 #else
       
  2932   soap->fopen = NULL;
       
  2933   soap->fclose = NULL;
       
  2934   soap->fpoll = NULL;
       
  2935 #endif
       
  2936 #ifndef WITH_LEANER
       
  2937   soap->fprepareinit = NULL;
       
  2938   soap->fpreparesend = NULL;
       
  2939   soap->fpreparerecv = NULL;
       
  2940   soap->fpreparefinal = NULL;
       
  2941 #endif
       
  2942   soap->fseterror = NULL;
       
  2943   soap->fignore = NULL;
       
  2944   soap->fserveloop = NULL;
       
  2945 #ifdef WITH_OPENSSL
       
  2946   if (soap->session)
       
  2947   { SSL_SESSION_free(soap->session);
       
  2948     soap->session = NULL;
       
  2949   }
       
  2950 #endif
       
  2951   if (!soap->copy)
       
  2952   { if (soap_valid_socket(soap->master))
       
  2953     { soap->fclosesocket(soap, (SOAP_SOCKET)soap->master);
       
  2954       soap->master = SOAP_INVALID_SOCKET;
       
  2955     }
       
  2956 #ifdef WITH_OPENSSL
       
  2957     if (soap->ctx)
       
  2958     { SSL_CTX_free(soap->ctx);
       
  2959       soap->ctx = NULL;
       
  2960     }
       
  2961 #endif
       
  2962   }
       
  2963 #ifdef SOAP_DEBUG
       
  2964   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free logfiles\n"));
       
  2965   for (i = 0; i < SOAP_MAXLOGS; i++)
       
  2966   { if (soap->logfile[i])
       
  2967     { SOAP_FREE(soap, (void*)soap->logfile[i]);
       
  2968       soap->logfile[i] = NULL;
       
  2969     }
       
  2970     soap_close_logfile(soap, i);
       
  2971   }
       
  2972   soap_free_mht(soap);
       
  2973 #endif
       
  2974 }
       
  2975 #endif
       
  2976 
       
  2977 /******************************************************************************/
       
  2978 #ifndef WITH_NOIO
       
  2979 #ifndef PALM_2
       
  2980 SOAP_FMAC1
       
  2981 void
       
  2982 SOAP_FMAC2
       
  2983 soap_cleanup(struct soap *soap)
       
  2984 { soap_done(soap);
       
  2985 #ifdef WIN32
       
  2986   if (!tcp_done)
       
  2987     return;
       
  2988   tcp_done = 0;
       
  2989   WSACleanup();
       
  2990 #endif
       
  2991 }
       
  2992 #endif
       
  2993 #endif
       
  2994 
       
  2995 /******************************************************************************/
       
  2996 #ifndef WITH_NOIO
       
  2997 #ifndef PALM_1
       
  2998 static const char*
       
  2999 tcp_error(struct soap *soap)
       
  3000 { register const char *msg = NULL;
       
  3001   switch (soap->errmode)
       
  3002   { case 0:
       
  3003       msg = soap_strerror(soap);
       
  3004       break;
       
  3005     case 1:
       
  3006       msg = "WSAStartup failed";
       
  3007       break;
       
  3008     case 2:
       
  3009     {
       
  3010 #ifndef WITH_LEAN
       
  3011       msg = soap_str_code(h_error_codes, soap->errnum);
       
  3012       if (!msg)
       
  3013 #endif
       
  3014       { sprintf(soap->msgbuf, "TCP/UDP IP error %d", soap->errnum);
       
  3015         msg = soap->msgbuf;
       
  3016       }
       
  3017     }
       
  3018   }
       
  3019   return msg;
       
  3020 }
       
  3021 #endif
       
  3022 #endif
       
  3023 
       
  3024 /******************************************************************************/
       
  3025 #ifndef WITH_NOHTTP
       
  3026 #ifndef PALM_1
       
  3027 static const char*
       
  3028 http_error(struct soap *soap, int status)
       
  3029 { register const char *msg = SOAP_STR_EOS;
       
  3030 #ifndef WITH_LEAN
       
  3031   msg = soap_str_code(h_http_error_codes, status);
       
  3032   if (!msg)
       
  3033     msg = SOAP_STR_EOS;
       
  3034 #endif
       
  3035   return msg;
       
  3036 }
       
  3037 #endif
       
  3038 #endif
       
  3039 
       
  3040 /******************************************************************************/
       
  3041 #ifndef WITH_IPV6
       
  3042 #ifndef WITH_NOIO
       
  3043 #ifndef PALM_1
       
  3044 static int
       
  3045 tcp_gethost(struct soap *soap, const char *addr, struct in_addr *inaddr)
       
  3046 { soap_int32 iadd = -1;
       
  3047   struct hostent hostent, *host = &hostent;
       
  3048 #ifdef VXWORKS
       
  3049   int hostint;
       
  3050   char *addrcopy = (char*)SOAP_MALLOC(soap, strlen(addr) + 1); /*copy of addr. */
       
  3051   /* inet_addr(), and hostGetByName() expect "char *"; addr is a "const char *". */
       
  3052   strncpy(addrcopy, addr, strlen(addr)+1);
       
  3053   iadd = inet_addr(addrcopy);
       
  3054 #else
       
  3055 #if defined(_AIXVERSION_431) || defined(TRU64)
       
  3056   struct hostent_data ht_data;
       
  3057 #endif
       
  3058   iadd = inet_addr(addr);
       
  3059 #endif
       
  3060   if (iadd != -1)
       
  3061   { memcpy(inaddr, &iadd, sizeof(iadd));
       
  3062 #ifdef VXWORKS
       
  3063     SOAP_FREE(soap, addrcopy);
       
  3064 #endif
       
  3065     return SOAP_OK;
       
  3066   }
       
  3067 #if defined(__GLIBC__)
       
  3068   if (gethostbyname_r(addr, &hostent, soap->buf, SOAP_BUFLEN, &host, &soap->errnum) < 0)
       
  3069     host = NULL;
       
  3070 #elif defined(_AIXVERSION_431) || defined(TRU64)
       
  3071   memset((void*)&ht_data, 0, sizeof(ht_data));
       
  3072   if (gethostbyname_r(addr, &hostent, &ht_data) < 0)
       
  3073   { host = NULL;
       
  3074     soap->errnum = h_errno;
       
  3075   }
       
  3076 #elif defined(HAVE_GETHOSTBYNAME_R)
       
  3077   host = gethostbyname_r(addr, &hostent, soap->buf, SOAP_BUFLEN, &soap->errnum);
       
  3078 #elif defined(VXWORKS)
       
  3079   /* If the DNS resolver library resolvLib has been configured in the vxWorks
       
  3080    * image, a query for the host IP address is sent to the DNS server, if the
       
  3081    * name was not found in the local host table. */
       
  3082   hostint = hostGetByName(addrcopy);
       
  3083   if (hostint == ERROR)
       
  3084   { host = NULL;
       
  3085     soap->errnum = soap_errno; 
       
  3086   }
       
  3087   SOAP_FREE(soap, addrcopy);  /*free() is placed after the error checking to assure that
       
  3088 		    * errno captured is that from hostGetByName() */
       
  3089 #else
       
  3090   if (!(host = gethostbyname(addr)))
       
  3091     soap->errnum = h_errno;
       
  3092 #endif
       
  3093   if (!host)
       
  3094   { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Host name not found\n"));
       
  3095     return SOAP_ERR;
       
  3096   }
       
  3097 #ifdef VXWORKS
       
  3098   inaddr->s_addr = hostint;
       
  3099 #else
       
  3100   memcpy(inaddr, host->h_addr, host->h_length);
       
  3101 #endif
       
  3102   return SOAP_OK;
       
  3103 }
       
  3104 #endif
       
  3105 #endif
       
  3106 #endif
       
  3107 
       
  3108 /******************************************************************************/
       
  3109 #ifndef WITH_NOIO
       
  3110 #ifndef PALM_1
       
  3111 static int
       
  3112 tcp_connect(struct soap *soap, const char *endpoint, const char *host, int port)
       
  3113 {
       
  3114 #ifdef WITH_IPV6
       
  3115   struct addrinfo hints, *res, *ressave;
       
  3116   int err;
       
  3117 #endif
       
  3118   register int fd;
       
  3119 #ifndef WITH_LEAN
       
  3120   int len = SOAP_BUFLEN;
       
  3121   int set = 1;
       
  3122 #endif
       
  3123   if (soap_valid_socket(soap->socket))
       
  3124     soap->fclosesocket(soap, (SOAP_SOCKET)soap->socket);
       
  3125   soap->socket = SOAP_INVALID_SOCKET;
       
  3126   if (tcp_init(soap))
       
  3127   { soap->errnum = 0;
       
  3128     soap_set_sender_error(soap, tcp_error(soap), "TCP init failed in tcp_connect()", SOAP_TCP_ERROR);
       
  3129     return SOAP_INVALID_SOCKET;
       
  3130   }
       
  3131   soap->errmode = 0;
       
  3132 #ifdef WITH_IPV6
       
  3133   memset((void*)&hints, 0, sizeof(hints));
       
  3134   hints.ai_family = PF_UNSPEC;
       
  3135 #ifdef WITH_UDP
       
  3136   if ((soap->omode & SOAP_IO_UDP))
       
  3137     hints.ai_socktype = SOCK_DGRAM;
       
  3138   else
       
  3139 #endif
       
  3140     hints.ai_socktype = SOCK_STREAM;
       
  3141   soap->errmode = 2;
       
  3142   if (soap->proxy_host)
       
  3143     err = getaddrinfo(soap->proxy_host, soap_int2s(soap, soap->proxy_port), &hints, &res);
       
  3144   else
       
  3145     err = getaddrinfo(host, soap_int2s(soap, port), &hints, &res);
       
  3146   if (err)
       
  3147   { soap_set_sender_error(soap, gai_strerror(err), "getaddrinfo failed in tcp_connect()", SOAP_TCP_ERROR);
       
  3148     return SOAP_INVALID_SOCKET;
       
  3149   }
       
  3150   ressave = res;
       
  3151 again:
       
  3152   fd = (int)socket(res->ai_family, res->ai_socktype, res->ai_protocol);
       
  3153   soap->errmode = 0;
       
  3154 #else
       
  3155 #ifdef WITH_UDP
       
  3156   if ((soap->omode & SOAP_IO_UDP))
       
  3157     fd = (int)socket(AF_INET, SOCK_DGRAM, 0);
       
  3158   else
       
  3159 #endif
       
  3160     fd = (int)socket(AF_INET, SOCK_STREAM, 0);
       
  3161 #endif
       
  3162   if (fd < 0)
       
  3163   { soap->errnum = soap_socket_errno;
       
  3164     soap_set_sender_error(soap, tcp_error(soap), "socket failed in tcp_connect()", SOAP_TCP_ERROR);
       
  3165     return SOAP_INVALID_SOCKET;
       
  3166   }
       
  3167 #ifdef SOCKET_CLOSE_ON_EXEC
       
  3168 #ifdef WIN32
       
  3169 #ifndef UNDER_CE
       
  3170   SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0);
       
  3171 #endif
       
  3172 #else
       
  3173   fcntl(fd, F_SETFD, 1);
       
  3174 #endif
       
  3175 #endif
       
  3176 #ifndef WITH_LEAN
       
  3177   if (soap->connect_flags & SO_LINGER)
       
  3178   { struct linger linger;
       
  3179     memset((void*)&linger, 0, sizeof(linger));
       
  3180     linger.l_onoff = 1;
       
  3181     linger.l_linger = 0;
       
  3182     if (setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger)))
       
  3183     { soap->errnum = soap_socket_errno;
       
  3184       soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_LINGER failed in tcp_connect()", SOAP_TCP_ERROR);
       
  3185       soap->fclosesocket(soap, (SOAP_SOCKET)fd);
       
  3186       return SOAP_INVALID_SOCKET;
       
  3187     }
       
  3188   }
       
  3189   if ((soap->connect_flags & ~SO_LINGER) && setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, soap->connect_flags & ~SO_LINGER, (char*)&set, sizeof(int)))
       
  3190   { soap->errnum = soap_socket_errno;
       
  3191     soap_set_sender_error(soap, tcp_error(soap), "setsockopt failed in tcp_connect()", SOAP_TCP_ERROR);
       
  3192     soap->fclosesocket(soap, (SOAP_SOCKET)fd);
       
  3193     return SOAP_INVALID_SOCKET;
       
  3194   }
       
  3195   if (soap->keep_alive && setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int)))
       
  3196   { soap->errnum = soap_socket_errno;
       
  3197     soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in tcp_connect()", SOAP_TCP_ERROR);
       
  3198     soap->fclosesocket(soap, (SOAP_SOCKET)fd);
       
  3199     return SOAP_INVALID_SOCKET;
       
  3200   }
       
  3201   if (setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int)))
       
  3202   { soap->errnum = soap_socket_errno;
       
  3203     soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in tcp_connect()", SOAP_TCP_ERROR);
       
  3204     soap->fclosesocket(soap, (SOAP_SOCKET)fd);
       
  3205     return SOAP_INVALID_SOCKET;
       
  3206   }
       
  3207   if (setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int)))
       
  3208   { soap->errnum = soap_socket_errno;
       
  3209     soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in tcp_connect()", SOAP_TCP_ERROR);
       
  3210     soap->fclosesocket(soap, (SOAP_SOCKET)fd);
       
  3211     return SOAP_INVALID_SOCKET;
       
  3212   }
       
  3213 #ifdef TCP_NODELAY
       
  3214   if (!(soap->omode & SOAP_IO_UDP) && setsockopt((SOAP_SOCKET)fd, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int)))
       
  3215   { soap->errnum = soap_socket_errno;
       
  3216     soap_set_sender_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in tcp_connect()", SOAP_TCP_ERROR);
       
  3217     soap->fclosesocket(soap, (SOAP_SOCKET)fd);
       
  3218     return SOAP_INVALID_SOCKET;
       
  3219   }
       
  3220 #endif
       
  3221 #endif
       
  3222   DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Opening socket %d to host='%s' port=%d\n", fd, host, port));
       
  3223 #ifndef WITH_IPV6
       
  3224   soap->peerlen = sizeof(soap->peer);
       
  3225   memset((void*)&soap->peer, 0, sizeof(soap->peer));
       
  3226   soap->peer.sin_family = AF_INET;
       
  3227   soap->errmode = 2;
       
  3228   if (soap->proxy_host)
       
  3229   { if (soap->fresolve(soap, soap->proxy_host, &soap->peer.sin_addr))
       
  3230     { soap_set_sender_error(soap, tcp_error(soap), "get proxy host by name failed in tcp_connect()", SOAP_TCP_ERROR);
       
  3231       soap->fclosesocket(soap, (SOAP_SOCKET)fd);
       
  3232       return SOAP_INVALID_SOCKET;
       
  3233     }
       
  3234     soap->peer.sin_port = htons((short)soap->proxy_port);
       
  3235   }
       
  3236   else
       
  3237   { if (soap->fresolve(soap, host, &soap->peer.sin_addr))
       
  3238     { soap_set_sender_error(soap, tcp_error(soap), "get host by name failed in tcp_connect()", SOAP_TCP_ERROR);
       
  3239       soap->fclosesocket(soap, (SOAP_SOCKET)fd);
       
  3240       return SOAP_INVALID_SOCKET;
       
  3241     }
       
  3242     soap->peer.sin_port = htons((short)port);
       
  3243   }
       
  3244   soap->errmode = 0;
       
  3245   if ((soap->omode & SOAP_IO_UDP))
       
  3246     return fd;
       
  3247 #endif
       
  3248 #ifndef WITH_LEAN
       
  3249   if (soap->connect_timeout)
       
  3250 #if defined(WIN32)
       
  3251   { u_long nonblocking = 1;
       
  3252     ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &nonblocking);
       
  3253   }
       
  3254 #elif defined(VXWORKS)
       
  3255   { vx_nonblocking = TRUE;
       
  3256     ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&vx_nonblocking)); /* modified to use fd */
       
  3257   }
       
  3258 #else
       
  3259     fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)|O_NONBLOCK);
       
  3260 #endif
       
  3261   else
       
  3262 #if defined(WIN32)
       
  3263   { u_long blocking = 0;
       
  3264     ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &blocking);
       
  3265   }
       
  3266 #elif defined(VXWORKS)
       
  3267   { vx_nonblocking = FALSE;
       
  3268     ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&vx_nonblocking)); /* modified to use fd */
       
  3269   }
       
  3270 #else
       
  3271     fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)&~O_NONBLOCK);
       
  3272 #endif
       
  3273 #endif
       
  3274   for (;;)
       
  3275   { 
       
  3276 #ifdef WITH_IPV6
       
  3277     if (connect((SOAP_SOCKET)fd, res->ai_addr, res->ai_addrlen))
       
  3278 #else
       
  3279     if (connect((SOAP_SOCKET)fd, (struct sockaddr*)&soap->peer, sizeof(soap->peer)))
       
  3280 #endif
       
  3281     { 
       
  3282 #ifndef WITH_LEAN
       
  3283       if (soap->connect_timeout && (soap_socket_errno == SOAP_EINPROGRESS || soap_socket_errno == SOAP_EWOULDBLOCK))
       
  3284       { struct timeval timeout;
       
  3285         SOAP_SOCKLEN_T k;
       
  3286         fd_set fds;
       
  3287         if (soap->connect_timeout > 0)
       
  3288         { timeout.tv_sec = soap->connect_timeout;
       
  3289           timeout.tv_usec = 0;
       
  3290         }
       
  3291         else
       
  3292         { timeout.tv_sec = -soap->connect_timeout/1000000;
       
  3293           timeout.tv_usec = -soap->connect_timeout%1000000;
       
  3294         }
       
  3295         FD_ZERO(&fds);
       
  3296         FD_SET((SOAP_SOCKET)fd, &fds);
       
  3297         for (;;)
       
  3298         { int r = select((SOAP_SOCKET)(fd + 1), NULL, &fds, NULL, &timeout);
       
  3299           if (r > 0)
       
  3300 	    break;
       
  3301           if (!r)
       
  3302           { soap->errnum = 0;
       
  3303             DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connect timeout\n"));
       
  3304             soap_set_sender_error(soap, "Timeout", "connect failed in tcp_connect()", SOAP_TCP_ERROR);
       
  3305             soap->fclosesocket(soap, (SOAP_SOCKET)fd);
       
  3306             return SOAP_INVALID_SOCKET;
       
  3307           }
       
  3308           if (soap_socket_errno != SOAP_EINTR)
       
  3309           { soap->errnum = soap_socket_errno;
       
  3310             DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
       
  3311             soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR);
       
  3312             soap->fclosesocket(soap, (SOAP_SOCKET)fd);
       
  3313             return SOAP_INVALID_SOCKET;
       
  3314           }
       
  3315         }
       
  3316 	k = (SOAP_SOCKLEN_T)sizeof(soap->errnum);
       
  3317         if (!getsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_ERROR, (char*)&soap->errnum, &k) && !soap->errnum)	/* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */
       
  3318           break;
       
  3319         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
       
  3320         soap->errnum = soap_socket_errno;
       
  3321         soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR);
       
  3322         soap->fclosesocket(soap, (SOAP_SOCKET)fd);
       
  3323         return SOAP_INVALID_SOCKET;
       
  3324       }
       
  3325       else
       
  3326 #endif
       
  3327 #ifdef WITH_IPV6
       
  3328       if (res->ai_next)
       
  3329       { res = res->ai_next;
       
  3330         soap->fclosesocket(soap, (SOAP_SOCKET)fd);
       
  3331         goto again;
       
  3332       }
       
  3333       else
       
  3334 #endif
       
  3335       if (soap_socket_errno != SOAP_EINTR)
       
  3336       { soap->errnum = soap_socket_errno;
       
  3337         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
       
  3338         soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR);
       
  3339         soap->fclosesocket(soap, (SOAP_SOCKET)fd);
       
  3340         return SOAP_INVALID_SOCKET;
       
  3341       }
       
  3342     }  
       
  3343     else
       
  3344       break;
       
  3345   }
       
  3346 #ifdef WITH_IPV6
       
  3347   soap->peerlen = 0; /* IPv6: already connected so use send() */
       
  3348   freeaddrinfo(ressave);
       
  3349 #endif
       
  3350 #ifndef WITH_LEAN
       
  3351   if (soap->connect_timeout)
       
  3352 #if defined(WIN32)
       
  3353   { u_long blocking = 0;
       
  3354     ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &blocking);
       
  3355   }
       
  3356 #elif defined(VXWORKS)
       
  3357   { vx_nonblocking = FALSE;
       
  3358     ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&vx_nonblocking)); /* modified to use fd */
       
  3359   }
       
  3360 #else
       
  3361     fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)&~O_NONBLOCK);
       
  3362 #endif
       
  3363 #endif
       
  3364   soap->socket = fd;
       
  3365   soap->imode &= ~SOAP_ENC_SSL;
       
  3366   soap->omode &= ~SOAP_ENC_SSL;
       
  3367   if (!strncmp(endpoint, "https:", 6))
       
  3368   {
       
  3369 #ifdef WITH_OPENSSL
       
  3370     BIO *bio;
       
  3371     int r;
       
  3372     if (soap->proxy_host)
       
  3373     { short v;
       
  3374       unsigned int k = soap->omode; /* make sure we only parse HTTP */
       
  3375       size_t n = soap->count; /* save the content length */
       
  3376       soap->omode &= ~SOAP_ENC; /* mask IO and ENC */
       
  3377       soap->omode |= SOAP_IO_BUFFER;
       
  3378       soap_begin_send(soap);
       
  3379       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connecting to proxy server\n"));
       
  3380       sprintf(soap->tmpbuf, "CONNECT %s:%d HTTP/%s", host, port, soap->http_version);
       
  3381       if ((soap->error = soap->fposthdr(soap, soap->tmpbuf, NULL)))
       
  3382         return SOAP_INVALID_SOCKET;
       
  3383 #ifndef WITH_LEAN
       
  3384       if (soap->proxy_userid && soap->proxy_passwd && strlen(soap->proxy_userid) + strlen(soap->proxy_passwd) < 761)
       
  3385       { sprintf(soap->tmpbuf + 262, "%s:%s", soap->proxy_userid, soap->proxy_passwd);
       
  3386         strcpy(soap->tmpbuf, "Basic ");
       
  3387         soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, strlen(soap->tmpbuf + 262));
       
  3388         if ((soap->error = soap->fposthdr(soap, "Proxy-Authorization", soap->tmpbuf)))
       
  3389           return soap->error;
       
  3390       }
       
  3391 #endif
       
  3392       if ((soap->error = soap->fposthdr(soap, NULL, NULL))
       
  3393        || soap_flush(soap))
       
  3394         return SOAP_INVALID_SOCKET;
       
  3395       soap->omode = k;
       
  3396       k = soap->imode;
       
  3397       soap->imode &= ~SOAP_ENC; /* mask IO and ENC */
       
  3398       v = soap->version; /* preserve */
       
  3399       if (soap_begin_recv(soap))
       
  3400         return SOAP_INVALID_SOCKET;
       
  3401       soap->version = v; /* restore */
       
  3402       soap->imode = k; /* restore */
       
  3403       soap->count = n; /* restore */
       
  3404       soap_begin_send(soap);
       
  3405     }
       
  3406     if (!soap->ctx && (soap->error = soap->fsslauth(soap)))
       
  3407     { soap_set_sender_error(soap, "SSL error", "SSL authentication failed in tcp_connect(): check password, key file, and ca file.", SOAP_SSL_ERROR);
       
  3408       return SOAP_INVALID_SOCKET;
       
  3409     }
       
  3410     soap->ssl = SSL_new(soap->ctx);
       
  3411     if (!soap->ssl)
       
  3412     { soap->error = SOAP_SSL_ERROR;
       
  3413       return SOAP_INVALID_SOCKET;
       
  3414     }
       
  3415     if (soap->session)
       
  3416     { if (!strcmp(soap->session_host, host) && soap->session_port == port)
       
  3417         SSL_set_session(soap->ssl, soap->session);
       
  3418       SSL_SESSION_free(soap->session);
       
  3419       soap->session = NULL;
       
  3420     }
       
  3421     soap->imode |= SOAP_ENC_SSL;
       
  3422     soap->omode |= SOAP_ENC_SSL;
       
  3423     bio = BIO_new_socket((SOAP_SOCKET)fd, BIO_NOCLOSE);
       
  3424     SSL_set_bio(soap->ssl, bio, bio);
       
  3425 #ifndef WITH_LEAN
       
  3426     if (soap->connect_timeout)
       
  3427 #ifdef WIN32
       
  3428     { u_long nonblocking = 1;
       
  3429       ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &nonblocking);
       
  3430     }
       
  3431 #else
       
  3432       fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)|O_NONBLOCK);
       
  3433 #endif
       
  3434 #endif
       
  3435     for (;;)
       
  3436     { if ((r = SSL_connect(soap->ssl)) <= 0)
       
  3437       { int err = SSL_get_error(soap->ssl, r);
       
  3438         if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
       
  3439         { soap_set_sender_error(soap, ssl_error(soap, r), "SSL connect failed in tcp_connect()", SOAP_SSL_ERROR);
       
  3440           return SOAP_INVALID_SOCKET;
       
  3441         }
       
  3442         if (soap->connect_timeout)
       
  3443         { struct timeval timeout;
       
  3444           fd_set fds;
       
  3445           if (soap->connect_timeout > 0)
       
  3446           { timeout.tv_sec = soap->connect_timeout;
       
  3447             timeout.tv_usec = 0;
       
  3448           }
       
  3449           else
       
  3450           { timeout.tv_sec = -soap->connect_timeout/1000000;
       
  3451             timeout.tv_usec = -soap->connect_timeout%1000000;
       
  3452           }
       
  3453           FD_ZERO(&fds);
       
  3454           FD_SET((SOAP_SOCKET)soap->socket, &fds);
       
  3455           for (;;)
       
  3456           { int r = select((SOAP_SOCKET)(soap->socket + 1), &fds, NULL, &fds, &timeout);
       
  3457             if (r > 0)
       
  3458 	      break;
       
  3459             if (!r)
       
  3460             { soap->errnum = 0;
       
  3461               DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connect timeout\n"));
       
  3462               soap_set_sender_error(soap, "Timeout", "connect failed in tcp_connect()", SOAP_TCP_ERROR);
       
  3463               return SOAP_INVALID_SOCKET;
       
  3464             }
       
  3465           }
       
  3466 	  continue;
       
  3467         }
       
  3468       }
       
  3469       break;
       
  3470     }
       
  3471 #ifndef WITH_LEAN
       
  3472     if (soap->connect_timeout)
       
  3473 #ifdef WIN32
       
  3474     { u_long blocking = 0;
       
  3475       ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &blocking);
       
  3476     }
       
  3477 #else
       
  3478       fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)&~O_NONBLOCK);
       
  3479 #endif
       
  3480 #endif
       
  3481     if (soap->require_server_auth)
       
  3482     { X509 *peer;
       
  3483       int err;
       
  3484       if ((err = SSL_get_verify_result(soap->ssl)) != X509_V_OK)
       
  3485       { 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);
       
  3486         return SOAP_INVALID_SOCKET;
       
  3487       }
       
  3488       peer = SSL_get_peer_certificate(soap->ssl);
       
  3489       if (!peer)
       
  3490       { soap_set_sender_error(soap, "SSL error", "No SSL certificate was presented by the peer in tcp_connect()", SOAP_SSL_ERROR);
       
  3491         return SOAP_INVALID_SOCKET;
       
  3492       }
       
  3493       X509_NAME_get_text_by_NID(X509_get_subject_name(peer), NID_commonName, soap->msgbuf, sizeof(soap->msgbuf));
       
  3494       X509_free(peer);
       
  3495       if (soap_tag_cmp(soap->msgbuf, host))
       
  3496       { soap_set_sender_error(soap, "SSL error", "SSL certificate host name mismatch in tcp_connect()", SOAP_SSL_ERROR);
       
  3497         return SOAP_INVALID_SOCKET;
       
  3498       }
       
  3499     }
       
  3500 #else
       
  3501     soap->error = SOAP_SSL_ERROR;
       
  3502     return SOAP_INVALID_SOCKET;
       
  3503 #endif
       
  3504   }
       
  3505   return fd;
       
  3506 }
       
  3507 #endif
       
  3508 #endif
       
  3509 
       
  3510 /******************************************************************************/
       
  3511 #ifndef WITH_NOIO
       
  3512 #ifndef PALM_1
       
  3513 SOAP_FMAC1
       
  3514 int
       
  3515 SOAP_FMAC2
       
  3516 soap_bind(struct soap *soap, const char *host, int port, int backlog)
       
  3517 {
       
  3518 #ifdef WITH_IPV6
       
  3519   struct addrinfo *addrinfo;
       
  3520   struct addrinfo hints;
       
  3521   struct addrinfo res;
       
  3522   int err;
       
  3523 #endif
       
  3524 #ifndef WITH_LEAN
       
  3525   int len = SOAP_BUFLEN;
       
  3526   int set = 1;
       
  3527 #endif
       
  3528   if (soap_valid_socket(soap->master))
       
  3529   { soap->fclosesocket(soap, (SOAP_SOCKET)soap->master);
       
  3530     soap->master = SOAP_INVALID_SOCKET;
       
  3531   }
       
  3532   soap->socket = SOAP_INVALID_SOCKET;
       
  3533   soap->errmode = 1;
       
  3534   if (tcp_init(soap))
       
  3535   { soap_set_receiver_error(soap, tcp_error(soap), "TCP init failed in soap_bind()", SOAP_TCP_ERROR);
       
  3536     return SOAP_INVALID_SOCKET;
       
  3537   }
       
  3538 #ifdef WITH_IPV6
       
  3539   memset((void*)&hints, 0, sizeof(hints));
       
  3540   hints.ai_family = PF_UNSPEC;
       
  3541 #ifdef WITH_UDP
       
  3542   if ((soap->omode & SOAP_IO_UDP))
       
  3543     hints.ai_socktype = SOCK_DGRAM;
       
  3544   else
       
  3545 #endif
       
  3546     hints.ai_socktype = SOCK_STREAM;
       
  3547   hints.ai_flags = AI_PASSIVE;
       
  3548   soap->errmode = 2;
       
  3549   err = getaddrinfo(host, soap_int2s(soap, port), &hints, &addrinfo);
       
  3550   if (addrinfo)
       
  3551   { res = *addrinfo;
       
  3552     soap->peer = *((struct sockaddr_storage*)addrinfo->ai_addr);
       
  3553     soap->peerlen = addrinfo->ai_addrlen;
       
  3554     res.ai_addr = (struct sockaddr*)&soap->peer;
       
  3555     res.ai_addrlen = soap->peerlen;
       
  3556     freeaddrinfo(addrinfo);
       
  3557   }
       
  3558   if (err)
       
  3559   { soap_set_receiver_error(soap, gai_strerror(err), "getaddrinfo failed in soap_bind()", SOAP_TCP_ERROR);
       
  3560     return SOAP_INVALID_SOCKET;
       
  3561   }
       
  3562   soap->master = socket(res.ai_family, res.ai_socktype, res.ai_protocol);
       
  3563 #else
       
  3564 #ifdef WITH_UDP
       
  3565   if ((soap->omode & SOAP_IO_UDP))
       
  3566     soap->master = (int)socket(AF_INET, SOCK_DGRAM, 0);
       
  3567   else
       
  3568 #endif
       
  3569     soap->master = (int)socket(AF_INET, SOCK_STREAM, 0);
       
  3570 #endif
       
  3571   soap->errmode = 0;
       
  3572   if (!soap_valid_socket(soap->master))
       
  3573   { soap->errnum = soap_socket_errno;
       
  3574     soap_set_receiver_error(soap, tcp_error(soap), "socket failed in soap_bind()", SOAP_TCP_ERROR);
       
  3575     return SOAP_INVALID_SOCKET;
       
  3576   }
       
  3577 #ifdef WITH_UDP
       
  3578   if ((soap->omode & SOAP_IO_UDP))
       
  3579     soap->socket = soap->master;
       
  3580 #endif
       
  3581 #ifdef SOCKET_CLOSE_ON_EXEC
       
  3582 #ifdef WIN32
       
  3583 #ifndef UNDER_CE
       
  3584   SetHandleInformation((HANDLE)soap->master, HANDLE_FLAG_INHERIT, 0);
       
  3585 #endif
       
  3586 #else
       
  3587   fcntl(soap->master, F_SETFD, 1);
       
  3588 #endif
       
  3589 #endif
       
  3590 #ifndef WITH_LEAN
       
  3591   if (soap->bind_flags && setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, soap->bind_flags, (char*)&set, sizeof(int)))
       
  3592   { soap->errnum = soap_socket_errno;
       
  3593     soap_set_receiver_error(soap, tcp_error(soap), "setsockopt failed in soap_bind()", SOAP_TCP_ERROR);
       
  3594     return SOAP_INVALID_SOCKET;
       
  3595   }
       
  3596   if (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) && setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int)))
       
  3597   { soap->errnum = soap_socket_errno;
       
  3598     soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in soap_bind()", SOAP_TCP_ERROR);
       
  3599     return SOAP_INVALID_SOCKET;
       
  3600   }
       
  3601   if (setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int)))
       
  3602   { soap->errnum = soap_socket_errno;
       
  3603     soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in soap_bind()", SOAP_TCP_ERROR);
       
  3604     return SOAP_INVALID_SOCKET;
       
  3605   }
       
  3606   if (setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int)))
       
  3607   { soap->errnum = soap_socket_errno;
       
  3608     soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in soap_bind()", SOAP_TCP_ERROR);
       
  3609     return SOAP_INVALID_SOCKET;
       
  3610   }
       
  3611 #ifdef TCP_NODELAY
       
  3612   if (!(soap->omode & SOAP_IO_UDP) && setsockopt((SOAP_SOCKET)soap->master, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int)))
       
  3613   { soap->errnum = soap_socket_errno;
       
  3614     soap_set_receiver_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in soap_bind()", SOAP_TCP_ERROR);
       
  3615     return SOAP_INVALID_SOCKET;
       
  3616   }
       
  3617 #endif
       
  3618 #endif
       
  3619 #ifdef WITH_IPV6
       
  3620   soap->errmode = 0;
       
  3621   if (bind((SOAP_SOCKET)soap->master, res.ai_addr, res.ai_addrlen))
       
  3622   { soap->errnum = soap_socket_errno;
       
  3623     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n"));
       
  3624     soap_closesock(soap);
       
  3625     soap_set_receiver_error(soap, tcp_error(soap), "bind failed in soap_bind()", SOAP_TCP_ERROR);
       
  3626     return SOAP_INVALID_SOCKET;
       
  3627   }  
       
  3628 #else
       
  3629   soap->peerlen = sizeof(soap->peer);
       
  3630   memset((void*)&soap->peer, 0, sizeof(soap->peer));
       
  3631   soap->peer.sin_family = AF_INET;
       
  3632   soap->errmode = 2;
       
  3633   if (host)
       
  3634   { if (soap->fresolve(soap, host, &soap->peer.sin_addr))
       
  3635     { soap_set_receiver_error(soap, tcp_error(soap), "get host by name failed in soap_bind()", SOAP_TCP_ERROR);
       
  3636       return SOAP_INVALID_SOCKET;
       
  3637     }
       
  3638   }
       
  3639   else
       
  3640     soap->peer.sin_addr.s_addr = htonl(INADDR_ANY);
       
  3641   soap->peer.sin_port = htons((short)port);
       
  3642   soap->errmode = 0;
       
  3643   if (bind((SOAP_SOCKET)soap->master, (struct sockaddr*)&soap->peer, soap->peerlen))
       
  3644   { soap->errnum = soap_socket_errno;
       
  3645     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n"));
       
  3646     soap_closesock(soap);
       
  3647     soap_set_receiver_error(soap, tcp_error(soap), "bind failed in soap_bind()", SOAP_TCP_ERROR);
       
  3648     return SOAP_INVALID_SOCKET;
       
  3649   }
       
  3650 #endif
       
  3651   if (!(soap->omode & SOAP_IO_UDP) && listen((SOAP_SOCKET)soap->master, backlog))
       
  3652   { soap->errnum = soap_socket_errno;
       
  3653     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n"));
       
  3654     soap_closesock(soap);
       
  3655     soap_set_receiver_error(soap, tcp_error(soap), "listen failed in soap_bind()", SOAP_TCP_ERROR);
       
  3656     return SOAP_INVALID_SOCKET;
       
  3657   }  
       
  3658   return soap->master;
       
  3659 }
       
  3660 #endif
       
  3661 #endif
       
  3662 
       
  3663 /******************************************************************************/
       
  3664 #ifndef WITH_NOIO
       
  3665 #ifndef PALM_1
       
  3666 SOAP_FMAC1
       
  3667 int
       
  3668 SOAP_FMAC2
       
  3669 soap_poll(struct soap *soap)
       
  3670 { 
       
  3671 #ifndef WITH_LEAN
       
  3672   struct timeval timeout;
       
  3673   fd_set rfd, sfd, xfd;
       
  3674   int r;
       
  3675   timeout.tv_sec = 0;
       
  3676   timeout.tv_usec = 0;
       
  3677   FD_ZERO(&rfd);
       
  3678   FD_ZERO(&sfd);
       
  3679   FD_ZERO(&xfd);
       
  3680   if (soap_valid_socket(soap->socket))
       
  3681   { FD_SET((SOAP_SOCKET)soap->socket, &rfd);
       
  3682     FD_SET((SOAP_SOCKET)soap->socket, &sfd);
       
  3683     FD_SET((SOAP_SOCKET)soap->socket, &xfd);
       
  3684     r = select((SOAP_SOCKET)(soap->socket + 1), &rfd, &sfd, &xfd, &timeout);
       
  3685     if (r > 0 && FD_ISSET((SOAP_SOCKET)soap->socket, &xfd))
       
  3686       r = -1;
       
  3687   }
       
  3688   else if (soap_valid_socket(soap->master))
       
  3689   { FD_SET((SOAP_SOCKET)soap->master, &sfd);
       
  3690     r = select((SOAP_SOCKET)(soap->master + 1), NULL, &sfd, NULL, &timeout);
       
  3691   }
       
  3692   else
       
  3693     return SOAP_OK;
       
  3694   if (r > 0)
       
  3695   { if (soap_valid_socket(soap->socket)
       
  3696      && FD_ISSET((SOAP_SOCKET)soap->socket, &sfd)
       
  3697      && (!FD_ISSET((SOAP_SOCKET)soap->socket, &rfd)
       
  3698       || recv((SOAP_SOCKET)soap->socket, soap->tmpbuf, 1, MSG_PEEK) > 0))
       
  3699       return SOAP_OK;
       
  3700   }
       
  3701   else if (r < 0)
       
  3702   { soap->errnum = soap_socket_errno;
       
  3703     if ((soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) && soap_socket_errno != SOAP_EINTR)
       
  3704     { soap_set_receiver_error(soap, tcp_error(soap), "select failed in soap_poll()", SOAP_TCP_ERROR);
       
  3705       return soap->error = SOAP_TCP_ERROR;
       
  3706     }
       
  3707   }
       
  3708   else
       
  3709     soap->errnum = 0;
       
  3710   DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Polling: other end down on socket=%d select=%d\n", soap->socket, r));
       
  3711   return SOAP_EOF;
       
  3712 #else
       
  3713   return SOAP_OK;
       
  3714 #endif
       
  3715 }
       
  3716 #endif
       
  3717 #endif
       
  3718 
       
  3719 /******************************************************************************/
       
  3720 #ifndef WITH_NOIO
       
  3721 #ifndef PALM_1
       
  3722 static int
       
  3723 tcp_accept(struct soap *soap, int s, struct sockaddr *a, int *n)
       
  3724 { int fd;
       
  3725   fd = (int)accept((SOAP_SOCKET)s, a, (SOAP_SOCKLEN_T*)n);	/* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */
       
  3726 #ifdef SOCKET_CLOSE_ON_EXEC
       
  3727 #ifdef WIN32
       
  3728 #ifndef UNDER_CE
       
  3729   SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0);
       
  3730 #endif
       
  3731 #else
       
  3732   fcntl(fd, F_SETFD, FD_CLOEXEC);
       
  3733 #endif
       
  3734 #endif
       
  3735   return fd;
       
  3736 }
       
  3737 #endif
       
  3738 #endif
       
  3739 
       
  3740 /******************************************************************************/
       
  3741 #ifndef WITH_NOIO
       
  3742 #ifndef PALM_1
       
  3743 SOAP_FMAC1
       
  3744 int
       
  3745 SOAP_FMAC2
       
  3746 soap_accept(struct soap *soap)
       
  3747 { int n = (int)sizeof(soap->peer);
       
  3748 #ifndef WITH_LEAN
       
  3749   int len = SOAP_BUFLEN;
       
  3750   int set = 1;
       
  3751 #endif
       
  3752   soap->error = SOAP_OK;
       
  3753 #ifdef WITH_UDP
       
  3754   if ((soap->omode & SOAP_IO_UDP))
       
  3755     return soap->socket = soap->master;
       
  3756 #endif
       
  3757   memset((void*)&soap->peer, 0, sizeof(soap->peer));
       
  3758   soap->socket = SOAP_INVALID_SOCKET;
       
  3759   soap->errmode = 0;
       
  3760   soap->keep_alive = 0;
       
  3761   if (soap_valid_socket(soap->master))
       
  3762   { for (;;)
       
  3763     { 
       
  3764 #ifndef WITH_LEAN
       
  3765       if (soap->accept_timeout)
       
  3766       { struct timeval timeout;
       
  3767         fd_set fd;
       
  3768         if (soap->accept_timeout > 0)
       
  3769         { timeout.tv_sec = soap->accept_timeout;
       
  3770           timeout.tv_usec = 0;
       
  3771         }
       
  3772         else
       
  3773         { timeout.tv_sec = -soap->accept_timeout/1000000;
       
  3774           timeout.tv_usec = -soap->accept_timeout%1000000;
       
  3775         }
       
  3776         FD_ZERO(&fd);
       
  3777         FD_SET((SOAP_SOCKET)soap->master, &fd);
       
  3778         for (;;)
       
  3779         { int r = select((SOAP_SOCKET)(soap->master + 1), &fd, &fd, NULL, &timeout);
       
  3780           if (r > 0)
       
  3781             break;
       
  3782           if (!r)
       
  3783           { soap->errnum = 0;
       
  3784             soap_set_receiver_error(soap, "Timeout", "accept failed in soap_accept()", SOAP_TCP_ERROR);
       
  3785             return SOAP_INVALID_SOCKET;
       
  3786           }
       
  3787           if (soap_socket_errno != SOAP_EINTR)
       
  3788           { soap->errnum = soap_socket_errno;
       
  3789             soap_closesock(soap);
       
  3790             soap_set_sender_error(soap, tcp_error(soap), "accept failed in soap_accept()", SOAP_TCP_ERROR);
       
  3791             return SOAP_INVALID_SOCKET;
       
  3792           }
       
  3793         }
       
  3794 #if defined(WIN32)
       
  3795 	{ u_long nonblocking = 1;
       
  3796           ioctlsocket((SOAP_SOCKET)soap->master, FIONBIO, &nonblocking);
       
  3797         }
       
  3798 #elif defined(VXWORKS)
       
  3799         { vx_nonblocking = TRUE;
       
  3800           ioctl((SOAP_SOCKET)soap->master, FIONBIO, (int)(&vx_nonblocking));
       
  3801         }
       
  3802 #else
       
  3803         fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL)|O_NONBLOCK);
       
  3804 #endif
       
  3805       }
       
  3806       else
       
  3807 #if defined(WIN32)
       
  3808       { u_long blocking = 0;
       
  3809         ioctlsocket((SOAP_SOCKET)soap->master, FIONBIO, &blocking);
       
  3810       }
       
  3811 #elif defined(VXWORKS)
       
  3812       { vx_nonblocking = FALSE;
       
  3813         ioctl((SOAP_SOCKET)soap->master, FIONBIO, (int)(&vx_nonblocking));
       
  3814       }
       
  3815 #else
       
  3816         fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL)&~O_NONBLOCK);
       
  3817 #endif
       
  3818 #endif
       
  3819       soap->socket = soap->faccept(soap, soap->master, (struct sockaddr*)&soap->peer, &n);
       
  3820       soap->peerlen = (size_t)n;
       
  3821       if (soap_valid_socket(soap->socket))
       
  3822       {
       
  3823 #ifdef WITH_IPV6
       
  3824 /* Use soap->host to store the numeric form of the remote host */
       
  3825         getnameinfo((struct sockaddr*)&soap->peer, n, soap->host, sizeof(soap->host), NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV); 
       
  3826         DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept socket %d from %s\n", soap->socket, soap->host));
       
  3827         soap->ip = 0; /* info stored in soap->peer and soap->host */
       
  3828         soap->port = 0; /* info stored in soap->peer and soap->host */
       
  3829 #else
       
  3830         soap->ip = ntohl(soap->peer.sin_addr.s_addr);
       
  3831         soap->port = (int)ntohs(soap->peer.sin_port); /* does not return port number on some systems */
       
  3832         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));
       
  3833 #endif
       
  3834 #ifndef WITH_LEAN
       
  3835 	if (soap->accept_flags & SO_LINGER)
       
  3836         { struct linger linger;
       
  3837           memset((void*)&linger, 0, sizeof(linger));
       
  3838           linger.l_onoff = 1;
       
  3839           linger.l_linger = 0;
       
  3840 	  if (setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger)))
       
  3841           { soap->errnum = soap_socket_errno;
       
  3842 	    soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_LINGER failed in soap_accept()", SOAP_TCP_ERROR);
       
  3843 	    soap_closesock(soap);
       
  3844             return SOAP_INVALID_SOCKET;
       
  3845 	  }
       
  3846         }
       
  3847         if ((soap->accept_flags & ~SO_LINGER) && setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, soap->accept_flags & ~SO_LINGER, (char*)&set, sizeof(int)))
       
  3848         { soap->errnum = soap_socket_errno;
       
  3849           soap_set_receiver_error(soap, tcp_error(soap), "setsockopt failed in soap_accept()", SOAP_TCP_ERROR);
       
  3850 	  soap_closesock(soap);
       
  3851           return SOAP_INVALID_SOCKET;
       
  3852         }
       
  3853         if (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) && setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int)))
       
  3854         { soap->errnum = soap_socket_errno;
       
  3855           soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in soap_accept()", SOAP_TCP_ERROR);
       
  3856 	  soap_closesock(soap);
       
  3857           return SOAP_INVALID_SOCKET;
       
  3858         }
       
  3859         if (setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int)))
       
  3860         { soap->errnum = soap_socket_errno;
       
  3861           soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in soap_accept()", SOAP_TCP_ERROR);
       
  3862 	  soap_closesock(soap);
       
  3863           return SOAP_INVALID_SOCKET;
       
  3864         }
       
  3865         if (setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int)))
       
  3866         { soap->errnum = soap_socket_errno;
       
  3867           soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in soap_accept()", SOAP_TCP_ERROR);
       
  3868 	  soap_closesock(soap);
       
  3869           return SOAP_INVALID_SOCKET;
       
  3870         }
       
  3871 #ifdef TCP_NODELAY
       
  3872         if (!(soap->omode & SOAP_IO_UDP) && setsockopt((SOAP_SOCKET)soap->socket, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int)))
       
  3873         { soap->errnum = soap_socket_errno;
       
  3874           soap_set_receiver_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in soap_accept()", SOAP_TCP_ERROR);
       
  3875 	  soap_closesock(soap);
       
  3876           return SOAP_INVALID_SOCKET;
       
  3877         }
       
  3878 #endif
       
  3879 #endif
       
  3880         if (soap->accept_timeout)
       
  3881         {
       
  3882 #if defined(WIN32)
       
  3883           u_long blocking = 0;
       
  3884           ioctlsocket((SOAP_SOCKET)soap->master, FIONBIO, &blocking);
       
  3885           ioctlsocket((SOAP_SOCKET)soap->socket, FIONBIO, &blocking);
       
  3886 #elif defined(VXWORKS)
       
  3887           vx_nonblocking = FALSE;
       
  3888           ioctl((SOAP_SOCKET)soap->master, FIONBIO, (int)(&vx_nonblocking));
       
  3889           ioctl((SOAP_SOCKET)soap->socket, FIONBIO, (int)(&vx_nonblocking));
       
  3890 #elif defined(PALM)
       
  3891           fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL,0)&~O_NONBLOCK);
       
  3892           fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL,0)&~O_NONBLOCK);
       
  3893 #elif defined(SYMBIAN)
       
  3894           long blocking = 0;
       
  3895           ioctl((SOAP_SOCKET)soap->master, 0/*FIONBIO*/, &blocking);
       
  3896 #else
       
  3897           fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL)&~O_NONBLOCK);
       
  3898           fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL)&~O_NONBLOCK);
       
  3899 #endif
       
  3900 	}
       
  3901         soap->keep_alive = (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) != 0);
       
  3902         return soap->socket;
       
  3903       }
       
  3904       if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EAGAIN)
       
  3905       { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept failed from %s\n", soap->host));
       
  3906         soap->errnum = soap_socket_errno;
       
  3907         soap_set_receiver_error(soap, tcp_error(soap), "accept failed in soap_accept()", SOAP_TCP_ERROR);
       
  3908 	soap_closesock(soap);
       
  3909         return SOAP_INVALID_SOCKET;
       
  3910       }
       
  3911     }
       
  3912   }
       
  3913   else
       
  3914   { soap->errnum = 0;
       
  3915     soap_set_receiver_error(soap, tcp_error(soap), "no master socket in soap_accept()", SOAP_TCP_ERROR);
       
  3916     return SOAP_INVALID_SOCKET;
       
  3917   }
       
  3918 }
       
  3919 #endif
       
  3920 #endif
       
  3921 
       
  3922 /******************************************************************************/
       
  3923 #ifndef WITH_NOIO
       
  3924 #ifndef PALM_1
       
  3925 static int
       
  3926 tcp_disconnect(struct soap *soap)
       
  3927 {
       
  3928 #ifdef WITH_OPENSSL
       
  3929   if (soap->ssl)
       
  3930   { int r, s = 0;
       
  3931     if (soap->session)
       
  3932       SSL_SESSION_free(soap->session);
       
  3933     if (*soap->host)
       
  3934     { soap->session = SSL_get1_session(soap->ssl);
       
  3935       if (soap->session)
       
  3936       { strcpy(soap->session_host, soap->host);
       
  3937         soap->session_port = soap->port;
       
  3938       }
       
  3939     }
       
  3940     r = SSL_shutdown(soap->ssl);
       
  3941     if (r != 1)
       
  3942     { s = ERR_get_error();
       
  3943       if (s)
       
  3944       { if (soap_valid_socket(soap->socket))
       
  3945         { soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 1);
       
  3946           soap->socket = SOAP_INVALID_SOCKET;
       
  3947         }
       
  3948         r = SSL_shutdown(soap->ssl);
       
  3949       }
       
  3950     }
       
  3951     DBGLOG(TEST, if (s) SOAP_MESSAGE(fdebug, "Shutdown failed: %d\n", SSL_get_error(soap->ssl, r)));
       
  3952     SSL_free(soap->ssl);
       
  3953     soap->ssl = NULL;
       
  3954     if (s)
       
  3955       return SOAP_SSL_ERROR;
       
  3956     ERR_remove_state(0);
       
  3957   }
       
  3958 #endif
       
  3959   if (soap_valid_socket(soap->socket) && !(soap->omode & SOAP_IO_UDP))
       
  3960   { soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 2);
       
  3961     soap->fclosesocket(soap, (SOAP_SOCKET)soap->socket);
       
  3962     soap->socket = SOAP_INVALID_SOCKET;
       
  3963   }
       
  3964   return SOAP_OK;
       
  3965 }
       
  3966 #endif
       
  3967 #endif
       
  3968 
       
  3969 /******************************************************************************/
       
  3970 #ifndef WITH_NOIO
       
  3971 #ifndef PALM_1
       
  3972 static int
       
  3973 tcp_closesocket(struct soap *soap, SOAP_SOCKET fd)
       
  3974 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Close socket %d\n", (int)fd));
       
  3975   return closesocket(fd);
       
  3976 }
       
  3977 #endif
       
  3978 #endif
       
  3979 
       
  3980 /******************************************************************************/
       
  3981 #ifndef WITH_NOIO
       
  3982 #ifndef PALM_1
       
  3983 static int
       
  3984 tcp_shutdownsocket(struct soap *soap, SOAP_SOCKET fd, int how)
       
  3985 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Shutdown socket %d how=%d\n", (int)fd, how));
       
  3986   //return shutdown(fd, how);
       
  3987   return how==SD_BOTH?shutdown(fd, how):0;
       
  3988 }
       
  3989 #endif
       
  3990 #endif
       
  3991 
       
  3992 /******************************************************************************/
       
  3993 #ifndef PALM_1
       
  3994 SOAP_FMAC1
       
  3995 int
       
  3996 SOAP_FMAC2
       
  3997 soap_closesock(struct soap *soap)
       
  3998 { register int status = soap->error;
       
  3999   if (status == SOAP_EOF || status == SOAP_TCP_ERROR || status == SOAP_SSL_ERROR || !soap->keep_alive)
       
  4000   { if (soap->fclose && (soap->error = soap->fclose(soap)))
       
  4001       return soap->error;
       
  4002     soap->keep_alive = 0;
       
  4003   }
       
  4004 #ifdef WITH_ZLIB
       
  4005   if (soap->zlib_state == SOAP_ZLIB_DEFLATE)
       
  4006     deflateEnd(&soap->d_stream);
       
  4007   else if (soap->zlib_state == SOAP_ZLIB_INFLATE)
       
  4008     inflateEnd(&soap->d_stream);
       
  4009   soap->zlib_state = SOAP_ZLIB_NONE;
       
  4010 #endif
       
  4011   return soap->error = status;
       
  4012 }
       
  4013 #endif
       
  4014 
       
  4015 /******************************************************************************/
       
  4016 #ifndef WITH_NOIDREF
       
  4017 #ifndef PALM_2
       
  4018 SOAP_FMAC1
       
  4019 size_t
       
  4020 SOAP_FMAC2
       
  4021 soap_hash(register const char *s)
       
  4022 { register size_t h = 0;
       
  4023   while (*s)
       
  4024     h = 65599*h + *s++;
       
  4025   return h % SOAP_IDHASH;
       
  4026 }
       
  4027 #endif
       
  4028 #endif
       
  4029 
       
  4030 /******************************************************************************/
       
  4031 #ifndef WITH_NOIDREF
       
  4032 #ifndef PALM_1
       
  4033 static void
       
  4034 soap_init_pht(struct soap *soap)
       
  4035 { register int i;
       
  4036   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing pointer hashtable\n"));
       
  4037   soap->pblk = NULL;
       
  4038   soap->pidx = 0;
       
  4039   for (i = 0; i < (int)SOAP_PTRHASH; i++)
       
  4040     soap->pht[i] = NULL;
       
  4041 }
       
  4042 #endif
       
  4043 #endif
       
  4044 
       
  4045 /******************************************************************************/
       
  4046 #ifndef PALM_1
       
  4047 SOAP_FMAC1
       
  4048 struct soap*
       
  4049 SOAP_FMAC2
       
  4050 soap_new1(soap_mode mode)
       
  4051 { return soap_new2(mode, mode);
       
  4052 }
       
  4053 #endif
       
  4054 
       
  4055 /******************************************************************************/
       
  4056 #ifndef PALM_1
       
  4057 SOAP_FMAC1
       
  4058 struct soap*
       
  4059 SOAP_FMAC2
       
  4060 soap_new()
       
  4061 { return soap_new2(SOAP_IO_DEFAULT, SOAP_IO_DEFAULT);
       
  4062 }
       
  4063 #endif
       
  4064 
       
  4065 /******************************************************************************/
       
  4066 #ifndef PALM_1
       
  4067 SOAP_FMAC1
       
  4068 struct soap*
       
  4069 SOAP_FMAC2
       
  4070 soap_new2(soap_mode imode, soap_mode omode)
       
  4071 { struct soap *soap = (struct soap*)malloc(sizeof(struct soap));
       
  4072   if (soap)
       
  4073     soap_init2(soap, imode, omode);
       
  4074   return soap;
       
  4075 }
       
  4076 #endif
       
  4077 
       
  4078 /******************************************************************************/
       
  4079 #ifndef WITH_NOIDREF
       
  4080 #ifndef PALM_1
       
  4081 static void
       
  4082 soap_free_pht(struct soap *soap)
       
  4083 { register struct soap_pblk *pb, *next;
       
  4084   register int i;
       
  4085   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free pointer hashtable\n"));
       
  4086   for (pb = soap->pblk; pb; pb = next)
       
  4087   { next = pb->next;
       
  4088     SOAP_FREE(soap, pb);
       
  4089   }
       
  4090   soap->pblk = NULL;
       
  4091   soap->pidx = 0;
       
  4092   for (i = 0; i < (int)SOAP_PTRHASH; i++)
       
  4093     soap->pht[i] = NULL;
       
  4094 }
       
  4095 #endif
       
  4096 #endif
       
  4097 
       
  4098 /******************************************************************************/
       
  4099 #ifndef WITH_NOIDREF
       
  4100 #ifndef PALM_2
       
  4101 SOAP_FMAC1
       
  4102 int
       
  4103 SOAP_FMAC2
       
  4104 soap_embed(struct soap *soap, const void *p, const struct soap_array *a, int n, const char *tag, int type)
       
  4105 { register int i;
       
  4106   struct soap_plist *pp;
       
  4107   if (soap->version != 1)
       
  4108     soap->encoding = 1;
       
  4109   if (a)
       
  4110     i = soap_array_pointer_lookup(soap, p, a, n, type, &pp);
       
  4111   else
       
  4112     i = soap_pointer_lookup(soap, p, type, &pp);
       
  4113   if (i)
       
  4114   { if (soap_is_embedded(soap, pp)
       
  4115      || soap_is_single(soap, pp))
       
  4116       return 0;
       
  4117     soap_set_embedded(soap, pp);
       
  4118   }
       
  4119   return i;
       
  4120 }
       
  4121 #endif
       
  4122 #endif
       
  4123 
       
  4124 /******************************************************************************/
       
  4125 #ifndef WITH_NOIDREF
       
  4126 #ifndef PALM_2
       
  4127 SOAP_FMAC1
       
  4128 int
       
  4129 SOAP_FMAC2
       
  4130 soap_pointer_lookup(struct soap *soap, const void *p, int type, struct soap_plist **ppp)
       
  4131 { register struct soap_plist *pp;
       
  4132   *ppp = NULL;
       
  4133   if (p)
       
  4134   { for (pp = soap->pht[soap_hash_ptr(p)]; pp; pp = pp->next)
       
  4135     { if (pp->ptr == p && pp->type == type)
       
  4136       { *ppp = pp;
       
  4137         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup location=%p type=%d id=%d\n", p, type, pp->id));
       
  4138         return pp->id;
       
  4139       }
       
  4140     }
       
  4141   }
       
  4142   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup location=%p type=%d: not found\n", p, type));
       
  4143   return 0;
       
  4144 }
       
  4145 #endif
       
  4146 #endif
       
  4147 
       
  4148 /******************************************************************************/
       
  4149 #ifndef WITH_NOIDREF
       
  4150 #ifndef PALM_2
       
  4151 SOAP_FMAC1
       
  4152 int
       
  4153 SOAP_FMAC2
       
  4154 soap_pointer_enter(struct soap *soap, const void *p, const struct soap_array *a, int n, int type, struct soap_plist **ppp)
       
  4155 { register int h;
       
  4156   register struct soap_plist *pp;
       
  4157   if (!soap->pblk || soap->pidx >= SOAP_PTRBLK)
       
  4158   { register struct soap_pblk *pb = (struct soap_pblk*)SOAP_MALLOC(soap, sizeof(struct soap_pblk));
       
  4159     if (!pb)
       
  4160     { soap->error = SOAP_EOM;
       
  4161       return 0;
       
  4162     }
       
  4163     pb->next = soap->pblk;
       
  4164     soap->pblk = pb;
       
  4165     soap->pidx = 0;
       
  4166   }
       
  4167   *ppp = pp = &soap->pblk->plist[soap->pidx++];
       
  4168   if (a)
       
  4169     h = soap_hash_ptr(a->__ptr);
       
  4170   else
       
  4171     h = soap_hash_ptr(p);
       
  4172   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));
       
  4173   pp->next = soap->pht[h];
       
  4174   pp->type = type;
       
  4175   pp->mark1 = 0;
       
  4176   pp->mark2 = 0;
       
  4177   pp->ptr = p;
       
  4178   pp->array = a;
       
  4179   soap->pht[h] = pp;
       
  4180   pp->id = ++soap->idnum;
       
  4181   return pp->id;
       
  4182 }
       
  4183 #endif
       
  4184 #endif
       
  4185 
       
  4186 /******************************************************************************/
       
  4187 #ifndef WITH_NOIDREF
       
  4188 #ifndef PALM_2
       
  4189 SOAP_FMAC1
       
  4190 int
       
  4191 SOAP_FMAC2
       
  4192 soap_array_pointer_lookup(struct soap *soap, const void *p, const struct soap_array *a, int n, int type, struct soap_plist **ppp)
       
  4193 { register struct soap_plist *pp;
       
  4194   *ppp = NULL;
       
  4195   if (!p || !a->__ptr)
       
  4196     return 0;
       
  4197   for (pp = soap->pht[soap_hash_ptr(a->__ptr)]; pp; pp = pp->next)
       
  4198   { if (pp->type == type && pp->array && pp->array->__ptr == a->__ptr)
       
  4199     { register int i;
       
  4200       for (i = 0; i < n; i++)
       
  4201         if (((const int*)&pp->array->__size)[i] != ((const int*)&a->__size)[i])
       
  4202 	  break;
       
  4203       if (i == n)
       
  4204       { *ppp = pp;
       
  4205         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array lookup location=%p type=%d id=%d\n", a->__ptr, type, pp->id));
       
  4206         return pp->id;
       
  4207       }
       
  4208     }
       
  4209   }
       
  4210   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array lookup location=%p type=%d: not found\n", a->__ptr, type));
       
  4211   return 0;
       
  4212 }
       
  4213 #endif
       
  4214 #endif
       
  4215 
       
  4216 /******************************************************************************/
       
  4217 #ifndef PALM_1
       
  4218 SOAP_FMAC1
       
  4219 int
       
  4220 SOAP_FMAC2
       
  4221 soap_begin_count(struct soap *soap)
       
  4222 { soap_clr_attr(soap);
       
  4223   soap_set_local_namespaces(soap);
       
  4224 #ifndef WITH_LEANER
       
  4225   if ((soap->mode & SOAP_ENC_DIME) || (soap->omode & SOAP_ENC_DIME))
       
  4226     soap->mode = soap->omode | SOAP_IO_LENGTH | SOAP_ENC_DIME;
       
  4227   else
       
  4228 #endif
       
  4229   { soap->mode = soap->omode;
       
  4230     if ((soap->mode & SOAP_IO) == SOAP_IO_STORE
       
  4231      || (((soap->mode & SOAP_IO) == SOAP_IO_CHUNK || (soap->mode & SOAP_ENC_XML))
       
  4232 #ifndef WITH_LEANER
       
  4233       && !soap->fpreparesend
       
  4234 #endif
       
  4235       ))
       
  4236       soap->mode &= ~SOAP_IO_LENGTH;
       
  4237     else
       
  4238       soap->mode |= SOAP_IO_LENGTH;
       
  4239   }
       
  4240 #ifdef WITH_ZLIB
       
  4241   if ((soap->mode & SOAP_ENC_ZLIB) && (soap->mode & SOAP_IO) == SOAP_IO_FLUSH)
       
  4242   { if (!(soap->mode & SOAP_ENC_DIME))
       
  4243       soap->mode &= ~SOAP_IO_LENGTH;
       
  4244     if (soap->mode & SOAP_ENC_XML)
       
  4245       soap->mode |= SOAP_IO_BUFFER;
       
  4246     else
       
  4247       soap->mode |= SOAP_IO_STORE;
       
  4248   }
       
  4249 #endif
       
  4250   if (!soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH))
       
  4251     soap->mode |= SOAP_XML_TREE;
       
  4252 #ifndef WITH_LEANER
       
  4253   if ((soap->mode & SOAP_ENC_MTOM) && (soap->mode & SOAP_ENC_DIME))
       
  4254     soap->mode |= SOAP_ENC_MIME;
       
  4255   else
       
  4256     soap->mode &= ~SOAP_ENC_MTOM;
       
  4257   if (soap->mode & SOAP_ENC_MIME)
       
  4258     soap_select_mime_boundary(soap);
       
  4259   soap->dime.list = soap->dime.last;	/* keep track of last DIME attachment */
       
  4260 #endif
       
  4261   soap->count = 0;
       
  4262   soap->ns = 0;
       
  4263   soap->null = 0;
       
  4264   soap->position = 0;
       
  4265   soap->mustUnderstand = 0;
       
  4266   soap->encoding = 0;
       
  4267   soap->part = SOAP_BEGIN;
       
  4268   soap->idnum = 0;
       
  4269   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin count phase (socket=%d mode=0x%x count=%lu)\n", soap->socket, soap->mode, (unsigned long)soap->count));
       
  4270 #ifndef WITH_LEANER
       
  4271   soap->dime.count = 0; /* count # of attachments */
       
  4272   soap->dime.size = 0; /* accumulate total size of attachments */
       
  4273   if (soap->fprepareinit && (soap->mode & SOAP_IO) != SOAP_IO_STORE)
       
  4274     return soap->error = soap->fprepareinit(soap);   
       
  4275 #endif
       
  4276   return SOAP_OK;
       
  4277 }
       
  4278 #endif
       
  4279 
       
  4280 /******************************************************************************/
       
  4281 #ifndef PALM_1
       
  4282 SOAP_FMAC1
       
  4283 int
       
  4284 SOAP_FMAC2
       
  4285 soap_end_count(struct soap *soap)
       
  4286 { 
       
  4287 #ifndef WITH_LEANER
       
  4288   if (soap->fpreparefinal)
       
  4289     return soap->error = soap->fpreparefinal(soap);
       
  4290 #endif
       
  4291   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of count phase\n"));
       
  4292   return SOAP_OK;
       
  4293 }
       
  4294 #endif
       
  4295 
       
  4296 /******************************************************************************/
       
  4297 #ifndef PALM_1
       
  4298 SOAP_FMAC1
       
  4299 int
       
  4300 SOAP_FMAC2
       
  4301 soap_begin_send(struct soap *soap)
       
  4302 { soap->error = SOAP_OK;
       
  4303   soap_clr_attr(soap);
       
  4304   soap_set_local_namespaces(soap);
       
  4305   soap->mode = soap->omode | (soap->mode & (SOAP_IO_LENGTH | SOAP_ENC_DIME));
       
  4306 #ifdef WITH_ZLIB
       
  4307   if ((soap->mode & SOAP_ENC_ZLIB) && (soap->mode & SOAP_IO) == SOAP_IO_FLUSH)
       
  4308   { if (soap->mode & SOAP_ENC_XML)
       
  4309       soap->mode |= SOAP_IO_BUFFER;
       
  4310     else
       
  4311       soap->mode |= SOAP_IO_STORE;
       
  4312   }
       
  4313 #endif
       
  4314 #ifdef WITH_UDP
       
  4315   if ((soap->mode & SOAP_IO_UDP))
       
  4316   { soap->mode |= SOAP_ENC_XML;
       
  4317     if (soap->count > SOAP_BUFLEN)
       
  4318       return soap->error = SOAP_UDP_ERROR;
       
  4319   }
       
  4320 #endif
       
  4321   if ((soap->mode & SOAP_IO) == SOAP_IO_FLUSH && soap_valid_socket(soap->socket))
       
  4322   { if (soap->count || (soap->mode & SOAP_IO_LENGTH) || (soap->mode & SOAP_ENC_XML))
       
  4323       soap->mode |= SOAP_IO_BUFFER;
       
  4324     else
       
  4325       soap->mode |= SOAP_IO_STORE;
       
  4326   }
       
  4327   soap->mode &= ~SOAP_IO_LENGTH;
       
  4328   if ((soap->mode & SOAP_IO) == SOAP_IO_STORE)
       
  4329     soap_new_block(soap);
       
  4330   if (!(soap->mode & SOAP_IO_KEEPALIVE))
       
  4331     soap->keep_alive = 0;
       
  4332   if (!soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH))
       
  4333     soap->mode |= SOAP_XML_TREE;
       
  4334 #ifndef WITH_LEANER
       
  4335   if ((soap->mode & SOAP_ENC_MTOM) && (soap->mode & SOAP_ENC_DIME))
       
  4336   { soap->mode |= SOAP_ENC_MIME;
       
  4337     soap->mode &= ~SOAP_ENC_DIME;
       
  4338   }
       
  4339   else
       
  4340     soap->mode &= ~SOAP_ENC_MTOM;
       
  4341   if (soap->mode & SOAP_ENC_MIME)
       
  4342     soap_select_mime_boundary(soap);
       
  4343 #ifdef WIN32
       
  4344 #ifndef UNDER_CE
       
  4345 #ifndef WITH_FASTCGI
       
  4346   if (!soap_valid_socket(soap->socket)) /* Set win32 stdout or soap->sendfd to BINARY, e.g. to support DIME */
       
  4347 #ifdef __BORLANDC__
       
  4348     setmode((SOAP_SOCKET)soap->sendfd, O_BINARY);
       
  4349 #else
       
  4350     _setmode((SOAP_SOCKET)soap->sendfd, _O_BINARY);
       
  4351 #endif
       
  4352 #endif
       
  4353 #endif
       
  4354 #endif
       
  4355 #endif
       
  4356   if (soap->mode & SOAP_IO)
       
  4357   { soap->bufidx = 0;
       
  4358     soap->buflen = 0;
       
  4359   }
       
  4360   soap->chunksize = 0;
       
  4361   soap->ns = 0;
       
  4362   soap->null = 0;
       
  4363   soap->position = 0;
       
  4364   soap->mustUnderstand = 0;
       
  4365   soap->encoding = 0;
       
  4366   soap->idnum = 0;
       
  4367   soap->level = 0;
       
  4368 #ifdef WITH_ZLIB
       
  4369   soap->z_ratio_out = 1.0;
       
  4370   if ((soap->mode & SOAP_ENC_ZLIB) && soap->zlib_state != SOAP_ZLIB_DEFLATE)
       
  4371   {
       
  4372 #ifdef WITH_GZIP
       
  4373     memcpy(soap->z_buf, "\37\213\10\0\0\0\0\0\0\377", 10);
       
  4374     soap->d_stream.next_out = (Byte*)soap->z_buf + 10;
       
  4375     soap->d_stream.avail_out = SOAP_BUFLEN - 10;
       
  4376     soap->z_crc = crc32(0L, NULL, 0);
       
  4377     if (deflateInit2(&soap->d_stream, soap->z_level, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY) != Z_OK)
       
  4378 #else
       
  4379     soap->d_stream.next_out = (Byte*)soap->z_buf;
       
  4380     soap->d_stream.avail_out = SOAP_BUFLEN;
       
  4381     if (deflateInit(&soap->d_stream, soap->z_level) != Z_OK)
       
  4382 #endif
       
  4383       return soap->error = SOAP_ZLIB_ERROR;
       
  4384     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflate initialized\n"));
       
  4385     soap->zlib_state = SOAP_ZLIB_DEFLATE;
       
  4386   }
       
  4387 #endif
       
  4388   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin send phase (socket=%d mode=0x%x count=%lu)\n", soap->socket, soap->mode, (unsigned long)soap->count));
       
  4389   soap->part = SOAP_BEGIN;
       
  4390 #ifndef WITH_LEANER
       
  4391   if (soap->fprepareinit && (soap->mode & SOAP_IO) == SOAP_IO_STORE)
       
  4392     soap->fprepareinit(soap);   
       
  4393 #endif
       
  4394   return SOAP_OK;
       
  4395 }
       
  4396 #endif
       
  4397 
       
  4398 /******************************************************************************/
       
  4399 #ifndef WITH_NOIDREF
       
  4400 #ifndef PALM_2
       
  4401 SOAP_FMAC1
       
  4402 void
       
  4403 SOAP_FMAC2
       
  4404 soap_embedded(struct soap *soap, const void *p, int t)
       
  4405 { struct soap_plist *pp;
       
  4406   if (soap_pointer_lookup(soap, p, t, &pp))
       
  4407   { pp->mark1 = 1;
       
  4408     pp->mark2 = 1;
       
  4409     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded %p type=%d mark set to 1\n", p, t));
       
  4410   }
       
  4411 }
       
  4412 #endif
       
  4413 #endif
       
  4414 
       
  4415 /******************************************************************************/
       
  4416 #ifndef WITH_NOIDREF
       
  4417 #ifndef PALM_2
       
  4418 SOAP_FMAC1
       
  4419 int
       
  4420 SOAP_FMAC2
       
  4421 soap_reference(struct soap *soap, const void *p, int t)
       
  4422 { struct soap_plist *pp;
       
  4423   if (!p || (soap->mode & SOAP_XML_TREE))
       
  4424     return 1;
       
  4425   if (soap_pointer_lookup(soap, p, t, &pp))
       
  4426   { if (pp->mark1 == 0)
       
  4427     { pp->mark1 = 2;
       
  4428       pp->mark2 = 2;
       
  4429     }
       
  4430   }
       
  4431   else if (soap_pointer_enter(soap, p, NULL, 0, t, &pp))
       
  4432   { pp->mark1 = 0;
       
  4433     pp->mark2 = 0;
       
  4434   }
       
  4435   else
       
  4436     return 1;
       
  4437   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Reference %p type=%d (%d %d)\n", p, t, (int)pp->mark1, (int)pp->mark2));
       
  4438   return pp->mark1;
       
  4439 }
       
  4440 #endif
       
  4441 #endif
       
  4442 
       
  4443 /******************************************************************************/
       
  4444 #ifndef WITH_NOIDREF
       
  4445 #ifndef PALM_2
       
  4446 SOAP_FMAC1
       
  4447 int
       
  4448 SOAP_FMAC2
       
  4449 soap_array_reference(struct soap *soap, const void *p, const struct soap_array *a, int n, int t)
       
  4450 { register int i;
       
  4451   struct soap_plist *pp;
       
  4452   if (!p || !a->__ptr)
       
  4453     return 1;
       
  4454   i = soap_array_pointer_lookup(soap, p, a, n, t, &pp);
       
  4455   if (i)
       
  4456   { if (pp->mark1 == 0)
       
  4457     { pp->mark1 = 2;
       
  4458       pp->mark2 = 2;
       
  4459     }
       
  4460   }
       
  4461   else if (!soap_pointer_enter(soap, p, a, n, t, &pp))
       
  4462     return 1;
       
  4463   else
       
  4464   { pp->mark1 = 0;
       
  4465     pp->mark2 = 0;
       
  4466   }
       
  4467   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array reference %p ptr=%p dim=%d type=%d (%d %d)\n", p, a->__ptr, n, t, (int)pp->mark1, (int)pp->mark2));
       
  4468   return pp->mark1;
       
  4469 }
       
  4470 #endif
       
  4471 #endif
       
  4472 
       
  4473 /******************************************************************************/
       
  4474 #ifndef WITH_NOIDREF
       
  4475 #ifndef PALM_2
       
  4476 SOAP_FMAC1
       
  4477 int
       
  4478 SOAP_FMAC2
       
  4479 soap_embedded_id(struct soap *soap, int id, const void *p, int t)
       
  4480 { struct soap_plist *pp;
       
  4481   if (soap->mode & SOAP_XML_TREE)
       
  4482     return id;
       
  4483   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded_id %p type=%d id=%d\n", p, t, id));
       
  4484   if (soap->version == 1 && soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH) && soap->part != SOAP_IN_HEADER)
       
  4485   { if (id < 0)
       
  4486     { id = soap_pointer_lookup(soap, p, t, &pp);
       
  4487       if (id)
       
  4488       { if (soap->mode & SOAP_IO_LENGTH)
       
  4489           pp->mark1 = 2;
       
  4490         else
       
  4491           pp->mark2 = 2;
       
  4492         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded_id multiref id=%d %p type=%d = (%d %d)\n", id, p, t, (int)pp->mark1, (int)pp->mark2));
       
  4493       }
       
  4494       return -1;
       
  4495     }
       
  4496     return id;
       
  4497   }
       
  4498   if (id < 0)
       
  4499     id = soap_pointer_lookup(soap, p, t, &pp);
       
  4500   else if (id && !soap_pointer_lookup(soap, p, t, &pp))
       
  4501     return 0;
       
  4502   if (id && pp)
       
  4503   { if (soap->mode & SOAP_IO_LENGTH)
       
  4504       pp->mark1 = 1;
       
  4505     else
       
  4506       pp->mark2 = 1;
       
  4507     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded_id embedded ref id=%d %p type=%d = (%d %d)\n", id, p, t, (int)pp->mark1, (int)pp->mark2));
       
  4508   }
       
  4509   return id;
       
  4510 }
       
  4511 #endif
       
  4512 #endif
       
  4513 
       
  4514 /******************************************************************************/
       
  4515 #ifndef WITH_NOIDREF
       
  4516 #ifndef PALM_2
       
  4517 SOAP_FMAC1
       
  4518 int
       
  4519 SOAP_FMAC2
       
  4520 soap_is_embedded(struct soap *soap, struct soap_plist *pp)
       
  4521 { if (!pp)
       
  4522     return 0;
       
  4523   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Is embedded? %d %d\n", (int)pp->mark1, (int)pp->mark2));
       
  4524   if (soap->version == 1 && soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH) && soap->part != SOAP_IN_HEADER)
       
  4525   { if (soap->mode & SOAP_IO_LENGTH)
       
  4526       return pp->mark1 != 0;
       
  4527     return pp->mark2 != 0;
       
  4528   }
       
  4529   if (soap->mode & SOAP_IO_LENGTH)
       
  4530     return pp->mark1 == 1;
       
  4531   return pp->mark2 == 1;
       
  4532 }
       
  4533 #endif
       
  4534 #endif
       
  4535 
       
  4536 /******************************************************************************/
       
  4537 #ifndef WITH_NOIDREF
       
  4538 #ifndef PALM_2
       
  4539 SOAP_FMAC1
       
  4540 int
       
  4541 SOAP_FMAC2
       
  4542 soap_is_single(struct soap *soap, struct soap_plist *pp)
       
  4543 { if (soap->part == SOAP_IN_HEADER)
       
  4544     return 1;
       
  4545   if (!pp)
       
  4546     return 0;
       
  4547   if (soap->mode & SOAP_IO_LENGTH)
       
  4548     return pp->mark1 == 0;
       
  4549   return pp->mark2 == 0;
       
  4550 }
       
  4551 #endif
       
  4552 #endif
       
  4553 
       
  4554 /******************************************************************************/
       
  4555 #ifndef WITH_NOIDREF
       
  4556 #ifndef PALM_2
       
  4557 SOAP_FMAC1
       
  4558 void
       
  4559 SOAP_FMAC2
       
  4560 soap_set_embedded(struct soap *soap, struct soap_plist *pp)
       
  4561 { if (!pp)
       
  4562     return;
       
  4563   if (soap->mode & SOAP_IO_LENGTH)
       
  4564     pp->mark1 = 1;
       
  4565   else
       
  4566     pp->mark2 = 1;
       
  4567 }
       
  4568 #endif
       
  4569 #endif
       
  4570 
       
  4571 /******************************************************************************/
       
  4572 #ifndef WITH_NOIDREF
       
  4573 #ifndef WITH_LEANER
       
  4574 #ifndef PALM_1
       
  4575 SOAP_FMAC1
       
  4576 int
       
  4577 SOAP_FMAC2
       
  4578 soap_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) 
       
  4579 { struct soap_plist *pp;
       
  4580   int i;
       
  4581   if (!p || !a->__ptr || (!aid && !atype))
       
  4582     return soap_element_id(soap, tag, id, p, a, n, type, t);
       
  4583   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Attachment tag='%s' id='%s' (%d) type='%s'\n", tag, aid?aid:"", id, atype?atype:""));
       
  4584   i = soap_array_pointer_lookup(soap, p, a, n, t, &pp);
       
  4585   if (!i)
       
  4586   { i = soap_pointer_enter(soap, p, a, n, t, &pp);
       
  4587     if (!i)
       
  4588     { soap->error = SOAP_EOM;
       
  4589       return -1;
       
  4590     }
       
  4591   }
       
  4592   if (id < 0)
       
  4593     id = i;
       
  4594   if (!aid)
       
  4595   { sprintf(soap->tmpbuf, soap->dime_id_format, id);
       
  4596     aid = soap_strdup(soap, soap->tmpbuf);
       
  4597   }
       
  4598   /* Add MTOM xop:Include element when necessary */
       
  4599   /* TODO: this code to be obsoleted with new import/xop.h conventions */
       
  4600   if ((soap->mode & SOAP_ENC_MTOM) && strcmp(tag, "xop:Include"))
       
  4601   { if (soap_element_begin_out(soap, tag, 0, type)
       
  4602      || soap_element_href(soap, "xop:Include", 0, "href", aid)
       
  4603      || soap_element_end_out(soap, tag))
       
  4604       return soap->error;
       
  4605   }
       
  4606   else if (soap_element_href(soap, tag, 0, "href", aid))
       
  4607     return soap->error;
       
  4608   if (soap->mode & SOAP_IO_LENGTH)
       
  4609   { if (pp->mark1 != 3)
       
  4610     { struct soap_multipart *content;
       
  4611       if (soap->mode & SOAP_ENC_MTOM)
       
  4612         content = soap_new_multipart(soap, &soap->mime.first, &soap->mime.last, (char*)a->__ptr, a->__size);
       
  4613       else
       
  4614         content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, (char*)a->__ptr, a->__size);
       
  4615       if (!content)
       
  4616       { soap->error = SOAP_EOM;
       
  4617         return -1;
       
  4618       }
       
  4619       if (!strncmp(aid, "cid:", 4)) /* RFC 2111 */
       
  4620       { if (soap->mode & SOAP_ENC_MTOM)
       
  4621         { char *s = (char*)soap_malloc(soap, strlen(aid) - 1);
       
  4622 	  if (s)
       
  4623 	  { *s = '<';
       
  4624 	    strcpy(s + 1, aid + 4);
       
  4625 	    strcat(s, ">");
       
  4626 	    content->id = s;
       
  4627           }
       
  4628         }
       
  4629         else
       
  4630           content->id = aid + 4;
       
  4631       }
       
  4632       else
       
  4633         content->id = aid;
       
  4634       content->type = atype;
       
  4635       content->options = aoptions;
       
  4636       content->encoding = SOAP_MIME_BINARY;
       
  4637       pp->mark1 = 3;
       
  4638     }
       
  4639   }
       
  4640   else
       
  4641     pp->mark2 = 3;
       
  4642   return -1;
       
  4643 }
       
  4644 #endif
       
  4645 #endif
       
  4646 #endif
       
  4647 
       
  4648 /******************************************************************************/
       
  4649 #ifndef WITH_NOIDREF
       
  4650 #ifndef PALM_1
       
  4651 static void
       
  4652 soap_init_iht(struct soap *soap)
       
  4653 { register int i;
       
  4654   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing ID hashtable\n"));
       
  4655   for (i = 0; i < SOAP_IDHASH; i++)
       
  4656     soap->iht[i] = NULL;
       
  4657 }
       
  4658 #endif
       
  4659 #endif
       
  4660 
       
  4661 /******************************************************************************/
       
  4662 #ifndef WITH_NOIDREF
       
  4663 #ifndef PALM_1
       
  4664 static void
       
  4665 soap_free_iht(struct soap *soap)
       
  4666 { register int i;
       
  4667   register struct soap_ilist *ip, *p;
       
  4668   register struct soap_flist *fp, *fq;
       
  4669   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free ID hashtable\n"));
       
  4670   for (i = 0; i < SOAP_IDHASH; i++)
       
  4671   { for (ip = soap->iht[i]; ip; ip = p)
       
  4672     { for (fp = ip->flist; fp; fp = fq)
       
  4673       { fq = fp->next;
       
  4674         SOAP_FREE(soap, fp);
       
  4675       }
       
  4676       p = ip->next;
       
  4677       SOAP_FREE(soap, ip);
       
  4678     }
       
  4679     soap->iht[i] = NULL;
       
  4680   }
       
  4681 }
       
  4682 #endif
       
  4683 #endif
       
  4684 
       
  4685 /******************************************************************************/
       
  4686 #ifndef WITH_NOIDREF
       
  4687 #ifndef PALM_2
       
  4688 SOAP_FMAC1
       
  4689 struct soap_ilist *
       
  4690 SOAP_FMAC2
       
  4691 soap_lookup(struct soap *soap, const char *id)
       
  4692 { register struct soap_ilist *ip;
       
  4693   for (ip = soap->iht[soap_hash(id)]; ip; ip = ip->next)
       
  4694     if (!strcmp(ip->id, id))
       
  4695       return ip;
       
  4696   return NULL;
       
  4697 }
       
  4698 #endif
       
  4699 #endif
       
  4700 
       
  4701 /******************************************************************************/
       
  4702 #ifndef WITH_NOIDREF
       
  4703 #ifndef PALM_2
       
  4704 SOAP_FMAC1
       
  4705 struct soap_ilist *
       
  4706 SOAP_FMAC2
       
  4707 soap_enter(struct soap *soap, const char *id)
       
  4708 { register size_t h;
       
  4709   register struct soap_ilist *ip;
       
  4710   ip = (struct soap_ilist*)SOAP_MALLOC(soap, sizeof(struct soap_ilist) + strlen(id));
       
  4711   if (ip)
       
  4712   { h = soap_hash(id);
       
  4713     strcpy(ip->id, id);
       
  4714     ip->next = soap->iht[h];
       
  4715     soap->iht[h] = ip;
       
  4716     return ip;
       
  4717   }
       
  4718   return NULL;
       
  4719 }
       
  4720 #endif
       
  4721 #endif
       
  4722 
       
  4723 /******************************************************************************/
       
  4724 #ifndef PALM_2
       
  4725 SOAP_FMAC1
       
  4726 void*
       
  4727 SOAP_FMAC2
       
  4728 soap_malloc(struct soap *soap, size_t n)
       
  4729 { register char *p;
       
  4730   if (!n)
       
  4731     return (void*)SOAP_NON_NULL;
       
  4732   if (!soap)
       
  4733     return SOAP_MALLOC(soap, n);
       
  4734   n += (-(long)n) & 7;
       
  4735   if (!(p = (char*)SOAP_MALLOC(soap, n + sizeof(void*) + sizeof(size_t))))
       
  4736   { soap->error = SOAP_EOM;
       
  4737     return NULL;
       
  4738   }
       
  4739   /* keep chain of alloced cells for later destruction */
       
  4740   soap->alloced = 1;
       
  4741   *(void**)(p + n) = soap->alist;
       
  4742   *(size_t*)(p + n + sizeof(void*)) = n;
       
  4743   soap->alist = p + n;
       
  4744   return p;
       
  4745 }
       
  4746 #endif
       
  4747 
       
  4748 /******************************************************************************/
       
  4749 #ifdef SOAP_DEBUG
       
  4750 static void
       
  4751 soap_init_mht(struct soap *soap)
       
  4752 { register int i;
       
  4753   for (i = 0; i < (int)SOAP_PTRHASH; i++)
       
  4754     soap->mht[i] = NULL;
       
  4755 }
       
  4756 #endif
       
  4757 
       
  4758 /******************************************************************************/
       
  4759 #ifdef SOAP_DEBUG
       
  4760 static void
       
  4761 soap_free_mht(struct soap *soap)
       
  4762 { register int i;
       
  4763   register struct soap_mlist *mp, *mq;
       
  4764   for (i = 0; i < (int)SOAP_PTRHASH; i++)
       
  4765   { for (mp = soap->mht[i]; mp; mp = mq)
       
  4766     { mq = mp->next;
       
  4767       if (mp->live)
       
  4768         fprintf(stderr, "%s(%d): malloc() = %p not freed (memory leak or forgot to call soap_end()?)\n", mp->file, mp->line, mp->ptr);
       
  4769       free(mp);
       
  4770     }
       
  4771     soap->mht[i] = NULL;
       
  4772   }
       
  4773 }
       
  4774 #endif
       
  4775 
       
  4776 /******************************************************************************/
       
  4777 #ifdef SOAP_DEBUG
       
  4778 SOAP_FMAC1
       
  4779 void*
       
  4780 SOAP_FMAC2
       
  4781 soap_track_malloc(struct soap *soap, const char *file, int line, size_t size)
       
  4782 { register void *p = malloc(size);
       
  4783   if (soap)
       
  4784   { register int h = soap_hash_ptr(p);
       
  4785     register struct soap_mlist *mp = (struct soap_mlist*)malloc(sizeof(struct soap_mlist));
       
  4786     if (soap->fdebug[SOAP_INDEX_TEST])
       
  4787       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): malloc(%lu) = %p\n", file, line, (unsigned long)size, p));
       
  4788     mp->next = soap->mht[h];
       
  4789     mp->ptr = p;
       
  4790     mp->file = file;
       
  4791     mp->line = line;
       
  4792     mp->live = 1;
       
  4793     soap->mht[h] = mp;
       
  4794   }
       
  4795   return p;
       
  4796 }
       
  4797 #endif
       
  4798 
       
  4799 /******************************************************************************/
       
  4800 #ifdef SOAP_DEBUG
       
  4801 SOAP_FMAC1
       
  4802 void
       
  4803 SOAP_FMAC2
       
  4804 soap_track_free(struct soap *soap, const char *file, int line, void *p)
       
  4805 { register int h = soap_hash_ptr(p);
       
  4806   register struct soap_mlist *mp;
       
  4807   for (mp = soap->mht[h]; mp; mp = mp->next)
       
  4808     if (mp->ptr == p)
       
  4809       break;
       
  4810   if (mp)
       
  4811   { if (mp->live)
       
  4812     { free(p);
       
  4813       if (soap->fdebug[SOAP_INDEX_TEST])
       
  4814         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): free(%p)\n", file, line, p));
       
  4815       mp->live = 0;
       
  4816     }
       
  4817     else
       
  4818       fprintf(stderr, "%s(%d): free(%p) double free of pointer malloced at %s(%d)\n", file, line, p, mp->file, mp->line);
       
  4819   }
       
  4820   else
       
  4821     fprintf(stderr, "%s(%d): free(%p) pointer not malloced\n", file, line, p);
       
  4822 }
       
  4823 #endif
       
  4824 
       
  4825 /******************************************************************************/
       
  4826 #ifdef SOAP_DEBUG
       
  4827 static void
       
  4828 soap_track_unlink(struct soap *soap, const void *p)
       
  4829 { register int h = soap_hash_ptr(p);
       
  4830   register struct soap_mlist *mp;
       
  4831   for (mp = soap->mht[h]; mp; mp = mp->next)
       
  4832     if (mp->ptr == p)
       
  4833       break;
       
  4834   if (mp)
       
  4835     mp->live = 0;
       
  4836 }
       
  4837 #endif
       
  4838 
       
  4839 /******************************************************************************/
       
  4840 #ifndef PALM_2
       
  4841 SOAP_FMAC1
       
  4842 void
       
  4843 SOAP_FMAC2
       
  4844 soap_dealloc(struct soap *soap, void *p)
       
  4845 { if (!soap)
       
  4846     return;
       
  4847   if (p)
       
  4848   { register char **q;
       
  4849     for (q = (char**)&soap->alist; *q; q = *(char***)q)
       
  4850     { if (p == (void*)(*q - *(size_t*)(*q + sizeof(void*))))
       
  4851       { *q = **(char***)q;
       
  4852         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Freed data at %p\n", p));
       
  4853         SOAP_FREE(soap, p);
       
  4854         return;
       
  4855       }
       
  4856     }
       
  4857     soap_delete(soap, p);
       
  4858   }
       
  4859   else
       
  4860   { register char *q;
       
  4861     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free all soap_malloc() data\n"));
       
  4862     while (soap->alist)
       
  4863     { q = (char*)soap->alist;
       
  4864       soap->alist = *(void**)q;
       
  4865       q -= *(size_t*)(q + sizeof(void*));
       
  4866       SOAP_FREE(soap, q);
       
  4867     }
       
  4868   }
       
  4869   /* we must assume these were deallocated: */
       
  4870   soap->action = NULL;
       
  4871   soap->fault = NULL;
       
  4872   soap->header = NULL;
       
  4873   soap->userid = NULL;
       
  4874   soap->passwd = NULL;
       
  4875   soap->authrealm = NULL;
       
  4876 #ifndef WITH_LEANER
       
  4877   soap_clr_mime(soap);
       
  4878 #endif
       
  4879 }
       
  4880 #endif
       
  4881 
       
  4882 /******************************************************************************/
       
  4883 #ifndef PALM_2
       
  4884 SOAP_FMAC1
       
  4885 void
       
  4886 SOAP_FMAC2
       
  4887 soap_delete(struct soap *soap, void *p)
       
  4888 { register struct soap_clist **cp = &soap->clist;
       
  4889   if (p)
       
  4890   { while (*cp)
       
  4891     { if (p == (*cp)->ptr)
       
  4892       { register struct soap_clist *q = *cp;
       
  4893         *cp = q->next;
       
  4894         q->fdelete(q);
       
  4895         SOAP_FREE(soap, q);
       
  4896         return;
       
  4897       }
       
  4898       cp = &(*cp)->next;
       
  4899     }
       
  4900     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not dealloc data %p: address not in list\n", p));
       
  4901   }
       
  4902   else
       
  4903   { while (*cp)
       
  4904     { register struct soap_clist *q = *cp;
       
  4905       *cp = q->next;
       
  4906       if (q->ptr == (void*)soap->fault)
       
  4907         soap->fault = NULL; /* this was deallocated */
       
  4908       else if (q->ptr == (void*)soap->header)
       
  4909         soap->header = NULL; /* this was deallocated */
       
  4910       q->fdelete(q);
       
  4911       SOAP_FREE(soap, q);
       
  4912     }
       
  4913   }
       
  4914 }
       
  4915 #endif
       
  4916 
       
  4917 /******************************************************************************/
       
  4918 #ifndef PALM_2
       
  4919 SOAP_FMAC1
       
  4920 struct soap_clist *
       
  4921 SOAP_FMAC2
       
  4922 soap_link(struct soap *soap, void *p, int t, int n, void (*fdelete)(struct soap_clist*))
       
  4923 { register struct soap_clist *cp;
       
  4924   if ((cp = (struct soap_clist*)SOAP_MALLOC(soap, sizeof(struct soap_clist))))
       
  4925   { cp->next = soap->clist;
       
  4926     cp->type = t;
       
  4927     cp->size = n; 
       
  4928     cp->ptr = p;
       
  4929     cp->fdelete = fdelete;
       
  4930     soap->clist = cp;
       
  4931   }
       
  4932   return cp;
       
  4933 }
       
  4934 #endif
       
  4935 
       
  4936 /******************************************************************************/
       
  4937 #ifndef PALM_2
       
  4938 SOAP_FMAC1
       
  4939 void
       
  4940 SOAP_FMAC2
       
  4941 soap_unlink(struct soap *soap, const void *p)
       
  4942 { register char **q;
       
  4943   register struct soap_clist **cp;
       
  4944   if (!soap || !p)
       
  4945     return;
       
  4946   for (q = (char**)&soap->alist; *q; q = *(char***)q)
       
  4947   { if (p == (void*)(*q - *(size_t*)(*q + sizeof(void*))))
       
  4948     { *q = **(char***)q;
       
  4949       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unlinked data %p\n", p));
       
  4950 #ifdef SOAP_DEBUG
       
  4951       soap_track_unlink(soap, p);
       
  4952 #endif
       
  4953       return;
       
  4954     }
       
  4955   }
       
  4956   for (cp = &soap->clist; *cp; cp = &(*cp)->next)
       
  4957   { if (p == (*cp)->ptr)
       
  4958     { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unlinked class instance %p\n", p));
       
  4959       q = (char**)*cp;
       
  4960       *cp = (*cp)->next;
       
  4961       SOAP_FREE(soap, q);
       
  4962       return;
       
  4963     }
       
  4964   }
       
  4965 }
       
  4966 #endif
       
  4967 
       
  4968 /******************************************************************************/
       
  4969 #ifndef WITH_NOIDREF
       
  4970 #ifndef PALM_2
       
  4971 SOAP_FMAC1
       
  4972 int
       
  4973 SOAP_FMAC2
       
  4974 soap_lookup_type(struct soap *soap, const char *id)
       
  4975 { register struct soap_ilist *ip;
       
  4976   if (id && *id)
       
  4977   { ip = soap_lookup(soap, id);
       
  4978     if (ip)
       
  4979     { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup id='%s' type=%d\n", id, ip->type));
       
  4980       return ip->type;
       
  4981     }
       
  4982   }
       
  4983   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "lookup type id='%s' NOT FOUND! Need to get it from xsi:type\n", id));
       
  4984   return 0;
       
  4985 }
       
  4986 #endif
       
  4987 #endif
       
  4988 
       
  4989 /******************************************************************************/
       
  4990 #ifndef WITH_NOIDREF
       
  4991 #ifndef PALM_2
       
  4992 SOAP_FMAC1
       
  4993 void*
       
  4994 SOAP_FMAC2
       
  4995 soap_id_lookup(struct soap *soap, const char *id, void **p, int t, size_t n, unsigned int k)
       
  4996 { struct soap_ilist *ip;
       
  4997   void **q;
       
  4998   if (!p || !id || !*id)
       
  4999     return p;
       
  5000   ip = soap_lookup(soap, id); /* lookup pointer to hash table entry for string id */
       
  5001   if (!ip)
       
  5002   { ip = soap_enter(soap, id); /* new hash table entry for string id */
       
  5003     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding first href='%s' type=%d %p (%u bytes)\n", id, t, p, (unsigned int)n));
       
  5004     ip->type = t;
       
  5005     ip->size = n; 
       
  5006     ip->link = p;
       
  5007     ip->copy = NULL;
       
  5008     ip->flist = NULL;
       
  5009     ip->ptr = NULL;
       
  5010     ip->level = k;
       
  5011     *p = NULL;
       
  5012   }
       
  5013   else if (ip->ptr)
       
  5014   { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolved href='%s' type=%d location=%p (%u bytes)\n", id, t, ip->ptr, (unsigned int)n));
       
  5015     if (ip->type != t)
       
  5016     { strcpy(soap->id, id);
       
  5017       soap->error = SOAP_HREF;
       
  5018       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Type incompatibility: id type=%d href type=%d\n", ip->type, t));
       
  5019       return NULL;
       
  5020     }
       
  5021     while (ip->level < k)
       
  5022     { q = (void**)soap_malloc(soap, sizeof(void*));  
       
  5023       if (!q)
       
  5024         return NULL;
       
  5025       *p = (void*)q;
       
  5026       p = q;
       
  5027       k--;
       
  5028       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n"));
       
  5029     }
       
  5030     *p = ip->ptr;
       
  5031   }
       
  5032   else if (ip->level > k)
       
  5033   { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving level %u pointers to href='%s'\n", ip->level, id));
       
  5034     while (ip->level > k)
       
  5035     { void *s, **r = &ip->link;
       
  5036       q = (void**)ip->link;
       
  5037       while (q)
       
  5038       { *r = (void*)soap_malloc(soap, sizeof(void*));
       
  5039         s = *q;
       
  5040         *q = *r;
       
  5041         r = (void**)*r;
       
  5042         q = (void**)s;
       
  5043       }
       
  5044       *r = NULL;
       
  5045       ip->size = n; 
       
  5046       ip->copy = NULL;
       
  5047       ip->level = ip->level - 1;
       
  5048       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n"));
       
  5049     }
       
  5050     q = (void**)ip->link;
       
  5051     ip->link = p;
       
  5052     *p = (void*)q;
       
  5053   }
       
  5054   else
       
  5055   { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarded href='%s' type=%d location=%p (%u bytes)\n", id, t, p, (unsigned int)n));
       
  5056     while (ip->level < k)
       
  5057     { q = (void**)soap_malloc(soap, sizeof(void*));  
       
  5058       *p = q;
       
  5059       p = q;
       
  5060       k--;
       
  5061       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n"));
       
  5062     }
       
  5063     q = (void**)ip->link;
       
  5064     ip->link = p;
       
  5065     *p = (void*)q;
       
  5066   }
       
  5067   return p;
       
  5068 }
       
  5069 #endif
       
  5070 #endif
       
  5071 
       
  5072 /******************************************************************************/
       
  5073 #ifndef WITH_NOIDREF
       
  5074 #ifndef PALM_2
       
  5075 SOAP_FMAC1
       
  5076 void*
       
  5077 SOAP_FMAC2
       
  5078 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))
       
  5079 { struct soap_ilist *ip;
       
  5080   if (!p || !href || !*href)
       
  5081     return p;
       
  5082   ip = soap_lookup(soap, href); /* lookup pointer to hash table entry for string id */
       
  5083   if (!ip)
       
  5084   { ip = soap_enter(soap, href); /* new hash table entry for string id */
       
  5085     ip->type = st;
       
  5086     ip->size = n;
       
  5087     ip->link = NULL;
       
  5088     ip->copy = NULL;
       
  5089     ip->ptr = NULL;
       
  5090     ip->level = 0;
       
  5091     ip->flist = NULL;
       
  5092     DBGLOG(TEST,SOAP_MESSAGE(fdebug, "New entry href='%s' type=%d size=%lu level=%d location=%p\n", href, st, (unsigned long)n, k, p));
       
  5093   }
       
  5094   else if (ip->type != st || (ip->level == k && ip->size != n))
       
  5095   { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Type incompatibility id='%s' expect type=%d size=%lu level=%u got type=%d size=%lu\n", href, ip->type, (unsigned long)ip->size, k, st, (unsigned long)n));
       
  5096     strcpy(soap->id, href);
       
  5097     soap->error = SOAP_HREF;
       
  5098     return NULL;
       
  5099   }
       
  5100   if (fcopy || n < sizeof(void*) || *href != '#')
       
  5101   { register struct soap_flist *fp = (struct soap_flist*)SOAP_MALLOC(soap, sizeof(struct soap_flist));
       
  5102     if (!fp)
       
  5103     { soap->error = SOAP_EOM;
       
  5104       return NULL;
       
  5105     }
       
  5106     fp->next = ip->flist;
       
  5107     fp->type = tt;
       
  5108     fp->ptr = p;
       
  5109     fp->level = k;
       
  5110     if (fcopy)
       
  5111       fp->fcopy = fcopy;
       
  5112     else
       
  5113       fp->fcopy = soap_fcopy;
       
  5114     ip->flist = fp;
       
  5115     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));
       
  5116   }
       
  5117   else
       
  5118   { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding copying address %p for type=%d href='%s'\n", p, st, href));
       
  5119     *(void**)p = ip->copy;
       
  5120     ip->copy = p;
       
  5121   }
       
  5122   return p;
       
  5123 }
       
  5124 #endif
       
  5125 #endif
       
  5126 
       
  5127 /******************************************************************************/
       
  5128 #ifndef PALM_2
       
  5129 SOAP_FMAC1
       
  5130 void*
       
  5131 SOAP_FMAC2
       
  5132 soap_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*))
       
  5133 {
       
  5134 #ifndef WITH_NOIDREF
       
  5135   struct soap_ilist *ip;
       
  5136 #endif
       
  5137   DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Enter id='%s' type=%d loc=%p size=%lu level=%u\n", id, t, p, (unsigned long)n, k));
       
  5138   soap->alloced = 0;
       
  5139   if (!p)
       
  5140   { if (finstantiate)
       
  5141       p = finstantiate(soap, t, type, arrayType, &n);
       
  5142     else
       
  5143       p = soap_malloc(soap, n);
       
  5144     if (p)
       
  5145       soap->alloced = 1;
       
  5146   }
       
  5147 #ifndef WITH_NOIDREF
       
  5148   if (!id || !*id)
       
  5149 #endif
       
  5150     return p;
       
  5151 #ifndef WITH_NOIDREF
       
  5152   ip = soap_lookup(soap, id); /* lookup pointer to hash table entry for string id */
       
  5153   DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Lookup entry id='%s for location=%p'\n", id, p));
       
  5154   if (!ip)
       
  5155   { ip = soap_enter(soap, id); /* new hash table entry for string id */
       
  5156     ip->type = t;
       
  5157     ip->link = NULL;
       
  5158     ip->copy = NULL;
       
  5159     ip->flist = NULL;
       
  5160     ip->size = n;
       
  5161     ip->ptr = p;
       
  5162     ip->level = k;
       
  5163     DBGLOG(TEST,SOAP_MESSAGE(fdebug, "New entry id='%s' type=%d size=%lu level=%u location=%p\n", id, t, (unsigned long)n, k, p));
       
  5164   }
       
  5165   else if ((ip->type != t || (ip->level == k && ip->size != n)) && (ip->copy || ip->flist))
       
  5166   { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Type incompatibility id='%s' expect type=%d size=%lu level=%u got type=%d size=%lu\n", id, ip->type, (unsigned long)ip->size, k, t, (unsigned long)n));
       
  5167     strcpy(soap->id, id);
       
  5168     soap->error = SOAP_HREF;
       
  5169     return NULL;
       
  5170   }
       
  5171   else if (ip->ptr)
       
  5172   { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Multiply defined id='%s'\n", id));
       
  5173     strcpy(soap->id, id);
       
  5174     soap->error = SOAP_DUPLICATE_ID;
       
  5175     return NULL;
       
  5176   }
       
  5177   else 
       
  5178   { ip->size = n;
       
  5179     ip->ptr = p;
       
  5180     ip->level = k;
       
  5181     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update entry id='%s' type=%d location=%p size=%lu level=%u\n", id, t, p, (unsigned long)n, k));
       
  5182   }
       
  5183   return ip->ptr;
       
  5184 #endif
       
  5185 }
       
  5186 #endif
       
  5187 
       
  5188 /******************************************************************************/
       
  5189 #ifndef PALM_2
       
  5190 SOAP_FMAC1
       
  5191 void
       
  5192 SOAP_FMAC2
       
  5193 soap_fcopy(struct soap *soap, int st, int tt, void *p, const void *q, size_t n)
       
  5194 { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Copying data type=%d (target type=%d) %p -> %p (%lu bytes)\n", st, tt, q, p, (unsigned long)n));
       
  5195   memcpy(p, q, n);
       
  5196 }
       
  5197 #endif
       
  5198 
       
  5199 /******************************************************************************/
       
  5200 #ifndef PALM_1
       
  5201 SOAP_FMAC1
       
  5202 int
       
  5203 SOAP_FMAC2
       
  5204 soap_end_send(struct soap *soap)
       
  5205 { 
       
  5206 #ifndef WITH_LEANER
       
  5207   if (soap->dime.list)
       
  5208   { /* SOAP body referenced attachments must appear first */
       
  5209     soap->dime.last->next = soap->dime.first;
       
  5210     soap->dime.first = soap->dime.list->next;
       
  5211     soap->dime.list->next = NULL;
       
  5212     soap->dime.last = soap->dime.list;
       
  5213   }
       
  5214   if (soap_putdime(soap) || soap_putmime(soap))
       
  5215     return soap->error;
       
  5216   soap->mime.list = NULL;
       
  5217   soap->mime.first = NULL;
       
  5218   soap->mime.last = NULL;
       
  5219   soap->dime.list = NULL;
       
  5220   soap->dime.first = NULL;
       
  5221   soap->dime.last = NULL;
       
  5222 #endif
       
  5223   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End send\n"));
       
  5224   if (soap->mode & SOAP_IO) /* need to flush the remaining data in buffer */
       
  5225   { if (soap_flush(soap))
       
  5226 #ifdef WITH_ZLIB
       
  5227     { if (soap->mode & SOAP_ENC_ZLIB && soap->zlib_state == SOAP_ZLIB_DEFLATE)
       
  5228       { soap->zlib_state = SOAP_ZLIB_NONE;
       
  5229         deflateEnd(&soap->d_stream);
       
  5230       }
       
  5231       return soap->error;
       
  5232     }
       
  5233 #else
       
  5234       return soap->error;
       
  5235 #endif
       
  5236 #ifdef WITH_ZLIB
       
  5237     if (soap->mode & SOAP_ENC_ZLIB)
       
  5238     { int r;
       
  5239       soap->d_stream.avail_in = 0;
       
  5240       do
       
  5241       { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflating remainder\n"));
       
  5242         r = deflate(&soap->d_stream, Z_FINISH);
       
  5243         if (soap->d_stream.avail_out != SOAP_BUFLEN)
       
  5244         { if (soap_flush_raw(soap, soap->z_buf, SOAP_BUFLEN - soap->d_stream.avail_out))
       
  5245           { soap->zlib_state = SOAP_ZLIB_NONE;
       
  5246             deflateEnd(&soap->d_stream);
       
  5247             return soap->error;
       
  5248 	  }
       
  5249           soap->d_stream.next_out = (Byte*)soap->z_buf;
       
  5250           soap->d_stream.avail_out = SOAP_BUFLEN;
       
  5251         }
       
  5252       } while (r == Z_OK);
       
  5253       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflated %lu->%lu bytes\n", soap->d_stream.total_in, soap->d_stream.total_out));
       
  5254       soap->z_ratio_out = (float)soap->d_stream.total_out / (float)soap->d_stream.total_in;
       
  5255       soap->mode &= ~SOAP_ENC_ZLIB;
       
  5256       soap->zlib_state = SOAP_ZLIB_NONE;
       
  5257       if (deflateEnd(&soap->d_stream) != Z_OK || r != Z_STREAM_END)
       
  5258       { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to end deflate: %s\n", soap->d_stream.msg?soap->d_stream.msg:""));
       
  5259         return soap->error = SOAP_ZLIB_ERROR;
       
  5260       }
       
  5261 #ifdef WITH_GZIP
       
  5262       soap->z_buf[0] = soap->z_crc & 0xFF;
       
  5263       soap->z_buf[1] = (soap->z_crc >> 8) & 0xFF;
       
  5264       soap->z_buf[2] = (soap->z_crc >> 16) & 0xFF;
       
  5265       soap->z_buf[3] = (soap->z_crc >> 24) & 0xFF;
       
  5266       soap->z_buf[4] = soap->d_stream.total_in & 0xFF;
       
  5267       soap->z_buf[5] = (soap->d_stream.total_in >> 8) & 0xFF;
       
  5268       soap->z_buf[6] = (soap->d_stream.total_in >> 16) & 0xFF;
       
  5269       soap->z_buf[7] = (soap->d_stream.total_in >> 24) & 0xFF;
       
  5270       if (soap_flush_raw(soap, soap->z_buf, 8))
       
  5271         return soap->error;
       
  5272       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip crc32=%lu\n", (unsigned long)soap->z_crc));
       
  5273 #endif
       
  5274     }
       
  5275 #endif
       
  5276     if ((soap->mode & SOAP_IO) == SOAP_IO_STORE)
       
  5277     { char *p;
       
  5278 #ifndef WITH_NOHTTP
       
  5279       if (!(soap->mode & SOAP_ENC_XML))
       
  5280       { soap->mode--;
       
  5281         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Sending buffered message of length %u\n", (unsigned int)soap->blist->size));
       
  5282         if (soap->status >= SOAP_POST)
       
  5283           soap->error = soap->fpost(soap, soap->endpoint, soap->host, soap->port, soap->path, soap->action, soap->blist->size);
       
  5284         else if (soap->status != SOAP_STOP)
       
  5285           soap->error = soap->fresponse(soap, soap->status, soap->blist->size);
       
  5286         if (soap->error || soap_flush(soap))
       
  5287           return soap->error;
       
  5288         soap->mode++;
       
  5289       }
       
  5290 #endif
       
  5291       for (p = soap_first_block(soap); p; p = soap_next_block(soap))
       
  5292       { DBGMSG(SENT, p, soap_block_size(soap));
       
  5293         if ((soap->error = soap->fsend(soap, p, soap_block_size(soap))))
       
  5294         { soap_end_block(soap);
       
  5295           return soap->error;
       
  5296         }
       
  5297       }
       
  5298       soap_end_block(soap);
       
  5299     }
       
  5300 #ifndef WITH_LEANER
       
  5301     else if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK)
       
  5302     { DBGMSG(SENT, "\r\n0\r\n\r\n", 7);
       
  5303       if ((soap->error = soap->fsend(soap, "\r\n0\r\n\r\n", 7)))
       
  5304         return soap->error;
       
  5305     }
       
  5306 #endif
       
  5307   }
       
  5308 #ifdef WITH_OPENSSL
       
  5309   if (!soap->ssl && soap_valid_socket(soap->socket) && !soap->keep_alive && !(soap->omode & SOAP_IO_UDP))
       
  5310     soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 1); /* Send TCP FIN */
       
  5311 #else
       
  5312   if (soap_valid_socket(soap->socket) && !soap->keep_alive && !(soap->omode & SOAP_IO_UDP))
       
  5313     soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 1); /* Send TCP FIN */
       
  5314 #endif
       
  5315   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of send phase\n"));
       
  5316   soap->omode &= ~SOAP_XML_SEC;
       
  5317   soap->count = 0;
       
  5318   soap->part = SOAP_END;
       
  5319   return SOAP_OK;
       
  5320 }
       
  5321 #endif
       
  5322 
       
  5323 /******************************************************************************/
       
  5324 #ifndef PALM_1
       
  5325 SOAP_FMAC1
       
  5326 int
       
  5327 SOAP_FMAC2
       
  5328 soap_end_recv(struct soap *soap)
       
  5329 { soap->part = SOAP_END;
       
  5330 #ifndef WITH_LEANER
       
  5331   if ((soap->mode & SOAP_ENC_DIME) && soap_getdime(soap))
       
  5332     return soap->error;
       
  5333   soap->dime.list = soap->dime.first;
       
  5334   soap->dime.first = NULL;
       
  5335   soap->dime.last = NULL;
       
  5336   if ((soap->mode & SOAP_ENC_MIME) && soap_getmime(soap))
       
  5337     return soap->error;
       
  5338   soap->mime.list = soap->mime.first;
       
  5339   soap->mime.first = NULL;
       
  5340   soap->mime.last = NULL;
       
  5341   soap->mime.boundary = NULL;
       
  5342 #endif
       
  5343   DBGLOG(TEST,SOAP_MESSAGE(fdebug, "End of receive message ok\n"));
       
  5344 #ifdef WITH_ZLIB
       
  5345   if (soap->mode & SOAP_ENC_ZLIB)
       
  5346   { soap->mode &= ~SOAP_ENC_ZLIB;
       
  5347     memcpy(soap->buf, soap->z_buf, SOAP_BUFLEN);
       
  5348     soap->bufidx = (char*)soap->d_stream.next_in - soap->z_buf;
       
  5349     soap->buflen = soap->z_buflen;
       
  5350     soap->zlib_state = SOAP_ZLIB_NONE;
       
  5351     if (inflateEnd(&soap->d_stream) != Z_OK)
       
  5352       return soap->error = SOAP_ZLIB_ERROR;
       
  5353 #ifdef WITH_GZIP
       
  5354     if (soap->zlib_in == SOAP_ZLIB_GZIP)
       
  5355     { soap_wchar c;
       
  5356       short i;
       
  5357       for (i = 0; i < 8; i++)
       
  5358       { if ((int)(c = soap_getchar(soap)) == EOF)
       
  5359           return soap->error = SOAP_EOF;
       
  5360         soap->z_buf[i] = (char)c;
       
  5361       }
       
  5362       if (soap->z_crc != ((uLong)(unsigned char)soap->z_buf[0] | ((uLong)(unsigned char)soap->z_buf[1] << 8) | ((uLong)(unsigned char)soap->z_buf[2] << 16) | ((uLong)(unsigned char)soap->z_buf[3] << 24)))
       
  5363       { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Gzip error: crc check failed, message corrupted? (crc32=%lu)\n", (unsigned long)soap->z_crc));
       
  5364         return soap->error = SOAP_ZLIB_ERROR;
       
  5365       }
       
  5366       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)))
       
  5367       { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Gzip error: incorrect message length\n"));
       
  5368         return soap->error = SOAP_ZLIB_ERROR;
       
  5369       }
       
  5370     }
       
  5371 #endif
       
  5372   }
       
  5373 #endif
       
  5374   if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK)
       
  5375     while ((int)soap_getchar(soap) != EOF) /* advance to last chunk */
       
  5376       ;
       
  5377   if (soap->fdisconnect && (soap->error = soap->fdisconnect(soap)))
       
  5378     return soap->error;
       
  5379 #ifndef WITH_NOIDREF
       
  5380   return soap_resolve(soap);
       
  5381 #else
       
  5382 #ifndef WITH_LEANER
       
  5383   if (soap->xlist)
       
  5384   { if (soap->mode & SOAP_ENC_MTOM)
       
  5385       return soap->error = SOAP_MIME_HREF;
       
  5386     return soap->error = SOAP_DIME_HREF;
       
  5387   }
       
  5388 #endif
       
  5389   return SOAP_OK;
       
  5390 #endif
       
  5391 }
       
  5392 #endif
       
  5393 
       
  5394 /******************************************************************************/
       
  5395 #ifndef PALM_1
       
  5396 SOAP_FMAC1
       
  5397 void
       
  5398 SOAP_FMAC2
       
  5399 soap_free(struct soap *soap)
       
  5400 { register struct Namespace *ns;
       
  5401   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free namespace stack\n"));
       
  5402   while (soap->nlist)
       
  5403   { register struct soap_nlist *np = soap->nlist->next;
       
  5404     SOAP_FREE(soap, soap->nlist);
       
  5405     soap->nlist = np;
       
  5406   }
       
  5407   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free any remaining temp blocks\n"));
       
  5408   while (soap->blist)
       
  5409     soap_end_block(soap);
       
  5410   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free attribute storage\n"));
       
  5411   while (soap->attributes)
       
  5412   { register struct soap_attribute *tp = soap->attributes->next;
       
  5413     if (soap->attributes->value)
       
  5414       SOAP_FREE(soap, soap->attributes->value);
       
  5415     SOAP_FREE(soap, soap->attributes);
       
  5416     soap->attributes = tp;
       
  5417   }
       
  5418 #ifdef WITH_FAST
       
  5419   if (soap->labbuf)
       
  5420     SOAP_FREE(soap, soap->labbuf);
       
  5421   soap->labbuf = NULL;
       
  5422   soap->lablen = 0;
       
  5423   soap->labidx = 0;
       
  5424 #endif
       
  5425   ns = soap->local_namespaces;
       
  5426   if (ns)
       
  5427   { for (; ns->id; ns++)
       
  5428     { if (ns->out)
       
  5429       { if (soap->encodingStyle == ns->out)
       
  5430           soap->encodingStyle = SOAP_STR_EOS;
       
  5431         SOAP_FREE(soap, ns->out);
       
  5432         ns->out = NULL;
       
  5433       }
       
  5434       if (soap->encodingStyle == ns->ns)
       
  5435         soap->encodingStyle = SOAP_STR_EOS;
       
  5436     }
       
  5437     SOAP_FREE(soap, soap->local_namespaces);
       
  5438     soap->local_namespaces = NULL;
       
  5439   }
       
  5440 #ifndef WITH_LEANER
       
  5441   while (soap->xlist)
       
  5442   { struct soap_xlist *xp = soap->xlist->next;
       
  5443     SOAP_FREE(soap, soap->xlist);
       
  5444     soap->xlist = xp;
       
  5445   }
       
  5446 #endif
       
  5447 #ifndef WITH_NOIDREF
       
  5448   soap_free_pht(soap);
       
  5449   soap_free_iht(soap);
       
  5450 #endif
       
  5451 }
       
  5452 #endif
       
  5453 
       
  5454 /******************************************************************************/
       
  5455 #ifdef SOAP_DEBUG
       
  5456 static void
       
  5457 soap_init_logs(struct soap *soap)
       
  5458 { int i;
       
  5459   for (i = 0; i < SOAP_MAXLOGS; i++)
       
  5460   { soap->logfile[i] = NULL;
       
  5461     soap->fdebug[i] = NULL;
       
  5462   }
       
  5463 }
       
  5464 #endif
       
  5465 
       
  5466 /******************************************************************************/
       
  5467 #if !defined(WITH_LEAN) || defined(SOAP_DEBUG)
       
  5468 SOAP_FMAC1
       
  5469 void
       
  5470 SOAP_FMAC2
       
  5471 soap_open_logfile(struct soap *soap, int i)
       
  5472 { if (soap->logfile[i])
       
  5473     soap->fdebug[i] = fopen(soap->logfile[i], i < 2 ? "ab" : "a");
       
  5474 }
       
  5475 #endif
       
  5476 
       
  5477 /******************************************************************************/
       
  5478 #ifdef SOAP_DEBUG
       
  5479 static void
       
  5480 soap_close_logfile(struct soap *soap, int i)
       
  5481 { if (soap->fdebug[i])
       
  5482   { fclose(soap->fdebug[i]);
       
  5483     soap->fdebug[i] = NULL;
       
  5484   }
       
  5485 }
       
  5486 #endif
       
  5487 
       
  5488 /******************************************************************************/
       
  5489 #ifdef SOAP_DEBUG
       
  5490 SOAP_FMAC1
       
  5491 void
       
  5492 SOAP_FMAC2
       
  5493 soap_close_logfiles(struct soap *soap)
       
  5494 { int i;
       
  5495   for (i = 0; i < SOAP_MAXLOGS; i++)
       
  5496     soap_close_logfile(soap, i);
       
  5497 }
       
  5498 #endif
       
  5499 
       
  5500 /******************************************************************************/
       
  5501 #ifdef SOAP_DEBUG
       
  5502 static void
       
  5503 soap_set_logfile(struct soap *soap, int i, const char *logfile)
       
  5504 { char *s = NULL;
       
  5505   soap_close_logfile(soap, i);
       
  5506   if (soap->logfile[i])
       
  5507     SOAP_FREE(soap, (void*)soap->logfile[i]);
       
  5508   if (logfile)
       
  5509     if ((s = (char*)SOAP_MALLOC(soap, strlen(logfile) + 1)))
       
  5510       strcpy(s, logfile);
       
  5511   soap->logfile[i] = s;
       
  5512 }
       
  5513 #endif
       
  5514 
       
  5515 /******************************************************************************/
       
  5516 #ifdef SOAP_DEBUG
       
  5517 SOAP_FMAC1
       
  5518 void
       
  5519 SOAP_FMAC2
       
  5520 soap_set_recv_logfile(struct soap *soap, const char *logfile)
       
  5521 { soap_set_logfile(soap, SOAP_INDEX_RECV, logfile);
       
  5522 }
       
  5523 #endif
       
  5524 
       
  5525 /******************************************************************************/
       
  5526 #ifdef SOAP_DEBUG
       
  5527 SOAP_FMAC1
       
  5528 void
       
  5529 SOAP_FMAC2
       
  5530 soap_set_sent_logfile(struct soap *soap, const char *logfile)
       
  5531 { soap_set_logfile(soap, SOAP_INDEX_SENT, logfile);
       
  5532 }
       
  5533 #endif
       
  5534 
       
  5535 /******************************************************************************/
       
  5536 #ifdef SOAP_DEBUG
       
  5537 SOAP_FMAC1
       
  5538 void
       
  5539 SOAP_FMAC2
       
  5540 soap_set_test_logfile(struct soap *soap, const char *logfile)
       
  5541 { soap_set_logfile(soap, SOAP_INDEX_TEST, logfile);
       
  5542 }
       
  5543 #endif
       
  5544 
       
  5545 /******************************************************************************/
       
  5546 #ifndef PALM_1
       
  5547 SOAP_FMAC1
       
  5548 struct soap*
       
  5549 SOAP_FMAC2
       
  5550 soap_copy(struct soap *soap)
       
  5551 { return soap_copy_context((struct soap*)malloc(sizeof(struct soap)), soap);
       
  5552 }
       
  5553 #endif
       
  5554 
       
  5555 /******************************************************************************/
       
  5556 #ifndef PALM_1
       
  5557 SOAP_FMAC1
       
  5558 struct soap*
       
  5559 SOAP_FMAC2
       
  5560 soap_copy_context(struct soap *copy, struct soap *soap)
       
  5561 { if (copy)
       
  5562   { register struct soap_plugin *p;
       
  5563     memcpy(copy, soap, sizeof(struct soap));
       
  5564     copy->copy = 1;
       
  5565     copy->user = NULL;
       
  5566     copy->error = SOAP_OK;
       
  5567     copy->userid = NULL;
       
  5568     copy->passwd = NULL;
       
  5569     copy->nlist = NULL;
       
  5570     copy->blist = NULL;
       
  5571     copy->clist = NULL;
       
  5572     copy->alist = NULL;
       
  5573     copy->attributes = NULL;
       
  5574 #ifdef WITH_FAST
       
  5575     copy->labbuf = NULL;
       
  5576     copy->lablen = 0;
       
  5577     copy->labidx = 0;
       
  5578 #endif
       
  5579 #ifdef SOAP_DEBUG
       
  5580     soap_init_mht(copy);
       
  5581 #endif
       
  5582     copy->local_namespaces = NULL;
       
  5583 #ifndef WITH_NOIDREF
       
  5584     soap_init_iht(copy);
       
  5585     soap_init_pht(copy);
       
  5586 #endif
       
  5587     copy->header = NULL;
       
  5588     copy->fault = NULL;
       
  5589     copy->action = NULL;
       
  5590     *copy->host = '\0';
       
  5591 #ifndef WITH_LEAN
       
  5592 #ifdef WITH_COOKIES
       
  5593     copy->cookies = soap_copy_cookies(copy);
       
  5594 #else
       
  5595     copy->cookies = NULL;
       
  5596 #endif
       
  5597 #endif
       
  5598 #ifdef SOAP_DEBUG
       
  5599     soap_init_logs(copy);
       
  5600     soap_set_recv_logfile(copy, soap->logfile[SOAP_INDEX_RECV]);
       
  5601     soap_set_sent_logfile(copy, soap->logfile[SOAP_INDEX_SENT]);
       
  5602     soap_set_test_logfile(copy, soap->logfile[SOAP_INDEX_TEST]);
       
  5603 #endif
       
  5604     copy->plugins = NULL;
       
  5605     for (p = soap->plugins; p; p = p->next)
       
  5606     { register struct soap_plugin *q = (struct soap_plugin*)SOAP_MALLOC(copy, sizeof(struct soap_plugin));
       
  5607       if (!q)
       
  5608         return NULL;
       
  5609       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying plugin '%s'\n", p->id));
       
  5610       *q = *p;
       
  5611       if (p->fcopy && (soap->error = p->fcopy(copy, q, p)))
       
  5612       { SOAP_FREE(copy, q);
       
  5613         return NULL;
       
  5614       }
       
  5615       q->next = copy->plugins;
       
  5616       copy->plugins = q;
       
  5617     }
       
  5618   }
       
  5619   else
       
  5620     soap->error = SOAP_EOM;
       
  5621   return copy;
       
  5622 }
       
  5623 #endif
       
  5624 
       
  5625 /******************************************************************************/
       
  5626 #ifndef PALM_1
       
  5627 SOAP_FMAC1
       
  5628 void
       
  5629 SOAP_FMAC2
       
  5630 soap_init(struct soap *soap)
       
  5631 { soap->version = 0;
       
  5632   soap_imode(soap, SOAP_IO_DEFAULT);
       
  5633   soap_omode(soap, SOAP_IO_DEFAULT);
       
  5634   soap->copy = 0;
       
  5635   soap->plugins = NULL;
       
  5636   soap->user = NULL;
       
  5637   soap->userid = NULL;
       
  5638   soap->passwd = NULL;
       
  5639 #ifndef WITH_NOHTTP
       
  5640   soap->fpost = http_post;
       
  5641   soap->fget = http_get;
       
  5642   soap->fform = NULL;
       
  5643   soap->fposthdr = http_post_header;
       
  5644   soap->fresponse = http_response;
       
  5645   soap->fparse = http_parse;
       
  5646   soap->fparsehdr = http_parse_header;
       
  5647 #endif
       
  5648   soap->fconnect = NULL;
       
  5649   soap->fdisconnect = NULL;
       
  5650 #ifndef WITH_NOIO
       
  5651 #ifndef WITH_IPV6
       
  5652   soap->fresolve = tcp_gethost;
       
  5653 #else
       
  5654   soap->fresolve = NULL;
       
  5655 #endif
       
  5656   soap->faccept = tcp_accept;
       
  5657   soap->fopen = tcp_connect;
       
  5658   soap->fclose = tcp_disconnect;
       
  5659   soap->fclosesocket = tcp_closesocket;
       
  5660   soap->fshutdownsocket = tcp_shutdownsocket;
       
  5661   soap->fsend = fsend;
       
  5662   soap->frecv = frecv;
       
  5663   soap->fpoll = soap_poll;
       
  5664 #else
       
  5665   soap->fopen = NULL;
       
  5666   soap->fclose = NULL;
       
  5667   soap->fpoll = NULL;
       
  5668 #endif
       
  5669 #ifndef WITH_LEANER
       
  5670   soap->fprepareinit = NULL;
       
  5671   soap->fpreparesend = NULL;
       
  5672   soap->fpreparerecv = NULL;
       
  5673   soap->fpreparefinal = NULL;
       
  5674 #endif
       
  5675   soap->fseterror = NULL;
       
  5676   soap->fignore = NULL;
       
  5677   soap->fserveloop = NULL;
       
  5678   soap->fplugin = fplugin;
       
  5679 #ifndef WITH_LEANER
       
  5680   soap->fdimereadopen = NULL;
       
  5681   soap->fdimewriteopen = NULL;
       
  5682   soap->fdimereadclose = NULL;
       
  5683   soap->fdimewriteclose = NULL;
       
  5684   soap->fdimeread = NULL;
       
  5685   soap->fdimewrite = NULL;
       
  5686 #endif
       
  5687   soap->float_format = "%.8g"; /* .8 preserves single FP precision as much as possible, but might not be very efficient */
       
  5688   soap->double_format = "%.17lg"; /* .17 preserves double FP precision as much as possible, but might not be very efficient */
       
  5689   soap->dime_id_format = "cid:id%d"; /* default DIME id format */
       
  5690   soap->http_version = "1.1";
       
  5691   soap->actor = NULL;
       
  5692   soap->max_keep_alive = SOAP_MAXKEEPALIVE;
       
  5693   soap->keep_alive = 0;
       
  5694   soap->recv_timeout = 0;
       
  5695   soap->send_timeout = 0;
       
  5696   soap->connect_timeout = 0;
       
  5697   soap->accept_timeout = 0;
       
  5698   soap->socket_flags = 0;
       
  5699   soap->connect_flags = 0;
       
  5700   soap->bind_flags = 0;
       
  5701   soap->accept_flags = 0;
       
  5702   soap->ip = 0;
       
  5703 #ifdef WITH_FAST
       
  5704   soap->labbuf = NULL;
       
  5705   soap->lablen = 0;
       
  5706   soap->labidx = 0;
       
  5707 #endif
       
  5708   soap->encodingStyle = SOAP_STR_EOS;
       
  5709 #ifndef WITH_NONAMESPACES
       
  5710   soap->namespaces = namespaces;
       
  5711 #else
       
  5712   soap->namespaces = NULL;
       
  5713 #endif
       
  5714   soap->local_namespaces = NULL;
       
  5715   soap->nlist = NULL;
       
  5716   soap->blist = NULL;
       
  5717   soap->clist = NULL;
       
  5718   soap->alist = NULL;
       
  5719   soap->attributes = NULL;
       
  5720   soap->header = NULL;
       
  5721   soap->fault = NULL;
       
  5722   soap->master = SOAP_INVALID_SOCKET;
       
  5723   soap->socket = SOAP_INVALID_SOCKET;
       
  5724   soap->os = NULL;
       
  5725   soap->is = NULL;
       
  5726 #ifndef WITH_LEANER
       
  5727   soap->dom = NULL;
       
  5728   soap->dime.list = NULL;
       
  5729   soap->dime.first = NULL;
       
  5730   soap->dime.last = NULL;
       
  5731   soap->mime.list = NULL;
       
  5732   soap->mime.first = NULL;
       
  5733   soap->mime.last = NULL;
       
  5734   soap->mime.boundary = NULL;
       
  5735   soap->mime.start = NULL;
       
  5736   soap->xlist = NULL;
       
  5737 #endif
       
  5738 #ifndef UNDER_CE
       
  5739   soap->recvfd = 0;
       
  5740   soap->sendfd = 1;
       
  5741 #else
       
  5742   soap->recvfd = stdin;
       
  5743   soap->sendfd = stdout;
       
  5744 #endif 
       
  5745   soap->host[0] = '\0';
       
  5746   soap->port = 0;
       
  5747   soap->action = NULL;
       
  5748   soap->proxy_host = NULL;
       
  5749   soap->proxy_port = 8080;
       
  5750   soap->proxy_userid = NULL;
       
  5751   soap->proxy_passwd = NULL;
       
  5752   soap->authrealm = NULL;
       
  5753   soap->prolog = NULL;
       
  5754 #ifdef WITH_OPENSSL
       
  5755   soap->fsslauth = ssl_auth_init;
       
  5756   soap->fsslverify = ssl_verify_callback;
       
  5757   soap->bio = NULL;
       
  5758   soap->ssl = NULL;
       
  5759   soap->ctx = NULL;
       
  5760   soap->require_server_auth = 0;
       
  5761   soap->require_client_auth = 0;
       
  5762   soap->rsa = 0;
       
  5763   soap->keyfile = NULL;
       
  5764   soap->password = NULL;
       
  5765   soap->dhfile = NULL;
       
  5766   soap->cafile = NULL;
       
  5767   soap->capath = NULL;
       
  5768   soap->crlfile = NULL;
       
  5769   soap->randfile = NULL;
       
  5770   soap->session = NULL;
       
  5771 #endif
       
  5772 #ifdef WITH_ZLIB
       
  5773   soap->zlib_state = SOAP_ZLIB_NONE;
       
  5774   soap->zlib_in = SOAP_ZLIB_NONE;
       
  5775   soap->zlib_out = SOAP_ZLIB_NONE;
       
  5776   soap->d_stream.zalloc = NULL;
       
  5777   soap->d_stream.zfree = NULL;
       
  5778   soap->d_stream.opaque = NULL;
       
  5779   soap->z_level = 6;
       
  5780 #endif
       
  5781 #ifndef WITH_LEAN
       
  5782   soap->c14ninclude = NULL;
       
  5783   soap->c14nexclude = NULL;
       
  5784   soap->cookies = NULL;
       
  5785   soap->cookie_domain = NULL;
       
  5786   soap->cookie_path = NULL;
       
  5787   soap->cookie_max = 32;
       
  5788 #endif
       
  5789 #ifdef SOAP_DEBUG
       
  5790   soap_init_mht(soap);
       
  5791   soap_init_logs(soap);
       
  5792   soap_set_recv_logfile(soap, "RECV.log");
       
  5793   soap_set_sent_logfile(soap, "SENT.log");
       
  5794   soap_set_test_logfile(soap, NULL);
       
  5795 #endif
       
  5796 #ifdef WMW_RPM_IO
       
  5797   soap->rpmreqid = NULL;
       
  5798 #endif /* WMW_RPM_IO */
       
  5799 #ifdef PALM
       
  5800   palmNetLibOpen();
       
  5801 #endif
       
  5802 #ifndef WITH_NOIDREF
       
  5803   soap_init_iht(soap);
       
  5804   soap_init_pht(soap);
       
  5805 #endif
       
  5806   soap_begin(soap);
       
  5807 #ifdef SOAP_DEBUG
       
  5808   soap_set_test_logfile(soap, "TEST.log");
       
  5809 #endif
       
  5810 }
       
  5811 #endif
       
  5812 
       
  5813 /******************************************************************************/
       
  5814 #ifndef PALM_1
       
  5815 SOAP_FMAC1
       
  5816 void
       
  5817 SOAP_FMAC2
       
  5818 soap_init1(struct soap *soap, soap_mode mode)
       
  5819 { soap_init2(soap, mode, mode);
       
  5820 }
       
  5821 #endif
       
  5822 
       
  5823 /******************************************************************************/
       
  5824 #ifndef PALM_1
       
  5825 SOAP_FMAC1
       
  5826 void
       
  5827 SOAP_FMAC2
       
  5828 soap_init2(struct soap *soap, soap_mode imode, soap_mode omode)
       
  5829 { soap_init(soap);
       
  5830   soap_imode(soap, imode);
       
  5831   soap_omode(soap, omode);
       
  5832 }
       
  5833 #endif
       
  5834 
       
  5835 /******************************************************************************/
       
  5836 #ifndef PALM_2
       
  5837 SOAP_FMAC1
       
  5838 void
       
  5839 SOAP_FMAC2
       
  5840 soap_begin(struct soap *soap)
       
  5841 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing\n"));
       
  5842   if (!soap->keep_alive)
       
  5843   { soap->buflen = 0;
       
  5844     soap->bufidx = 0;
       
  5845   }
       
  5846   soap->keep_alive = (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) != 0);
       
  5847   soap->null = 0;
       
  5848   soap->position = 0;
       
  5849   soap->encoding = 0;
       
  5850   soap->mustUnderstand = 0;
       
  5851   soap->mode = 0;
       
  5852   soap->ns = 0;
       
  5853   soap->part = SOAP_END;
       
  5854   soap->alloced = 0;
       
  5855   soap->count = 0;
       
  5856   soap->length = 0;
       
  5857   soap->cdata = 0;
       
  5858   soap->error = SOAP_OK;
       
  5859   soap->peeked = 0;
       
  5860   soap->ahead = 0;
       
  5861   soap->idnum = 0;
       
  5862   soap->level = 0;
       
  5863   soap->endpoint[0] = '\0';
       
  5864 #ifndef WITH_LEANER
       
  5865   soap->dime.chunksize = 0;
       
  5866   soap->dime.buflen = 0;
       
  5867 #endif
       
  5868   soap_free(soap);
       
  5869 }
       
  5870 #endif
       
  5871 
       
  5872 /******************************************************************************/
       
  5873 #ifndef PALM_2
       
  5874 SOAP_FMAC1
       
  5875 void
       
  5876 SOAP_FMAC2
       
  5877 soap_end(struct soap *soap)
       
  5878 { register struct soap_clist *cp;
       
  5879   soap_free(soap);
       
  5880   soap_dealloc(soap, NULL);
       
  5881   while (soap->clist)
       
  5882   { cp = soap->clist->next;
       
  5883     SOAP_FREE(soap, soap->clist);
       
  5884     soap->clist = cp;
       
  5885   }
       
  5886   soap_closesock(soap);
       
  5887 #ifdef SOAP_DEBUG
       
  5888   soap_close_logfiles(soap);
       
  5889 #endif
       
  5890 #ifdef PALM
       
  5891   palmNetLibClose();
       
  5892 #endif
       
  5893 }
       
  5894 #endif
       
  5895 
       
  5896 /******************************************************************************/
       
  5897 #ifndef PALM_1
       
  5898 SOAP_FMAC1
       
  5899 int
       
  5900 SOAP_FMAC2
       
  5901 soap_set_namespaces(struct soap *soap, struct Namespace *p)
       
  5902 { register struct Namespace *ns = soap->local_namespaces;
       
  5903   register struct soap_nlist *np, *nq, *nr;
       
  5904   register unsigned int level = soap->level;
       
  5905   soap->namespaces = p;
       
  5906   soap->local_namespaces = NULL;
       
  5907   soap_set_local_namespaces(soap);
       
  5908   /* reverse the namespace list */
       
  5909   np = soap->nlist;
       
  5910   soap->nlist = NULL;
       
  5911   if (np)
       
  5912   { nq = np->next;
       
  5913     np->next = NULL;
       
  5914     while (nq)
       
  5915     { nr = nq->next;
       
  5916       nq->next = np;
       
  5917       np = nq;
       
  5918       nq = nr;
       
  5919     }
       
  5920   }
       
  5921   /* then push on new stack */
       
  5922   while (np)
       
  5923   { register const char *s;
       
  5924     soap->level = np->level; /* preserve element nesting level */
       
  5925     s = np->ns;
       
  5926     if (!s && np->index >= 0 && ns)
       
  5927     { s = ns[np->index].out;
       
  5928       if (!s)
       
  5929         s = ns[np->index].ns;
       
  5930     }
       
  5931     if (s && soap_push_namespace(soap, np->id, s))
       
  5932       return soap->error;
       
  5933     nq = np;
       
  5934     np = np->next;
       
  5935     SOAP_FREE(soap, nq);
       
  5936   }
       
  5937   if (ns)
       
  5938   { register int i;
       
  5939     for (i = 0; ns[i].id; i++)
       
  5940     { if (ns[i].out)
       
  5941       { SOAP_FREE(soap, ns[i].out);
       
  5942         ns[i].out = NULL;
       
  5943       }
       
  5944     }
       
  5945     SOAP_FREE(soap, ns);
       
  5946   }
       
  5947   soap->level = level; /* restore level */
       
  5948   return SOAP_OK;
       
  5949 }
       
  5950 #endif
       
  5951 
       
  5952 /******************************************************************************/
       
  5953 #ifndef PALM_1
       
  5954 SOAP_FMAC1
       
  5955 void
       
  5956 SOAP_FMAC2
       
  5957 soap_set_local_namespaces(struct soap *soap)
       
  5958 { if (soap->namespaces && !soap->local_namespaces)
       
  5959   { register const struct Namespace *ns1;
       
  5960     register struct Namespace *ns2;
       
  5961     register size_t n = 1;
       
  5962     for (ns1 = soap->namespaces; ns1->id; ns1++)
       
  5963       n++;
       
  5964     n *= sizeof(struct Namespace);
       
  5965     ns2 = (struct Namespace*)SOAP_MALLOC(soap, n);
       
  5966     if (ns2)
       
  5967     { memcpy(ns2, soap->namespaces, n);
       
  5968       if (ns2[0].ns)
       
  5969       { if (!strcmp(ns2[0].ns, soap_env1))
       
  5970           soap->version = 1;
       
  5971         else
       
  5972           soap->version = 2;
       
  5973       }
       
  5974       soap->local_namespaces = ns2;
       
  5975     }
       
  5976   }
       
  5977 }
       
  5978 #endif
       
  5979 
       
  5980 /******************************************************************************/
       
  5981 #ifndef WITH_LEAN
       
  5982 #ifndef PALM_1
       
  5983 SOAP_FMAC1
       
  5984 const char *
       
  5985 SOAP_FMAC2
       
  5986 soap_strsearch(const char *big, const char *little)
       
  5987 { size_t n = strlen(little);
       
  5988   const char *s = big;
       
  5989   while (s) 
       
  5990   { if (!strncmp(s, little, n) && (s[n] == '\0' || s[n] == ' '))
       
  5991       return s;
       
  5992     s = strchr(s, ' ');
       
  5993     if (s)
       
  5994       s++;
       
  5995   }
       
  5996   return NULL;
       
  5997 }
       
  5998 #endif
       
  5999 #endif
       
  6000 
       
  6001 /******************************************************************************/
       
  6002 #ifndef WITH_LEAN
       
  6003 static struct soap_nlist *
       
  6004 soap_lookup_ns(struct soap *soap, const char *tag, size_t n)
       
  6005 { register struct soap_nlist *np;
       
  6006   for (np = soap->nlist; np; np = np->next)
       
  6007   { if (!strncmp(np->id, tag, n) && !np->id[n])
       
  6008       return np;
       
  6009   }
       
  6010   return NULL;
       
  6011 }
       
  6012 #endif
       
  6013 
       
  6014 /******************************************************************************/
       
  6015 #ifndef WITH_LEAN
       
  6016 static struct soap_nlist *
       
  6017 soap_push_ns(struct soap *soap, const char *id, const char *ns, short utilized)
       
  6018 { register struct soap_nlist *np;
       
  6019   size_t n, k;
       
  6020   if (soap_strsearch(soap->c14nexclude, id))
       
  6021     return NULL;
       
  6022   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push namespace binding (level=%u) '%s' '%s'\n", soap->level, id, ns?ns:""));
       
  6023   if (!utilized)
       
  6024   { for (np = soap->nlist; np; np = np->next)
       
  6025     { if (!strcmp(np->id, id) && (!np->ns || !strcmp(np->ns, ns)))
       
  6026         break;
       
  6027     }
       
  6028     if (np)
       
  6029     { if (np->index == 1)
       
  6030         utilized = np->index;
       
  6031       else
       
  6032         return NULL;
       
  6033     }
       
  6034   }
       
  6035   n = strlen(id);
       
  6036   if (ns)
       
  6037     k = strlen(ns);
       
  6038   else
       
  6039     k = 0;
       
  6040   np = (struct soap_nlist*)SOAP_MALLOC(soap, sizeof(struct soap_nlist) + n + k + 1);
       
  6041   if (!np)
       
  6042   { soap->error = SOAP_EOM;
       
  6043     return NULL;
       
  6044   }
       
  6045   np->next = soap->nlist;
       
  6046   soap->nlist = np;
       
  6047   strcpy(np->id, id);
       
  6048   if (ns)
       
  6049   { np->ns = np->id + n + 1;
       
  6050     strcpy(np->ns, ns);
       
  6051   }
       
  6052   else
       
  6053     np->ns = NULL;
       
  6054   np->level = soap->level;
       
  6055   np->index = utilized;
       
  6056   return np;
       
  6057 }
       
  6058 #endif
       
  6059 
       
  6060 /******************************************************************************/
       
  6061 #ifndef WITH_LEAN
       
  6062 static void
       
  6063 soap_utilize_ns(struct soap *soap, const char *tag, size_t n)
       
  6064 { register struct soap_nlist *np = soap_lookup_ns(soap, tag, n);
       
  6065   if (np)
       
  6066   { if (np->index == 0)
       
  6067       soap_push_ns(soap, np->id, np->ns, 1);
       
  6068   }
       
  6069   else
       
  6070   { strncpy(soap->tmpbuf, tag, n);
       
  6071     soap->tmpbuf[n] = '\0';
       
  6072     soap_push_ns(soap, soap->tmpbuf, NULL, 1);
       
  6073   }
       
  6074 }
       
  6075 #endif
       
  6076 
       
  6077 /******************************************************************************/
       
  6078 #ifndef WITH_LEAN
       
  6079 static void
       
  6080 soap_pop_ns(struct soap *soap)
       
  6081 { soap_pop_namespace(soap);
       
  6082 }
       
  6083 #endif
       
  6084 
       
  6085 /******************************************************************************/
       
  6086 #ifndef PALM_2
       
  6087 SOAP_FMAC1
       
  6088 int
       
  6089 SOAP_FMAC2
       
  6090 soap_element(struct soap *soap, const char *tag, int id, const char *type)
       
  6091 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element begin tag='%s' id='%d' type='%s'\n", tag, id, type?type:""));
       
  6092 #ifdef WITH_DOM
       
  6093   if (soap->mode & SOAP_XML_DOM)
       
  6094   { register struct soap_dom_element *elt = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element));
       
  6095     if (!elt)
       
  6096       return soap->error = SOAP_EOM;
       
  6097     elt->soap = soap;
       
  6098     elt->next = NULL;
       
  6099     elt->prnt = soap->dom;
       
  6100     elt->name = soap_strdup(soap, tag);
       
  6101     elt->elts = NULL;
       
  6102     elt->atts = NULL;
       
  6103     elt->nstr = NULL;
       
  6104     elt->data = NULL;
       
  6105     elt->wide = NULL;
       
  6106     elt->node = NULL;
       
  6107     elt->type = 0;
       
  6108     elt->head = NULL;
       
  6109     elt->tail = NULL;
       
  6110     if (soap->dom)
       
  6111     { struct soap_dom_element *p = soap->dom->elts;
       
  6112       if (p)
       
  6113       { while (p->next)
       
  6114           p = p->next;
       
  6115         p->next = elt;
       
  6116       }
       
  6117       else
       
  6118         soap->dom->elts = elt;
       
  6119     }
       
  6120     soap->dom = elt;
       
  6121   }
       
  6122   else
       
  6123   {
       
  6124 #endif
       
  6125     soap->level++;
       
  6126 #ifndef WITH_LEAN
       
  6127     if (!soap->ns)
       
  6128     { if (!(soap->mode & SOAP_XML_CANONICAL)
       
  6129        && soap_send(soap, soap->prolog ? soap->prolog : "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"))
       
  6130         return soap->error;
       
  6131     }
       
  6132     else if (soap->mode & SOAP_XML_INDENT)
       
  6133     { if (soap->ns == 1 && soap_send_raw(soap, soap_indent, soap->level < sizeof(soap_indent) ? soap->level : sizeof(soap_indent) - 1))
       
  6134         return soap->error;
       
  6135       soap->body = 1;
       
  6136     }
       
  6137 #endif
       
  6138     if (soap_send_raw(soap, "<", 1)
       
  6139      || soap_send(soap, tag))
       
  6140       return soap->error;
       
  6141 #ifdef WITH_DOM
       
  6142   }
       
  6143 #endif
       
  6144   if (!soap->ns)
       
  6145   { struct Namespace *ns;
       
  6146     for (ns = soap->local_namespaces; ns && ns->id; ns++)
       
  6147     { if (*ns->id && (ns->out || ns->ns))
       
  6148       { sprintf(soap->tmpbuf, "xmlns:%s", ns->id);
       
  6149         if (soap_attribute(soap, soap->tmpbuf, ns->out ? ns->out : ns->ns))
       
  6150           return soap->error;
       
  6151       }
       
  6152     }   
       
  6153   }
       
  6154   soap->ns = 1; /* start with 0 or 2, but should be one to continue */
       
  6155 #ifndef WITH_LEAN
       
  6156   if (soap->mode & SOAP_XML_CANONICAL)
       
  6157   { const char *s = strchr(tag, ':');
       
  6158     if (s)
       
  6159       soap_utilize_ns(soap, tag, s - tag);
       
  6160   }
       
  6161 #endif
       
  6162   if (id > 0)
       
  6163   { sprintf(soap->tmpbuf, "_%d", id);
       
  6164     if (soap_attribute(soap, "id", soap->tmpbuf))
       
  6165       return soap->error;
       
  6166   }
       
  6167   if (type && *type)
       
  6168   { if (soap_attribute(soap, "xsi:type", type))
       
  6169       return soap->error;
       
  6170 #ifndef WITH_LEAN
       
  6171     if (soap->mode & SOAP_XML_CANONICAL)
       
  6172     { const char *s = strchr(type, ':');
       
  6173       if (s)
       
  6174         soap_utilize_ns(soap, type, s - type);
       
  6175     }
       
  6176 #endif
       
  6177   }
       
  6178   if (soap->null && soap->position > 0)
       
  6179   { int i;
       
  6180     sprintf(soap->tmpbuf, "[%d", soap->positions[0]);
       
  6181     for (i = 1; i < soap->position; i++)
       
  6182       sprintf(soap->tmpbuf + strlen(soap->tmpbuf), ",%d", soap->positions[i]);
       
  6183     strcat(soap->tmpbuf, "]");
       
  6184     if (soap_attribute(soap, "SOAP-ENC:position", soap->tmpbuf))
       
  6185       return soap->error;
       
  6186   }
       
  6187   if (soap->mustUnderstand)
       
  6188   { if (soap->actor && *soap->actor)
       
  6189     { if (soap_attribute(soap, soap->version == 2 ? "SOAP-ENV:role" : "SOAP-ENV:actor", soap->actor))
       
  6190         return soap->error;
       
  6191     }
       
  6192     if (soap_attribute(soap, "SOAP-ENV:mustUnderstand", soap->version == 2 ? "true" : "1"))
       
  6193       return soap->error;
       
  6194     soap->mustUnderstand = 0;
       
  6195   }
       
  6196   if (soap->encoding)
       
  6197   { if (soap->encodingStyle && soap->local_namespaces)
       
  6198     { if (!*soap->encodingStyle)
       
  6199       { if (soap->local_namespaces[1].out)
       
  6200           soap->encodingStyle = soap->local_namespaces[1].out;
       
  6201         else
       
  6202           soap->encodingStyle = soap->local_namespaces[1].ns;
       
  6203       }
       
  6204       if (soap_attribute(soap, "SOAP-ENV:encodingStyle", soap->encodingStyle))
       
  6205         return soap->error;
       
  6206     }
       
  6207     soap->encoding = 0;
       
  6208   }
       
  6209   soap->null = 0;
       
  6210   soap->position = 0;
       
  6211   return SOAP_OK;
       
  6212 }
       
  6213 #endif
       
  6214 
       
  6215 /******************************************************************************/
       
  6216 #ifndef PALM_2
       
  6217 SOAP_FMAC1
       
  6218 int
       
  6219 SOAP_FMAC2
       
  6220 soap_element_begin_out(struct soap *soap, const char *tag, int id, const char *type)
       
  6221 { if (*tag == '-')
       
  6222     return SOAP_OK;
       
  6223   if (soap_element(soap, tag, id, type))
       
  6224     return soap->error;
       
  6225   return soap_element_start_end_out(soap, NULL);
       
  6226 }
       
  6227 #endif
       
  6228 
       
  6229 /******************************************************************************/
       
  6230 #ifndef PALM_2
       
  6231 #ifndef HAVE_STRRCHR
       
  6232 SOAP_FMAC1
       
  6233 char*
       
  6234 SOAP_FMAC2
       
  6235 soap_strrchr(const char *s, int t)
       
  6236 { register char *r = NULL;
       
  6237   while (*s)
       
  6238     if (*s++ == t)
       
  6239       r = (char*)s - 1;
       
  6240   return r;
       
  6241 }
       
  6242 #endif
       
  6243 #endif
       
  6244 
       
  6245 /******************************************************************************/
       
  6246 #ifndef PALM_2
       
  6247 #ifndef HAVE_STRTOL
       
  6248 SOAP_FMAC1
       
  6249 long
       
  6250 SOAP_FMAC2
       
  6251 soap_strtol(const char *s, char **t, int b)
       
  6252 { register long n = 0;
       
  6253   register int c;
       
  6254   while (*s > 0 && *s <= 32)
       
  6255     s++;
       
  6256   if (b == 10)
       
  6257   { short neg = 0;
       
  6258     if (*s == '-')
       
  6259     { s++;
       
  6260       neg = 1;
       
  6261     }
       
  6262     else if (*s == '+')
       
  6263       s++;
       
  6264     while ((c = *s) && c >= '0' && c <= '9')
       
  6265     { if (n >= 214748364 && (n > 214748364 || c >= '8'))
       
  6266         break;
       
  6267       n *= 10;
       
  6268       n += c - '0';
       
  6269       s++;
       
  6270     }
       
  6271     if (neg)
       
  6272       n = -n;
       
  6273   }
       
  6274   else /* b == 16 and value is always positive */
       
  6275   { while ((c = *s))
       
  6276     { if (c >= '0' && c <= '9')
       
  6277         c -= '0';
       
  6278       else if (c >= 'A' && c <= 'F')
       
  6279         c -= 'A' - 10;
       
  6280       else if (c >= 'a' && c <= 'f')
       
  6281         c -= 'a' - 10;
       
  6282       if (n > 0x07FFFFFF)
       
  6283         break;
       
  6284       n <<= 4;
       
  6285       n += c;
       
  6286       s++;
       
  6287     }
       
  6288   }
       
  6289   if (t)
       
  6290     *t = (char*)s;
       
  6291   return n;
       
  6292 }
       
  6293 #endif
       
  6294 #endif
       
  6295 
       
  6296 /******************************************************************************/
       
  6297 #ifndef PALM_2
       
  6298 #ifndef HAVE_STRTOUL
       
  6299 SOAP_FMAC1
       
  6300 unsigned long
       
  6301 SOAP_FMAC2
       
  6302 soap_strtoul(const char *s, char **t, int b)
       
  6303 { unsigned long n = 0;
       
  6304   register int c;
       
  6305   while (*s > 0 && *s <= 32)
       
  6306     s++;
       
  6307   if (b == 10)
       
  6308   { if (*s == '+')
       
  6309       s++;
       
  6310     while ((c = *s) && c >= '0' && c <= '9')
       
  6311     { if (n >= 429496729 && (n > 429496729 || c >= '6'))
       
  6312         break;
       
  6313       n *= 10;
       
  6314       n += c - '0';
       
  6315       s++;
       
  6316     }
       
  6317   }
       
  6318   else /* b == 16 */
       
  6319   { while ((c = *s))
       
  6320     { if (c >= '0' && c <= '9')
       
  6321         c -= '0';
       
  6322       else if (c >= 'A' && c <= 'F')
       
  6323         c -= 'A' - 10;
       
  6324       else if (c >= 'a' && c <= 'f')
       
  6325         c -= 'a' - 10;
       
  6326       if (n > 0x0FFFFFFF)
       
  6327         break;
       
  6328       n <<= 4;
       
  6329       n += c;
       
  6330       s++;
       
  6331     }
       
  6332   }
       
  6333   if (t)
       
  6334     *t = (char*)s;
       
  6335   return n;
       
  6336 }
       
  6337 #endif
       
  6338 #endif
       
  6339 
       
  6340 /******************************************************************************/
       
  6341 #ifndef PALM_1
       
  6342 SOAP_FMAC1
       
  6343 int
       
  6344 SOAP_FMAC2
       
  6345 soap_array_begin_out(struct soap *soap, const char *tag, int id, const char *type, const char *offset)
       
  6346 { if (soap_element(soap, tag, id, "SOAP-ENC:Array"))
       
  6347     return soap->error;
       
  6348   if (soap->version == 2)
       
  6349   { const char *s;
       
  6350     s = soap_strrchr(type, '[');
       
  6351     if ((size_t)(s - type) < sizeof(soap->tmpbuf))
       
  6352     { strncpy(soap->tmpbuf, type, s - type);
       
  6353       soap->tmpbuf[s - type] = '\0';
       
  6354       if (type && *type && (soap_attribute(soap, "SOAP-ENC:itemType", soap->tmpbuf)))
       
  6355         return soap->error;
       
  6356       if (s && (soap_attribute(soap, "SOAP-ENC:arraySize", s + 1)))
       
  6357         return soap->error;
       
  6358     }
       
  6359   }
       
  6360   else
       
  6361   { if (offset && (soap_attribute(soap, "SOAP-ENC:offset", offset)))
       
  6362       return soap->error;
       
  6363     if (type && *type && (soap_attribute(soap, "SOAP-ENC:arrayType", type)))
       
  6364       return soap->error;
       
  6365   }
       
  6366 #ifndef WITH_LEAN
       
  6367   if (type && *type && (soap->mode & SOAP_XML_CANONICAL))
       
  6368   { const char *s = strchr(type, ':');
       
  6369     if (s)
       
  6370       soap_utilize_ns(soap, type, s - type);
       
  6371   }
       
  6372 #endif
       
  6373   return soap_element_start_end_out(soap, NULL);
       
  6374 }
       
  6375 #endif
       
  6376 
       
  6377 /******************************************************************************/
       
  6378 #ifndef PALM_1
       
  6379 SOAP_FMAC1
       
  6380 int
       
  6381 SOAP_FMAC2
       
  6382 soap_element_start_end_out(struct soap *soap, const char *tag)
       
  6383 { register struct soap_attribute *tp;
       
  6384 #ifdef WITH_DOM
       
  6385   register struct soap_dom_attribute **att;
       
  6386   if ((soap->mode & SOAP_XML_DOM) && soap->dom)
       
  6387   { att = &soap->dom->atts;
       
  6388     for (tp = soap->attributes; tp; tp = tp->next)
       
  6389     { if (tp->visible)
       
  6390       { *att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute));
       
  6391 	if (!*att)
       
  6392 	  return soap->error = SOAP_EOM;
       
  6393 	(*att)->next = NULL;
       
  6394         (*att)->nstr = NULL;
       
  6395         (*att)->name = soap_strdup(soap, tp->name);
       
  6396         (*att)->data = soap_strdup(soap, tp->value);
       
  6397         (*att)->wide = NULL;
       
  6398         (*att)->soap = soap;
       
  6399         tp->visible = 0;
       
  6400       }
       
  6401     }
       
  6402     return SOAP_OK;
       
  6403   }
       
  6404 #endif
       
  6405 #ifndef WITH_LEAN
       
  6406   if (soap->mode & SOAP_XML_CANONICAL)
       
  6407   { struct soap_nlist *np;
       
  6408     for (tp = soap->attributes; tp; tp = tp->next)
       
  6409     { if (tp->visible && tp->name)
       
  6410       { const char *s = strchr(tp->name, ':');
       
  6411         if (s)
       
  6412           soap_utilize_ns(soap, tp->name, s - tp->name);
       
  6413       }
       
  6414     }
       
  6415     for (np = soap->nlist; np; np = np->next)
       
  6416     { if (np->index == 1 && np->ns)
       
  6417       { sprintf(soap->tmpbuf, "xmlns:%s", np->id);
       
  6418         soap_set_attr(soap, soap->tmpbuf, np->ns);
       
  6419         np->index = 2;
       
  6420       }
       
  6421     }
       
  6422   }
       
  6423 #endif
       
  6424   for (tp = soap->attributes; tp; tp = tp->next)
       
  6425   { if (tp->visible)
       
  6426     { if (soap_send(soap, " ") || soap_send(soap, tp->name))
       
  6427         return soap->error;
       
  6428       if (tp->visible == 2 && tp->value)
       
  6429         if (soap_send_raw(soap, "=\"", 2)
       
  6430 	 || soap_string_out(soap, tp->value, 1)
       
  6431 	 || soap_send_raw(soap, "\"", 1))
       
  6432           return soap->error;
       
  6433       tp->visible = 0;
       
  6434     }
       
  6435   }
       
  6436   if (tag)
       
  6437   { 
       
  6438 #ifndef WITH_LEAN
       
  6439     if (soap->mode & SOAP_XML_CANONICAL)
       
  6440     { if (soap_send_raw(soap, ">", 1)
       
  6441        || soap_element_end_out(soap, tag))
       
  6442         return soap->error;
       
  6443     }
       
  6444     else
       
  6445 #endif
       
  6446     soap->level--;	/* decrement level just before /> */
       
  6447     if (soap_send_raw(soap, "/>", 2))
       
  6448       return soap->error;
       
  6449     return SOAP_OK;
       
  6450   }
       
  6451   return soap_send_raw(soap, ">", 1);
       
  6452 }
       
  6453 #endif
       
  6454 
       
  6455 /******************************************************************************/
       
  6456 #ifndef PALM_1
       
  6457 SOAP_FMAC1
       
  6458 int
       
  6459 SOAP_FMAC2
       
  6460 soap_element_end_out(struct soap *soap, const char *tag)
       
  6461 { if (*tag == '-')
       
  6462     return SOAP_OK;
       
  6463   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element ending tag='%s'\n", tag));
       
  6464 #ifdef WITH_DOM
       
  6465   if ((soap->mode & SOAP_XML_DOM) && soap->dom)
       
  6466   { if (soap->dom->prnt)
       
  6467       soap->dom = soap->dom->prnt;
       
  6468     return SOAP_OK;
       
  6469   }
       
  6470 #endif
       
  6471 #ifndef WITH_LEAN
       
  6472   if (soap->mode & SOAP_XML_CANONICAL)
       
  6473     soap_pop_ns(soap);
       
  6474   if (soap->mode & SOAP_XML_INDENT)
       
  6475   { if (!soap->body)
       
  6476     { if (soap_send_raw(soap, soap_indent, soap->level < sizeof(soap_indent) ? soap->level : sizeof(soap_indent) - 1))
       
  6477         return soap->error;
       
  6478     }
       
  6479     soap->body = 0;
       
  6480   }
       
  6481 #endif
       
  6482   if (soap_send_raw(soap, "</", 2)
       
  6483    || soap_send(soap, tag))
       
  6484     return soap->error;
       
  6485   soap->level--;	/* decrement level just before > */
       
  6486   return soap_send_raw(soap, ">", 1);
       
  6487 }
       
  6488 #endif
       
  6489 
       
  6490 /******************************************************************************/
       
  6491 #ifndef PALM_1
       
  6492 SOAP_FMAC1
       
  6493 int
       
  6494 SOAP_FMAC2
       
  6495 soap_element_ref(struct soap *soap, const char *tag, int id, int href)
       
  6496 { register int n = 0;
       
  6497   if (soap->version == 2)
       
  6498     n = 1;
       
  6499   sprintf(soap->href, "#_%d", href);
       
  6500   return soap_element_href(soap, tag, id, "href" + n, soap->href + n);
       
  6501 }
       
  6502 #endif
       
  6503 
       
  6504 /******************************************************************************/
       
  6505 #ifndef PALM_1
       
  6506 SOAP_FMAC1
       
  6507 int
       
  6508 SOAP_FMAC2
       
  6509 soap_element_href(struct soap *soap, const char *tag, int id, const char *ref, const char *val)
       
  6510 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element '%s' reference %s='%s'\n", tag, ref, val));
       
  6511   if (soap_element(soap, tag, id, NULL)
       
  6512    || soap_attribute(soap, ref, val)
       
  6513    || soap_element_start_end_out(soap, tag))
       
  6514     return soap->error;
       
  6515   return SOAP_OK;
       
  6516 }
       
  6517 #endif
       
  6518 
       
  6519 /******************************************************************************/
       
  6520 #ifndef PALM_1
       
  6521 SOAP_FMAC1
       
  6522 int
       
  6523 SOAP_FMAC2
       
  6524 soap_element_null(struct soap *soap, const char *tag, int id, const char *type)
       
  6525 { struct soap_attribute *tp;
       
  6526   for (tp = soap->attributes; tp; tp = tp->next)
       
  6527     if (tp->visible)
       
  6528       break;
       
  6529   if (tp || (soap->version == 2 && soap->position > 0) || id > 0 || (soap->mode & SOAP_XML_NIL))
       
  6530   { if (soap_element(soap, tag, id, type))
       
  6531       return soap->error;
       
  6532     if (soap->part != SOAP_IN_HEADER && soap->encodingStyle)
       
  6533       if (soap_attribute(soap, "xsi:nil", "true"))
       
  6534         return soap->error;
       
  6535     return soap_element_start_end_out(soap, tag);
       
  6536   }
       
  6537   soap->null = 1;
       
  6538   soap->position = 0;
       
  6539   soap->mustUnderstand = 0;
       
  6540   return SOAP_OK;
       
  6541 }
       
  6542 #endif
       
  6543 
       
  6544 /******************************************************************************/
       
  6545 #ifndef PALM_1
       
  6546 SOAP_FMAC1
       
  6547 int
       
  6548 SOAP_FMAC2
       
  6549 soap_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) 
       
  6550 { if (!p || (a && !a->__ptr))
       
  6551   { soap_element_null(soap, tag, id, type);
       
  6552     return -1;
       
  6553   }
       
  6554 #ifndef WITH_NOIDREF
       
  6555   if (soap->mode & SOAP_XML_TREE)
       
  6556     return 0;
       
  6557   if (id < 0)
       
  6558   { struct soap_plist *pp;
       
  6559     if (a)
       
  6560       id = soap_array_pointer_lookup(soap, p, a, n, t, &pp);
       
  6561     else
       
  6562       id = soap_pointer_lookup(soap, p, t, &pp);
       
  6563     if (id)
       
  6564     { if (soap_is_embedded(soap, pp))
       
  6565       { soap_element_ref(soap, tag, 0, id);
       
  6566         return -1;
       
  6567       }
       
  6568       if (soap_is_single(soap, pp))
       
  6569         return 0;
       
  6570       soap_set_embedded(soap, pp);
       
  6571     }
       
  6572   }
       
  6573   return id;
       
  6574 #else
       
  6575   return 0;
       
  6576 #endif
       
  6577 }
       
  6578 #endif
       
  6579 
       
  6580 /******************************************************************************/
       
  6581 #ifndef PALM_1
       
  6582 SOAP_FMAC1
       
  6583 int
       
  6584 SOAP_FMAC2
       
  6585 soap_element_result(struct soap *soap, const char *tag)
       
  6586 { if (soap->version == 2 && soap->encodingStyle)
       
  6587     if (soap_element(soap, "SOAP-RPC:result", 0, NULL)
       
  6588      || soap_attribute(soap, "xmlns:SOAP-RPC", soap_rpc)
       
  6589      || soap_element_start_end_out(soap, NULL)
       
  6590      || soap_string_out(soap, tag, 0)
       
  6591      || soap_element_end_out(soap, "SOAP-RPC:result"))
       
  6592       return soap->error;
       
  6593   return SOAP_OK;
       
  6594 }
       
  6595 #endif
       
  6596 
       
  6597 /******************************************************************************/
       
  6598 #ifndef PALM_2
       
  6599 SOAP_FMAC1
       
  6600 int
       
  6601 SOAP_FMAC2
       
  6602 soap_attribute(struct soap *soap, const char *name, const char *value)
       
  6603 { 
       
  6604 #ifdef WITH_DOM
       
  6605   if ((soap->mode & SOAP_XML_DOM) && soap->dom)
       
  6606   { register struct soap_dom_attribute *a = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute));
       
  6607     a->next = soap->dom->atts;
       
  6608     a->nstr = NULL;
       
  6609     a->name = soap_strdup(soap, name);
       
  6610     a->data = soap_strdup(soap, value);
       
  6611     a->wide = NULL;
       
  6612     a->soap = soap;
       
  6613     soap->dom->atts = a;
       
  6614     return SOAP_OK;
       
  6615   }
       
  6616 #endif
       
  6617 #ifndef WITH_LEAN
       
  6618   if (soap->mode & SOAP_XML_CANONICAL)
       
  6619   { /* TODO: consider using this code to handle default namespace
       
  6620     if (!strncmp(name, "xmlns", 5) && (name[5] == ':' || name[5] == '\0'))
       
  6621     { if (name[5] == ':')
       
  6622         soap_push_ns(soap, name + 6, value, 0);
       
  6623       else
       
  6624         soap_push_ns(soap, "", value, 0);
       
  6625     }
       
  6626     */
       
  6627     if (!strncmp(name, "xmlns:", 6))
       
  6628       soap_push_ns(soap, name + 6, value, 0);
       
  6629     else if (soap_set_attr(soap, name, value))
       
  6630       return soap->error;
       
  6631   }
       
  6632   else
       
  6633 #endif
       
  6634   { if (soap_send(soap, " ") || soap_send(soap, name))
       
  6635       return soap->error;
       
  6636     if (value)
       
  6637       if (soap_send_raw(soap, "=\"", 2)
       
  6638        || soap_string_out(soap, value, 1)
       
  6639        || soap_send_raw(soap, "\"", 1))
       
  6640         return soap->error;
       
  6641   }
       
  6642   return SOAP_OK;
       
  6643 }
       
  6644 #endif
       
  6645 
       
  6646 /******************************************************************************/
       
  6647 #ifndef PALM_2
       
  6648 SOAP_FMAC1
       
  6649 int
       
  6650 SOAP_FMAC2
       
  6651 soap_element_begin_in(struct soap *soap, const char *tag, int nillable)
       
  6652 { if (!soap_peek_element(soap))
       
  6653   { if (soap->other)
       
  6654       return soap->error = SOAP_TAG_MISMATCH;
       
  6655     if (tag && *tag == '-')
       
  6656       return SOAP_OK;
       
  6657     if (!(soap->error = soap_match_tag(soap, soap->tag, tag)))
       
  6658     { soap->peeked = 0;
       
  6659       if (soap->body)
       
  6660         soap->level++;
       
  6661       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag?tag:"" ));
       
  6662       if (!nillable && soap->null && (soap->mode & SOAP_XML_STRICT))
       
  6663         return soap->error = SOAP_NULL;
       
  6664     }
       
  6665   }
       
  6666   else if (soap->error == SOAP_NO_TAG && tag && *tag == '-')
       
  6667     soap->error = SOAP_OK;
       
  6668   return soap->error;
       
  6669 }
       
  6670 #endif
       
  6671 
       
  6672 /******************************************************************************/
       
  6673 #ifndef PALM_2
       
  6674 SOAP_FMAC1
       
  6675 int
       
  6676 SOAP_FMAC2
       
  6677 soap_element_end_in(struct soap *soap, const char *tag)  
       
  6678 { register soap_wchar c;
       
  6679   register char *s;
       
  6680   register const char *t;
       
  6681   register int n = 0;
       
  6682   if (tag && *tag == '-')
       
  6683     return SOAP_OK;
       
  6684   soap->level--;
       
  6685   soap_pop_namespace(soap);
       
  6686 #ifdef WITH_DOM
       
  6687   /* this whitespace or mixed content is not insignificant for DOM */
       
  6688   if ((soap->mode & SOAP_XML_DOM) && soap->dom)
       
  6689   { if (!soap->peeked && !soap_string_in(soap, 3, -1, -1))
       
  6690       return soap->error;
       
  6691     if (soap->dom->prnt)
       
  6692       soap->dom = soap->dom->prnt;
       
  6693   }
       
  6694 #endif
       
  6695   if (soap->peeked)
       
  6696   { if (soap->error == SOAP_NO_TAG)
       
  6697       soap->error = SOAP_OK;
       
  6698     if (*soap->tag)
       
  6699       n++;
       
  6700     soap->peeked = 0;
       
  6701   }
       
  6702   do
       
  6703   { while (((c = soap_get(soap)) != SOAP_TT))
       
  6704     { if ((int)c == EOF)
       
  6705         return soap->error = SOAP_EOF;
       
  6706       if (c == SOAP_LT)
       
  6707         n++;
       
  6708       else if (c == '/')
       
  6709       { c = soap_get(soap);
       
  6710         if (c == SOAP_GT)
       
  6711 	  n--;
       
  6712         else
       
  6713 	  soap_unget(soap, c);
       
  6714       }
       
  6715     }
       
  6716   } while (n--);
       
  6717   s = soap->tag;
       
  6718   while (soap_notblank(c = soap_getutf8(soap)))
       
  6719     *s++ = (char)c;
       
  6720   *s = '\0';
       
  6721   if ((int)c == EOF)
       
  6722     return soap->error = SOAP_EOF;
       
  6723   while (soap_blank(c))
       
  6724     c = soap_get(soap);
       
  6725   if (c != SOAP_GT)
       
  6726     return soap->error = SOAP_SYNTAX_ERROR;
       
  6727   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag?tag:""));
       
  6728   if (!tag || !*tag)
       
  6729     return SOAP_OK;
       
  6730   if ((s = strchr(soap->tag, ':')))
       
  6731     s++;
       
  6732   else
       
  6733     s = soap->tag;
       
  6734   if ((t = strchr(tag, ':')))
       
  6735     t++;
       
  6736   else
       
  6737     t = tag;
       
  6738   if (!SOAP_STRCMP(s, t))
       
  6739     return SOAP_OK;
       
  6740   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element tag name does not match\n"));
       
  6741   return soap->error = SOAP_SYNTAX_ERROR;
       
  6742 }
       
  6743 #endif
       
  6744 
       
  6745 /******************************************************************************/
       
  6746 #ifndef PALM_2
       
  6747 SOAP_FMAC1
       
  6748 const char *
       
  6749 SOAP_FMAC2
       
  6750 soap_attr_value(struct soap *soap, const char *name, int flag)
       
  6751 { register struct soap_attribute *tp;
       
  6752   for (tp = soap->attributes; tp; tp = tp->next)
       
  6753     if (!soap_match_tag(soap, tp->name, name))
       
  6754       break;
       
  6755   if (tp && tp->visible == 2)
       
  6756   { if (flag == 2 && (soap->mode & SOAP_XML_STRICT))
       
  6757       soap->error = SOAP_PROHIBITED;
       
  6758     else
       
  6759       return tp->value;
       
  6760   }
       
  6761   else if (flag == 1 && (soap->mode & SOAP_XML_STRICT))
       
  6762     soap->error = SOAP_REQUIRED;
       
  6763   return NULL;
       
  6764 }
       
  6765 #endif
       
  6766 
       
  6767 /******************************************************************************/
       
  6768 #ifndef PALM_2
       
  6769 SOAP_FMAC1
       
  6770 int
       
  6771 SOAP_FMAC2
       
  6772 soap_set_attr(struct soap *soap, const char *name, const char *value)
       
  6773 { register struct soap_attribute *tp;
       
  6774   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set attribute %s='%s'\n", name, value?value:""));
       
  6775   for (tp = soap->attributes; tp; tp = tp->next)
       
  6776   { if (!strcmp(tp->name, name))
       
  6777       break;
       
  6778   }
       
  6779   if (!tp)
       
  6780   { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Allocate attribute %s\n", name));
       
  6781     if (!(tp = (struct soap_attribute*)SOAP_MALLOC(soap, sizeof(struct soap_attribute) + strlen(name))))
       
  6782       return soap->error = SOAP_EOM;
       
  6783     tp->ns = NULL;
       
  6784 #ifndef WITH_LEAN
       
  6785     if (soap->mode & SOAP_XML_CANONICAL)
       
  6786     { struct soap_attribute **tpp = &soap->attributes;
       
  6787       const char *s = strchr(name, ':');
       
  6788       if (!strncmp(name, "xmlns", 5))
       
  6789       { for (; *tpp; tpp = &(*tpp)->next)
       
  6790           if (strncmp((*tpp)->name, "xmlns", 5) || strcmp((*tpp)->name + 5, name + 5) > 0)
       
  6791             break;
       
  6792       }
       
  6793       else if (!s)
       
  6794       { for (; *tpp; tpp = &(*tpp)->next)
       
  6795           if (strncmp((*tpp)->name, "xmlns", 5) && ((*tpp)->ns || strcmp((*tpp)->name, name) > 0))
       
  6796             break;
       
  6797       }
       
  6798       else
       
  6799       { int k;
       
  6800         for (; *tpp; tpp = &(*tpp)->next)
       
  6801 	{ if (!strncmp((*tpp)->name, "xmlns:", 6) && !strncmp((*tpp)->name + 6, name, s - name) && !(*tpp)->name[6 + s - name])
       
  6802 	  { if (!tp->ns)
       
  6803             { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Canonicalization: prefix %s=%p(%s)\n", name, (*tpp)->ns, (*tpp)->ns));
       
  6804 	      tp->ns = (*tpp)->ns;
       
  6805 	    }
       
  6806 	  }
       
  6807           else if (strncmp((*tpp)->name, "xmlns", 5) && (*tpp)->ns && tp->ns && ((k = strcmp((*tpp)->ns, tp->ns)) > 0 || (!k && strcmp((*tpp)->name, name) > 0)))
       
  6808             break;
       
  6809         }
       
  6810       }
       
  6811       tp->next = *tpp;
       
  6812       *tpp = tp;
       
  6813     }
       
  6814     else
       
  6815 #endif
       
  6816     { tp->next = soap->attributes;
       
  6817       soap->attributes = tp;
       
  6818     }
       
  6819     strcpy(tp->name, name);
       
  6820     tp->value = NULL;
       
  6821   }
       
  6822   else if (value && tp->value && tp->size <= strlen(value))
       
  6823   { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free attribute value of %s (free %p)\n", name, tp->value));
       
  6824     SOAP_FREE(soap, tp->value);
       
  6825     tp->value = NULL;
       
  6826     tp->ns = NULL;
       
  6827   }
       
  6828   if (value)
       
  6829   { if (!tp->value)
       
  6830     { tp->size = strlen(value) + 1;
       
  6831       if (!(tp->value = (char*)SOAP_MALLOC(soap, tp->size)))
       
  6832         return soap->error = SOAP_EOM;
       
  6833       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Allocate attribute value of %s (%p)\n", tp->name, tp->value));
       
  6834     }
       
  6835     strcpy(tp->value, value);
       
  6836     if (!strncmp(tp->name, "xmlns:", 6))
       
  6837       tp->ns = tp->value;
       
  6838     tp->visible = 2;
       
  6839 #ifndef WITH_LEAN
       
  6840     if (!strcmp(name, "wsu:Id"))
       
  6841     { soap->part = SOAP_BEGIN_SECURITY;
       
  6842       strncpy(soap->id, value, sizeof(soap->id));
       
  6843       soap->id[sizeof(soap->id)-1] = '\0';
       
  6844     }
       
  6845 #endif
       
  6846   }
       
  6847   else
       
  6848     tp->visible = 1;
       
  6849   return SOAP_OK;
       
  6850 }
       
  6851 #endif
       
  6852 
       
  6853 /******************************************************************************/
       
  6854 #ifndef PALM_2
       
  6855 SOAP_FMAC1
       
  6856 void
       
  6857 SOAP_FMAC2
       
  6858 soap_clr_attr(struct soap *soap)
       
  6859 { register struct soap_attribute *tp;
       
  6860 #ifndef WITH_LEAN
       
  6861   if (soap->mode & SOAP_XML_CANONICAL)
       
  6862   { while (soap->attributes)
       
  6863     { tp = soap->attributes->next;
       
  6864       SOAP_FREE(soap, soap->attributes->value);
       
  6865       SOAP_FREE(soap, soap->attributes);
       
  6866       soap->attributes = tp;
       
  6867     }
       
  6868   }
       
  6869   else
       
  6870 #endif
       
  6871   { for (tp = soap->attributes; tp; tp = tp->next)
       
  6872       tp->visible = 0;
       
  6873   }
       
  6874 }
       
  6875 #endif
       
  6876 
       
  6877 /******************************************************************************/
       
  6878 #ifndef PALM_2
       
  6879 static int
       
  6880 soap_getattrval(struct soap *soap, char *s, size_t n, soap_wchar d)
       
  6881 { size_t i;
       
  6882   soap_wchar c;
       
  6883   for (i = 0; i < n; i++)
       
  6884   { c = soap_getutf8(soap);
       
  6885     switch (c)
       
  6886     {
       
  6887     case SOAP_TT:
       
  6888       *s++ = '<';
       
  6889       soap_unget(soap, '/');
       
  6890       break;
       
  6891     case SOAP_LT:
       
  6892       *s++ = '<';
       
  6893       break;
       
  6894     case SOAP_GT:
       
  6895       if (d == ' ')
       
  6896       { soap_unget(soap, c);
       
  6897         *s = '\0';
       
  6898         return SOAP_OK;
       
  6899       }
       
  6900       *s++ = '>';
       
  6901       break;
       
  6902     case SOAP_QT:
       
  6903       if (c == d)
       
  6904       { *s = '\0';
       
  6905         return SOAP_OK;
       
  6906       }
       
  6907       *s++ = '"';
       
  6908       break;
       
  6909     case SOAP_AP:
       
  6910       if (c == d)
       
  6911       { *s = '\0';
       
  6912         return SOAP_OK;
       
  6913       }
       
  6914       *s++ = '\'';
       
  6915       break;
       
  6916     case '\t':
       
  6917     case '\n':
       
  6918     case '\r':
       
  6919     case ' ':
       
  6920     case '/':
       
  6921       if (d == ' ')
       
  6922       { soap_unget(soap, c);
       
  6923         *s = '\0';
       
  6924         return SOAP_OK;
       
  6925       }
       
  6926     default:
       
  6927       if ((int)c == EOF)
       
  6928         return soap->error = SOAP_EOF;
       
  6929       *s++ = (char)c;
       
  6930     }
       
  6931   }
       
  6932   return soap->error = SOAP_EOM;
       
  6933 }
       
  6934 #endif
       
  6935 
       
  6936 /******************************************************************************/
       
  6937 #ifdef WITH_FAST
       
  6938 #ifndef PALM_2
       
  6939 SOAP_FMAC1
       
  6940 int
       
  6941 SOAP_FMAC2
       
  6942 soap_store_lab(struct soap *soap, const char *s, size_t n)
       
  6943 { soap->labidx = 0;
       
  6944   return soap_append_lab(soap, s, n);
       
  6945 }
       
  6946 #endif
       
  6947 #endif
       
  6948 
       
  6949 /******************************************************************************/
       
  6950 #ifdef WITH_FAST
       
  6951 #ifndef PALM_2
       
  6952 SOAP_FMAC1
       
  6953 int
       
  6954 SOAP_FMAC2
       
  6955 soap_append_lab(struct soap *soap, const char *s, size_t n)
       
  6956 { if (soap->labidx + n >= soap->lablen)
       
  6957   { register char *t = soap->labbuf;
       
  6958     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Enlarging look-aside buffer to append data, old size=%lu", (unsigned long)soap->lablen));
       
  6959     if (soap->lablen == 0)
       
  6960       soap->lablen = SOAP_LABLEN;
       
  6961     while (soap->labidx + n >= soap->lablen)
       
  6962       soap->lablen <<= 1;
       
  6963     DBGLOG(TEST, SOAP_MESSAGE(fdebug, ", new size=%lu\n", (unsigned long)soap->lablen));
       
  6964     soap->labbuf = (char*)SOAP_MALLOC(soap, soap->lablen);
       
  6965     if (!soap->labbuf)
       
  6966     { if (t)
       
  6967         SOAP_FREE(soap, t);
       
  6968       return soap->error = SOAP_EOM;
       
  6969     }
       
  6970     if (t)
       
  6971     { memcpy(soap->labbuf, t, soap->labidx);
       
  6972       SOAP_FREE(soap, t);
       
  6973     }
       
  6974   }
       
  6975   if (s)
       
  6976   { memcpy(soap->labbuf + soap->labidx, s, n);
       
  6977     soap->labidx += n;
       
  6978   }
       
  6979   return SOAP_OK;
       
  6980 }
       
  6981 #endif
       
  6982 #endif
       
  6983 
       
  6984 /******************************************************************************/
       
  6985 #ifndef PALM_2
       
  6986 SOAP_FMAC1
       
  6987 int
       
  6988 SOAP_FMAC2
       
  6989 soap_peek_element(struct soap *soap)
       
  6990 {
       
  6991 #ifdef WITH_DOM
       
  6992   register struct soap_dom_attribute **att = NULL;
       
  6993   register char *lead = NULL;
       
  6994 #endif
       
  6995   register struct soap_attribute *tp;
       
  6996   const char *t;
       
  6997   register char *s;
       
  6998   register soap_wchar c;
       
  6999   register int i;
       
  7000   if (soap->peeked)
       
  7001   { if (!*soap->tag)
       
  7002       return soap->error = SOAP_NO_TAG;
       
  7003     return SOAP_OK;
       
  7004   }
       
  7005   soap->peeked = 1;
       
  7006   for (;;)
       
  7007   { c = soap_getutf8(soap);
       
  7008     if (c == SOAP_BOM)
       
  7009       c = soap_get(soap);
       
  7010 #ifdef WITH_DOM
       
  7011     /* whitespace leading to start tag is not insignificant for DOM */
       
  7012     if (soap_blank(c))
       
  7013     { soap->labidx = 0;
       
  7014       do
       
  7015       { if (soap_append_lab(soap, NULL, 0))
       
  7016           return SOAP_EOM;
       
  7017         s = soap->labbuf + soap->labidx;
       
  7018         i = soap->lablen - soap->labidx;
       
  7019         soap->labidx = soap->lablen;
       
  7020         while (soap_blank(c) && i--)
       
  7021 	{ *s++ = c;
       
  7022 	  c = soap_get(soap);
       
  7023 	}
       
  7024       }
       
  7025       while (soap_blank(c));
       
  7026       *s = '\0';
       
  7027       lead = soap_strdup(soap, soap->labbuf);
       
  7028     }
       
  7029 #else
       
  7030     while (soap_blank(c))
       
  7031       c = soap_get(soap);
       
  7032 #endif
       
  7033     if (c != SOAP_LT)
       
  7034     { *soap->tag = '\0';
       
  7035       if ((int)c == EOF)
       
  7036         return soap->error = SOAP_EOF;
       
  7037       soap_unget(soap, c);
       
  7038 #ifdef WITH_DOM
       
  7039       /* whitespace leading to end tag is not insignificant for DOM */
       
  7040       if ((soap->mode & SOAP_XML_DOM) && soap->dom)
       
  7041         soap->dom->tail = soap_strdup(soap, lead);
       
  7042 #endif
       
  7043       return soap->error = SOAP_NO_TAG;
       
  7044     }
       
  7045     s = soap->tag;
       
  7046     do c = soap_getutf8(soap);
       
  7047     while (soap_blank(c));
       
  7048     i = sizeof(soap->tag);
       
  7049     while (c != '/' && soap_notblank(c))
       
  7050     { if (--i > 0)
       
  7051         *s++ = (char)c;
       
  7052       c = soap_getutf8(soap);
       
  7053     }
       
  7054     while (soap_blank(c))
       
  7055       c = soap_get(soap);
       
  7056     *s = '\0';
       
  7057     if (*soap->tag != '?')
       
  7058       break;
       
  7059     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "XML PI <%s?>\n", soap->tag));
       
  7060     while ((int)c != EOF && c != SOAP_GT && c != '?')
       
  7061     { s = soap->tmpbuf;
       
  7062       i = sizeof(soap->tmpbuf) - 2;
       
  7063       while (c != '=' && c != SOAP_GT && c != '?' && soap_notblank(c))
       
  7064       { if (--i > 0)
       
  7065           *s++ = (char)c;
       
  7066         c = soap_get(soap);
       
  7067       }
       
  7068       while (soap_blank(c))
       
  7069         c = soap_get(soap);
       
  7070       if (c == '=')
       
  7071       { *s++ = '=';
       
  7072 	do c = soap_get(soap);
       
  7073         while (soap_blank(c));
       
  7074         if (c != SOAP_QT && c != SOAP_AP)
       
  7075         { soap_unget(soap, c);
       
  7076           c = ' '; /* blank delimiter */
       
  7077         }
       
  7078         if (soap_getattrval(soap, s, i, c) == SOAP_EOM)
       
  7079 	{ while (soap_getattrval(soap, soap->tmpbuf, sizeof(soap->tmpbuf), c) == SOAP_EOM)
       
  7080 	    ;
       
  7081 	}
       
  7082         else if (!strcmp(soap->tag, "?xml")
       
  7083 	      && (!soap_tag_cmp(soap->tmpbuf, "encoding=iso-8859-1")
       
  7084 	       || !soap_tag_cmp(soap->tmpbuf, "encoding=latin1")))
       
  7085         { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "XML latin1 encoding\n"));
       
  7086           soap->mode |= SOAP_ENC_LATIN;
       
  7087         }
       
  7088       }
       
  7089       do c = soap_get(soap);
       
  7090       while (soap_blank(c));
       
  7091     }
       
  7092   }
       
  7093   soap->id[0] = '\0';
       
  7094   soap->href[0] = '\0';
       
  7095   soap->type[0] = '\0';
       
  7096   soap->arrayType[0] = '\0';
       
  7097   soap->arraySize[0] = '\0';
       
  7098   soap->arrayOffset[0] = '\0';
       
  7099   soap->other = 0;
       
  7100   soap->root = -1;
       
  7101   soap->position = 0;
       
  7102   soap->null = 0;
       
  7103   soap->mustUnderstand = 0;
       
  7104 #ifdef WITH_DOM
       
  7105   if (soap->mode & SOAP_XML_DOM)
       
  7106   { register struct soap_dom_element *elt;
       
  7107     elt = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element));
       
  7108     if (!elt)
       
  7109       return soap->error = SOAP_EOM;
       
  7110     elt->next = NULL;
       
  7111     elt->nstr = NULL;
       
  7112     elt->name = soap_strdup(soap, soap->tag);
       
  7113     elt->prnt = soap->dom;
       
  7114     elt->elts = NULL;
       
  7115     elt->atts = NULL;
       
  7116     elt->data = NULL;
       
  7117     elt->wide = NULL;
       
  7118     elt->type = 0;
       
  7119     elt->node = NULL;
       
  7120     elt->head = lead;
       
  7121     elt->tail = NULL;
       
  7122     elt->soap = soap;
       
  7123     if (soap->dom)
       
  7124     { struct soap_dom_element *p = soap->dom->elts;
       
  7125       if (p)
       
  7126       { while (p->next)
       
  7127           p = p->next;
       
  7128         p->next = elt;
       
  7129       }
       
  7130       else
       
  7131         soap->dom->elts = elt;
       
  7132     }
       
  7133     soap->dom = elt;
       
  7134     att = &elt->atts;
       
  7135   }
       
  7136 #endif
       
  7137   for (tp = soap->attributes; tp; tp = tp->next)
       
  7138     tp->visible = 0;
       
  7139   while ((int)c != EOF && c != SOAP_GT && c != '/')
       
  7140   { s = soap->tmpbuf;
       
  7141     i = sizeof(soap->tmpbuf);
       
  7142     while (c != '=' && c != '/' && soap_notblank(c))
       
  7143     { if (--i > 0)
       
  7144         *s++ = (char)c;
       
  7145       c = soap_get(soap);
       
  7146     }
       
  7147     *s = '\0';
       
  7148     if (i == sizeof(soap->tmpbuf))
       
  7149       return soap->error = SOAP_SYNTAX_ERROR;
       
  7150 #ifdef WITH_DOM
       
  7151     /* add attribute name to dom */
       
  7152     if (att)
       
  7153     { *att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute));
       
  7154        if (!*att)
       
  7155          return soap->error = SOAP_EOM;
       
  7156        (*att)->next = NULL;
       
  7157        (*att)->nstr = NULL;
       
  7158        (*att)->name = soap_strdup(soap, soap->tmpbuf);
       
  7159        (*att)->data = NULL;
       
  7160        (*att)->wide = NULL;
       
  7161        (*att)->soap = soap;
       
  7162     }
       
  7163 #endif
       
  7164     if (!strncmp(soap->tmpbuf, "xmlns", 5))
       
  7165     { if (soap->tmpbuf[5] == ':')
       
  7166       { soap->tmpbuf[5] = '\0';
       
  7167         t = soap->tmpbuf + 6;
       
  7168       }
       
  7169       else if (soap->tmpbuf[5])
       
  7170         t = NULL;
       
  7171       else
       
  7172         t = SOAP_STR_EOS;
       
  7173     }
       
  7174     else
       
  7175       t = NULL;
       
  7176     for (tp = soap->attributes; tp; tp = tp->next)
       
  7177     { if (!SOAP_STRCMP(tp->name, soap->tmpbuf))
       
  7178         break;
       
  7179     }
       
  7180     if (!tp)
       
  7181     { tp = (struct soap_attribute*)SOAP_MALLOC(soap, sizeof(struct soap_attribute) + strlen(soap->tmpbuf));
       
  7182       if (!tp)
       
  7183         return soap->error = SOAP_EOM;
       
  7184       strcpy(tp->name, soap->tmpbuf);
       
  7185       tp->value = NULL;
       
  7186       tp->size = 0;
       
  7187       tp->next = soap->attributes;
       
  7188       soap->attributes = tp;
       
  7189     }
       
  7190     while (soap_blank(c))
       
  7191       c = soap_get(soap);
       
  7192     if (c == '=')
       
  7193     { do c = soap_get(soap);
       
  7194       while (soap_blank(c));
       
  7195       if (c != SOAP_QT && c != SOAP_AP)
       
  7196       { soap_unget(soap, c);
       
  7197         c = ' '; /* blank delimiter */
       
  7198       }
       
  7199       if (soap_getattrval(soap, tp->value, tp->size, c))
       
  7200       {
       
  7201 #ifdef WITH_FAST
       
  7202         if (soap->error != SOAP_EOM)
       
  7203           return soap->error;
       
  7204         soap->error = SOAP_OK;
       
  7205 	if (soap_store_lab(soap, tp->value, tp->size))
       
  7206 	  return soap->error;
       
  7207 	if (tp->value)
       
  7208 	  SOAP_FREE(soap, tp->value);
       
  7209 	for (;;)
       
  7210 	{ if (soap_getattrval(soap, soap->labbuf + soap->labidx, soap->lablen - soap->labidx, c))
       
  7211 	  { if (soap->error != SOAP_EOM)
       
  7212 	      return soap->error;
       
  7213             soap->error = SOAP_OK;
       
  7214 	    soap->labidx = soap->lablen;
       
  7215 	    if (soap_append_lab(soap, NULL, 0))
       
  7216 	      return soap->error;
       
  7217 	  }
       
  7218 	  else
       
  7219 	    break;
       
  7220 	}
       
  7221 	if (soap->labidx)
       
  7222           tp->size = soap->lablen;
       
  7223 	else
       
  7224 	{ tp->size = strlen(soap->labbuf) + 1;
       
  7225           if (tp->size < SOAP_LABLEN)
       
  7226 	    tp->size = SOAP_LABLEN;
       
  7227         }
       
  7228 	if (!(tp->value = (char*)SOAP_MALLOC(soap, tp->size)))
       
  7229 	  return soap->error = SOAP_EOM;
       
  7230         strcpy(tp->value, soap->labbuf);
       
  7231 #else
       
  7232 	size_t n;
       
  7233         if (soap->error != SOAP_EOM)
       
  7234           return soap->error;
       
  7235         soap->error = SOAP_OK;
       
  7236         if (soap_new_block(soap))
       
  7237           return soap->error;
       
  7238         for (;;)
       
  7239         { if (!(s = (char*)soap_push_block(soap, SOAP_BLKLEN)))
       
  7240             return soap->error;
       
  7241           if (soap_getattrval(soap, s, SOAP_BLKLEN, c))
       
  7242           { if (soap->error != SOAP_EOM)
       
  7243               return soap->error;
       
  7244             soap->error = SOAP_OK;
       
  7245           }
       
  7246           else
       
  7247             break;
       
  7248         }
       
  7249 	n = tp->size + soap->blist->size;
       
  7250         if (!(s = (char*)SOAP_MALLOC(soap, n)))
       
  7251           return soap->error = SOAP_EOM;
       
  7252         if (tp->value)
       
  7253         { memcpy(s, tp->value, tp->size);
       
  7254           SOAP_FREE(soap, tp->value);
       
  7255         }
       
  7256         soap_save_block(soap, s + tp->size, 0);
       
  7257         tp->value = s;
       
  7258         tp->size = n;
       
  7259 #endif
       
  7260       }
       
  7261       do c = soap_get(soap);
       
  7262       while (soap_blank(c));
       
  7263       tp->visible = 2; /* seen this attribute w/ value */
       
  7264 #ifdef WITH_DOM
       
  7265       if (att)
       
  7266         (*att)->data = soap_strdup(soap, tp->value);
       
  7267 #endif
       
  7268     }
       
  7269     else
       
  7270       tp->visible = 1; /* seen this attribute w/o value */
       
  7271 #ifdef WITH_DOM
       
  7272     if (att)
       
  7273       att = &(*att)->next;
       
  7274 #endif
       
  7275     if (t && tp->value)
       
  7276     { if (soap_push_namespace(soap, t, tp->value))
       
  7277         return soap->error;
       
  7278       tp->visible = 0;
       
  7279     }
       
  7280   }
       
  7281 #ifdef WITH_DOM
       
  7282   if (att)
       
  7283   { soap->dom->nstr = soap_dom_current_nstr(soap, soap->tag);
       
  7284     for (att = &soap->dom->atts; *att; att = &(*att)->next)
       
  7285       (*att)->nstr = soap_dom_current_nstr(soap, (*att)->name);
       
  7286   }
       
  7287 #endif
       
  7288   if ((int)c == EOF)
       
  7289     return soap->error = SOAP_EOF;
       
  7290   if (!(soap->body = (c != '/')))
       
  7291     do c = soap_get(soap);
       
  7292     while (soap_blank(c));
       
  7293 #ifdef WITH_DOM
       
  7294   if (soap->mode & SOAP_XML_DOM)
       
  7295   { if (!soap->body && soap->dom->prnt)
       
  7296       soap->dom = soap->dom->prnt;
       
  7297   }
       
  7298 #endif
       
  7299   for (tp = soap->attributes; tp; tp = tp->next)
       
  7300   { if (tp->visible && tp->value)
       
  7301     { if (!strcmp(tp->name, "id"))
       
  7302       { *soap->id = '#';
       
  7303         strncpy(soap->id + 1, tp->value, sizeof(soap->id) - 2);
       
  7304         soap->id[sizeof(soap->id)-1] = '\0';
       
  7305       }
       
  7306       else if (!strcmp(tp->name, "href"))
       
  7307       { strncpy(soap->href, tp->value, sizeof(soap->href) - 1);
       
  7308         soap->href[sizeof(soap->href)-1] = '\0';
       
  7309       }
       
  7310       else if ((soap->version == 2 || (soap->mode & SOAP_XML_GRAPH)) && !strcmp(tp->name, "ref"))
       
  7311       { *soap->href = '#';
       
  7312         strncpy(soap->href + 1, tp->value, sizeof(soap->href) - 2);
       
  7313         soap->href[sizeof(soap->href)-1] = '\0';
       
  7314       }
       
  7315       else if (!soap_match_tag(soap, tp->name, "xsi:type"))
       
  7316       { strncpy(soap->type, tp->value, sizeof(soap->type) - 1);
       
  7317         soap->type[sizeof(soap->type)-1] = '\0';
       
  7318       }
       
  7319       else if (soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENC:arrayType"))
       
  7320       { s = soap_strrchr(tp->value, '[');
       
  7321         if (s && (size_t)(s - tp->value) < sizeof(soap->arrayType))
       
  7322         { strncpy(soap->arrayType, tp->value, s - tp->value);
       
  7323           soap->arrayType[s - tp->value] = '\0';
       
  7324           strncpy(soap->arraySize, s, sizeof(soap->arraySize) - 1);
       
  7325         }
       
  7326         else
       
  7327           strncpy(soap->arrayType, tp->value, sizeof(soap->arrayType) - 1);
       
  7328         soap->arraySize[sizeof(soap->arrayType)-1] = '\0';
       
  7329         soap->arrayType[sizeof(soap->arrayType)-1] = '\0';
       
  7330       }
       
  7331       else if (soap->version == 2 && !soap_match_tag(soap, tp->name, "SOAP-ENC:itemType"))
       
  7332         strncpy(soap->arrayType, tp->value, sizeof(soap->arrayType) - 1);
       
  7333       else if (soap->version == 2 && !soap_match_tag(soap, tp->name, "SOAP-ENC:arraySize"))
       
  7334         strncpy(soap->arraySize, tp->value, sizeof(soap->arraySize) - 1);
       
  7335       else if (soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENC:offset"))
       
  7336         strncpy(soap->arrayOffset, tp->value, sizeof(soap->arrayOffset));
       
  7337       else if (soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENC:position"))
       
  7338         soap->position = soap_getposition(tp->value, soap->positions);
       
  7339       else if (soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENC:root"))
       
  7340         soap->root = ((!strcmp(tp->value, "1") || !strcmp(tp->value, "true")));
       
  7341       else if ((soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENV:actor"))
       
  7342             || (soap->version == 2 && !soap_match_tag(soap, tp->name, "SOAP-ENV:role")))
       
  7343       { if ((!soap->actor || strcmp(soap->actor, tp->value))
       
  7344          && strcmp(tp->value, "http://schemas.xmlsoap.org/soap/actor/next")
       
  7345          && strcmp(tp->value, "http://www.w3.org/2003/05/soap-envelope/role/next"))
       
  7346           soap->other = 1;
       
  7347       }
       
  7348       else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:mustUnderstand")
       
  7349             && (!strcmp(tp->value, "1") || !strcmp(tp->value, "true")))
       
  7350         soap->mustUnderstand = 1;
       
  7351       else if ((!soap_match_tag(soap, tp->name, "xsi:null")
       
  7352              || !soap_match_tag(soap, tp->name, "xsi:nil"))
       
  7353             && (!strcmp(tp->value, "1")
       
  7354              || !strcmp(tp->value, "true")))
       
  7355         soap->null = 1;
       
  7356     }
       
  7357   }
       
  7358   return soap->error = SOAP_OK;
       
  7359 }
       
  7360 #endif
       
  7361 
       
  7362 /******************************************************************************/
       
  7363 #ifndef PALM_2
       
  7364 SOAP_FMAC1
       
  7365 void
       
  7366 SOAP_FMAC2
       
  7367 soap_retry(struct soap *soap)
       
  7368 { soap->error = SOAP_OK;
       
  7369   soap_revert(soap);
       
  7370 }
       
  7371 #endif
       
  7372 
       
  7373 /******************************************************************************/
       
  7374 #ifndef PALM_2
       
  7375 SOAP_FMAC1
       
  7376 void
       
  7377 SOAP_FMAC2
       
  7378 soap_revert(struct soap *soap)
       
  7379 { if (!soap->peeked)
       
  7380   { soap->peeked = 1;
       
  7381     if (soap->body)
       
  7382       soap->level--;
       
  7383   }
       
  7384   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Reverting last element (level=%u)\n", soap->level));
       
  7385 }
       
  7386 #endif
       
  7387 
       
  7388 /******************************************************************************/
       
  7389 #ifndef PALM_2
       
  7390 SOAP_FMAC1
       
  7391 int
       
  7392 SOAP_FMAC2
       
  7393 soap_string_out(struct soap *soap, const char *s, int flag)
       
  7394 { register const char *t;
       
  7395   register soap_wchar c;
       
  7396   register soap_wchar mask = 0xFFFFFF80UL;
       
  7397 #ifdef WITH_DOM
       
  7398   if ((soap->mode & SOAP_XML_DOM) && soap->dom)
       
  7399   { soap->dom->data = soap_strdup(soap, s);
       
  7400     return SOAP_OK;
       
  7401   }
       
  7402 #endif
       
  7403   if (soap->mode & SOAP_C_UTFSTRING)
       
  7404     mask = 0;
       
  7405   t = s;
       
  7406   while ((c = *t++))
       
  7407   { switch (c)
       
  7408     { 
       
  7409     case 9:
       
  7410       if (flag)
       
  7411       { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&#x9;", 5))
       
  7412 	  return soap->error;
       
  7413         s = t;
       
  7414       }
       
  7415       break;
       
  7416     case 10:
       
  7417       if (flag || !(soap->mode & SOAP_XML_CANONICAL))
       
  7418       { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&#xA;", 5))
       
  7419 	  return soap->error;
       
  7420         s = t;
       
  7421       }
       
  7422       break;
       
  7423     case 13:
       
  7424       if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&#xD;", 5))
       
  7425         return soap->error;
       
  7426       s = t;
       
  7427       break;
       
  7428     case '&':
       
  7429       if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&amp;", 5))
       
  7430         return soap->error;
       
  7431       s = t;
       
  7432       break;
       
  7433     case '<':
       
  7434       if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&lt;", 4))
       
  7435         return soap->error;
       
  7436       s = t;
       
  7437       break;
       
  7438     case '>':
       
  7439       if (!flag)
       
  7440       { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&gt;", 4))
       
  7441 	  return soap->error;
       
  7442         s = t;
       
  7443       }
       
  7444       break;
       
  7445     case '"':
       
  7446       if (flag)
       
  7447       { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&quot;", 6))
       
  7448 	  return soap->error;
       
  7449         s = t;
       
  7450       }
       
  7451       break;
       
  7452     default:
       
  7453 #ifndef WITH_LEANER
       
  7454 #ifdef HAVE_MBTOWC
       
  7455       if (soap->mode & SOAP_C_MBSTRING)
       
  7456       { wchar_t wc;
       
  7457         register int m = mbtowc(&wc, t - 1, MB_CUR_MAX);
       
  7458         if (m > 0 && wc != c)
       
  7459         { if (soap_send_raw(soap, s, t - s - 1) || soap_pututf8(soap, wc))
       
  7460             return soap->error;
       
  7461 	  s = t += m - 1;
       
  7462 	  continue;
       
  7463         }
       
  7464       }
       
  7465 #endif
       
  7466 #endif
       
  7467       if (c & mask)
       
  7468       { if (soap_send_raw(soap, s, t - s - 1) || soap_pututf8(soap, (unsigned char)c))
       
  7469           return soap->error;
       
  7470         s = t;
       
  7471       }
       
  7472     }
       
  7473   }
       
  7474   return soap_send_raw(soap, s, t - s - 1);
       
  7475 }
       
  7476 #endif
       
  7477 
       
  7478 /******************************************************************************/
       
  7479 #ifndef PALM_2
       
  7480 SOAP_FMAC1
       
  7481 char *
       
  7482 SOAP_FMAC2
       
  7483 soap_string_in(struct soap *soap, int flag, long minlen, long maxlen)
       
  7484 { register char *s;
       
  7485   char *t = NULL;
       
  7486   register size_t i;
       
  7487   register long l = 0;
       
  7488   register int n = 0;
       
  7489   register int m = 0;
       
  7490   register soap_wchar c;
       
  7491 #if !defined(WITH_LEANER) && defined(HAVE_WCTOMB)
       
  7492   char buf[MB_LEN_MAX > 8 ? MB_LEN_MAX : 8];
       
  7493 #else
       
  7494   char buf[8];
       
  7495 #endif
       
  7496   DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Reading string content\n"));
       
  7497   if (soap->peeked)
       
  7498   { if (!soap->body)
       
  7499       return NULL;
       
  7500     if (*soap->tag)
       
  7501     { n = 1;
       
  7502       soap->peeked = 0;
       
  7503 #ifndef WITH_LEAN
       
  7504       t = soap->tmpbuf;
       
  7505       t[0] = '<';
       
  7506       strncpy(t + 1, soap->tag, sizeof(soap->tmpbuf) - 1);
       
  7507       strncat(t, ">", sizeof(soap->tmpbuf));
       
  7508       m = strlen(soap->tag) + 2;
       
  7509 #endif
       
  7510     }
       
  7511   }
       
  7512 #ifdef WITH_CDATA
       
  7513   if (!flag)
       
  7514   { register int state = 0;
       
  7515 #ifdef WITH_FAST
       
  7516     soap->labidx = 0;			/* use look-aside buffer */
       
  7517 #else
       
  7518     if (soap_new_block(soap))
       
  7519       return NULL;
       
  7520 #endif
       
  7521     for (;;)
       
  7522     { 
       
  7523 #ifdef WITH_FAST
       
  7524       register size_t k;
       
  7525       if (soap_append_lab(soap, NULL, 0))	/* allocate more space in look-aside buffer if necessary */
       
  7526         return NULL;
       
  7527       s = soap->labbuf + soap->labidx;	/* space to populate */
       
  7528       k = soap->lablen - soap->labidx;	/* number of bytes available */
       
  7529       soap->labidx = soap->lablen;	/* claim this space */
       
  7530 #else
       
  7531       register size_t k = SOAP_BLKLEN;
       
  7532       if (!(s = (char*)soap_push_block(soap, k)))
       
  7533         return NULL;
       
  7534 #endif
       
  7535       for (i = 0; i < k; i++)
       
  7536       { if (m > 0)
       
  7537         { *s++ = *t++;	/* copy multibyte characters */
       
  7538 	  m--;
       
  7539           continue;
       
  7540         }
       
  7541         c = soap_getchar(soap);
       
  7542 	if ((int)c == EOF)
       
  7543           goto end;
       
  7544         if (c >= 0x80 && !(soap->mode & SOAP_ENC_LATIN))
       
  7545         { soap_unget(soap, c);
       
  7546 	  c = soap_getutf8(soap);
       
  7547 	  if (soap->mode & SOAP_C_UTFSTRING)
       
  7548           { if ((c & 0x80000000) && c >= -0x7FFFFF80 && c < SOAP_AP)
       
  7549             { c &= 0x7FFFFFFF;
       
  7550               t = buf;
       
  7551               if (c < 0x0800)
       
  7552                 *t++ = (char)(0xC0 | ((c >> 6) & 0x1F));
       
  7553               else
       
  7554               { if (c < 0x010000)
       
  7555                   *t++ = (char)(0xE0 | ((c >> 12) & 0x0F));
       
  7556                 else
       
  7557                 { if (c < 0x200000)
       
  7558                     *t++ = (char)(0xF0 | ((c >> 18) & 0x07));
       
  7559                   else
       
  7560                   { if (c < 0x04000000)
       
  7561                       *t++ = (char)(0xF8 | ((c >> 24) & 0x03));
       
  7562                     else
       
  7563                     { *t++ = (char)(0xFC | ((c >> 30) & 0x01));
       
  7564                       *t++ = (char)(0x80 | ((c >> 24) & 0x3F));
       
  7565                     }
       
  7566                     *t++ = (char)(0x80 | ((c >> 18) & 0x3F));
       
  7567                   }     
       
  7568                   *t++ = (char)(0x80 | ((c >> 12) & 0x3F));
       
  7569                 }
       
  7570                 *t++ = (char)(0x80 | ((c >> 6) & 0x3F));
       
  7571               }
       
  7572               *t++ = (char)(0x80 | (c & 0x3F));
       
  7573 	      m = (int)(t - buf) - 1;
       
  7574               t = buf;
       
  7575               *s++ = *t++;
       
  7576               continue;
       
  7577 	    }
       
  7578           }
       
  7579         }
       
  7580 	switch (state)
       
  7581         { case 1:
       
  7582             if (c == ']')
       
  7583 	      state = 4;
       
  7584 	    *s++ = c;
       
  7585 	    continue;
       
  7586 	  case 2:
       
  7587 	    if (c == '-')
       
  7588               state = 6;
       
  7589 	    *s++ = c;
       
  7590 	    continue;
       
  7591 	  case 3:
       
  7592 	    if (c == '?')
       
  7593 	      state = 8;
       
  7594 	    *s++ = c;
       
  7595 	    continue;
       
  7596           /* CDATA */
       
  7597 	  case 4:
       
  7598 	    if (c == ']')
       
  7599               state = 5;
       
  7600 	    else
       
  7601 	      state = 1;
       
  7602 	    *s++ = c;
       
  7603 	    continue;
       
  7604 	  case 5:
       
  7605 	    if (c == '>')
       
  7606 	      state = 0;
       
  7607 	    else
       
  7608 	      state = 1;
       
  7609 	    *s++ = c;
       
  7610 	    continue;
       
  7611           /* comment */
       
  7612           case 6:
       
  7613             if (c == '-')
       
  7614 	      state = 7;
       
  7615 	    else
       
  7616 	      state = 2;
       
  7617 	    *s++ = c;
       
  7618 	    continue;
       
  7619           case 7:
       
  7620             if (c == '>')
       
  7621 	      state = 0;
       
  7622 	    else
       
  7623 	      state = 2;
       
  7624 	    *s++ = c;
       
  7625 	    continue;
       
  7626           /* PI */
       
  7627 	  case 8:
       
  7628             if (c == '>')
       
  7629 	      state = 0;
       
  7630 	    else
       
  7631 	      state = 3;
       
  7632 	    *s++ = c;
       
  7633 	    continue;
       
  7634         }
       
  7635         switch (c)
       
  7636         {
       
  7637         case '/':
       
  7638           if (n > 0)
       
  7639           { c = soap_getchar(soap);
       
  7640             if (c == '>')
       
  7641               n--;
       
  7642             soap_unget(soap, c);
       
  7643           }
       
  7644           *s++ = '/';
       
  7645           break;
       
  7646         case '<':
       
  7647 	  c = soap_getchar(soap);
       
  7648 	  if (c == '/')
       
  7649 	  { if (n == 0)
       
  7650 	    { c = SOAP_TT;
       
  7651 	      goto end;
       
  7652 	    }
       
  7653 	    n--;
       
  7654 	  }
       
  7655 	  else if (c == '!')
       
  7656 	  { c = soap_getchar(soap);
       
  7657 	    if (c == '[')
       
  7658             { do c = soap_getchar(soap);
       
  7659               while ((int)c != EOF && c != '[');
       
  7660               if ((int)c == EOF)
       
  7661                  goto end;
       
  7662 	      t = (char*)"![CDATA[";
       
  7663 	      m = 8;
       
  7664 	      state = 1;
       
  7665 	    }
       
  7666             else if (c == '-')
       
  7667 	    { if ((c = soap_getchar(soap)) == '-')
       
  7668 	        state = 2;
       
  7669 	      t = (char*)"!-";
       
  7670 	      m = 2;
       
  7671 	      soap_unget(soap, c);
       
  7672 	    }
       
  7673 	    else
       
  7674 	    { t = (char*)"!";
       
  7675 	      m = 1;
       
  7676 	      soap_unget(soap, c);
       
  7677 	    }
       
  7678 	    *s++ = '<';
       
  7679 	    break;
       
  7680 	  }
       
  7681 	  else if (c == '?')
       
  7682 	    state = 3;
       
  7683 	  else
       
  7684 	    n++;
       
  7685           soap_unget(soap, c);
       
  7686           *s++ = '<';
       
  7687           break;
       
  7688         case '>':
       
  7689           *s++ = '>';
       
  7690           break;
       
  7691         case '"':
       
  7692           *s++ = '"';
       
  7693           break;
       
  7694         default:
       
  7695 #ifndef WITH_LEANER
       
  7696 #ifdef HAVE_WCTOMB
       
  7697           if (soap->mode & SOAP_C_MBSTRING)
       
  7698           { m = wctomb(buf, c & 0x7FFFFFFF);
       
  7699             if (m >= 1 && m <= (int)MB_CUR_MAX)
       
  7700             { t = buf;
       
  7701               *s++ = *t++;
       
  7702               m--;
       
  7703             }
       
  7704             else
       
  7705             { *s++ = SOAP_UNKNOWN_CHAR;
       
  7706 	      m = 0;
       
  7707 	    }
       
  7708           }
       
  7709           else
       
  7710 #endif
       
  7711 #endif
       
  7712             *s++ = (char)(c & 0xFF);
       
  7713         }
       
  7714 	l++;
       
  7715         if ((soap->mode & SOAP_XML_STRICT) && maxlen >= 0 && l > maxlen)
       
  7716         { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen));
       
  7717           soap->error = SOAP_LENGTH;
       
  7718           return NULL;
       
  7719         }
       
  7720       }
       
  7721     }
       
  7722   }
       
  7723 #endif
       
  7724 #ifdef WITH_FAST
       
  7725   soap->labidx = 0;			/* use look-aside buffer */
       
  7726 #else
       
  7727   if (soap_new_block(soap))
       
  7728     return NULL;
       
  7729 #endif
       
  7730   for (;;)
       
  7731   { 
       
  7732 #ifdef WITH_FAST
       
  7733     register size_t k;
       
  7734     if (soap_append_lab(soap, NULL, 0))	/* allocate more space in look-aside buffer if necessary */
       
  7735       return NULL;
       
  7736     s = soap->labbuf + soap->labidx;	/* space to populate */
       
  7737     k = soap->lablen - soap->labidx;	/* number of bytes available */
       
  7738     soap->labidx = soap->lablen;	/* claim this space */
       
  7739 #else
       
  7740     register size_t k = SOAP_BLKLEN;
       
  7741     if (!(s = (char*)soap_push_block(soap, k)))
       
  7742       return NULL;
       
  7743 #endif
       
  7744     for (i = 0; i < k; i++)
       
  7745     { if (m > 0)
       
  7746       { *s++ = *t++;	/* copy multibyte characters */
       
  7747         m--;
       
  7748         continue;
       
  7749       }
       
  7750       if (soap->mode & SOAP_C_UTFSTRING)
       
  7751       { if (((c = soap_get(soap)) & 0x80000000) && c >= -0x7FFFFF80 && c < SOAP_AP)
       
  7752         { c &= 0x7FFFFFFF;
       
  7753           t = buf;
       
  7754           if (c < 0x0800)
       
  7755             *t++ = (char)(0xC0 | ((c >> 6) & 0x1F));
       
  7756           else
       
  7757           { if (c < 0x010000)
       
  7758               *t++ = (char)(0xE0 | ((c >> 12) & 0x0F));
       
  7759             else
       
  7760             { if (c < 0x200000)
       
  7761                 *t++ = (char)(0xF0 | ((c >> 18) & 0x07));
       
  7762               else
       
  7763               { if (c < 0x04000000)
       
  7764                   *t++ = (char)(0xF8 | ((c >> 24) & 0x03));
       
  7765                 else
       
  7766                 { *t++ = (char)(0xFC | ((c >> 30) & 0x01));
       
  7767                   *t++ = (char)(0x80 | ((c >> 24) & 0x3F));
       
  7768                 }
       
  7769                 *t++ = (char)(0x80 | ((c >> 18) & 0x3F));
       
  7770               }     
       
  7771               *t++ = (char)(0x80 | ((c >> 12) & 0x3F));
       
  7772             }
       
  7773             *t++ = (char)(0x80 | ((c >> 6) & 0x3F));
       
  7774           }
       
  7775           *t++ = (char)(0x80 | (c & 0x3F));
       
  7776 	  m = (int)(t - buf) - 1;
       
  7777           t = buf;
       
  7778           *s++ = *t++;
       
  7779           continue;
       
  7780         }
       
  7781       }
       
  7782       else
       
  7783         c = soap_getutf8(soap);
       
  7784       switch (c)
       
  7785       {
       
  7786       case SOAP_TT:
       
  7787         if (n == 0)
       
  7788           goto end;
       
  7789         n--;
       
  7790         *s++ = '<';
       
  7791         t = (char*)"/";
       
  7792 	m = 1;
       
  7793         break;
       
  7794       case SOAP_LT:
       
  7795         n++;
       
  7796         *s++ = '<';
       
  7797         break;
       
  7798       case SOAP_GT:
       
  7799         *s++ = '>';
       
  7800         break;
       
  7801       case SOAP_QT:
       
  7802         *s++ = '"';
       
  7803         break;
       
  7804       case SOAP_AP:
       
  7805         *s++ = '\'';
       
  7806         break;
       
  7807       case '/':
       
  7808         if (n > 0)
       
  7809         { c = soap_get(soap);
       
  7810           if (c == SOAP_GT)
       
  7811             n--;
       
  7812           soap_unget(soap, c);
       
  7813         }
       
  7814         *s++ = '/';
       
  7815         break;
       
  7816       case '<' | 0x80000000:
       
  7817         if (flag)
       
  7818           *s++ = '<';
       
  7819         else
       
  7820         { *s++ = '&';
       
  7821           t = (char*)"lt;";
       
  7822 	  m = 3;
       
  7823         }
       
  7824         break;
       
  7825       case '>' | 0x80000000:
       
  7826         if (flag)
       
  7827           *s++ = '>';
       
  7828         else
       
  7829         { *s++ = '&';
       
  7830           t = (char*)"gt;";
       
  7831 	  m = 3;
       
  7832         }
       
  7833         break;
       
  7834       case '&' | 0x80000000:
       
  7835         if (flag)
       
  7836           *s++ = '&';
       
  7837         else
       
  7838         { *s++ = '&';
       
  7839           t = (char*)"amp;";
       
  7840 	  m = 4;
       
  7841         }
       
  7842         break;
       
  7843       case '"' | 0x80000000:
       
  7844         if (flag)
       
  7845           *s++ = '"';
       
  7846         else
       
  7847         { *s++ = '&';
       
  7848           t = (char*)"quot;";
       
  7849 	  m = 5;
       
  7850         }
       
  7851         break;
       
  7852       case '\'' | 0x80000000:
       
  7853         if (flag)
       
  7854           *s++ = '\'';
       
  7855         else
       
  7856         { *s++ = '&';
       
  7857           t = (char*)"apos;";
       
  7858 	  m = 5;
       
  7859         }
       
  7860         break;
       
  7861       default:
       
  7862         if ((int)c == EOF)
       
  7863           goto end;
       
  7864 #ifndef WITH_LEANER
       
  7865 #ifdef HAVE_WCTOMB
       
  7866         if (soap->mode & SOAP_C_MBSTRING)
       
  7867         { m = wctomb(buf, c & 0x7FFFFFFF);
       
  7868           if (m >= 1 && m <= (int)MB_CUR_MAX)
       
  7869           { t = buf;
       
  7870             *s++ = *t++;
       
  7871             m--;
       
  7872           }
       
  7873           else
       
  7874           { *s++ = SOAP_UNKNOWN_CHAR;
       
  7875 	    m = 0;
       
  7876 	  }
       
  7877         }
       
  7878         else
       
  7879 #endif
       
  7880 #endif
       
  7881           *s++ = (char)(c & 0xFF);
       
  7882       }
       
  7883       l++;
       
  7884       if ((soap->mode & SOAP_XML_STRICT) && maxlen >= 0 && l > maxlen)
       
  7885       { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen));
       
  7886         soap->error = SOAP_LENGTH;
       
  7887         return NULL;
       
  7888       }
       
  7889     }
       
  7890   }
       
  7891 end:
       
  7892   soap_unget(soap, c);
       
  7893   *s = '\0';
       
  7894 #ifdef WITH_FAST
       
  7895   t = soap_strdup(soap, soap->labbuf);
       
  7896 #else
       
  7897   soap_size_block(soap, i+1);
       
  7898   t = soap_save_block(soap, NULL, 0);
       
  7899 #endif
       
  7900   if ((soap->mode & SOAP_XML_STRICT) && l < minlen)
       
  7901   { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too short: %ld chars, minlen=%ld\n", l, minlen));
       
  7902     soap->error = SOAP_LENGTH;
       
  7903     return NULL;
       
  7904   }
       
  7905 #ifdef WITH_DOM
       
  7906   if ((soap->mode & SOAP_XML_DOM) && soap->dom)
       
  7907   { if (flag == 3)
       
  7908       soap->dom->tail = t;
       
  7909     else
       
  7910       soap->dom->data = t;
       
  7911   }
       
  7912 #endif
       
  7913   if (flag == 2)
       
  7914     if (soap_s2QName(soap, t, &t))
       
  7915       return NULL;
       
  7916   return t;
       
  7917 }
       
  7918 #endif
       
  7919 
       
  7920 /******************************************************************************/
       
  7921 #ifndef WITH_LEANER
       
  7922 #ifndef PALM_2
       
  7923 SOAP_FMAC1
       
  7924 int
       
  7925 SOAP_FMAC2
       
  7926 soap_wstring_out(struct soap *soap, const wchar_t *s, int flag)
       
  7927 { const char *t;
       
  7928   char tmp;
       
  7929   register soap_wchar c;
       
  7930 #ifdef WITH_DOM
       
  7931   if ((soap->mode & SOAP_XML_DOM) && soap->dom)
       
  7932   { wchar_t *r = (wchar_t*)s;
       
  7933     int n = 1;
       
  7934     while (*r++)
       
  7935       n++;
       
  7936     soap->dom->wide = r = (wchar_t*)soap_malloc(soap, n * sizeof(wchar_t));
       
  7937     while (n--)
       
  7938       *r++ = *s++;
       
  7939     return SOAP_OK;
       
  7940   }
       
  7941 #endif
       
  7942   while ((c = *s++))
       
  7943   { switch (c)
       
  7944     { 
       
  7945     case 9:
       
  7946       if (flag)
       
  7947         t = "&#x9;";
       
  7948       else
       
  7949         t = "\t";
       
  7950       break;
       
  7951     case 10:
       
  7952       if (flag || !(soap->mode & SOAP_XML_CANONICAL))
       
  7953         t = "&#xA;";
       
  7954       else
       
  7955         t = "\n";
       
  7956       break;
       
  7957     case 13:
       
  7958       t = "&#xD;";
       
  7959       break;
       
  7960     case '&':
       
  7961       t = "&amp;";
       
  7962       break;
       
  7963     case '<':
       
  7964       t = "&lt;";
       
  7965       break;
       
  7966     case '>':
       
  7967       if (flag)
       
  7968         t = ">";
       
  7969       else
       
  7970 	t = "&gt;";
       
  7971       break;
       
  7972     case '"':
       
  7973       if (flag)
       
  7974         t = "&quot;";
       
  7975       else
       
  7976         t = "\"";
       
  7977       break;
       
  7978     default:
       
  7979       if (c > 0 && c < 0x80)
       
  7980       { tmp = (char)c;
       
  7981         if (soap_send_raw(soap, &tmp, 1))
       
  7982           return soap->error;
       
  7983       }
       
  7984       else if (soap_pututf8(soap, (unsigned long)c))
       
  7985         return soap->error;
       
  7986       continue;
       
  7987     }
       
  7988     if (soap_send(soap, t))
       
  7989       return soap->error;
       
  7990   }
       
  7991   return SOAP_OK;
       
  7992 }
       
  7993 #endif
       
  7994 #endif
       
  7995 
       
  7996 /******************************************************************************/
       
  7997 #ifndef WITH_LEANER
       
  7998 #ifndef PALM_2
       
  7999 SOAP_FMAC1
       
  8000 wchar_t *
       
  8001 SOAP_FMAC2
       
  8002 soap_wstring_in(struct soap *soap, int flag, long minlen, long maxlen)
       
  8003 { wchar_t *s;
       
  8004   register int i, n = 0;
       
  8005   register long l = 0;
       
  8006   register soap_wchar c;
       
  8007   const char *t = NULL;
       
  8008   DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Reading wide string content\n"));
       
  8009   if (soap->peeked)
       
  8010   { if (!soap->body)
       
  8011       return NULL;
       
  8012     if (*soap->tag)
       
  8013     { n = 1;
       
  8014       soap->peeked = 0;
       
  8015     }
       
  8016   }
       
  8017   if (soap_new_block(soap))
       
  8018     return NULL;
       
  8019   for (;;)
       
  8020   { if (!(s = (wchar_t*)soap_push_block(soap, sizeof(wchar_t)*SOAP_BLKLEN)))
       
  8021       return NULL;
       
  8022     for (i = 0; i < SOAP_BLKLEN; i++)
       
  8023     { if (t)
       
  8024       { *s++ = (wchar_t)*t++;
       
  8025         if (!*t)
       
  8026           t = NULL;
       
  8027         continue;
       
  8028       }
       
  8029       c = soap_getutf8(soap);
       
  8030       switch (c)
       
  8031       {
       
  8032       case SOAP_TT:
       
  8033         if (n == 0)
       
  8034           goto end;
       
  8035         n--;
       
  8036         *s++ = '<';
       
  8037         soap_unget(soap, '/');
       
  8038         break;
       
  8039       case SOAP_LT:
       
  8040         n++;
       
  8041         *s++ = '<';
       
  8042         break;
       
  8043       case SOAP_GT:
       
  8044         *s++ = '>';
       
  8045         break;
       
  8046       case SOAP_QT:
       
  8047         *s++ = '"';
       
  8048         break;
       
  8049       case SOAP_AP:
       
  8050         *s++ = '\'';
       
  8051         break;
       
  8052       case '/':
       
  8053         if (n > 0)
       
  8054         { c = soap_getutf8(soap);
       
  8055           if (c == SOAP_GT)
       
  8056             n--;
       
  8057           soap_unget(soap, c);
       
  8058         }
       
  8059         *s++ = '/';
       
  8060         break;
       
  8061       case '<':
       
  8062         if (flag)
       
  8063           *s++ = (soap_wchar)'<';
       
  8064         else
       
  8065         { *s++ = (soap_wchar)'&';
       
  8066           t = "lt;";
       
  8067         }
       
  8068         break;
       
  8069       case '>':
       
  8070         if (flag)
       
  8071           *s++ = (soap_wchar)'>';
       
  8072         else
       
  8073         { *s++ = (soap_wchar)'&';
       
  8074           t = "gt;";
       
  8075         }
       
  8076         break;
       
  8077       case '"':
       
  8078         if (flag)
       
  8079           *s++ = (soap_wchar)'"';
       
  8080         else
       
  8081         { *s++ = (soap_wchar)'&';
       
  8082           t = "quot;";
       
  8083         }
       
  8084         break;
       
  8085       default:
       
  8086         if ((int)c == EOF)
       
  8087           goto end;
       
  8088         *s++ = (wchar_t)c & 0x7FFFFFFF;
       
  8089       }
       
  8090       l++;
       
  8091       if ((soap->mode & SOAP_XML_STRICT) && maxlen >= 0 && l > maxlen)
       
  8092       { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen));
       
  8093         soap->error = SOAP_LENGTH;
       
  8094         return NULL;
       
  8095       }
       
  8096     }
       
  8097   }
       
  8098 end:
       
  8099   soap_unget(soap, c);
       
  8100   *s = '\0';
       
  8101   soap_size_block(soap, sizeof(wchar_t) * (i + 1));
       
  8102   if ((soap->mode & SOAP_XML_STRICT) && l < minlen)
       
  8103   { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too short: %ld chars, minlen=%ld\n", l, minlen));
       
  8104     soap->error = SOAP_LENGTH;
       
  8105     return NULL;
       
  8106   }
       
  8107   s = (wchar_t*)soap_save_block(soap, NULL, 0);
       
  8108 #ifdef WITH_DOM
       
  8109   if ((soap->mode & SOAP_XML_DOM) && soap->dom)
       
  8110     soap->dom->wide = s;
       
  8111 #endif
       
  8112   return s;
       
  8113 }
       
  8114 #endif
       
  8115 #endif
       
  8116 
       
  8117 /******************************************************************************/
       
  8118 #ifndef PALM_2
       
  8119 SOAP_FMAC1
       
  8120 const char*
       
  8121 SOAP_FMAC2
       
  8122 soap_int2s(struct soap *soap, int n)
       
  8123 { return soap_long2s(soap, (long)n);
       
  8124 }
       
  8125 #endif
       
  8126 
       
  8127 /******************************************************************************/
       
  8128 #ifndef PALM_2
       
  8129 SOAP_FMAC1
       
  8130 int
       
  8131 SOAP_FMAC2
       
  8132 soap_outint(struct soap *soap, const char *tag, int id, const int *p, const char *type, int n)
       
  8133 { if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
       
  8134    || soap_string_out(soap, soap_long2s(soap, (long)*p), 0))
       
  8135     return soap->error;
       
  8136   return soap_element_end_out(soap, tag);
       
  8137 }
       
  8138 #endif
       
  8139 
       
  8140 /******************************************************************************/
       
  8141 #ifndef PALM_2
       
  8142 SOAP_FMAC1
       
  8143 int
       
  8144 SOAP_FMAC2
       
  8145 soap_s2int(struct soap *soap, const char *s, int *p)
       
  8146 { if (s)
       
  8147   { char *r;
       
  8148     *p = (int)soap_strtol(s, &r, 10);
       
  8149     if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
       
  8150 #ifndef WITH_NOIO
       
  8151 #ifndef WITH_LEAN
       
  8152      || soap_errno == SOAP_ERANGE
       
  8153 #endif
       
  8154 #endif
       
  8155     )
       
  8156       soap->error = SOAP_TYPE;
       
  8157   }
       
  8158   return soap->error;
       
  8159 }
       
  8160 #endif
       
  8161 
       
  8162 /******************************************************************************/
       
  8163 #ifndef PALM_2
       
  8164 SOAP_FMAC1
       
  8165 int *
       
  8166 SOAP_FMAC2
       
  8167 soap_inint(struct soap *soap, const char *tag, int *p, const char *type, int t)
       
  8168 { if (soap_element_begin_in(soap, tag, 0))
       
  8169     return NULL;
       
  8170 #ifndef WITH_LEAN
       
  8171   if (*soap->type
       
  8172    && soap_match_tag(soap, soap->type, type)
       
  8173    && soap_match_tag(soap, soap->type, ":int")
       
  8174    && soap_match_tag(soap, soap->type, ":short")
       
  8175    && soap_match_tag(soap, soap->type, ":byte"))
       
  8176   { soap->error = SOAP_TYPE;
       
  8177     soap_revert(soap);
       
  8178     return NULL;
       
  8179   }
       
  8180 #endif
       
  8181   p = (int*)soap_id_enter(soap, soap->id, p, t, sizeof(int), 0, NULL, NULL, NULL);
       
  8182   if (*soap->href)
       
  8183     p = (int*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(int), 0, NULL);
       
  8184   else if (p)
       
  8185   { if (soap_s2int(soap, soap_value(soap), p))
       
  8186       return NULL;
       
  8187   }
       
  8188   if (soap->body && soap_element_end_in(soap, tag))
       
  8189     return NULL;
       
  8190   return p;
       
  8191 }
       
  8192 #endif
       
  8193 
       
  8194 /******************************************************************************/
       
  8195 #ifndef PALM_2
       
  8196 SOAP_FMAC1
       
  8197 const char*
       
  8198 SOAP_FMAC2
       
  8199 soap_long2s(struct soap *soap, long n)
       
  8200 { sprintf(soap->tmpbuf, "%ld", n);
       
  8201   return soap->tmpbuf;
       
  8202 }
       
  8203 #endif
       
  8204 
       
  8205 /******************************************************************************/
       
  8206 #ifndef PALM_2
       
  8207 SOAP_FMAC1
       
  8208 int
       
  8209 SOAP_FMAC2
       
  8210 soap_outlong(struct soap *soap, const char *tag, int id, const long *p, const char *type, int n)
       
  8211 { if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
       
  8212    || soap_string_out(soap, soap_long2s(soap, *p), 0))
       
  8213     return soap->error;
       
  8214   return soap_element_end_out(soap, tag);
       
  8215 }
       
  8216 #endif
       
  8217 
       
  8218 /******************************************************************************/
       
  8219 #ifndef PALM_2
       
  8220 SOAP_FMAC1
       
  8221 int
       
  8222 SOAP_FMAC2
       
  8223 soap_s2long(struct soap *soap, const char *s, long *p)
       
  8224 { if (s)
       
  8225   { char *r;
       
  8226     *p = soap_strtol(s, &r, 10);
       
  8227     if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
       
  8228 #ifndef WITH_NOIO
       
  8229 #ifndef WITH_LEAN
       
  8230      || soap_errno == SOAP_ERANGE
       
  8231 #endif
       
  8232 #endif
       
  8233     )
       
  8234       soap->error = SOAP_TYPE;
       
  8235   }
       
  8236   return soap->error;
       
  8237 }
       
  8238 #endif
       
  8239 
       
  8240 /******************************************************************************/
       
  8241 #ifndef PALM_2
       
  8242 SOAP_FMAC1
       
  8243 long *
       
  8244 SOAP_FMAC2
       
  8245 soap_inlong(struct soap *soap, const char *tag, long *p, const char *type, int t)
       
  8246 { if (soap_element_begin_in(soap, tag, 0))
       
  8247     return NULL;
       
  8248 #ifndef WITH_LEAN
       
  8249   if (*soap->type
       
  8250    && soap_match_tag(soap, soap->type, type)
       
  8251    && soap_match_tag(soap, soap->type, ":int")
       
  8252    && soap_match_tag(soap, soap->type, ":short")
       
  8253    && soap_match_tag(soap, soap->type, ":byte"))
       
  8254   { soap->error = SOAP_TYPE;
       
  8255     soap_revert(soap);
       
  8256     return NULL;
       
  8257   }
       
  8258 #endif
       
  8259   p = (long*)soap_id_enter(soap, soap->id, p, t, sizeof(long), 0, NULL, NULL, NULL);
       
  8260   if (*soap->href)
       
  8261     p = (long*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(long), 0, NULL);
       
  8262   else if (p)
       
  8263   { if (soap_s2long(soap, soap_value(soap), p))
       
  8264       return NULL;
       
  8265   }
       
  8266   if (soap->body && soap_element_end_in(soap, tag))
       
  8267     return NULL;
       
  8268   return p;
       
  8269 }
       
  8270 #endif
       
  8271 
       
  8272 /******************************************************************************/
       
  8273 #ifndef WITH_LEAN
       
  8274 SOAP_FMAC1
       
  8275 const char*
       
  8276 SOAP_FMAC2
       
  8277 soap_LONG642s(struct soap *soap, LONG64 n)
       
  8278 { sprintf(soap->tmpbuf, SOAP_LONG_FORMAT, n);
       
  8279   return soap->tmpbuf;
       
  8280 }
       
  8281 #endif
       
  8282 
       
  8283 /******************************************************************************/
       
  8284 #ifndef WITH_LEAN
       
  8285 SOAP_FMAC1
       
  8286 int
       
  8287 SOAP_FMAC2
       
  8288 soap_outLONG64(struct soap *soap, const char *tag, int id, const LONG64 *p, const char *type, int n)
       
  8289 { if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
       
  8290    || soap_string_out(soap, soap_LONG642s(soap, *p), 0))
       
  8291     return soap->error;
       
  8292   return soap_element_end_out(soap, tag);
       
  8293 }
       
  8294 #endif
       
  8295 
       
  8296 /******************************************************************************/
       
  8297 #ifndef WITH_LEAN
       
  8298 SOAP_FMAC1
       
  8299 int
       
  8300 SOAP_FMAC2
       
  8301 soap_s2LONG64(struct soap *soap, const char *s, LONG64 *p)
       
  8302 { if (s)
       
  8303   {
       
  8304 #ifdef HAVE_STRTOLL
       
  8305     char *r;
       
  8306     *p = strtoll(s, &r, 10);
       
  8307     if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
       
  8308 #ifndef WITH_NOIO
       
  8309 #ifndef WITH_LEAN
       
  8310        || soap_errno == SOAP_ERANGE
       
  8311 #endif
       
  8312 #endif
       
  8313       )
       
  8314 #else
       
  8315 # ifdef HAVE_SSCANF
       
  8316     if (sscanf(s, SOAP_LONG_FORMAT, p) != 1)
       
  8317 # endif
       
  8318 #endif
       
  8319       soap->error = SOAP_TYPE;
       
  8320   }
       
  8321   return soap->error;
       
  8322 }
       
  8323 #endif
       
  8324 
       
  8325 /******************************************************************************/
       
  8326 #ifndef WITH_LEAN
       
  8327 SOAP_FMAC1
       
  8328 LONG64 *
       
  8329 SOAP_FMAC2
       
  8330 soap_inLONG64(struct soap *soap, const char *tag, LONG64 *p, const char *type, int t)
       
  8331 { if (soap_element_begin_in(soap, tag, 0))
       
  8332     return NULL;
       
  8333 #ifndef WITH_LEAN
       
  8334   if (*soap->type
       
  8335    && soap_match_tag(soap, soap->type, type)
       
  8336    && soap_match_tag(soap, soap->type, ":integer")
       
  8337    && soap_match_tag(soap, soap->type, ":positiveInteger")
       
  8338    && soap_match_tag(soap, soap->type, ":negativeInteger")
       
  8339    && soap_match_tag(soap, soap->type, ":nonPositiveInteger")
       
  8340    && soap_match_tag(soap, soap->type, ":nonNegativeInteger")
       
  8341    && soap_match_tag(soap, soap->type, ":long")
       
  8342    && soap_match_tag(soap, soap->type, ":int")
       
  8343    && soap_match_tag(soap, soap->type, ":short")
       
  8344    && soap_match_tag(soap, soap->type, ":byte"))
       
  8345   { soap->error = SOAP_TYPE;
       
  8346     soap_revert(soap);
       
  8347     return NULL;
       
  8348   }
       
  8349 #endif
       
  8350   p = (LONG64*)soap_id_enter(soap, soap->id, p, t, sizeof(LONG64), 0, NULL, NULL, NULL);
       
  8351   if (*soap->href)
       
  8352     p = (LONG64*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(LONG64), 0, NULL);
       
  8353   else if (p)
       
  8354   { if (soap_s2LONG64(soap, soap_value(soap), p))
       
  8355       return NULL;
       
  8356   }
       
  8357   if (soap->body && soap_element_end_in(soap, tag))
       
  8358     return NULL;
       
  8359   return p;
       
  8360 }
       
  8361 #endif
       
  8362 
       
  8363 /******************************************************************************/
       
  8364 #ifndef PALM_2
       
  8365 SOAP_FMAC1
       
  8366 const char*
       
  8367 SOAP_FMAC2
       
  8368 soap_byte2s(struct soap *soap, char n)
       
  8369 { return soap_long2s(soap, (long)n);
       
  8370 }
       
  8371 #endif
       
  8372 
       
  8373 /******************************************************************************/
       
  8374 #ifndef PALM_2
       
  8375 SOAP_FMAC1
       
  8376 int
       
  8377 SOAP_FMAC2
       
  8378 soap_outbyte(struct soap *soap, const char *tag, int id, const char *p, const char *type, int n)
       
  8379 { if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
       
  8380    || soap_string_out(soap, soap_long2s(soap, (long)*p), 0))
       
  8381     return soap->error;
       
  8382   return soap_element_end_out(soap, tag);
       
  8383 }
       
  8384 #endif
       
  8385 
       
  8386 /******************************************************************************/
       
  8387 #ifndef PALM_2
       
  8388 SOAP_FMAC1
       
  8389 int
       
  8390 SOAP_FMAC2
       
  8391 soap_s2byte(struct soap *soap, const char *s, char *p)
       
  8392 { if (s)
       
  8393   { long n;
       
  8394     char *r;
       
  8395     n = soap_strtol(s, &r, 10);
       
  8396     if (s == r || *r || n < -128 || n > 127)
       
  8397       soap->error = SOAP_TYPE;
       
  8398     *p = (char)n;
       
  8399   }
       
  8400   return soap->error;
       
  8401 }
       
  8402 #endif
       
  8403 
       
  8404 /******************************************************************************/
       
  8405 #ifndef PALM_2
       
  8406 SOAP_FMAC1
       
  8407 char *
       
  8408 SOAP_FMAC2
       
  8409 soap_inbyte(struct soap *soap, const char *tag, char *p, const char *type, int t)
       
  8410 { if (soap_element_begin_in(soap, tag, 0))
       
  8411     return NULL;
       
  8412 #ifndef WITH_LEAN
       
  8413   if (*soap->type
       
  8414    && soap_match_tag(soap, soap->type, type)
       
  8415    && soap_match_tag(soap, soap->type, ":byte"))
       
  8416   { soap->error = SOAP_TYPE;
       
  8417     soap_revert(soap);
       
  8418     return NULL;
       
  8419   }
       
  8420 #endif
       
  8421   p = (char*)soap_id_enter(soap, soap->id, p, t, sizeof(char), 0, NULL, NULL, NULL);
       
  8422   if (*soap->href)
       
  8423     p = (char*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(char), 0, NULL);
       
  8424   else if (p)
       
  8425   { if (soap_s2byte(soap, soap_value(soap), p))
       
  8426       return NULL;
       
  8427   }
       
  8428   if (soap->body && soap_element_end_in(soap, tag))
       
  8429     return NULL;
       
  8430   return p;
       
  8431 }
       
  8432 #endif
       
  8433 
       
  8434 /******************************************************************************/
       
  8435 #ifndef PALM_2
       
  8436 SOAP_FMAC1
       
  8437 const char*
       
  8438 SOAP_FMAC2
       
  8439 soap_short2s(struct soap *soap, short n)
       
  8440 { return soap_long2s(soap, (long)n);
       
  8441 }
       
  8442 #endif
       
  8443 
       
  8444 /******************************************************************************/
       
  8445 #ifndef PALM_2
       
  8446 SOAP_FMAC1
       
  8447 int
       
  8448 SOAP_FMAC2
       
  8449 soap_outshort(struct soap *soap, const char *tag, int id, const short *p, const char *type, int n)
       
  8450 { if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
       
  8451    || soap_string_out(soap, soap_long2s(soap, (long)*p), 0))
       
  8452     return soap->error;
       
  8453   return soap_element_end_out(soap, tag);
       
  8454 }
       
  8455 #endif
       
  8456 
       
  8457 /******************************************************************************/
       
  8458 #ifndef PALM_2
       
  8459 SOAP_FMAC1
       
  8460 int
       
  8461 SOAP_FMAC2
       
  8462 soap_s2short(struct soap *soap, const char *s, short *p)
       
  8463 { if (s)
       
  8464   { long n;
       
  8465     char *r;
       
  8466     n = soap_strtol(s, &r, 10);
       
  8467     if (s == r || *r || n < -32768 || n > 32767)
       
  8468       soap->error = SOAP_TYPE;
       
  8469     *p = (short)n;
       
  8470   }
       
  8471   return soap->error;
       
  8472 }
       
  8473 #endif
       
  8474 
       
  8475 /******************************************************************************/
       
  8476 #ifndef PALM_2
       
  8477 SOAP_FMAC1
       
  8478 short *
       
  8479 SOAP_FMAC2
       
  8480 soap_inshort(struct soap *soap, const char *tag, short *p, const char *type, int t)
       
  8481 { if (soap_element_begin_in(soap, tag, 0))
       
  8482     return NULL;
       
  8483 #ifndef WITH_LEAN
       
  8484   if (*soap->type
       
  8485    && soap_match_tag(soap, soap->type, type)
       
  8486    && soap_match_tag(soap, soap->type, ":short")
       
  8487    && soap_match_tag(soap, soap->type, ":byte"))
       
  8488   { soap->error = SOAP_TYPE;
       
  8489     soap_revert(soap);
       
  8490     return NULL;
       
  8491   }
       
  8492 #endif
       
  8493   p = (short*)soap_id_enter(soap, soap->id, p, t, sizeof(short), 0, NULL, NULL, NULL);
       
  8494   if (*soap->href)
       
  8495     p = (short*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(short), 0, NULL);
       
  8496   else if (p)
       
  8497   { if (soap_s2short(soap, soap_value(soap), p))
       
  8498       return NULL;
       
  8499   }
       
  8500   if (soap->body && soap_element_end_in(soap, tag))
       
  8501     return NULL;
       
  8502   return p;
       
  8503 }
       
  8504 #endif
       
  8505 
       
  8506 /******************************************************************************/
       
  8507 #ifndef PALM_2
       
  8508 SOAP_FMAC1
       
  8509 const char*
       
  8510 SOAP_FMAC2
       
  8511 soap_float2s(struct soap *soap, float n)
       
  8512 { const char *s;
       
  8513   if (soap_isnan((double)n))
       
  8514     s = "NaN";
       
  8515   else if (soap_ispinff(n))
       
  8516     s = "INF";
       
  8517   else if (soap_isninff(n))
       
  8518     s = "-INF";
       
  8519   else
       
  8520   { sprintf(soap->tmpbuf, soap->float_format, n);
       
  8521     s = soap->tmpbuf;
       
  8522   }
       
  8523   return s;
       
  8524 }
       
  8525 #endif
       
  8526 
       
  8527 /******************************************************************************/
       
  8528 #ifndef PALM_2
       
  8529 SOAP_FMAC1
       
  8530 int
       
  8531 SOAP_FMAC2
       
  8532 soap_outfloat(struct soap *soap, const char *tag, int id, const float *p, const char *type, int n)
       
  8533 { if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
       
  8534    || soap_string_out(soap, soap_float2s(soap, *p), 0))
       
  8535     return soap->error;
       
  8536   return soap_element_end_out(soap, tag);
       
  8537 }
       
  8538 #endif
       
  8539 
       
  8540 /******************************************************************************/
       
  8541 #ifndef PALM_2
       
  8542 SOAP_FMAC1
       
  8543 int
       
  8544 SOAP_FMAC2
       
  8545 soap_s2float(struct soap *soap, const char *s, float *p)
       
  8546 { if (s)
       
  8547   { if (!*s)
       
  8548       return soap->error = SOAP_TYPE;
       
  8549     if (!soap_tag_cmp(s, "INF"))
       
  8550       *p = FLT_PINFTY;
       
  8551     else if (!soap_tag_cmp(s, "+INF"))
       
  8552       *p = FLT_PINFTY;
       
  8553     else if (!soap_tag_cmp(s, "-INF"))
       
  8554       *p = FLT_NINFTY;
       
  8555     else if (!soap_tag_cmp(s, "NaN"))
       
  8556       *p = FLT_NAN;
       
  8557     else
       
  8558     {
       
  8559 /* On some systems, strtof appears to be broken or doesn't link: use with caution */
       
  8560 #if defined(HAVE_STRTOF)
       
  8561       char *r;
       
  8562       *p = strtof((char*)s, &r);
       
  8563       if (*r)
       
  8564 #elif defined(HAVE_STRTOD)
       
  8565       char *r;
       
  8566       *p = (float)strtod(s, &r);
       
  8567       if (*r)
       
  8568 #endif
       
  8569 #ifdef HAVE_SSCANF
       
  8570         if (sscanf(s, "%g", p) != 1)
       
  8571           soap->error = SOAP_TYPE;
       
  8572 #else
       
  8573         soap->error = SOAP_TYPE;
       
  8574 #endif
       
  8575     }
       
  8576   }
       
  8577   return soap->error;
       
  8578 }
       
  8579 #endif
       
  8580 
       
  8581 /******************************************************************************/
       
  8582 #ifndef WITH_LEAN
       
  8583 static int soap_isnumeric(struct soap *soap, const char *type)
       
  8584 { if (soap_match_tag(soap, soap->type, type)
       
  8585    && soap_match_tag(soap, soap->type, ":float")
       
  8586    && soap_match_tag(soap, soap->type, ":double")
       
  8587    && soap_match_tag(soap, soap->type, ":decimal")
       
  8588    && soap_match_tag(soap, soap->type, ":integer")
       
  8589    && soap_match_tag(soap, soap->type, ":positiveInteger")
       
  8590    && soap_match_tag(soap, soap->type, ":negativeInteger")
       
  8591    && soap_match_tag(soap, soap->type, ":nonPositiveInteger")
       
  8592    && soap_match_tag(soap, soap->type, ":nonNegativeInteger")
       
  8593    && soap_match_tag(soap, soap->type, ":long")
       
  8594    && soap_match_tag(soap, soap->type, ":int")
       
  8595    && soap_match_tag(soap, soap->type, ":short")
       
  8596    && soap_match_tag(soap, soap->type, ":byte")
       
  8597    && soap_match_tag(soap, soap->type, ":unsignedLong")
       
  8598    && soap_match_tag(soap, soap->type, ":unsignedInt")
       
  8599    && soap_match_tag(soap, soap->type, ":unsignedShort")
       
  8600    && soap_match_tag(soap, soap->type, ":unsignedByte"))
       
  8601   { soap->error = SOAP_TYPE;
       
  8602     soap_revert(soap);
       
  8603     return SOAP_ERR;
       
  8604   }
       
  8605   return SOAP_OK;
       
  8606 }
       
  8607 #endif
       
  8608 
       
  8609 /******************************************************************************/
       
  8610 #ifndef PALM_2
       
  8611 SOAP_FMAC1
       
  8612 float *
       
  8613 SOAP_FMAC2
       
  8614 soap_infloat(struct soap *soap, const char *tag, float *p, const char *type, int t)
       
  8615 { if (soap_element_begin_in(soap, tag, 0))
       
  8616     return NULL;
       
  8617 #ifndef WITH_LEAN
       
  8618   if (*soap->type != '\0' && soap_isnumeric(soap, type))
       
  8619     return NULL;
       
  8620 #endif
       
  8621   p = (float*)soap_id_enter(soap, soap->id, p, t, sizeof(float), 0, NULL, NULL, NULL);
       
  8622   if (*soap->href)
       
  8623     p = (float*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(float), 0, NULL);
       
  8624   else if (p)
       
  8625   { if (soap_s2float(soap, soap_value(soap), p))
       
  8626       return NULL;
       
  8627   }
       
  8628   if (soap->body && soap_element_end_in(soap, tag))
       
  8629     return NULL;
       
  8630   return p;
       
  8631 }
       
  8632 #endif
       
  8633 
       
  8634 /******************************************************************************/
       
  8635 #ifndef PALM_2
       
  8636 SOAP_FMAC1
       
  8637 const char*
       
  8638 SOAP_FMAC2
       
  8639 soap_double2s(struct soap *soap, double n)
       
  8640 { const char *s;
       
  8641   if (soap_isnan(n))
       
  8642     s = "NaN";
       
  8643   else if (soap_ispinfd(n))
       
  8644     s = "INF";
       
  8645   else if (soap_isninfd(n))
       
  8646     s = "-INF";
       
  8647   else
       
  8648   { sprintf(soap->tmpbuf, soap->double_format, n);
       
  8649     s = soap->tmpbuf;
       
  8650   }
       
  8651   return s;
       
  8652 }
       
  8653 #endif
       
  8654 
       
  8655 /******************************************************************************/
       
  8656 #ifndef PALM_2
       
  8657 SOAP_FMAC1
       
  8658 int
       
  8659 SOAP_FMAC2
       
  8660 soap_outdouble(struct soap *soap, const char *tag, int id, const double *p, const char *type, int n)
       
  8661 { if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
       
  8662    || soap_string_out(soap, soap_double2s(soap, *p), 0))
       
  8663     return soap->error;
       
  8664   return soap_element_end_out(soap, tag);
       
  8665 }
       
  8666 #endif
       
  8667 
       
  8668 /******************************************************************************/
       
  8669 #ifndef PALM_2
       
  8670 SOAP_FMAC1
       
  8671 int
       
  8672 SOAP_FMAC2
       
  8673 soap_s2double(struct soap *soap, const char *s, double *p)
       
  8674 { if (s)
       
  8675   { if (!*s)
       
  8676       return soap->error = SOAP_TYPE;
       
  8677     if (!soap_tag_cmp(s, "INF"))
       
  8678       *p = DBL_PINFTY;
       
  8679     else if (!soap_tag_cmp(s, "+INF"))
       
  8680       *p = DBL_PINFTY;
       
  8681     else if (!soap_tag_cmp(s, "-INF"))
       
  8682       *p = DBL_NINFTY;
       
  8683     else if (!soap_tag_cmp(s, "NaN"))
       
  8684       *p = DBL_NAN;
       
  8685     else
       
  8686     {
       
  8687 #ifdef HAVE_STRTOD
       
  8688       char *r;
       
  8689       *p = strtod(s, &r);
       
  8690       if (*r)
       
  8691 #endif
       
  8692 #ifdef HAVE_SSCANF
       
  8693         if (sscanf(s, "%lg", p) != 1)
       
  8694           soap->error = SOAP_TYPE;
       
  8695 #else
       
  8696         soap->error = SOAP_TYPE;
       
  8697 #endif
       
  8698     }
       
  8699   }
       
  8700   return soap->error;
       
  8701 }
       
  8702 #endif
       
  8703 
       
  8704 /******************************************************************************/
       
  8705 #ifndef PALM_2
       
  8706 SOAP_FMAC1
       
  8707 double *
       
  8708 SOAP_FMAC2
       
  8709 soap_indouble(struct soap *soap, const char *tag, double *p, const char *type, int t)
       
  8710 { if (soap_element_begin_in(soap, tag, 0))
       
  8711     return NULL;
       
  8712 #ifndef WITH_LEAN
       
  8713   if (*soap->type != '\0' && soap_isnumeric(soap, type))
       
  8714     return NULL;
       
  8715 #endif
       
  8716   p = (double*)soap_id_enter(soap, soap->id, p, t, sizeof(double), 0, NULL, NULL, NULL);
       
  8717   if (*soap->href)
       
  8718     p = (double*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(double), 0, NULL);
       
  8719   else if (p)
       
  8720   { if (soap_s2double(soap, soap_value(soap), p))
       
  8721       return NULL;
       
  8722   }
       
  8723   if (soap->body && soap_element_end_in(soap, tag))
       
  8724     return NULL;
       
  8725   return p;
       
  8726 }
       
  8727 #endif
       
  8728 
       
  8729 /******************************************************************************/
       
  8730 #ifndef PALM_2
       
  8731 SOAP_FMAC1
       
  8732 const char*
       
  8733 SOAP_FMAC2
       
  8734 soap_unsignedByte2s(struct soap *soap, unsigned char n)
       
  8735 { return soap_unsignedLong2s(soap, (unsigned long)n);
       
  8736 }
       
  8737 #endif
       
  8738 
       
  8739 /******************************************************************************/
       
  8740 #ifndef PALM_2
       
  8741 SOAP_FMAC1
       
  8742 int
       
  8743 SOAP_FMAC2
       
  8744 soap_outunsignedByte(struct soap *soap, const char *tag, int id, const unsigned char *p, const char *type, int n)
       
  8745 { if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
       
  8746    || soap_string_out(soap, soap_unsignedLong2s(soap, (unsigned long)*p), 0))
       
  8747     return soap->error;
       
  8748   return soap_element_end_out(soap, tag);
       
  8749 }
       
  8750 #endif
       
  8751 
       
  8752 /******************************************************************************/
       
  8753 #ifndef PALM_2
       
  8754 SOAP_FMAC1
       
  8755 int
       
  8756 SOAP_FMAC2
       
  8757 soap_s2unsignedByte(struct soap *soap, const char *s, unsigned char *p)
       
  8758 { if (s)
       
  8759   { unsigned long n;
       
  8760     char *r;
       
  8761     n = soap_strtoul(s, &r, 10);
       
  8762     if (s == r || *r || n > 255)
       
  8763       soap->error = SOAP_TYPE;
       
  8764     *p = (unsigned char)n;
       
  8765   }
       
  8766   return soap->error;
       
  8767 }
       
  8768 #endif
       
  8769 
       
  8770 /******************************************************************************/
       
  8771 #ifndef PALM_2
       
  8772 SOAP_FMAC1
       
  8773 unsigned char *
       
  8774 SOAP_FMAC2
       
  8775 soap_inunsignedByte(struct soap *soap, const char *tag, unsigned char *p, const char *type, int t)
       
  8776 { if (soap_element_begin_in(soap, tag, 0))
       
  8777     return NULL;
       
  8778 #ifndef WITH_LEAN
       
  8779   if (*soap->type
       
  8780    && soap_match_tag(soap, soap->type, type)
       
  8781    && soap_match_tag(soap, soap->type, ":unsignedByte"))
       
  8782   { soap->error = SOAP_TYPE;
       
  8783     soap_revert(soap);
       
  8784     return NULL;
       
  8785   }
       
  8786 #endif
       
  8787   p = (unsigned char*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned char), 0, NULL, NULL, NULL);
       
  8788   if (*soap->href)
       
  8789     p = (unsigned char*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(unsigned char), 0, NULL);
       
  8790   else if (p)
       
  8791   { if (soap_s2unsignedByte(soap, soap_value(soap), p))
       
  8792       return NULL;
       
  8793   }
       
  8794   if (soap->body && soap_element_end_in(soap, tag))
       
  8795     return NULL;
       
  8796   return p;
       
  8797 }
       
  8798 #endif
       
  8799 
       
  8800 /******************************************************************************/
       
  8801 #ifndef PALM_2
       
  8802 SOAP_FMAC1
       
  8803 const char*
       
  8804 SOAP_FMAC2
       
  8805 soap_unsignedShort2s(struct soap *soap, unsigned short n)
       
  8806 { return soap_unsignedLong2s(soap, (unsigned long)n);
       
  8807 }
       
  8808 #endif
       
  8809 
       
  8810 /******************************************************************************/
       
  8811 #ifndef PALM_2
       
  8812 SOAP_FMAC1
       
  8813 int
       
  8814 SOAP_FMAC2
       
  8815 soap_outunsignedShort(struct soap *soap, const char *tag, int id, const unsigned short *p, const char *type, int n)
       
  8816 { if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
       
  8817    || soap_string_out(soap, soap_unsignedLong2s(soap, (unsigned long)*p), 0))
       
  8818     return soap->error;
       
  8819   return soap_element_end_out(soap, tag);
       
  8820 }
       
  8821 #endif
       
  8822 
       
  8823 /******************************************************************************/
       
  8824 #ifndef PALM_2
       
  8825 SOAP_FMAC1
       
  8826 int
       
  8827 SOAP_FMAC2
       
  8828 soap_s2unsignedShort(struct soap *soap, const char *s, unsigned short *p)
       
  8829 { if (s)
       
  8830   { unsigned long n;
       
  8831     char *r;
       
  8832     n = soap_strtoul(s, &r, 10);
       
  8833     if (s == r || *r || n > 65535)
       
  8834       soap->error = SOAP_TYPE;
       
  8835     *p = (unsigned short)n;
       
  8836   }
       
  8837   return soap->error;
       
  8838 }
       
  8839 #endif
       
  8840 
       
  8841 /******************************************************************************/
       
  8842 #ifndef PALM_2
       
  8843 SOAP_FMAC1
       
  8844 unsigned short *
       
  8845 SOAP_FMAC2
       
  8846 soap_inunsignedShort(struct soap *soap, const char *tag, unsigned short *p, const char *type, int t)
       
  8847 { if (soap_element_begin_in(soap, tag, 0))
       
  8848     return NULL;
       
  8849 #ifndef WITH_LEAN
       
  8850   if (*soap->type
       
  8851    && soap_match_tag(soap, soap->type, type)
       
  8852    && soap_match_tag(soap, soap->type, ":unsignedShort")
       
  8853    && soap_match_tag(soap, soap->type, ":unsignedByte"))
       
  8854   { soap->error = SOAP_TYPE;
       
  8855     soap_revert(soap);
       
  8856     return NULL;
       
  8857   }
       
  8858 #endif
       
  8859   p = (unsigned short*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned short), 0, NULL, NULL, NULL);
       
  8860   if (*soap->href)
       
  8861     p = (unsigned short*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(unsigned short), 0, NULL);
       
  8862   else if (p)
       
  8863   { if (soap_s2unsignedShort(soap, soap_value(soap), p))
       
  8864       return NULL;
       
  8865   }
       
  8866   if (soap->body && soap_element_end_in(soap, tag))
       
  8867     return NULL;
       
  8868   return p;
       
  8869 }
       
  8870 #endif
       
  8871 
       
  8872 /******************************************************************************/
       
  8873 #ifndef PALM_2
       
  8874 SOAP_FMAC1
       
  8875 const char*
       
  8876 SOAP_FMAC2
       
  8877 soap_unsignedInt2s(struct soap *soap, unsigned int n)
       
  8878 { return soap_unsignedLong2s(soap, (unsigned long)n);
       
  8879 }
       
  8880 #endif
       
  8881 
       
  8882 /******************************************************************************/
       
  8883 #ifndef PALM_2
       
  8884 SOAP_FMAC1
       
  8885 int
       
  8886 SOAP_FMAC2
       
  8887 soap_outunsignedInt(struct soap *soap, const char *tag, int id, const unsigned int *p, const char *type, int n)
       
  8888 { if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
       
  8889    || soap_string_out(soap, soap_unsignedLong2s(soap, (unsigned long)*p), 0))
       
  8890     return soap->error;
       
  8891   return soap_element_end_out(soap, tag);
       
  8892 }
       
  8893 #endif
       
  8894 
       
  8895 /******************************************************************************/
       
  8896 #ifndef PALM_2
       
  8897 SOAP_FMAC1
       
  8898 int
       
  8899 SOAP_FMAC2
       
  8900 soap_s2unsignedInt(struct soap *soap, const char *s, unsigned int *p)
       
  8901 { if (s)
       
  8902   { char *r;
       
  8903     *p = (unsigned int)soap_strtoul(s, &r, 10);
       
  8904     if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
       
  8905 #ifndef WITH_NOIO
       
  8906 #ifndef WITH_LEAN
       
  8907      || soap_errno == SOAP_ERANGE
       
  8908 #endif
       
  8909 #endif
       
  8910     )
       
  8911       soap->error = SOAP_TYPE;
       
  8912   }
       
  8913   return soap->error;
       
  8914 }
       
  8915 #endif
       
  8916 
       
  8917 /******************************************************************************/
       
  8918 #ifndef PALM_2
       
  8919 SOAP_FMAC1
       
  8920 unsigned int *
       
  8921 SOAP_FMAC2
       
  8922 soap_inunsignedInt(struct soap *soap, const char *tag, unsigned int *p, const char *type, int t)
       
  8923 { if (soap_element_begin_in(soap, tag, 0))
       
  8924     return NULL;
       
  8925 #ifndef WITH_LEAN
       
  8926   if (*soap->type
       
  8927    && soap_match_tag(soap, soap->type, type)
       
  8928    && soap_match_tag(soap, soap->type, ":unsignedInt")
       
  8929    && soap_match_tag(soap, soap->type, ":unsignedShort")
       
  8930    && soap_match_tag(soap, soap->type, ":unsignedByte"))
       
  8931   { soap->error = SOAP_TYPE;
       
  8932     soap_revert(soap);
       
  8933     return NULL;
       
  8934   }
       
  8935 #endif
       
  8936   p = (unsigned int*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned int), 0, NULL, NULL, NULL);
       
  8937   if (*soap->href)
       
  8938     p = (unsigned int*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(unsigned int), 0, NULL);
       
  8939   else if (p)
       
  8940   { if (soap_s2unsignedInt(soap, soap_value(soap), p))
       
  8941       return NULL;
       
  8942   }
       
  8943   if (soap->body && soap_element_end_in(soap, tag))
       
  8944     return NULL;
       
  8945   return p;
       
  8946 }
       
  8947 #endif
       
  8948 
       
  8949 /******************************************************************************/
       
  8950 #ifndef PALM_2
       
  8951 SOAP_FMAC1
       
  8952 const char*
       
  8953 SOAP_FMAC2
       
  8954 soap_unsignedLong2s(struct soap *soap, unsigned long n)
       
  8955 { sprintf(soap->tmpbuf, "%lu", n);
       
  8956   return soap->tmpbuf;
       
  8957 }
       
  8958 #endif
       
  8959 
       
  8960 /******************************************************************************/
       
  8961 #ifndef PALM_2
       
  8962 SOAP_FMAC1
       
  8963 int
       
  8964 SOAP_FMAC2
       
  8965 soap_outunsignedLong(struct soap *soap, const char *tag, int id, const unsigned long *p, const char *type, int n)
       
  8966 { if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
       
  8967    || soap_string_out(soap, soap_unsignedLong2s(soap, *p), 0))
       
  8968     return soap->error;
       
  8969   return soap_element_end_out(soap, tag);
       
  8970 }
       
  8971 #endif
       
  8972 
       
  8973 /******************************************************************************/
       
  8974 #ifndef PALM_2
       
  8975 SOAP_FMAC1
       
  8976 int
       
  8977 SOAP_FMAC2
       
  8978 soap_s2unsignedLong(struct soap *soap, const char *s, unsigned long *p)
       
  8979 { if (s)
       
  8980   { char *r;
       
  8981     *p = soap_strtoul(s, &r, 10);
       
  8982     if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
       
  8983 #ifndef WITH_NOIO
       
  8984 #ifndef WITH_LEAN
       
  8985      || soap_errno == SOAP_ERANGE
       
  8986 #endif
       
  8987 #endif
       
  8988     )
       
  8989       soap->error = SOAP_TYPE;
       
  8990   }
       
  8991   return soap->error;
       
  8992 }
       
  8993 #endif
       
  8994 
       
  8995 /******************************************************************************/
       
  8996 #ifndef PALM_2
       
  8997 SOAP_FMAC1
       
  8998 unsigned long *
       
  8999 SOAP_FMAC2
       
  9000 soap_inunsignedLong(struct soap *soap, const char *tag, unsigned long *p, const char *type, int t)
       
  9001 { if (soap_element_begin_in(soap, tag, 0))
       
  9002     return NULL;
       
  9003 #ifndef WITH_LEAN
       
  9004   if (*soap->type
       
  9005    && soap_match_tag(soap, soap->type, type)
       
  9006    && soap_match_tag(soap, soap->type, ":unsignedInt")
       
  9007    && soap_match_tag(soap, soap->type, ":unsignedShort")
       
  9008    && soap_match_tag(soap, soap->type, ":unsignedByte"))
       
  9009   { soap->error = SOAP_TYPE;
       
  9010     soap_revert(soap);
       
  9011     return NULL;
       
  9012   }
       
  9013 #endif
       
  9014   p = (unsigned long*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned long), 0, NULL, NULL, NULL);
       
  9015   if (*soap->href)
       
  9016     p = (unsigned long*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(unsigned long), 0, NULL);
       
  9017   else if (p)
       
  9018   { if (soap_s2unsignedLong(soap, soap_value(soap), p))
       
  9019       return NULL;
       
  9020   }
       
  9021   if (soap->body && soap_element_end_in(soap, tag))
       
  9022     return NULL;
       
  9023   return p;
       
  9024 }
       
  9025 #endif
       
  9026 
       
  9027 /******************************************************************************/
       
  9028 #ifndef WITH_LEAN
       
  9029 SOAP_FMAC1
       
  9030 const char*
       
  9031 SOAP_FMAC2
       
  9032 soap_ULONG642s(struct soap *soap, ULONG64 n)
       
  9033 { sprintf(soap->tmpbuf, SOAP_ULONG_FORMAT, n);
       
  9034   return soap->tmpbuf;
       
  9035 }
       
  9036 #endif
       
  9037 
       
  9038 /******************************************************************************/
       
  9039 #ifndef WITH_LEAN
       
  9040 SOAP_FMAC1
       
  9041 int
       
  9042 SOAP_FMAC2
       
  9043 soap_outULONG64(struct soap *soap, const char *tag, int id, const ULONG64 *p, const char *type, int n)
       
  9044 { if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
       
  9045    || soap_string_out(soap, soap_ULONG642s(soap, *p), 0))
       
  9046     return soap->error;
       
  9047   return soap_element_end_out(soap, tag);
       
  9048 }
       
  9049 #endif
       
  9050 
       
  9051 /******************************************************************************/
       
  9052 #ifndef WITH_LEAN
       
  9053 SOAP_FMAC1
       
  9054 int
       
  9055 SOAP_FMAC2
       
  9056 soap_s2ULONG64(struct soap *soap, const char *s, ULONG64 *p)
       
  9057 { if (s)
       
  9058   {
       
  9059 #ifdef HAVE_STRTOULL
       
  9060     char *r;
       
  9061     *p = strtoull(s, &r, 10);
       
  9062     if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
       
  9063 #ifndef WITH_NOIO
       
  9064 #ifndef WITH_LEAN
       
  9065        || soap_errno == SOAP_ERANGE
       
  9066 #endif
       
  9067 #endif
       
  9068       )
       
  9069 #else
       
  9070 # ifdef HAVE_SSCANF
       
  9071     if (sscanf(s, SOAP_ULONG_FORMAT, p) != 1)
       
  9072 # endif
       
  9073 #endif
       
  9074       soap->error = SOAP_TYPE;
       
  9075   }
       
  9076   return soap->error;
       
  9077 }
       
  9078 #endif
       
  9079 
       
  9080 /******************************************************************************/
       
  9081 #ifndef WITH_LEAN
       
  9082 SOAP_FMAC1
       
  9083 ULONG64 *
       
  9084 SOAP_FMAC2
       
  9085 soap_inULONG64(struct soap *soap, const char *tag, ULONG64 *p, const char *type, int t)
       
  9086 { if (soap_element_begin_in(soap, tag, 0))
       
  9087     return NULL;
       
  9088   if (*soap->type
       
  9089    && soap_match_tag(soap, soap->type, type)
       
  9090    && soap_match_tag(soap, soap->type, ":positiveInteger")
       
  9091    && soap_match_tag(soap, soap->type, ":nonNegativeInteger")
       
  9092    && soap_match_tag(soap, soap->type, ":unsignedLong")
       
  9093    && soap_match_tag(soap, soap->type, ":unsignedInt")
       
  9094    && soap_match_tag(soap, soap->type, ":unsignedShort")
       
  9095    && soap_match_tag(soap, soap->type, ":unsignedByte"))
       
  9096   { soap->error = SOAP_TYPE;
       
  9097     soap_revert(soap);
       
  9098     return NULL;
       
  9099   }
       
  9100   p = (ULONG64*)soap_id_enter(soap, soap->id, p, t, sizeof(ULONG64), 0, NULL, NULL, NULL);
       
  9101   if (*soap->href)
       
  9102     p = (ULONG64*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(ULONG64), 0, NULL);
       
  9103   else if (p)
       
  9104   { if (soap_s2ULONG64(soap, soap_value(soap), p))
       
  9105       return NULL;
       
  9106   }
       
  9107   if (soap->body && soap_element_end_in(soap, tag))
       
  9108     return NULL;
       
  9109   return p;
       
  9110 }
       
  9111 #endif
       
  9112 
       
  9113 /******************************************************************************/
       
  9114 #ifndef PALM_2
       
  9115 SOAP_FMAC1
       
  9116 int
       
  9117 SOAP_FMAC2
       
  9118 soap_s2string(struct soap *soap, const char *s, char **t)
       
  9119 { *t = NULL;
       
  9120   if (s && !(*t = soap_strdup(soap, s)))
       
  9121     soap->error = SOAP_EOM;
       
  9122   return soap->error;
       
  9123 }
       
  9124 #endif
       
  9125 
       
  9126 /******************************************************************************/
       
  9127 #ifndef PALM_2
       
  9128 SOAP_FMAC1
       
  9129 int
       
  9130 SOAP_FMAC2
       
  9131 soap_s2QName(struct soap *soap, const char *s, char **t)
       
  9132 { if (s)
       
  9133   { struct soap_nlist *np;
       
  9134     const char *p;
       
  9135     if (!strncmp(s, "xml:", 4))
       
  9136     { *t = soap_strdup(soap, s);
       
  9137       return SOAP_OK;
       
  9138     }
       
  9139     np = soap->nlist;
       
  9140     p = strchr(s, ':');
       
  9141     if (p)
       
  9142     { register int n = p - s;
       
  9143       while (np && (strncmp(np->id, s, n) || np->id[n]))
       
  9144         np = np->next;
       
  9145       p++;
       
  9146     }
       
  9147     else
       
  9148     { while (np && *np->id)
       
  9149         np = np->next;
       
  9150       p = s;
       
  9151     }
       
  9152     if (np)
       
  9153     { if (np->index >= 0 && soap->local_namespaces)
       
  9154       { register const char *q = soap->local_namespaces[np->index].id;
       
  9155         if (q)
       
  9156         { if ((*t = (char*)soap_malloc(soap, strlen(p) + strlen(q) + 2)))
       
  9157             sprintf(*t, "%s:%s", q, p);
       
  9158           return SOAP_OK;
       
  9159         }
       
  9160       }
       
  9161       if (np->ns)
       
  9162       { if ((*t = (char*)soap_malloc(soap, strlen(p) + strlen(np->ns) + 4)))
       
  9163           sprintf(*t, "\"%s\":%s", np->ns, p);
       
  9164         return SOAP_OK;
       
  9165       }
       
  9166       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Namespace prefix of '%s' not defined (index=%d, URI=%s)\n", s, np->index, np->ns?np->ns:""));
       
  9167       return soap->error = SOAP_NAMESPACE; 
       
  9168     }
       
  9169     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Namespace prefix of '%s' not defined, assuming empty namespace\n", s));
       
  9170     if ((*t = (char*)soap_malloc(soap, strlen(p) + 4)))
       
  9171       sprintf(*t, "\"\":%s", p);
       
  9172   }
       
  9173   return soap->error;
       
  9174 }
       
  9175 #endif
       
  9176 
       
  9177 /******************************************************************************/
       
  9178 #ifndef PALM_2
       
  9179 SOAP_FMAC1
       
  9180 const char*
       
  9181 SOAP_FMAC2
       
  9182 soap_QName2s(struct soap *soap, const char *s)
       
  9183 { struct Namespace *p;
       
  9184   char *t;
       
  9185   int n;
       
  9186   if (!s || *s != '"')
       
  9187   {
       
  9188 #ifndef WITH_LEAN
       
  9189     if (s && (soap->mode & SOAP_XML_CANONICAL))
       
  9190     { t = strchr(const_cast<char*>(s), ':');
       
  9191       if (t)
       
  9192         soap_utilize_ns(soap, s, t - s);
       
  9193     }
       
  9194 #endif
       
  9195     return s;
       
  9196   }
       
  9197   s++;
       
  9198   if ((p = soap->local_namespaces))
       
  9199   { for (; p->id; p++)
       
  9200     { if (p->ns)
       
  9201         if (!soap_tag_cmp(s, p->ns))
       
  9202           break;
       
  9203       if (p->in)
       
  9204         if (!soap_tag_cmp(s, p->in))
       
  9205           break;
       
  9206     }
       
  9207     if (p && p->id)
       
  9208     { s = strchr(s, '"');
       
  9209       if (s)
       
  9210       { t = (char*)soap_malloc(soap, strlen(p->id) + strlen(s));
       
  9211         strcpy(t, p->id);
       
  9212 	strcat(t, s + 1);
       
  9213         return t;
       
  9214       }
       
  9215     }
       
  9216   }
       
  9217   t = (char*)strchr(s, '"');
       
  9218   if (t)
       
  9219     n = t - s;
       
  9220   else
       
  9221     n = 0;
       
  9222   t = soap_strdup(soap, s);
       
  9223   t[n] = '\0';
       
  9224   sprintf(soap->tmpbuf, "xmlns:_%d", soap->idnum++);
       
  9225   soap_set_attr(soap, soap->tmpbuf, t);
       
  9226   s = strchr(s, '"');
       
  9227   if (s)
       
  9228   { t = (char*)soap_malloc(soap, strlen(soap->tmpbuf) + strlen(s) - 6);
       
  9229     strcpy(t, soap->tmpbuf + 6);
       
  9230     strcat(t, s + 1);
       
  9231   }
       
  9232   return t;
       
  9233 }
       
  9234 #endif
       
  9235 
       
  9236 /******************************************************************************/
       
  9237 #ifndef PALM_2
       
  9238 SOAP_FMAC1
       
  9239 int
       
  9240 SOAP_FMAC2
       
  9241 soap_outstring(struct soap *soap, const char *tag, int id, char *const*p, const char *type, int n) 
       
  9242 { id = soap_element_id(soap, tag, id, *p, NULL, 0, type, n);
       
  9243   if (id < 0
       
  9244    || soap_element_begin_out(soap, tag, id, type)
       
  9245    || soap_string_out(soap, *p, 0)
       
  9246    || soap_element_end_out(soap, tag))
       
  9247     return soap->error;
       
  9248   return SOAP_OK;
       
  9249 }
       
  9250 #endif
       
  9251 
       
  9252 /******************************************************************************/
       
  9253 #ifndef PALM_2
       
  9254 SOAP_FMAC1
       
  9255 char **
       
  9256 SOAP_FMAC2
       
  9257 soap_instring(struct soap *soap, const char *tag, char **p, const char *type, int t, int flag, long minlen, long maxlen)
       
  9258 { if (soap_element_begin_in(soap, tag, 1))
       
  9259   { if (!tag || *tag != '-' || soap->error != SOAP_NO_TAG)
       
  9260       return NULL;
       
  9261     soap->error = SOAP_OK;
       
  9262   }
       
  9263   if (!p)
       
  9264     if (!(p = (char**)soap_malloc(soap, sizeof(char*))))
       
  9265       return NULL;
       
  9266   if (soap->body)
       
  9267   { *p = soap_string_in(soap, flag, minlen, maxlen);
       
  9268     if (!*p || !(char*)soap_id_enter(soap, soap->id, *p, t, sizeof(char*), 0, NULL, NULL, NULL))
       
  9269       return NULL;
       
  9270   }
       
  9271   else
       
  9272     *p = NULL;
       
  9273   if (*soap->href)
       
  9274     p = (char**)soap_id_lookup(soap, soap->href, (void**)p, t, sizeof(char**), 0);
       
  9275   if (soap->body && soap_element_end_in(soap, tag))
       
  9276     return NULL;
       
  9277   return p;
       
  9278 }
       
  9279 #endif
       
  9280 
       
  9281 /******************************************************************************/
       
  9282 #ifndef WITH_LEANER
       
  9283 #ifndef PALM_2
       
  9284 SOAP_FMAC1
       
  9285 int
       
  9286 SOAP_FMAC2
       
  9287 soap_outwstring(struct soap *soap, const char *tag, int id, wchar_t *const*p, const char *type, int n) 
       
  9288 { id = soap_element_id(soap, tag, id, *p, NULL, 0, type, n);
       
  9289   if (id < 0
       
  9290    || soap_element_begin_out(soap, tag, id, type)
       
  9291    || soap_wstring_out(soap, *p, 0)
       
  9292    || soap_element_end_out(soap, tag))
       
  9293     return soap->error;
       
  9294   return SOAP_OK;
       
  9295 }
       
  9296 #endif
       
  9297 #endif
       
  9298 
       
  9299 /******************************************************************************/
       
  9300 #ifndef WITH_LEANER
       
  9301 #ifndef PALM_2
       
  9302 SOAP_FMAC1
       
  9303 wchar_t **
       
  9304 SOAP_FMAC2
       
  9305 soap_inwstring(struct soap *soap, const char *tag, wchar_t **p, const char *type, int t, long minlen, long maxlen)
       
  9306 { if (soap_element_begin_in(soap, tag, 1))
       
  9307   { if (!tag || *tag != '-' || soap->error != SOAP_NO_TAG)
       
  9308       return NULL;
       
  9309     soap->error = SOAP_OK;
       
  9310   }
       
  9311   if (!p)
       
  9312     if (!(p = (wchar_t**)soap_malloc(soap, sizeof(wchar_t*))))
       
  9313       return NULL;
       
  9314   if (soap->body)
       
  9315   { *p = soap_wstring_in(soap, 1, minlen, maxlen);
       
  9316     if (!*p || !(wchar_t*)soap_id_enter(soap, soap->id, *p, t, sizeof(wchar_t*), 0, NULL, NULL, NULL))
       
  9317       return NULL;
       
  9318   }
       
  9319   else
       
  9320     *p = NULL;
       
  9321   if (*soap->href)
       
  9322     p = (wchar_t**)soap_id_lookup(soap, soap->href, (void**)p, t, sizeof(wchar_t**), 0);
       
  9323   if (soap->body && soap_element_end_in(soap, tag))
       
  9324     return NULL;
       
  9325   return p;
       
  9326 }
       
  9327 #endif
       
  9328 #endif
       
  9329 
       
  9330 /******************************************************************************/
       
  9331 #ifndef WITH_LEAN
       
  9332 static time_t
       
  9333 soap_timegm(struct tm *T)
       
  9334 {
       
  9335 #if defined(HAVE_TIMEGM)
       
  9336   return timegm(T);
       
  9337 #else
       
  9338   time_t t, g, z;
       
  9339 #ifdef HAVE_GMTIME_R
       
  9340   struct tm tm, *tmp = &tm;
       
  9341 #else
       
  9342   struct tm *tmp;
       
  9343 #endif
       
  9344   t = mktime(T);
       
  9345   if (t == -1)
       
  9346     return -1;
       
  9347 #ifdef HAVE_GMTIME_R
       
  9348   gmtime_r(&t, tmp);
       
  9349 #else
       
  9350   tmp = gmtime(&t);
       
  9351 #endif
       
  9352   tmp->tm_isdst = 0;
       
  9353   g = mktime(tmp);
       
  9354   if (g == -1)
       
  9355     return -1;
       
  9356   z = g - t;
       
  9357   return t - z;
       
  9358 #endif
       
  9359 }
       
  9360 #endif
       
  9361 
       
  9362 /******************************************************************************/
       
  9363 #ifndef WITH_LEAN
       
  9364 SOAP_FMAC1
       
  9365 const char*
       
  9366 SOAP_FMAC2
       
  9367 soap_dateTime2s(struct soap *soap, time_t n)
       
  9368 { struct tm T, *pT = &T;
       
  9369 #if defined(HAVE_GMTIME_R)
       
  9370   if (gmtime_r(&n, pT))
       
  9371     strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT);
       
  9372   /* The following defines were added for VxWorks*/
       
  9373 #elif defined(HAVE_PGMTIME_R)
       
  9374   if (gmtime_r(&n, pT))
       
  9375     strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT);
       
  9376 #elif defined(HAVE_PGMTIME)
       
  9377   if (gmtime(&n, pT))
       
  9378     strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT);
       
  9379 #elif defined(HAVE_GMTIME)
       
  9380   if ((pT = gmtime(&n)))
       
  9381     strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT);
       
  9382 #elif defined(HAVE_GETTIMEOFDAY)
       
  9383   struct timezone tz;
       
  9384   memset((void*)&tz, 0, sizeof(tz));
       
  9385 # if defined(HAVE_LOCALTIME_R)
       
  9386   if (localtime_r(&n, pT))
       
  9387   { struct timeval tv;
       
  9388     gettimeofday(&tv, &tz);
       
  9389     strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
       
  9390     sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -tz.tz_minuteswest/60+(pT->tm_isdst!=0), abs(tz.tz_minuteswest)%60);
       
  9391   }
       
  9392 # else
       
  9393   if ((pT = localtime(&n)))
       
  9394   { struct timeval tv;
       
  9395     gettimeofday(&tv, &tz);
       
  9396     strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
       
  9397     sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -tz.tz_minuteswest/60+(pT->tm_isdst!=0), abs(tz.tz_minuteswest)%60);
       
  9398   }
       
  9399 #endif
       
  9400 #elif defined(HAVE_FTIME)
       
  9401   struct timeb t;
       
  9402   memset((void*)&t, 0, sizeof(t));
       
  9403 # if defined(HAVE_LOCALTIME_R)
       
  9404   if (localtime_r(&n, pT))
       
  9405   { ftime(&t);
       
  9406     strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
       
  9407     sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -t.timezone/60+(pT->tm_isdst!=0), abs(t.timezone)%60);
       
  9408   }
       
  9409   /* The following defines were added for VxWorks*/
       
  9410 # elif defined(HAVE_PLOCALTIME_R)
       
  9411   if (localtime_r(&n, pT))
       
  9412   { strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
       
  9413     sprintf(soap->tmpbuf+strlen(soap->tmpbuf), "%+03d:%02d", t.timezone/60, abs(t.timezone)%60);
       
  9414   }
       
  9415 # else
       
  9416   if ((pT = localtime(&n)))
       
  9417   { ftime(&t);
       
  9418     strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
       
  9419     sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -t.timezone/60+(pT->tm_isdst!=0), abs(t.timezone)%60);
       
  9420   }
       
  9421 # endif
       
  9422 #elif defined(HAVE_LOCALTIME_R)
       
  9423   if (localtime_r(&n, pT))
       
  9424     strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
       
  9425   /* The following defines were added for VxWorks*/
       
  9426 #elif defined(HAVE_PLOCALTIME_R)
       
  9427   if (localtime_r(&n, pT))
       
  9428     strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
       
  9429 #else
       
  9430   if ((pT = localtime(&n)))
       
  9431     strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
       
  9432 #endif
       
  9433   else
       
  9434     strcpy(soap->tmpbuf, "1969-12-31T23:59:59Z");
       
  9435   return soap->tmpbuf;
       
  9436 }
       
  9437 #endif
       
  9438 
       
  9439 /******************************************************************************/
       
  9440 #ifndef WITH_LEAN
       
  9441 SOAP_FMAC1
       
  9442 int
       
  9443 SOAP_FMAC2
       
  9444 soap_outdateTime(struct soap *soap, const char *tag, int id, const time_t *p, const char *type, int n)
       
  9445 { if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
       
  9446    || soap_string_out(soap, soap_dateTime2s(soap, *p), 0))
       
  9447     return soap->error;
       
  9448   return soap_element_end_out(soap, tag);
       
  9449 }
       
  9450 #endif
       
  9451 
       
  9452 /******************************************************************************/
       
  9453 #ifndef WITH_LEAN
       
  9454 SOAP_FMAC1
       
  9455 int
       
  9456 SOAP_FMAC2
       
  9457 soap_s2dateTime(struct soap *soap, const char *s, time_t *p)
       
  9458 { if (s)
       
  9459   { struct tm T;
       
  9460     char zone[16];
       
  9461     const char *t;
       
  9462     memset((void*)&T, 0, sizeof(T));
       
  9463     zone[sizeof(zone)-1] = '\0';
       
  9464     if (strchr(s, '-'))
       
  9465       t = "%d-%d-%dT%d:%d:%d%15s";
       
  9466     else if (strchr(s, ':'))
       
  9467       t = "%4d%2d%2dT%d:%d:%d%15s";
       
  9468     else /* parse non-XSD-standard alternative ISO 8601 format */
       
  9469       t = "%4d%2d%2dT%2d%2d%2d%15s";
       
  9470     sscanf(s, t, &T.tm_year, &T.tm_mon, &T.tm_mday, &T.tm_hour, &T.tm_min, &T.tm_sec, zone);
       
  9471     if (T.tm_year == 1)
       
  9472       T.tm_year = 70;
       
  9473     else
       
  9474       T.tm_year -= 1900;
       
  9475     T.tm_mon--;
       
  9476     if (*zone)
       
  9477     { if (*zone == '.')
       
  9478       { for (s = zone + 1; *s; s++)
       
  9479           if (*s < '0' || *s > '9')
       
  9480             break;
       
  9481       }
       
  9482       else
       
  9483         s = zone;
       
  9484       if (*s == '+' || *s == '-')
       
  9485       { int h = 0, m = 0;
       
  9486         if (s[3] == ':')
       
  9487 	{ sscanf(s, "%d:%d", &h, &m);
       
  9488 	  if (h < 0)
       
  9489 	    m = -m;
       
  9490 	}
       
  9491 	else
       
  9492 	{ m = (int)atol(s);
       
  9493 	  h = m / 100;
       
  9494 	  m = m % 100;
       
  9495 	}
       
  9496         T.tm_hour -= h;
       
  9497         T.tm_min -= m;
       
  9498       }
       
  9499       *p = soap_timegm(&T);
       
  9500     }
       
  9501     else
       
  9502       *p = mktime(&T); /* no time zone: suppose it is localtime? */
       
  9503   }
       
  9504   return soap->error;
       
  9505 }
       
  9506 #endif
       
  9507 
       
  9508 /******************************************************************************/
       
  9509 #ifndef WITH_LEAN
       
  9510 SOAP_FMAC1
       
  9511 time_t *
       
  9512 SOAP_FMAC2
       
  9513 soap_indateTime(struct soap *soap, const char *tag, time_t *p, const char * type, int t)
       
  9514 { if (soap_element_begin_in(soap, tag, 0))
       
  9515     return NULL;
       
  9516   if (*soap->type
       
  9517    && soap_match_tag(soap, soap->type, type)
       
  9518    && soap_match_tag(soap, soap->type, ":dateTime"))
       
  9519   { soap->error = SOAP_TYPE;
       
  9520     soap_revert(soap);
       
  9521     return NULL;
       
  9522   }
       
  9523   p = (time_t*)soap_id_enter(soap, soap->id, p, t, sizeof(time_t), 0, NULL, NULL, NULL);
       
  9524   if (*soap->href)
       
  9525     p = (time_t*)soap_id_forward(soap, soap->href, p, t, 0, sizeof(time_t), 0, NULL);
       
  9526   else if (p)
       
  9527   { if (soap_s2dateTime(soap, soap_value(soap), p))
       
  9528       return NULL;
       
  9529   }
       
  9530   if (soap->body && soap_element_end_in(soap, tag))
       
  9531     return NULL;
       
  9532   return p;
       
  9533 }
       
  9534 #endif
       
  9535 
       
  9536 /******************************************************************************/
       
  9537 #ifndef PALM_2
       
  9538 SOAP_FMAC1
       
  9539 int
       
  9540 SOAP_FMAC2
       
  9541 soap_outliteral(struct soap *soap, const char *tag, char *const*p)
       
  9542 { int i;
       
  9543   const char *t = NULL;
       
  9544   if (tag && *tag != '-')
       
  9545   { if (soap->local_namespaces && (t = strchr(tag, ':')))
       
  9546     { strncpy(soap->tmpbuf, tag, t-tag);
       
  9547       soap->tmpbuf[t-tag] = '\0';
       
  9548       for (i = 0; soap->local_namespaces[i].id; i++)
       
  9549         if (!strcmp(soap->tmpbuf, soap->local_namespaces[i].id))
       
  9550           break;
       
  9551       t++;
       
  9552       sprintf(soap->tmpbuf, "<%s xmlns=\"%s\">", t, soap->local_namespaces[i].ns ? soap->local_namespaces[i].ns : SOAP_STR_EOS);
       
  9553     }
       
  9554     else
       
  9555     { t = tag;
       
  9556       sprintf(soap->tmpbuf, "<%s>", tag);
       
  9557     }
       
  9558     if (soap_send(soap, soap->tmpbuf))
       
  9559       return soap->error;
       
  9560   }
       
  9561   if (p && *p)
       
  9562   { if (soap_send(soap, *p))
       
  9563       return soap->error;
       
  9564   }
       
  9565   if (t)
       
  9566   { sprintf(soap->tmpbuf, "</%s>", t);
       
  9567     return soap_send(soap, soap->tmpbuf);
       
  9568   }
       
  9569   return SOAP_OK;
       
  9570 }
       
  9571 #endif
       
  9572 
       
  9573 /******************************************************************************/
       
  9574 #ifndef PALM_2
       
  9575 SOAP_FMAC1
       
  9576 char **
       
  9577 SOAP_FMAC2
       
  9578 soap_inliteral(struct soap *soap, const char *tag, char **p)
       
  9579 { if (soap_element_begin_in(soap, tag, 1))
       
  9580   { if (soap->error != SOAP_NO_TAG || soap_unget(soap, soap_get(soap)) == SOAP_TT)
       
  9581       return NULL;
       
  9582     soap->error = SOAP_OK;
       
  9583   }
       
  9584   if (!p)
       
  9585     if (!(p = (char**)soap_malloc(soap, sizeof(char*))))
       
  9586       return NULL;
       
  9587   if (soap->null)
       
  9588     *p = NULL;
       
  9589   else
       
  9590     *p = soap_string_in(soap, 0, -1, -1);
       
  9591   if (soap->body && soap_element_end_in(soap, tag))
       
  9592     return NULL;
       
  9593   return p;
       
  9594 }
       
  9595 #endif
       
  9596 
       
  9597 /******************************************************************************/
       
  9598 #ifndef WITH_LEANER
       
  9599 #ifndef PALM_2
       
  9600 SOAP_FMAC1
       
  9601 int
       
  9602 SOAP_FMAC2
       
  9603 soap_outwliteral(struct soap *soap, const char *tag, wchar_t *const*p)
       
  9604 { int i;
       
  9605   const char *t = NULL;
       
  9606   wchar_t c;
       
  9607   const wchar_t *s;
       
  9608   if (tag && *tag != '-')
       
  9609   { if (soap->local_namespaces && (t = strchr(tag, ':')))
       
  9610     { strncpy(soap->tmpbuf, tag, t-tag);
       
  9611       soap->tmpbuf[t-tag] = '\0';
       
  9612       for (i = 0; soap->local_namespaces[i].id; i++)
       
  9613         if (!strcmp(soap->tmpbuf, soap->local_namespaces[i].id))
       
  9614           break;
       
  9615       t++;
       
  9616       sprintf(soap->tmpbuf, "<%s xmlns=\"%s\">", t, soap->local_namespaces[i].ns ? soap->local_namespaces[i].ns : SOAP_STR_EOS);
       
  9617     }
       
  9618     else
       
  9619     { t = tag;
       
  9620       sprintf(soap->tmpbuf, "<%s>", tag);
       
  9621     }
       
  9622     if (soap_send(soap, soap->tmpbuf))
       
  9623       return soap->error;
       
  9624   }
       
  9625   if (p)
       
  9626   { s = *p;
       
  9627     while ((c = *s++))
       
  9628       if (soap_pututf8(soap, (unsigned char)c))
       
  9629         return soap->error;
       
  9630   }
       
  9631   if (t)
       
  9632   { sprintf(soap->tmpbuf, "</%s>", t);
       
  9633     return soap_send(soap, soap->tmpbuf);
       
  9634   }
       
  9635   return SOAP_OK;
       
  9636 }
       
  9637 #endif
       
  9638 #endif
       
  9639 
       
  9640 /******************************************************************************/
       
  9641 #ifndef WITH_LEANER
       
  9642 #ifndef PALM_2
       
  9643 SOAP_FMAC1
       
  9644 wchar_t **
       
  9645 SOAP_FMAC2
       
  9646 soap_inwliteral(struct soap *soap, const char *tag, wchar_t **p)
       
  9647 { if (soap_element_begin_in(soap, tag, 1))
       
  9648   { if (soap->error != SOAP_NO_TAG || soap_unget(soap, soap_get(soap)) == SOAP_TT)
       
  9649       return NULL;
       
  9650     soap->error = SOAP_OK;
       
  9651   }
       
  9652   if (!p)
       
  9653     if (!(p = (wchar_t**)soap_malloc(soap, sizeof(wchar_t*))))
       
  9654       return NULL;
       
  9655   if (soap->null)
       
  9656     *p = NULL;
       
  9657   else
       
  9658     *p = soap_wstring_in(soap, 0, -1, -1);
       
  9659   if (soap->body && soap_element_end_in(soap, tag))
       
  9660     return NULL;
       
  9661   return p;
       
  9662 }
       
  9663 #endif
       
  9664 #endif
       
  9665 
       
  9666 /******************************************************************************/
       
  9667 #ifndef PALM_2
       
  9668 SOAP_FMAC1
       
  9669 const char *
       
  9670 SOAP_FMAC2
       
  9671 soap_token(struct soap *soap)
       
  9672 { register size_t i;
       
  9673   register soap_wchar c = 0;
       
  9674   register char *s = soap->tmpbuf;
       
  9675   if (!soap->body)
       
  9676     return SOAP_STR_EOS;
       
  9677   do c = soap_get(soap);
       
  9678   while (soap_blank(c));
       
  9679   for (i = 0; i < sizeof(soap->tmpbuf) - 1; i++)
       
  9680   { if (c == SOAP_TT || (int)c == EOF || soap_blank(c))
       
  9681       break;
       
  9682     *s++ = (char)c;
       
  9683     c = soap_get(soap);
       
  9684   }
       
  9685   if ((int)c == EOF || c == SOAP_TT)
       
  9686     soap_unget(soap, c);
       
  9687   *s = '\0';
       
  9688   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element content value='%s'\n", soap->tmpbuf));
       
  9689   return soap->tmpbuf; /* return non-null pointer */
       
  9690 }
       
  9691 #endif
       
  9692 
       
  9693 /******************************************************************************/
       
  9694 #ifndef PALM_2
       
  9695 SOAP_FMAC1
       
  9696 const char *
       
  9697 SOAP_FMAC2
       
  9698 soap_value(struct soap *soap)
       
  9699 { register size_t i;
       
  9700   register soap_wchar c = 0;
       
  9701   register char *s = soap->tmpbuf;
       
  9702   if (!soap->body)
       
  9703     return SOAP_STR_EOS;
       
  9704   do c = soap_get(soap);
       
  9705   while (soap_blank(c));
       
  9706   for (i = 0; i < sizeof(soap->tmpbuf) - 1; i++)
       
  9707   { if (c == SOAP_TT || (int)c == EOF)
       
  9708       break;
       
  9709     *s++ = (char)c;
       
  9710     c = soap_get(soap);
       
  9711   }
       
  9712   for (s--; i > 0; i--, s--)
       
  9713     if (!soap_blank(*s))
       
  9714       break;
       
  9715   s[1] = '\0';
       
  9716   if ((int)c == EOF || c == SOAP_TT)
       
  9717     soap_unget(soap, c);
       
  9718   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element content value='%s'\n", soap->tmpbuf));
       
  9719 #ifdef WITH_DOM
       
  9720   if ((soap->mode & SOAP_XML_DOM) && soap->dom)
       
  9721     soap->dom->data = soap_strdup(soap, soap->tmpbuf);
       
  9722 #endif
       
  9723   return soap->tmpbuf; /* return non-null pointer */
       
  9724 }
       
  9725 #endif
       
  9726 
       
  9727 /******************************************************************************/
       
  9728 #if !defined(WITH_LEANER) || !defined(WITH_NOHTTP)
       
  9729 #ifndef PALM_2
       
  9730 SOAP_FMAC1
       
  9731 int
       
  9732 SOAP_FMAC2
       
  9733 soap_getline(struct soap *soap, char *s, int len)
       
  9734 { int i = len;
       
  9735   soap_wchar c = 0;
       
  9736   for (;;)
       
  9737   { while (--i > 0)
       
  9738     { c = soap_getchar(soap);
       
  9739       if (c == '\r' || c == '\n')
       
  9740         break;
       
  9741       if ((int)c == EOF)
       
  9742         return soap->error = SOAP_EOF;
       
  9743       *s++ = (char)c;
       
  9744     }
       
  9745     if (c != '\n')
       
  9746       c = soap_getchar(soap); /* got \r, now get \n */
       
  9747     if (c == '\n')
       
  9748     { *s = '\0';
       
  9749       if (i+1 == len) /* empty line: end of HTTP/MIME header */
       
  9750         break;
       
  9751       c = soap_unget(soap, soap_getchar(soap));
       
  9752       if (c != ' ' && c != '\t') /* HTTP line continuation? */
       
  9753         break;
       
  9754     }
       
  9755     else if ((int)c == EOF)
       
  9756       return soap->error = SOAP_EOF;
       
  9757   }
       
  9758   return SOAP_OK;
       
  9759 }
       
  9760 #endif
       
  9761 #endif
       
  9762 
       
  9763 /******************************************************************************/
       
  9764 #ifndef PALM_1
       
  9765 static size_t
       
  9766 soap_count_attachments(struct soap *soap)
       
  9767 { 
       
  9768 #ifndef WITH_LEANER
       
  9769   register struct soap_multipart *content;
       
  9770   register size_t count = soap->count;
       
  9771   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the message size with attachments, current count=%lu\n", (unsigned long)count));
       
  9772   if ((soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM))
       
  9773   { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the size of DIME attachments\n"));
       
  9774     for (content = soap->dime.first; content; content = content->next)
       
  9775     { count += 12 + ((content->size+3)&(~3));
       
  9776       if (content->id)
       
  9777         count += ((strlen(content->id)+3)&(~3));
       
  9778       if (content->type)
       
  9779         count += ((strlen(content->type)+3)&(~3));
       
  9780       if (content->options)
       
  9781         count += ((((unsigned char)content->options[2] << 8) | ((unsigned char)content->options[3]))+7)&(~3);
       
  9782       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Size of DIME attachment content is %lu bytes\n", (unsigned long)content->size));
       
  9783     }
       
  9784   }
       
  9785   if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary)
       
  9786   { register size_t n = strlen(soap->mime.boundary);
       
  9787     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the size of MIME attachments\n"));
       
  9788     for (content = soap->mime.first; content; content = content->next)
       
  9789     { register const char *s;
       
  9790       /* count \r\n--boundary\r\n */
       
  9791       count += 6 + n;
       
  9792       /* count Content-Type: ...\r\n */
       
  9793       if (content->type)
       
  9794         count += 16 + strlen(content->type);
       
  9795       /* count Content-Transfer-Encoding: ...\r\n */
       
  9796       s = soap_str_code(mime_codes, content->encoding);
       
  9797       if (s)
       
  9798         count += 29 + strlen(s);
       
  9799       /* count Content-ID: ...\r\n */
       
  9800       if (content->id)
       
  9801         count += 14 + strlen(content->id);
       
  9802       /* count Content-Location: ...\r\n */
       
  9803       if (content->location)
       
  9804         count += 20 + strlen(content->location);
       
  9805       /* count Content-Description: ...\r\n */
       
  9806       if (content->description)
       
  9807         count += 23 + strlen(content->location);
       
  9808       /* count \r\n...content */
       
  9809       count += 2 + content->size;
       
  9810       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Size of MIME attachment content is %lu bytes\n", (unsigned long)content->size));
       
  9811     }
       
  9812     /* count \r\n--boundary-- */
       
  9813     count += 6 + n;
       
  9814   }
       
  9815   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "New count is %lu bytes\n", (unsigned long)count));
       
  9816   return count;
       
  9817 #else
       
  9818   return soap->count;
       
  9819 #endif
       
  9820 }
       
  9821 #endif
       
  9822 
       
  9823 /******************************************************************************/
       
  9824 #ifndef WITH_LEANER
       
  9825 #ifndef PALM_1
       
  9826 static int
       
  9827 soap_putdimefield(struct soap *soap, const char *s, size_t n)
       
  9828 { if (soap_send_raw(soap, s, n))
       
  9829     return soap->error;
       
  9830   return soap_send_raw(soap, SOAP_STR_PADDING, -(long)n&3);
       
  9831 }
       
  9832 #endif
       
  9833 #endif
       
  9834 
       
  9835 /******************************************************************************/
       
  9836 #ifndef WITH_LEANER
       
  9837 #ifndef PALM_1
       
  9838 SOAP_FMAC1
       
  9839 char *
       
  9840 SOAP_FMAC2
       
  9841 soap_dime_option(struct soap *soap, unsigned short optype, const char *option)
       
  9842 { size_t n;
       
  9843   char *s = NULL;
       
  9844   if (option)
       
  9845   { n = strlen(option);
       
  9846     s = (char*)soap_malloc(soap, n + 5);
       
  9847     if (s)
       
  9848     { s[0] = optype >> 8;
       
  9849       s[1] = optype & 0xFF;
       
  9850       s[2] = n >> 8;
       
  9851       s[3] = n & 0xFF;
       
  9852       strcpy(s + 4, option);
       
  9853     }
       
  9854   }
       
  9855   return s;
       
  9856 }
       
  9857 #endif
       
  9858 #endif
       
  9859 
       
  9860 /******************************************************************************/
       
  9861 #ifndef WITH_LEANER
       
  9862 #ifndef PALM_1
       
  9863 SOAP_FMAC1
       
  9864 int
       
  9865 SOAP_FMAC2
       
  9866 soap_putdimehdr(struct soap *soap)
       
  9867 { unsigned char tmp[12];
       
  9868   size_t optlen = 0, idlen = 0, typelen = 0;
       
  9869   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Put DIME header id='%s'\n", soap->dime.id?soap->dime.id:""));
       
  9870   if (soap->dime.options)
       
  9871     optlen = (((unsigned char)soap->dime.options[2] << 8) | ((unsigned char)soap->dime.options[3])) + 4;
       
  9872   if (soap->dime.id)
       
  9873     idlen = strlen(soap->dime.id);
       
  9874   if (soap->dime.type)
       
  9875     typelen = strlen(soap->dime.type);
       
  9876   tmp[0] = SOAP_DIME_VERSION | (soap->dime.flags & 0x7);
       
  9877   tmp[1] = soap->dime.flags & 0xF0;
       
  9878   tmp[2] = optlen >> 8;
       
  9879   tmp[3] = optlen & 0xFF;
       
  9880   tmp[4] = idlen >> 8;
       
  9881   tmp[5] = idlen & 0xFF;
       
  9882   tmp[6] = typelen >> 8;
       
  9883   tmp[7] = typelen & 0xFF;
       
  9884   tmp[8] = soap->dime.size >> 24;
       
  9885   tmp[9] = (soap->dime.size >> 16) & 0xFF;
       
  9886   tmp[10] = (soap->dime.size >> 8) & 0xFF;
       
  9887   tmp[11] = soap->dime.size & 0xFF;
       
  9888   if (soap_send_raw(soap, (char*)tmp, 12)
       
  9889    || soap_putdimefield(soap, soap->dime.options, optlen)
       
  9890    || soap_putdimefield(soap, soap->dime.id, idlen)
       
  9891    || soap_putdimefield(soap, soap->dime.type, typelen))
       
  9892     return soap->error;
       
  9893   return SOAP_OK;
       
  9894 }
       
  9895 #endif
       
  9896 #endif
       
  9897 
       
  9898 /******************************************************************************/
       
  9899 #ifndef WITH_LEANER
       
  9900 #ifndef PALM_1
       
  9901 SOAP_FMAC1
       
  9902 int
       
  9903 SOAP_FMAC2
       
  9904 soap_putdime(struct soap *soap)
       
  9905 { struct soap_multipart *content;
       
  9906   if (!(soap->mode & SOAP_ENC_DIME))
       
  9907     return SOAP_OK;
       
  9908   for (content = soap->dime.first; content; content = content->next)
       
  9909   { void *handle;
       
  9910     soap->dime.size = content->size;
       
  9911     soap->dime.id = content->id;
       
  9912     soap->dime.type = content->type;
       
  9913     soap->dime.options = content->options;
       
  9914     soap->dime.flags = SOAP_DIME_VERSION | SOAP_DIME_MEDIA;
       
  9915     if (soap->fdimereadopen && ((handle = soap->fdimereadopen(soap, (void*)content->ptr, content->id, content->type, content->options)) || soap->error))
       
  9916     { size_t size = content->size;
       
  9917       if (!handle)
       
  9918       { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimereadopen failed\n"));
       
  9919         return soap->error;
       
  9920       }
       
  9921       if (!content->size && ((soap->mode & SOAP_ENC_XML) || (soap->mode & SOAP_IO) == SOAP_IO_CHUNK || (soap->mode & SOAP_IO) == SOAP_IO_STORE))
       
  9922       { size_t chunksize = sizeof(soap->tmpbuf);
       
  9923         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunked streaming DIME\n"));
       
  9924         do 
       
  9925         { size = soap->fdimeread(soap, handle, soap->tmpbuf, chunksize);
       
  9926           DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimeread returned %lu bytes\n", (unsigned long)size));
       
  9927           if (size < chunksize)
       
  9928  	  { soap->dime.flags &= ~SOAP_DIME_CF;
       
  9929             if (!content->next)
       
  9930               soap->dime.flags |= SOAP_DIME_ME;
       
  9931 	  }
       
  9932           else
       
  9933             soap->dime.flags |= SOAP_DIME_CF;
       
  9934 	  soap->dime.size = size;
       
  9935           if (soap_putdimehdr(soap)
       
  9936 	   || soap_putdimefield(soap, soap->tmpbuf, size))
       
  9937             break;
       
  9938           if (soap->dime.id)
       
  9939  	  { soap->dime.flags &= ~(SOAP_DIME_MB | SOAP_DIME_MEDIA);
       
  9940             soap->dime.id = NULL;
       
  9941             soap->dime.type = NULL;
       
  9942             soap->dime.options = NULL;
       
  9943           }  
       
  9944         } while (size >= chunksize);
       
  9945       }
       
  9946       else
       
  9947       { if (!content->next)
       
  9948           soap->dime.flags |= SOAP_DIME_ME;
       
  9949         if (soap_putdimehdr(soap))
       
  9950           return soap->error;
       
  9951         do
       
  9952         { size_t bufsize;
       
  9953 	  if (size < sizeof(soap->tmpbuf))
       
  9954             bufsize = size;
       
  9955           else
       
  9956             bufsize = sizeof(soap->tmpbuf);
       
  9957           if (!(bufsize = soap->fdimeread(soap, handle, soap->tmpbuf, bufsize)))
       
  9958           { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimeread failed: insufficient data (%lu bytes remaining from %lu bytes)\n", (unsigned long)size, (unsigned long)soap->dime.size));
       
  9959             soap->error = SOAP_EOF;
       
  9960 	    break;
       
  9961           }
       
  9962           if (soap_send_raw(soap, soap->tmpbuf, bufsize))
       
  9963             break;
       
  9964           size -= bufsize;
       
  9965         } while (size);
       
  9966         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimereadclose\n"));
       
  9967         soap_send_raw(soap, SOAP_STR_PADDING, -(long)soap->dime.size&3);
       
  9968       }
       
  9969       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimereadclose\n"));
       
  9970       if (soap->fdimereadclose)
       
  9971         soap->fdimereadclose(soap, handle);
       
  9972     }
       
  9973     else
       
  9974     { if (!content->next)
       
  9975         soap->dime.flags |= SOAP_DIME_ME;
       
  9976       if (soap_putdimehdr(soap)
       
  9977        || soap_putdimefield(soap, (char*)content->ptr, content->size))
       
  9978         return soap->error;
       
  9979     }
       
  9980   }
       
  9981   return SOAP_OK;
       
  9982 }
       
  9983 #endif
       
  9984 #endif
       
  9985 
       
  9986 /******************************************************************************/
       
  9987 #ifndef WITH_LEANER
       
  9988 #ifndef PALM_1
       
  9989 static char *
       
  9990 soap_getdimefield(struct soap *soap, size_t n)
       
  9991 { register soap_wchar c;
       
  9992   register int i;
       
  9993   register char *s;
       
  9994   char *p = NULL;
       
  9995   if (n)
       
  9996   { p = (char*)soap_malloc(soap, n + 1);
       
  9997     if (p)
       
  9998     { s = p;
       
  9999       for (i = n; i > 0; i--)
       
 10000       { if ((int)(c = soap_get1(soap)) == EOF)
       
 10001         { soap->error = SOAP_EOF;
       
 10002           return NULL;
       
 10003         }
       
 10004         *s++ = (char)c;
       
 10005       }
       
 10006       *s = '\0';
       
 10007       if ((soap->error = soap_move(soap, -(long)n&3)))
       
 10008         return NULL;
       
 10009     }
       
 10010     else
       
 10011       soap->error = SOAP_EOM;
       
 10012   }
       
 10013   return p;
       
 10014 }
       
 10015 #endif
       
 10016 #endif
       
 10017 
       
 10018 /******************************************************************************/
       
 10019 #ifndef WITH_LEANER
       
 10020 #ifndef PALM_1
       
 10021 SOAP_FMAC1
       
 10022 int
       
 10023 SOAP_FMAC2
       
 10024 soap_getdimehdr(struct soap *soap)
       
 10025 { register soap_wchar c;
       
 10026   register char *s;
       
 10027   register int i;
       
 10028   unsigned char tmp[12];
       
 10029   size_t optlen, idlen, typelen;
       
 10030   if (!(soap->mode & SOAP_ENC_DIME))
       
 10031     return soap->error = SOAP_DIME_END;
       
 10032   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME header\n"));
       
 10033   if (soap->dime.buflen || soap->dime.chunksize)
       
 10034   { if (soap_move(soap, (long)(soap->dime.size - soap_tell(soap))))
       
 10035       return soap->error = SOAP_EOF;
       
 10036     soap_unget(soap, soap_getchar(soap)); /* skip padding and get hdr */
       
 10037     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "... From chunked\n"));
       
 10038     return SOAP_OK;
       
 10039   }
       
 10040   s = (char*)tmp;
       
 10041   for (i = 12; i > 0; i--)
       
 10042   { if ((int)(c = soap_getchar(soap)) == EOF)
       
 10043       return soap->error = SOAP_EOF;
       
 10044     *s++ = (char)c;
       
 10045   }
       
 10046   if ((tmp[0] & 0xF8) != SOAP_DIME_VERSION)
       
 10047     return soap->error = SOAP_DIME_MISMATCH;
       
 10048   soap->dime.flags = (tmp[0] & 0x7) | (tmp[1] & 0xF0);
       
 10049   optlen = (tmp[2] << 8) | tmp[3];
       
 10050   idlen = (tmp[4] << 8) | tmp[5];
       
 10051   typelen = (tmp[6] << 8) | tmp[7];
       
 10052   soap->dime.size = (tmp[8] << 24) | (tmp[9] << 16) | (tmp[10] << 8) | tmp[11];
       
 10053   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME size=%lu flags=0x%X\n", (unsigned long)soap->dime.size, soap->dime.flags));
       
 10054   if (!(soap->dime.options = soap_getdimefield(soap, optlen)) && soap->error)
       
 10055     return soap->error;
       
 10056   if (!(soap->dime.id = soap_getdimefield(soap, idlen)) && soap->error)
       
 10057     return soap->error;
       
 10058   if (!(soap->dime.type = soap_getdimefield(soap, typelen)) && soap->error)
       
 10059     return soap->error;
       
 10060   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:""));
       
 10061   if (soap->dime.flags & SOAP_DIME_ME)
       
 10062     soap->mode &= ~SOAP_ENC_DIME;
       
 10063   return SOAP_OK;
       
 10064 }
       
 10065 #endif
       
 10066 #endif
       
 10067 
       
 10068 /******************************************************************************/
       
 10069 #ifndef WITH_LEANER
       
 10070 #ifndef PALM_1
       
 10071 SOAP_FMAC1
       
 10072 int
       
 10073 SOAP_FMAC2
       
 10074 soap_getdime(struct soap *soap)
       
 10075 { while (soap->dime.flags & SOAP_DIME_CF)
       
 10076   { if (soap_getdimehdr(soap))
       
 10077       return soap->error;
       
 10078     if (soap_move(soap, soap->dime.size))
       
 10079       return soap->error = SOAP_EOF;
       
 10080   }
       
 10081   if (soap_move(soap, ((soap->dime.size+3)&(~3))-soap_tell(soap)))
       
 10082     return soap->error = SOAP_EOF;
       
 10083   for (;;)
       
 10084   { register struct soap_multipart *content;
       
 10085     if (soap_getdimehdr(soap))
       
 10086       break;
       
 10087     if (soap->fdimewriteopen && ((soap->dime.ptr = (char*)soap->fdimewriteopen(soap, soap->dime.id, soap->dime.type, soap->dime.options)) || soap->error))
       
 10088     { const char *id, *type, *options;
       
 10089       size_t size, n;
       
 10090       if (!soap->dime.ptr)
       
 10091         return soap->error;
       
 10092       id = soap->dime.id;
       
 10093       type = soap->dime.type;
       
 10094       options = soap->dime.options;
       
 10095       for (;;)
       
 10096       { size = soap->dime.size;
       
 10097         for (;;)
       
 10098         { n = soap->buflen - soap->bufidx;
       
 10099           if (size < n)
       
 10100             n = size;
       
 10101           if ((soap->error = soap->fdimewrite(soap, (void*)soap->dime.ptr, soap->buf + soap->bufidx, n)))
       
 10102             break;
       
 10103 	  size -= n;
       
 10104 	  if (!size)
       
 10105 	  { soap->bufidx += n;
       
 10106 	    break;
       
 10107 	  }
       
 10108 	  if (soap_recv(soap))
       
 10109           { soap->error = SOAP_EOF;
       
 10110 	    goto end;
       
 10111           }
       
 10112         }
       
 10113         if (soap_move(soap, -(long)soap->dime.size&3))
       
 10114         { soap->error = SOAP_EOF;
       
 10115 	  break;
       
 10116         }
       
 10117         if (!(soap->dime.flags & SOAP_DIME_CF))
       
 10118           break;
       
 10119         if (soap_getdimehdr(soap))
       
 10120           break;
       
 10121       }
       
 10122 end:
       
 10123       if (soap->fdimewriteclose)
       
 10124         soap->fdimewriteclose(soap, (void*)soap->dime.ptr);
       
 10125       soap->dime.size = 0;
       
 10126       soap->dime.id = id;
       
 10127       soap->dime.type = type;
       
 10128       soap->dime.options = options;
       
 10129     }
       
 10130     else if (soap->dime.flags & SOAP_DIME_CF)
       
 10131     { const char *id, *type, *options;
       
 10132       register soap_wchar c;
       
 10133       register char *s;
       
 10134       register int i;
       
 10135       id = soap->dime.id;
       
 10136       type = soap->dime.type;
       
 10137       options = soap->dime.options;
       
 10138       if (soap_new_block(soap))
       
 10139         return SOAP_EOM;
       
 10140       for (;;)
       
 10141       { s = (char*)soap_push_block(soap, soap->dime.size);
       
 10142         if (!s)
       
 10143           return soap->error = SOAP_EOM;
       
 10144         for (i = soap->dime.size; i > 0; i--)
       
 10145         { if ((int)(c = soap_get1(soap)) == EOF)
       
 10146             return soap->error = SOAP_EOF;
       
 10147           *s++ = (char)c;
       
 10148         }
       
 10149         if (soap_move(soap, -(long)soap->dime.size&3))
       
 10150           return soap->error = SOAP_EOF;
       
 10151         if (!(soap->dime.flags & SOAP_DIME_CF))
       
 10152           break;
       
 10153         if (soap_getdimehdr(soap))
       
 10154           return soap->error;
       
 10155       }
       
 10156       soap->dime.size = soap->blist->size++; /* allocate one more for '\0' */
       
 10157       if (!(soap->dime.ptr = soap_save_block(soap, NULL, 0)))
       
 10158         return soap->error;
       
 10159       soap->dime.ptr[soap->dime.size] = '\0'; /* force 0-terminated */
       
 10160       soap->dime.id = id;
       
 10161       soap->dime.type = type;
       
 10162       soap->dime.options = options;
       
 10163     }
       
 10164     else
       
 10165       soap->dime.ptr = soap_getdimefield(soap, soap->dime.size);
       
 10166     content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, soap->dime.ptr, soap->dime.size);
       
 10167     if (!content)
       
 10168       return soap->error = SOAP_EOM;
       
 10169     content->id = soap->dime.id;
       
 10170     content->type = soap->dime.type;
       
 10171     content->options = soap->dime.options;
       
 10172     soap_resolve_attachment(soap, content);
       
 10173     if (soap->error)
       
 10174       return soap->error;
       
 10175   }
       
 10176   if (soap->error != SOAP_DIME_END)
       
 10177     return soap->error;
       
 10178   return soap->error = SOAP_OK;
       
 10179 }
       
 10180 #endif
       
 10181 #endif
       
 10182 
       
 10183 /******************************************************************************/
       
 10184 #ifndef WITH_LEANER
       
 10185 #ifndef PALM_1
       
 10186 SOAP_FMAC1
       
 10187 int
       
 10188 SOAP_FMAC2
       
 10189 soap_getmimehdr(struct soap *soap)
       
 10190 { struct soap_multipart *content;
       
 10191   do
       
 10192   { if (soap_getline(soap, soap->msgbuf, sizeof(soap->msgbuf)))
       
 10193       return soap->error;
       
 10194   }
       
 10195   while (!*soap->msgbuf);
       
 10196   if (soap->msgbuf[0] == '-' && soap->msgbuf[1] == '-')
       
 10197   { char *s = soap->msgbuf + strlen(soap->msgbuf) - 1;
       
 10198     /* remove white space */
       
 10199     while (soap_blank(*s))
       
 10200       s--;
       
 10201     s[1] = '\0';
       
 10202     if (soap->mime.boundary)
       
 10203     { if (strcmp(soap->msgbuf + 2, soap->mime.boundary))
       
 10204         return soap->error = SOAP_MIME_ERROR;
       
 10205     }
       
 10206     else
       
 10207       soap->mime.boundary = soap_strdup(soap, soap->msgbuf + 2);
       
 10208     if (soap_getline(soap, soap->msgbuf, sizeof(soap->msgbuf)))
       
 10209       return soap->error;
       
 10210   }
       
 10211   if (soap_set_mime_attachment(soap, NULL, 0, SOAP_MIME_NONE, NULL, NULL, NULL, NULL))
       
 10212     return soap->error = SOAP_EOM;
       
 10213   content = soap->mime.last;
       
 10214   for (;;)
       
 10215   { register char *key = soap->msgbuf;
       
 10216     register char *val;
       
 10217     if (!*key)
       
 10218       break;
       
 10219     DBGLOG(TEST,SOAP_MESSAGE(fdebug, "MIME header: %s\n", key));
       
 10220     val = strchr(soap->msgbuf, ':');
       
 10221     if (val)
       
 10222     { *val = '\0';
       
 10223       do val++;
       
 10224       while (*val && *val <= 32);
       
 10225       if (!soap_tag_cmp(key, "Content-ID"))
       
 10226         content->id = soap_strdup(soap, val);
       
 10227       else if (!soap_tag_cmp(key, "Content-Location"))
       
 10228         content->location = soap_strdup(soap, val);
       
 10229       else if (!soap_tag_cmp(key, "Content-Disposition"))
       
 10230         content->id = soap_strdup(soap, soap_get_header_attribute(soap, val, "name"));
       
 10231       else if (!soap_tag_cmp(key, "Content-Type"))
       
 10232         content->type = soap_strdup(soap, val);
       
 10233       else if (!soap_tag_cmp(key, "Content-Description"))
       
 10234         content->description = soap_strdup(soap, val);
       
 10235       else if (!soap_tag_cmp(key, "Content-Transfer-Encoding"))
       
 10236         content->encoding = (enum soap_mime_encoding)soap_int_code(mime_codes, val, (long)SOAP_MIME_NONE);
       
 10237     }
       
 10238     if (soap_getline(soap, key, sizeof(soap->msgbuf)))
       
 10239       return soap->error;
       
 10240   }
       
 10241   return SOAP_OK;
       
 10242 }
       
 10243 #endif
       
 10244 #endif
       
 10245 
       
 10246 /******************************************************************************/
       
 10247 #ifndef WITH_LEANER
       
 10248 #ifndef PALM_1
       
 10249 SOAP_FMAC1
       
 10250 int
       
 10251 SOAP_FMAC2
       
 10252 soap_getmime(struct soap *soap)
       
 10253 { register soap_wchar c = 0;
       
 10254   if (!soap->mime.last)
       
 10255     return SOAP_OK;
       
 10256   for (;;)
       
 10257   { register size_t i, m = 0;
       
 10258     register char *s, *t = NULL;
       
 10259     struct soap_multipart *content = soap->mime.last;
       
 10260     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Parsing MIME content id=%s type=%s\n", content->id?content->id:"", content->type?content->type:""));
       
 10261     if (soap_new_block(soap))
       
 10262       return soap->error = SOAP_EOM;
       
 10263     for (;;)
       
 10264     { register short flag = 0;
       
 10265       if (!(s = (char*)soap_push_block(soap, SOAP_BLKLEN)))
       
 10266         return soap->error = SOAP_EOM;
       
 10267       for (i = 0; i < SOAP_BLKLEN; i++)
       
 10268       { if (m > 0)
       
 10269         { flag = (*t == '\r');
       
 10270 	  *s++ = *t++;
       
 10271 	  m--;
       
 10272 	}
       
 10273 	else
       
 10274         { if (!flag)
       
 10275 	  { c = soap_get1(soap);
       
 10276 	    if ((int)c == EOF)
       
 10277 	      return soap->error = SOAP_EOF;
       
 10278 	  }
       
 10279 	  if (flag || c == '\r')
       
 10280 	  { t = soap->tmpbuf;
       
 10281 	    memset(t, 0, sizeof(soap->tmpbuf));
       
 10282             strcpy(t, "\n--");
       
 10283             if (soap->mime.boundary)
       
 10284 	      strncat(t, soap->mime.boundary, sizeof(soap->tmpbuf)-4);
       
 10285 	    do c = soap_getchar(soap);
       
 10286 	    while (c == *t++);
       
 10287 	    if ((int)c == EOF)
       
 10288 	      return soap->error = SOAP_EOF;
       
 10289 	    if (!*--t)
       
 10290 	      goto end;
       
 10291 	    *t = (char)c;
       
 10292 	    m = t - soap->tmpbuf + 1;
       
 10293 	    t = soap->tmpbuf;
       
 10294 	    c = '\r';
       
 10295 	  }
       
 10296 	  *s++ = (char)c;
       
 10297         }
       
 10298       }
       
 10299     }
       
 10300 end:
       
 10301     *s = '\0'; /* force 0-terminated */
       
 10302     content->size = soap_size_block(soap, i+1)-1;
       
 10303     content->ptr = soap_save_block(soap, NULL, 0);
       
 10304     soap_resolve_attachment(soap, content);
       
 10305     if (c == '-' && soap_getchar(soap) == '-')
       
 10306       break;
       
 10307     while (c != '\r' && (int)c != EOF && soap_blank(c))
       
 10308       c = soap_getchar(soap);
       
 10309     if (c != '\r' || soap_getchar(soap) != '\n')
       
 10310       return soap->error = SOAP_MIME_ERROR;
       
 10311     if (soap_getmimehdr(soap))
       
 10312       return soap->error;
       
 10313   }
       
 10314   /*
       
 10315   do c = soap_getchar(soap);
       
 10316   while ((int)c != EOF && c != '\r' && c != '\n');
       
 10317   if ((int)c != '\r' || soap_getchar(soap) != '\n')
       
 10318     return soap->error = SOAP_MIME_ERROR;
       
 10319   */
       
 10320   return SOAP_OK;
       
 10321 }
       
 10322 #endif
       
 10323 #endif
       
 10324 
       
 10325 /******************************************************************************/
       
 10326 #ifndef WITH_LEANER
       
 10327 #ifndef PALM_1
       
 10328 static int
       
 10329 soap_match_cid(const char *s, const char *t)
       
 10330 { register size_t n;
       
 10331   if (!s)
       
 10332     return 1;
       
 10333   if (!strcmp(s, t))
       
 10334     return 0;
       
 10335   if (!strncmp(s, "cid:", 4))
       
 10336     s += 4;
       
 10337   n = strlen(t);
       
 10338   if (*t == '<')
       
 10339   { t++;
       
 10340     n -= 2;
       
 10341   }
       
 10342   if (!strncmp(s, t, n) && !s[n])
       
 10343     return 0;
       
 10344   return 1;
       
 10345 }
       
 10346 #endif
       
 10347 #endif
       
 10348 
       
 10349 /******************************************************************************/
       
 10350 #ifndef WITH_LEANER
       
 10351 #ifndef PALM_1
       
 10352 static void
       
 10353 soap_resolve_attachment(struct soap *soap, struct soap_multipart *content)
       
 10354 { if (content->id)
       
 10355   { register struct soap_xlist **xp = &soap->xlist;
       
 10356     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving attachment data for id=%s\n", content->id));
       
 10357     while (*xp)
       
 10358     { register struct soap_xlist *xq = *xp;
       
 10359       if (!soap_match_cid(xq->id, content->id))
       
 10360       { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Found matching attachment %s for content id=%s\n", xq->id, content->id));
       
 10361 	*xp = xq->next;
       
 10362         *xq->ptr = (unsigned char*)content->ptr;
       
 10363         *xq->size = (int)content->size;
       
 10364         *xq->type = (char*)content->type;
       
 10365 	if (content->options)
       
 10366           *xq->options = (char*)content->options;
       
 10367         else
       
 10368           *xq->options = (char*)content->description;
       
 10369 	SOAP_FREE(soap, xq);
       
 10370       }
       
 10371       else
       
 10372         xp = &(*xp)->next;
       
 10373     }
       
 10374   }
       
 10375 }
       
 10376 #endif
       
 10377 #endif
       
 10378 
       
 10379 /******************************************************************************/
       
 10380 #ifndef WITH_LEANER
       
 10381 #ifndef PALM_1
       
 10382 SOAP_FMAC1
       
 10383 int
       
 10384 SOAP_FMAC2
       
 10385 soap_putmimehdr(struct soap *soap, struct soap_multipart *content)
       
 10386 { const char *s;
       
 10387   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "MIME attachment type=%s\n", content->type?content->type:""));
       
 10388   if (soap_send3(soap, "\r\n--", soap->mime.boundary, "\r\n"))
       
 10389     return soap->error;
       
 10390   if (content->type && soap_send3(soap, "Content-Type: ", content->type, "\r\n"))
       
 10391     return soap->error;
       
 10392   s = soap_str_code(mime_codes, content->encoding);
       
 10393   if (s && soap_send3(soap, "Content-Transfer-Encoding: ", s, "\r\n"))
       
 10394     return soap->error;
       
 10395   if (content->id && soap_send3(soap, "Content-ID: ", content->id, "\r\n"))
       
 10396     return soap->error;
       
 10397   if (content->location && soap_send3(soap, "Content-Location: ", content->location, "\r\n"))
       
 10398     return soap->error;
       
 10399   if (content->description && soap_send3(soap, "Content-Description: ", content->description, "\r\n"))
       
 10400     return soap->error;
       
 10401   return soap_send_raw(soap, "\r\n", 2);
       
 10402 }
       
 10403 #endif
       
 10404 #endif
       
 10405 
       
 10406 /******************************************************************************/
       
 10407 #ifndef WITH_LEANER
       
 10408 #ifndef PALM_1
       
 10409 SOAP_FMAC1
       
 10410 int
       
 10411 SOAP_FMAC2
       
 10412 soap_putmime(struct soap *soap)
       
 10413 { struct soap_multipart *content;
       
 10414   if (!(soap->mode & SOAP_ENC_MIME) || !soap->mime.boundary)
       
 10415     return SOAP_OK;
       
 10416   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Sending MIME attachments\n"));
       
 10417   for (content = soap->mime.first; content; content = content->next)
       
 10418     if (soap_putmimehdr(soap, content)
       
 10419      || soap_send_raw(soap, content->ptr, content->size))
       
 10420       return soap->error;
       
 10421   return soap_send3(soap, "\r\n--", soap->mime.boundary, "--");
       
 10422 }
       
 10423 #endif
       
 10424 #endif
       
 10425 
       
 10426 /******************************************************************************/
       
 10427 #ifndef WITH_LEANER
       
 10428 #ifndef PALM_1
       
 10429 SOAP_FMAC1
       
 10430 void
       
 10431 SOAP_FMAC2
       
 10432 soap_set_dime(struct soap *soap)
       
 10433 { soap->omode |= SOAP_ENC_DIME;
       
 10434   soap->dime.first = NULL;
       
 10435   soap->dime.last = NULL;
       
 10436 }
       
 10437 #endif
       
 10438 #endif
       
 10439 
       
 10440 /******************************************************************************/
       
 10441 #ifndef WITH_LEANER
       
 10442 #ifndef PALM_1
       
 10443 SOAP_FMAC1
       
 10444 void
       
 10445 SOAP_FMAC2
       
 10446 soap_set_mime(struct soap *soap, const char *boundary, const char *start)
       
 10447 { soap->omode |= SOAP_ENC_MIME;
       
 10448   soap->mime.first = NULL;
       
 10449   soap->mime.last = NULL;
       
 10450   soap->mime.boundary = soap_strdup(soap, boundary);
       
 10451   soap->mime.start = soap_strdup(soap, start);
       
 10452 }
       
 10453 #endif
       
 10454 #endif
       
 10455 
       
 10456 /******************************************************************************/
       
 10457 #ifndef WITH_LEANER
       
 10458 #ifndef PALM_1
       
 10459 SOAP_FMAC1
       
 10460 void
       
 10461 SOAP_FMAC2
       
 10462 soap_clr_dime(struct soap *soap)
       
 10463 { soap->omode &= ~SOAP_ENC_DIME;
       
 10464   soap->dime.first = NULL;
       
 10465   soap->dime.last = NULL;
       
 10466 }
       
 10467 #endif
       
 10468 #endif
       
 10469 
       
 10470 /******************************************************************************/
       
 10471 #ifndef WITH_LEANER
       
 10472 #ifndef PALM_1
       
 10473 SOAP_FMAC1
       
 10474 void
       
 10475 SOAP_FMAC2
       
 10476 soap_clr_mime(struct soap *soap)
       
 10477 { soap->omode &= ~SOAP_ENC_MIME;
       
 10478   soap->mime.first = NULL;
       
 10479   soap->mime.last = NULL;
       
 10480   soap->mime.boundary = NULL;
       
 10481   soap->mime.start = NULL;
       
 10482 }
       
 10483 #endif
       
 10484 #endif
       
 10485 
       
 10486 /******************************************************************************/
       
 10487 #ifndef WITH_LEANER
       
 10488 #ifndef PALM_1
       
 10489 static struct soap_multipart*
       
 10490 soap_new_multipart(struct soap *soap, struct soap_multipart **first, struct soap_multipart **last, char *ptr, size_t size)
       
 10491 { struct soap_multipart *content;
       
 10492   content = (struct soap_multipart*)soap_malloc(soap, sizeof(struct soap_multipart));
       
 10493   if (content)
       
 10494   { content->next = NULL;
       
 10495     content->ptr = ptr;
       
 10496     content->size = size;
       
 10497     content->id = NULL;
       
 10498     content->type = NULL;
       
 10499     content->options = NULL;
       
 10500     content->encoding = SOAP_MIME_NONE;
       
 10501     content->location = NULL;
       
 10502     content->description = NULL;
       
 10503     if (!*first)
       
 10504       *first = content;
       
 10505     if (*last)
       
 10506       (*last)->next = content;
       
 10507     *last = content;
       
 10508   }
       
 10509   return content;
       
 10510 }
       
 10511 #endif
       
 10512 #endif
       
 10513 
       
 10514 /******************************************************************************/
       
 10515 #ifndef WITH_LEANER
       
 10516 #ifndef PALM_1
       
 10517 SOAP_FMAC1
       
 10518 int
       
 10519 SOAP_FMAC2
       
 10520 soap_set_dime_attachment(struct soap *soap, char *ptr, size_t size, const char *type, const char *id, unsigned short optype, const char *option)
       
 10521 { struct soap_multipart *content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, ptr, size);
       
 10522   if (!content)
       
 10523     return SOAP_EOM;
       
 10524   content->id = soap_strdup(soap, id);
       
 10525   content->type = soap_strdup(soap, type);
       
 10526   content->options = soap_dime_option(soap, optype, option);
       
 10527   return SOAP_OK;
       
 10528 }
       
 10529 #endif
       
 10530 #endif
       
 10531 
       
 10532 /******************************************************************************/
       
 10533 #ifndef WITH_LEANER
       
 10534 #ifndef PALM_1
       
 10535 SOAP_FMAC1
       
 10536 int
       
 10537 SOAP_FMAC2
       
 10538 soap_set_mime_attachment(struct soap *soap, char *ptr, size_t size, enum soap_mime_encoding encoding, const char *type, const char *id, const char *location, const char *description)
       
 10539 { struct soap_multipart *content = soap_new_multipart(soap, &soap->mime.first, &soap->mime.last, ptr, size);
       
 10540   if (!content)
       
 10541     return SOAP_EOM;
       
 10542   content->id = soap_strdup(soap, id);
       
 10543   content->type = soap_strdup(soap, type);
       
 10544   content->encoding = encoding;
       
 10545   content->location = soap_strdup(soap, location);
       
 10546   content->description = soap_strdup(soap, description);
       
 10547   return SOAP_OK;
       
 10548 }
       
 10549 #endif
       
 10550 #endif
       
 10551 
       
 10552 /******************************************************************************/
       
 10553 #ifndef WITH_LEANER
       
 10554 #ifndef PALM_1
       
 10555 SOAP_FMAC1
       
 10556 struct soap_multipart*
       
 10557 SOAP_FMAC2
       
 10558 soap_next_multipart(struct soap_multipart *content)
       
 10559 { if (content)
       
 10560     return content->next;
       
 10561   return NULL;
       
 10562 }
       
 10563 #endif
       
 10564 #endif
       
 10565 
       
 10566 /******************************************************************************/
       
 10567 #ifndef WITH_LEANER
       
 10568 #ifndef PALM_1
       
 10569 static void
       
 10570 soap_select_mime_boundary(struct soap *soap)
       
 10571 { while (!soap->mime.boundary || soap_valid_mime_boundary(soap))
       
 10572   { register char *s = soap->mime.boundary;
       
 10573     register size_t n = 0;
       
 10574     if (s)
       
 10575       n = strlen(s);
       
 10576     if (n < 16)
       
 10577     { n = 72;
       
 10578       s = soap->mime.boundary = (char*)soap_malloc(soap, n + 1);
       
 10579       if (!s)
       
 10580         return;
       
 10581     }
       
 10582     strcpy(s, "<>");
       
 10583     s += 2;
       
 10584     n -= 4;
       
 10585     while (n)
       
 10586     { *s++ = soap_base64o[soap_random & 0x3F];
       
 10587       n--;
       
 10588     }
       
 10589     strcpy(s, "<>");
       
 10590   }
       
 10591   if (!soap->mime.start)
       
 10592     soap->mime.start = "<SOAP-ENV:Envelope>";
       
 10593 }
       
 10594 #endif
       
 10595 #endif
       
 10596 
       
 10597 /******************************************************************************/
       
 10598 #ifndef WITH_LEANER
       
 10599 #ifndef PALM_1
       
 10600 static int
       
 10601 soap_valid_mime_boundary(struct soap *soap)
       
 10602 { register struct soap_multipart *content;
       
 10603   register size_t k = strlen(soap->mime.boundary);
       
 10604   for (content = soap->mime.first; content; content = content->next)
       
 10605   { if (content->ptr && content->size >= k)
       
 10606     { register const char *p = (const char*)content->ptr; 
       
 10607       register size_t i;
       
 10608       for (i = 0; i < content->size - k; i++, p++)
       
 10609         if (!strncmp(p, soap->mime.boundary, k))
       
 10610           return SOAP_ERR;
       
 10611     }
       
 10612   }
       
 10613   return SOAP_OK;
       
 10614 }
       
 10615 #endif
       
 10616 #endif
       
 10617 
       
 10618 /******************************************************************************/
       
 10619 
       
 10620 #ifdef WITH_COOKIES
       
 10621 /******************************************************************************/
       
 10622 SOAP_FMAC1
       
 10623 size_t
       
 10624 SOAP_FMAC2
       
 10625 soap_encode_cookie(const char *s, char *t, size_t len)
       
 10626 { register int c;
       
 10627   register size_t n = len;
       
 10628   while ((c = *s++) && --n > 0)
       
 10629   { if (c > ' ' && c < 128 && !strchr("()<>@,;:\\\"/[]?={}", c))
       
 10630       *t++ = c;
       
 10631     else if (n > 2)
       
 10632     { *t++ = '%';
       
 10633       *t++ = (c >> 4) + (c > 159 ? '7' : '0');
       
 10634       c &= 0xF;
       
 10635       *t++ = c + (c > 9 ? '7' : '0');
       
 10636       n -= 2;
       
 10637     }
       
 10638     else
       
 10639       break;
       
 10640   }
       
 10641   *t = '\0';
       
 10642   return len - n;
       
 10643 }
       
 10644 
       
 10645 /******************************************************************************/
       
 10646 SOAP_FMAC1
       
 10647 struct soap_cookie*
       
 10648 SOAP_FMAC2
       
 10649 soap_cookie(struct soap *soap, const char *name, const char *domain, const char *path)
       
 10650 { struct soap_cookie *p;
       
 10651   size_t n;
       
 10652   if (!domain)
       
 10653     domain = soap->cookie_domain;
       
 10654   if (!path)
       
 10655     path = soap->cookie_path;
       
 10656   if (*path == '/')
       
 10657     path++;
       
 10658   n = strlen(path);
       
 10659   for (p = soap->cookies; p; p = p->next)
       
 10660     if (!strcmp(p->name, name)
       
 10661      && domain
       
 10662      && p->domain
       
 10663      && !strcmp(p->domain, domain)
       
 10664      && !strncmp(p->path, path, n))
       
 10665       break;
       
 10666   return p;
       
 10667 }
       
 10668 
       
 10669 /******************************************************************************/
       
 10670 SOAP_FMAC1
       
 10671 struct soap_cookie*
       
 10672 SOAP_FMAC2
       
 10673 soap_set_cookie(struct soap *soap, const char *name, const char *value, const char *domain, const char *path)
       
 10674 { struct soap_cookie **p, *q;
       
 10675   int n;
       
 10676   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set cookie: %s=%s domain=%s path=%s\n", name, value?value:"", domain?domain:"", path?path:""));
       
 10677   if (!domain)
       
 10678     domain = soap->cookie_domain;
       
 10679   if (!path)
       
 10680     path = soap->cookie_path;
       
 10681   if (!path)
       
 10682   { soap_set_receiver_error(soap, "Cookie path not set", NULL, SOAP_HTTP_ERROR);
       
 10683     return NULL;
       
 10684   }
       
 10685   if (*path == '/')
       
 10686     path++;
       
 10687   q = soap_cookie(soap, name, domain, path);
       
 10688   if (!q)
       
 10689   { if ((q = (struct soap_cookie*)SOAP_MALLOC(soap, sizeof(struct soap_cookie))))
       
 10690     { if ((q->name = (char*)SOAP_MALLOC(soap, strlen(name)+1)))
       
 10691         strcpy(q->name, name);
       
 10692       q->value = NULL;
       
 10693       q->domain = NULL;
       
 10694       q->path = NULL;
       
 10695       q->expire = -1;
       
 10696       q->version = 0;
       
 10697       q->secure = 0;
       
 10698       q->modified = 0;
       
 10699       for (p = &soap->cookies, n = soap->cookie_max; *p && n; p = &(*p)->next, n--)
       
 10700         if (!strcmp((*p)->name, name) && (*p)->path && strcmp((*p)->path, path) < 0)
       
 10701           break;
       
 10702       if (n)
       
 10703       { q->next = *p;
       
 10704         *p = q;
       
 10705       }
       
 10706       else
       
 10707       { SOAP_FREE(soap, q->name);
       
 10708         SOAP_FREE(soap, q);
       
 10709         q = NULL;
       
 10710       }
       
 10711     }
       
 10712   }
       
 10713   else
       
 10714     q->modified = 1;
       
 10715   if (q)
       
 10716   { if (q->value)
       
 10717     { SOAP_FREE(soap, q->value);
       
 10718       q->value = NULL;
       
 10719     }
       
 10720     if (q->domain)
       
 10721     { SOAP_FREE(soap, q->domain);
       
 10722       q->domain = NULL;
       
 10723     }
       
 10724     if (q->path)
       
 10725     { SOAP_FREE(soap, q->path);
       
 10726       q->path = NULL;
       
 10727     }
       
 10728     if (value && *value && (q->value = (char*)SOAP_MALLOC(soap, strlen(value)+1)))
       
 10729       strcpy(q->value, value);
       
 10730     if (domain && *domain && (q->domain = (char*)SOAP_MALLOC(soap, strlen(domain)+1)))
       
 10731       strcpy(q->domain, domain);
       
 10732     if (path && *path && (q->path = (char*)SOAP_MALLOC(soap, strlen(path)+1)))
       
 10733       strcpy(q->path, path);
       
 10734     q->session = 1;
       
 10735     q->env = 0;
       
 10736   }
       
 10737   return q;
       
 10738 }
       
 10739 
       
 10740 /******************************************************************************/
       
 10741 SOAP_FMAC1
       
 10742 void
       
 10743 SOAP_FMAC2
       
 10744 soap_clr_cookie(struct soap *soap, const char *name, const char *domain, const char *path)
       
 10745 { struct soap_cookie **p, *q;
       
 10746   if (!domain)
       
 10747     domain = soap->cookie_domain;
       
 10748   if (!domain)
       
 10749   { soap_set_receiver_error(soap, "Cookie domain not set", NULL, SOAP_HTTP_ERROR);
       
 10750     return;
       
 10751   }
       
 10752   if (!path)
       
 10753     path = soap->cookie_path;
       
 10754   if (!path)
       
 10755   { soap_set_receiver_error(soap, "Cookie path not set", NULL, SOAP_HTTP_ERROR);
       
 10756     return;
       
 10757   }
       
 10758   if (*path == '/')
       
 10759     path++;
       
 10760   for (p = &soap->cookies, q = *p; q; q = *p)
       
 10761     if (!strcmp(q->name, name) && !strcmp(q->domain, domain) && !strncmp(q->path, path, strlen(q->path)))
       
 10762     { if (q->value)
       
 10763         SOAP_FREE(soap, q->value);
       
 10764       if (q->domain)
       
 10765         SOAP_FREE(soap, q->domain);
       
 10766       if (q->path)
       
 10767         SOAP_FREE(soap, q->path);
       
 10768       *p = q->next;
       
 10769       SOAP_FREE(soap, q);
       
 10770     }
       
 10771     else
       
 10772       p = &q->next;
       
 10773 }
       
 10774 
       
 10775 /******************************************************************************/
       
 10776 SOAP_FMAC1
       
 10777 char *
       
 10778 SOAP_FMAC2
       
 10779 soap_cookie_value(struct soap *soap, const char *name, const char *domain, const char *path)
       
 10780 { struct soap_cookie *p;
       
 10781   if ((p = soap_cookie(soap, name, domain, path)))
       
 10782     return p->value;
       
 10783   return NULL;
       
 10784 }
       
 10785 
       
 10786 /******************************************************************************/
       
 10787 SOAP_FMAC1
       
 10788 char *
       
 10789 SOAP_FMAC2
       
 10790 soap_env_cookie_value(struct soap *soap, const char *name, const char *domain, const char *path)
       
 10791 { struct soap_cookie *p;
       
 10792   if ((p = soap_cookie(soap, name, domain, path)) && p->env)
       
 10793     return p->value;
       
 10794   return NULL;
       
 10795 }
       
 10796 
       
 10797 /******************************************************************************/
       
 10798 SOAP_FMAC1
       
 10799 long
       
 10800 SOAP_FMAC2
       
 10801 soap_cookie_expire(struct soap *soap, const char *name, const char *domain, const char *path)
       
 10802 { struct soap_cookie *p;
       
 10803   if ((p = soap_cookie(soap, name, domain, path)))
       
 10804     return p->expire;
       
 10805   return -1;
       
 10806 }
       
 10807 
       
 10808 /******************************************************************************/
       
 10809 SOAP_FMAC1
       
 10810 int
       
 10811 SOAP_FMAC2
       
 10812 soap_set_cookie_expire(struct soap *soap, const char *name, long expire, const char *domain, const char *path)
       
 10813 { struct soap_cookie *p;
       
 10814   if ((p = soap_cookie(soap, name, domain, path)))
       
 10815   { p->expire = expire;
       
 10816     p->modified = 1;
       
 10817     return SOAP_OK;
       
 10818   }
       
 10819   return SOAP_ERR;
       
 10820 }
       
 10821 
       
 10822 /******************************************************************************/
       
 10823 SOAP_FMAC1
       
 10824 int
       
 10825 SOAP_FMAC2
       
 10826 soap_set_cookie_session(struct soap *soap, const char *name, const char *domain, const char *path)
       
 10827 { struct soap_cookie *p;
       
 10828   if ((p = soap_cookie(soap, name, domain, path)))
       
 10829   { p->session = 1;
       
 10830     p->modified = 1;
       
 10831     return SOAP_OK;
       
 10832   }
       
 10833   return SOAP_ERR;
       
 10834 }
       
 10835 
       
 10836 /******************************************************************************/
       
 10837 SOAP_FMAC1
       
 10838 int
       
 10839 SOAP_FMAC2
       
 10840 soap_clr_cookie_session(struct soap *soap, const char *name, const char *domain, const char *path)
       
 10841 { struct soap_cookie *p;
       
 10842   if ((p = soap_cookie(soap, name, domain, path)))
       
 10843   { p->session = 0;
       
 10844     p->modified = 1;
       
 10845     return SOAP_OK;
       
 10846   }
       
 10847   return SOAP_ERR;
       
 10848 }
       
 10849 
       
 10850 /******************************************************************************/
       
 10851 SOAP_FMAC1
       
 10852 int
       
 10853 SOAP_FMAC2
       
 10854 soap_putsetcookies(struct soap *soap)
       
 10855 { struct soap_cookie *p;
       
 10856   char *s, tmp[4096];
       
 10857   const char *t;
       
 10858   for (p = soap->cookies; p; p = p->next)
       
 10859   { if (p->modified || !p->env)
       
 10860     { s = tmp;
       
 10861       if (p->name)
       
 10862         s += soap_encode_cookie(p->name, s, tmp-s+4064);
       
 10863       if (p->value && *p->value)
       
 10864       { *s++ = '=';
       
 10865         s += soap_encode_cookie(p->value, s, tmp-s+4064);
       
 10866       }
       
 10867       if (p->domain && (int)strlen(p->domain) < tmp-s+4064)
       
 10868         sprintf(s, ";Domain=\"%s\"", p->domain);
       
 10869       else if (soap->cookie_domain && (int)strlen(soap->cookie_domain) < tmp-s+4064)
       
 10870         sprintf(s, ";Domain=\"%s\"", soap->cookie_domain);
       
 10871       strcat(s, ";Path=\"/");
       
 10872       if (p->path)
       
 10873         t = p->path;
       
 10874       else
       
 10875         t = soap->cookie_path;
       
 10876       if (t)
       
 10877       { if (*t == '/')
       
 10878           t++;
       
 10879         if ((int)strlen(t) < tmp-s+4064)
       
 10880           strcat(s, t);
       
 10881       }
       
 10882       s += strlen(s);
       
 10883       *s++ = '"';
       
 10884       if (p->version > 0)
       
 10885         sprintf(s, ";Version=%u", p->version);
       
 10886       if (p->expire >= 0)
       
 10887         sprintf(s, ";Max-Age=%ld", p->expire);
       
 10888       if (p->secure)
       
 10889         strcat(s, ";Secure");
       
 10890       DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set-Cookie: %s\n", tmp));
       
 10891       if ((soap->error = soap->fposthdr(soap, "Set-Cookie", tmp)))
       
 10892         return soap->error;
       
 10893     }
       
 10894   }
       
 10895   return SOAP_OK;
       
 10896 }
       
 10897 
       
 10898 /******************************************************************************/
       
 10899 SOAP_FMAC1
       
 10900 int
       
 10901 SOAP_FMAC2
       
 10902 soap_putcookies(struct soap *soap, const char *domain, const char *path, int secure)
       
 10903 { struct soap_cookie **p, *q;
       
 10904   unsigned int version = 0;
       
 10905   time_t now = time(NULL);
       
 10906   char *s, tmp[4096];
       
 10907   p = &soap->cookies;
       
 10908   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Sending cookies for domain=%s path=%s\n", domain, path));
       
 10909   if (*path == '/')
       
 10910     path++;
       
 10911   while ((q = *p))
       
 10912   { if (q->expire && now > q->expire)
       
 10913     { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie %s expired\n", q->name));
       
 10914       SOAP_FREE(soap, q->name);
       
 10915       if (q->value)
       
 10916         SOAP_FREE(soap, q->value);
       
 10917       if (q->domain)
       
 10918         SOAP_FREE(soap, q->domain);
       
 10919       if (q->path)
       
 10920         SOAP_FREE(soap, q->path);
       
 10921       *p = q->next;
       
 10922       SOAP_FREE(soap, q);
       
 10923     }
       
 10924     else
       
 10925     { size_t domlen = 0;
       
 10926       if (q->domain)
       
 10927       { const char *s = strchr(q->domain, ':');
       
 10928         if (s)
       
 10929 	  domlen = s - q->domain;
       
 10930 	else
       
 10931           domlen = strlen(q->domain);
       
 10932       }
       
 10933       if ((!q->domain || !strncmp(q->domain, domain, domlen))
       
 10934           && (!q->path || !strncmp(q->path, path, strlen(q->path)))
       
 10935           && (!q->secure || secure))
       
 10936       { s = tmp;
       
 10937         if (q->version != version)
       
 10938         { sprintf(s, "$Version=%u;", q->version);
       
 10939           version = q->version;
       
 10940         }
       
 10941         if (q->name)
       
 10942           s += soap_encode_cookie(q->name, s, tmp-s+4080);
       
 10943         if (q->value && *q->value)
       
 10944         { *s++ = '=';
       
 10945           s += soap_encode_cookie(q->value, s, tmp-s+4080);
       
 10946         }
       
 10947         if (q->path && (int)strlen(q->path) < tmp-s+4080)
       
 10948         { sprintf(s, ";$Path=\"/%s\"", (*q->path == '/' ? q->path + 1 : q->path));
       
 10949           s += strlen(s);
       
 10950         }
       
 10951         if (q->domain && (int)strlen(q->domain) < tmp-s+4080)
       
 10952           sprintf(s, ";$Domain=\"%s\"", q->domain);
       
 10953         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie: %s\n", tmp));
       
 10954         if ((soap->error = soap->fposthdr(soap, "Cookie", tmp)))
       
 10955           return soap->error;
       
 10956       }
       
 10957       p = &q->next;
       
 10958     }
       
 10959   }
       
 10960   return SOAP_OK;
       
 10961 }
       
 10962 
       
 10963 /******************************************************************************/
       
 10964 SOAP_FMAC1
       
 10965 void
       
 10966 SOAP_FMAC2
       
 10967 soap_getcookies(struct soap *soap, const char *val)
       
 10968 { struct soap_cookie *p = NULL, *q;
       
 10969   const char *s;
       
 10970   char *t, tmp[4096]; /* cookie size is up to 4096 bytes [RFC2109] */
       
 10971   char *domain = NULL;
       
 10972   char *path = NULL;
       
 10973   unsigned int version = 0;
       
 10974   time_t now = time(NULL);
       
 10975   if (!val)
       
 10976     return;
       
 10977   s = val;
       
 10978   while (*s)
       
 10979   { s = soap_decode_key(tmp, sizeof(tmp), s);
       
 10980     if (!soap_tag_cmp(tmp, "$Version"))
       
 10981     { if ((s = soap_decode_val(tmp, sizeof(tmp), s)))
       
 10982       { if (p)
       
 10983           p->version = (int)atol(tmp);
       
 10984         else
       
 10985           version = (int)atol(tmp);
       
 10986       }
       
 10987     }
       
 10988     else if (!soap_tag_cmp(tmp, "$Path"))
       
 10989     { s = soap_decode_val(tmp, sizeof(tmp), s);
       
 10990       if (*tmp)
       
 10991       { if ((t = (char*)SOAP_MALLOC(soap, strlen(tmp)+1)))
       
 10992           strcpy(t, tmp);
       
 10993       }
       
 10994       else
       
 10995         t = NULL;
       
 10996       if (p)
       
 10997       { if (p->path)
       
 10998           SOAP_FREE(soap, p->path);
       
 10999         p->path = t;
       
 11000       }
       
 11001       else
       
 11002       { if (path)
       
 11003           SOAP_FREE(soap, path);
       
 11004         path = t;
       
 11005       }
       
 11006     }
       
 11007     else if (!soap_tag_cmp(tmp, "$Domain"))
       
 11008     { s = soap_decode_val(tmp, sizeof(tmp), s);
       
 11009       if (*tmp)
       
 11010       { if ((t = (char*)SOAP_MALLOC(soap, strlen(tmp)+1)))
       
 11011           strcpy(t, tmp);
       
 11012       }
       
 11013       else
       
 11014         t = NULL;
       
 11015       if (p)
       
 11016       { if (p->domain)
       
 11017           SOAP_FREE(soap, p->domain);
       
 11018 	p->domain = t;
       
 11019       }
       
 11020       else
       
 11021       { if (domain)
       
 11022           SOAP_FREE(soap, domain);
       
 11023         domain = t;
       
 11024       }
       
 11025     }
       
 11026     else if (p && !soap_tag_cmp(tmp, "Path"))
       
 11027     { if (p->path)
       
 11028         SOAP_FREE(soap, p->path);
       
 11029       s = soap_decode_val(tmp, sizeof(tmp), s);
       
 11030       if (*tmp)
       
 11031       { if ((p->path = (char*)SOAP_MALLOC(soap, strlen(tmp)+1)))
       
 11032           strcpy(p->path, tmp);
       
 11033       }
       
 11034       else
       
 11035         p->path = NULL;
       
 11036     }
       
 11037     else if (p && !soap_tag_cmp(tmp, "Domain"))
       
 11038     { if (p->domain)
       
 11039         SOAP_FREE(soap, p->domain);
       
 11040       s = soap_decode_val(tmp, sizeof(tmp), s);
       
 11041       if (*tmp)
       
 11042       { if ((p->domain = (char*)SOAP_MALLOC(soap, strlen(tmp)+1)))
       
 11043           strcpy(p->domain, tmp);
       
 11044       }
       
 11045       else
       
 11046         p->domain = NULL;
       
 11047     }
       
 11048     else if (p && !soap_tag_cmp(tmp, "Version"))
       
 11049     { s = soap_decode_val(tmp, sizeof(tmp), s);
       
 11050       p->version = (unsigned int)atol(tmp);
       
 11051     }
       
 11052     else if (p && !soap_tag_cmp(tmp, "Max-Age"))
       
 11053     { s = soap_decode_val(tmp, sizeof(tmp), s);
       
 11054       p->expire = now + atol(tmp);
       
 11055     }
       
 11056     else if (p && !soap_tag_cmp(tmp, "Expires"))
       
 11057     { struct tm T;
       
 11058       char a[3]; 
       
 11059       static const char mns[] = "anebarprayunulugepctovec";
       
 11060       s = soap_decode_val(tmp, sizeof(tmp), s);
       
 11061       if (strlen(tmp) > 20)
       
 11062       { memset((void*)&T, 0, sizeof(T));
       
 11063         a[0] = tmp[4];
       
 11064         a[1] = tmp[5];
       
 11065         a[2] = '\0';
       
 11066         T.tm_mday = (int)atol(a);
       
 11067         a[0] = tmp[8];
       
 11068         a[1] = tmp[9];
       
 11069         T.tm_mon = (strstr(mns, a) - mns) / 2;
       
 11070         a[0] = tmp[11];
       
 11071         a[1] = tmp[12];
       
 11072         T.tm_year = 100 + (int)atol(a);
       
 11073         a[0] = tmp[13];
       
 11074         a[1] = tmp[14];
       
 11075         T.tm_hour = (int)atol(a);
       
 11076         a[0] = tmp[16];
       
 11077         a[1] = tmp[17];
       
 11078         T.tm_min = (int)atol(a);
       
 11079         a[0] = tmp[19];
       
 11080         a[1] = tmp[20];
       
 11081         T.tm_sec = (int)atol(a);
       
 11082         p->expire = soap_timegm(&T);
       
 11083       }
       
 11084     }
       
 11085     else if (p && !soap_tag_cmp(tmp, "Secure"))
       
 11086       p->secure = 1;
       
 11087     else
       
 11088     { if (p)
       
 11089       { 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));
       
 11090         if ((q = soap_set_cookie(soap, p->name, p->value, p->domain, p->path)))
       
 11091         { q->version = p->version;
       
 11092           q->expire = p->expire;
       
 11093           q->secure = p->secure;
       
 11094           q->env = 1;
       
 11095         }
       
 11096         if (p->name)
       
 11097           SOAP_FREE(soap, p->name);
       
 11098         if (p->value)
       
 11099           SOAP_FREE(soap, p->value);
       
 11100         if (p->domain)
       
 11101           SOAP_FREE(soap, p->domain);
       
 11102         if (p->path)
       
 11103           SOAP_FREE(soap, p->path);
       
 11104         SOAP_FREE(soap, p);
       
 11105       }
       
 11106       if ((p = (struct soap_cookie*)SOAP_MALLOC(soap, sizeof(struct soap_cookie))))
       
 11107       { p->name = (char*)SOAP_MALLOC(soap, strlen(tmp)+1);
       
 11108         strcpy(p->name, tmp);
       
 11109         s = soap_decode_val(tmp, sizeof(tmp), s);
       
 11110         if (*tmp)
       
 11111         { p->value = (char*)SOAP_MALLOC(soap, strlen(tmp)+1);
       
 11112           strcpy(p->value, tmp);
       
 11113         }
       
 11114         else
       
 11115           p->value = NULL;
       
 11116         p->domain = domain;
       
 11117         p->path = path;
       
 11118         p->expire = 0;
       
 11119         p->secure = 0;
       
 11120         p->version = version;
       
 11121       }
       
 11122     }
       
 11123   }
       
 11124   if (p)
       
 11125   { 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));
       
 11126     if ((q = soap_set_cookie(soap, p->name, p->value, p->domain, p->path)))
       
 11127     { q->version = p->version;
       
 11128       q->expire = p->expire;
       
 11129       q->secure = p->secure;
       
 11130       q->env = 1;
       
 11131     }
       
 11132     if (p->name)
       
 11133       SOAP_FREE(soap, p->name);
       
 11134     if (p->value)
       
 11135       SOAP_FREE(soap, p->value);
       
 11136     if (p->domain)
       
 11137       SOAP_FREE(soap, p->domain);
       
 11138     if (p->path)
       
 11139       SOAP_FREE(soap, p->path);
       
 11140     SOAP_FREE(soap, p);
       
 11141   }
       
 11142   if (domain)
       
 11143     SOAP_FREE(soap, domain);
       
 11144   if (path)
       
 11145     SOAP_FREE(soap, path);
       
 11146 }
       
 11147 
       
 11148 /******************************************************************************/
       
 11149 SOAP_FMAC1
       
 11150 int
       
 11151 SOAP_FMAC2
       
 11152 soap_getenv_cookies(struct soap *soap)
       
 11153 { struct soap_cookie *p;
       
 11154   const char *s;
       
 11155   char key[4096], val[4096]; /* cookie size is up to 4096 bytes [RFC2109] */
       
 11156   if (!(s = getenv("HTTP_COOKIE")))
       
 11157     return SOAP_ERR;
       
 11158   do
       
 11159   { s = soap_decode_key(key, sizeof(key), s);
       
 11160     s = soap_decode_val(val, sizeof(val), s);
       
 11161     p = soap_set_cookie(soap, key, val, NULL, NULL);
       
 11162     if (p)
       
 11163       p->env = 1;
       
 11164   } while (*s);
       
 11165   return SOAP_OK;
       
 11166 }
       
 11167 
       
 11168 /******************************************************************************/
       
 11169 SOAP_FMAC1
       
 11170 struct soap_cookie*
       
 11171 SOAP_FMAC2
       
 11172 soap_copy_cookies(struct soap *soap)
       
 11173 { struct soap_cookie *p, **q, *r;
       
 11174   q = &r;
       
 11175   for (p = soap->cookies; p; p = p->next)
       
 11176   { if (!(*q = (struct soap_cookie*)SOAP_MALLOC(soap, sizeof(struct soap_cookie))))
       
 11177       return r;
       
 11178     **q = *p;
       
 11179     if (p->name)
       
 11180     { if (((*q)->name = (char*)SOAP_MALLOC(soap, strlen(p->name)+1)))
       
 11181         strcpy((*q)->name, p->name);
       
 11182     }
       
 11183     if (p->value)
       
 11184     { if (((*q)->value = (char*)SOAP_MALLOC(soap, strlen(p->value)+1)))
       
 11185         strcpy((*q)->value, p->value);
       
 11186     }
       
 11187     if (p->domain)
       
 11188     { if (((*q)->domain = (char*)SOAP_MALLOC(soap, strlen(p->domain)+1)))
       
 11189         strcpy((*q)->domain, p->domain);
       
 11190     }
       
 11191     if (p->path)
       
 11192     { if (((*q)->path = (char*)SOAP_MALLOC(soap, strlen(p->path)+1)))
       
 11193         strcpy((*q)->path, p->path);
       
 11194     }
       
 11195     q = &(*q)->next;
       
 11196   }
       
 11197   *q = NULL;
       
 11198   return r;
       
 11199 }
       
 11200 
       
 11201 /******************************************************************************/
       
 11202 SOAP_FMAC1
       
 11203 void
       
 11204 SOAP_FMAC2
       
 11205 soap_free_cookies(struct soap *soap)
       
 11206 { struct soap_cookie *p;
       
 11207   for (p = soap->cookies; p; p = soap->cookies)
       
 11208   { soap->cookies = p->next;
       
 11209     SOAP_FREE(soap, p->name);
       
 11210     if (p->value)
       
 11211       SOAP_FREE(soap, p->value);
       
 11212     if (p->domain)
       
 11213       SOAP_FREE(soap, p->domain);
       
 11214     if (p->path)
       
 11215       SOAP_FREE(soap, p->path);
       
 11216     SOAP_FREE(soap, p);
       
 11217   }
       
 11218 }
       
 11219 
       
 11220 /******************************************************************************/
       
 11221 #endif /* WITH_COOKIES */
       
 11222 
       
 11223 /******************************************************************************/
       
 11224 #ifdef WITH_GZIP
       
 11225 #ifndef PALM_1
       
 11226 static int
       
 11227 soap_getgziphdr(struct soap *soap)
       
 11228 { int i;
       
 11229   soap_wchar c, f = 0;
       
 11230   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get gzip header\n"));
       
 11231   for (i = 0; i < 9; i++)
       
 11232   { if ((int)(c = soap_get1(soap) == EOF))
       
 11233       return soap->error = SOAP_EOF;
       
 11234     if (i == 2)
       
 11235       f = c;
       
 11236   }
       
 11237   if (f & 0x04) /* FEXTRA */
       
 11238   { for (i = soap_get1(soap) | (soap_get1(soap) << 8); i; i--)
       
 11239       if ((int)soap_get1(soap) == EOF)
       
 11240         return soap->error = SOAP_EOF;
       
 11241   }
       
 11242   if (f & 0x08) /* FNAME */
       
 11243     do
       
 11244       c = soap_get1(soap);
       
 11245     while (c && (int)c != EOF);
       
 11246   if ((int)c != EOF && (f & 0x10)) /* FCOMMENT */
       
 11247     do
       
 11248       c = soap_get1(soap);
       
 11249     while (c && (int)f != EOF);
       
 11250   if ((int)c != EOF && (f & 0x01)) /* FHCRC */
       
 11251   { if ((int)(c = soap_get1(soap)) != EOF)
       
 11252       c = soap_get1(soap);
       
 11253   }
       
 11254   if ((int)c == EOF)
       
 11255     return soap->error = SOAP_EOF;
       
 11256   return SOAP_OK;
       
 11257 }
       
 11258 #endif
       
 11259 #endif
       
 11260 
       
 11261 /******************************************************************************/
       
 11262 #ifndef PALM_1
       
 11263 SOAP_FMAC1
       
 11264 int
       
 11265 SOAP_FMAC2
       
 11266 soap_begin_recv(struct soap *soap)
       
 11267 { soap_wchar c;
       
 11268   soap->error = SOAP_OK;
       
 11269   soap_free(soap);
       
 11270   soap_set_local_namespaces(soap);
       
 11271   soap->version = 0;	/* don't assume we're parsing SOAP content by default */
       
 11272 #ifndef WITH_NOIDREF
       
 11273   soap_free_iht(soap);
       
 11274 #endif
       
 11275   if ((soap->imode & SOAP_IO) == SOAP_IO_CHUNK)
       
 11276     soap->omode |= SOAP_IO_CHUNK;
       
 11277   soap->imode &= ~SOAP_IO;
       
 11278   soap->mode = soap->imode;
       
 11279   if (!soap->keep_alive)
       
 11280   { soap->buflen = 0;
       
 11281     soap->bufidx = 0;
       
 11282   }
       
 11283   if (!(soap->mode & SOAP_IO_KEEPALIVE))
       
 11284     soap->keep_alive = 0;
       
 11285   soap->ahead = 0;
       
 11286   soap->peeked = 0;
       
 11287   soap->level = 0;
       
 11288   soap->part = SOAP_BEGIN;
       
 11289   soap->alloced = 0;
       
 11290   soap->count = 0;
       
 11291   soap->length = 0;
       
 11292   soap->cdata = 0;
       
 11293   *soap->endpoint = '\0';
       
 11294   soap->action = NULL;
       
 11295 #ifndef WITH_LEANER
       
 11296   soap->dom = NULL;
       
 11297   soap->dime.chunksize = 0;
       
 11298   soap->dime.buflen = 0;
       
 11299   soap->dime.list = NULL;
       
 11300   soap->dime.first = NULL;
       
 11301   soap->dime.last = NULL;
       
 11302   soap->mime.list = NULL;
       
 11303   soap->mime.first = NULL;
       
 11304   soap->mime.last = NULL;
       
 11305   soap->mime.boundary = NULL;
       
 11306   soap->mime.start = NULL;
       
 11307   soap->xlist = NULL;
       
 11308 #endif
       
 11309 #ifdef WIN32
       
 11310 #ifndef UNDER_CE
       
 11311 #ifndef WITH_FASTCGI
       
 11312   if (!soap_valid_socket(soap->socket))
       
 11313 #ifdef __BORLANDC__
       
 11314     setmode((SOAP_SOCKET)soap->recvfd, O_BINARY);
       
 11315 #else
       
 11316     _setmode((SOAP_SOCKET)soap->recvfd, _O_BINARY);
       
 11317 #endif
       
 11318 #endif
       
 11319 #endif
       
 11320 #endif
       
 11321 #ifdef WITH_ZLIB
       
 11322   soap->mode &= ~SOAP_ENC_ZLIB;
       
 11323   soap->zlib_in = SOAP_ZLIB_NONE;
       
 11324   soap->zlib_out = SOAP_ZLIB_NONE;
       
 11325   soap->d_stream.next_in = Z_NULL;
       
 11326   soap->d_stream.avail_in = 0;
       
 11327   soap->d_stream.next_out = (Byte*)soap->buf;
       
 11328   soap->d_stream.avail_out = SOAP_BUFLEN;
       
 11329   soap->z_ratio_in = 1.0;
       
 11330 #endif
       
 11331 #ifndef WITH_LEANER
       
 11332   if (soap->fprepareinit)
       
 11333     soap->fprepareinit(soap);
       
 11334 #endif
       
 11335   c = soap_getchar(soap);
       
 11336 #ifdef WITH_GZIP
       
 11337   if (c == 0x1F)
       
 11338   { if (soap_getgziphdr(soap))
       
 11339       return soap->error;
       
 11340     if (inflateInit2(&soap->d_stream, -MAX_WBITS) != Z_OK)
       
 11341       return soap->error = SOAP_ZLIB_ERROR;
       
 11342     soap->zlib_state = SOAP_ZLIB_INFLATE;
       
 11343     soap->mode |= SOAP_ENC_ZLIB;
       
 11344     soap->zlib_in = SOAP_ZLIB_GZIP;
       
 11345     soap->z_crc = crc32(0L, NULL, 0);
       
 11346     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip initialized\n"));
       
 11347     memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN);
       
 11348     /* should not chunk over plain transport, so why bother to check? */
       
 11349     /* if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) */
       
 11350     /*   soap->z_buflen = soap->bufidx; */
       
 11351     /* else */
       
 11352     soap->d_stream.next_in = (Byte*)(soap->z_buf + soap->bufidx);
       
 11353     soap->d_stream.avail_in = soap->buflen - soap->bufidx;
       
 11354     soap->z_buflen = soap->buflen;
       
 11355     soap->buflen = soap->bufidx;
       
 11356     c = soap_getchar(soap);
       
 11357   }  
       
 11358 #endif
       
 11359 #ifndef WITH_LEANER
       
 11360   if (c == '-' && soap_get0(soap) == '-')
       
 11361     soap->mode |= SOAP_ENC_MIME;
       
 11362   else if ((c & 0xFFFC) == (SOAP_DIME_VERSION | SOAP_DIME_MB) && (soap_get0(soap) & 0xFFF0) == 0x20)
       
 11363     soap->mode |= SOAP_ENC_DIME;
       
 11364   else
       
 11365 #endif
       
 11366   { while (soap_blank(c))
       
 11367       c = soap_getchar(soap);
       
 11368   }
       
 11369   if ((int)c == EOF)
       
 11370     return soap->error = SOAP_EOF;
       
 11371   soap_unget(soap, c);
       
 11372 #ifndef WITH_NOHTTP
       
 11373   /* if not XML or (start of)BOM or MIME/DIME/ZLIB, assume HTTP header */
       
 11374   if (c != '<' && c != 0xEF && !(soap->mode & (SOAP_ENC_MIME | SOAP_ENC_DIME | SOAP_ENC_ZLIB)))
       
 11375   { soap->mode &= ~SOAP_IO;
       
 11376     soap->error = soap->fparse(soap);
       
 11377     if (soap->error && soap->error < SOAP_STOP)
       
 11378     { soap->keep_alive = 0; /* force close later */
       
 11379       return soap->error;
       
 11380     }
       
 11381     if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK)
       
 11382     { soap->chunkbuflen = soap->buflen;
       
 11383       soap->buflen = soap->bufidx;
       
 11384       soap->chunksize = 0;
       
 11385     }
       
 11386 #ifndef WITH_LEANER
       
 11387     else if (soap->fpreparerecv && soap->buflen != soap->bufidx)
       
 11388       soap->fpreparerecv(soap, soap->buf + soap->bufidx, soap->buflen - soap->bufidx);
       
 11389 #endif
       
 11390 #ifdef WITH_ZLIB
       
 11391     if (soap->zlib_in != SOAP_ZLIB_NONE)
       
 11392     { /* fparse should not use soap_unget to push back last char */
       
 11393 #ifdef WITH_GZIP
       
 11394       c = soap_get1(soap);
       
 11395       if (c == 0x1F)
       
 11396       { if (soap_getgziphdr(soap))
       
 11397           return soap->error;
       
 11398         if (inflateInit2(&soap->d_stream, -MAX_WBITS) != Z_OK)
       
 11399           return soap->error = SOAP_ZLIB_ERROR;
       
 11400         soap->zlib_state = SOAP_ZLIB_INFLATE;
       
 11401         soap->z_crc = crc32(0L, NULL, 0);
       
 11402         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip initialized\n"));
       
 11403       }
       
 11404       else
       
 11405       { soap_revget1(soap);
       
 11406 #else
       
 11407       {
       
 11408 #endif
       
 11409         if (inflateInit(&soap->d_stream) != Z_OK)
       
 11410           return soap->error = SOAP_ZLIB_ERROR;
       
 11411         soap->zlib_state = SOAP_ZLIB_INFLATE;
       
 11412         DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflate initialized\n"));
       
 11413       }
       
 11414       soap->mode |= SOAP_ENC_ZLIB;
       
 11415       memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN);
       
 11416       soap->d_stream.next_in = (Byte*)(soap->z_buf + soap->bufidx);
       
 11417       soap->d_stream.avail_in = soap->buflen - soap->bufidx;
       
 11418       soap->z_buflen = soap->buflen;
       
 11419       soap->buflen = soap->bufidx;
       
 11420     }
       
 11421 #endif
       
 11422     if (soap->error)
       
 11423     { if (soap->error == SOAP_FORM && soap->fform)
       
 11424       { soap->error = soap->fform(soap);
       
 11425         if (soap->error == SOAP_OK)
       
 11426           soap->error = SOAP_STOP; /* prevents further processing */
       
 11427       }
       
 11428       return soap->error;
       
 11429     }
       
 11430   }
       
 11431 #endif
       
 11432 #ifndef WITH_LEANER
       
 11433   if (soap->mode & SOAP_ENC_MIME)
       
 11434   { if (soap_getmimehdr(soap))
       
 11435       return soap->error;
       
 11436     if (soap_get_header_attribute(soap, soap->mime.first->type, "application/dime"))
       
 11437       soap->mode |= SOAP_ENC_DIME;
       
 11438   }
       
 11439   if (soap->mode & SOAP_ENC_DIME)
       
 11440   { if (soap_getdimehdr(soap))
       
 11441       return soap->error;
       
 11442     if (soap->dime.flags & SOAP_DIME_CF)
       
 11443     { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunked DIME SOAP message\n"));
       
 11444       soap->dime.chunksize = soap->dime.size;
       
 11445       if (soap->buflen - soap->bufidx >= soap->dime.chunksize)
       
 11446       { soap->dime.buflen = soap->buflen;
       
 11447         soap->buflen = soap->bufidx + soap->dime.chunksize;
       
 11448       }
       
 11449       else
       
 11450         soap->dime.chunksize -= soap->buflen - soap->bufidx;
       
 11451     }
       
 11452     soap->count = soap->buflen - soap->bufidx;
       
 11453   }
       
 11454 #endif
       
 11455   return SOAP_OK;
       
 11456 }
       
 11457 #endif
       
 11458 
       
 11459 /******************************************************************************/
       
 11460 #ifndef WITH_NOHTTP
       
 11461 #ifndef PALM_1
       
 11462 static int
       
 11463 http_parse(struct soap *soap)
       
 11464 { char header[SOAP_HDRLEN], *s;
       
 11465   unsigned short get = 0, status = 0, k = 0;
       
 11466   DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Waiting for HTTP request/response...\n"));
       
 11467   *soap->endpoint = '\0';
       
 11468   soap->length = 0;
       
 11469   soap->userid = NULL;
       
 11470   soap->passwd = NULL;
       
 11471   soap->action = NULL;
       
 11472   soap->authrealm = NULL;
       
 11473   do
       
 11474   { if (soap_getline(soap, soap->msgbuf, sizeof(soap->msgbuf)))
       
 11475       return soap->error;
       
 11476     DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP status: %s\n", soap->msgbuf));
       
 11477     for (;;)
       
 11478     { if (soap_getline(soap, header, SOAP_HDRLEN))
       
 11479       { if (soap->error == SOAP_EOF)
       
 11480 	{ soap->error = SOAP_OK;
       
 11481           DBGLOG(TEST,SOAP_MESSAGE(fdebug, "EOF in HTTP header, continue anyway\n"));
       
 11482 	  break;
       
 11483 	}
       
 11484         return soap->error;
       
 11485       }
       
 11486       if (!*header)
       
 11487         break;
       
 11488       DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP header: %s\n", header));
       
 11489       s = strchr(header, ':');
       
 11490       if (s)
       
 11491       { *s = '\0';
       
 11492         do s++;
       
 11493         while (*s && *s <= 32);
       
 11494         if ((soap->error = soap->fparsehdr(soap, header, s)))
       
 11495         { if (soap->error < SOAP_STOP)
       
 11496 	    return soap->error;
       
 11497 	  status = soap->error;
       
 11498 	  soap->error = SOAP_OK;
       
 11499         }
       
 11500       }
       
 11501     }
       
 11502     if ((s = strchr(soap->msgbuf, ' ')))
       
 11503     { k = (unsigned short)soap_strtoul(s, &s, 10);
       
 11504       if (!soap_blank(*s))
       
 11505         k = 0;
       
 11506     }
       
 11507     else
       
 11508       k = 0;
       
 11509   } while (k == 100);
       
 11510   DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Finished HTTP header parsing\n"));
       
 11511   s = strstr(soap->msgbuf, "HTTP/");
       
 11512   if (s && s[7] != '1')
       
 11513   { if (soap->keep_alive == 1)
       
 11514       soap->keep_alive = 0;
       
 11515     if (k == 0 && (soap->omode & SOAP_IO) == SOAP_IO_CHUNK) /* k == 0 for HTTP request */
       
 11516     { soap->imode |= SOAP_IO_CHUNK;
       
 11517       soap->omode = (soap->omode & ~SOAP_IO) | SOAP_IO_STORE;
       
 11518     }
       
 11519   }
       
 11520   if (soap->keep_alive < 0)
       
 11521     soap->keep_alive = 1;
       
 11522   DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Keep alive connection = %d\n", soap->keep_alive));
       
 11523   if (s && (((get = !strncmp(soap->msgbuf, "GET ", 4))) || !strncmp(soap->msgbuf, "POST ", 5)))
       
 11524   { size_t m = strlen(soap->endpoint);
       
 11525     size_t n = m + (s - soap->msgbuf) - 5 - (!get);
       
 11526     if (n >= sizeof(soap->endpoint))
       
 11527       n = sizeof(soap->endpoint) - 1;
       
 11528     strncpy(soap->path, soap->msgbuf + 4 + (!get), n - m);
       
 11529     soap->path[n - m] = '\0';
       
 11530     strcat(soap->endpoint, soap->path);
       
 11531     DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Target endpoint='%s'\n", soap->endpoint));
       
 11532     if (get)
       
 11533     { soap->error = soap->fget(soap);
       
 11534       if (soap->error == SOAP_OK)
       
 11535         soap->error = SOAP_STOP; /* prevents further processing */
       
 11536       return soap->error;
       
 11537     }
       
 11538     if (status)
       
 11539       return soap->error = status;
       
 11540     return SOAP_OK;
       
 11541   }
       
 11542   if (k == 0 || (k >= 200 && k <= 299) || k == 400 || k == 500)
       
 11543     return SOAP_OK;
       
 11544   DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP error %d\n", k));
       
 11545   return soap_set_receiver_error(soap, "HTTP error", soap->msgbuf, k);
       
 11546 }
       
 11547 #endif
       
 11548 #endif
       
 11549 
       
 11550 /******************************************************************************/
       
 11551 #ifndef WITH_NOHTTP
       
 11552 #ifndef PALM_1
       
 11553 static int
       
 11554 http_parse_header(struct soap *soap, const char *key, const char *val)
       
 11555 { if (!soap_tag_cmp(key, "Host"))
       
 11556   { 
       
 11557 #ifdef WITH_OPENSSL
       
 11558     if (soap->imode & SOAP_ENC_SSL)
       
 11559       strcpy(soap->endpoint, "https://");
       
 11560     else
       
 11561 #endif
       
 11562       strcpy(soap->endpoint, "http://");
       
 11563     strncat(soap->endpoint, val, sizeof(soap->endpoint) - 8);
       
 11564     soap->endpoint[sizeof(soap->endpoint) - 1] = '\0';
       
 11565   }
       
 11566 #ifndef WITH_LEANER
       
 11567   else if (!soap_tag_cmp(key, "Content-Type"))
       
 11568   { if (soap_get_header_attribute(soap, val, "application/dime"))
       
 11569       soap->mode |= SOAP_ENC_DIME;
       
 11570     else if (soap_get_header_attribute(soap, val, "multipart/related")
       
 11571           || soap_get_header_attribute(soap, val, "multipart/form-data"))
       
 11572     { soap->mime.boundary = soap_strdup(soap, soap_get_header_attribute(soap, val, "boundary"));
       
 11573       soap->mime.start = soap_strdup(soap, soap_get_header_attribute(soap, val, "start"));
       
 11574       soap->mode |= SOAP_ENC_MIME;
       
 11575     }
       
 11576   }
       
 11577 #endif
       
 11578   else if (!soap_tag_cmp(key, "Content-Length"))
       
 11579     soap->length = soap_strtoul(val, NULL, 10);
       
 11580   else if (!soap_tag_cmp(key, "Content-Encoding"))
       
 11581   { if (!soap_tag_cmp(val, "deflate"))
       
 11582 #ifdef WITH_ZLIB
       
 11583       soap->zlib_in = SOAP_ZLIB_DEFLATE;
       
 11584 #else
       
 11585       return SOAP_ZLIB_ERROR;
       
 11586 #endif
       
 11587     else if (!soap_tag_cmp(val, "gzip"))
       
 11588 #ifdef WITH_GZIP
       
 11589       soap->zlib_in = SOAP_ZLIB_GZIP;
       
 11590 #else
       
 11591       return SOAP_ZLIB_ERROR;
       
 11592 #endif
       
 11593   }
       
 11594 #ifdef WITH_ZLIB
       
 11595   else if (!soap_tag_cmp(key, "Accept-Encoding"))
       
 11596   {
       
 11597 #ifdef WITH_GZIP
       
 11598     if (strchr(val, '*') || soap_get_header_attribute(soap, val, "gzip"))
       
 11599       soap->zlib_out = SOAP_ZLIB_GZIP;
       
 11600     else
       
 11601 #endif
       
 11602     if (strchr(val, '*') || soap_get_header_attribute(soap, val, "deflate"))
       
 11603       soap->zlib_out = SOAP_ZLIB_DEFLATE;
       
 11604     else
       
 11605       soap->zlib_out = SOAP_ZLIB_NONE;
       
 11606   }
       
 11607 #endif
       
 11608   else if (!soap_tag_cmp(key, "Transfer-Encoding"))
       
 11609   { soap->mode &= ~SOAP_IO;
       
 11610     if (!soap_tag_cmp(val, "chunked"))
       
 11611       soap->mode |= SOAP_IO_CHUNK;
       
 11612   }
       
 11613   else if (!soap_tag_cmp(key, "Connection"))
       
 11614   { if (!soap_tag_cmp(val, "keep-alive"))
       
 11615       soap->keep_alive = -soap->keep_alive;
       
 11616     else if (!soap_tag_cmp(val, "close"))
       
 11617       soap->keep_alive = 0;
       
 11618   }
       
 11619 #ifndef WITH_LEAN
       
 11620   else if (!soap_tag_cmp(key, "Authorization"))
       
 11621   { if (!soap_tag_cmp(val, "Basic *"))
       
 11622     { int n;
       
 11623       char *s;
       
 11624       soap_base642s(soap, val + 6, soap->tmpbuf, sizeof(soap->tmpbuf) - 1, &n);
       
 11625       soap->tmpbuf[n] = '\0';
       
 11626       if ((s = strchr(soap->tmpbuf, ':')))
       
 11627       { *s = '\0';
       
 11628 	soap->userid = soap_strdup(soap, soap->tmpbuf);
       
 11629 	soap->passwd = soap_strdup(soap, s + 1);
       
 11630       }
       
 11631     }
       
 11632   }
       
 11633   else if (!soap_tag_cmp(key, "WWW-Authenticate"))
       
 11634     soap->authrealm = soap_strdup(soap, soap_get_header_attribute(soap, val + 6, "realm"));
       
 11635   else if (!soap_tag_cmp(key, "Expect"))
       
 11636   { if (!soap_tag_cmp(val, "100-continue"))
       
 11637     { if ((soap->error = soap->fposthdr(soap, "HTTP/1.1 100 Continue", NULL))
       
 11638        || (soap->error = soap->fposthdr(soap, NULL, NULL)))
       
 11639         return soap->error;
       
 11640     }
       
 11641   }
       
 11642 #endif
       
 11643   else if (!soap_tag_cmp(key, "SOAPAction"))
       
 11644   { if (*val == '"')
       
 11645     { soap->action = soap_strdup(soap, val + 1);
       
 11646       soap->action[strlen(soap->action) - 1] = '\0';
       
 11647     }
       
 11648   }
       
 11649   else if (!soap_tag_cmp(key, "Location"))
       
 11650   { strncpy(soap->endpoint, val, sizeof(soap->endpoint));
       
 11651     soap->endpoint[sizeof(soap->endpoint) - 1] = '\0';
       
 11652   }
       
 11653 #ifdef WITH_COOKIES
       
 11654   else if (!soap_tag_cmp(key, "Cookie") || !soap_tag_cmp(key, "Set-Cookie"))
       
 11655     soap_getcookies(soap, val);
       
 11656 #endif
       
 11657   return SOAP_OK;
       
 11658 }
       
 11659 #endif
       
 11660 #endif
       
 11661 
       
 11662 /******************************************************************************/
       
 11663 #if !defined(WITH_NOHTTP) || !defined(WITH_LEANER)
       
 11664 #ifndef PALM_1
       
 11665 SOAP_FMAC1
       
 11666 const char*
       
 11667 SOAP_FMAC2
       
 11668 soap_get_header_attribute(struct soap *soap, const char *line, const char *key)
       
 11669 { register const char *s = line;
       
 11670   if (s)
       
 11671   { while (*s)
       
 11672     { register short flag;
       
 11673       s = soap_decode_key(soap->tmpbuf, sizeof(soap->tmpbuf), s);
       
 11674       flag = soap_tag_cmp(soap->tmpbuf, key);
       
 11675       s = soap_decode_val(soap->tmpbuf, sizeof(soap->tmpbuf), s);
       
 11676       if (!flag)
       
 11677         return soap->tmpbuf;
       
 11678     }
       
 11679   }
       
 11680   return NULL;
       
 11681 }
       
 11682 #endif
       
 11683 #endif
       
 11684 
       
 11685 /******************************************************************************/
       
 11686 #if !defined(WITH_NOHTTP) || !defined(WITH_LEANER)
       
 11687 #ifndef PALM_1
       
 11688 SOAP_FMAC1
       
 11689 const char*
       
 11690 SOAP_FMAC2
       
 11691 soap_decode_key(char *buf, size_t len, const char *val)
       
 11692 { return soap_decode(buf, len, val, "=,;");
       
 11693 }
       
 11694 #endif
       
 11695 #endif
       
 11696 
       
 11697 /******************************************************************************/
       
 11698 #if !defined(WITH_NOHTTP) || !defined(WITH_LEANER)
       
 11699 #ifndef PALM_1
       
 11700 SOAP_FMAC1
       
 11701 const char*
       
 11702 SOAP_FMAC2
       
 11703 soap_decode_val(char *buf, size_t len, const char *val)
       
 11704 { if (*val != '=')
       
 11705   { *buf = '\0';
       
 11706     return val;
       
 11707   }
       
 11708   return soap_decode(buf, len, val + 1, ",;");
       
 11709 }
       
 11710 #endif
       
 11711 #endif
       
 11712 
       
 11713 /******************************************************************************/
       
 11714 #if !defined(WITH_NOHTTP) || !defined(WITH_LEANER)
       
 11715 #ifndef PALM_1
       
 11716 static const char*
       
 11717 soap_decode(char *buf, size_t len, const char *val, const char *sep)
       
 11718 { const char *s;
       
 11719   char *t = buf;
       
 11720   for (s = val; *s; s++)
       
 11721     if (*s != ' ' && *s != '\t' && !strchr(sep, *s))
       
 11722       break;
       
 11723   if (*s == '"')
       
 11724   { s++;
       
 11725     while (*s && *s != '"' && --len)
       
 11726       *t++ = *s++;
       
 11727   }
       
 11728   else
       
 11729   { while (soap_notblank(*s) && !strchr(sep, *s) && --len)
       
 11730     { if (*s == '%')
       
 11731       { *t++ = ((s[1] >= 'A' ? (s[1] & 0x7) + 9 : s[1] - '0') << 4)
       
 11732               + (s[2] >= 'A' ? (s[2] & 0x7) + 9 : s[2] - '0');
       
 11733         s += 3;
       
 11734       }
       
 11735       else
       
 11736         *t++ = *s++;
       
 11737     }
       
 11738   }
       
 11739   *t = '\0';
       
 11740   while (*s && !strchr(sep, *s))
       
 11741     s++;
       
 11742   return s;
       
 11743 }
       
 11744 #endif
       
 11745 #endif
       
 11746 
       
 11747 /******************************************************************************/
       
 11748 #ifndef PALM_2
       
 11749 SOAP_FMAC1
       
 11750 int
       
 11751 SOAP_FMAC2
       
 11752 soap_envelope_begin_out(struct soap *soap)
       
 11753 {
       
 11754 #ifndef WITH_LEANER
       
 11755   size_t n = 0;
       
 11756   if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary && soap->mime.start)
       
 11757   { const char *s;
       
 11758     if ((soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM))
       
 11759       s = "application/dime";
       
 11760     else if (soap->version == 2)
       
 11761       s = "application/soap+xml; charset=utf-8";
       
 11762     else
       
 11763       s = "text/xml; charset=utf-8";
       
 11764     sprintf(soap->tmpbuf, "--%s\r\nContent-Type: %s\r\nContent-Transfer-Encoding: binary\r\nContent-ID: %s\r\n\r\n", soap->mime.boundary, s, soap->mime.start);
       
 11765     n = strlen(soap->tmpbuf);
       
 11766     if (soap_send_raw(soap, soap->tmpbuf, n))
       
 11767       return soap->error;
       
 11768   }
       
 11769   if (soap->mode & SOAP_IO_LENGTH)
       
 11770     soap->dime.size = soap->count;	/* DIME in MIME correction */
       
 11771   if (!(soap->mode & SOAP_IO_LENGTH) && (soap->mode & SOAP_ENC_DIME))
       
 11772   { if (soap_putdimehdr(soap))
       
 11773       return soap->error;
       
 11774   }
       
 11775 #endif
       
 11776   soap->part = SOAP_IN_ENVELOPE;
       
 11777   return soap_element_begin_out(soap, "SOAP-ENV:Envelope", 0, NULL);
       
 11778 }
       
 11779 #endif
       
 11780 
       
 11781 /******************************************************************************/
       
 11782 #ifndef PALM_2
       
 11783 SOAP_FMAC1
       
 11784 int
       
 11785 SOAP_FMAC2
       
 11786 soap_envelope_end_out(struct soap *soap)
       
 11787 { if (soap_element_end_out(soap, "SOAP-ENV:Envelope"))
       
 11788     return soap->error;
       
 11789 #ifndef WITH_LEANER
       
 11790   if ((soap->mode & SOAP_IO_LENGTH) && (soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM))
       
 11791   { soap->dime.size = soap->count - soap->dime.size;	/* DIME in MIME correction */
       
 11792     sprintf(soap->id, soap->dime_id_format, 0);
       
 11793     soap->dime.id = soap->id;
       
 11794     if (soap->local_namespaces)
       
 11795     { if (soap->local_namespaces[0].out)
       
 11796         soap->dime.type = (char*)soap->local_namespaces[0].out;
       
 11797       else
       
 11798         soap->dime.type = (char*)soap->local_namespaces[0].ns;
       
 11799     }
       
 11800     soap->dime.options = NULL;
       
 11801     soap->dime.flags = SOAP_DIME_MB | SOAP_DIME_ABSURI;
       
 11802     if (!soap->dime.first)
       
 11803       soap->dime.flags |= SOAP_DIME_ME;
       
 11804     soap->count += 12 + ((strlen(soap->dime.id)+3)&(~3)) + ((strlen(soap->dime.type)+3)&(~3));
       
 11805   }
       
 11806   if ((soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM))
       
 11807     return soap_send_raw(soap, SOAP_STR_PADDING, -(long)soap->dime.size&3);
       
 11808 #endif
       
 11809   soap->part = SOAP_END_ENVELOPE;
       
 11810   return SOAP_OK;
       
 11811 } 
       
 11812 #endif
       
 11813 
       
 11814 /******************************************************************************/
       
 11815 #ifndef PALM_1
       
 11816 SOAP_FMAC1
       
 11817 int
       
 11818 SOAP_FMAC2
       
 11819 soap_envelope_begin_in(struct soap *soap)
       
 11820 { register struct Namespace *p;
       
 11821   soap->part = SOAP_IN_ENVELOPE;
       
 11822   if (soap_element_begin_in(soap, "SOAP-ENV:Envelope", 0))
       
 11823     return soap->error = SOAP_VERSIONMISMATCH;
       
 11824   p = soap->local_namespaces;
       
 11825   if (p)
       
 11826   { const char *ns = p[0].out;
       
 11827     if (!ns)
       
 11828       ns = p[0].ns;
       
 11829     if (!strcmp(ns, soap_env1))
       
 11830     { soap->version = 1; /* make sure we use SOAP 1.1 */
       
 11831       if (p[1].out)
       
 11832         SOAP_FREE(soap, p[1].out);
       
 11833       if ((p[1].out = (char*)SOAP_MALLOC(soap, sizeof(soap_enc1))))
       
 11834         strcpy(p[1].out, soap_enc1);
       
 11835     }
       
 11836     else if (!strcmp(ns, soap_env2))
       
 11837     { soap->version = 2; /* make sure we use SOAP 1.2 */
       
 11838       if (p[1].out)
       
 11839         SOAP_FREE(soap, p[1].out);
       
 11840       if ((p[1].out = (char*)SOAP_MALLOC(soap, sizeof(soap_enc2))))
       
 11841         strcpy(p[1].out, soap_enc2);
       
 11842     }
       
 11843   }
       
 11844   return SOAP_OK;
       
 11845 }
       
 11846 #endif
       
 11847 
       
 11848 /******************************************************************************/
       
 11849 #ifndef PALM_1
       
 11850 SOAP_FMAC1
       
 11851 int
       
 11852 SOAP_FMAC2
       
 11853 soap_envelope_end_in(struct soap *soap)
       
 11854 { soap->part = SOAP_END_ENVELOPE;
       
 11855   return soap_element_end_in(soap, "SOAP-ENV:Envelope");
       
 11856 }
       
 11857 #endif
       
 11858 
       
 11859 /******************************************************************************/
       
 11860 #ifndef PALM_2
       
 11861 SOAP_FMAC1
       
 11862 int
       
 11863 SOAP_FMAC2
       
 11864 soap_body_begin_out(struct soap *soap)
       
 11865 { soap->part = SOAP_IN_BODY;
       
 11866   if (soap->version == 1)
       
 11867     soap->encoding = 1;
       
 11868 #ifndef WITH_LEAN
       
 11869   if ((soap->mode & SOAP_XML_SEC) && soap_set_attr(soap, "wsu:Id", "Body"))
       
 11870     return soap->error;
       
 11871 #endif
       
 11872   if (soap_element(soap, "SOAP-ENV:Body", 0, NULL))
       
 11873     return soap->error;
       
 11874   return soap_element_start_end_out(soap, NULL);
       
 11875 }
       
 11876 #endif
       
 11877 
       
 11878 /******************************************************************************/
       
 11879 #ifndef PALM_2
       
 11880 SOAP_FMAC1
       
 11881 int
       
 11882 SOAP_FMAC2
       
 11883 soap_body_end_out(struct soap *soap)
       
 11884 { if (soap_element_end_out(soap, "SOAP-ENV:Body"))
       
 11885     return soap->error;
       
 11886   soap->part = SOAP_END_BODY;
       
 11887   return SOAP_OK;
       
 11888 }
       
 11889 #endif
       
 11890 
       
 11891 /******************************************************************************/
       
 11892 #ifndef PALM_2
       
 11893 SOAP_FMAC1
       
 11894 int
       
 11895 SOAP_FMAC2
       
 11896 soap_body_begin_in(struct soap *soap)
       
 11897 { soap->part = SOAP_IN_BODY;
       
 11898   if (soap_element_begin_in(soap, "SOAP-ENV:Body", 0))
       
 11899     return soap->error;
       
 11900   if (!soap->body)
       
 11901     soap->part = SOAP_NO_BODY;
       
 11902   return SOAP_OK;
       
 11903 }
       
 11904 #endif
       
 11905 
       
 11906 /******************************************************************************/
       
 11907 #ifndef PALM_2
       
 11908 SOAP_FMAC1
       
 11909 int
       
 11910 SOAP_FMAC2
       
 11911 soap_body_end_in(struct soap *soap)
       
 11912 { if (soap->part == SOAP_NO_BODY)
       
 11913     return SOAP_OK;
       
 11914   soap->part = SOAP_END_BODY;
       
 11915   return soap_element_end_in(soap, "SOAP-ENV:Body");
       
 11916 }
       
 11917 #endif
       
 11918 
       
 11919 /******************************************************************************/
       
 11920 #ifndef PALM_2
       
 11921 SOAP_FMAC1
       
 11922 int
       
 11923 SOAP_FMAC2
       
 11924 soap_recv_header(struct soap *soap)
       
 11925 { if (soap_getheader(soap) && soap->error == SOAP_TAG_MISMATCH)
       
 11926     soap->error = SOAP_OK;
       
 11927   return soap->error;
       
 11928 }
       
 11929 #endif
       
 11930 
       
 11931 /******************************************************************************/
       
 11932 #ifndef PALM_1
       
 11933 SOAP_FMAC1
       
 11934 void
       
 11935 SOAP_FMAC2
       
 11936 soap_set_endpoint(struct soap *soap, const char *endpoint)
       
 11937 { register const char *s;
       
 11938   register size_t i, n;
       
 11939   soap->endpoint[0] = '\0';
       
 11940   soap->host[0] = '\0';
       
 11941   soap->path[0] = '/';
       
 11942   soap->path[1] = '\0';
       
 11943   soap->port = 80;
       
 11944   if (!endpoint || !*endpoint)
       
 11945     return;
       
 11946   if (!strncmp(endpoint, "https:", 6))
       
 11947     soap->port = 443;
       
 11948   strncpy(soap->endpoint, endpoint, sizeof(soap->endpoint) - 1);
       
 11949   s = strchr(endpoint, ':');
       
 11950   if (s && s[1] == '/' && s[2] == '/')
       
 11951     s += 3;
       
 11952   else
       
 11953     s = endpoint;
       
 11954   n = strlen(s);
       
 11955   if (n >= sizeof(soap->host))
       
 11956     n = sizeof(soap->host) - 1;
       
 11957 #ifdef WITH_IPV6
       
 11958   if (s[0] == '[')
       
 11959   { s++;
       
 11960     for (i = 0; i < n; i++)
       
 11961     { soap->host[i] = s[i];
       
 11962       if (s[i] == ']')
       
 11963       { s++;
       
 11964         break; 
       
 11965       }
       
 11966     }
       
 11967   }
       
 11968   else
       
 11969   { for (i = 0; i < n; i++)
       
 11970     { soap->host[i] = s[i];
       
 11971       if (s[i] == '/' || s[i] == ':')
       
 11972         break; 
       
 11973     }
       
 11974   }
       
 11975 #else
       
 11976   for (i = 0; i < n; i++)
       
 11977   { soap->host[i] = s[i];
       
 11978     if (s[i] == '/' || s[i] == ':')
       
 11979       break; 
       
 11980   }
       
 11981 #endif
       
 11982   soap->host[i] = '\0';
       
 11983   if (s[i] == ':')
       
 11984   { soap->port = (int)atol(s + i + 1);
       
 11985     for (i++; i < n; i++)
       
 11986       if (s[i] == '/')
       
 11987         break;
       
 11988   }
       
 11989   if (s[i])
       
 11990   { strncpy(soap->path, s + i, sizeof(soap->path));
       
 11991     soap->path[sizeof(soap->path) - 1] = '\0';
       
 11992   }
       
 11993 }
       
 11994 #endif
       
 11995 
       
 11996 /******************************************************************************/
       
 11997 #ifndef PALM_1
       
 11998 SOAP_FMAC1
       
 11999 int
       
 12000 SOAP_FMAC2
       
 12001 soap_connect(struct soap *soap, const char *endpoint, const char *action)
       
 12002 { return soap_connect_command(soap, SOAP_POST, endpoint, action);
       
 12003 }
       
 12004 #endif
       
 12005 
       
 12006 /******************************************************************************/
       
 12007 #ifndef PALM_1
       
 12008 SOAP_FMAC1
       
 12009 int
       
 12010 SOAP_FMAC2
       
 12011 soap_connect_command(struct soap *soap, int http_command, const char *endpoint, const char *action)
       
 12012 { char host[sizeof(soap->host)];
       
 12013   int port;
       
 12014   size_t count;
       
 12015   soap->error = SOAP_OK;
       
 12016   strcpy(host, soap->host); /* save to compare */
       
 12017   port = soap->port; /* save to compare */
       
 12018   soap_set_endpoint(soap, endpoint);
       
 12019 #ifndef WITH_LEANER
       
 12020   if (soap->fconnect)
       
 12021   { if ((soap->error = soap->fconnect(soap, endpoint, soap->host, soap->port)))
       
 12022       return soap->error;
       
 12023   }
       
 12024   else
       
 12025 #endif
       
 12026   if (soap->fopen && *soap->host)
       
 12027   { soap->status = http_command;
       
 12028     if (!soap->keep_alive || !soap_valid_socket(soap->socket) || strcmp(soap->host, host) || soap->port != port || !soap->fpoll || soap->fpoll(soap))
       
 12029     { soap->keep_alive = 0; /* to force close */
       
 12030       soap->omode &= ~SOAP_IO_UDP; /* to force close */
       
 12031       soap_closesock(soap);
       
 12032       DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Connect/reconnect to host='%s' path='%s' port=%d\n", soap->host, soap->path, soap->port));
       
 12033 #ifdef WITH_UDP
       
 12034       if (!strncmp(endpoint, "soap.udp:", 9))
       
 12035         soap->omode |= SOAP_IO_UDP;
       
 12036 #endif
       
 12037       soap->socket = soap->fopen(soap, endpoint, soap->host, soap->port);
       
 12038       if (soap->error)
       
 12039         return soap->error;
       
 12040       soap->keep_alive = ((soap->omode & SOAP_IO_KEEPALIVE) != 0);
       
 12041     }
       
 12042   }
       
 12043   count = soap_count_attachments(soap);
       
 12044   if (soap_begin_send(soap))
       
 12045     return soap->error;
       
 12046 #ifndef WITH_NOHTTP
       
 12047   if ((soap->mode & SOAP_IO) != SOAP_IO_STORE && !(soap->mode & SOAP_ENC_XML) && endpoint)
       
 12048   { unsigned int k = soap->mode;
       
 12049     soap->mode &= ~(SOAP_IO | SOAP_ENC_ZLIB);
       
 12050     if ((k & SOAP_IO) != SOAP_IO_FLUSH)
       
 12051       soap->mode |= SOAP_IO_BUFFER;
       
 12052     if ((soap->error = soap->fpost(soap, endpoint, soap->host, soap->port, soap->path, action, count)))
       
 12053       return soap->error;
       
 12054 #ifndef WITH_LEANER
       
 12055     if ((k & SOAP_IO) == SOAP_IO_CHUNK)
       
 12056     { if (soap_flush(soap))
       
 12057         return soap->error;
       
 12058     }
       
 12059 #endif
       
 12060     soap->mode = k;
       
 12061   }
       
 12062   else if (action)
       
 12063     soap->action = soap_strdup(soap, action);
       
 12064   if (http_command != SOAP_POST)
       
 12065     return soap_end_send(soap);
       
 12066 #endif
       
 12067   return SOAP_OK;
       
 12068 }
       
 12069 #endif
       
 12070 
       
 12071 /******************************************************************************/
       
 12072 #ifndef WITH_LEAN
       
 12073 SOAP_FMAC1
       
 12074 char*
       
 12075 SOAP_FMAC2
       
 12076 soap_s2base64(struct soap *soap, const unsigned char *s, char *t, int n)
       
 12077 { register int i;
       
 12078   register unsigned long m;
       
 12079   register char *p;
       
 12080   if (!t)
       
 12081     t = (char*)soap_malloc(soap, (n + 2) / 3 * 4 + 1);
       
 12082   if (!t)
       
 12083   { soap->error = SOAP_EOM;
       
 12084     return NULL;
       
 12085   }
       
 12086   p = t;
       
 12087   t[0] = '\0';
       
 12088   if (!s)
       
 12089     return p;
       
 12090   for (; n > 2; n -= 3, s += 3)
       
 12091   { m = s[0];
       
 12092     m = (m << 8) | s[1];
       
 12093     m = (m << 8) | s[2];
       
 12094     for (i = 4; i > 0; m >>= 6)
       
 12095       t[--i] = soap_base64o[m & 0x3F];
       
 12096     t += 4;
       
 12097   }
       
 12098   t[0] = '\0';
       
 12099   if (n > 0)
       
 12100   { m = 0;
       
 12101     for (i = 0; i < n; i++)
       
 12102       m = (m << 8) | *s++;
       
 12103     for (; i < 3; i++)
       
 12104       m <<= 8;
       
 12105     for (i++; i > 0; m >>= 6)
       
 12106       t[--i] = soap_base64o[m & 0x3F];
       
 12107     for (i = 3; i > n; i--)
       
 12108       t[i] = '=';
       
 12109     t[4] = '\0';
       
 12110   }
       
 12111   return p;
       
 12112 }
       
 12113 #endif
       
 12114 
       
 12115 /******************************************************************************/
       
 12116 #ifndef WITH_LEAN
       
 12117 SOAP_FMAC1
       
 12118 const char*
       
 12119 SOAP_FMAC2
       
 12120 soap_base642s(struct soap *soap, const char *s, char *t, size_t l, int *n)
       
 12121 { register int i, j, c;
       
 12122   register unsigned long m;
       
 12123   register const char *p;
       
 12124   if (!s || !*s)
       
 12125   { if (n)
       
 12126       *n = 0;
       
 12127     if (soap->error)
       
 12128       return NULL;
       
 12129     return SOAP_NON_NULL;
       
 12130   }
       
 12131   if (!t)
       
 12132   { l = (strlen(s) + 3) / 4 * 3;
       
 12133     t = (char*)soap_malloc(soap, l);
       
 12134   }
       
 12135   if (!t)
       
 12136   { soap->error = SOAP_EOM;
       
 12137     return NULL;
       
 12138   }
       
 12139   p = t;
       
 12140   if (n)
       
 12141     *n = 0;
       
 12142   for (;;)
       
 12143   { for (i = 0; i < SOAP_BLKLEN; i++)
       
 12144     { m = 0;
       
 12145       j = 0;
       
 12146       while (j < 4)
       
 12147       { c = *s++;
       
 12148         if (c == '=' || !c)
       
 12149         { i *= 3;
       
 12150           switch (j)
       
 12151           { case 2:
       
 12152               *t++ = (char)((m >> 4) & 0xFF);
       
 12153               i++;
       
 12154               break;
       
 12155             case 3:
       
 12156               *t++ = (char)((m >> 10) & 0xFF);
       
 12157               *t++ = (char)((m >> 2) & 0xFF);
       
 12158               i += 2;
       
 12159           }
       
 12160           if (n)
       
 12161 	    *n += i;
       
 12162           return p;
       
 12163         }
       
 12164         c -= '+';
       
 12165         if (c >= 0 && c <= 79)
       
 12166         { m = (m << 6) + soap_base64i[c];
       
 12167           j++;
       
 12168         }
       
 12169       }
       
 12170       *t++ = (char)((m >> 16) & 0xFF);
       
 12171       *t++ = (char)((m >> 8) & 0xFF);
       
 12172       *t++ = (char)(m & 0xFF);
       
 12173       if (l < 3)
       
 12174       { if (n)
       
 12175 	  *n += i;
       
 12176         return p;
       
 12177       }
       
 12178       l -= 3;
       
 12179     }
       
 12180     if (n)
       
 12181       *n += 3 * SOAP_BLKLEN;
       
 12182   }
       
 12183 }
       
 12184 #endif
       
 12185 
       
 12186 /******************************************************************************/
       
 12187 #ifndef WITH_LEAN
       
 12188 SOAP_FMAC1
       
 12189 char*
       
 12190 SOAP_FMAC2
       
 12191 soap_s2hex(struct soap *soap, const unsigned char *s, char *t, int n)
       
 12192 { register char *p;
       
 12193   if (!t)
       
 12194     t = (char*)soap_malloc(soap, 2 * n + 1);
       
 12195   if (!t)
       
 12196   { soap->error = SOAP_EOM;
       
 12197     return NULL;
       
 12198   }
       
 12199   p = t;
       
 12200   t[0] = '\0';
       
 12201   if (s)
       
 12202   { for (; n > 0; n--)
       
 12203     { register int m = *s++;
       
 12204       *t++ = (char)((m >> 4) + (m > 159 ? 'a' - 10 : '0'));
       
 12205       m &= 0x0F;
       
 12206       *t++ = (char)(m + (m > 9 ? 'a' - 10 : '0'));
       
 12207     }
       
 12208   }
       
 12209   *t++ = '\0';
       
 12210   return p;
       
 12211 }
       
 12212 #endif
       
 12213 
       
 12214 /******************************************************************************/
       
 12215 #ifndef WITH_LEAN
       
 12216 SOAP_FMAC1
       
 12217 const char*
       
 12218 SOAP_FMAC2
       
 12219 soap_hex2s(struct soap *soap, const char *s, char *t, size_t l, int *n)
       
 12220 { register const char *p;
       
 12221   if (!s || !*s)
       
 12222   { if (n)
       
 12223       *n = 0;
       
 12224     if (soap->error)
       
 12225       return NULL;
       
 12226     return SOAP_NON_NULL;
       
 12227   }
       
 12228   if (!t)
       
 12229   { l = strlen(s) / 2;
       
 12230     t = (char*)soap_malloc(soap, l);
       
 12231   }
       
 12232   if (!t)
       
 12233   { soap->error = SOAP_EOM;
       
 12234     return NULL;
       
 12235   }
       
 12236   p = t;
       
 12237   while (l)
       
 12238   { register int d1, d2;
       
 12239     d1 = *s++;
       
 12240     if (!d1)
       
 12241       break;
       
 12242     d2 = *s++;
       
 12243     if (!d2)
       
 12244       break;
       
 12245     *t++ = ((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0');
       
 12246     l--;
       
 12247   }
       
 12248   if (n)
       
 12249     *n = t - p;
       
 12250   return p;
       
 12251 }
       
 12252 #endif
       
 12253 
       
 12254 /******************************************************************************/
       
 12255 #ifndef WITH_NOHTTP
       
 12256 #ifndef PALM_1
       
 12257 SOAP_FMAC1
       
 12258 int
       
 12259 SOAP_FMAC2
       
 12260 soap_puthttphdr(struct soap *soap, int status, size_t count)
       
 12261 { register const char *s;
       
 12262 #ifndef WITH_LEANER
       
 12263   register const char *r = NULL;
       
 12264 #endif
       
 12265   register int err;
       
 12266   if (status == SOAP_FILE && soap->http_content)
       
 12267     s = soap->http_content;
       
 12268   else if (status == SOAP_HTML)
       
 12269     s = "text/html; charset=utf-8";
       
 12270   else if (soap->version == 2)
       
 12271     s = "application/soap+xml; charset=utf-8";
       
 12272   else
       
 12273     s = "text/xml; charset=utf-8";
       
 12274 #ifndef WITH_LEANER
       
 12275   if (soap->mode & (SOAP_ENC_DIME | SOAP_ENC_MTOM))
       
 12276   { if (soap->mode & SOAP_ENC_MTOM)
       
 12277     { r = s;
       
 12278       s = "application/xop+xml; charset=utf-8";
       
 12279     }
       
 12280     else
       
 12281       s = "application/dime";
       
 12282   }
       
 12283   if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary && soap->status != SOAP_GET)
       
 12284   { register const char *t = strchr(s, ';');
       
 12285     sprintf(soap->tmpbuf, "multipart/related; boundary=\"%s\"; type=\"", soap->mime.boundary);
       
 12286     if (t)
       
 12287       strncat(soap->tmpbuf, s, t - s);
       
 12288     else
       
 12289       strcat(soap->tmpbuf, s);
       
 12290     if (soap->mime.start)
       
 12291     { strcat(soap->tmpbuf, "\"; start=\"");
       
 12292       strcat(soap->tmpbuf, soap->mime.start);
       
 12293     }
       
 12294     strcat(soap->tmpbuf, "\"");
       
 12295     if (r)
       
 12296     { strcat(soap->tmpbuf, "; start-info=\"");
       
 12297       strcat(soap->tmpbuf, r);
       
 12298       strcat(soap->tmpbuf, "\"");
       
 12299     }
       
 12300     s = soap->tmpbuf;
       
 12301   }
       
 12302 #endif
       
 12303   if ((err = soap->fposthdr(soap, "Content-Type", s)))
       
 12304     return err;
       
 12305 #ifdef WITH_ZLIB
       
 12306   if (soap->omode & SOAP_ENC_ZLIB)
       
 12307   {
       
 12308 #ifdef WITH_GZIP
       
 12309     err = soap->fposthdr(soap, "Content-Encoding", "gzip");
       
 12310 #else
       
 12311     err = soap->fposthdr(soap, "Content-Encoding", "deflate");
       
 12312 #endif
       
 12313     if (err)
       
 12314       return err;
       
 12315   }
       
 12316 #endif
       
 12317 #ifndef WITH_LEANER
       
 12318   if ((soap->omode & SOAP_IO) == SOAP_IO_CHUNK)
       
 12319     err = soap->fposthdr(soap, "Transfer-Encoding", "chunked");
       
 12320   else
       
 12321 #endif
       
 12322   if (count > 0)
       
 12323   { sprintf(soap->tmpbuf, "%lu", (unsigned long)count);
       
 12324     err = soap->fposthdr(soap, "Content-Length", soap->tmpbuf);
       
 12325   }
       
 12326   if (err)
       
 12327     return err;
       
 12328   return soap->fposthdr(soap, "Connection", soap->keep_alive ? "keep-alive" : "close");
       
 12329 }
       
 12330 #endif
       
 12331 #endif
       
 12332 
       
 12333 /******************************************************************************/
       
 12334 #ifndef WITH_NOHTTP
       
 12335 #ifndef PALM_1
       
 12336 static int
       
 12337 http_get(struct soap *soap)
       
 12338 { return SOAP_GET_METHOD;
       
 12339 }
       
 12340 #endif
       
 12341 #endif
       
 12342 
       
 12343 /******************************************************************************/
       
 12344 #ifndef WITH_NOHTTP
       
 12345 #ifndef PALM_1
       
 12346 static int
       
 12347 http_post(struct soap *soap, const char *endpoint, const char *host, int port, const char *path, const char *action, size_t count)
       
 12348 { register const char *s;
       
 12349   register int err;
       
 12350   if (soap->status == SOAP_GET)
       
 12351   { s = "GET";
       
 12352     count = 0;
       
 12353   }
       
 12354   else
       
 12355     s = "POST";
       
 12356 #ifdef PALM
       
 12357   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))
       
 12358 #else
       
 12359   if (!endpoint || (strncmp(endpoint, "http:", 5) && strncmp(endpoint, "https:", 6) && strncmp(endpoint, "httpg:", 6)))
       
 12360 #endif
       
 12361     return SOAP_OK;
       
 12362   if (soap->proxy_host && strncmp(endpoint, "https:", 6))
       
 12363     sprintf(soap->tmpbuf, "%s %s HTTP/%s", s, endpoint, soap->http_version);
       
 12364   else
       
 12365     sprintf(soap->tmpbuf, "%s /%s HTTP/%s", s, (*path == '/' ? path + 1 : path), soap->http_version);
       
 12366   if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL)))
       
 12367     return err;
       
 12368   if (port != 80)
       
 12369     sprintf(soap->tmpbuf, "%s:%d", host, port);
       
 12370   else
       
 12371     strcpy(soap->tmpbuf, host); 
       
 12372   if ((err = soap->fposthdr(soap, "Host", soap->tmpbuf))
       
 12373    || (err = soap->fposthdr(soap, "User-Agent", "gSOAP/2.7"))
       
 12374    || (err = soap_puthttphdr(soap, SOAP_OK, count)))
       
 12375     return err;
       
 12376 #ifdef WITH_ZLIB
       
 12377 #ifdef WITH_GZIP
       
 12378   if ((err = soap->fposthdr(soap, "Accept-Encoding", "gzip, deflate")))
       
 12379 #else
       
 12380   if ((err = soap->fposthdr(soap, "Accept-Encoding", "deflate")))
       
 12381 #endif
       
 12382     return err;
       
 12383 #endif
       
 12384 #ifndef WITH_LEAN
       
 12385   if (soap->userid && soap->passwd && strlen(soap->userid) + strlen(soap->passwd) < 761)
       
 12386   { sprintf(soap->tmpbuf + 262, "%s:%s", soap->userid, soap->passwd);
       
 12387     strcpy(soap->tmpbuf, "Basic ");
       
 12388     soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, strlen(soap->tmpbuf + 262));
       
 12389     if ((err = soap->fposthdr(soap, "Authorization", soap->tmpbuf)))
       
 12390       return err;
       
 12391   }
       
 12392   if (soap->proxy_userid && soap->proxy_passwd && strlen(soap->proxy_userid) + strlen(soap->proxy_passwd) < 761)
       
 12393   { sprintf(soap->tmpbuf + 262, "%s:%s", soap->proxy_userid, soap->proxy_passwd);
       
 12394     strcpy(soap->tmpbuf, "Basic ");
       
 12395     soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, strlen(soap->tmpbuf + 262));
       
 12396     if ((err = soap->fposthdr(soap, "Proxy-Authorization", soap->tmpbuf)))
       
 12397       return err;
       
 12398   }
       
 12399 #endif
       
 12400 #ifdef WITH_COOKIES
       
 12401 #ifdef WITH_OPENSSL
       
 12402   if (soap_putcookies(soap, host, path, soap->ssl != NULL))
       
 12403     return soap->error;
       
 12404 #else
       
 12405   if (soap_putcookies(soap, host, path, 0))
       
 12406     return soap->error;
       
 12407 #endif
       
 12408 #endif
       
 12409   if (action && soap->version == 1)
       
 12410   { sprintf(soap->tmpbuf, "\"%s\"", action);
       
 12411     if ((err = soap->fposthdr(soap, "SOAPAction", soap->tmpbuf)))
       
 12412       return err;
       
 12413   }
       
 12414   return soap->fposthdr(soap, NULL, NULL);
       
 12415 }
       
 12416 #endif
       
 12417 #endif
       
 12418 
       
 12419 /******************************************************************************/
       
 12420 #ifndef WITH_NOHTTP
       
 12421 #ifndef PALM_1
       
 12422 static int
       
 12423 http_send_header(struct soap *soap, const char *s)
       
 12424 { register const char *t;
       
 12425   do
       
 12426   { t = strchr(s, '\n'); /* disallow \n in HTTP headers */
       
 12427     if (!t)
       
 12428       t = s + strlen(s);
       
 12429     if (soap_send_raw(soap, s, t - s))
       
 12430       return soap->error;
       
 12431     s = t + 1;
       
 12432   } while (*t);
       
 12433   return SOAP_OK;
       
 12434 }
       
 12435 #endif
       
 12436 #endif
       
 12437 
       
 12438 /******************************************************************************/
       
 12439 #ifndef WITH_NOHTTP
       
 12440 #ifndef PALM_1
       
 12441 static int
       
 12442 http_post_header(struct soap *soap, const char *key, const char *val)
       
 12443 { if (key)
       
 12444   { if (http_send_header(soap, key))
       
 12445       return soap->error;
       
 12446     if (val && (soap_send_raw(soap, ": ", 2) || http_send_header(soap, val)))
       
 12447       return soap->error;
       
 12448   }
       
 12449   return soap_send_raw(soap, "\r\n", 2);
       
 12450 }
       
 12451 #endif
       
 12452 #endif
       
 12453 
       
 12454 /******************************************************************************/
       
 12455 #ifndef WITH_NOHTTP
       
 12456 #ifndef PALM_1
       
 12457 static int
       
 12458 http_response(struct soap *soap, int status, size_t count)
       
 12459 { register int err;
       
 12460 #ifdef WMW_RPM_IO
       
 12461   if (soap->rpmreqid)
       
 12462     httpOutputEnable(soap->rpmreqid);
       
 12463 #endif  /* WMW_RPM_IO */
       
 12464   if (!status || status == SOAP_HTML || status == SOAP_FILE)
       
 12465   { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "OK 200\n"));
       
 12466 #ifdef WMW_RPM_IO
       
 12467     if (soap->rpmreqid || soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* RPM behaves as if standalone */
       
 12468 #else
       
 12469     if (soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* standalone application */
       
 12470 #endif /* WMW_RPM_IO */
       
 12471     { sprintf(soap->tmpbuf, "HTTP/%s 200 OK", soap->http_version);
       
 12472       if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL)))
       
 12473         return err;
       
 12474     }
       
 12475     else if ((err = soap->fposthdr(soap, "Status", "200 OK")))
       
 12476       return err;
       
 12477   }
       
 12478   else if (status > 200 && status < 600)
       
 12479   { sprintf(soap->tmpbuf, "HTTP/%s %d %s", soap->http_version, status, http_error(soap, status));
       
 12480     if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL)))
       
 12481       return err;
       
 12482 #ifndef WITH_LEAN 
       
 12483     if (status == 401)
       
 12484     { sprintf(soap->tmpbuf, "Basic realm=\"%s\"", soap->authrealm ? soap->authrealm : "gSOAP Web Service");
       
 12485       if ((err = soap->fposthdr(soap, "WWW-Authenticate", soap->tmpbuf)))
       
 12486         return err;
       
 12487     }
       
 12488     else if ((status >= 301 && status <= 303) || status == 307)
       
 12489     { if ((err = soap->fposthdr(soap, "Location", soap->endpoint)))
       
 12490         return err;
       
 12491     }
       
 12492 #endif
       
 12493   }
       
 12494   else
       
 12495   { const char *s = *soap_faultcode(soap);
       
 12496     if (soap->version == 2 && !strcmp(s, "SOAP-ENV:Sender"))
       
 12497       s = "400 Bad Request";
       
 12498     else
       
 12499       s = "500 Internal Server Error";
       
 12500     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error %s (status=%d)\n", s, status));
       
 12501 #ifdef WMW_RPM_IO
       
 12502     if (soap->rpmreqid || soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* RPM behaves as if standalone */
       
 12503 #else
       
 12504     if (soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* standalone application */
       
 12505 #endif /* WMW_RPM_IO */
       
 12506     { sprintf(soap->tmpbuf, "HTTP/%s %s", soap->http_version, s);
       
 12507       if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL)))
       
 12508         return err;
       
 12509     }
       
 12510     else if ((err = soap->fposthdr(soap, "Status", s)))
       
 12511       return err;
       
 12512   }
       
 12513   if ((err = soap->fposthdr(soap, "Server", "gSOAP/2.7"))
       
 12514    || (err = soap_puthttphdr(soap, status, count)))
       
 12515     return err;
       
 12516 #ifdef WITH_COOKIES
       
 12517   if (soap_putsetcookies(soap))
       
 12518     return soap->error;
       
 12519 #endif
       
 12520   return soap->fposthdr(soap, NULL, NULL);
       
 12521 }
       
 12522 #endif
       
 12523 #endif
       
 12524 
       
 12525 /******************************************************************************/
       
 12526 #ifndef PALM_1
       
 12527 SOAP_FMAC1
       
 12528 int
       
 12529 SOAP_FMAC2
       
 12530 soap_response(struct soap *soap, int status)
       
 12531 { register size_t count;
       
 12532   if (!(soap->omode & (SOAP_ENC_XML | SOAP_IO_STORE /* this tests for chunking too */))
       
 12533    && (status == SOAP_HTML || status == SOAP_FILE))
       
 12534   { soap->omode &= ~SOAP_IO;
       
 12535     soap->omode |= SOAP_IO_STORE;
       
 12536   }
       
 12537   soap->status = status;
       
 12538   count = soap_count_attachments(soap);
       
 12539   if (soap_begin_send(soap))
       
 12540     return soap->error;
       
 12541 #ifndef WITH_NOHTTP
       
 12542   if ((soap->mode & SOAP_IO) != SOAP_IO_STORE && !(soap->mode & SOAP_ENC_XML))
       
 12543   { register int n = soap->mode;
       
 12544     soap->mode &= ~(SOAP_IO | SOAP_ENC_ZLIB);
       
 12545     if ((n & SOAP_IO) != SOAP_IO_FLUSH)
       
 12546       soap->mode |= SOAP_IO_BUFFER;
       
 12547     if ((soap->error = soap->fresponse(soap, status, count)))
       
 12548       return soap->error;
       
 12549 #ifndef WITH_LEANER
       
 12550     if ((n & SOAP_IO) == SOAP_IO_CHUNK)
       
 12551     { if (soap_flush(soap))
       
 12552         return soap->error;
       
 12553     }
       
 12554 #endif
       
 12555     soap->mode = n;
       
 12556   }
       
 12557 #endif
       
 12558   return SOAP_OK;
       
 12559 }
       
 12560 #endif
       
 12561 
       
 12562 /******************************************************************************/
       
 12563 #ifndef WITH_LEAN
       
 12564 static const char*
       
 12565 soap_set_validation_fault(struct soap *soap, const char *s, const char *t)
       
 12566 { if (*soap->tag)
       
 12567     sprintf(soap->msgbuf, "Validation constraint violation: %s%s in element <%s>", s, t?t:SOAP_STR_EOS, soap->tag);
       
 12568   else
       
 12569     sprintf(soap->msgbuf, "Validation constraint violation: %s%s", s, t?t:SOAP_STR_EOS);
       
 12570   return soap->msgbuf;
       
 12571 }
       
 12572 #endif
       
 12573 
       
 12574 /******************************************************************************/
       
 12575 #ifndef PALM_1
       
 12576 SOAP_FMAC1
       
 12577 void
       
 12578 SOAP_FMAC2
       
 12579 soap_set_fault(struct soap *soap)
       
 12580 { const char **c = soap_faultcode(soap);
       
 12581   const char **s = soap_faultstring(soap);
       
 12582   if (!*c && !*s && soap->fseterror)
       
 12583     soap->fseterror(soap, c, s);
       
 12584   if (!*c)
       
 12585   { if (soap->version == 2)
       
 12586       *c = "SOAP-ENV:Sender";
       
 12587     else
       
 12588       *c = "SOAP-ENV:Client";
       
 12589   }
       
 12590   if (*s)
       
 12591     return;
       
 12592   switch (soap->error)
       
 12593   {
       
 12594 #ifndef WITH_LEAN
       
 12595     case SOAP_CLI_FAULT:
       
 12596       *s = "Client fault";
       
 12597       break;
       
 12598     case SOAP_SVR_FAULT:
       
 12599       *s = "Server fault";
       
 12600       break;
       
 12601     case SOAP_TAG_MISMATCH:
       
 12602       *s = soap_set_validation_fault(soap, "tag name or namespace mismatch", NULL);
       
 12603       break;
       
 12604     case SOAP_TYPE:
       
 12605       *s = soap_set_validation_fault(soap, "data type mismatch ", soap->type);
       
 12606       break;
       
 12607     case SOAP_SYNTAX_ERROR:
       
 12608       *s = "Well-formedness violation";
       
 12609       break;
       
 12610     case SOAP_NO_TAG:
       
 12611       *s = "No XML element tag";
       
 12612       break;
       
 12613     case SOAP_MUSTUNDERSTAND:
       
 12614       *c = "SOAP-ENV:MustUnderstand";
       
 12615       sprintf(soap->msgbuf, "The data in element '%s' must be understood but cannot be handled", soap->tag);
       
 12616       *s = soap->msgbuf;
       
 12617       break;
       
 12618     case SOAP_VERSIONMISMATCH:
       
 12619       *c = "SOAP-ENV:VersionMismatch";
       
 12620       *s = "SOAP version mismatch or invalid SOAP message";
       
 12621       break;
       
 12622     case SOAP_DATAENCODINGUNKNOWN:
       
 12623       *c = "SOAP-ENV:DataEncodingUnknown";
       
 12624       *s = "Unsupported SOAP data encoding";
       
 12625       break;
       
 12626     case SOAP_NAMESPACE:
       
 12627       *s = soap_set_validation_fault(soap, "namespace mismatch", NULL);
       
 12628       break;
       
 12629     case SOAP_USER_ERROR:
       
 12630       *s = "User error";
       
 12631       break;
       
 12632     case SOAP_FATAL_ERROR:
       
 12633       *s = "Fatal error";
       
 12634       break;
       
 12635     case SOAP_NO_METHOD:
       
 12636       sprintf(soap->msgbuf, "Method '%s' not implemented: method name or namespace not recognized", soap->tag);
       
 12637       *s = soap->msgbuf;
       
 12638       break;
       
 12639     case SOAP_GET_METHOD:
       
 12640       *s = "HTTP GET method not implemented";
       
 12641       break;
       
 12642     case SOAP_EOM:
       
 12643       *s = "Out of memory";
       
 12644       break;
       
 12645     case SOAP_IOB:
       
 12646       *s = "Array index out of bounds";
       
 12647       break;
       
 12648     case SOAP_NULL:
       
 12649       *s = soap_set_validation_fault(soap, "nil not allowed", NULL);
       
 12650       break;
       
 12651     case SOAP_DUPLICATE_ID:
       
 12652       *s = soap_set_validation_fault(soap, "multiple definitions of id ", soap->id);
       
 12653       if (soap->version == 2)
       
 12654         *soap_faultsubcode(soap) = "SOAP-ENC:DuplicateID";
       
 12655       break;
       
 12656     case SOAP_MISSING_ID:
       
 12657       *s = soap_set_validation_fault(soap, "missing id for ref ", soap->id);
       
 12658       if (soap->version == 2)
       
 12659         *soap_faultsubcode(soap) = "SOAP-ENC:MissingID";
       
 12660       break;
       
 12661     case SOAP_HREF:
       
 12662       *s = soap_set_validation_fault(soap, "incompatible object ref ", soap->id);
       
 12663       break;
       
 12664     case SOAP_FAULT:
       
 12665       break;
       
 12666 #ifndef WITH_NOIO
       
 12667     case SOAP_UDP_ERROR:
       
 12668       *s = "Message too large for UDP packet";
       
 12669       break;
       
 12670     case SOAP_TCP_ERROR:
       
 12671       *s = tcp_error(soap);
       
 12672       break;
       
 12673 #endif
       
 12674     case SOAP_HTTP_ERROR:
       
 12675       *s = "HTTP error";
       
 12676       break;
       
 12677     case SOAP_SSL_ERROR:
       
 12678 #ifdef WITH_OPENSSL
       
 12679       *s = "SSL error";
       
 12680 #else
       
 12681       *s = "OpenSSL not installed: recompile with -DWITH_OPENSSL";
       
 12682 #endif
       
 12683       break;
       
 12684     case SOAP_PLUGIN_ERROR:
       
 12685       *s = "Plugin registry error";
       
 12686       break;
       
 12687     case SOAP_DIME_ERROR:
       
 12688       *s = "DIME format error";
       
 12689       break;
       
 12690     case SOAP_DIME_HREF:
       
 12691       *s = "DIME href to missing attachment";
       
 12692       break;
       
 12693     case SOAP_DIME_MISMATCH:
       
 12694       *s = "DIME version/transmission error";
       
 12695       break;
       
 12696     case SOAP_DIME_END:
       
 12697       *s = "End of DIME error";
       
 12698       break;
       
 12699     case SOAP_MIME_ERROR:
       
 12700       *s = "MIME format error";
       
 12701       break;
       
 12702     case SOAP_MIME_HREF:
       
 12703       *s = "MIME href to missing attachment";
       
 12704       break;
       
 12705     case SOAP_MIME_END:
       
 12706       *s = "End of MIME error";
       
 12707       break;
       
 12708     case SOAP_ZLIB_ERROR:
       
 12709 #ifdef WITH_ZLIB
       
 12710       sprintf(soap->msgbuf, "Zlib/gzip error: '%s'", soap->d_stream.msg?soap->d_stream.msg:"");
       
 12711       *s = soap->msgbuf;
       
 12712 #else
       
 12713       *s = "Zlib/gzip not installed for (de)compression: recompile with -DWITH_GZIP";
       
 12714 #endif
       
 12715       break;
       
 12716     case SOAP_REQUIRED:
       
 12717       *s = soap_set_validation_fault(soap, "missing required attribute", NULL);
       
 12718       break;
       
 12719     case SOAP_PROHIBITED:
       
 12720       *s = soap_set_validation_fault(soap, "prohibited attribute present", NULL);
       
 12721       break;
       
 12722     case SOAP_OCCURS:
       
 12723       *s = soap_set_validation_fault(soap, "min/maxOccurs violation", NULL);
       
 12724       break;
       
 12725     case SOAP_LENGTH:
       
 12726       *s = soap_set_validation_fault(soap, "content length violation", NULL);
       
 12727       break;
       
 12728     case SOAP_STOP:
       
 12729       *s = "Stopped: no response sent";
       
 12730       break;
       
 12731 #endif
       
 12732     case SOAP_EOF:
       
 12733 #ifndef WITH_NOIO
       
 12734       sprintf(soap->msgbuf, "End of file or no input: '%s'", soap_strerror(soap));
       
 12735       *s = soap->msgbuf;
       
 12736       break;
       
 12737 #else
       
 12738       *s = "End of file or no input";
       
 12739       break;
       
 12740 #endif
       
 12741     default:
       
 12742 #ifndef WITH_NOHTTP
       
 12743 #ifndef WITH_LEAN
       
 12744       if (soap->error > 200 && soap->error < 600)
       
 12745       { sprintf(soap->msgbuf, "HTTP Error: %d %s", soap->error, http_error(soap, soap->error));
       
 12746         *s = soap->msgbuf;
       
 12747       }
       
 12748       else
       
 12749 #endif
       
 12750 #endif
       
 12751       { sprintf(soap->msgbuf, "Error %d", soap->error);
       
 12752         *s = soap->msgbuf;
       
 12753       }
       
 12754     }
       
 12755 }
       
 12756 #endif
       
 12757 
       
 12758 /******************************************************************************/
       
 12759 #ifndef PALM_1
       
 12760 SOAP_FMAC1
       
 12761 int
       
 12762 SOAP_FMAC2
       
 12763 soap_send_fault(struct soap *soap)
       
 12764 { register int status = soap->error;
       
 12765   int r = 1;
       
 12766   if (status == SOAP_STOP)
       
 12767     return status;
       
 12768   DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Sending back fault struct for error code %d\n", soap->error));
       
 12769   soap->keep_alive = 0; /* to terminate connection */
       
 12770   soap_set_fault(soap);
       
 12771 #ifndef WITH_NOIO
       
 12772 #ifndef WITH_LEAN
       
 12773   if (soap_valid_socket(soap->socket))
       
 12774   { struct timeval timeout;
       
 12775     fd_set rfd, sfd;
       
 12776     timeout.tv_sec = 0;
       
 12777     timeout.tv_usec = 0;
       
 12778     FD_ZERO(&rfd);
       
 12779     FD_ZERO(&sfd);
       
 12780     FD_SET((SOAP_SOCKET)soap->socket, &rfd);
       
 12781     FD_SET((SOAP_SOCKET)soap->socket, &sfd);
       
 12782     r = select((SOAP_SOCKET)(soap->socket + 1), &rfd, &sfd, NULL, &timeout);
       
 12783     if (r > 0)
       
 12784     { if (!FD_ISSET((SOAP_SOCKET)soap->socket, &sfd)
       
 12785        || (FD_ISSET((SOAP_SOCKET)soap->socket, &rfd)
       
 12786         && recv((SOAP_SOCKET)soap->socket, soap->tmpbuf, 1, MSG_PEEK) < 0))
       
 12787         r = 0;
       
 12788     }
       
 12789   }
       
 12790 #endif
       
 12791 #endif
       
 12792   if ((status != SOAP_EOF || (!soap->recv_timeout && !soap->send_timeout)) && r > 0)
       
 12793   { soap->error = SOAP_OK;
       
 12794     soap_serializeheader(soap);
       
 12795     soap_serializefault(soap);
       
 12796     soap_begin_count(soap);
       
 12797     if (soap->mode & SOAP_IO_LENGTH)
       
 12798     { soap_envelope_begin_out(soap);
       
 12799       soap_putheader(soap);
       
 12800       soap_body_begin_out(soap);
       
 12801       soap_putfault(soap);
       
 12802       soap_body_end_out(soap);
       
 12803       soap_envelope_end_out(soap);
       
 12804     }
       
 12805     soap_end_count(soap);
       
 12806     if (soap_response(soap, status)
       
 12807      || soap_envelope_begin_out(soap)
       
 12808      || soap_putheader(soap)
       
 12809      || soap_body_begin_out(soap)
       
 12810      || soap_putfault(soap)
       
 12811      || soap_body_end_out(soap)
       
 12812      || soap_envelope_end_out(soap))
       
 12813       return soap_closesock(soap);
       
 12814     soap_end_send(soap);
       
 12815   }
       
 12816   soap->error = status;
       
 12817   return soap_closesock(soap);
       
 12818 }
       
 12819 #endif
       
 12820 
       
 12821 /******************************************************************************/
       
 12822 #ifndef PALM_1
       
 12823 SOAP_FMAC1
       
 12824 int
       
 12825 SOAP_FMAC2
       
 12826 soap_recv_fault(struct soap *soap)
       
 12827 { register int status = soap->error;
       
 12828   DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Receiving SOAP Fault\n"));
       
 12829   soap->error = SOAP_OK;
       
 12830   if (soap_getfault(soap))
       
 12831   { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Error: soap_get_soapfault() failed. Is this a SOAP message at all?\n"));
       
 12832     *soap_faultcode(soap) = (soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client");
       
 12833     soap->error = status;
       
 12834     soap_set_fault(soap);
       
 12835   }
       
 12836   else
       
 12837   { register const char *s = *soap_faultcode(soap);
       
 12838     if (!soap_match_tag(soap, s, "SOAP-ENV:Server") || !soap_match_tag(soap, s, "SOAP-ENV:Receiver"))
       
 12839       status = SOAP_SVR_FAULT; 
       
 12840     else if (!soap_match_tag(soap, s, "SOAP-ENV:Client") || !soap_match_tag(soap, s, "SOAP-ENV:Sender"))
       
 12841       status = SOAP_CLI_FAULT;
       
 12842     else if (!soap_match_tag(soap, s, "SOAP-ENV:MustUnderstand"))
       
 12843       status = SOAP_MUSTUNDERSTAND;
       
 12844     else if (!soap_match_tag(soap, s, "SOAP-ENV:VersionMismatch"))
       
 12845       status = SOAP_VERSIONMISMATCH;
       
 12846     else
       
 12847     { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Fault code %s\n", s));
       
 12848       status = SOAP_FAULT;
       
 12849     }
       
 12850     if (soap_body_end_in(soap)
       
 12851      || soap_envelope_end_in(soap)
       
 12852      || soap_end_recv(soap))
       
 12853       return soap_closesock(soap);
       
 12854     soap->error = status;
       
 12855   }
       
 12856   return soap_closesock(soap);
       
 12857 }
       
 12858 #endif
       
 12859 
       
 12860 /******************************************************************************/
       
 12861 #ifndef WITH_NOHTTP
       
 12862 #ifndef PALM_1
       
 12863 SOAP_FMAC1
       
 12864 int
       
 12865 SOAP_FMAC2
       
 12866 soap_send_empty_response(struct soap *soap)
       
 12867 { soap->count = 0;
       
 12868   if (soap_response(soap, SOAP_OK) || soap_end_send(soap))
       
 12869     return soap_closesock(soap);
       
 12870   return SOAP_OK;
       
 12871 }
       
 12872 #endif
       
 12873 #endif
       
 12874 
       
 12875 /******************************************************************************/
       
 12876 #ifndef WITH_NOHTTP
       
 12877 #ifndef PALM_1
       
 12878 SOAP_FMAC1
       
 12879 int
       
 12880 SOAP_FMAC2
       
 12881 soap_recv_empty_response(struct soap *soap)
       
 12882 { if (soap_begin_recv(soap) || soap_end_recv(soap))
       
 12883     return soap_closesock(soap);
       
 12884   return SOAP_OK;
       
 12885 }
       
 12886 #endif
       
 12887 #endif
       
 12888 
       
 12889 /******************************************************************************/
       
 12890 #ifndef WITH_NOIO
       
 12891 #ifndef PALM_1
       
 12892 static const char*
       
 12893 soap_strerror(struct soap *soap)
       
 12894 { register int err = soap->errnum;
       
 12895   if (err)
       
 12896   {
       
 12897 #ifndef WIN32
       
 12898     return strerror(err);
       
 12899 #else
       
 12900     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, 0, (LPTSTR)&soap->errorstr, sizeof(soap->errorstr), NULL);
       
 12901     return soap->errorstr;
       
 12902 #endif
       
 12903   }
       
 12904   return "Operation interrupted or timed out";
       
 12905 }
       
 12906 #endif
       
 12907 #endif 
       
 12908 
       
 12909 /******************************************************************************/
       
 12910 #ifndef PALM_2
       
 12911 static int
       
 12912 soap_set_error(struct soap *soap, const char *faultcode, const char *faultsubcode, const char *faultstring, const char *faultdetail, int soaperror)
       
 12913 { *soap_faultcode(soap) = faultcode;
       
 12914   if (faultsubcode)
       
 12915     *soap_faultsubcode(soap) = faultsubcode;
       
 12916   *soap_faultstring(soap) = faultstring;
       
 12917   if (faultdetail && *faultdetail)
       
 12918   { register const char **s = soap_faultdetail(soap);
       
 12919     if (s)
       
 12920       *s = faultdetail;
       
 12921   }
       
 12922   return soap->error = soaperror;
       
 12923 }
       
 12924 #endif
       
 12925 
       
 12926 /******************************************************************************/
       
 12927 #ifndef PALM_2
       
 12928 SOAP_FMAC1
       
 12929 int
       
 12930 SOAP_FMAC2
       
 12931 soap_set_sender_error(struct soap *soap, const char *faultstring, const char *faultdetail, int soaperror)
       
 12932 { return soap_set_error(soap, soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client", NULL, faultstring, faultdetail, soaperror);
       
 12933 }
       
 12934 #endif
       
 12935 
       
 12936 /******************************************************************************/
       
 12937 #ifndef PALM_2
       
 12938 SOAP_FMAC1
       
 12939 int
       
 12940 SOAP_FMAC2
       
 12941 soap_set_receiver_error(struct soap *soap, const char *faultstring, const char *faultdetail, int soaperror)
       
 12942 { return soap_set_error(soap, soap->version == 2 ? "SOAP-ENV:Receiver" : "SOAP-ENV:Server", NULL, faultstring, faultdetail, soaperror);
       
 12943 }
       
 12944 #endif
       
 12945 
       
 12946 /******************************************************************************/
       
 12947 #ifndef PALM_2
       
 12948 static int
       
 12949 soap_copy_fault(struct soap *soap, const char *faultcode, const char *faultsubcode, const char *faultstring, const char *faultdetail)
       
 12950 { char *r = NULL, *s = NULL, *t = NULL;
       
 12951   if (faultsubcode)
       
 12952     r = soap_strdup(soap, faultsubcode);
       
 12953   if (faultstring)
       
 12954     s = soap_strdup(soap, faultstring);
       
 12955   if (faultdetail)
       
 12956     t = soap_strdup(soap, faultdetail);
       
 12957   return soap_set_error(soap, faultcode, r, s, t, SOAP_FAULT);
       
 12958 }
       
 12959 #endif
       
 12960 
       
 12961 /******************************************************************************/
       
 12962 #ifndef PALM_2
       
 12963 SOAP_FMAC1
       
 12964 int
       
 12965 SOAP_FMAC2
       
 12966 soap_sender_fault(struct soap *soap, const char *faultstring, const char *faultdetail)
       
 12967 { return soap_sender_fault_subcode(soap, NULL, faultstring, faultdetail);
       
 12968 }
       
 12969 #endif
       
 12970 
       
 12971 /******************************************************************************/
       
 12972 #ifndef PALM_2
       
 12973 SOAP_FMAC1
       
 12974 int
       
 12975 SOAP_FMAC2
       
 12976 soap_sender_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail)
       
 12977 { return soap_copy_fault(soap, soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client", faultsubcode, faultstring, faultdetail);
       
 12978 }
       
 12979 #endif
       
 12980 
       
 12981 /******************************************************************************/
       
 12982 #ifndef PALM_2
       
 12983 SOAP_FMAC1
       
 12984 int
       
 12985 SOAP_FMAC2
       
 12986 soap_receiver_fault(struct soap *soap, const char *faultstring, const char *faultdetail)
       
 12987 { return soap_receiver_fault_subcode(soap, NULL, faultstring, faultdetail);
       
 12988 }
       
 12989 #endif
       
 12990 
       
 12991 /******************************************************************************/
       
 12992 #ifndef PALM_2
       
 12993 SOAP_FMAC1
       
 12994 int
       
 12995 SOAP_FMAC2
       
 12996 soap_receiver_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail)
       
 12997 { return soap_copy_fault(soap, soap->version == 2 ? "SOAP-ENV:Receiver" : "SOAP-ENV:Server", faultsubcode, faultstring, faultdetail);
       
 12998 }
       
 12999 #endif
       
 13000 
       
 13001 /******************************************************************************/
       
 13002 #ifndef PALM_2
       
 13003 #ifndef WITH_NOSTDLIB
       
 13004 SOAP_FMAC1
       
 13005 void
       
 13006 SOAP_FMAC2
       
 13007 soap_print_fault(struct soap *soap, FILE *fd)
       
 13008 { if (soap->error)
       
 13009   { const char *c, *v = NULL, *s, **d;
       
 13010     d = soap_faultcode(soap);
       
 13011     if (!*d)
       
 13012       soap_set_fault(soap);
       
 13013     c = *d;
       
 13014     if (soap->version == 2)
       
 13015       v = *soap_faultsubcode(soap);
       
 13016     s = *soap_faultstring(soap);
       
 13017     d = soap_faultdetail(soap);
       
 13018     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]");
       
 13019   }
       
 13020 }
       
 13021 #endif
       
 13022 #endif
       
 13023  
       
 13024 /******************************************************************************/
       
 13025 #ifndef PALM_1
       
 13026 #ifndef WITH_NOSTDLIB
       
 13027 SOAP_FMAC1
       
 13028 void
       
 13029 SOAP_FMAC2
       
 13030 soap_print_fault_location(struct soap *soap, FILE *fd)
       
 13031 { 
       
 13032 #ifndef WITH_LEAN
       
 13033   int i, j, c1, c2;
       
 13034   if (soap->error && soap->buflen > 0)
       
 13035   { i = (int)soap->bufidx - 1;
       
 13036     if (i <= 0)
       
 13037       i = 0;
       
 13038     c1 = soap->buf[i];
       
 13039     soap->buf[i] = '\0';
       
 13040     if ((int)soap->buflen >= i + 1024)
       
 13041       j = i + 1023;
       
 13042     else
       
 13043       j = (int)soap->buflen - 1;
       
 13044     c2 = soap->buf[j];
       
 13045     soap->buf[j] = '\0';
       
 13046     fprintf(fd, "%s%c\n** HERE **\n", soap->buf, c1);
       
 13047     if (soap->bufidx < soap->buflen)
       
 13048       fprintf(fd, "%s\n", soap->buf + soap->bufidx);
       
 13049     soap->buf[i] = c1;
       
 13050     soap->buf[j] = c2;
       
 13051   }
       
 13052 #endif
       
 13053 }
       
 13054 #endif
       
 13055 #endif
       
 13056  
       
 13057 /******************************************************************************/
       
 13058 #ifndef PALM_1
       
 13059 SOAP_FMAC1
       
 13060 int
       
 13061 SOAP_FMAC2
       
 13062 soap_register_plugin_arg(struct soap *soap, int (*fcreate)(struct soap*, struct soap_plugin*, void*), void *arg)
       
 13063 { register struct soap_plugin *p;
       
 13064   register int r;
       
 13065   if (!(p = (struct soap_plugin*)SOAP_MALLOC(soap, sizeof(struct soap_plugin))))
       
 13066     return soap->error = SOAP_EOM;
       
 13067   p->id = NULL;
       
 13068   p->data = NULL;
       
 13069   p->fcopy = NULL;
       
 13070   p->fdelete = NULL;
       
 13071   r = fcreate(soap, p, arg);
       
 13072   if (!r && p->fdelete)
       
 13073   { p->next = soap->plugins;
       
 13074     soap->plugins = p;
       
 13075     DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Registered '%s' plugin\n", p->id));
       
 13076     return SOAP_OK;
       
 13077   }
       
 13078   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));
       
 13079   SOAP_FREE(soap, p);
       
 13080   return r;
       
 13081 }
       
 13082 #endif
       
 13083 
       
 13084 /******************************************************************************/
       
 13085 #ifndef PALM_1
       
 13086 static void *
       
 13087 fplugin(struct soap *soap, const char *id)
       
 13088 { register struct soap_plugin *p;
       
 13089   for (p = soap->plugins; p; p = p->next)
       
 13090     if (p->id == id || !strcmp(p->id, id))
       
 13091       return p->data;
       
 13092   return NULL;
       
 13093 }
       
 13094 #endif
       
 13095 
       
 13096 /******************************************************************************/
       
 13097 #ifndef PALM_2
       
 13098 SOAP_FMAC1
       
 13099 void *
       
 13100 SOAP_FMAC2
       
 13101 soap_lookup_plugin(struct soap *soap, const char *id)
       
 13102 { return soap->fplugin(soap, id);
       
 13103 }
       
 13104 #endif
       
 13105 
       
 13106 /******************************************************************************/
       
 13107 #ifdef __cplusplus
       
 13108 }
       
 13109 #endif
       
 13110