00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 #ifdef AS400
00065 # pragma convert(819)
00066 #endif
00067
00068 #include "stdsoap2.h"
00069
00070 #ifdef __cplusplus
00071 SOAP_SOURCE_STAMP("@(#) stdsoap2.cpp ver 2.7.8c 2006-06-24 12:00:00 GMT")
00072 extern "C" {
00073 #else
00074 SOAP_SOURCE_STAMP("@(#) stdsoap2.c ver 2.7.8c 2006-06-24 12:00:00 GMT")
00075 #endif
00076
00077
00078 #ifndef SOAP_UNKNOWN_CHAR
00079 #define SOAP_UNKNOWN_CHAR (127)
00080 #endif
00081
00082
00083 #define SOAP_LT (soap_wchar)(-2)
00084 #define SOAP_TT (soap_wchar)(-3)
00085 #define SOAP_GT (soap_wchar)(-4)
00086 #define SOAP_QT (soap_wchar)(-5)
00087 #define SOAP_AP (soap_wchar)(-6)
00088
00089 #define soap_blank(c) ((c) >= 0 && (c) <= 32)
00090 #define soap_notblank(c) ((c) > 32)
00091 #define soap_hash_ptr(p) (((unsigned long)(p) >> 3) & (SOAP_PTRHASH - 1))
00092
00093 #ifdef SOAP_DEBUG
00094 static void soap_init_logs(struct soap*);
00095 static void soap_close_logfile(struct soap*, int);
00096 static void soap_set_logfile(struct soap*, int, const char*);
00097 static void soap_free_mht(struct soap*);
00098 static void soap_track_unlink(struct soap*, const void*);
00099 #endif
00100
00101 #ifndef PALM_2
00102 static int soap_set_error(struct soap*, const char*, const char*, const char*, const char*, int);
00103 static int soap_copy_fault(struct soap*, const char*, const char*, const char*, const char*);
00104 static int soap_getattrval(struct soap*, char*, size_t, soap_wchar);
00105 #endif
00106
00107 #ifndef PALM_1
00108 static soap_wchar soap_char(struct soap*);
00109 static soap_wchar soap_get_pi(struct soap*);
00110 static int soap_isxdigit(int);
00111 static void *fplugin(struct soap*, const char*);
00112 #ifndef WITH_NOIDREF
00113 static void soap_update_ptrs(struct soap*, char*, char*, char*, char*);
00114 static int soap_has_copies(struct soap*, const char*, const char*);
00115 static void soap_init_iht(struct soap*);
00116 static void soap_free_iht(struct soap*);
00117 static void soap_init_pht(struct soap*);
00118 static void soap_free_pht(struct soap*);
00119 #endif
00120 #endif
00121
00122 #ifndef WITH_LEAN
00123 static const char *soap_set_validation_fault(struct soap*, const char*, const char*);
00124 static int soap_isnumeric(struct soap*, const char*);
00125 static time_t soap_timegm(struct tm*);
00126 static struct soap_nlist *soap_lookup_ns(struct soap *soap, const char *tag, size_t n);
00127 static struct soap_nlist *soap_push_ns(struct soap *soap, const char *id, const char *ns, short utilized);
00128 static void soap_pop_ns(struct soap *soap);
00129 static void soap_utilize_ns(struct soap *soap, const char *tag, size_t n);
00130 #endif
00131
00132 #ifndef WITH_LEANER
00133 #ifndef PALM_1
00134 static struct soap_multipart *soap_new_multipart(struct soap*, struct soap_multipart**, struct soap_multipart**, char*, size_t);
00135 static int soap_putdimefield(struct soap*, const char*, size_t);
00136 static char *soap_getdimefield(struct soap*, size_t);
00137 static void soap_select_mime_boundary(struct soap*);
00138 static int soap_valid_mime_boundary(struct soap*);
00139 static void soap_resolve_attachment(struct soap*, struct soap_multipart*);
00140 #endif
00141 #endif
00142
00143 #ifdef WITH_GZIP
00144 static int soap_getgziphdr(struct soap*);
00145 #endif
00146
00147 #ifdef WITH_OPENSSL
00148 static int ssl_init_done = 0;
00149 static int ssl_auth_init(struct soap*);
00150 static int ssl_verify_callback(int, X509_STORE_CTX*);
00151 static int ssl_password(char*, int, int, void *);
00152
00153
00154
00155 #endif
00156
00157 #if !defined(WITH_NOHTTP) || !defined(WITH_LEANER)
00158 #ifndef PALM_1
00159 static const char *soap_decode(char*, size_t, const char*, const char*);
00160 #endif
00161 #endif
00162
00163 #ifndef WITH_NOHTTP
00164 #ifndef PALM_1
00165 static soap_wchar soap_getchunkchar(struct soap*);
00166 static const char *http_error(struct soap*, int);
00167 static int http_post(struct soap*, const char*, const char*, int, const char*, const char*, size_t);
00168 static int http_get(struct soap*);
00169 static int http_send_header(struct soap*, const char*);
00170 static int http_post_header(struct soap*, const char*, const char*);
00171 static int http_response(struct soap*, int, size_t);
00172 static int http_parse(struct soap*);
00173 static int http_parse_header(struct soap*, const char*, const char*);
00174 #endif
00175 #endif
00176
00177 #ifndef WITH_NOIO
00178 #ifndef PALM_1
00179 static int fsend(struct soap*, const char*, size_t);
00180 static size_t frecv(struct soap*, char*, size_t);
00181 static int tcp_init(struct soap*);
00182 static const char *tcp_error(struct soap*);
00183 #ifndef WITH_IPV6
00184 static int tcp_gethost(struct soap*, const char *addr, struct in_addr *inaddr);
00185 #endif
00186 static int tcp_connect(struct soap*, const char *endpoint, const char *host, int port);
00187 static int tcp_accept(struct soap*, int, struct sockaddr*, int*);
00188 static int tcp_disconnect(struct soap*);
00189 static int tcp_closesocket(struct soap*, SOAP_SOCKET);
00190 static int tcp_shutdownsocket(struct soap*, SOAP_SOCKET, int);
00191 static const char *soap_strerror(struct soap*);
00192 #endif
00193 #endif
00194
00195 #if defined(PALM) && !defined(PALM_2)
00196 unsigned short errno;
00197 #endif
00198
00199 #ifndef PALM_1
00200 static const char soap_env1[42] = "http://schemas.xmlsoap.org/soap/envelope/";
00201 static const char soap_enc1[42] = "http://schemas.xmlsoap.org/soap/encoding/";
00202 static const char soap_env2[40] = "http://www.w3.org/2003/05/soap-envelope";
00203 static const char soap_enc2[40] = "http://www.w3.org/2003/05/soap-encoding";
00204 static const char soap_rpc[35] = "http://www.w3.org/2003/05/soap-rpc";
00205 #endif
00206
00207 #ifndef PALM_1
00208 const struct soap_double_nan soap_double_nan = {0xFFFFFFFF, 0xFFFFFFFF};
00209 static const char soap_base64o[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00210 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";
00211 #endif
00212
00213 #ifndef WITH_LEAN
00214 static const char soap_indent[11] = "\n\t\t\t\t\t\t\t\t\t";
00215
00216
00217
00218 #endif
00219
00220 #ifndef SOAP_CANARY
00221 # define SOAP_CANARY (0xC0DE)
00222 #endif
00223
00224 static const char soap_padding[4] = "\0\0\0";
00225 #define SOAP_STR_PADDING (soap_padding)
00226 #define SOAP_STR_EOS (soap_padding)
00227 #define SOAP_NON_NULL (soap_padding)
00228
00229 #ifndef WITH_LEAN
00230 static const struct soap_code_map html_entity_codes[] =
00231 { { 160, "nbsp" },
00232 { 161, "iexcl" },
00233 { 162, "cent" },
00234 { 163, "pound" },
00235 { 164, "curren" },
00236 { 165, "yen" },
00237 { 166, "brvbar" },
00238 { 167, "sect" },
00239 { 168, "uml" },
00240 { 169, "copy" },
00241 { 170, "ordf" },
00242 { 171, "laquo" },
00243 { 172, "not" },
00244 { 173, "shy" },
00245 { 174, "reg" },
00246 { 175, "macr" },
00247 { 176, "deg" },
00248 { 177, "plusmn" },
00249 { 178, "sup2" },
00250 { 179, "sup3" },
00251 { 180, "acute" },
00252 { 181, "micro" },
00253 { 182, "para" },
00254 { 183, "middot" },
00255 { 184, "cedil" },
00256 { 185, "sup1" },
00257 { 186, "ordm" },
00258 { 187, "raquo" },
00259 { 188, "frac14" },
00260 { 189, "frac12" },
00261 { 190, "frac34" },
00262 { 191, "iquest" },
00263 { 192, "Agrave" },
00264 { 193, "Aacute" },
00265 { 194, "Acirc" },
00266 { 195, "Atilde" },
00267 { 196, "Auml" },
00268 { 197, "Aring" },
00269 { 198, "AElig" },
00270 { 199, "Ccedil" },
00271 { 200, "Egrave" },
00272 { 201, "Eacute" },
00273 { 202, "Ecirc" },
00274 { 203, "Euml" },
00275 { 204, "Igrave" },
00276 { 205, "Iacute" },
00277 { 206, "Icirc" },
00278 { 207, "Iuml" },
00279 { 208, "ETH" },
00280 { 209, "Ntilde" },
00281 { 210, "Ograve" },
00282 { 211, "Oacute" },
00283 { 212, "Ocirc" },
00284 { 213, "Otilde" },
00285 { 214, "Ouml" },
00286 { 215, "times" },
00287 { 216, "Oslash" },
00288 { 217, "Ugrave" },
00289 { 218, "Uacute" },
00290 { 219, "Ucirc" },
00291 { 220, "Uuml" },
00292 { 221, "Yacute" },
00293 { 222, "THORN" },
00294 { 223, "szlig" },
00295 { 224, "agrave" },
00296 { 225, "aacute" },
00297 { 226, "acirc" },
00298 { 227, "atilde" },
00299 { 228, "auml" },
00300 { 229, "aring" },
00301 { 230, "aelig" },
00302 { 231, "ccedil" },
00303 { 232, "egrave" },
00304 { 233, "eacute" },
00305 { 234, "ecirc" },
00306 { 235, "euml" },
00307 { 236, "igrave" },
00308 { 237, "iacute" },
00309 { 238, "icirc" },
00310 { 239, "iuml" },
00311 { 240, "eth" },
00312 { 241, "ntilde" },
00313 { 242, "ograve" },
00314 { 243, "oacute" },
00315 { 244, "ocirc" },
00316 { 245, "otilde" },
00317 { 246, "ouml" },
00318 { 247, "divide" },
00319 { 248, "oslash" },
00320 { 249, "ugrave" },
00321 { 250, "uacute" },
00322 { 251, "ucirc" },
00323 { 252, "uuml" },
00324 { 253, "yacute" },
00325 { 254, "thorn" },
00326 { 255, "yuml" },
00327 { 0, NULL }
00328 };
00329 #endif
00330
00331 #ifndef WITH_NOIO
00332 #ifndef WITH_LEAN
00333 static const struct soap_code_map h_error_codes[] =
00334 {
00335 #ifdef HOST_NOT_FOUND
00336 { HOST_NOT_FOUND, "Host not found" },
00337 #endif
00338 #ifdef TRY_AGAIN
00339 { TRY_AGAIN, "Try Again" },
00340 #endif
00341 #ifdef NO_RECOVERY
00342 { NO_RECOVERY, "No Recovery" },
00343 #endif
00344 #ifdef NO_DATA
00345 { NO_DATA, "No Data" },
00346 #endif
00347 #ifdef NO_ADDRESS
00348 { NO_ADDRESS, "No Address" },
00349 #endif
00350 { 0, NULL }
00351 };
00352 #endif
00353 #endif
00354
00355 #ifndef WITH_NOHTTP
00356 #ifndef WITH_LEAN
00357 static const struct soap_code_map h_http_error_codes[] =
00358 { { 200, "OK" },
00359 { 201, "Created" },
00360 { 202, "Accepted" },
00361 { 203, "Non-Authoritative Information" },
00362 { 204, "No Content" },
00363 { 205, "Reset Content" },
00364 { 206, "Partial Content" },
00365 { 300, "Multiple Choices" },
00366 { 301, "Moved Permanently" },
00367 { 302, "Found" },
00368 { 303, "See Other" },
00369 { 304, "Not Modified" },
00370 { 305, "Use Proxy" },
00371 { 307, "Temporary Redirect" },
00372 { 400, "Bad Request" },
00373 { 401, "Unauthorized" },
00374 { 402, "Payment Required" },
00375 { 403, "Forbidden" },
00376 { 404, "Not Found" },
00377 { 405, "Method Not Allowed" },
00378 { 406, "Not Acceptable" },
00379 { 407, "Proxy Authentication Required" },
00380 { 408, "Request Time-out" },
00381 { 409, "Conflict" },
00382 { 410, "Gone" },
00383 { 411, "Length Required" },
00384 { 412, "Precondition Failed" },
00385 { 413, "Request Entity Too Large" },
00386 { 414, "Request-URI Too Large" },
00387 { 415, "Unsupported Media Type" },
00388 { 416, "Requested range not satisfiable" },
00389 { 417, "Expectation Failed" },
00390 { 500, "Internal Server Error" },
00391 { 501, "Not Implemented" },
00392 { 502, "Bad Gateway" },
00393 { 503, "Service Unavailable" },
00394 { 504, "Gateway Time-out" },
00395 { 505, "HTTP Version not supported" },
00396 { 0, NULL }
00397 };
00398 #endif
00399 #endif
00400
00401 #ifdef WITH_OPENSSL
00402 static const struct soap_code_map h_ssl_error_codes[] =
00403 {
00404 #define _SSL_ERROR(e) { e, #e }
00405 _SSL_ERROR(SSL_ERROR_SSL),
00406 _SSL_ERROR(SSL_ERROR_ZERO_RETURN),
00407 _SSL_ERROR(SSL_ERROR_WANT_READ),
00408 _SSL_ERROR(SSL_ERROR_WANT_WRITE),
00409 _SSL_ERROR(SSL_ERROR_WANT_CONNECT),
00410 _SSL_ERROR(SSL_ERROR_WANT_X509_LOOKUP),
00411 _SSL_ERROR(SSL_ERROR_SYSCALL),
00412 { 0, NULL }
00413 };
00414 #endif
00415
00416 #ifndef WITH_LEANER
00417 static const struct soap_code_map mime_codes[] =
00418 { { SOAP_MIME_7BIT, "7bit" },
00419 { SOAP_MIME_8BIT, "8bit" },
00420 { SOAP_MIME_BINARY, "binary" },
00421 { SOAP_MIME_QUOTED_PRINTABLE, "quoted-printable" },
00422 { SOAP_MIME_BASE64, "base64" },
00423 { SOAP_MIME_IETF_TOKEN, "ietf-token" },
00424 { SOAP_MIME_X_TOKEN, "x-token" },
00425 { 0, NULL }
00426 };
00427 #endif
00428
00429 #ifdef WIN32
00430 static int tcp_done = 0;
00431 #endif
00432
00433
00434 #ifndef WITH_NOIO
00435 #ifndef PALM_1
00436 static int
00437 fsend(struct soap *soap, const char *s, size_t n)
00438 { register int nwritten;
00439 #if defined(__cplusplus) && !defined(WITH_LEAN)
00440 if (soap->os)
00441 { soap->os->write(s, n);
00442 if (soap->os->good())
00443 return SOAP_OK;
00444 return SOAP_EOF;
00445 }
00446 #endif
00447 while (n)
00448 { if (soap_valid_socket(soap->socket))
00449 {
00450 #ifndef WITH_LEAN
00451 if (soap->send_timeout)
00452 { struct timeval timeout;
00453 fd_set fd;
00454 if (soap->send_timeout > 0)
00455 { timeout.tv_sec = soap->send_timeout;
00456 timeout.tv_usec = 0;
00457 }
00458 else
00459 { timeout.tv_sec = -soap->send_timeout/1000000;
00460 timeout.tv_usec = -soap->send_timeout%1000000;
00461 }
00462 #ifndef WIN32
00463 if ((int)soap->socket > FD_SETSIZE)
00464 return SOAP_FD_EXCEEDED;
00465 #endif
00466 FD_ZERO(&fd);
00467 FD_SET((SOAP_SOCKET)soap->socket, &fd);
00468 for (;;)
00469 { register int r = select((SOAP_SOCKET)(soap->socket + 1), NULL, &fd, &fd, &timeout);
00470 if (r > 0)
00471 break;
00472 if (!r)
00473 { soap->errnum = 0;
00474 return SOAP_EOF;
00475 }
00476 if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EAGAIN)
00477 { soap->errnum = soap_socket_errno;
00478 return SOAP_EOF;
00479 }
00480 }
00481 }
00482 #endif
00483 #ifdef WITH_OPENSSL
00484 if (soap->ssl)
00485 nwritten = SSL_write(soap->ssl, s, n);
00486 else if (soap->bio)
00487 nwritten = BIO_write(soap->bio, s, n);
00488 else
00489 #endif
00490 #ifdef WITH_UDP
00491 if ((soap->omode & SOAP_IO_UDP))
00492 { if (soap->peerlen)
00493 nwritten = sendto((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags, (struct sockaddr*)&soap->peer, soap->peerlen);
00494 else
00495 nwritten = send((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags);
00496
00497
00498 if (nwritten < 0)
00499 { struct timeval timeout;
00500 fd_set fd;
00501 int udp_repeat;
00502 int udp_delay;
00503 #ifndef WIN32
00504 if ((int)soap->socket > FD_SETSIZE)
00505 return SOAP_FD_EXCEEDED;
00506 #endif
00507 if ((soap->connect_flags & SO_BROADCAST))
00508 udp_repeat = 3;
00509 else
00510 udp_repeat = 1;
00511 udp_delay = (soap_random % 201) + 50;
00512 do
00513 { timeout.tv_sec = 0;
00514 timeout.tv_usec = 1000 * udp_delay;
00515 FD_ZERO(&fd);
00516 FD_SET((SOAP_SOCKET)soap->socket, &fd);
00517 select((SOAP_SOCKET)(soap->socket + 1), NULL, NULL, &fd, &timeout);
00518 if (soap->peerlen)
00519 nwritten = sendto((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags, (struct sockaddr*)&soap->peer, soap->peerlen);
00520 else
00521 nwritten = send((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags);
00522 udp_delay <<= 1;
00523 if (udp_delay > 500)
00524 udp_delay = 500;
00525 }
00526 while (nwritten < 0 && --udp_repeat > 0);
00527 }
00528 }
00529 else
00530 #endif
00531 #if !defined(PALM) && !defined(AS400)
00532 nwritten = send((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags);
00533 #else
00534 nwritten = send((SOAP_SOCKET)soap->socket, (void*)s, n, soap->socket_flags);
00535 #endif
00536 if (nwritten <= 0)
00537 {
00538 #ifdef WITH_OPENSSL
00539 int err;
00540 if (soap->ssl && (err = SSL_get_error(soap->ssl, nwritten)) != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
00541 return SOAP_EOF;
00542 #endif
00543 if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EWOULDBLOCK && soap_socket_errno != SOAP_EAGAIN)
00544 { soap->errnum = soap_socket_errno;
00545 return SOAP_EOF;
00546 }
00547 nwritten = 0;
00548 }
00549 }
00550 else
00551 {
00552 #ifdef WITH_FASTCGI
00553 nwritten = fwrite((void*)s, 1, n, stdout);
00554 fflush(stdout);
00555 #else
00556 #ifdef UNDER_CE
00557 nwritten = fwrite(s, 1, n, soap->sendfd);
00558 #else
00559 #ifdef VXWORKS
00560 #ifdef WMW_RPM_IO
00561 if (soap->rpmreqid)
00562 nwritten = (httpBlockPut(soap->rpmreqid, s, n) == 0) ? n : -1;
00563 else
00564 #endif
00565 nwritten = fwrite(s, sizeof(char), n, fdopen(soap->sendfd, "w"));
00566 #else
00567 nwritten = write((SOAP_SOCKET)soap->sendfd, s, n);
00568 #endif
00569 #endif
00570 #endif
00571 if (nwritten <= 0)
00572 { if (soap_errno != SOAP_EINTR && soap_errno != SOAP_EWOULDBLOCK && soap_errno != SOAP_EAGAIN)
00573 { soap->errnum = soap_errno;
00574 return SOAP_EOF;
00575 }
00576 nwritten = 0;
00577 }
00578 }
00579 n -= nwritten;
00580 s += nwritten;
00581 }
00582 return SOAP_OK;
00583 }
00584 #endif
00585 #endif
00586
00587
00588 #ifndef PALM_1
00589 SOAP_FMAC1
00590 int
00591 SOAP_FMAC2
00592 soap_send_raw(struct soap *soap, const char *s, size_t n)
00593 { if (!n)
00594 return SOAP_OK;
00595 if (soap->mode & SOAP_IO_LENGTH)
00596 { soap->count += n;
00597 #ifndef WITH_LEANER
00598 if (soap->fpreparesend && (soap->mode & SOAP_IO) != SOAP_IO_STORE)
00599 return soap->error = soap->fpreparesend(soap, s, n);
00600 #endif
00601 return SOAP_OK;
00602 }
00603 if (soap->mode & SOAP_IO)
00604 { register size_t i = SOAP_BUFLEN - soap->bufidx;
00605 while (n >= i)
00606 { memcpy(soap->buf + soap->bufidx, s, i);
00607 soap->bufidx = SOAP_BUFLEN;
00608 if (soap_flush(soap))
00609 return soap->error;
00610 s += i;
00611 n -= i;
00612 i = SOAP_BUFLEN;
00613 }
00614 memcpy(soap->buf + soap->bufidx, s, n);
00615 soap->bufidx += n;
00616 return SOAP_OK;
00617 }
00618 return soap_flush_raw(soap, s, n);
00619 }
00620 #endif
00621
00622
00623 #ifndef PALM_1
00624 SOAP_FMAC1
00625 int
00626 SOAP_FMAC2
00627 soap_flush(struct soap *soap)
00628 { register int n = soap->bufidx;
00629 if (n)
00630 { soap->bufidx = 0;
00631 #ifdef WITH_ZLIB
00632 if (soap->mode & SOAP_ENC_ZLIB)
00633 { soap->d_stream.next_in = (Byte*)soap->buf;
00634 soap->d_stream.avail_in = (unsigned int)n;
00635 #ifdef WITH_GZIP
00636 soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)n);
00637 #endif
00638 do
00639 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflating %u bytes\n", soap->d_stream.avail_in));
00640 if (deflate(&soap->d_stream, Z_NO_FLUSH) != Z_OK)
00641 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to deflate: %s\n", soap->d_stream.msg?soap->d_stream.msg:""));
00642 return soap->error = SOAP_ZLIB_ERROR;
00643 }
00644 if (!soap->d_stream.avail_out)
00645 { if (soap_flush_raw(soap, soap->z_buf, SOAP_BUFLEN))
00646 return soap->error;
00647 soap->d_stream.next_out = (Byte*)soap->z_buf;
00648 soap->d_stream.avail_out = SOAP_BUFLEN;
00649 }
00650 } while (soap->d_stream.avail_in);
00651 }
00652 else
00653 #endif
00654 return soap_flush_raw(soap, soap->buf, n);
00655 }
00656 return SOAP_OK;
00657 }
00658 #endif
00659
00660
00661 #ifndef PALM_1
00662 SOAP_FMAC1
00663 int
00664 SOAP_FMAC2
00665 soap_flush_raw(struct soap *soap, const char *s, size_t n)
00666 { if ((soap->mode & SOAP_IO) == SOAP_IO_STORE)
00667 { register char *t;
00668 if (!(t = (char*)soap_push_block(soap, n)))
00669 return soap->error = SOAP_EOM;
00670 memcpy(t, s, n);
00671 #ifndef WITH_LEANER
00672 if (soap->fpreparesend)
00673 return soap->error = soap->fpreparesend(soap, s, n);
00674 #endif
00675 return SOAP_OK;
00676 }
00677 #ifndef WITH_LEANER
00678 if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK)
00679 { char t[16];
00680 sprintf(t, "\r\n%lX\r\n" + (soap->chunksize ? 0 : 2), (unsigned long)n);
00681 DBGMSG(SENT, t, strlen(t));
00682 if ((soap->error = soap->fsend(soap, t, strlen(t))))
00683 return soap->error;
00684 soap->chunksize += n;
00685 }
00686 DBGMSG(SENT, s, n);
00687 #endif
00688 return soap->error = soap->fsend(soap, s, n);
00689 }
00690 #endif
00691
00692
00693 #ifndef PALM_1
00694 SOAP_FMAC1
00695 int
00696 SOAP_FMAC2
00697 soap_send(struct soap *soap, const char *s)
00698 { if (s)
00699 return soap_send_raw(soap, s, strlen(s));
00700 return SOAP_OK;
00701 }
00702 #endif
00703
00704
00705 #ifndef WITH_LEANER
00706 #ifndef PALM_1
00707 SOAP_FMAC1
00708 int
00709 SOAP_FMAC2
00710 soap_send2(struct soap *soap, const char *s1, const char *s2)
00711 { if (soap_send(soap, s1))
00712 return soap->error;
00713 return soap_send(soap, s2);
00714 }
00715 #endif
00716 #endif
00717
00718
00719 #ifndef WITH_LEANER
00720 #ifndef PALM_1
00721 SOAP_FMAC1
00722 int
00723 SOAP_FMAC2
00724 soap_send3(struct soap *soap, const char *s1, const char *s2, const char *s3)
00725 { if (soap_send(soap, s1)
00726 || soap_send(soap, s2))
00727 return soap->error;
00728 return soap_send(soap, s3);
00729 }
00730 #endif
00731 #endif
00732
00733
00734 #ifndef WITH_NOIO
00735 #ifndef PALM_1
00736 static size_t
00737 frecv(struct soap *soap, char *s, size_t n)
00738 { register int r;
00739 #ifdef PALM
00740 register int timeouts = 0;
00741 #endif
00742 soap->errnum = 0;
00743 #if defined(__cplusplus) && !defined(WITH_LEAN)
00744 if (soap->is)
00745 { if (soap->is->good())
00746 return soap->is->read(s, n).gcount();
00747 return 0;
00748 }
00749 #endif
00750 if (soap_valid_socket(soap->socket))
00751 { for (;;)
00752 {
00753 #ifndef WITH_LEAN
00754 if (soap->recv_timeout)
00755 { struct timeval timeout;
00756 fd_set fd;
00757 if (soap->recv_timeout > 0)
00758 { timeout.tv_sec = soap->recv_timeout;
00759 timeout.tv_usec = 0;
00760 }
00761 else
00762 { timeout.tv_sec = -soap->recv_timeout/1000000;
00763 timeout.tv_usec = -soap->recv_timeout%1000000;
00764 }
00765 #ifndef WIN32
00766 if ((int)soap->socket > FD_SETSIZE)
00767 { soap->error = SOAP_FD_EXCEEDED;
00768 return 0;
00769 }
00770 #endif
00771 FD_ZERO(&fd);
00772 FD_SET((SOAP_SOCKET)soap->socket, &fd);
00773 for (;;)
00774 { r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout);
00775 if (r > 0)
00776 break;
00777 if (!r)
00778 { soap->errnum = 0;
00779 return 0;
00780 }
00781 if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EAGAIN)
00782 { soap->errnum = soap_socket_errno;
00783 return 0;
00784 }
00785 }
00786 }
00787 #endif
00788 #ifdef WITH_OPENSSL
00789 if (soap->ssl)
00790 { int err;
00791 r = SSL_read(soap->ssl, s, n);
00792 if (r > 0)
00793 return (size_t)r;
00794 err = SSL_get_error(soap->ssl, r);
00795 if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
00796 return 0;
00797 }
00798 else if (soap->bio)
00799 { r = BIO_read(soap->bio, s, n);
00800 if (r > 0)
00801 return (size_t)r;
00802 return 0;
00803 }
00804 else
00805 #endif
00806 {
00807 #ifdef WITH_UDP
00808 if ((soap->omode & SOAP_IO_UDP))
00809 { SOAP_SOCKLEN_T k = (SOAP_SOCKLEN_T)sizeof(soap->peer);
00810 memset((void*)&soap->peer, 0, sizeof(soap->peer));
00811 r = recvfrom((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags, (struct sockaddr*)&soap->peer, &k);
00812 soap->peerlen = (size_t)k;
00813 #ifndef WITH_IPV6
00814 soap->ip = ntohl(soap->peer.sin_addr.s_addr);
00815 #endif
00816 }
00817 else
00818 #endif
00819 r = recv((SOAP_SOCKET)soap->socket, s, n, soap->socket_flags);
00820 #ifdef PALM
00821
00822 #endif
00823 if (r >= 0)
00824 return (size_t)r;
00825 if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EAGAIN && soap_socket_errno != SOAP_EWOULDBLOCK)
00826 { soap->errnum = soap_socket_errno;
00827 return 0;
00828 }
00829 }
00830 #ifndef WITH_LEAN
00831 { struct timeval timeout;
00832 fd_set fd;
00833 timeout.tv_sec = 0;
00834 timeout.tv_usec = 10000;
00835 #ifndef WIN32
00836 if ((int)soap->socket > FD_SETSIZE)
00837 { soap->error = SOAP_FD_EXCEEDED;
00838 return 0;
00839 }
00840 #endif
00841 FD_ZERO(&fd);
00842 FD_SET((SOAP_SOCKET)soap->socket, &fd);
00843 #ifdef WITH_OPENSSL
00844 if (soap->ssl && SSL_get_error(soap->ssl, r) == SSL_ERROR_WANT_WRITE)
00845 r = select((SOAP_SOCKET)(soap->socket + 1), NULL, &fd, &fd, &timeout);
00846 else
00847 r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout);
00848 #else
00849 r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout);
00850 #endif
00851 if (r < 0 && soap_socket_errno != SOAP_EINTR)
00852 { soap->errnum = soap_socket_errno;
00853 return 0;
00854 }
00855 }
00856 #endif
00857 #ifdef PALM
00858 if (r < 0 && soap_socket_errno == SOAP_EINTR)
00859 { timeouts++;
00860 if (timeouts > 10)
00861 { soap->errnum = soap_socket_errno;
00862 return 0;
00863 }
00864 }
00865 #endif
00866 }
00867 }
00868 #ifdef WITH_FASTCGI
00869 return fread(s, 1, n, stdin);
00870 #else
00871 #ifdef UNDER_CE
00872 return fread(s, 1, n, soap->recvfd);
00873 #else
00874 #ifdef WMW_RPM_IO
00875 if (soap->rpmreqid)
00876 r = httpBlockRead(soap->rpmreqid, s, n);
00877 else
00878 #endif
00879 r = read((SOAP_SOCKET)soap->recvfd, s, n);
00880 if (r >= 0)
00881 return (size_t)r;
00882 soap->errnum = soap_errno;
00883 return 0;
00884 #endif
00885 #endif
00886 }
00887 #endif
00888 #endif
00889
00890
00891 #ifndef WITH_NOHTTP
00892 #ifndef PALM_1
00893 static soap_wchar
00894 soap_getchunkchar(struct soap *soap)
00895 { if (soap->bufidx < soap->buflen)
00896 return soap->buf[soap->bufidx++];
00897 soap->bufidx = 0;
00898 soap->buflen = soap->chunkbuflen = soap->frecv(soap, soap->buf, SOAP_BUFLEN);
00899 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes from socket %d\n", (unsigned int)soap->buflen, soap->socket));
00900 DBGMSG(RECV, soap->buf, soap->buflen);
00901 if (soap->buflen)
00902 return soap->buf[soap->bufidx++];
00903 return EOF;
00904 }
00905 #endif
00906 #endif
00907
00908
00909 #ifndef PALM_1
00910 static int
00911 soap_isxdigit(int c)
00912 { return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
00913 }
00914 #endif
00915
00916
00917 #ifndef PALM_1
00918 SOAP_FMAC1
00919 int
00920 SOAP_FMAC2
00921 soap_recv_raw(struct soap *soap)
00922 { register size_t ret;
00923 #ifdef WITH_ZLIB
00924 if (soap->mode & SOAP_ENC_ZLIB)
00925 { if (soap->d_stream.next_out == Z_NULL)
00926 return EOF;
00927 if (soap->d_stream.avail_in || !soap->d_stream.avail_out)
00928 { register int r;
00929 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflating\n"));
00930 soap->d_stream.next_out = (Byte*)soap->buf;
00931 soap->d_stream.avail_out = SOAP_BUFLEN;
00932 r = inflate(&soap->d_stream, Z_NO_FLUSH);
00933 if (r == Z_OK || r == Z_STREAM_END)
00934 { soap->bufidx = 0;
00935 soap->buflen = SOAP_BUFLEN - soap->d_stream.avail_out;
00936 if (soap->zlib_in == SOAP_ZLIB_GZIP)
00937 soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)soap->buflen);
00938 if (r == Z_STREAM_END)
00939 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %lu->%lu bytes\n", soap->d_stream.total_in, soap->d_stream.total_out));
00940 soap->z_ratio_in = (float)soap->d_stream.total_in / (float)soap->d_stream.total_out;
00941 soap->d_stream.next_out = Z_NULL;
00942 }
00943 if (soap->buflen)
00944 { soap->count += soap->buflen;
00945 return SOAP_OK;
00946 }
00947 }
00948 else if (r != Z_BUF_ERROR)
00949 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflate error: %s\n", soap->d_stream.msg?soap->d_stream.msg:""));
00950 soap->d_stream.next_out = Z_NULL;
00951 soap->error = SOAP_ZLIB_ERROR;
00952 return EOF;
00953 }
00954 }
00955 zlib_again:
00956 if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK && !soap->chunksize)
00957 { memcpy(soap->buf, soap->z_buf, SOAP_BUFLEN);
00958 soap->buflen = soap->z_buflen;
00959 }
00960 }
00961 #endif
00962 #ifndef WITH_NOHTTP
00963 if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK)
00964 {
00965 chunk_again:
00966 if (soap->chunksize)
00967 { soap->buflen = ret = soap->frecv(soap, soap->buf, soap->chunksize > SOAP_BUFLEN ? SOAP_BUFLEN : soap->chunksize);
00968 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Getting chunk: read %u bytes\n", (unsigned int)ret));
00969 DBGMSG(RECV, soap->buf, ret);
00970 soap->bufidx = 0;
00971 soap->chunksize -= ret;
00972 }
00973 else
00974 { register soap_wchar c;
00975 char *t, tmp[8];
00976 t = tmp;
00977 if (!soap->chunkbuflen)
00978 { soap->chunkbuflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN);
00979 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes (chunked) from socket %d\n", (unsigned int)ret, soap->socket));
00980 DBGMSG(RECV, soap->buf, ret);
00981 soap->bufidx = 0;
00982 if (!ret)
00983 return soap->ahead = EOF;
00984 }
00985 else
00986 soap->bufidx = soap->buflen;
00987 soap->buflen = soap->chunkbuflen;
00988 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Getting chunk size (idx=%u len=%u)\n", (unsigned int)soap->bufidx, (unsigned int)soap->buflen));
00989 while (!soap_isxdigit((int)(c = soap_getchunkchar(soap))))
00990 if ((int)c == EOF)
00991 return soap->ahead = EOF;
00992 do
00993 *t++ = (char)c;
00994 while (soap_isxdigit((int)(c = soap_getchunkchar(soap))) && t - tmp < 7);
00995 while ((int)c != EOF && c != '\n')
00996 c = soap_getchunkchar(soap);
00997 if ((int)c == EOF)
00998 return soap->ahead = EOF;
00999 *t = '\0';
01000 soap->chunksize = soap_strtoul(tmp, &t, 16);
01001 if (!soap->chunksize)
01002 { soap->chunkbuflen = 0;
01003 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of chunked message\n"));
01004 while ((int)c != EOF && c != '\n')
01005 c = soap_getchunkchar(soap);
01006 return soap->ahead = EOF;
01007 }
01008 soap->buflen = soap->bufidx + soap->chunksize;
01009 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Moving buf len to idx=%u len=%u (%s)\n", (unsigned int)soap->bufidx, (unsigned int)soap->buflen, tmp));
01010 if (soap->buflen > soap->chunkbuflen)
01011 { soap->buflen = soap->chunkbuflen;
01012 soap->chunksize -= soap->buflen - soap->bufidx;
01013 soap->chunkbuflen = 0;
01014 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Passed end of buffer for chunked HTTP (%u bytes left)\n", (unsigned int)(soap->buflen - soap->bufidx)));
01015 }
01016 else if (soap->chunkbuflen)
01017 soap->chunksize = 0;
01018 ret = soap->buflen - soap->bufidx;
01019 if (!ret)
01020 goto chunk_again;
01021 }
01022 }
01023 else
01024 #endif
01025 { soap->bufidx = 0;
01026 soap->buflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN);
01027 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes from socket %d\n", (unsigned int)ret, soap->socket));
01028 DBGMSG(RECV, soap->buf, ret);
01029 }
01030 #ifndef WITH_LEANER
01031 if (soap->fpreparerecv && (soap->error = soap->fpreparerecv(soap, soap->buf, ret)))
01032 return soap->error;
01033 #endif
01034 #ifdef WITH_ZLIB
01035 if (soap->mode & SOAP_ENC_ZLIB)
01036 { register int r;
01037 memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN);
01038 soap->d_stream.next_in = (Byte*)(soap->z_buf + soap->bufidx);
01039 soap->d_stream.avail_in = (unsigned int)ret;
01040 soap->d_stream.next_out = (Byte*)soap->buf;
01041 soap->d_stream.avail_out = SOAP_BUFLEN;
01042 r = inflate(&soap->d_stream, Z_NO_FLUSH);
01043 if (r == Z_OK || r == Z_STREAM_END)
01044 { soap->bufidx = 0;
01045 soap->z_buflen = soap->buflen;
01046 soap->buflen = ret = SOAP_BUFLEN - soap->d_stream.avail_out;
01047 if (soap->zlib_in == SOAP_ZLIB_GZIP)
01048 soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)soap->buflen);
01049 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %u bytes\n", (unsigned int)ret));
01050 if (!ret)
01051 goto zlib_again;
01052 if (r == Z_STREAM_END)
01053 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %lu->%lu bytes\n", soap->d_stream.total_in, soap->d_stream.total_out));
01054 soap->z_ratio_in = (float)soap->d_stream.total_in / (float)soap->d_stream.total_out;
01055 soap->d_stream.next_out = Z_NULL;
01056 }
01057 }
01058 else
01059 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to inflate: (%d) %s\n", r, soap->d_stream.msg?soap->d_stream.msg:""));
01060 soap->d_stream.next_out = Z_NULL;
01061 soap->error = SOAP_ZLIB_ERROR;
01062 return EOF;
01063 }
01064 }
01065 #endif
01066 soap->count += ret;
01067 return !ret;
01068 }
01069 #endif
01070
01071
01072 #ifndef PALM_1
01073 SOAP_FMAC1
01074 int
01075 SOAP_FMAC2
01076 soap_recv(struct soap *soap)
01077 {
01078 #ifndef WITH_LEANER
01079 if (soap->mode & SOAP_ENC_DIME)
01080 { if (soap->dime.buflen)
01081 { char *s;
01082 int i;
01083 unsigned char tmp[12];
01084 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME hdr for chunked DIME is in buffer\n"));
01085 soap->count += soap->dime.buflen - soap->buflen;
01086 soap->buflen = soap->dime.buflen;
01087 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Skip padding (%ld bytes)\n", -(long)soap->dime.size&3));
01088 for (i = -(long)soap->dime.size&3; i > 0; i--)
01089 { soap->bufidx++;
01090 if (soap->bufidx >= soap->buflen)
01091 if (soap_recv_raw(soap))
01092 return EOF;
01093 }
01094 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME hdr for next chunk\n"));
01095 s = (char*)tmp;
01096 for (i = 12; i > 0; i--)
01097 { *s++ = soap->buf[soap->bufidx++];
01098 if (soap->bufidx >= soap->buflen)
01099 if (soap_recv_raw(soap))
01100 return EOF;
01101 }
01102 soap->dime.flags = tmp[0] & 0x7;
01103 soap->dime.size = ((size_t)tmp[8] << 24) | ((size_t)tmp[9] << 16) | ((size_t)tmp[10] << 8) | ((size_t)tmp[11]);
01104 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME chunk (%u bytes)\n", (unsigned int)soap->dime.size));
01105 if (soap->dime.flags & SOAP_DIME_CF)
01106 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "More chunking\n"));
01107 soap->dime.chunksize = soap->dime.size;
01108 if (soap->buflen - soap->bufidx >= soap->dime.size)
01109 { soap->dime.buflen = soap->buflen;
01110 soap->buflen = soap->bufidx + soap->dime.chunksize;
01111 }
01112 else
01113 soap->dime.chunksize -= soap->buflen - soap->bufidx;
01114 }
01115 else
01116 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Last chunk\n"));
01117 soap->dime.buflen = 0;
01118 soap->dime.chunksize = 0;
01119 }
01120 soap->count = soap->buflen - soap->bufidx;
01121 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%u bytes remaining\n", (unsigned int)soap->count));
01122 return SOAP_OK;
01123 }
01124 if (soap->dime.chunksize)
01125 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get next DIME hdr for chunked DIME (%u bytes chunk)\n", (unsigned int)soap->dime.chunksize));
01126 if (soap_recv_raw(soap))
01127 return EOF;
01128 if (soap->buflen - soap->bufidx >= soap->dime.chunksize)
01129 { soap->dime.buflen = soap->buflen;
01130 soap->count -= soap->buflen - soap->bufidx - soap->dime.chunksize;
01131 soap->buflen = soap->bufidx + soap->dime.chunksize;
01132 }
01133 else
01134 soap->dime.chunksize -= soap->buflen - soap->bufidx;
01135 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%lu bytes remaining, count=%u\n", (unsigned long)(soap->buflen-soap->bufidx), (unsigned int)soap->count));
01136 return SOAP_OK;
01137 }
01138 }
01139 #endif
01140 return soap_recv_raw(soap);
01141 }
01142 #endif
01143
01144
01145 #ifndef PALM_1
01146 SOAP_FMAC1
01147 soap_wchar
01148 SOAP_FMAC2
01149 soap_getchar(struct soap *soap)
01150 { register soap_wchar c;
01151 c = soap->ahead;
01152 if (c)
01153 { if (c != EOF)
01154 soap->ahead = 0;
01155 return c;
01156 }
01157 return soap_get1(soap);
01158 }
01159 #endif
01160
01161
01162 #ifndef PALM_1
01163 SOAP_FMAC1
01164 const struct soap_code_map*
01165 SOAP_FMAC2
01166 soap_code(const struct soap_code_map *map, const char *str)
01167 { if (map && str)
01168 { while (map->string)
01169 { if (!strcmp(str, map->string))
01170 return map;
01171 map++;
01172 }
01173 }
01174 return NULL;
01175 }
01176 #endif
01177
01178
01179 #ifndef PALM_1
01180 SOAP_FMAC1
01181 long
01182 SOAP_FMAC2
01183 soap_code_int(const struct soap_code_map *map, const char *str, long other)
01184 { if (map)
01185 { while (map->string)
01186 { if (!soap_tag_cmp(str, map->string))
01187 return map->code;
01188 map++;
01189 }
01190 }
01191 return other;
01192 }
01193 #endif
01194
01195
01196 #ifndef PALM_1
01197 SOAP_FMAC1
01198 const char*
01199 SOAP_FMAC2
01200 soap_code_str(const struct soap_code_map *map, long code)
01201 { if (!map)
01202 return NULL;
01203 while (map->code != code && map->string)
01204 map++;
01205 return map->string;
01206 }
01207 #endif
01208
01209
01210 #ifndef PALM_1
01211 SOAP_FMAC1
01212 long
01213 SOAP_FMAC2
01214 soap_code_bits(const struct soap_code_map *map, const char *str)
01215 { register long bits = 0;
01216 if (map)
01217 { while (str && *str)
01218 { const struct soap_code_map *p;
01219 for (p = map; p->string; p++)
01220 { register size_t n = strlen(p->string);
01221 if (!strncmp(p->string, str, n) && soap_blank(str[n]))
01222 { bits |= p->code;
01223 str += n;
01224 while (*str > 0 && *str <= 32)
01225 str++;
01226 break;
01227 }
01228 }
01229 if (!p->string)
01230 return 0;
01231 }
01232 }
01233 return bits;
01234 }
01235 #endif
01236
01237
01238 #ifndef PALM_1
01239 SOAP_FMAC1
01240 const char*
01241 SOAP_FMAC2
01242 soap_code_list(struct soap *soap, const struct soap_code_map *map, long code)
01243 { register char *t = soap->tmpbuf;
01244 if (map)
01245 { while (map->string)
01246 { if (map->code & code)
01247 { register const char *s = map->string;
01248 if (t != soap->tmpbuf)
01249 *t++ = ' ';
01250 while (*s && t < soap->tmpbuf + sizeof(soap->tmpbuf) - 1)
01251 *t++ = *s++;
01252 if (t == soap->tmpbuf + sizeof(soap->tmpbuf) - 1)
01253 break;
01254 }
01255 map++;
01256 }
01257 }
01258 *t = '\0';
01259 return soap->tmpbuf;
01260 }
01261 #endif
01262
01263
01264 #ifndef PALM_1
01265 static soap_wchar
01266 soap_char(struct soap *soap)
01267 { char tmp[8];
01268 register int i;
01269 register soap_wchar c;
01270 register char *s = tmp;
01271 for (i = 0; i < 7; i++)
01272 { c = soap_get1(soap);
01273 if (c == ';' || (int)c == EOF)
01274 break;
01275 *s++ = (char)c;
01276 }
01277 *s = '\0';
01278 if (*tmp == '#')
01279 { if (tmp[1] == 'x' || tmp[1] == 'X')
01280 return soap_strtol(tmp + 2, NULL, 16);
01281 return atol(tmp + 1);
01282 }
01283 if (!strcmp(tmp, "lt"))
01284 return '<';
01285 if (!strcmp(tmp, "gt"))
01286 return '>';
01287 if (!strcmp(tmp, "amp"))
01288 return '&';
01289 if (!strcmp(tmp, "quot"))
01290 return '"';
01291 if (!strcmp(tmp, "apos"))
01292 return '\'';
01293 #ifndef WITH_LEAN
01294 return (soap_wchar)soap_code_int(html_entity_codes, tmp, SOAP_UNKNOWN_CHAR);
01295 #else
01296 return SOAP_UNKNOWN_CHAR;
01297 #endif
01298 }
01299 #endif
01300
01301
01302 #ifdef WITH_LEAN
01303 #ifndef PALM_1
01304 soap_wchar
01305 soap_get0(struct soap *soap)
01306 { if (soap->bufidx >= soap->buflen && soap_recv(soap))
01307 return EOF;
01308 return (unsigned char)soap->buf[soap->bufidx];
01309 }
01310 #endif
01311 #endif
01312
01313
01314 #ifdef WITH_LEAN
01315 #ifndef PALM_1
01316 soap_wchar
01317 soap_get1(struct soap *soap)
01318 { if (soap->bufidx >= soap->buflen && soap_recv(soap))
01319 return EOF;
01320 return (unsigned char)soap->buf[soap->bufidx++];
01321 }
01322 #endif
01323 #endif
01324
01325
01326 #ifndef PALM_1
01327 SOAP_FMAC1
01328 soap_wchar
01329 SOAP_FMAC2
01330 soap_get(struct soap *soap)
01331 { register soap_wchar c;
01332 c = soap->ahead;
01333 if (c)
01334 { if ((int)c != EOF)
01335 soap->ahead = 0;
01336 }
01337 else
01338 c = soap_get1(soap);
01339 while ((int)c != EOF)
01340 { if (soap->cdata)
01341 { if (c == ']')
01342 { c = soap_get1(soap);
01343 if (c == ']')
01344 { c = soap_get0(soap);
01345 if (c == '>')
01346 { soap->cdata = 0;
01347 soap_get1(soap);
01348 c = soap_get1(soap);
01349 }
01350 else
01351 { soap_unget(soap, ']');
01352 return ']';
01353 }
01354 }
01355 else
01356 { soap_revget1(soap);
01357 return ']';
01358 }
01359 }
01360 else
01361 return c;
01362 }
01363 switch (c)
01364 { case '<':
01365 do c = soap_get1(soap);
01366 while (soap_blank(c));
01367 if (c == '!' || c == '?' || c == '%')
01368 { register int k = 1;
01369 if (c == '!')
01370 { c = soap_get1(soap);
01371 if (c == '[')
01372 { do c = soap_get1(soap);
01373 while ((int)c != EOF && c != '[');
01374 if ((int)c == EOF)
01375 break;
01376 soap->cdata = 1;
01377 c = soap_get1(soap);
01378 continue;
01379 }
01380 if (c == '-' && (c = soap_get1(soap)) == '-')
01381 { do
01382 { c = soap_get1(soap);
01383 if (c == '-' && (c = soap_get1(soap)) == '-')
01384 break;
01385 } while ((int)c != EOF);
01386 }
01387 }
01388 else if (c == '?')
01389 c = soap_get_pi(soap);
01390 while ((int)c != EOF)
01391 { if (c == '<')
01392 k++;
01393 else if (c == '>')
01394 { if (--k <= 0)
01395 break;
01396 }
01397 c = soap_get1(soap);
01398 }
01399 if ((int)c == EOF)
01400 break;
01401 c = soap_get1(soap);
01402 continue;
01403 }
01404 if (c == '/')
01405 return SOAP_TT;
01406 soap_revget1(soap);
01407 return SOAP_LT;
01408 case '>':
01409 return SOAP_GT;
01410 case '"':
01411 return SOAP_QT;
01412 case '\'':
01413 return SOAP_AP;
01414 case '&':
01415 return soap_char(soap) | 0x80000000;
01416 }
01417 break;
01418 }
01419 return c;
01420 }
01421 #endif
01422
01423
01424 #ifndef PALM_1
01425 static soap_wchar
01426 soap_get_pi(struct soap *soap)
01427 { char buf[64];
01428 register char *s = buf;
01429 register int i = sizeof(buf);
01430 register soap_wchar c = soap_getchar(soap);
01431
01432
01433 while ((int)c != EOF && c != '?')
01434 { if (--i > 0)
01435 { if (soap_blank(c))
01436 c = ' ';
01437 *s++ = (char)c;
01438 }
01439 c = soap_getchar(soap);
01440 }
01441 *s = '\0';
01442 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "XML PI <?%s?>\n", buf));
01443 if (!strncmp(buf, "xml ", 4))
01444 { s = strstr(buf, " encoding=");
01445 if (s && s[10])
01446 { if (!soap_tag_cmp(s + 11, "iso-8859-1*")
01447 || !soap_tag_cmp(s + 11, "latin1*"))
01448 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Switching to latin1 encoding\n"));
01449 soap->mode |= SOAP_ENC_LATIN;
01450 }
01451 else if (!soap_tag_cmp(s + 11, "utf-8*"))
01452 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Switching to utf-8 encoding\n"));
01453 soap->mode &= ~SOAP_ENC_LATIN;
01454 }
01455 }
01456 }
01457 if ((int)c != EOF)
01458 c = soap_getchar(soap);
01459 return c;
01460 }
01461 #endif
01462
01463
01464 #ifndef WITH_LEANER
01465 #ifndef PALM_1
01466 SOAP_FMAC1
01467 int
01468 SOAP_FMAC2
01469 soap_move(struct soap *soap, long n)
01470 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Moving %ld bytes forward\n", (long)n));
01471 for (; n > 0; n--)
01472 if ((int)soap_getchar(soap) == EOF)
01473 return SOAP_EOF;
01474 return SOAP_OK;
01475 }
01476 #endif
01477 #endif
01478
01479
01480 #ifndef WITH_LEANER
01481 #ifndef PALM_1
01482 SOAP_FMAC1
01483 size_t
01484 SOAP_FMAC2
01485 soap_tell(struct soap *soap)
01486 { return soap->count - soap->buflen + soap->bufidx - (soap->ahead != 0);
01487 }
01488 #endif
01489 #endif
01490
01491
01492 #ifndef PALM_1
01493 SOAP_FMAC1
01494 int
01495 SOAP_FMAC2
01496 soap_pututf8(struct soap *soap, register unsigned long c)
01497 { char tmp[16];
01498 if (c > 0 && c < 0x80)
01499 { *tmp = (char)c;
01500 return soap_send_raw(soap, tmp, 1);
01501 }
01502 #ifndef WITH_LEAN
01503 if (soap->mode & SOAP_XML_CANONICAL)
01504 { register char *t = tmp;
01505 if (c < 0x0800)
01506 *t++ = (char)(0xC0 | ((c >> 6) & 0x1F));
01507 else
01508 { if (c < 0x010000)
01509 *t++ = (char)(0xE0 | ((c >> 12) & 0x0F));
01510 else
01511 { if (c < 0x200000)
01512 *t++ = (char)(0xF0 | ((c >> 18) & 0x07));
01513 else
01514 { if (c < 0x04000000)
01515 *t++ = (char)(0xF8 | ((c >> 24) & 0x03));
01516 else
01517 { *t++ = (char)(0xFC | ((c >> 30) & 0x01));
01518 *t++ = (char)(0x80 | ((c >> 24) & 0x3F));
01519 }
01520 *t++ = (char)(0x80 | ((c >> 18) & 0x3F));
01521 }
01522 *t++ = (char)(0x80 | ((c >> 12) & 0x3F));
01523 }
01524 *t++ = (char)(0x80 | ((c >> 6) & 0x3F));
01525 }
01526 *t++ = (char)(0x80 | (c & 0x3F));
01527 *t = '\0';
01528 }
01529 else
01530 #endif
01531 sprintf(tmp, "&#%lu;", c);
01532 return soap_send(soap, tmp);
01533 }
01534 #endif
01535
01536
01537 #ifndef PALM_1
01538 SOAP_FMAC1
01539 soap_wchar
01540 SOAP_FMAC2
01541 soap_getutf8(struct soap *soap)
01542 { register soap_wchar c, c1, c2, c3, c4;
01543 c = soap->ahead;
01544 if (c > 0xFF)
01545 { soap->ahead = 0;
01546 return c;
01547 }
01548 again:
01549 c = soap_get(soap);
01550 if (c < 0x80 || (soap->mode & SOAP_ENC_LATIN))
01551 return c;
01552 c1 = soap_get1(soap);
01553 if (c1 < 0x80)
01554 { soap_revget1(soap);
01555 return c;
01556 }
01557 c1 &= 0x3F;
01558 if (c < 0xE0)
01559 return ((soap_wchar)(c & 0x1F) << 6) | c1;
01560 c2 = (soap_wchar)soap_get1(soap) & 0x3F;
01561 if (c == 0xEF && c1 == 0x3B && c2 == 0x3F)
01562 goto again;
01563 if (c < 0xF0)
01564 return ((soap_wchar)(c & 0x0F) << 12) | (c1 << 6) | c2;
01565 c3 = (soap_wchar)soap_get1(soap) & 0x3F;
01566 if (c < 0xF8)
01567 return ((soap_wchar)(c & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3;
01568 c4 = (soap_wchar)soap_get1(soap) & 0x3F;
01569 if (c < 0xFC)
01570 return ((soap_wchar)(c & 0x03) << 24) | (c1 << 18) | (c2 << 12) | (c3 << 6) | c4;
01571 return ((soap_wchar)(c & 0x01) << 30) | (c1 << 24) | (c2 << 18) | (c3 << 12) | (c4 << 6) | (soap_wchar)(soap_get1(soap) & 0x3F);
01572 }
01573 #endif
01574
01575
01576 #ifndef PALM_1
01577 SOAP_FMAC1
01578 int
01579 SOAP_FMAC2
01580 soap_puthex(struct soap *soap, const unsigned char *s, int n)
01581 { char d[2];
01582 register int i;
01583 #ifdef WITH_DOM
01584 if ((soap->mode & SOAP_XML_DOM) && soap->dom)
01585 { if (!(soap->dom->data = soap_s2hex(soap, s, NULL, n)))
01586 return soap->error;
01587 return SOAP_OK;
01588 }
01589 #endif
01590 for (i = 0; i < n; i++)
01591 { register int m = *s++;
01592 d[0] = (char)((m >> 4) + (m > 159 ? '7' : '0'));
01593 m &= 0x0F;
01594 d[1] = (char)(m + (m > 9 ? '7' : '0'));
01595 if (soap_send_raw(soap, d, 2))
01596 return soap->error;
01597 }
01598 return SOAP_OK;
01599 }
01600 #endif
01601
01602
01603 #ifndef PALM_1
01604 SOAP_FMAC1
01605 unsigned char*
01606 SOAP_FMAC2
01607 soap_gethex(struct soap *soap, int *n)
01608 {
01609 #ifdef WITH_DOM
01610 if ((soap->mode & SOAP_XML_DOM) && soap->dom)
01611 { soap->dom->data = soap_string_in(soap, 0, -1, -1);
01612 return (unsigned char*)soap_hex2s(soap, soap->dom->data, NULL, 0, n);
01613 }
01614 #endif
01615 #ifdef WITH_FAST
01616 soap->labidx = 0;
01617 for (;;)
01618 { register char *s;
01619 register int i, k;
01620 if (soap_append_lab(soap, NULL, 0))
01621 return NULL;
01622 s = soap->labbuf + soap->labidx;
01623 k = soap->lablen - soap->labidx;
01624 soap->labidx = soap->lablen;
01625 for (i = 0; i < k; i++)
01626 { register char d1, d2;
01627 register soap_wchar c;
01628 c = soap_get(soap);
01629 if (soap_isxdigit(c))
01630 { d1 = (char)c;
01631 c = soap_get(soap);
01632 if (soap_isxdigit(c))
01633 d2 = (char)c;
01634 else
01635 { soap->error = SOAP_TYPE;
01636 return NULL;
01637 }
01638 }
01639 else
01640 { unsigned char *p;
01641 soap_unget(soap, c);
01642 if (n)
01643 *n = (int)(soap->lablen - k + i);
01644 p = (unsigned char*)soap_malloc(soap, soap->lablen - k + i);
01645 if (p)
01646 memcpy(p, soap->labbuf, soap->lablen - k + i);
01647 return p;
01648 }
01649 *s++ = ((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0');
01650 }
01651 }
01652 #else
01653 if (soap_new_block(soap))
01654 return NULL;
01655 for (;;)
01656 { register int i;
01657 register char *s = (char*)soap_push_block(soap, SOAP_BLKLEN);
01658 if (!s)
01659 { soap_end_block(soap);
01660 return NULL;
01661 }
01662 for (i = 0; i < SOAP_BLKLEN; i++)
01663 { register char d1, d2;
01664 register soap_wchar c = soap_get(soap);
01665 if (soap_isxdigit(c))
01666 { d1 = (char)c;
01667 c = soap_get(soap);
01668 if (soap_isxdigit(c))
01669 d2 = (char)c;
01670 else
01671 { soap_end_block(soap);
01672 soap->error = SOAP_TYPE;
01673 return NULL;
01674 }
01675 }
01676 else
01677 { unsigned char *p;
01678 soap_unget(soap, c);
01679 if (n)
01680 *n = soap_size_block(soap, i);
01681 p = (unsigned char*)soap_save_block(soap, NULL, 0);
01682 return p;
01683 }
01684 *s++ = ((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0');
01685 }
01686 }
01687 #endif
01688 }
01689 #endif
01690
01691
01692 #ifndef PALM_1
01693 SOAP_FMAC1
01694 int
01695 SOAP_FMAC2
01696 soap_putbase64(struct soap *soap, const unsigned char *s, int n)
01697 { register int i;
01698 register unsigned long m;
01699 char d[4];
01700 if (!s)
01701 return SOAP_OK;
01702 #ifdef WITH_DOM
01703 if ((soap->mode & SOAP_XML_DOM) && soap->dom)
01704 { if (!(soap->dom->data = soap_s2base64(soap, s, NULL, n)))
01705 return soap->error;
01706 return SOAP_OK;
01707 }
01708 #endif
01709 for (; n > 2; n -= 3, s += 3)
01710 { m = s[0];
01711 m = (m << 8) | s[1];
01712 m = (m << 8) | s[2];
01713 for (i = 4; i > 0; m >>= 6)
01714 d[--i] = soap_base64o[m & 0x3F];
01715 if (soap_send_raw(soap, d, 4))
01716 return soap->error;
01717 }
01718 if (n > 0)
01719 { m = 0;
01720 for (i = 0; i < n; i++)
01721 m = (m << 8) | *s++;
01722 for (; i < 3; i++)
01723 m <<= 8;
01724 for (i++; i > 0; m >>= 6)
01725 d[--i] = soap_base64o[m & 0x3F];
01726 for (i = 3; i > n; i--)
01727 d[i] = '=';
01728 if (soap_send_raw(soap, d, 4))
01729 return soap->error;
01730 }
01731 return SOAP_OK;
01732 }
01733 #endif
01734
01735
01736 #ifndef PALM_1
01737 SOAP_FMAC1
01738 unsigned char*
01739 SOAP_FMAC2
01740 soap_getbase64(struct soap *soap, int *n, int malloc_flag)
01741 {
01742 #ifdef WITH_DOM
01743 if ((soap->mode & SOAP_XML_DOM) && soap->dom)
01744 { soap->dom->data = soap_string_in(soap, 0, -1, -1);
01745 return (unsigned char*)soap_base642s(soap, soap->dom->data, NULL, 0, n);
01746 }
01747 #endif
01748 #ifdef WITH_FAST
01749 soap->labidx = 0;
01750 for (;;)
01751 { register int i, k;
01752 register char *s;
01753 if (soap_append_lab(soap, NULL, 2))
01754 return NULL;
01755 s = soap->labbuf + soap->labidx;
01756 k = soap->lablen - soap->labidx;
01757 soap->labidx = 3 * (soap->lablen / 3);
01758 if (!s)
01759 return NULL;
01760 for (i = 0; i < k - 2; i += 3)
01761 { register unsigned long m = 0;
01762 register int j = 0;
01763 do
01764 { register soap_wchar c = soap_get(soap);
01765 if (c == '=' || c < 0)
01766 { unsigned char *p;
01767 switch (j)
01768 { case 2:
01769 *s++ = (char)((m >> 4) & 0xFF);
01770 i++;
01771 break;
01772 case 3:
01773 *s++ = (char)((m >> 10) & 0xFF);
01774 *s++ = (char)((m >> 2) & 0xFF);
01775 i += 2;
01776 }
01777 if (n)
01778 *n = (int)(soap->lablen - k + i);
01779 p = (unsigned char*)soap_malloc(soap, soap->lablen - k + i);
01780 if (p)
01781 memcpy(p, soap->labbuf, soap->lablen - k + i);
01782 if (c >= 0)
01783 { while ((int)((c = soap_get(soap)) != EOF) && c != SOAP_LT && c != SOAP_TT)
01784 ;
01785 }
01786 soap_unget(soap, c);
01787 return p;
01788 }
01789 c -= '+';
01790 if (c >= 0 && c <= 79)
01791 { m = (m << 6) + soap_base64i[c];
01792 j++;
01793 }
01794 } while (j < 4);
01795 *s++ = (char)((m >> 16) & 0xFF);
01796 *s++ = (char)((m >> 8) & 0xFF);
01797 *s++ = (char)(m & 0xFF);
01798 }
01799 }
01800 #else
01801 if (soap_new_block(soap))
01802 return NULL;
01803 for (;;)
01804 { register int i;
01805 register char *s = (char*)soap_push_block(soap, 3 * SOAP_BLKLEN);
01806 if (!s)
01807 { soap_end_block(soap);
01808 return NULL;
01809 }
01810 for (i = 0; i < SOAP_BLKLEN; i++)
01811 { register unsigned long m = 0;
01812 register int j = 0;
01813 do
01814 { register soap_wchar c = soap_get(soap);
01815 if (c == '=' || c < 0)
01816 { unsigned char *p;
01817 i *= 3;
01818 switch (j)
01819 { case 2:
01820 *s++ = (char)((m >> 4) & 0xFF);
01821 i++;
01822 break;
01823 case 3:
01824 *s++ = (char)((m >> 10) & 0xFF);
01825 *s++ = (char)((m >> 2) & 0xFF);
01826 i += 2;
01827 }
01828 if (n)
01829 *n = (int)soap_size_block(soap, i);
01830 p = (unsigned char*)soap_save_block(soap, NULL, 0);
01831 if (c >= 0)
01832 { while ((int)((c = soap_get(soap)) != EOF) && c != SOAP_LT && c != SOAP_TT)
01833 ;
01834 }
01835 soap_unget(soap, c);
01836 return p;
01837 }
01838 c -= '+';
01839 if (c >= 0 && c <= 79)
01840 { m = (m << 6) + soap_base64i[c];
01841 j++;
01842 }
01843 } while (j < 4);
01844 *s++ = (char)((m >> 16) & 0xFF);
01845 *s++ = (char)((m >> 8) & 0xFF);
01846 *s++ = (char)(m & 0xFF);
01847 }
01848 }
01849 #endif
01850 }
01851 #endif
01852
01853
01854 #ifndef WITH_LEANER
01855 #ifndef PALM_1
01856 SOAP_FMAC1
01857 int
01858 SOAP_FMAC2
01859 soap_xop_forward(struct soap *soap, unsigned char **ptr, int *size, char **id, char **type, char **options)
01860 {
01861
01862 int body = soap->body;
01863 if (!soap_peek_element(soap))
01864 { if (!soap_element_begin_in(soap, "xop:Include", 0, NULL) && *soap->href)
01865 { if (soap_dime_forward(soap, ptr, size, id, type, options))
01866 return soap->error;
01867 }
01868 if (soap->body && soap_element_end_in(soap, NULL))
01869 return soap->error;
01870 }
01871 soap->body = body;
01872 return SOAP_OK;
01873 }
01874 #endif
01875 #endif
01876
01877
01878 #ifndef WITH_LEANER
01879 #ifndef PALM_1
01880 SOAP_FMAC1
01881 int
01882 SOAP_FMAC2
01883 soap_dime_forward(struct soap *soap, unsigned char **ptr, int *size, char **id, char **type, char **options)
01884 { struct soap_xlist *xp = (struct soap_xlist*)SOAP_MALLOC(soap, sizeof(struct soap_xlist));
01885 *ptr = NULL;
01886 *size = 0;
01887 *id = soap_strdup(soap, soap->href);
01888 *type = NULL;
01889 *options = NULL;
01890 if (!xp)
01891 return soap->error = SOAP_EOM;
01892 xp->next = soap->xlist;
01893 xp->ptr = ptr;
01894 xp->size = size;
01895 xp->id = *id;
01896 xp->type = type;
01897 xp->options = options;
01898 soap->xlist = xp;
01899 return SOAP_OK;
01900 }
01901 #endif
01902 #endif
01903
01904
01905 #ifndef PALM_1
01906 SOAP_FMAC1
01907 char *
01908 SOAP_FMAC2
01909 soap_strdup(struct soap *soap, const char *s)
01910 { char *t = NULL;
01911 if (s && (t = (char*)soap_malloc(soap, strlen(s) + 1)))
01912 strcpy(t, s);
01913 return t;
01914 }
01915 #endif
01916
01917
01918 #ifndef PALM_1
01919 SOAP_FMAC1
01920 int
01921 SOAP_FMAC2
01922 soap_new_block(struct soap *soap)
01923 { struct soap_blist *p;
01924 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "New block sequence (prev=%p)\n", soap->blist));
01925 if (!(p = (struct soap_blist*)SOAP_MALLOC(soap, sizeof(struct soap_blist))))
01926 return SOAP_EOM;
01927 p->next = soap->blist;
01928 p->ptr = NULL;
01929 p->size = 0;
01930 soap->blist = p;
01931 return SOAP_OK;
01932 }
01933 #endif
01934
01935
01936 #ifndef PALM_1
01937 SOAP_FMAC1
01938 void*
01939 SOAP_FMAC2
01940 soap_push_block(struct soap *soap, size_t n)
01941 { char *p;
01942 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));
01943 if (!(p = (char*)SOAP_MALLOC(soap, n + sizeof(char*) + sizeof(size_t))))
01944 { soap->error = SOAP_EOM;
01945 return NULL;
01946 }
01947 *(char**)p = soap->blist->ptr;
01948 *(size_t*)(p + sizeof(char*)) = n;
01949 soap->blist->ptr = p;
01950 soap->blist->size += n;
01951 return p + sizeof(char*) + sizeof(size_t);
01952 }
01953 #endif
01954
01955
01956 #ifndef PALM_1
01957 SOAP_FMAC1
01958 void
01959 SOAP_FMAC2
01960 soap_pop_block(struct soap *soap)
01961 { char *p;
01962 if (!soap->blist->ptr)
01963 return;
01964 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Pop block\n"));
01965 p = soap->blist->ptr;
01966 soap->blist->size -= *(size_t*)(p + sizeof(char*));
01967 soap->blist->ptr = *(char**)p;
01968 SOAP_FREE(soap, p);
01969 }
01970 #endif
01971
01972
01973 #ifndef WITH_NOIDREF
01974 #ifndef PALM_1
01975 static void
01976 soap_update_ptrs(struct soap *soap, char *start, char *end, char *p1, char *p2)
01977 { int i;
01978 register struct soap_ilist *ip;
01979 register struct soap_flist *fp;
01980 #ifndef WITH_LEANER
01981 register struct soap_xlist *xp;
01982 #endif
01983 register void *p, **q;
01984 for (i = 0; i < SOAP_IDHASH; i++)
01985 { for (ip = soap->iht[i]; ip; ip = ip->next)
01986 { if (ip->ptr && (char*)ip->ptr >= start && (char*)ip->ptr < end)
01987 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update id='%s' %p -> %p\n", ip->id, ip->ptr, (char*)ip->ptr + (p1-p2)));
01988 ip->ptr = (char*)ip->ptr + (p1-p2);
01989 }
01990 for (q = &ip->link; q; q = (void**)p)
01991 { p = *q;
01992 if (p && (char*)p >= start && (char*)p < end)
01993 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Link update id='%s' %p\n", ip->id, p));
01994 *q = (char*)p + (p1-p2);
01995 }
01996 }
01997 for (q = &ip->copy; q; q = (void**)p)
01998 { p = *q;
01999 if (p && (char*)p >= start && (char*)p < end)
02000 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy chain update id='%s' %p\n", ip->id, p));
02001 *q = (char*)p + (p1-p2);
02002 }
02003 }
02004 for (fp = ip->flist; fp; fp = fp->next)
02005 { if ((char*)fp->ptr >= start && (char*)fp->ptr < end)
02006 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy list update id='%s' %p\n", ip->id, fp));
02007 fp->ptr = (char*)fp->ptr + (p1-p2);
02008 }
02009 }
02010 }
02011 }
02012 #ifndef WITH_LEANER
02013 for (xp = soap->xlist; xp; xp = xp->next)
02014 { if (xp->ptr && (char*)xp->ptr >= start && (char*)xp->ptr < end)
02015 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update id='%s' %p -> %p\n", xp->id?xp->id:"", xp->ptr, (char*)xp->ptr + (p1-p2)));
02016 xp->ptr = (unsigned char**)((char*)xp->ptr + (p1-p2));
02017 xp->size = (int*)((char*)xp->size + (p1-p2));
02018 xp->type = (char**)((char*)xp->type + (p1-p2));
02019 xp->options = (char**)((char*)xp->options + (p1-p2));
02020 }
02021 }
02022 #endif
02023 }
02024 #endif
02025 #endif
02026
02027
02028 #ifndef WITH_NOIDREF
02029 #ifndef PALM_1
02030 static int
02031 soap_has_copies(struct soap *soap, register const char *start, register const char *end)
02032 { register int i;
02033 register struct soap_ilist *ip;
02034 register struct soap_flist *fp;
02035 register const char *p;
02036 for (i = 0; i < SOAP_IDHASH; i++)
02037 { for (ip = soap->iht[i]; ip; ip = ip->next)
02038 { for (p = (const char*)ip->copy; p; p = *(const char**)p)
02039 if (p >= start && p < end)
02040 return SOAP_ERR;
02041 for (fp = ip->flist; fp; fp = fp->next)
02042 if ((const char*)fp->ptr >= start && (const char*)fp->ptr < end)
02043 return SOAP_ERR;
02044 }
02045 }
02046 return SOAP_OK;
02047 }
02048 #endif
02049 #endif
02050
02051
02052 #ifndef WITH_NOIDREF
02053 #ifndef PALM_1
02054 SOAP_FMAC1
02055 int
02056 SOAP_FMAC2
02057 soap_resolve(struct soap *soap)
02058 { register int i;
02059 register struct soap_ilist *ip;
02060 register struct soap_flist *fp;
02061 short flag;
02062 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving forwarded data\n"));
02063 for (i = 0; i < SOAP_IDHASH; i++)
02064 { for (ip = soap->iht[i]; ip; ip = ip->next)
02065 { if (ip->ptr)
02066 { register void *p, **q, *r;
02067 q = (void**)ip->link;
02068 ip->link = NULL;
02069 r = ip->ptr;
02070 DBGLOG(TEST, if (q) SOAP_MESSAGE(fdebug, "Traversing link chain to resolve id='%s'\n", ip->id));
02071 while (q)
02072 { p = *q;
02073 *q = r;
02074 DBGLOG(TEST,SOAP_MESSAGE(fdebug, "... link %p -> %p\n", q, r));
02075 q = (void**)p;
02076 }
02077 }
02078 else if (*ip->id == '#')
02079 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Missing data for id='%s'\n", ip->id));
02080 strcpy(soap->id, ip->id + 1);
02081 return soap->error = SOAP_MISSING_ID;
02082 }
02083 }
02084 }
02085 do
02086 { flag = 0;
02087 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolution phase\n"));
02088 for (i = 0; i < SOAP_IDHASH; i++)
02089 { for (ip = soap->iht[i]; ip; ip = ip->next)
02090 { if (ip->ptr && !soap_has_copies(soap, (const char*)ip->ptr, (const char*)ip->ptr + ip->size))
02091 { if (ip->copy)
02092 { register void *p, **q = (void**)ip->copy;
02093 DBGLOG(TEST, if (q) SOAP_MESSAGE(fdebug, "Traversing copy chain to resolve id='%s'\n", ip->id));
02094 ip->copy = NULL;
02095 do
02096 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "... copy %p -> %p (%u bytes)\n", ip->ptr, q, (unsigned int)ip->size));
02097 p = *q;
02098 memcpy(q, ip->ptr, ip->size);
02099 q = (void**)p;
02100 } while (q);
02101 flag = 1;
02102 }
02103 for (fp = ip->flist; fp; fp = ip->flist)
02104 { register unsigned int k = fp->level;
02105 register void *p = ip->ptr;
02106 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));
02107 while (ip->level < k)
02108 { register void **q = (void**)soap_malloc(soap, sizeof(void*));
02109 if (!q)
02110 return soap->error;
02111 *q = p;
02112 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level, new location=%p holds=%p...\n", q, *q));
02113 p = (void*)q;
02114 k--;
02115 }
02116 if (fp->fcopy)
02117 fp->fcopy(soap, ip->type, fp->type, fp->ptr, fp->len, p, ip->size);
02118 else
02119 soap_fcopy(soap, ip->type, fp->type, fp->ptr, fp->len, p, ip->size);
02120 ip->flist = fp->next;
02121 SOAP_FREE(soap, fp);
02122 flag = 1;
02123 }
02124 }
02125 }
02126 }
02127 } while (flag);
02128 #ifdef SOAP_DEBUG
02129 for (i = 0; i < SOAP_IDHASH; i++)
02130 { for (ip = soap->iht[i]; ip; ip = ip->next)
02131 { if (ip->copy || ip->flist)
02132 { 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));
02133 }
02134 }
02135 }
02136 #endif
02137 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolution done\n"));
02138 return SOAP_OK;
02139 }
02140 #endif
02141 #endif
02142
02143
02144 #ifndef PALM_1
02145 SOAP_FMAC1
02146 size_t
02147 SOAP_FMAC2
02148 soap_size_block(struct soap *soap, size_t n)
02149 { if (soap->blist->ptr)
02150 { soap->blist->size -= *(size_t*)(soap->blist->ptr + sizeof(char*)) - n;
02151 *(size_t*)(soap->blist->ptr + sizeof(char*)) = n;
02152 }
02153 return soap->blist->size;
02154 }
02155 #endif
02156
02157
02158 #ifndef PALM_1
02159 SOAP_FMAC1
02160 char*
02161 SOAP_FMAC2
02162 soap_first_block(struct soap *soap)
02163 { char *p, *q, *r;
02164 p = soap->blist->ptr;
02165 if (!p)
02166 return NULL;
02167 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "First block\n"));
02168 r = NULL;
02169 do
02170 { q = *(char**)p;
02171 *(char**)p = r;
02172 r = p;
02173 p = q;
02174 } while (p);
02175 soap->blist->ptr = r;
02176 return r + sizeof(char*) + sizeof(size_t);
02177 }
02178 #endif
02179
02180
02181 #ifndef PALM_1
02182 SOAP_FMAC1
02183 char*
02184 SOAP_FMAC2
02185 soap_next_block(struct soap *soap)
02186 { char *p;
02187 p = soap->blist->ptr;
02188 if (p)
02189 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Next block\n"));
02190 soap->blist->ptr = *(char**)p;
02191 SOAP_FREE(soap, p);
02192 if (soap->blist->ptr)
02193 return soap->blist->ptr + sizeof(char*) + sizeof(size_t);
02194 }
02195 return NULL;
02196 }
02197 #endif
02198
02199
02200 #ifndef PALM_1
02201 SOAP_FMAC1
02202 size_t
02203 SOAP_FMAC2
02204 soap_block_size(struct soap *soap)
02205 { return *(size_t*)(soap->blist->ptr + sizeof(char*));
02206 }
02207 #endif
02208
02209
02210 #ifndef PALM_1
02211 SOAP_FMAC1
02212 void
02213 SOAP_FMAC2
02214 soap_end_block(struct soap *soap)
02215 { struct soap_blist *bp;
02216 char *p, *q;
02217 bp = soap->blist;
02218 if (bp)
02219 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of block sequence, free all remaining blocks\n"));
02220 for (p = bp->ptr; p; p = q)
02221 { q = *(char**)p;
02222 SOAP_FREE(soap, p);
02223 }
02224 soap->blist = bp->next;
02225 SOAP_FREE(soap, bp);
02226 }
02227 DBGLOG(TEST, if (soap->blist) SOAP_MESSAGE(fdebug, "Restore previous block sequence\n"));
02228 }
02229 #endif
02230
02231
02232 #ifndef PALM_1
02233 SOAP_FMAC1
02234 char*
02235 SOAP_FMAC2
02236 soap_save_block(struct soap *soap, char *p, int flag)
02237 { register size_t n;
02238 register char *q, *s;
02239 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));
02240 if (soap->blist->size)
02241 { if (!p)
02242 p = (char*)soap_malloc(soap, soap->blist->size);
02243 if (p)
02244 { for (s = p, q = soap_first_block(soap); q; q = soap_next_block(soap))
02245 { n = soap_block_size(soap);
02246 #ifndef WITH_NOIDREF
02247 if (flag)
02248 soap_update_ptrs(soap, q, q + n, s, q);
02249 #endif
02250 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy %u bytes from %p to %p\n", (unsigned int)n, q, s));
02251 memcpy(s, q, n);
02252 s += n;
02253 }
02254 }
02255 else
02256 soap->error = SOAP_EOM;
02257 }
02258 soap_end_block(soap);
02259 return p;
02260 }
02261 #endif
02262
02263
02264 #ifndef PALM_2
02265 SOAP_FMAC1
02266 char *
02267 SOAP_FMAC2
02268 soap_putsize(struct soap *soap, const char *type, int size)
02269 { return soap_putsizes(soap, type, &size, 1);
02270 }
02271 #endif
02272
02273
02274 #ifndef PALM_2
02275 SOAP_FMAC1
02276 char *
02277 SOAP_FMAC2
02278 soap_putsizes(struct soap *soap, const char *type, const int *size, int dim)
02279 { return soap_putsizesoffsets(soap, type, size, NULL, dim);
02280 }
02281 #endif
02282
02283
02284 #ifndef PALM_2
02285 SOAP_FMAC1
02286 char *
02287 SOAP_FMAC2
02288 soap_putsizesoffsets(struct soap *soap, const char *type, const int *size, const int *offset, int dim)
02289 { int i;
02290 if (!type)
02291 return NULL;
02292 if (soap->version == 2)
02293 { sprintf(soap->type, "%s[%d", type, size[0]);
02294 for (i = 1; i < dim; i++)
02295 sprintf(soap->type + strlen(soap->type), " %d", size[i]);
02296 }
02297 else
02298 { if (offset)
02299 { sprintf(soap->type, "%s[%d", type, size[0] + offset[0]);
02300 for (i = 1; i < dim; i++)
02301 sprintf(soap->type + strlen(soap->type), ",%d", size[i] + offset[i]);
02302 }
02303 else
02304 { sprintf(soap->type, "%s[%d", type, size[0]);
02305 for (i = 1; i < dim; i++)
02306 sprintf(soap->type + strlen(soap->type), ",%d", size[i]);
02307 }
02308 strcat(soap->type, "]");
02309 }
02310 return soap->type;
02311 }
02312 #endif
02313
02314
02315 #ifndef PALM_2
02316 SOAP_FMAC1
02317 char *
02318 SOAP_FMAC2
02319 soap_putoffset(struct soap *soap, int offset)
02320 { return soap_putoffsets(soap, &offset, 1);
02321 }
02322 #endif
02323
02324
02325 #ifndef PALM_2
02326 SOAP_FMAC1
02327 char *
02328 SOAP_FMAC2
02329 soap_putoffsets(struct soap *soap, const int *offset, int dim)
02330 { register int i;
02331 sprintf(soap->arrayOffset, "[%d", offset[0]);
02332 for (i = 1; i < dim; i++)
02333 sprintf(soap->arrayOffset + strlen(soap->arrayOffset), ",%d", offset[i]);
02334 strcat(soap->arrayOffset, "]");
02335 return soap->arrayOffset;
02336 }
02337 #endif
02338
02339
02340 #ifndef PALM_2
02341 SOAP_FMAC1
02342 int
02343 SOAP_FMAC2
02344 soap_size(const int *size, int dim)
02345 { register int i, n = size[0];
02346 for (i = 1; i < dim; i++)
02347 n *= size[i];
02348 return n;
02349 }
02350 #endif
02351
02352
02353 #ifndef PALM_2
02354 SOAP_FMAC1
02355 int
02356 SOAP_FMAC2
02357 soap_getoffsets(const char *attr, const int *size, int *offset, int dim)
02358 { register int i, j = 0;
02359 if (offset)
02360 for (i = 0; i < dim && attr && *attr; i++)
02361 { attr++;
02362 j *= size[i];
02363 j += offset[i] = (int)atol(attr);
02364 attr = strchr(attr, ',');
02365 }
02366 else
02367 for (i = 0; i < dim && attr && *attr; i++)
02368 { attr++;
02369 j *= size[i];
02370 j += (int)atol(attr);
02371 attr = strchr(attr, ',');
02372 }
02373 return j;
02374 }
02375 #endif
02376
02377
02378 #ifndef PALM_2
02379 SOAP_FMAC1
02380 int
02381 SOAP_FMAC2
02382 soap_getsize(const char *attr1, const char *attr2, int *j)
02383 { register int n, k;
02384 char *s;
02385 *j = 0;
02386 if (!*attr1)
02387 return -1;
02388 if (*attr1 == '[')
02389 attr1++;
02390 n = 1;
02391 for (;;)
02392 { k = (int)soap_strtol(attr1, &s, 10);
02393 n *= k;
02394 if (k < 0 || n > SOAP_MAXARRAYSIZE || s == attr1)
02395 return -1;
02396 attr1 = strchr(s, ',');
02397 if (!attr1)
02398 attr1 = strchr(s, ' ');
02399 if (attr2 && *attr2)
02400 { attr2++;
02401 *j *= k;
02402 k = (int)soap_strtol(attr2, &s, 10);
02403 *j += k;
02404 if (k < 0)
02405 return -1;
02406 attr2 = s;
02407 }
02408 if (!attr1)
02409 break;
02410 attr1++;
02411 }
02412 return n - *j;
02413 }
02414 #endif
02415
02416
02417 #ifndef PALM_2
02418 SOAP_FMAC1
02419 int
02420 SOAP_FMAC2
02421 soap_getsizes(const char *attr, int *size, int dim)
02422 { register int i, k, n;
02423 if (!*attr)
02424 return -1;
02425 i = strlen(attr);
02426 n = 1;
02427 do
02428 { for (i = i-1; i >= 0; i--)
02429 if (attr[i] == '[' || attr[i] == ',' || attr[i] == ' ')
02430 break;
02431 k = (int)atol(attr + i + 1);
02432 n *= size[--dim] = k;
02433 if (k < 0 || n > SOAP_MAXARRAYSIZE)
02434 return -1;
02435 } while (i >= 0 && attr[i] != '[');
02436 return n;
02437 }
02438 #endif
02439
02440
02441 #ifndef PALM_2
02442 SOAP_FMAC1
02443 int
02444 SOAP_FMAC2
02445 soap_getposition(const char *attr, int *pos)
02446 { register int i, n;
02447 if (!*attr)
02448 return -1;
02449 n = 0;
02450 i = 1;
02451 do
02452 { pos[n++] = (int)atol(attr + i);
02453 while (attr[i] && attr[i] != ',' && attr[i] != ']')
02454 i++;
02455 if (attr[i] == ',')
02456 i++;
02457 } while (n < SOAP_MAXDIMS && attr[i] && attr[i] != ']');
02458 return n;
02459 }
02460 #endif
02461
02462
02463 #ifndef PALM_2
02464 SOAP_FMAC1
02465 int
02466 SOAP_FMAC2
02467 soap_push_namespace(struct soap *soap, const char *id, const char *ns)
02468 { register struct soap_nlist *np;
02469 register struct Namespace *p;
02470 register short i = -1;
02471 register size_t n, k;
02472 n = strlen(id);
02473 k = strlen(ns) + 1;
02474 p = soap->local_namespaces;
02475 if (p)
02476 { for (i = 0; p->id; p++, i++)
02477 { if (p->ns && !strcmp(ns, p->ns))
02478 { if (p->out)
02479 { SOAP_FREE(soap, p->out);
02480 p->out = NULL;
02481 }
02482 break;
02483 }
02484 if (p->out)
02485 { if (!strcmp(ns, p->out))
02486 break;
02487 }
02488 else if (p->in)
02489 { if (!soap_tag_cmp(ns, p->in))
02490 { if ((p->out = (char*)SOAP_MALLOC(soap, k)))
02491 strcpy(p->out, ns);
02492 break;
02493 }
02494 }
02495 }
02496 if (!p || !p->id)
02497 i = -1;
02498 }
02499 if (i >= 0)
02500 k = 0;
02501 np = (struct soap_nlist*)SOAP_MALLOC(soap, sizeof(struct soap_nlist) + n + k);
02502 if (!np)
02503 return soap->error = SOAP_EOM;
02504 np->next = soap->nlist;
02505 soap->nlist = np;
02506 np->level = soap->level;
02507 np->index = i;
02508 strcpy(np->id, id);
02509 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push namespace binding (level=%u) '%s' '%s'\n", soap->level, id, ns));
02510 if (i < 0)
02511 { np->ns = np->id + n + 1;
02512 strcpy(np->ns, ns);
02513 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push NOT OK: no match found for '%s' in namespace mapping table (added to stack anyway)\n", ns));
02514 }
02515 else
02516 { np->ns = NULL;
02517 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push OK ('%s' matches '%s' in namespace table)\n", id, p->id));
02518 }
02519 return SOAP_OK;
02520 }
02521 #endif
02522
02523
02524 #ifndef PALM_2
02525 SOAP_FMAC1
02526 void
02527 SOAP_FMAC2
02528 soap_pop_namespace(struct soap *soap)
02529 { register struct soap_nlist *np;
02530 while (soap->nlist && soap->nlist->level >= soap->level)
02531 { np = soap->nlist->next;
02532 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Popped namespace binding (level=%u) '%s'\n", soap->level, soap->nlist->id));
02533 SOAP_FREE(soap, soap->nlist);
02534 soap->nlist = np;
02535 }
02536 }
02537 #endif
02538
02539
02540 #ifndef PALM_2
02541 SOAP_FMAC1
02542 int
02543 SOAP_FMAC2
02544 soap_match_namespace(struct soap *soap, const char *id1, const char *id2, int n1, int n2)
02545 { register struct soap_nlist *np = soap->nlist;
02546 while (np && (strncmp(np->id, id1, n1) || np->id[n1]))
02547 np = np->next;
02548 if (np)
02549 { if (np->index < 0
02550 || (soap->local_namespaces[np->index].id
02551 && (strncmp(soap->local_namespaces[np->index].id, id2, n2)
02552 || soap->local_namespaces[np->index].id[n2])))
02553 return SOAP_NAMESPACE;
02554 return SOAP_OK;
02555 }
02556 if (n1 == 3 && n1 == n2 && !strcmp(id1, "xml") && !strcmp(id1, id2))
02557 return SOAP_OK;
02558 return SOAP_SYNTAX_ERROR;
02559 }
02560 #endif
02561
02562
02563 #ifndef PALM_2
02564 SOAP_FMAC1
02565 const char*
02566 SOAP_FMAC2
02567 soap_current_namespace(struct soap *soap, const char *tag)
02568 { register struct soap_nlist *np;
02569 register const char *s;
02570 np = soap->nlist;
02571 if (!(s = strchr(tag, ':')))
02572 { while (np && *np->id)
02573 np = np->next;
02574 }
02575 else
02576 { while (np && (strncmp(np->id, tag, s - tag) || np->id[s - tag]))
02577 np = np->next;
02578 if (!np)
02579 soap->error = SOAP_NAMESPACE;
02580 }
02581 if (np)
02582 { if (np->index >= 0)
02583 return soap->namespaces[np->index].ns;
02584 if (np->ns)
02585 return soap_strdup(soap, np->ns);
02586 }
02587 return NULL;
02588 }
02589 #endif
02590
02591
02592 #ifndef PALM_2
02593 SOAP_FMAC1
02594 int
02595 SOAP_FMAC2
02596 soap_tag_cmp(const char *s, const char *t)
02597 { for (;;)
02598 { register int c1 = *s;
02599 register int c2 = *t;
02600 if (!c1 || c1 == '"')
02601 break;
02602 if (c2 != '-')
02603 { if (c1 != c2)
02604 { if (c1 >= 'A' && c1 <= 'Z')
02605 c1 += 'a' - 'A';
02606 if (c2 >= 'A' && c2 <= 'Z')
02607 c2 += 'a' - 'A';
02608 }
02609 if (c1 != c2)
02610 { if (c2 != '*')
02611 return 1;
02612 c2 = *++t;
02613 if (!c2)
02614 return 0;
02615 if (c2 >= 'A' && c2 <= 'Z')
02616 c2 += 'a' - 'A';
02617 for (;;)
02618 { c1 = *s;
02619 if (!c1 || c1 == '"')
02620 break;
02621 if (c1 >= 'A' && c1 <= 'Z')
02622 c1 += 'a' - 'A';
02623 if (c1 == c2 && !soap_tag_cmp(s + 1, t + 1))
02624 return 0;
02625 s++;
02626 }
02627 break;
02628 }
02629 }
02630 s++;
02631 t++;
02632 }
02633 if (*t == '*' && !t[1])
02634 return 0;
02635 return *t;
02636 }
02637 #endif
02638
02639
02640 #ifndef PALM_2
02641 SOAP_FMAC1
02642 int
02643 SOAP_FMAC2
02644 soap_match_tag(struct soap *soap, const char *tag1, const char *tag2)
02645 { register const char *s, *t;
02646 if (!tag1 || !tag2 || !*tag2)
02647 return SOAP_OK;
02648 s = strchr(tag1, ':');
02649 t = strchr(tag2, ':');
02650 if (t)
02651 { if (s)
02652 { if (t[1] && SOAP_STRCMP(s + 1, t + 1))
02653 return SOAP_TAG_MISMATCH;
02654 if (t != tag2 && soap_match_namespace(soap, tag1, tag2, s - tag1, t - tag2))
02655 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags '%s' and '%s' match but namespaces differ\n", tag1, tag2));
02656 return SOAP_TAG_MISMATCH;
02657 }
02658 }
02659 else if (SOAP_STRCMP(tag1, t + 1))
02660 return SOAP_TAG_MISMATCH;
02661 else if (t != tag2 && soap_match_namespace(soap, tag1, tag2, 0, t - tag2))
02662 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags '%s' and '%s' match but namespaces differ\n", tag1, tag2));
02663 return SOAP_TAG_MISMATCH;
02664 }
02665 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags and (default) namespaces match: '%s' '%s'\n", tag1, tag2));
02666 return SOAP_OK;
02667 }
02668 if (s)
02669 { if (SOAP_STRCMP(s + 1, tag2))
02670 return SOAP_TAG_MISMATCH;
02671 }
02672 else if (SOAP_STRCMP(tag1, tag2))
02673 return SOAP_TAG_MISMATCH;
02674 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags match: '%s' '%s'\n", tag1, tag2));
02675 return SOAP_OK;
02676 }
02677 #endif
02678
02679
02680 #ifndef PALM_2
02681 SOAP_FMAC1
02682 int
02683 SOAP_FMAC2
02684 soap_match_array(struct soap *soap, const char *type)
02685 { if (*soap->arrayType)
02686 if (soap_match_tag(soap, soap->arrayType, type)
02687 && soap_match_tag(soap, soap->arrayType, "xsd:anyType")
02688 && soap_match_tag(soap, soap->arrayType, "xsd:ur-type")
02689 )
02690 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array type mismatch: '%s' '%s'\n", soap->arrayType, type));
02691 return SOAP_TAG_MISMATCH;
02692 }
02693 return SOAP_OK;
02694 }
02695 #endif
02696
02697
02698
02699
02700
02701
02702
02703 #ifdef WITH_OPENSSL
02704
02705 #ifndef PALM_2
02706 SOAP_FMAC1
02707 int
02708 SOAP_FMAC2
02709 soap_rand()
02710 { unsigned char buf[4];
02711 if (!ssl_init_done)
02712 soap_ssl_init();
02713 RAND_pseudo_bytes(buf, 4);
02714 return *(int*)buf;
02715 }
02716 #endif
02717
02718
02719 #ifndef PALM_2
02720 SOAP_FMAC1
02721 int
02722 SOAP_FMAC2
02723 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)
02724 { int err;
02725 soap->keyfile = keyfile;
02726 soap->password = password;
02727 soap->cafile = cafile;
02728 soap->capath = capath;
02729 soap->dhfile = dhfile;
02730 soap->rsa = (dhfile == NULL);
02731 soap->randfile = randfile;
02732 soap->require_client_auth = (flags & SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION);
02733 if (!(err = soap->fsslauth(soap)))
02734 { if (sid)
02735 SSL_CTX_set_session_id_context(soap->ctx, (unsigned char*)sid, strlen(sid));
02736 }
02737 return err;
02738 }
02739 #endif
02740
02741
02742 #ifndef PALM_2
02743 SOAP_FMAC1
02744 int
02745 SOAP_FMAC2
02746 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)
02747 { soap->keyfile = keyfile;
02748 soap->password = password;
02749 soap->cafile = cafile;
02750 soap->capath = capath;
02751 soap->dhfile = NULL;
02752 soap->rsa = 0;
02753 soap->randfile = randfile;
02754 soap->require_server_auth = (flags & SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION);
02755 return soap->fsslauth(soap);
02756 }
02757 #endif
02758
02759
02760 #ifndef PALM_2
02761 SOAP_FMAC1
02762 void
02763 SOAP_FMAC2
02764 soap_ssl_init()
02765 {
02766 if (!ssl_init_done)
02767 { ssl_init_done = 1;
02768 SSL_library_init();
02769 #ifndef WITH_LEAN
02770 SSL_load_error_strings();
02771 #endif
02772 if (!RAND_load_file("/dev/urandom", 1024))
02773 { char buf[1024];
02774 RAND_seed(buf, sizeof(buf));
02775 while (!RAND_status())
02776 { int r = rand();
02777 RAND_seed(&r, sizeof(int));
02778 }
02779 }
02780 }
02781 }
02782 #endif
02783
02784
02785 #ifndef PALM_1
02786 SOAP_FMAC1
02787 const char *
02788 SOAP_FMAC2
02789 soap_ssl_error(struct soap *soap, int ret)
02790 { int err = SSL_get_error(soap->ssl, ret);
02791 const char *msg = soap_code_str(h_ssl_error_codes, err);
02792 if (msg)
02793 strcpy(soap->msgbuf, msg);
02794 else
02795 return ERR_error_string(err, soap->msgbuf);
02796 if (ERR_peek_error())
02797 { unsigned long r;
02798 strcat(soap->msgbuf, "\n");
02799 while ((r = ERR_get_error()))
02800 ERR_error_string_n(r, soap->msgbuf + strlen(soap->msgbuf), sizeof(soap->msgbuf) - strlen(soap->msgbuf));
02801 }
02802 else
02803 { switch (ret)
02804 { case 0:
02805 strcpy(soap->msgbuf, "EOF was observed that violates the protocol. The client probably provided invalid authentication information.");
02806 break;
02807 case -1:
02808 sprintf(soap->msgbuf, "Error observed by underlying BIO: %s", strerror(errno));
02809 break;
02810 }
02811 }
02812 return soap->msgbuf;
02813 }
02814 #endif
02815
02816
02817 #ifndef PALM_1
02818 static int
02819 ssl_password(char *buf, int num, int rwflag, void *userdata)
02820 { if (num < (int)strlen((char*)userdata) + 1)
02821 return 0;
02822 return strlen(strcpy(buf, (char*)userdata));
02823 }
02824 #endif
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837
02838
02839
02840
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
02856
02857
02858
02859
02860
02861
02862 #ifndef PALM_1
02863 static int
02864 ssl_auth_init(struct soap *soap)
02865 { if (!ssl_init_done)
02866 soap_ssl_init();
02867 if (!soap->ctx)
02868 { if (!(soap->ctx = SSL_CTX_new(SSLv23_method())))
02869 return soap_set_receiver_error(soap, "SSL error", "Can't setup context", SOAP_SSL_ERROR);
02870 }
02871 if (soap->randfile)
02872 { if (!RAND_load_file(soap->randfile, -1))
02873 return soap_set_receiver_error(soap, "SSL error", "Can't load randomness", SOAP_SSL_ERROR);
02874 }
02875 if (soap->cafile || soap->capath)
02876 { if (!SSL_CTX_load_verify_locations(soap->ctx, soap->cafile, soap->capath))
02877 return soap_set_receiver_error(soap, "SSL error", "Can't read CA file and directory", SOAP_SSL_ERROR);
02878 if (soap->cafile && soap->require_client_auth)
02879 SSL_CTX_set_client_CA_list(soap->ctx, SSL_load_client_CA_file(soap->cafile));
02880 }
02881 if (!SSL_CTX_set_default_verify_paths(soap->ctx))
02882 return soap_set_receiver_error(soap, "SSL error", "Can't read default CA file and/or directory", SOAP_SSL_ERROR);
02883
02884 if (soap->keyfile)
02885 { if (!SSL_CTX_use_certificate_chain_file(soap->ctx, soap->keyfile))
02886 return soap_set_receiver_error(soap, "SSL error", "Can't read certificate key file", SOAP_SSL_ERROR);
02887 if (soap->password)
02888 { SSL_CTX_set_default_passwd_cb_userdata(soap->ctx, (void*)soap->password);
02889 SSL_CTX_set_default_passwd_cb(soap->ctx, ssl_password);
02890 }
02891 if (!SSL_CTX_use_PrivateKey_file(soap->ctx, soap->keyfile, SSL_FILETYPE_PEM))
02892 return soap_set_receiver_error(soap, "SSL error", "Can't read key file", SOAP_SSL_ERROR);
02893 }
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906
02907
02908 if (soap->rsa)
02909 { RSA *rsa = RSA_generate_key(1024, RSA_F4, NULL, NULL);
02910 if (!SSL_CTX_set_tmp_rsa(soap->ctx, rsa))
02911 { if (rsa)
02912 RSA_free(rsa);
02913 return soap_set_receiver_error(soap, "SSL error", "Can't set RSA key", SOAP_SSL_ERROR);
02914 }
02915 RSA_free(rsa);
02916 }
02917 else if (soap->dhfile)
02918 { DH *dh = 0;
02919 BIO *bio;
02920 bio = BIO_new_file(soap->dhfile, "r");
02921 if (!bio)
02922 return soap_set_receiver_error(soap, "SSL error", "Can't read DH file", SOAP_SSL_ERROR);
02923 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
02924 BIO_free(bio);
02925 if (SSL_CTX_set_tmp_dh(soap->ctx, dh) < 0)
02926 { if (dh)
02927 DH_free(dh);
02928 return soap_set_receiver_error(soap, "SSL error", "Can't set DH parameters", SOAP_SSL_ERROR);
02929 }
02930 DH_free(dh);
02931 }
02932 SSL_CTX_set_options(soap->ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2);
02933 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);
02934 #if (OPENSSL_VERSION_NUMBER < 0x00905100L)
02935 SSL_CTX_set_verify_depth(soap->ctx, 1);
02936 #else
02937 SSL_CTX_set_verify_depth(soap->ctx, 9);
02938 #endif
02939 return SOAP_OK;
02940 }
02941 #endif
02942
02943
02944 #ifndef PALM_1
02945 static int
02946 ssl_verify_callback(int ok, X509_STORE_CTX *store)
02947 {
02948 #ifdef SOAP_DEBUG
02949 if (!ok)
02950 { char data[256];
02951 X509 *cert = X509_STORE_CTX_get_current_cert(store);
02952 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)));
02953 X509_NAME_oneline(X509_get_issuer_name(cert), data, sizeof(data));
02954 fprintf(stderr, "certificate issuer %s\n", data);
02955 X509_NAME_oneline(X509_get_subject_name(cert), data, sizeof(data));
02956 fprintf(stderr, "certificate subject %s\n", data);
02957 }
02958 #endif
02959
02960 return ok;
02961 }
02962 #endif
02963
02964
02965 #ifndef PALM_1
02966 SOAP_FMAC1
02967 int
02968 SOAP_FMAC2
02969 soap_ssl_accept(struct soap *soap)
02970 { BIO *bio;
02971 int i, r;
02972 if (!soap_valid_socket(soap->socket))
02973 return soap_set_receiver_error(soap, "SSL error", "No socket in soap_ssl_accept()", SOAP_SSL_ERROR);
02974 if (!soap->ctx && (soap->error = soap->fsslauth(soap)))
02975 return SOAP_INVALID_SOCKET;
02976 if (!soap->ssl)
02977 { soap->ssl = SSL_new(soap->ctx);
02978 if (!soap->ssl)
02979 return soap_set_receiver_error(soap, "SSL error", "SSL_new() failed in soap_ssl_accept()", SOAP_SSL_ERROR);
02980 }
02981 else
02982 SSL_clear(soap->ssl);
02983 soap->imode |= SOAP_ENC_SSL;
02984 soap->omode |= SOAP_ENC_SSL;
02985 #if defined(WIN32)
02986 { u_long nonblocking = 1;
02987 ioctlsocket((SOAP_SOCKET)soap->socket, FIONBIO, &nonblocking);
02988 }
02989 #elif defined(VXWORKS)
02990 { u_long nonblocking = 1;
02991 ioctl((SOAP_SOCKET)soap->socket, FIONBIO, (int)&nonblocking);
02992 }
02993 #else
02994 fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL)|O_NONBLOCK);
02995 #endif
02996 bio = BIO_new_socket((SOAP_SOCKET)soap->socket, BIO_NOCLOSE);
02997 SSL_set_bio(soap->ssl, bio, bio);
02998 i = 100;
02999 while ((r = SSL_accept(soap->ssl)) <= 0)
03000 { int err = SSL_get_error(soap->ssl, r);
03001 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
03002 { struct timeval timeout;
03003 fd_set fd;
03004 if (i-- <= 0)
03005 break;
03006 timeout.tv_sec = 0;
03007 timeout.tv_usec = 100000;
03008 #ifndef WIN32
03009 if ((int)soap->socket > FD_SETSIZE)
03010 return SOAP_FD_EXCEEDED;
03011 #endif
03012 FD_ZERO(&fd);
03013 FD_SET((SOAP_SOCKET)soap->socket, &fd);
03014 r = select((SOAP_SOCKET)(soap->socket + 1), &fd, NULL, &fd, &timeout);
03015 if (r < 0 && soap_socket_errno != SOAP_EINTR)
03016 { soap->errnum = soap_socket_errno;
03017 return SOAP_EOF;
03018 }
03019 }
03020 else
03021 { soap->errnum = err;
03022 break;
03023 }
03024 }
03025 #if defined(WIN32)
03026 { u_long blocking = 0;
03027 ioctlsocket((SOAP_SOCKET)soap->socket, FIONBIO, &blocking);
03028 }
03029 #elif defined(VXWORKS)
03030 { u_long blocking = 0;
03031 ioctl((SOAP_SOCKET)soap->socket, FIONBIO, (int)&blocking);
03032 }
03033 #else
03034 fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL)&~O_NONBLOCK);
03035 #endif
03036 if (r <= 0)
03037 { soap_set_receiver_error(soap, soap_ssl_error(soap, r), "SSL_accept() failed in soap_ssl_accept()", SOAP_SSL_ERROR);
03038 soap_closesock(soap);
03039 return SOAP_SSL_ERROR;
03040 }
03041 if (soap->require_client_auth)
03042 { X509 *peer;
03043 int err;
03044 if ((err = SSL_get_verify_result(soap->ssl)) != X509_V_OK)
03045 { soap_closesock(soap);
03046 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);
03047 }
03048 peer = SSL_get_peer_certificate(soap->ssl);
03049 if (!peer)
03050 { soap_closesock(soap);
03051 return soap_set_sender_error(soap, "SSL error", "No SSL certificate was presented by the peer in soap_ssl_accept()", SOAP_SSL_ERROR);
03052 }
03053 X509_free(peer);
03054 }
03055 return SOAP_OK;
03056 }
03057 #endif
03058
03059
03060 #endif
03061
03062
03063 #ifndef WITH_NOIO
03064 #ifndef PALM_1
03065 static int
03066 tcp_init(struct soap *soap)
03067 { soap->errmode = 1;
03068 #ifdef WIN32
03069 if (tcp_done)
03070 return 0;
03071 else
03072 { WSADATA w;
03073 if (WSAStartup(MAKEWORD(1, 1), &w))
03074 return -1;
03075 tcp_done = 1;
03076 }
03077 #endif
03078 return 0;
03079 }
03080 #endif
03081 #endif
03082
03083
03084 #ifndef PALM_1
03085 SOAP_FMAC1
03086 void
03087 SOAP_FMAC2
03088 soap_done(struct soap *soap)
03089 {
03090 #ifdef SOAP_DEBUG
03091 int i;
03092 #endif
03093 if (soap_check_state(soap))
03094 return;
03095 soap_free(soap);
03096 while (soap->clist)
03097 { struct soap_clist *p = soap->clist->next;
03098 SOAP_FREE(soap, soap->clist);
03099 soap->clist = p;
03100 }
03101 soap->keep_alive = 0;
03102 soap_closesock(soap);
03103 #ifdef WITH_COOKIES
03104 soap_free_cookies(soap);
03105 #endif
03106 while (soap->plugins)
03107 { register struct soap_plugin *p = soap->plugins->next;
03108 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Removing plugin '%s'\n", soap->plugins->id));
03109 if (soap->plugins->fcopy || soap->state == SOAP_INIT)
03110 soap->plugins->fdelete(soap, soap->plugins);
03111 SOAP_FREE(soap, soap->plugins);
03112 soap->plugins = p;
03113 }
03114 soap->fplugin = fplugin;
03115 #ifndef WITH_NOHTTP
03116 soap->fpost = http_post;
03117 soap->fget = http_get;
03118 soap->fform = NULL;
03119 soap->fposthdr = http_post_header;
03120 soap->fresponse = http_response;
03121 soap->fparse = http_parse;
03122 soap->fparsehdr = http_parse_header;
03123 #endif
03124 soap->fheader = NULL;
03125 #ifndef WITH_NOIO
03126 #ifndef WITH_IPV6
03127 soap->fresolve = tcp_gethost;
03128 #else
03129 soap->fresolve = NULL;
03130 #endif
03131 soap->faccept = tcp_accept;
03132 soap->fopen = tcp_connect;
03133 soap->fclose = tcp_disconnect;
03134 soap->fclosesocket = tcp_closesocket;
03135 soap->fshutdownsocket = tcp_shutdownsocket;
03136 soap->fsend = fsend;
03137 soap->frecv = frecv;
03138 soap->fpoll = soap_poll;
03139 #else
03140 soap->fopen = NULL;
03141 soap->fclose = NULL;
03142 soap->fpoll = NULL;
03143 #endif
03144 #ifndef WITH_LEANER
03145 soap->fprepareinit = NULL;
03146 soap->fpreparesend = NULL;
03147 soap->fpreparerecv = NULL;
03148 soap->fpreparefinal = NULL;
03149 #endif
03150 soap->fseterror = NULL;
03151 soap->fignore = NULL;
03152 soap->fserveloop = NULL;
03153 #ifdef WITH_OPENSSL
03154 if (soap->session)
03155 { SSL_SESSION_free(soap->session);
03156 soap->session = NULL;
03157 }
03158 #endif
03159 if (soap->state == SOAP_INIT)
03160 { if (soap_valid_socket(soap->master))
03161 { soap->fclosesocket(soap, (SOAP_SOCKET)soap->master);
03162 soap->master = SOAP_INVALID_SOCKET;
03163 }
03164 #ifdef WITH_OPENSSL
03165 if (soap->ctx)
03166 { SSL_CTX_free(soap->ctx);
03167 soap->ctx = NULL;
03168 }
03169 #endif
03170 }
03171 #ifdef SOAP_DEBUG
03172 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free logfiles\n"));
03173 for (i = 0; i < SOAP_MAXLOGS; i++)
03174 { if (soap->logfile[i])
03175 { SOAP_FREE(soap, (void*)soap->logfile[i]);
03176 soap->logfile[i] = NULL;
03177 }
03178 soap_close_logfile(soap, i);
03179 }
03180 soap_free_mht(soap);
03181 soap->state = 0;
03182 #endif
03183 }
03184 #endif
03185
03186
03187 #ifndef WITH_NOIO
03188 #ifndef PALM_2
03189 SOAP_FMAC1
03190 void
03191 SOAP_FMAC2
03192 soap_cleanup(struct soap *soap)
03193 { soap_done(soap);
03194 #ifdef WIN32
03195 if (!tcp_done)
03196 return;
03197 tcp_done = 0;
03198 WSACleanup();
03199 #endif
03200 }
03201 #endif
03202 #endif
03203
03204
03205 #ifndef WITH_NOIO
03206 #ifndef PALM_1
03207 static const char*
03208 tcp_error(struct soap *soap)
03209 { register const char *msg = NULL;
03210 switch (soap->errmode)
03211 { case 0:
03212 msg = soap_strerror(soap);
03213 break;
03214 case 1:
03215 msg = "WSAStartup failed";
03216 break;
03217 case 2:
03218 {
03219 #ifndef WITH_LEAN
03220 msg = soap_code_str(h_error_codes, soap->errnum);
03221 if (!msg)
03222 #endif
03223 { sprintf(soap->msgbuf, "TCP/UDP IP error %d", soap->errnum);
03224 msg = soap->msgbuf;
03225 }
03226 }
03227 }
03228 return msg;
03229 }
03230 #endif
03231 #endif
03232
03233
03234 #ifndef WITH_NOHTTP
03235 #ifndef PALM_1
03236 static const char*
03237 http_error(struct soap *soap, int status)
03238 { register const char *msg = SOAP_STR_EOS;
03239 #ifndef WITH_LEAN
03240 msg = soap_code_str(h_http_error_codes, status);
03241 if (!msg)
03242 msg = SOAP_STR_EOS;
03243 #endif
03244 return msg;
03245 }
03246 #endif
03247 #endif
03248
03249
03250 #ifndef WITH_IPV6
03251 #ifndef WITH_NOIO
03252 #ifndef PALM_1
03253 static int
03254 tcp_gethost(struct soap *soap, const char *addr, struct in_addr *inaddr)
03255 { soap_int32 iadd = -1;
03256 struct hostent hostent, *host = &hostent;
03257 #ifdef VXWORKS
03258 int hostint;
03259
03260 iadd = inet_addr((char*)addr);
03261 #else
03262 #if defined(_AIXVERSION_431) || defined(TRU64)
03263 struct hostent_data ht_data;
03264 #endif
03265 #ifdef AS400
03266 iadd = inet_addr((void*)addr);
03267 #else
03268 iadd = inet_addr(addr);
03269 #endif
03270 #endif
03271 if (iadd != -1)
03272 { memcpy(inaddr, &iadd, sizeof(iadd));
03273 return SOAP_OK;
03274 }
03275 #if defined(__GLIBC__)
03276 if (gethostbyname_r(addr, &hostent, soap->buf, SOAP_BUFLEN, &host, &soap->errnum) < 0)
03277 host = NULL;
03278 #elif defined(_AIXVERSION_431) || defined(TRU64)
03279 memset((void*)&ht_data, 0, sizeof(ht_data));
03280 if (gethostbyname_r(addr, &hostent, &ht_data) < 0)
03281 { host = NULL;
03282 soap->errnum = h_errno;
03283 }
03284 #elif defined(HAVE_GETHOSTBYNAME_R)
03285 host = gethostbyname_r(addr, &hostent, soap->buf, SOAP_BUFLEN, &soap->errnum);
03286 #elif defined(VXWORKS)
03287
03288
03289
03290 hostint = hostGetByName((char*)addr);
03291 if (hostint == ERROR)
03292 { host = NULL;
03293 soap->errnum = soap_errno;
03294 }
03295 #else
03296 #ifdef AS400
03297 if (!(host = gethostbyname((void*)addr)))
03298 soap->errnum = h_errno;
03299 #else
03300 if (!(host = gethostbyname(addr)))
03301 soap->errnum = h_errno;
03302 #endif
03303 #endif
03304 if (!host)
03305 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Host name not found\n"));
03306 return SOAP_ERR;
03307 }
03308 #ifdef VXWORKS
03309 inaddr->s_addr = hostint;
03310 #else
03311 memcpy(inaddr, host->h_addr, host->h_length);
03312 #endif
03313 return SOAP_OK;
03314 }
03315 #endif
03316 #endif
03317 #endif
03318
03319
03320 #ifndef WITH_NOIO
03321 #ifndef PALM_1
03322 static int
03323 tcp_connect(struct soap *soap, const char *endpoint, const char *host, int port)
03324 {
03325 #ifdef WITH_IPV6
03326 struct addrinfo hints, *res, *ressave;
03327 int err;
03328 #endif
03329 register int fd;
03330 #ifndef WITH_LEAN
03331 int len = SOAP_BUFLEN;
03332 int set = 1;
03333 #endif
03334 if (soap_valid_socket(soap->socket))
03335 soap->fclosesocket(soap, (SOAP_SOCKET)soap->socket);
03336 soap->socket = SOAP_INVALID_SOCKET;
03337 if (tcp_init(soap))
03338 { soap->errnum = 0;
03339 soap_set_sender_error(soap, tcp_error(soap), "TCP init failed in tcp_connect()", SOAP_TCP_ERROR);
03340 return SOAP_INVALID_SOCKET;
03341 }
03342 soap->errmode = 0;
03343 #ifdef WITH_IPV6
03344 memset((void*)&hints, 0, sizeof(hints));
03345 hints.ai_family = PF_UNSPEC;
03346 #ifdef WITH_UDP
03347 if ((soap->omode & SOAP_IO_UDP))
03348 hints.ai_socktype = SOCK_DGRAM;
03349 else
03350 #endif
03351 hints.ai_socktype = SOCK_STREAM;
03352 soap->errmode = 2;
03353 if (soap->proxy_host)
03354 err = getaddrinfo(soap->proxy_host, soap_int2s(soap, soap->proxy_port), &hints, &res);
03355 else
03356 err = getaddrinfo(host, soap_int2s(soap, port), &hints, &res);
03357 if (err)
03358 { soap_set_sender_error(soap, gai_strerror(err), "getaddrinfo failed in tcp_connect()", SOAP_TCP_ERROR);
03359 return SOAP_INVALID_SOCKET;
03360 }
03361 ressave = res;
03362 again:
03363 fd = (int)socket(res->ai_family, res->ai_socktype, res->ai_protocol);
03364 soap->errmode = 0;
03365 #else
03366 #ifdef WITH_UDP
03367 if ((soap->omode & SOAP_IO_UDP))
03368 fd = (int)socket(AF_INET, SOCK_DGRAM, 0);
03369 else
03370 #endif
03371 fd = (int)socket(AF_INET, SOCK_STREAM, 0);
03372 #endif
03373 if (fd < 0)
03374 { soap->errnum = soap_socket_errno;
03375 soap_set_sender_error(soap, tcp_error(soap), "socket failed in tcp_connect()", SOAP_TCP_ERROR);
03376 return SOAP_INVALID_SOCKET;
03377 }
03378 #ifdef SOCKET_CLOSE_ON_EXEC
03379 #ifdef WIN32
03380 #ifndef UNDER_CE
03381 SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0);
03382 #endif
03383 #else
03384 fcntl(fd, F_SETFD, 1);
03385 #endif
03386 #endif
03387 #ifndef WITH_LEAN
03388 if (soap->connect_flags == SO_LINGER)
03389 { struct linger linger;
03390 memset((void*)&linger, 0, sizeof(linger));
03391 linger.l_onoff = 1;
03392 linger.l_linger = 0;
03393 if (setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger)))
03394 { soap->errnum = soap_socket_errno;
03395 soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_LINGER failed in tcp_connect()", SOAP_TCP_ERROR);
03396 soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03397 return SOAP_INVALID_SOCKET;
03398 }
03399 }
03400 else if (soap->connect_flags && setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, soap->connect_flags, (char*)&set, sizeof(int)))
03401 { soap->errnum = soap_socket_errno;
03402 soap_set_sender_error(soap, tcp_error(soap), "setsockopt failed in tcp_connect()", SOAP_TCP_ERROR);
03403 soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03404 return SOAP_INVALID_SOCKET;
03405 }
03406 if (soap->keep_alive && setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int)))
03407 { soap->errnum = soap_socket_errno;
03408 soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in tcp_connect()", SOAP_TCP_ERROR);
03409 soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03410 return SOAP_INVALID_SOCKET;
03411 }
03412 if (setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int)))
03413 { soap->errnum = soap_socket_errno;
03414 soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in tcp_connect()", SOAP_TCP_ERROR);
03415 soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03416 return SOAP_INVALID_SOCKET;
03417 }
03418 if (setsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int)))
03419 { soap->errnum = soap_socket_errno;
03420 soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in tcp_connect()", SOAP_TCP_ERROR);
03421 soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03422 return SOAP_INVALID_SOCKET;
03423 }
03424 #ifdef TCP_NODELAY
03425 if (!(soap->omode & SOAP_IO_UDP) && setsockopt((SOAP_SOCKET)fd, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int)))
03426 { soap->errnum = soap_socket_errno;
03427 soap_set_sender_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in tcp_connect()", SOAP_TCP_ERROR);
03428 soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03429 return SOAP_INVALID_SOCKET;
03430 }
03431 #endif
03432 #endif
03433 DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Opening socket %d to host='%s' port=%d\n", fd, host, port));
03434 #ifndef WITH_IPV6
03435 soap->peerlen = sizeof(soap->peer);
03436 memset((void*)&soap->peer, 0, sizeof(soap->peer));
03437 soap->peer.sin_family = AF_INET;
03438 soap->errmode = 2;
03439 if (soap->proxy_host)
03440 { if (soap->fresolve(soap, soap->proxy_host, &soap->peer.sin_addr))
03441 { soap_set_sender_error(soap, tcp_error(soap), "get proxy host by name failed in tcp_connect()", SOAP_TCP_ERROR);
03442 soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03443 return SOAP_INVALID_SOCKET;
03444 }
03445 soap->peer.sin_port = htons((short)soap->proxy_port);
03446 }
03447 else
03448 { if (soap->fresolve(soap, host, &soap->peer.sin_addr))
03449 { soap_set_sender_error(soap, tcp_error(soap), "get host by name failed in tcp_connect()", SOAP_TCP_ERROR);
03450 soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03451 return SOAP_INVALID_SOCKET;
03452 }
03453 soap->peer.sin_port = htons((short)port);
03454 }
03455 soap->errmode = 0;
03456 if ((soap->omode & SOAP_IO_UDP))
03457 return fd;
03458 #endif
03459 #ifndef WITH_LEAN
03460 if (soap->connect_timeout)
03461 #if defined(WIN32)
03462 { u_long nonblocking = 1;
03463 ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &nonblocking);
03464 }
03465 #elif defined(VXWORKS)
03466 { u_long nonblocking = 1;
03467 ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&nonblocking));
03468 }
03469 #else
03470 fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)|O_NONBLOCK);
03471 #endif
03472 else
03473 #if defined(WIN32)
03474 { u_long blocking = 0;
03475 ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &blocking);
03476 }
03477 #elif defined(VXWORKS)
03478 { u_long blocking = 0;
03479 ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&blocking));
03480 }
03481 #else
03482 fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)&~O_NONBLOCK);
03483 #endif
03484 #endif
03485 for (;;)
03486 {
03487 #ifdef WITH_IPV6
03488 if (connect((SOAP_SOCKET)fd, res->ai_addr, res->ai_addrlen))
03489 #else
03490 if (connect((SOAP_SOCKET)fd, (struct sockaddr*)&soap->peer, sizeof(soap->peer)))
03491 #endif
03492 {
03493 #ifndef WITH_LEAN
03494 if (soap->connect_timeout && (soap_socket_errno == SOAP_EINPROGRESS || soap_socket_errno == SOAP_EWOULDBLOCK))
03495 { struct timeval timeout;
03496 SOAP_SOCKLEN_T k;
03497 fd_set fds;
03498 if (soap->connect_timeout > 0)
03499 { timeout.tv_sec = soap->connect_timeout;
03500 timeout.tv_usec = 0;
03501 }
03502 else
03503 { timeout.tv_sec = -soap->connect_timeout/1000000;
03504 timeout.tv_usec = -soap->connect_timeout%1000000;
03505 }
03506 #ifndef WIN32
03507 if ((int)soap->socket > FD_SETSIZE)
03508 { soap->error = SOAP_FD_EXCEEDED;
03509 return SOAP_INVALID_SOCKET;
03510 }
03511 #endif
03512 FD_ZERO(&fds);
03513 FD_SET((SOAP_SOCKET)fd, &fds);
03514 for (;;)
03515 { int r = select((SOAP_SOCKET)(fd + 1), NULL, &fds, NULL, &timeout);
03516 if (r > 0)
03517 break;
03518 if (!r)
03519 { soap->errnum = 0;
03520 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connect timeout\n"));
03521 soap_set_sender_error(soap, "Timeout", "connect failed in tcp_connect()", SOAP_TCP_ERROR);
03522 soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03523 return SOAP_INVALID_SOCKET;
03524 }
03525 if (soap_socket_errno != SOAP_EINTR)
03526 { soap->errnum = soap_socket_errno;
03527 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
03528 soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR);
03529 soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03530 return SOAP_INVALID_SOCKET;
03531 }
03532 }
03533 k = (SOAP_SOCKLEN_T)sizeof(soap->errnum);
03534 if (!getsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_ERROR, (char*)&soap->errnum, &k) && !soap->errnum)
03535 break;
03536 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
03537 soap->errnum = soap_socket_errno;
03538 soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR);
03539 soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03540 return SOAP_INVALID_SOCKET;
03541 }
03542 else
03543 #endif
03544 #ifdef WITH_IPV6
03545 if (res->ai_next)
03546 { res = res->ai_next;
03547 soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03548 goto again;
03549 }
03550 else
03551 #endif
03552 if (soap_socket_errno != SOAP_EINTR)
03553 { soap->errnum = soap_socket_errno;
03554 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
03555 soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR);
03556 soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03557 return SOAP_INVALID_SOCKET;
03558 }
03559 }
03560 else
03561 break;
03562 }
03563 #ifdef WITH_IPV6
03564 soap->peerlen = 0;
03565 freeaddrinfo(ressave);
03566 #endif
03567 #ifndef WITH_LEAN
03568 if (soap->connect_timeout)
03569 #if defined(WIN32)
03570 { u_long blocking = 0;
03571 ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &blocking);
03572 }
03573 #elif defined(VXWORKS)
03574 { u_long blocking = 0;
03575 ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&blocking));
03576 }
03577 #else
03578 fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)&~O_NONBLOCK);
03579 #endif
03580 #endif
03581 soap->socket = fd;
03582 soap->imode &= ~SOAP_ENC_SSL;
03583 soap->omode &= ~SOAP_ENC_SSL;
03584 if (!soap_tag_cmp(endpoint, "https:*"))
03585 {
03586 #ifdef WITH_OPENSSL
03587 BIO *bio;
03588 int r;
03589 if (soap->proxy_host)
03590 { unsigned int k = soap->omode;
03591 size_t n = soap->count;
03592 char *userid, *passwd;
03593 soap->omode &= ~SOAP_ENC;
03594 soap->omode |= SOAP_IO_BUFFER;
03595 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connecting to proxy server\n"));
03596 sprintf(soap->tmpbuf, "CONNECT %s:%d HTTP/%s", host, port, soap->http_version);
03597 if (soap_begin_send(soap)
03598 || (soap->error = soap->fposthdr(soap, soap->tmpbuf, NULL)))
03599 { soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03600 return SOAP_INVALID_SOCKET;
03601 }
03602 #ifndef WITH_LEAN
03603 if (soap->proxy_userid && soap->proxy_passwd && strlen(soap->proxy_userid) + strlen(soap->proxy_passwd) < 761)
03604 { sprintf(soap->tmpbuf + 262, "%s:%s", soap->proxy_userid, soap->proxy_passwd);
03605 strcpy(soap->tmpbuf, "Basic ");
03606 soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, strlen(soap->tmpbuf + 262));
03607 if ((soap->error = soap->fposthdr(soap, "Proxy-Authorization", soap->tmpbuf)))
03608 { soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03609 return soap->error;
03610 }
03611 }
03612 #endif
03613 if ((soap->error = soap->fposthdr(soap, NULL, NULL))
03614 || soap_flush(soap))
03615 { soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03616 return SOAP_INVALID_SOCKET;
03617 }
03618 soap->omode = k;
03619 k = soap->imode;
03620 soap->imode &= ~SOAP_ENC;
03621 userid = soap->userid;
03622 passwd = soap->passwd;
03623 if ((soap->error = soap->fparse(soap)))
03624 { soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03625 return SOAP_INVALID_SOCKET;
03626 }
03627 soap->userid = userid;
03628 soap->passwd = passwd;
03629 soap->imode = k;
03630 soap->count = n;
03631 if (soap_begin_send(soap))
03632 { soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03633 return SOAP_INVALID_SOCKET;
03634 }
03635 }
03636 if (!soap->ctx && (soap->error = soap->fsslauth(soap)))
03637 { soap_set_sender_error(soap, "SSL error", "SSL authentication failed in tcp_connect(): check password, key file, and ca file.", SOAP_SSL_ERROR);
03638 soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03639 return SOAP_INVALID_SOCKET;
03640 }
03641 soap->ssl = SSL_new(soap->ctx);
03642 if (!soap->ssl)
03643 { soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03644 soap->error = SOAP_SSL_ERROR;
03645 return SOAP_INVALID_SOCKET;
03646 }
03647 if (soap->session)
03648 { if (!strcmp(soap->session_host, host) && soap->session_port == port)
03649 SSL_set_session(soap->ssl, soap->session);
03650 SSL_SESSION_free(soap->session);
03651 soap->session = NULL;
03652 }
03653 soap->imode |= SOAP_ENC_SSL;
03654 soap->omode |= SOAP_ENC_SSL;
03655 bio = BIO_new_socket((SOAP_SOCKET)fd, BIO_NOCLOSE);
03656 SSL_set_bio(soap->ssl, bio, bio);
03657 #ifndef WITH_LEAN
03658 if (soap->connect_timeout)
03659 #if defined(WIN32)
03660 { u_long nonblocking = 1;
03661 ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &nonblocking);
03662 }
03663 #elif defined(VXWORKS)
03664 { u_long nonblocking = 1;
03665 ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&nonblocking));
03666 }
03667 #else
03668 fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)|O_NONBLOCK);
03669 #endif
03670 #endif
03671 for (;;)
03672 { if ((r = SSL_connect(soap->ssl)) <= 0)
03673 { int err = SSL_get_error(soap->ssl, r);
03674 if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
03675 { soap_set_sender_error(soap, soap_ssl_error(soap, r), "SSL connect failed in tcp_connect()", SOAP_SSL_ERROR);
03676 soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03677 return SOAP_INVALID_SOCKET;
03678 }
03679 if (soap->connect_timeout)
03680 { struct timeval timeout;
03681 fd_set fds;
03682 if (soap->connect_timeout > 0)
03683 { timeout.tv_sec = soap->connect_timeout;
03684 timeout.tv_usec = 0;
03685 }
03686 else
03687 { timeout.tv_sec = -soap->connect_timeout/1000000;
03688 timeout.tv_usec = -soap->connect_timeout%1000000;
03689 }
03690 #ifndef WIN32
03691 if ((int)soap->socket > FD_SETSIZE)
03692 { soap->error = SOAP_FD_EXCEEDED;
03693 return SOAP_INVALID_SOCKET;
03694 }
03695 #endif
03696 FD_ZERO(&fds);
03697 FD_SET((SOAP_SOCKET)fd, &fds);
03698 for (;;)
03699 { int r = select((SOAP_SOCKET)(fd + 1), &fds, NULL, &fds, &timeout);
03700 if (r > 0)
03701 break;
03702 if (!r)
03703 { soap->errnum = 0;
03704 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connect timeout\n"));
03705 soap_set_sender_error(soap, "Timeout", "connect failed in tcp_connect()", SOAP_TCP_ERROR);
03706 soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03707 return SOAP_INVALID_SOCKET;
03708 }
03709 }
03710 continue;
03711 }
03712 }
03713 break;
03714 }
03715 #ifndef WITH_LEAN
03716 if (soap->connect_timeout)
03717 #ifdef WIN32
03718 { u_long blocking = 0;
03719 ioctlsocket((SOAP_SOCKET)fd, FIONBIO, &blocking);
03720 }
03721 #elif defined(VXWORKS)
03722 { u_long blocking = 0;
03723 ioctl((SOAP_SOCKET)fd, FIONBIO, (int)(&blocking));
03724 }
03725 #else
03726 fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)&~O_NONBLOCK);
03727 #endif
03728 #endif
03729 if (soap->require_server_auth)
03730 { X509 *peer;
03731 X509_NAME *subj;
03732 int ext_count;
03733 int err;
03734 int ok = 0;
03735 if ((err = SSL_get_verify_result(soap->ssl)) != X509_V_OK)
03736 { 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);
03737 soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03738 return SOAP_INVALID_SOCKET;
03739 }
03740 peer = SSL_get_peer_certificate(soap->ssl);
03741 if (!peer)
03742 { soap_set_sender_error(soap, "SSL error", "No SSL certificate was presented by the peer in tcp_connect()", SOAP_SSL_ERROR);
03743 soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03744 return SOAP_INVALID_SOCKET;
03745 }
03746 ext_count = X509_get_ext_count(peer);
03747 if (ext_count > 0)
03748 { int i;
03749 for (i = 0; i < ext_count; i++)
03750 { X509_EXTENSION *ext = X509_get_ext(peer, i);
03751 const char *ext_str = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
03752 if (!strcmp(ext_str, "subjectAltName"))
03753 { int j;
03754 STACK_OF(CONF_VALUE) *val;
03755 X509V3_EXT_METHOD *meth = X509V3_EXT_get(ext);
03756 if (!meth)
03757 break;
03758 val = meth->i2v(meth, meth->d2i(NULL, (unsigned char**)&ext->value->data, ext->value->length), NULL);
03759 for (j = 0; j < sk_CONF_VALUE_num(val); j++)
03760 { CONF_VALUE *nval = sk_CONF_VALUE_value(val, j);
03761 if (nval && !strcmp(nval->name, "DNS") && !strcmp(nval->value, host))
03762 { ok = 1;
03763 break;
03764 }
03765 }
03766 }
03767 if (ok)
03768 break;
03769 }
03770 }
03771 if (!ok && (subj = X509_get_subject_name(peer)))
03772 { X509_NAME_get_text_by_NID(subj, NID_commonName, soap->msgbuf, sizeof(soap->msgbuf));
03773 if (soap_tag_cmp(soap->msgbuf, host))
03774 { soap_set_sender_error(soap, "SSL error", "SSL certificate host name mismatch in tcp_connect()", SOAP_SSL_ERROR);
03775 soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03776 X509_free(peer);
03777 return SOAP_INVALID_SOCKET;
03778 }
03779 }
03780 X509_free(peer);
03781 }
03782 #else
03783 soap->fclosesocket(soap, (SOAP_SOCKET)fd);
03784 soap->error = SOAP_SSL_ERROR;
03785 return SOAP_INVALID_SOCKET;
03786 #endif
03787 }
03788 return fd;
03789 }
03790 #endif
03791 #endif
03792
03793
03794 #ifndef WITH_NOIO
03795 #ifndef PALM_1
03796 SOAP_FMAC1
03797 int
03798 SOAP_FMAC2
03799 soap_bind(struct soap *soap, const char *host, int port, int backlog)
03800 {
03801 #ifdef WITH_IPV6
03802 struct addrinfo *addrinfo = NULL;
03803 struct addrinfo hints;
03804 struct addrinfo res;
03805 int err;
03806 #endif
03807 #ifndef WITH_LEAN
03808 int len = SOAP_BUFLEN;
03809 int set = 1;
03810 #endif
03811 if (soap_valid_socket(soap->master))
03812 { soap->fclosesocket(soap, (SOAP_SOCKET)soap->master);
03813 soap->master = SOAP_INVALID_SOCKET;
03814 }
03815 soap->socket = SOAP_INVALID_SOCKET;
03816 soap->errmode = 1;
03817 if (tcp_init(soap))
03818 { soap_set_receiver_error(soap, tcp_error(soap), "TCP init failed in soap_bind()", SOAP_TCP_ERROR);
03819 return SOAP_INVALID_SOCKET;
03820 }
03821 #ifdef WITH_IPV6
03822 memset((void*)&hints, 0, sizeof(hints));
03823 hints.ai_family = PF_UNSPEC;
03824 #ifdef WITH_UDP
03825 if ((soap->omode & SOAP_IO_UDP))
03826 hints.ai_socktype = SOCK_DGRAM;
03827 else
03828 #endif
03829 hints.ai_socktype = SOCK_STREAM;
03830 hints.ai_flags = AI_PASSIVE;
03831 soap->errmode = 2;
03832 err = getaddrinfo(host, soap_int2s(soap, port), &hints, &addrinfo);
03833 if (addrinfo)
03834 { res = *addrinfo;
03835 soap->peer = *((struct sockaddr_storage*)addrinfo->ai_addr);
03836 soap->peerlen = addrinfo->ai_addrlen;
03837 res.ai_addr = (struct sockaddr*)&soap->peer;
03838 res.ai_addrlen = soap->peerlen;
03839 freeaddrinfo(addrinfo);
03840 }
03841 if (err)
03842 { soap_set_receiver_error(soap, gai_strerror(err), "getaddrinfo failed in soap_bind()", SOAP_TCP_ERROR);
03843 return SOAP_INVALID_SOCKET;
03844 }
03845 soap->master = socket(res.ai_family, res.ai_socktype, res.ai_protocol);
03846 #else
03847 #ifdef WITH_UDP
03848 if ((soap->omode & SOAP_IO_UDP))
03849 soap->master = (int)socket(AF_INET, SOCK_DGRAM, 0);
03850 else
03851 #endif
03852 soap->master = (int)socket(AF_INET, SOCK_STREAM, 0);
03853 #endif
03854 soap->errmode = 0;
03855 if (!soap_valid_socket(soap->master))
03856 { soap->errnum = soap_socket_errno;
03857 soap_set_receiver_error(soap, tcp_error(soap), "socket failed in soap_bind()", SOAP_TCP_ERROR);
03858 return SOAP_INVALID_SOCKET;
03859 }
03860 #ifdef WITH_UDP
03861 if ((soap->omode & SOAP_IO_UDP))
03862 soap->socket = soap->master;
03863 #endif
03864 #ifdef SOCKET_CLOSE_ON_EXEC
03865 #ifdef WIN32
03866 #ifndef UNDER_CE
03867 SetHandleInformation((HANDLE)soap->master, HANDLE_FLAG_INHERIT, 0);
03868 #endif
03869 #else
03870 fcntl(soap->master, F_SETFD, 1);
03871 #endif
03872 #endif
03873 #ifndef WITH_LEAN
03874 if (soap->bind_flags && setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, soap->bind_flags, (char*)&set, sizeof(int)))
03875 { soap->errnum = soap_socket_errno;
03876 soap_set_receiver_error(soap, tcp_error(soap), "setsockopt failed in soap_bind()", SOAP_TCP_ERROR);
03877 return SOAP_INVALID_SOCKET;
03878 }
03879 if (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) && setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int)))
03880 { soap->errnum = soap_socket_errno;
03881 soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in soap_bind()", SOAP_TCP_ERROR);
03882 return SOAP_INVALID_SOCKET;
03883 }
03884 if (setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int)))
03885 { soap->errnum = soap_socket_errno;
03886 soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in soap_bind()", SOAP_TCP_ERROR);
03887 return SOAP_INVALID_SOCKET;
03888 }
03889 if (setsockopt((SOAP_SOCKET)soap->master, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int)))
03890 { soap->errnum = soap_socket_errno;
03891 soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in soap_bind()", SOAP_TCP_ERROR);
03892 return SOAP_INVALID_SOCKET;
03893 }
03894 #ifdef TCP_NODELAY
03895 if (!(soap->omode & SOAP_IO_UDP) && setsockopt((SOAP_SOCKET)soap->master, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int)))
03896 { soap->errnum = soap_socket_errno;
03897 soap_set_receiver_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in soap_bind()", SOAP_TCP_ERROR);
03898 return SOAP_INVALID_SOCKET;
03899 }
03900 #endif
03901 #endif
03902 #ifdef WITH_IPV6
03903 soap->errmode = 0;
03904 if (bind((SOAP_SOCKET)soap->master, res.ai_addr, res.ai_addrlen))
03905 { soap->errnum = soap_socket_errno;
03906 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n"));
03907 soap_closesock(soap);
03908 soap_set_receiver_error(soap, tcp_error(soap), "bind failed in soap_bind()", SOAP_TCP_ERROR);
03909 return SOAP_INVALID_SOCKET;
03910 }
03911 #else
03912 soap->peerlen = sizeof(soap->peer);
03913 memset((void*)&soap->peer, 0, sizeof(soap->peer));
03914 soap->peer.sin_family = AF_INET;
03915 soap->errmode = 2;
03916 if (host)
03917 { if (soap->fresolve(soap, host, &soap->peer.sin_addr))
03918 { soap_set_receiver_error(soap, tcp_error(soap), "get host by name failed in soap_bind()", SOAP_TCP_ERROR);
03919 return SOAP_INVALID_SOCKET;
03920 }
03921 }
03922 else
03923 soap->peer.sin_addr.s_addr = htonl(INADDR_ANY);
03924 soap->peer.sin_port = htons((short)port);
03925 soap->errmode = 0;
03926 if (bind((SOAP_SOCKET)soap->master, (struct sockaddr*)&soap->peer, soap->peerlen))
03927 { soap->errnum = soap_socket_errno;
03928 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n"));
03929 soap_closesock(soap);
03930 soap_set_receiver_error(soap, tcp_error(soap), "bind failed in soap_bind()", SOAP_TCP_ERROR);
03931 return SOAP_INVALID_SOCKET;
03932 }
03933 #endif
03934 if (!(soap->omode & SOAP_IO_UDP) && listen((SOAP_SOCKET)soap->master, backlog))
03935 { soap->errnum = soap_socket_errno;
03936 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n"));
03937 soap_closesock(soap);
03938 soap_set_receiver_error(soap, tcp_error(soap), "listen failed in soap_bind()", SOAP_TCP_ERROR);
03939 return SOAP_INVALID_SOCKET;
03940 }
03941 return soap->master;
03942 }
03943 #endif
03944 #endif
03945
03946
03947 #ifndef WITH_NOIO
03948 #ifndef PALM_1
03949 SOAP_FMAC1
03950 int
03951 SOAP_FMAC2
03952 soap_poll(struct soap *soap)
03953 {
03954 #ifndef WITH_LEAN
03955 struct timeval timeout;
03956 fd_set rfd, sfd, xfd;
03957 int r;
03958 timeout.tv_sec = 0;
03959 timeout.tv_usec = 0;
03960 #ifndef WIN32
03961 if ((int)soap->socket > FD_SETSIZE)
03962 return SOAP_FD_EXCEEDED;
03963 #endif
03964 FD_ZERO(&rfd);
03965 FD_ZERO(&sfd);
03966 FD_ZERO(&xfd);
03967 if (soap_valid_socket(soap->socket))
03968 { FD_SET((SOAP_SOCKET)soap->socket, &rfd);
03969 FD_SET((SOAP_SOCKET)soap->socket, &sfd);
03970 FD_SET((SOAP_SOCKET)soap->socket, &xfd);
03971 r = select((SOAP_SOCKET)(soap->socket + 1), &rfd, &sfd, &xfd, &timeout);
03972 if (r > 0 && FD_ISSET((SOAP_SOCKET)soap->socket, &xfd))
03973 r = -1;
03974 }
03975 else if (soap_valid_socket(soap->master))
03976 { FD_SET((SOAP_SOCKET)soap->master, &sfd);
03977 r = select((SOAP_SOCKET)(soap->master + 1), NULL, &sfd, NULL, &timeout);
03978 }
03979 else
03980 return SOAP_OK;
03981 if (r > 0)
03982 {
03983 #ifdef WITH_OPENSSL
03984 if (soap->imode & SOAP_ENC_SSL)
03985 {
03986 if (soap_valid_socket(soap->socket)
03987 && FD_ISSET((SOAP_SOCKET)soap->socket, &sfd)
03988 && (!FD_ISSET((SOAP_SOCKET)soap->socket, &rfd)
03989 || SSL_peek(soap->ssl, soap->tmpbuf, 1) > 0))
03990 return SOAP_OK;
03991 }
03992 else
03993 #endif
03994 if (soap_valid_socket(soap->socket)
03995 && FD_ISSET((SOAP_SOCKET)soap->socket, &sfd)
03996 && (!FD_ISSET((SOAP_SOCKET)soap->socket, &rfd)
03997 || recv((SOAP_SOCKET)soap->socket, soap->tmpbuf, 1, MSG_PEEK) > 0))
03998 return SOAP_OK;
03999 }
04000 else if (r < 0)
04001 { soap->errnum = soap_socket_errno;
04002 if ((soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) && soap_socket_errno != SOAP_EINTR)
04003 { soap_set_receiver_error(soap, tcp_error(soap), "select failed in soap_poll()", SOAP_TCP_ERROR);
04004 return soap->error = SOAP_TCP_ERROR;
04005 }
04006 }
04007 else
04008 soap->errnum = 0;
04009 DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Polling: other end down on socket=%d select=%d\n", soap->socket, r));
04010 return SOAP_EOF;
04011 #else
04012 return SOAP_OK;
04013 #endif
04014 }
04015 #endif
04016 #endif
04017
04018
04019 #ifndef WITH_NOIO
04020 #ifndef PALM_1
04021 static int
04022 tcp_accept(struct soap *soap, int s, struct sockaddr *a, int *n)
04023 { int fd;
04024 fd = (int)accept((SOAP_SOCKET)s, a, (SOAP_SOCKLEN_T*)n);
04025 #ifdef SOCKET_CLOSE_ON_EXEC
04026 #ifdef WIN32
04027 #ifndef UNDER_CE
04028 SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0);
04029 #endif
04030 #else
04031 fcntl(fd, F_SETFD, FD_CLOEXEC);
04032 #endif
04033 #endif
04034 return fd;
04035 }
04036 #endif
04037 #endif
04038
04039
04040 #ifndef WITH_NOIO
04041 #ifndef PALM_1
04042 SOAP_FMAC1
04043 int
04044 SOAP_FMAC2
04045 soap_accept(struct soap *soap)
04046 { int n = (int)sizeof(soap->peer);
04047 #ifndef WITH_LEAN
04048 int len = SOAP_BUFLEN;
04049 int set = 1;
04050 #endif
04051 soap->error = SOAP_OK;
04052 #ifdef WITH_UDP
04053 if ((soap->omode & SOAP_IO_UDP))
04054 return soap->socket = soap->master;
04055 #endif
04056 memset((void*)&soap->peer, 0, sizeof(soap->peer));
04057 soap->socket = SOAP_INVALID_SOCKET;
04058 soap->errmode = 0;
04059 soap->keep_alive = 0;
04060 if (soap_valid_socket(soap->master))
04061 { for (;;)
04062 {
04063 #ifndef WITH_LEAN
04064 if (soap->accept_timeout)
04065 { struct timeval timeout;
04066 fd_set fd;
04067 if (soap->accept_timeout > 0)
04068 { timeout.tv_sec = soap->accept_timeout;
04069 timeout.tv_usec = 0;
04070 }
04071 else
04072 { timeout.tv_sec = -soap->accept_timeout/1000000;
04073 timeout.tv_usec = -soap->accept_timeout%1000000;
04074 }
04075 #ifndef WIN32
04076 if ((int)soap->socket > FD_SETSIZE)
04077 { soap->error = SOAP_FD_EXCEEDED;
04078 return SOAP_INVALID_SOCKET;
04079 }
04080 #endif
04081 FD_ZERO(&fd);
04082 FD_SET((SOAP_SOCKET)soap->master, &fd);
04083 for (;;)
04084 { int r = select((SOAP_SOCKET)(soap->master + 1), &fd, &fd, NULL, &timeout);
04085 if (r > 0)
04086 break;
04087 if (!r)
04088 { soap->errnum = 0;
04089 soap_set_receiver_error(soap, "Timeout", "accept failed in soap_accept()", SOAP_TCP_ERROR);
04090 return SOAP_INVALID_SOCKET;
04091 }
04092 if (soap_socket_errno != SOAP_EINTR)
04093 { soap->errnum = soap_socket_errno;
04094 soap_closesock(soap);
04095 soap_set_sender_error(soap, tcp_error(soap), "accept failed in soap_accept()", SOAP_TCP_ERROR);
04096 return SOAP_INVALID_SOCKET;
04097 }
04098 }
04099 #if defined(WIN32)
04100 { u_long nonblocking = 1;
04101 ioctlsocket((SOAP_SOCKET)soap->master, FIONBIO, &nonblocking);
04102 }
04103 #elif defined(VXWORKS)
04104 { u_long nonblocking = 1;
04105 ioctl((SOAP_SOCKET)soap->master, FIONBIO, (int)(&nonblocking));
04106 }
04107 #else
04108 fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL)|O_NONBLOCK);
04109 #endif
04110 }
04111 else
04112 #if defined(WIN32)
04113 { u_long blocking = 0;
04114 ioctlsocket((SOAP_SOCKET)soap->master, FIONBIO, &blocking);
04115 }
04116 #elif defined(VXWORKS)
04117 { u_long blocking = 0;
04118 ioctl((SOAP_SOCKET)soap->master, FIONBIO, (int)(&blocking));
04119 }
04120 #else
04121 fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL)&~O_NONBLOCK);
04122 #endif
04123 #endif
04124 soap->socket = soap->faccept(soap, soap->master, (struct sockaddr*)&soap->peer, &n);
04125 soap->peerlen = (size_t)n;
04126 if (soap_valid_socket(soap->socket))
04127 {
04128 #ifdef WITH_IPV6
04129
04130 getnameinfo((struct sockaddr*)&soap->peer, n, soap->host, sizeof(soap->host), NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV);
04131 DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept socket %d from %s\n", soap->socket, soap->host));
04132 soap->ip = 0;
04133 soap->port = 0;
04134 #else
04135 soap->ip = ntohl(soap->peer.sin_addr.s_addr);
04136 soap->port = (int)ntohs(soap->peer.sin_port);
04137 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));
04138 #endif
04139 #ifndef WITH_LEAN
04140 if (soap->accept_flags == SO_LINGER)
04141 { struct linger linger;
04142 memset((void*)&linger, 0, sizeof(linger));
04143 linger.l_onoff = 1;
04144 linger.l_linger = 0;
04145 if (setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger)))
04146 { soap->errnum = soap_socket_errno;
04147 soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_LINGER failed in soap_accept()", SOAP_TCP_ERROR);
04148 soap_closesock(soap);
04149 return SOAP_INVALID_SOCKET;
04150 }
04151 }
04152 else if (soap->accept_flags && setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, soap->accept_flags, (char*)&set, sizeof(int)))
04153 { soap->errnum = soap_socket_errno;
04154 soap_set_receiver_error(soap, tcp_error(soap), "setsockopt failed in soap_accept()", SOAP_TCP_ERROR);
04155 soap_closesock(soap);
04156 return SOAP_INVALID_SOCKET;
04157 }
04158 if (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) && setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int)))
04159 { soap->errnum = soap_socket_errno;
04160 soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in soap_accept()", SOAP_TCP_ERROR);
04161 soap_closesock(soap);
04162 return SOAP_INVALID_SOCKET;
04163 }
04164 if (setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int)))
04165 { soap->errnum = soap_socket_errno;
04166 soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in soap_accept()", SOAP_TCP_ERROR);
04167 soap_closesock(soap);
04168 return SOAP_INVALID_SOCKET;
04169 }
04170 if (setsockopt((SOAP_SOCKET)soap->socket, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int)))
04171 { soap->errnum = soap_socket_errno;
04172 soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in soap_accept()", SOAP_TCP_ERROR);
04173 soap_closesock(soap);
04174 return SOAP_INVALID_SOCKET;
04175 }
04176 #ifdef TCP_NODELAY
04177 if (!(soap->omode & SOAP_IO_UDP) && setsockopt((SOAP_SOCKET)soap->socket, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int)))
04178 { soap->errnum = soap_socket_errno;
04179 soap_set_receiver_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in soap_accept()", SOAP_TCP_ERROR);
04180 soap_closesock(soap);
04181 return SOAP_INVALID_SOCKET;
04182 }
04183 #endif
04184 #endif
04185 if (soap->accept_timeout)
04186 {
04187 #if defined(WIN32)
04188 u_long blocking = 0;
04189 ioctlsocket((SOAP_SOCKET)soap->master, FIONBIO, &blocking);
04190 ioctlsocket((SOAP_SOCKET)soap->socket, FIONBIO, &blocking);
04191 #elif defined(VXWORKS)
04192 u_long blocking = 0;
04193 ioctl((SOAP_SOCKET)soap->master, FIONBIO, (int)(&blocking));
04194 ioctl((SOAP_SOCKET)soap->socket, FIONBIO, (int)(&blocking));
04195 #elif defined(PALM)
04196 fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL,0)&~O_NONBLOCK);
04197 fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL,0)&~O_NONBLOCK);
04198 #elif defined(SYMBIAN)
04199 long blocking = 0;
04200 ioctl((SOAP_SOCKET)soap->master, 0, &blocking);
04201 #else
04202 fcntl((SOAP_SOCKET)soap->master, F_SETFL, fcntl((SOAP_SOCKET)soap->master, F_GETFL)&~O_NONBLOCK);
04203 fcntl((SOAP_SOCKET)soap->socket, F_SETFL, fcntl((SOAP_SOCKET)soap->socket, F_GETFL)&~O_NONBLOCK);
04204 #endif
04205 }
04206 soap->keep_alive = (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) != 0);
04207 return soap->socket;
04208 }
04209 if (soap_socket_errno != SOAP_EINTR && soap_socket_errno != SOAP_EAGAIN)
04210 { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept failed from %s\n", soap->host));
04211 soap->errnum = soap_socket_errno;
04212 soap_set_receiver_error(soap, tcp_error(soap), "accept failed in soap_accept()", SOAP_TCP_ERROR);
04213 soap_closesock(soap);
04214 return SOAP_INVALID_SOCKET;
04215 }
04216 }
04217 }
04218 else
04219 { soap->errnum = 0;
04220 soap_set_receiver_error(soap, tcp_error(soap), "no master socket in soap_accept()", SOAP_TCP_ERROR);
04221 return SOAP_INVALID_SOCKET;
04222 }
04223 }
04224 #endif
04225 #endif
04226
04227
04228 #ifndef WITH_NOIO
04229 #ifndef PALM_1
04230 static int
04231 tcp_disconnect(struct soap *soap)
04232 {
04233 #ifdef WITH_OPENSSL
04234 if (soap->ssl)
04235 { int r, s = 0;
04236 if (soap->session)
04237 SSL_SESSION_free(soap->session);
04238 if (*soap->host)
04239 { soap->session = SSL_get1_session(soap->ssl);
04240 if (soap->session)
04241 { strcpy(soap->session_host, soap->host);
04242 soap->session_port = soap->port;
04243 }
04244 }
04245 r = SSL_shutdown(soap->ssl);
04246 if (r != 1)
04247 { s = ERR_get_error();
04248 if (s)
04249 { if (soap_valid_socket(soap->socket))
04250 { soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 1);
04251 soap->socket = SOAP_INVALID_SOCKET;
04252 }
04253 r = SSL_shutdown(soap->ssl);
04254 }
04255 }
04256 DBGLOG(TEST, if (s) SOAP_MESSAGE(fdebug, "Shutdown failed: %d\n", SSL_get_error(soap->ssl, r)));
04257 SSL_free(soap->ssl);
04258 soap->ssl = NULL;
04259 if (s)
04260 return SOAP_SSL_ERROR;
04261 ERR_remove_state(0);
04262 }
04263 #endif
04264 if (soap_valid_socket(soap->socket) && !(soap->omode & SOAP_IO_UDP))
04265 { soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 2);
04266 soap->fclosesocket(soap, (SOAP_SOCKET)soap->socket);
04267 soap->socket = SOAP_INVALID_SOCKET;
04268 }
04269 return SOAP_OK;
04270 }
04271 #endif
04272 #endif
04273
04274
04275 #ifndef WITH_NOIO
04276 #ifndef PALM_1
04277 static int
04278 tcp_closesocket(struct soap *soap, SOAP_SOCKET fd)
04279 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Close socket %d\n", (int)fd));
04280 return soap_closesocket(fd);
04281 }
04282 #endif
04283 #endif
04284
04285
04286 #ifndef WITH_NOIO
04287 #ifndef PALM_1
04288 static int
04289 tcp_shutdownsocket(struct soap *soap, SOAP_SOCKET fd, int how)
04290 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Shutdown socket %d how=%d\n", (int)fd, how));
04291 return shutdown(fd, how);
04292 }
04293 #endif
04294 #endif
04295
04296
04297 #ifndef PALM_1
04298 SOAP_FMAC1
04299 int
04300 SOAP_FMAC2
04301 soap_closesock(struct soap *soap)
04302 { register int status = soap->error;
04303 if (status == SOAP_EOF || status == SOAP_TCP_ERROR || status == SOAP_SSL_ERROR || !soap->keep_alive)
04304 { if (soap->fclose && (soap->error = soap->fclose(soap)))
04305 return soap->error;
04306 soap->keep_alive = 0;
04307 }
04308 #ifdef WITH_ZLIB
04309 if (soap->zlib_state == SOAP_ZLIB_DEFLATE)
04310 deflateEnd(&soap->d_stream);
04311 else if (soap->zlib_state == SOAP_ZLIB_INFLATE)
04312 inflateEnd(&soap->d_stream);
04313 soap->zlib_state = SOAP_ZLIB_NONE;
04314 #endif
04315 return soap->error = status;
04316 }
04317 #endif
04318
04319
04320 #ifndef WITH_NOIDREF
04321 #ifndef PALM_2
04322 SOAP_FMAC1
04323 size_t
04324 SOAP_FMAC2
04325 soap_hash(register const char *s)
04326 { register size_t h = 0;
04327 while (*s)
04328 h = 65599*h + *s++;
04329 return h % SOAP_IDHASH;
04330 }
04331 #endif
04332 #endif
04333
04334
04335 #ifndef WITH_NOIDREF
04336 #ifndef PALM_1
04337 static void
04338 soap_init_pht(struct soap *soap)
04339 { register int i;
04340 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing pointer hashtable\n"));
04341 soap->pblk = NULL;
04342 soap->pidx = 0;
04343 for (i = 0; i < (int)SOAP_PTRHASH; i++)
04344 soap->pht[i] = NULL;
04345 }
04346 #endif
04347 #endif
04348
04349
04350 #ifndef PALM_1
04351 SOAP_FMAC1
04352 struct soap*
04353 SOAP_FMAC2
04354 soap_new1(soap_mode mode)
04355 { return soap_new2(mode, mode);
04356 }
04357 #endif
04358
04359
04360 #ifndef PALM_1
04361 SOAP_FMAC1
04362 struct soap*
04363 SOAP_FMAC2
04364 soap_new()
04365 { return soap_new2(SOAP_IO_DEFAULT, SOAP_IO_DEFAULT);
04366 }
04367 #endif
04368
04369
04370 #ifndef PALM_1
04371 SOAP_FMAC1
04372 struct soap*
04373 SOAP_FMAC2
04374 soap_new2(soap_mode imode, soap_mode omode)
04375 { struct soap *soap = (struct soap*)malloc(sizeof(struct soap));
04376 if (soap)
04377 soap_init2(soap, imode, omode);
04378 return soap;
04379 }
04380 #endif
04381
04382
04383 #ifndef PALM_1
04384 SOAP_FMAC1
04385 void
04386 SOAP_FMAC2
04387 soap_del(struct soap *soap)
04388 { free(soap);
04389 }
04390 #endif
04391
04392
04393 #ifndef WITH_NOIDREF
04394 #ifndef PALM_1
04395 static void
04396 soap_free_pht(struct soap *soap)
04397 { register struct soap_pblk *pb, *next;
04398 register int i;
04399 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free pointer hashtable\n"));
04400 for (pb = soap->pblk; pb; pb = next)
04401 { next = pb->next;
04402 SOAP_FREE(soap, pb);
04403 }
04404 soap->pblk = NULL;
04405 soap->pidx = 0;
04406 for (i = 0; i < (int)SOAP_PTRHASH; i++)
04407 soap->pht[i] = NULL;
04408 }
04409 #endif
04410 #endif
04411
04412
04413 #ifndef WITH_NOIDREF
04414 #ifndef PALM_2
04415 SOAP_FMAC1
04416 int
04417 SOAP_FMAC2
04418 soap_embed(struct soap *soap, const void *p, const struct soap_array *a, int n, const char *tag, int type)
04419 { register int i;
04420 struct soap_plist *pp;
04421 if (soap->version != 1)
04422 soap->encoding = 1;
04423 if (a)
04424 i = soap_array_pointer_lookup(soap, p, a, n, type, &pp);
04425 else
04426 i = soap_pointer_lookup(soap, p, type, &pp);
04427 if (i)
04428 { if (soap_is_embedded(soap, pp)
04429 || soap_is_single(soap, pp))
04430 return 0;
04431 soap_set_embedded(soap, pp);
04432 }
04433 return i;
04434 }
04435 #endif
04436 #endif
04437
04438
04439 #ifndef WITH_NOIDREF
04440 #ifndef PALM_2
04441 SOAP_FMAC1
04442 int
04443 SOAP_FMAC2
04444 soap_pointer_lookup(struct soap *soap, const void *p, int type, struct soap_plist **ppp)
04445 { register struct soap_plist *pp;
04446 *ppp = NULL;
04447 if (p)
04448 { for (pp = soap->pht[soap_hash_ptr(p)]; pp; pp = pp->next)
04449 { if (pp->ptr == p && pp->type == type)
04450 { *ppp = pp;
04451 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup location=%p type=%d id=%d\n", p, type, pp->id));
04452 return pp->id;
04453 }
04454 }
04455 }
04456 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup location=%p type=%d: not found\n", p, type));
04457 return 0;
04458 }
04459 #endif
04460 #endif
04461
04462
04463 #ifndef WITH_NOIDREF
04464 #ifndef PALM_2
04465 SOAP_FMAC1
04466 int
04467 SOAP_FMAC2
04468 soap_pointer_enter(struct soap *soap, const void *p, const struct soap_array *a, int n, int type, struct soap_plist **ppp)
04469 { register int h;
04470 register struct soap_plist *pp;
04471 if (!soap->pblk || soap->pidx >= SOAP_PTRBLK)
04472 { register struct soap_pblk *pb = (struct soap_pblk*)SOAP_MALLOC(soap, sizeof(struct soap_pblk));
04473 if (!pb)
04474 { soap->error = SOAP_EOM;
04475 return 0;
04476 }
04477 pb->next = soap->pblk;
04478 soap->pblk = pb;
04479 soap->pidx = 0;
04480 }
04481 *ppp = pp = &soap->pblk->plist[soap->pidx++];
04482 if (a)
04483 h = soap_hash_ptr(a->__ptr);
04484 else
04485 h = soap_hash_ptr(p);
04486 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));
04487 pp->next = soap->pht[h];
04488 pp->type = type;
04489 pp->mark1 = 0;
04490 pp->mark2 = 0;
04491 pp->ptr = p;
04492 pp->array = a;
04493 soap->pht[h] = pp;
04494 pp->id = ++soap->idnum;
04495 return pp->id;
04496 }
04497 #endif
04498 #endif
04499
04500
04501 #ifndef WITH_NOIDREF
04502 #ifndef PALM_2
04503 SOAP_FMAC1
04504 int
04505 SOAP_FMAC2
04506 soap_array_pointer_lookup(struct soap *soap, const void *p, const struct soap_array *a, int n, int type, struct soap_plist **ppp)
04507 { register struct soap_plist *pp;
04508 *ppp = NULL;
04509 if (!p || !a->__ptr)
04510 return 0;
04511 for (pp = soap->pht[soap_hash_ptr(a->__ptr)]; pp; pp = pp->next)
04512 { if (pp->type == type && pp->array && pp->array->__ptr == a->__ptr)
04513 { register int i;
04514 for (i = 0; i < n; i++)
04515 if (((const int*)&pp->array->__size)[i] != ((const int*)&a->__size)[i])
04516 break;
04517 if (i == n)
04518 { *ppp = pp;
04519 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array lookup location=%p type=%d id=%d\n", a->__ptr, type, pp->id));
04520 return pp->id;
04521 }
04522 }
04523 }
04524 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array lookup location=%p type=%d: not found\n", a->__ptr, type));
04525 return 0;
04526 }
04527 #endif
04528 #endif
04529
04530
04531 #ifndef PALM_1
04532 SOAP_FMAC1
04533 int
04534 SOAP_FMAC2
04535 soap_begin_count(struct soap *soap)
04536 {
04537 #ifndef WITH_LEANER
04538 if ((soap->mode & SOAP_ENC_DIME) || (soap->omode & SOAP_ENC_DIME))
04539 soap->mode = soap->omode | SOAP_IO_LENGTH | SOAP_ENC_DIME;
04540 else
04541 #endif
04542 { soap->mode = soap->omode;
04543 if ((soap->mode & SOAP_IO) == SOAP_IO_STORE
04544 || (((soap->mode & SOAP_IO) == SOAP_IO_CHUNK || (soap->mode & SOAP_ENC_XML))
04545 #ifndef WITH_LEANER
04546 && !soap->fpreparesend
04547 #endif
04548 ))
04549 soap->mode &= ~SOAP_IO_LENGTH;
04550 else
04551 soap->mode |= SOAP_IO_LENGTH;
04552 }
04553 #ifdef WITH_ZLIB
04554 if ((soap->mode & SOAP_ENC_ZLIB) && (soap->mode & SOAP_IO) == SOAP_IO_FLUSH)
04555 { if (!(soap->mode & SOAP_ENC_DIME))
04556 soap->mode &= ~SOAP_IO_LENGTH;
04557 if (soap->mode & SOAP_ENC_XML)
04558 soap->mode |= SOAP_IO_BUFFER;
04559 else
04560 soap->mode |= SOAP_IO_STORE;
04561 }
04562 #endif
04563 if (!soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH))
04564 soap->mode |= SOAP_XML_TREE;
04565 #ifndef WITH_LEANER
04566 if ((soap->mode & SOAP_ENC_MTOM) && (soap->mode & SOAP_ENC_DIME))
04567 soap->mode |= SOAP_ENC_MIME;
04568 else
04569 soap->mode &= ~SOAP_ENC_MTOM;
04570 if (soap->mode & SOAP_ENC_MIME)
04571 soap_select_mime_boundary(soap);
04572 soap->dime.list = soap->dime.last;
04573 #endif
04574 soap->count = 0;
04575 soap->ns = 0;
04576 soap->null = 0;
04577 soap->position = 0;
04578 soap->mustUnderstand = 0;
04579 soap->encoding = 0;
04580 soap->part = SOAP_BEGIN;
04581 soap->idnum = 0;
04582 soap_clr_attr(soap);
04583 soap_set_local_namespaces(soap);
04584 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin count phase (socket=%d mode=0x%x count=%lu)\n", soap->socket, soap->mode, (unsigned long)soap->count));
04585 #ifndef WITH_LEANER
04586 soap->dime.count = 0;
04587 soap->dime.size = 0;
04588 if (soap->fprepareinit && (soap->mode & SOAP_IO) != SOAP_IO_STORE)
04589 return soap->error = soap->fprepareinit(soap);
04590 #endif
04591 return SOAP_OK;
04592 }
04593 #endif
04594
04595
04596 #ifndef PALM_1
04597 SOAP_FMAC1
04598 int
04599 SOAP_FMAC2
04600 soap_end_count(struct soap *soap)
04601 {
04602 #ifndef WITH_LEANER
04603 if (soap->fpreparefinal)
04604 return soap->error = soap->fpreparefinal(soap);
04605 #endif
04606 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of count phase\n"));
04607 return SOAP_OK;
04608 }
04609 #endif
04610
04611
04612 #ifndef PALM_1
04613 SOAP_FMAC1
04614 int
04615 SOAP_FMAC2
04616 soap_begin_send(struct soap *soap)
04617 { soap->error = SOAP_OK;
04618 soap->mode = soap->omode | (soap->mode & (SOAP_IO_LENGTH | SOAP_ENC_DIME));
04619 #ifdef WITH_ZLIB
04620 if ((soap->mode & SOAP_ENC_ZLIB) && (soap->mode & SOAP_IO) == SOAP_IO_FLUSH)
04621 { if (soap->mode & SOAP_ENC_XML)
04622 soap->mode |= SOAP_IO_BUFFER;
04623 else
04624 soap->mode |= SOAP_IO_STORE;
04625 }
04626 #endif
04627 #ifdef WITH_UDP
04628 if ((soap->mode & SOAP_IO_UDP))
04629 { soap->mode |= SOAP_ENC_XML;
04630 if (soap->count > SOAP_BUFLEN)
04631 return soap->error = SOAP_UDP_ERROR;
04632 }
04633 #endif
04634 if ((soap->mode & SOAP_IO) == SOAP_IO_FLUSH && soap_valid_socket(soap->socket))
04635 { if (soap->count || (soap->mode & SOAP_IO_LENGTH) || (soap->mode & SOAP_ENC_XML))
04636 soap->mode |= SOAP_IO_BUFFER;
04637 else
04638 soap->mode |= SOAP_IO_STORE;
04639 }
04640 soap->mode &= ~SOAP_IO_LENGTH;
04641 if ((soap->mode & SOAP_IO) == SOAP_IO_STORE)
04642 soap_new_block(soap);
04643 if (!(soap->mode & SOAP_IO_KEEPALIVE))
04644 soap->keep_alive = 0;
04645 if (!soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH))
04646 soap->mode |= SOAP_XML_TREE;
04647 #ifndef WITH_LEANER
04648 if ((soap->mode & SOAP_ENC_MTOM) && (soap->mode & SOAP_ENC_DIME))
04649 { soap->mode |= SOAP_ENC_MIME;
04650 soap->mode &= ~SOAP_ENC_DIME;
04651 }
04652 else
04653 soap->mode &= ~SOAP_ENC_MTOM;
04654 if (soap->mode & SOAP_ENC_MIME)
04655 soap_select_mime_boundary(soap);
04656 #ifdef WIN32
04657 #ifndef UNDER_CE
04658 #ifndef WITH_FASTCGI
04659 if (!soap_valid_socket(soap->socket))
04660 #ifdef __BORLANDC__
04661 setmode((SOAP_SOCKET)soap->sendfd, O_BINARY);
04662 #else
04663 _setmode((SOAP_SOCKET)soap->sendfd, _O_BINARY);
04664 #endif
04665 #endif
04666 #endif
04667 #endif
04668 #endif
04669 if (soap->mode & SOAP_IO)
04670 { soap->bufidx = 0;
04671 soap->buflen = 0;
04672 }
04673 soap->chunksize = 0;
04674 soap->ns = 0;
04675 soap->null = 0;
04676 soap->position = 0;
04677 soap->mustUnderstand = 0;
04678 soap->encoding = 0;
04679 soap->idnum = 0;
04680 soap->level = 0;
04681 soap_clr_attr(soap);
04682 soap_set_local_namespaces(soap);
04683 #ifdef WITH_ZLIB
04684 soap->z_ratio_out = 1.0;
04685 if ((soap->mode & SOAP_ENC_ZLIB) && soap->zlib_state != SOAP_ZLIB_DEFLATE)
04686 {
04687 #ifdef WITH_GZIP
04688 memcpy(soap->z_buf, "\37\213\10\0\0\0\0\0\0\377", 10);
04689 soap->d_stream.next_out = (Byte*)soap->z_buf + 10;
04690 soap->d_stream.avail_out = SOAP_BUFLEN - 10;
04691 soap->z_crc = crc32(0L, NULL, 0);
04692 if (deflateInit2(&soap->d_stream, soap->z_level, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY) != Z_OK)
04693 #else
04694 soap->d_stream.next_out = (Byte*)soap->z_buf;
04695 soap->d_stream.avail_out = SOAP_BUFLEN;
04696 if (deflateInit(&soap->d_stream, soap->z_level) != Z_OK)
04697 #endif
04698 return soap->error = SOAP_ZLIB_ERROR;
04699 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflate initialized\n"));
04700 soap->zlib_state = SOAP_ZLIB_DEFLATE;
04701 }
04702 #endif
04703 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin send phase (socket=%d mode=0x%x count=%lu)\n", soap->socket, soap->mode, (unsigned long)soap->count));
04704 soap->part = SOAP_BEGIN;
04705 #ifndef WITH_LEANER
04706 if (soap->fprepareinit && (soap->mode & SOAP_IO) == SOAP_IO_STORE)
04707 soap->fprepareinit(soap);
04708 #endif
04709 return SOAP_OK;
04710 }
04711 #endif
04712
04713
04714 #ifndef WITH_NOIDREF
04715 #ifndef PALM_2
04716 SOAP_FMAC1
04717 void
04718 SOAP_FMAC2
04719 soap_embedded(struct soap *soap, const void *p, int t)
04720 { struct soap_plist *pp;
04721 if (soap_pointer_lookup(soap, p, t, &pp))
04722 { pp->mark1 = 1;
04723 pp->mark2 = 1;
04724 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded %p type=%d mark set to 1\n", p, t));
04725 }
04726 }
04727 #endif
04728 #endif
04729
04730
04731 #ifndef WITH_NOIDREF
04732 #ifndef PALM_2
04733 SOAP_FMAC1
04734 int
04735 SOAP_FMAC2
04736 soap_reference(struct soap *soap, const void *p, int t)
04737 { struct soap_plist *pp;
04738 if (!p || (soap->mode & SOAP_XML_TREE))
04739 return 1;
04740 if (soap_pointer_lookup(soap, p, t, &pp))
04741 { if (pp->mark1 == 0)
04742 { pp->mark1 = 2;
04743 pp->mark2 = 2;
04744 }
04745 }
04746 else if (soap_pointer_enter(soap, p, NULL, 0, t, &pp))
04747 { pp->mark1 = 0;
04748 pp->mark2 = 0;
04749 }
04750 else
04751 return 1;
04752 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Reference %p type=%d (%d %d)\n", p, t, (int)pp->mark1, (int)pp->mark2));
04753 return pp->mark1;
04754 }
04755 #endif
04756 #endif
04757
04758
04759 #ifndef WITH_NOIDREF
04760 #ifndef PALM_2
04761 SOAP_FMAC1
04762 int
04763 SOAP_FMAC2
04764 soap_array_reference(struct soap *soap, const void *p, const struct soap_array *a, int n, int t)
04765 { register int i;
04766 struct soap_plist *pp;
04767 if (!p || !a->__ptr)
04768 return 1;
04769 i = soap_array_pointer_lookup(soap, p, a, n, t, &pp);
04770 if (i)
04771 { if (pp->mark1 == 0)
04772 { pp->mark1 = 2;
04773 pp->mark2 = 2;
04774 }
04775 }
04776 else if (!soap_pointer_enter(soap, p, a, n, t, &pp))
04777 return 1;
04778 else
04779 { pp->mark1 = 0;
04780 pp->mark2 = 0;
04781 }
04782 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));
04783 return pp->mark1;
04784 }
04785 #endif
04786 #endif
04787
04788
04789 #ifndef WITH_NOIDREF
04790 #ifndef PALM_2
04791 SOAP_FMAC1
04792 int
04793 SOAP_FMAC2
04794 soap_embedded_id(struct soap *soap, int id, const void *p, int t)
04795 { struct soap_plist *pp;
04796 if (soap->mode & SOAP_XML_TREE)
04797 return id;
04798 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded_id %p type=%d id=%d\n", p, t, id));
04799 if (soap->version == 1 && soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH) && soap->part != SOAP_IN_HEADER)
04800 { if (id < 0)
04801 { id = soap_pointer_lookup(soap, p, t, &pp);
04802 if (id)
04803 { if (soap->mode & SOAP_IO_LENGTH)
04804 pp->mark1 = 2;
04805 else
04806 pp->mark2 = 2;
04807 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));
04808 }
04809 return -1;
04810 }
04811 return id;
04812 }
04813 if (id < 0)
04814 id = soap_pointer_lookup(soap, p, t, &pp);
04815 else if (id && !soap_pointer_lookup(soap, p, t, &pp))
04816 return 0;
04817 if (id && pp)
04818 { if (soap->mode & SOAP_IO_LENGTH)
04819 pp->mark1 = 1;
04820 else
04821 pp->mark2 = 1;
04822 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));
04823 }
04824 return id;
04825 }
04826 #endif
04827 #endif
04828
04829
04830 #ifndef WITH_NOIDREF
04831 #ifndef PALM_2
04832 SOAP_FMAC1
04833 int
04834 SOAP_FMAC2
04835 soap_is_embedded(struct soap *soap, struct soap_plist *pp)
04836 { if (!pp)
04837 return 0;
04838 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Is embedded? %d %d\n", (int)pp->mark1, (int)pp->mark2));
04839 if (soap->version == 1 && soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH) && soap->part != SOAP_IN_HEADER)
04840 { if (soap->mode & SOAP_IO_LENGTH)
04841 return pp->mark1 != 0;
04842 return pp->mark2 != 0;
04843 }
04844 if (soap->mode & SOAP_IO_LENGTH)
04845 return pp->mark1 == 1;
04846 return pp->mark2 == 1;
04847 }
04848 #endif
04849 #endif
04850
04851
04852 #ifndef WITH_NOIDREF
04853 #ifndef PALM_2
04854 SOAP_FMAC1
04855 int
04856 SOAP_FMAC2
04857 soap_is_single(struct soap *soap, struct soap_plist *pp)
04858 { if (soap->part == SOAP_IN_HEADER)
04859 return 1;
04860 if (!pp)
04861 return 0;
04862 if (soap->mode & SOAP_IO_LENGTH)
04863 return pp->mark1 == 0;
04864 return pp->mark2 == 0;
04865 }
04866 #endif
04867 #endif
04868
04869
04870 #ifndef WITH_NOIDREF
04871 #ifndef PALM_2
04872 SOAP_FMAC1
04873 void
04874 SOAP_FMAC2
04875 soap_set_embedded(struct soap *soap, struct soap_plist *pp)
04876 { if (!pp)
04877 return;
04878 if (soap->mode & SOAP_IO_LENGTH)
04879 pp->mark1 = 1;
04880 else
04881 pp->mark2 = 1;
04882 }
04883 #endif
04884 #endif
04885
04886
04887 #ifndef WITH_NOIDREF
04888 #ifndef WITH_LEANER
04889 #ifndef PALM_1
04890 SOAP_FMAC1
04891 int
04892 SOAP_FMAC2
04893 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)
04894 { struct soap_plist *pp;
04895 int i;
04896 if (!p || !a->__ptr || (!aid && !atype))
04897 return soap_element_id(soap, tag, id, p, a, n, type, t);
04898 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Attachment tag='%s' id='%s' (%d) type='%s'\n", tag, aid?aid:"", id, atype?atype:""));
04899 i = soap_array_pointer_lookup(soap, p, a, n, t, &pp);
04900 if (!i)
04901 { i = soap_pointer_enter(soap, p, a, n, t, &pp);
04902 if (!i)
04903 { soap->error = SOAP_EOM;
04904 return -1;
04905 }
04906 }
04907 if (id <= 0)
04908 id = i;
04909 if (!aid)
04910 { sprintf(soap->tmpbuf, soap->dime_id_format, id);
04911 aid = soap_strdup(soap, soap->tmpbuf);
04912 }
04913
04914
04915 if ((soap->mode & SOAP_ENC_MTOM) && strcmp(tag, "xop:Include"))
04916 { if (soap_element_begin_out(soap, tag, 0, type)
04917 || soap_element_href(soap, "xop:Include", 0, "href", aid)
04918 || soap_element_end_out(soap, tag))
04919 return soap->error;
04920 }
04921 else if (soap_element_href(soap, tag, 0, "href", aid))
04922 return soap->error;
04923 if (soap->mode & SOAP_IO_LENGTH)
04924 { if (pp->mark1 != 3)
04925 { struct soap_multipart *content;
04926 if (soap->mode & SOAP_ENC_MTOM)
04927 content = soap_new_multipart(soap, &soap->mime.first, &soap->mime.last, (char*)a->__ptr, a->__size);
04928 else
04929 content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, (char*)a->__ptr, a->__size);
04930 if (!content)
04931 { soap->error = SOAP_EOM;
04932 return -1;
04933 }
04934 if (!strncmp(aid, "cid:", 4))
04935 { if (soap->mode & SOAP_ENC_MTOM)
04936 { char *s = (char*)soap_malloc(soap, strlen(aid) - 1);
04937 if (s)
04938 { *s = '<';
04939 strcpy(s + 1, aid + 4);
04940 strcat(s, ">");
04941 content->id = s;
04942 }
04943 }
04944 else
04945 content->id = aid + 4;
04946 }
04947 else
04948 content->id = aid;
04949 content->type = atype;
04950 content->options = aoptions;
04951 content->encoding = SOAP_MIME_BINARY;
04952 pp->mark1 = 3;
04953 }
04954 }
04955 else
04956 pp->mark2 = 3;
04957 return -1;
04958 }
04959 #endif
04960 #endif
04961 #endif
04962
04963
04964 #ifndef WITH_NOIDREF
04965 #ifndef PALM_1
04966 static void
04967 soap_init_iht(struct soap *soap)
04968 { register int i;
04969 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing ID hashtable\n"));
04970 for (i = 0; i < SOAP_IDHASH; i++)
04971 soap->iht[i] = NULL;
04972 }
04973 #endif
04974 #endif
04975
04976
04977 #ifndef WITH_NOIDREF
04978 #ifndef PALM_1
04979 static void
04980 soap_free_iht(struct soap *soap)
04981 { register int i;
04982 register struct soap_ilist *ip, *p;
04983 register struct soap_flist *fp, *fq;
04984 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free ID hashtable\n"));
04985 for (i = 0; i < SOAP_IDHASH; i++)
04986 { for (ip = soap->iht[i]; ip; ip = p)
04987 { for (fp = ip->flist; fp; fp = fq)
04988 { fq = fp->next;
04989 SOAP_FREE(soap, fp);
04990 }
04991 p = ip->next;
04992 SOAP_FREE(soap, ip);
04993 }
04994 soap->iht[i] = NULL;
04995 }
04996 }
04997 #endif
04998 #endif
04999
05000
05001 #ifndef WITH_NOIDREF
05002 #ifndef PALM_2
05003 SOAP_FMAC1
05004 struct soap_ilist *
05005 SOAP_FMAC2
05006 soap_lookup(struct soap *soap, const char *id)
05007 { register struct soap_ilist *ip;
05008 for (ip = soap->iht[soap_hash(id)]; ip; ip = ip->next)
05009 if (!strcmp(ip->id, id))
05010 return ip;
05011 return NULL;
05012 }
05013 #endif
05014 #endif
05015
05016
05017 #ifndef WITH_NOIDREF
05018 #ifndef PALM_2
05019 SOAP_FMAC1
05020 struct soap_ilist *
05021 SOAP_FMAC2
05022 soap_enter(struct soap *soap, const char *id)
05023 { register size_t h;
05024 register struct soap_ilist *ip;
05025 ip = (struct soap_ilist*)SOAP_MALLOC(soap, sizeof(struct soap_ilist) + strlen(id));
05026 if (ip)
05027 { h = soap_hash(id);
05028 strcpy(ip->id, id);
05029 ip->next = soap->iht[h];
05030 soap->iht[h] = ip;
05031 return ip;
05032 }
05033 return NULL;
05034 }
05035 #endif
05036 #endif
05037
05038
05039 #ifndef PALM_2
05040 SOAP_FMAC1
05041 void*
05042 SOAP_FMAC2
05043 soap_malloc(struct soap *soap, size_t n)
05044 { register char *p;
05045 if (!n)
05046 return (void*)SOAP_NON_NULL;
05047 if (!soap)
05048 return SOAP_MALLOC(soap, n);
05049 #ifdef SOAP_DEBUG
05050 n += sizeof(short);
05051 #endif
05052 n += (-(long)n) & (sizeof(void*)-1);
05053 if (!(p = (char*)SOAP_MALLOC(soap, n + sizeof(void*) + sizeof(size_t))))
05054 { soap->error = SOAP_EOM;
05055 return NULL;
05056 }
05057
05058 soap->alloced = 1;
05059 #ifdef SOAP_DEBUG
05060
05061 *(short*)(p + n - sizeof(short)) = (short)SOAP_CANARY;
05062 #endif
05063 *(void**)(p + n) = soap->alist;
05064 *(size_t*)(p + n + sizeof(void*)) = n;
05065 soap->alist = p + n;
05066 return p;
05067 }
05068 #endif
05069
05070
05071 #ifdef SOAP_DEBUG
05072 static void
05073 soap_init_mht(struct soap *soap)
05074 { register int i;
05075 for (i = 0; i < (int)SOAP_PTRHASH; i++)
05076 soap->mht[i] = NULL;
05077 }
05078 #endif
05079
05080
05081 #ifdef SOAP_DEBUG
05082 static void
05083 soap_free_mht(struct soap *soap)
05084 { register int i;
05085 register struct soap_mlist *mp, *mq;
05086 for (i = 0; i < (int)SOAP_PTRHASH; i++)
05087 { for (mp = soap->mht[i]; mp; mp = mq)
05088 { mq = mp->next;
05089 if (mp->live)
05090 fprintf(stderr, "%s(%d): malloc() = %p not freed (memory leak or forgot to call soap_end()?)\n", mp->file, mp->line, mp->ptr);
05091 free(mp);
05092 }
05093 soap->mht[i] = NULL;
05094 }
05095 }
05096 #endif
05097
05098
05099 #ifdef SOAP_DEBUG
05100 SOAP_FMAC1
05101 void*
05102 SOAP_FMAC2
05103 soap_track_malloc(struct soap *soap, const char *file, int line, size_t size)
05104 { register void *p = malloc(size);
05105 if (soap)
05106 { register int h = soap_hash_ptr(p);
05107 register struct soap_mlist *mp = (struct soap_mlist*)malloc(sizeof(struct soap_mlist));
05108 if (soap->fdebug[SOAP_INDEX_TEST])
05109 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): malloc(%lu) = %p\n", file, line, (unsigned long)size, p));
05110 mp->next = soap->mht[h];
05111 mp->ptr = p;
05112 mp->file = file;
05113 mp->line = line;
05114 mp->live = 1;
05115 soap->mht[h] = mp;
05116 }
05117 return p;
05118 }
05119 #endif
05120
05121
05122 #ifdef SOAP_DEBUG
05123 SOAP_FMAC1
05124 void
05125 SOAP_FMAC2
05126 soap_track_free(struct soap *soap, const char *file, int line, void *p)
05127 { register int h = soap_hash_ptr(p);
05128 register struct soap_mlist *mp;
05129 for (mp = soap->mht[h]; mp; mp = mp->next)
05130 if (mp->ptr == p)
05131 break;
05132 if (mp)
05133 { if (mp->live)
05134 { free(p);
05135 if (soap->fdebug[SOAP_INDEX_TEST])
05136 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): free(%p)\n", file, line, p));
05137 mp->live = 0;
05138 }
05139 else
05140 fprintf(stderr, "%s(%d): free(%p) double free of pointer malloced at %s(%d)\n", file, line, p, mp->file, mp->line);
05141 }
05142 else
05143 fprintf(stderr, "%s(%d): free(%p) pointer not malloced\n", file, line, p);
05144 }
05145 #endif
05146
05147
05148 #ifdef SOAP_DEBUG
05149 static void
05150 soap_track_unlink(struct soap *soap, const void *p)
05151 { register int h = soap_hash_ptr(p);
05152 register struct soap_mlist *mp;
05153 for (mp = soap->mht[h]; mp; mp = mp->next)
05154 if (mp->ptr == p)
05155 break;
05156 if (mp)
05157 mp->live = 0;
05158 }
05159 #endif
05160
05161
05162 #ifndef PALM_2
05163 SOAP_FMAC1
05164 void
05165 SOAP_FMAC2
05166 soap_dealloc(struct soap *soap, void *p)
05167 { if (!soap)
05168 return;
05169 if (p)
05170 { register char **q;
05171 for (q = (char**)&soap->alist; *q; q = *(char***)q)
05172 {
05173 #ifdef SOAP_DEBUG
05174 if (*(short*)(char*)(*q - sizeof(short)) != (short)SOAP_CANARY)
05175 { fprintf(stderr, "Data corruption in dynamic allocation (see logs)\n");
05176 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Data corruption:\n"));
05177 DBGHEX(TEST, *q - 200, 200);
05178 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n"));
05179 return;
05180 }
05181 #endif
05182 if (p == (void*)(*q - *(size_t*)(*q + sizeof(void*))))
05183 { *q = **(char***)q;
05184 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Freed data at %p\n", p));
05185 SOAP_FREE(soap, p);
05186 return;
05187 }
05188 }
05189 soap_delete(soap, p);
05190 }
05191 else
05192 { register char *q;
05193 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free all soap_malloc() data\n"));
05194 while (soap->alist)
05195 { q = (char*)soap->alist;
05196 #ifdef SOAP_DEBUG
05197 if (*(short*)(char*)(q - sizeof(short)) != (short)SOAP_CANARY)
05198 { fprintf(stderr, "Data corruption in dynamic allocation (see logs)\n");
05199 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Data corruption:\n"));
05200 DBGHEX(TEST, q - 200, 200);
05201 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n"));
05202 return;
05203 }
05204 #endif
05205 soap->alist = *(void**)q;
05206 q -= *(size_t*)(q + sizeof(void*));
05207 SOAP_FREE(soap, q);
05208 }
05209 }
05210
05211 soap->action = NULL;
05212 soap->fault = NULL;
05213 soap->header = NULL;
05214 soap->userid = NULL;
05215 soap->passwd = NULL;
05216 soap->authrealm = NULL;
05217 #ifndef WITH_LEANER
05218 soap_clr_mime(soap);
05219 #endif
05220 }
05221 #endif
05222
05223
05224 #ifndef PALM_2
05225 SOAP_FMAC1
05226 void
05227 SOAP_FMAC2
05228 soap_delete(struct soap *soap, void *p)
05229 { register struct soap_clist **cp;
05230 if (soap_check_state(soap))
05231 return;
05232 cp = &soap->clist;
05233 if (p)
05234 { while (*cp)
05235 { if (p == (*cp)->ptr)
05236 { register struct soap_clist *q = *cp;
05237 *cp = q->next;
05238 q->fdelete(q);
05239 SOAP_FREE(soap, q);
05240 return;
05241 }
05242 cp = &(*cp)->next;
05243 }
05244 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not dealloc data %p: address not in list\n", p));
05245 }
05246 else
05247 { while (*cp)
05248 { register struct soap_clist *q = *cp;
05249 *cp = q->next;
05250 q->fdelete(q);
05251 SOAP_FREE(soap, q);
05252 }
05253 }
05254 }
05255 #endif
05256
05257
05258 #ifndef PALM_2
05259 SOAP_FMAC1
05260 struct soap_clist *
05261 SOAP_FMAC2
05262 soap_link(struct soap *soap, void *p, int t, int n, void (*fdelete)(struct soap_clist*))
05263 { register struct soap_clist *cp;
05264 if ((cp = (struct soap_clist*)SOAP_MALLOC(soap, sizeof(struct soap_clist))))
05265 { cp->next = soap->clist;
05266 cp->type = t;
05267 cp->size = n;
05268 cp->ptr = p;
05269 cp->fdelete = fdelete;
05270 soap->clist = cp;
05271 }
05272 return cp;
05273 }
05274 #endif
05275
05276
05277 #ifndef PALM_2
05278 SOAP_FMAC1
05279 void
05280 SOAP_FMAC2
05281 soap_unlink(struct soap *soap, const void *p)
05282 { register char **q;
05283 register struct soap_clist **cp;
05284 if (!soap || !p)
05285 return;
05286 for (q = (char**)&soap->alist; *q; q = *(char***)q)
05287 { if (p == (void*)(*q - *(size_t*)(*q + sizeof(void*))))
05288 { *q = **(char***)q;
05289 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unlinked data %p\n", p));
05290 #ifdef SOAP_DEBUG
05291 soap_track_unlink(soap, p);
05292 #endif
05293 return;
05294 }
05295 }
05296 for (cp = &soap->clist; *cp; cp = &(*cp)->next)
05297 { if (p == (*cp)->ptr)
05298 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unlinked class instance %p\n", p));
05299 q = (char**)*cp;
05300 *cp = (*cp)->next;
05301 SOAP_FREE(soap, q);
05302 return;
05303 }
05304 }
05305 }
05306 #endif
05307
05308
05309 #ifndef WITH_NOIDREF
05310 #ifndef PALM_2
05311 SOAP_FMAC1
05312 int
05313 SOAP_FMAC2
05314 soap_lookup_type(struct soap *soap, const char *id)
05315 { register struct soap_ilist *ip;
05316 if (id && *id)
05317 { ip = soap_lookup(soap, id);
05318 if (ip)
05319 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup id='%s' type=%d\n", id, ip->type));
05320 return ip->type;
05321 }
05322 }
05323 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "lookup type id='%s' NOT FOUND! Need to get it from xsi:type\n", id));
05324 return 0;
05325 }
05326 #endif
05327 #endif
05328
05329
05330 #ifndef WITH_NOIDREF
05331 #ifndef PALM_2
05332 SOAP_FMAC1
05333 void*
05334 SOAP_FMAC2
05335 soap_id_lookup(struct soap *soap, const char *id, void **p, int t, size_t n, unsigned int k)
05336 { struct soap_ilist *ip;
05337 void **q;
05338 if (!p || !id || !*id)
05339 return p;
05340 ip = soap_lookup(soap, id);
05341 if (!ip)
05342 { ip = soap_enter(soap, id);
05343 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding first href='%s' type=%d %p (%u bytes)\n", id, t, p, (unsigned int)n));
05344 ip->type = t;
05345 ip->size = n;
05346 ip->link = p;
05347 ip->copy = NULL;
05348 ip->flist = NULL;
05349 ip->ptr = NULL;
05350 ip->level = k;
05351 *p = NULL;
05352 }
05353 else if (ip->ptr)
05354 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolved href='%s' type=%d location=%p (%u bytes)\n", id, t, ip->ptr, (unsigned int)n));
05355 if (ip->type != t)
05356 { strcpy(soap->id, id);
05357 soap->error = SOAP_HREF;
05358 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Type incompatibility: id type=%d href type=%d\n", ip->type, t));
05359 return NULL;
05360 }
05361 while (ip->level < k)
05362 { q = (void**)soap_malloc(soap, sizeof(void*));
05363 if (!q)
05364 return NULL;
05365 *p = (void*)q;
05366 p = q;
05367 k--;
05368 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n"));
05369 }
05370 *p = ip->ptr;
05371 }
05372 else if (ip->level > k)
05373 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving level %u pointers to href='%s'\n", ip->level, id));
05374 while (ip->level > k)
05375 { void *s, **r = &ip->link;
05376 q = (void**)ip->link;
05377 while (q)
05378 { *r = (void*)soap_malloc(soap, sizeof(void*));
05379 s = *q;
05380 *q = *r;
05381 r = (void**)*r;
05382 q = (void**)s;
05383 }
05384 *r = NULL;
05385 ip->size = n;
05386 ip->copy = NULL;
05387 ip->level = ip->level - 1;
05388 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n"));
05389 }
05390 q = (void**)ip->link;
05391 ip->link = p;
05392 *p = (void*)q;
05393 }
05394 else
05395 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarded href='%s' type=%d location=%p (%u bytes)\n", id, t, p, (unsigned int)n));
05396 while (ip->level < k)
05397 { q = (void**)soap_malloc(soap, sizeof(void*));
05398 *p = q;
05399 p = q;
05400 k--;
05401 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n"));
05402 }
05403 q = (void**)ip->link;
05404 ip->link = p;
05405 *p = (void*)q;
05406 }
05407 return p;
05408 }
05409 #endif
05410 #endif
05411
05412
05413 #ifndef WITH_NOIDREF
05414 #ifndef PALM_2
05415 SOAP_FMAC1
05416 void*
05417 SOAP_FMAC2
05418 soap_id_forward(struct soap *soap, const char *href, void *p, size_t len, int st, int tt, size_t n, unsigned int k, void (*fcopy)(struct soap*, int, int, void*, size_t, const void*, size_t))
05419 { struct soap_ilist *ip;
05420 if (!p || !href || !*href)
05421 return p;
05422 ip = soap_lookup(soap, href);
05423 if (!ip)
05424 { ip = soap_enter(soap, href);
05425 ip->type = st;
05426 ip->size = n;
05427 ip->link = NULL;
05428 ip->copy = NULL;
05429 ip->ptr = NULL;
05430 ip->level = 0;
05431 ip->flist = NULL;
05432 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));
05433 }
05434 else if (ip->type != st || (ip->level == k && ip->size != n))
05435 { 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));
05436 strcpy(soap->id, href);
05437 soap->error = SOAP_HREF;
05438 return NULL;
05439 }
05440 if (fcopy || n < sizeof(void*) || *href != '#')
05441 { register struct soap_flist *fp = (struct soap_flist*)SOAP_MALLOC(soap, sizeof(struct soap_flist));
05442 if (!fp)
05443 { soap->error = SOAP_EOM;
05444 return NULL;
05445 }
05446 fp->next = ip->flist;
05447 fp->type = tt;
05448 fp->ptr = p;
05449 fp->level = k;
05450 fp->len = len;
05451 if (fcopy)
05452 fp->fcopy = fcopy;
05453 else
05454 fp->fcopy = soap_fcopy;
05455 ip->flist = fp;
05456 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding type=%d (target type=%d) size=%lu location=%p level=%u len=%lu href='%s'\n", st, tt, (unsigned long)n, p, k, (unsigned long)len, href));
05457 }
05458 else
05459 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding copying address %p for type=%d href='%s'\n", p, st, href));
05460 *(void**)p = ip->copy;
05461 ip->copy = p;
05462 }
05463 return p;
05464 }
05465 #endif
05466 #endif
05467
05468
05469 #ifndef PALM_2
05470 SOAP_FMAC1
05471 void*
05472 SOAP_FMAC2
05473 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*))
05474 {
05475 #ifndef WITH_NOIDREF
05476 struct soap_ilist *ip;
05477 #endif
05478 DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Enter id='%s' type=%d loc=%p size=%lu level=%u\n", id, t, p, (unsigned long)n, k));
05479 soap->alloced = 0;
05480 if (!p)
05481 { if (finstantiate)
05482 p = finstantiate(soap, t, type, arrayType, &n);
05483 else
05484 p = soap_malloc(soap, n);
05485 if (p)
05486 soap->alloced = 1;
05487 }
05488 #ifndef WITH_NOIDREF
05489 if (!id || !*id)
05490 #endif
05491 return p;
05492 #ifndef WITH_NOIDREF
05493 ip = soap_lookup(soap, id);
05494 DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Lookup entry id='%s for location=%p'\n", id, p));
05495 if (!ip)
05496 { ip = soap_enter(soap, id);
05497 ip->type = t;
05498 ip->link = NULL;
05499 ip->copy = NULL;
05500 ip->flist = NULL;
05501 ip->size = n;
05502 ip->ptr = p;
05503 ip->level = k;
05504 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));
05505 }
05506 else if ((ip->type != t || (ip->level == k && ip->size != n)) && (ip->copy || ip->flist))
05507 { 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));
05508 strcpy(soap->id, id);
05509 soap->error = SOAP_HREF;
05510 return NULL;
05511 }
05512 else if (ip->ptr)
05513 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Multiply defined id='%s'\n", id));
05514 strcpy(soap->id, id);
05515 soap->error = SOAP_DUPLICATE_ID;
05516 return NULL;
05517 }
05518 else
05519 { ip->size = n;
05520 ip->ptr = p;
05521 ip->level = k;
05522 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));
05523 }
05524 return ip->ptr;
05525 #endif
05526 }
05527 #endif
05528
05529
05530 #ifndef PALM_2
05531 SOAP_FMAC1
05532 void
05533 SOAP_FMAC2
05534 soap_fcopy(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n)
05535 { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Copying data type=%d (target type=%d) %p -> %p (%lu bytes)\n", st, tt, q, p, (unsigned long)n));
05536 memcpy(p, q, n);
05537 }
05538 #endif
05539
05540
05541 #ifndef PALM_1
05542 SOAP_FMAC1
05543 int
05544 SOAP_FMAC2
05545 soap_end_send(struct soap *soap)
05546 {
05547 #ifndef WITH_LEANER
05548 if (soap->dime.list)
05549 {
05550 soap->dime.last->next = soap->dime.first;
05551 soap->dime.first = soap->dime.list->next;
05552 soap->dime.list->next = NULL;
05553 soap->dime.last = soap->dime.list;
05554 }
05555 if (soap_putdime(soap) || soap_putmime(soap))
05556 return soap->error;
05557 soap->mime.list = NULL;
05558 soap->mime.first = NULL;
05559 soap->mime.last = NULL;
05560 soap->dime.list = NULL;
05561 soap->dime.first = NULL;
05562 soap->dime.last = NULL;
05563 #endif
05564 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End send\n"));
05565 if (soap->mode & SOAP_IO)
05566 { if (soap_flush(soap))
05567 #ifdef WITH_ZLIB
05568 { if (soap->mode & SOAP_ENC_ZLIB && soap->zlib_state == SOAP_ZLIB_DEFLATE)
05569 { soap->zlib_state = SOAP_ZLIB_NONE;
05570 deflateEnd(&soap->d_stream);
05571 }
05572 return soap->error;
05573 }
05574 #else
05575 return soap->error;
05576 #endif
05577 #ifdef WITH_ZLIB
05578 if (soap->mode & SOAP_ENC_ZLIB)
05579 { int r;
05580 soap->d_stream.avail_in = 0;
05581 do
05582 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflating remainder\n"));
05583 r = deflate(&soap->d_stream, Z_FINISH);
05584 if (soap->d_stream.avail_out != SOAP_BUFLEN)
05585 { if (soap_flush_raw(soap, soap->z_buf, SOAP_BUFLEN - soap->d_stream.avail_out))
05586 { soap->zlib_state = SOAP_ZLIB_NONE;
05587 deflateEnd(&soap->d_stream);
05588 return soap->error;
05589 }
05590 soap->d_stream.next_out = (Byte*)soap->z_buf;
05591 soap->d_stream.avail_out = SOAP_BUFLEN;
05592 }
05593 } while (r == Z_OK);
05594 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflated %lu->%lu bytes\n", soap->d_stream.total_in, soap->d_stream.total_out));
05595 soap->z_ratio_out = (float)soap->d_stream.total_out / (float)soap->d_stream.total_in;
05596 soap->mode &= ~SOAP_ENC_ZLIB;
05597 soap->zlib_state = SOAP_ZLIB_NONE;
05598 if (deflateEnd(&soap->d_stream) != Z_OK || r != Z_STREAM_END)
05599 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to end deflate: %s\n", soap->d_stream.msg?soap->d_stream.msg:""));
05600 return soap->error = SOAP_ZLIB_ERROR;
05601 }
05602 #ifdef WITH_GZIP
05603 soap->z_buf[0] = soap->z_crc & 0xFF;
05604 soap->z_buf[1] = (soap->z_crc >> 8) & 0xFF;
05605 soap->z_buf[2] = (soap->z_crc >> 16) & 0xFF;
05606 soap->z_buf[3] = (soap->z_crc >> 24) & 0xFF;
05607 soap->z_buf[4] = soap->d_stream.total_in & 0xFF;
05608 soap->z_buf[5] = (soap->d_stream.total_in >> 8) & 0xFF;
05609 soap->z_buf[6] = (soap->d_stream.total_in >> 16) & 0xFF;
05610 soap->z_buf[7] = (soap->d_stream.total_in >> 24) & 0xFF;
05611 if (soap_flush_raw(soap, soap->z_buf, 8))
05612 return soap->error;
05613 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip crc32=%lu\n", (unsigned long)soap->z_crc));
05614 #endif
05615 }
05616 #endif
05617 if ((soap->mode & SOAP_IO) == SOAP_IO_STORE)
05618 { char *p;
05619 #ifndef WITH_NOHTTP
05620 if (!(soap->mode & SOAP_ENC_XML))
05621 { soap->mode--;
05622 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Sending buffered message of length %u\n", (unsigned int)soap->blist->size));
05623 if (soap->status >= SOAP_POST)
05624 soap->error = soap->fpost(soap, soap->endpoint, soap->host, soap->port, soap->path, soap->action, soap->blist->size);
05625 else if (soap->status != SOAP_STOP)
05626 soap->error = soap->fresponse(soap, soap->status, soap->blist->size);
05627 if (soap->error || soap_flush(soap))
05628 return soap->error;
05629 soap->mode++;
05630 }
05631 #endif
05632 for (p = soap_first_block(soap); p; p = soap_next_block(soap))
05633 { DBGMSG(SENT, p, soap_block_size(soap));
05634 if ((soap->error = soap->fsend(soap, p, soap_block_size(soap))))
05635 { soap_end_block(soap);
05636 return soap->error;
05637 }
05638 }
05639 soap_end_block(soap);
05640 }
05641 #ifndef WITH_LEANER
05642 else if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK)
05643 { DBGMSG(SENT, "\r\n0\r\n\r\n", 7);
05644 if ((soap->error = soap->fsend(soap, "\r\n0\r\n\r\n", 7)))
05645 return soap->error;
05646 }
05647 #endif
05648 }
05649 #ifdef WITH_TCPFIN
05650 #ifdef WITH_OPENSSL
05651 if (!soap->ssl && soap_valid_socket(soap->socket) && !soap->keep_alive && !(soap->omode & SOAP_IO_UDP))
05652 soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 1);
05653 #else
05654 if (soap_valid_socket(soap->socket) && !soap->keep_alive && !(soap->omode & SOAP_IO_UDP))
05655 soap->fshutdownsocket(soap, (SOAP_SOCKET)soap->socket, 1);
05656 #endif
05657 #endif
05658 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of send phase\n"));
05659 soap->omode &= ~SOAP_XML_SEC;
05660 soap->count = 0;
05661 soap->part = SOAP_END;
05662 return SOAP_OK;
05663 }
05664 #endif
05665
05666
05667 #ifndef PALM_1
05668 SOAP_FMAC1
05669 int
05670 SOAP_FMAC2
05671 soap_end_recv(struct soap *soap)
05672 { soap->part = SOAP_END;
05673 #ifndef WITH_LEANER
05674 if ((soap->mode & SOAP_ENC_DIME) && soap_getdime(soap))
05675 return soap->error;
05676 soap->dime.list = soap->dime.first;
05677 soap->dime.first = NULL;
05678 soap->dime.last = NULL;
05679
05680 if (soap->mode & SOAP_ENC_MIME)
05681 { if (soap->mode & SOAP_MIME_POSTCHECK)
05682 { soap_resolve(soap);
05683 return SOAP_OK;
05684 }
05685 if (soap_getmime(soap))
05686 return soap->error;
05687 }
05688 soap->mime.list = soap->mime.first;
05689 soap->mime.first = NULL;
05690 soap->mime.last = NULL;
05691 soap->mime.boundary = NULL;
05692 #endif
05693 DBGLOG(TEST,SOAP_MESSAGE(fdebug, "End of receive message ok\n"));
05694 #ifdef WITH_ZLIB
05695 if (soap->mode & SOAP_ENC_ZLIB)
05696 { soap->mode &= ~SOAP_ENC_ZLIB;
05697 memcpy(soap->buf, soap->z_buf, SOAP_BUFLEN);
05698 soap->bufidx = (char*)soap->d_stream.next_in - soap->z_buf;
05699 soap->buflen = soap->z_buflen;
05700 soap->zlib_state = SOAP_ZLIB_NONE;
05701 if (inflateEnd(&soap->d_stream) != Z_OK)
05702 return soap->error = SOAP_ZLIB_ERROR;
05703 #ifdef WITH_GZIP
05704 if (soap->zlib_in == SOAP_ZLIB_GZIP)
05705 { soap_wchar c;
05706 short i;
05707 for (i = 0; i < 8; i++)
05708 { if ((int)(c = soap_getchar(soap)) == EOF)
05709 return soap->error = SOAP_EOF;
05710 soap->z_buf[i] = (char)c;
05711 }
05712 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)))
05713 { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Gzip error: crc check failed, message corrupted? (crc32=%lu)\n", (unsigned long)soap->z_crc));
05714 return soap->error = SOAP_ZLIB_ERROR;
05715 }
05716 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)))
05717 { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Gzip error: incorrect message length\n"));
05718 return soap->error = SOAP_ZLIB_ERROR;
05719 }
05720 }
05721 #endif
05722 }
05723 #endif
05724 if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK)
05725 while ((int)soap_getchar(soap) != EOF)
05726 ;
05727 if (soap->fdisconnect && (soap->error = soap->fdisconnect(soap)))
05728 return soap->error;
05729 #ifndef WITH_NOIDREF
05730 return soap_resolve(soap);
05731 #else
05732 #ifndef WITH_LEANER
05733 if (soap->xlist)
05734 { if (soap->mode & SOAP_ENC_MTOM)
05735 return soap->error = SOAP_MIME_HREF;
05736 return soap->error = SOAP_DIME_HREF;
05737 }
05738 #endif
05739 return SOAP_OK;
05740 #endif
05741 }
05742 #endif
05743
05744
05745 #ifndef PALM_1
05746 SOAP_FMAC1
05747 void
05748 SOAP_FMAC2
05749 soap_free(struct soap *soap)
05750 { register struct Namespace *ns;
05751 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free namespace stack\n"));
05752 while (soap->nlist)
05753 { register struct soap_nlist *np = soap->nlist->next;
05754 SOAP_FREE(soap, soap->nlist);
05755 soap->nlist = np;
05756 }
05757 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free any remaining temp blocks\n"));
05758 while (soap->blist)
05759 soap_end_block(soap);
05760 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free attribute storage\n"));
05761 while (soap->attributes)
05762 { register struct soap_attribute *tp = soap->attributes->next;
05763 if (soap->attributes->value)
05764 SOAP_FREE(soap, soap->attributes->value);
05765 SOAP_FREE(soap, soap->attributes);
05766 soap->attributes = tp;
05767 }
05768 #ifdef WITH_FAST
05769 if (soap->labbuf)
05770 SOAP_FREE(soap, soap->labbuf);
05771 soap->labbuf = NULL;
05772 soap->lablen = 0;
05773 soap->labidx = 0;
05774 #endif
05775 ns = soap->local_namespaces;
05776 if (ns)
05777 { for (; ns->id; ns++)
05778 { if (ns->out)
05779 { if (soap->encodingStyle == ns->out)
05780 soap->encodingStyle = SOAP_STR_EOS;
05781 SOAP_FREE(soap, ns->out);
05782 ns->out = NULL;
05783 }
05784 if (soap->encodingStyle == ns->ns)
05785 soap->encodingStyle = SOAP_STR_EOS;
05786 }
05787 SOAP_FREE(soap, soap->local_namespaces);
05788 soap->local_namespaces = NULL;
05789 }
05790 #ifndef WITH_LEANER
05791 while (soap->xlist)
05792 { struct soap_xlist *xp = soap->xlist->next;
05793 SOAP_FREE(soap, soap->xlist);
05794 soap->xlist = xp;
05795 }
05796 #endif
05797 #ifndef WITH_NOIDREF
05798 soap_free_pht(soap);
05799 soap_free_iht(soap);
05800 #endif
05801 }
05802 #endif
05803
05804
05805 #ifdef SOAP_DEBUG
05806 static void
05807 soap_init_logs(struct soap *soap)
05808 { int i;
05809 for (i = 0; i < SOAP_MAXLOGS; i++)
05810 { soap->logfile[i] = NULL;
05811 soap->fdebug[i] = NULL;
05812 }
05813 }
05814 #endif
05815
05816
05817 #if !defined(WITH_LEAN) || defined(SOAP_DEBUG)
05818 SOAP_FMAC1
05819 void
05820 SOAP_FMAC2
05821 soap_open_logfile(struct soap *soap, int i)
05822 { if (soap->logfile[i])
05823 soap->fdebug[i] = fopen(soap->logfile[i], i < 2 ? "ab" : "a");
05824 }
05825 #endif
05826
05827
05828 #ifdef SOAP_DEBUG
05829 static void
05830 soap_close_logfile(struct soap *soap, int i)
05831 { if (soap->fdebug[i])
05832 { fclose(soap->fdebug[i]);
05833 soap->fdebug[i] = NULL;
05834 }
05835 }
05836 #endif
05837
05838
05839 #ifdef SOAP_DEBUG
05840 SOAP_FMAC1
05841 void
05842 SOAP_FMAC2
05843 soap_close_logfiles(struct soap *soap)
05844 { int i;
05845 for (i = 0; i < SOAP_MAXLOGS; i++)
05846 soap_close_logfile(soap, i);
05847 }
05848 #endif
05849
05850
05851 #ifdef SOAP_DEBUG
05852 static void
05853 soap_set_logfile(struct soap *soap, int i, const char *logfile)
05854 { char *s = NULL;
05855 soap_close_logfile(soap, i);
05856 if (soap->logfile[i])
05857 SOAP_FREE(soap, (void*)soap->logfile[i]);
05858 if (logfile)
05859 if ((s = (char*)SOAP_MALLOC(soap, strlen(logfile) + 1)))
05860 strcpy(s, logfile);
05861 soap->logfile[i] = s;
05862 }
05863 #endif
05864
05865
05866 #ifdef SOAP_DEBUG
05867 SOAP_FMAC1
05868 void
05869 SOAP_FMAC2
05870 soap_set_recv_logfile(struct soap *soap, const char *logfile)
05871 { soap_set_logfile(soap, SOAP_INDEX_RECV, logfile);
05872 }
05873 #endif
05874
05875
05876 #ifdef SOAP_DEBUG
05877 SOAP_FMAC1
05878 void
05879 SOAP_FMAC2
05880 soap_set_sent_logfile(struct soap *soap, const char *logfile)
05881 { soap_set_logfile(soap, SOAP_INDEX_SENT, logfile);
05882 }
05883 #endif
05884
05885
05886 #ifdef SOAP_DEBUG
05887 SOAP_FMAC1
05888 void
05889 SOAP_FMAC2
05890 soap_set_test_logfile(struct soap *soap, const char *logfile)
05891 { soap_set_logfile(soap, SOAP_INDEX_TEST, logfile);
05892 }
05893 #endif
05894
05895
05896 #ifndef PALM_1
05897 SOAP_FMAC1
05898 struct soap*
05899 SOAP_FMAC2
05900 soap_copy(struct soap *soap)
05901 { return soap_copy_context((struct soap*)malloc(sizeof(struct soap)), soap);
05902 }
05903 #endif
05904
05905
05906 #ifndef PALM_1
05907 SOAP_FMAC1
05908 struct soap*
05909 SOAP_FMAC2
05910 soap_copy_context(struct soap *copy, struct soap *soap)
05911 { if (soap_check_state(soap))
05912 return NULL;
05913 if (copy)
05914 { register struct soap_plugin *p;
05915 memcpy(copy, soap, sizeof(struct soap));
05916 copy->state = SOAP_COPY;
05917 copy->error = SOAP_OK;
05918 copy->userid = NULL;
05919 copy->passwd = NULL;
05920 copy->nlist = NULL;
05921 copy->blist = NULL;
05922 copy->clist = NULL;
05923 copy->alist = NULL;
05924 copy->attributes = NULL;
05925 #ifdef WITH_FAST
05926 copy->labbuf = NULL;
05927 copy->lablen = 0;
05928 copy->labidx = 0;
05929 #endif
05930 #ifdef SOAP_DEBUG
05931 soap_init_mht(copy);
05932 #endif
05933 copy->local_namespaces = NULL;
05934 #ifndef WITH_NOIDREF
05935 soap_init_iht(copy);
05936 soap_init_pht(copy);
05937 #endif
05938 copy->header = NULL;
05939 copy->fault = NULL;
05940 copy->action = NULL;
05941 #ifndef WITH_LEAN
05942 #ifdef WITH_COOKIES
05943 copy->cookies = soap_copy_cookies(copy, soap);
05944 #else
05945 copy->cookies = NULL;
05946 #endif
05947 #endif
05948 #ifdef SOAP_DEBUG
05949 soap_init_logs(copy);
05950 soap_set_recv_logfile(copy, soap->logfile[SOAP_INDEX_RECV]);
05951 soap_set_sent_logfile(copy, soap->logfile[SOAP_INDEX_SENT]);
05952 soap_set_test_logfile(copy, soap->logfile[SOAP_INDEX_TEST]);
05953 #endif
05954 copy->plugins = NULL;
05955 for (p = soap->plugins; p; p = p->next)
05956 { register struct soap_plugin *q = (struct soap_plugin*)SOAP_MALLOC(copy, sizeof(struct soap_plugin));
05957 if (!q)
05958 return NULL;
05959 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying plugin '%s'\n", p->id));
05960 *q = *p;
05961 if (p->fcopy && (soap->error = p->fcopy(copy, q, p)))
05962 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not copy plugin '%s'\n", p->id));
05963 SOAP_FREE(copy, q);
05964 return NULL;
05965 }
05966 q->next = copy->plugins;
05967 copy->plugins = q;
05968 }
05969 }
05970 else
05971 soap->error = SOAP_EOM;
05972 return copy;
05973 }
05974 #endif
05975
05976
05977 #ifndef PALM_1
05978 SOAP_FMAC1
05979 void
05980 SOAP_FMAC2
05981 soap_copy_stream(struct soap *copy, struct soap *soap)
05982 { copy->mode = soap->mode;
05983 copy->imode = soap->imode;
05984 copy->omode = soap->omode;
05985 copy->socket = soap->socket;
05986 copy->recv_timeout = soap->recv_timeout;
05987 copy->send_timeout = soap->send_timeout;
05988 #if defined(__cplusplus) && !defined(WITH_LEAN)
05989 copy->os = soap->os;
05990 copy->is = soap->is;
05991 #endif
05992 copy->sendfd = soap->sendfd;
05993 copy->recvfd = soap->recvfd;
05994 copy->bufidx = soap->bufidx;
05995 copy->buflen = soap->buflen;
05996 copy->ahead = soap->ahead;
05997 copy->cdata = soap->cdata;
05998 copy->chunksize = soap->chunksize;
05999 copy->chunkbuflen = soap->chunkbuflen;
06000 copy->keep_alive = soap->keep_alive;
06001 copy->max_keep_alive = soap->max_keep_alive;
06002 copy->peer = soap->peer;
06003 copy->peerlen = soap->peerlen;
06004 #ifdef WITH_OPENSSL
06005 copy->bio = soap->bio;
06006 copy->ssl = soap->ssl;
06007 copy->ctx = soap->ctx;
06008 #endif
06009 #ifdef WITH_ZLIB
06010 copy->zlib_state = soap->zlib_state;
06011 copy->zlib_in = soap->zlib_in;
06012 copy->zlib_out = soap->zlib_out;
06013 copy->d_stream = soap->d_stream;
06014 copy->z_buflen = soap->z_buflen;
06015 copy->z_level = soap->z_level;
06016 copy->z_crc = soap->z_crc;
06017 copy->z_ratio_in = soap->z_ratio_in;
06018 copy->z_ratio_out = soap->z_ratio_out;
06019 memcpy(copy->z_buf, soap->z_buf, sizeof(soap->z_buf));
06020 #endif
06021 memcpy(copy->buf, soap->buf, sizeof(soap->buf));
06022 }
06023 #endif
06024
06025
06026 #ifndef PALM_1
06027 SOAP_FMAC1
06028 void
06029 SOAP_FMAC2
06030 soap_init(struct soap *soap)
06031 { soap->state = SOAP_INIT;
06032 soap->version = 0;
06033 soap_imode(soap, SOAP_IO_DEFAULT);
06034 soap_omode(soap, SOAP_IO_DEFAULT);
06035 soap->plugins = NULL;
06036 soap->user = NULL;
06037 soap->userid = NULL;
06038 soap->passwd = NULL;
06039 #ifndef WITH_NOHTTP
06040 soap->fpost = http_post;
06041 soap->fget = http_get;
06042 soap->fform = NULL;
06043 soap->fposthdr = http_post_header;
06044 soap->fresponse = http_response;
06045 soap->fparse = http_parse;
06046 soap->fparsehdr = http_parse_header;
06047 #endif
06048 soap->fheader = NULL;
06049 soap->fconnect = NULL;
06050 soap->fdisconnect = NULL;
06051 #ifndef WITH_NOIO
06052 #ifndef WITH_IPV6
06053 soap->fresolve = tcp_gethost;
06054 #else
06055 soap->fresolve = NULL;
06056 #endif
06057 soap->faccept = tcp_accept;
06058 soap->fopen = tcp_connect;
06059 soap->fclose = tcp_disconnect;
06060 soap->fclosesocket = tcp_closesocket;
06061 soap->fshutdownsocket = tcp_shutdownsocket;
06062 soap->fsend = fsend;
06063 soap->frecv = frecv;
06064 soap->fpoll = soap_poll;
06065 #else
06066 soap->fopen = NULL;
06067 soap->fclose = NULL;
06068 soap->fpoll = NULL;
06069 #endif
06070 soap->fseterror = NULL;
06071 soap->fignore = NULL;
06072 soap->fserveloop = NULL;
06073 soap->fplugin = fplugin;
06074 #ifndef WITH_LEANER
06075 soap->fprepareinit = NULL;
06076 soap->fpreparesend = NULL;
06077 soap->fpreparerecv = NULL;
06078 soap->fpreparefinal = NULL;
06079 soap->fdimereadopen = NULL;
06080 soap->fdimewriteopen = NULL;
06081 soap->fdimereadclose = NULL;
06082 soap->fdimewriteclose = NULL;
06083 soap->fdimeread = NULL;
06084 soap->fdimewrite = NULL;
06085 soap->fmimereadopen = NULL;
06086 soap->fmimewriteopen = NULL;
06087 soap->fmimereadclose = NULL;
06088 soap->fmimewriteclose = NULL;
06089 soap->fmimeread = NULL;
06090 soap->fmimewrite = NULL;
06091 #endif
06092 soap->float_format = "%G";
06093 soap->double_format = "%lG";
06094 soap->dime_id_format = "cid:id%d";
06095 soap->http_version = "1.1";
06096 soap->http_content = NULL;
06097 soap->actor = NULL;
06098 soap->max_keep_alive = SOAP_MAXKEEPALIVE;
06099 soap->keep_alive = 0;
06100 soap->recv_timeout = 0;
06101 soap->send_timeout = 0;
06102 soap->connect_timeout = 0;
06103 soap->accept_timeout = 0;
06104 soap->socket_flags = 0;
06105 soap->connect_flags = 0;
06106 soap->bind_flags = 0;
06107 soap->accept_flags = 0;
06108 soap->ip = 0;
06109 #ifdef WITH_FAST
06110 soap->labbuf = NULL;
06111 soap->lablen = 0;
06112 soap->labidx = 0;
06113 #endif
06114 soap->encodingStyle = SOAP_STR_EOS;
06115 #ifndef WITH_NONAMESPACES
06116 soap->namespaces = namespaces;
06117 #else
06118 soap->namespaces = NULL;
06119 #endif
06120 soap->local_namespaces = NULL;
06121 soap->nlist = NULL;
06122 soap->blist = NULL;
06123 soap->clist = NULL;
06124 soap->alist = NULL;
06125 soap->attributes = NULL;
06126 soap->header = NULL;
06127 soap->fault = NULL;
06128 soap->master = SOAP_INVALID_SOCKET;
06129 soap->socket = SOAP_INVALID_SOCKET;
06130 soap->os = NULL;
06131 soap->is = NULL;
06132 #ifndef WITH_LEANER
06133 soap->dom = NULL;
06134 soap->dime.list = NULL;
06135 soap->dime.first = NULL;
06136 soap->dime.last = NULL;
06137 soap->mime.list = NULL;
06138 soap->mime.first = NULL;
06139 soap->mime.last = NULL;
06140 soap->mime.boundary = NULL;
06141 soap->mime.start = NULL;
06142 soap->xlist = NULL;
06143 #endif
06144 #ifndef UNDER_CE
06145 soap->recvfd = 0;
06146 soap->sendfd = 1;
06147 #else
06148 soap->recvfd = stdin;
06149 soap->sendfd = stdout;
06150 #endif
06151 soap->host[0] = '\0';
06152 soap->port = 0;
06153 soap->action = NULL;
06154 soap->proxy_host = NULL;
06155 soap->proxy_port = 8080;
06156 soap->proxy_userid = NULL;
06157 soap->proxy_passwd = NULL;
06158 soap->authrealm = NULL;
06159 soap->prolog = NULL;
06160 #ifdef WITH_OPENSSL
06161 if (!ssl_init_done)
06162 soap_ssl_init();
06163 soap->fsslauth = ssl_auth_init;
06164 soap->fsslverify = ssl_verify_callback;
06165 soap->bio = NULL;
06166 soap->ssl = NULL;
06167 soap->ctx = NULL;
06168 soap->require_server_auth = 0;
06169 soap->require_client_auth = 0;
06170 soap->rsa = 0;
06171 soap->keyfile = NULL;
06172 soap->password = NULL;
06173 soap->dhfile = NULL;
06174 soap->cafile = NULL;
06175 soap->capath = NULL;
06176 soap->crlfile = NULL;
06177 soap->randfile = NULL;
06178 soap->session = NULL;
06179 #endif
06180 #ifdef WITH_ZLIB
06181 soap->zlib_state = SOAP_ZLIB_NONE;
06182 soap->zlib_in = SOAP_ZLIB_NONE;
06183 soap->zlib_out = SOAP_ZLIB_NONE;
06184 soap->d_stream.zalloc = NULL;
06185 soap->d_stream.zfree = NULL;
06186 soap->d_stream.opaque = NULL;
06187 soap->z_level = 6;
06188 #endif
06189 #ifndef WITH_LEAN
06190 soap->c14ninclude = NULL;
06191 soap->c14nexclude = NULL;
06192 soap->cookies = NULL;
06193 soap->cookie_domain = NULL;
06194 soap->cookie_path = NULL;
06195 soap->cookie_max = 32;
06196 #endif
06197 #ifdef SOAP_DEBUG
06198 soap_init_mht(soap);
06199 soap_init_logs(soap);
06200 soap_set_recv_logfile(soap, "RECV.log");
06201 soap_set_sent_logfile(soap, "SENT.log");
06202 soap_set_test_logfile(soap, NULL);
06203 #endif
06204 #ifdef WMW_RPM_IO
06205 soap->rpmreqid = NULL;
06206 #endif
06207 #ifdef PALM
06208 palmNetLibOpen();
06209 #endif
06210 #ifndef WITH_NOIDREF
06211 soap_init_iht(soap);
06212 soap_init_pht(soap);
06213 #endif
06214 soap_begin(soap);
06215 #ifdef SOAP_DEBUG
06216 soap_set_test_logfile(soap, "TEST.log");
06217 #endif
06218 }
06219 #endif
06220
06221
06222 #ifndef PALM_1
06223 SOAP_FMAC1
06224 void
06225 SOAP_FMAC2
06226 soap_init1(struct soap *soap, soap_mode mode)
06227 { soap_init2(soap, mode, mode);
06228 }
06229 #endif
06230
06231
06232 #ifndef PALM_1
06233 SOAP_FMAC1
06234 void
06235 SOAP_FMAC2
06236 soap_init2(struct soap *soap, soap_mode imode, soap_mode omode)
06237 { soap_init(soap);
06238 soap_imode(soap, imode);
06239 soap_omode(soap, omode);
06240 }
06241 #endif
06242
06243
06244 #ifndef PALM_2
06245 SOAP_FMAC1
06246 void
06247 SOAP_FMAC2
06248 soap_begin(struct soap *soap)
06249 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing\n"));
06250 if (!soap->keep_alive)
06251 { soap->buflen = 0;
06252 soap->bufidx = 0;
06253 }
06254 soap->keep_alive = (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) != 0);
06255 soap->null = 0;
06256 soap->position = 0;
06257 soap->encoding = 0;
06258 soap->mustUnderstand = 0;
06259 soap->mode = 0;
06260 soap->ns = 0;
06261 soap->part = SOAP_END;
06262 soap->alloced = 0;
06263 soap->count = 0;
06264 soap->length = 0;
06265 soap->cdata = 0;
06266 soap->error = SOAP_OK;
06267 soap->peeked = 0;
06268 soap->ahead = 0;
06269 soap->idnum = 0;
06270 soap->level = 0;
06271 soap->endpoint[0] = '\0';
06272 #ifndef WITH_LEANER
06273 soap->dime.chunksize = 0;
06274 soap->dime.buflen = 0;
06275 #endif
06276 soap_free(soap);
06277 }
06278 #endif
06279
06280
06281 #ifndef PALM_2
06282 SOAP_FMAC1
06283 void
06284 SOAP_FMAC2
06285 soap_end(struct soap *soap)
06286 { register struct soap_clist *cp;
06287 if (soap_check_state(soap))
06288 return;
06289 soap_free(soap);
06290 soap_dealloc(soap, NULL);
06291 while (soap->clist)
06292 { cp = soap->clist->next;
06293 SOAP_FREE(soap, soap->clist);
06294 soap->clist = cp;
06295 }
06296 soap_closesock(soap);
06297 #ifdef SOAP_DEBUG
06298 soap_close_logfiles(soap);
06299 #endif
06300 #ifdef PALM
06301 palmNetLibClose();
06302 #endif
06303 }
06304 #endif
06305
06306
06307 #ifndef PALM_1
06308 SOAP_FMAC1
06309 int
06310 SOAP_FMAC2
06311 soap_set_namespaces(struct soap *soap, const struct Namespace *p)
06312 { register struct Namespace *ns = soap->local_namespaces;
06313 register struct soap_nlist *np, *nq, *nr;
06314 register unsigned int level = soap->level;
06315 soap->namespaces = p;
06316 soap->local_namespaces = NULL;
06317 soap_set_local_namespaces(soap);
06318
06319 np = soap->nlist;
06320 soap->nlist = NULL;
06321 if (np)
06322 { nq = np->next;
06323 np->next = NULL;
06324 while (nq)
06325 { nr = nq->next;
06326 nq->next = np;
06327 np = nq;
06328 nq = nr;
06329 }
06330 }
06331
06332 while (np)
06333 { register const char *s;
06334 soap->level = np->level;
06335 s = np->ns;
06336 if (!s && np->index >= 0 && ns)
06337 { s = ns[np->index].out;
06338 if (!s)
06339 s = ns[np->index].ns;
06340 }
06341 if (s && soap_push_namespace(soap, np->id, s))
06342 return soap->error;
06343 nq = np;
06344 np = np->next;
06345 SOAP_FREE(soap, nq);
06346 }
06347 if (ns)
06348 { register int i;
06349 for (i = 0; ns[i].id; i++)
06350 { if (ns[i].out)
06351 { SOAP_FREE(soap, ns[i].out);
06352 ns[i].out = NULL;
06353 }
06354 }
06355 SOAP_FREE(soap, ns);
06356 }
06357 soap->level = level;
06358 return SOAP_OK;
06359 }
06360 #endif
06361
06362
06363 #ifndef PALM_1
06364 SOAP_FMAC1
06365 void
06366 SOAP_FMAC2
06367 soap_set_local_namespaces(struct soap *soap)
06368 { if (soap->namespaces && !soap->local_namespaces)
06369 { register const struct Namespace *ns1;
06370 register struct Namespace *ns2;
06371 register size_t n = 1;
06372 for (ns1 = soap->namespaces; ns1->id; ns1++)
06373 n++;
06374 n *= sizeof(struct Namespace);
06375 ns2 = (struct Namespace*)SOAP_MALLOC(soap, n);
06376 if (ns2)
06377 { memcpy(ns2, soap->namespaces, n);
06378 if (ns2[0].ns)
06379 { if (!strcmp(ns2[0].ns, soap_env1))
06380 soap->version = 1;
06381 else
06382 soap->version = 2;
06383 }
06384 soap->local_namespaces = ns2;
06385 }
06386 }
06387 }
06388 #endif
06389
06390
06391 #ifndef WITH_LEAN
06392 #ifndef PALM_1
06393 SOAP_FMAC1
06394 const char *
06395 SOAP_FMAC2
06396 soap_strsearch(const char *big, const char *little)
06397 { size_t n = strlen(little);
06398 const char *s = big;
06399 while (s)
06400 { if (!strncmp(s, little, n) && (s[n] == '\0' || s[n] == ' '))
06401 return s;
06402 s = strchr(s, ' ');
06403 if (s)
06404 s++;
06405 }
06406 return NULL;
06407 }
06408 #endif
06409 #endif
06410
06411
06412 #ifndef WITH_LEAN
06413 static struct soap_nlist *
06414 soap_lookup_ns(struct soap *soap, const char *tag, size_t n)
06415 { register struct soap_nlist *np;
06416 for (np = soap->nlist; np; np = np->next)
06417 { if (!strncmp(np->id, tag, n) && !np->id[n])
06418 return np;
06419 }
06420 return NULL;
06421 }
06422 #endif
06423
06424
06425 #ifndef WITH_LEAN
06426 static struct soap_nlist *
06427 soap_push_ns(struct soap *soap, const char *id, const char *ns, short utilized)
06428 { register struct soap_nlist *np;
06429 size_t n, k;
06430 if (soap_strsearch(soap->c14nexclude, id))
06431 return NULL;
06432 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push namespace binding (level=%u) '%s' '%s'\n", soap->level, id, ns?ns:""));
06433 if (!utilized)
06434 { for (np = soap->nlist; np; np = np->next)
06435 { if (!strcmp(np->id, id) && (!np->ns || !strcmp(np->ns, ns)))
06436 break;
06437 }
06438 if (np)
06439 { if (np->index == 1)
06440 utilized = np->index;
06441 else
06442 return NULL;
06443 }
06444 }
06445 n = strlen(id);
06446 if (ns)
06447 k = strlen(ns);
06448 else
06449 k = 0;
06450 np = (struct soap_nlist*)SOAP_MALLOC(soap, sizeof(struct soap_nlist) + n + k + 1);
06451 if (!np)
06452 { soap->error = SOAP_EOM;
06453 return NULL;
06454 }
06455 np->next = soap->nlist;
06456 soap->nlist = np;
06457 strcpy(np->id, id);
06458 if (ns)
06459 { np->ns = np->id + n + 1;
06460 strcpy(np->ns, ns);
06461 }
06462 else
06463 np->ns = NULL;
06464 np->level = soap->level;
06465 np->index = utilized;
06466 return np;
06467 }
06468 #endif
06469
06470
06471 #ifndef WITH_LEAN
06472 static void
06473 soap_utilize_ns(struct soap *soap, const char *tag, size_t n)
06474 { register struct soap_nlist *np = soap_lookup_ns(soap, tag, n);
06475 if (np)
06476 { if (np->index == 0)
06477 soap_push_ns(soap, np->id, np->ns, 1);
06478 }
06479 else
06480 { strncpy(soap->tmpbuf, tag, n);
06481 soap->tmpbuf[n] = '\0';
06482 soap_push_ns(soap, soap->tmpbuf, NULL, 1);
06483 }
06484 }
06485 #endif
06486
06487
06488 #ifndef WITH_LEAN
06489 static void
06490 soap_pop_ns(struct soap *soap)
06491 { soap_pop_namespace(soap);
06492 }
06493 #endif
06494
06495
06496 #ifndef PALM_2
06497 SOAP_FMAC1
06498 int
06499 SOAP_FMAC2
06500 soap_element(struct soap *soap, const char *tag, int id, const char *type)
06501 {
06502 #ifdef WITH_XMLNS
06503 register const char *s;
06504 #endif
06505 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element begin tag='%s' id='%d' type='%s'\n", tag, id, type?type:""));
06506 #ifdef WITH_DOM
06507 if (soap->mode & SOAP_XML_DOM)
06508 { register struct soap_dom_element *elt = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element));
06509 if (!elt)
06510 return soap->error = SOAP_EOM;
06511 elt->soap = soap;
06512 elt->next = NULL;
06513 elt->prnt = soap->dom;
06514 elt->name = soap_strdup(soap, tag);
06515 elt->elts = NULL;
06516 elt->atts = NULL;
06517 elt->nstr = NULL;
06518 elt->data = NULL;
06519 elt->wide = NULL;
06520 elt->node = NULL;
06521 elt->type = 0;
06522 elt->head = NULL;
06523 elt->tail = NULL;
06524 if (soap->dom)
06525 { struct soap_dom_element *p = soap->dom->elts;
06526 if (p)
06527 { while (p->next)
06528 p = p->next;
06529 p->next = elt;
06530 }
06531 else
06532 soap->dom->elts = elt;
06533 }
06534 soap->dom = elt;
06535 }
06536 else
06537 {
06538 #endif
06539 soap->level++;
06540 #ifndef WITH_LEAN
06541 if (!soap->ns)
06542 { if (!(soap->mode & SOAP_XML_CANONICAL)
06543 && soap_send(soap, soap->prolog ? soap->prolog : "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"))
06544 return soap->error;
06545 }
06546 else if (soap->mode & SOAP_XML_INDENT)
06547 { if (soap->ns == 1 && soap_send_raw(soap, soap_indent, soap->level < sizeof(soap_indent) ? soap->level : sizeof(soap_indent) - 1))
06548 return soap->error;
06549 soap->body = 1;
06550 }
06551 #endif
06552 #ifdef WITH_XMLNS
06553 s = strchr(tag, ':');
06554 if (s && strncmp(tag, "SOAP-ENV", s - tag))
06555 { struct Namespace *ns = soap->local_namespaces;
06556 size_t n = s - tag;
06557 if (soap_send_raw(soap, "<", 1)
06558 || soap_send(soap, s + 1))
06559 return soap->error;
06560 if (soap->nlist && !strncmp(soap->nlist->id, tag, n) && !soap->nlist->id[n])
06561 ns = NULL;
06562 for (; ns && ns->id; ns++)
06563 { if (*ns->id && (ns->out || ns->ns) && !strncmp(ns->id, tag, n) && !ns->id[n])
06564 { soap_push_ns(soap, ns->id, ns->out ? ns->out : ns->ns, 0);
06565 if (soap_attribute(soap, "xmlns", ns->out ? ns->out : ns->ns))
06566 return soap->error;
06567 break;
06568 }
06569 }
06570 }
06571 else
06572 #endif
06573 if (soap_send_raw(soap, "<", 1)
06574 || soap_send(soap, tag))
06575 return soap->error;
06576 #ifdef WITH_DOM
06577 }
06578 #endif
06579 if (!soap->ns)
06580 { struct Namespace *ns;
06581 for (ns = soap->local_namespaces; ns && ns->id; ns++)
06582 { if (*ns->id && (ns->out || ns->ns))
06583 { sprintf(soap->tmpbuf, "xmlns:%s", ns->id);
06584 if (soap_attribute(soap, soap->tmpbuf, ns->out ? ns->out : ns->ns))
06585 return soap->error;
06586 }
06587 }
06588 }
06589 soap->ns = 1;
06590 #ifndef WITH_LEAN
06591 if (soap->mode & SOAP_XML_CANONICAL)
06592 { const char *t = strchr(tag, ':');
06593 if (t)
06594 soap_utilize_ns(soap, tag, t - tag);
06595 }
06596 #endif
06597 if (id > 0)
06598 { sprintf(soap->tmpbuf, "_%d", id);
06599 if (soap_attribute(soap, "id", soap->tmpbuf))
06600 return soap->error;
06601 }
06602 if (type && *type)
06603 { if (soap_attribute(soap, "xsi:type", type))
06604 return soap->error;
06605 #ifndef WITH_LEAN
06606 if (soap->mode & SOAP_XML_CANONICAL)
06607 { const char *t = strchr(type, ':');
06608 if (t)
06609 soap_utilize_ns(soap, type, t - type);
06610 }
06611 #endif
06612 }
06613 if (soap->null && soap->position > 0)
06614 { register int i;
06615 sprintf(soap->tmpbuf, "[%d", soap->positions[0]);
06616 for (i = 1; i < soap->position; i++)
06617 sprintf(soap->tmpbuf + strlen(soap->tmpbuf), ",%d", soap->positions[i]);
06618 strcat(soap->tmpbuf, "]");
06619 if (soap_attribute(soap, "SOAP-ENC:position", soap->tmpbuf))
06620 return soap->error;
06621 }
06622 if (soap->mustUnderstand)
06623 { if (soap->actor && *soap->actor)
06624 { if (soap_attribute(soap, soap->version == 2 ? "SOAP-ENV:role" : "SOAP-ENV:actor", soap->actor))
06625 return soap->error;
06626 }
06627 if (soap_attribute(soap, "SOAP-ENV:mustUnderstand", soap->version == 2 ? "true" : "1"))
06628 return soap->error;
06629 soap->mustUnderstand = 0;
06630 }
06631 if (soap->encoding)
06632 { if (soap->encodingStyle && soap->local_namespaces)
06633 { if (!*soap->encodingStyle)
06634 { if (soap->local_namespaces[1].out)
06635 soap->encodingStyle = soap->local_namespaces[1].out;
06636 else
06637 soap->encodingStyle = soap->local_namespaces[1].ns;
06638 }
06639 if (soap_attribute(soap, "SOAP-ENV:encodingStyle", soap->encodingStyle))
06640 return soap->error;
06641 }
06642 soap->encoding = 0;
06643 }
06644 soap->null = 0;
06645 soap->position = 0;
06646 return SOAP_OK;
06647 }
06648 #endif
06649
06650
06651 #ifndef PALM_2
06652 SOAP_FMAC1
06653 int
06654 SOAP_FMAC2
06655 soap_element_begin_out(struct soap *soap, const char *tag, int id, const char *type)
06656 { if (*tag == '-')
06657 return SOAP_OK;
06658 if (soap_element(soap, tag, id, type))
06659 return soap->error;
06660 return soap_element_start_end_out(soap, NULL);
06661 }
06662 #endif
06663
06664
06665 #ifndef PALM_2
06666 #ifndef HAVE_STRRCHR
06667 SOAP_FMAC1
06668 char*
06669 SOAP_FMAC2
06670 soap_strrchr(const char *s, int t)
06671 { register char *r = NULL;
06672 while (*s)
06673 if (*s++ == t)
06674 r = (char*)s - 1;
06675 return r;
06676 }
06677 #endif
06678 #endif
06679
06680
06681 #ifndef PALM_2
06682 #ifndef HAVE_STRTOL
06683 SOAP_FMAC1
06684 long
06685 SOAP_FMAC2
06686 soap_strtol(const char *s, char **t, int b)
06687 { register long n = 0;
06688 register int c;
06689 while (*s > 0 && *s <= 32)
06690 s++;
06691 if (b == 10)
06692 { short neg = 0;
06693 if (*s == '-')
06694 { s++;
06695 neg = 1;
06696 }
06697 else if (*s == '+')
06698 s++;
06699 while ((c = *s) && c >= '0' && c <= '9')
06700 { if (n >= 214748364 && (n > 214748364 || c >= '8'))
06701 break;
06702 n *= 10;
06703 n += c - '0';
06704 s++;
06705 }
06706 if (neg)
06707 n = -n;
06708 }
06709 else
06710 { while ((c = *s))
06711 { if (c >= '0' && c <= '9')
06712 c -= '0';
06713 else if (c >= 'A' && c <= 'F')
06714 c -= 'A' - 10;
06715 else if (c >= 'a' && c <= 'f')
06716 c -= 'a' - 10;
06717 if (n > 0x07FFFFFF)
06718 break;
06719 n <<= 4;
06720 n += c;
06721 s++;
06722 }
06723 }
06724 if (t)
06725 *t = (char*)s;
06726 return n;
06727 }
06728 #endif
06729 #endif
06730
06731
06732 #ifndef PALM_2
06733 #ifndef HAVE_STRTOUL
06734 SOAP_FMAC1
06735 unsigned long
06736 SOAP_FMAC2
06737 soap_strtoul(const char *s, char **t, int b)
06738 { unsigned long n = 0;
06739 register int c;
06740 while (*s > 0 && *s <= 32)
06741 s++;
06742 if (b == 10)
06743 { if (*s == '+')
06744 s++;
06745 while ((c = *s) && c >= '0' && c <= '9')
06746 { if (n >= 429496729 && (n > 429496729 || c >= '6'))
06747 break;
06748 n *= 10;
06749 n += c - '0';
06750 s++;
06751 }
06752 }
06753 else
06754 { while ((c = *s))
06755 { if (c >= '0' && c <= '9')
06756 c -= '0';
06757 else if (c >= 'A' && c <= 'F')
06758 c -= 'A' - 10;
06759 else if (c >= 'a' && c <= 'f')
06760 c -= 'a' - 10;
06761 if (n > 0x0FFFFFFF)
06762 break;
06763 n <<= 4;
06764 n += c;
06765 s++;
06766 }
06767 }
06768 if (t)
06769 *t = (char*)s;
06770 return n;
06771 }
06772 #endif
06773 #endif
06774
06775
06776 #ifndef PALM_1
06777 SOAP_FMAC1
06778 int
06779 SOAP_FMAC2
06780 soap_array_begin_out(struct soap *soap, const char *tag, int id, const char *type, const char *offset)
06781 { if (soap_element(soap, tag, id, "SOAP-ENC:Array"))
06782 return soap->error;
06783 if (soap->version == 2)
06784 { const char *s;
06785 s = soap_strrchr(type, '[');
06786 if ((size_t)(s - type) < sizeof(soap->tmpbuf))
06787 { strncpy(soap->tmpbuf, type, s - type);
06788 soap->tmpbuf[s - type] = '\0';
06789 if (type && *type && (soap_attribute(soap, "SOAP-ENC:itemType", soap->tmpbuf)))
06790 return soap->error;
06791 if (s && (soap_attribute(soap, "SOAP-ENC:arraySize", s + 1)))
06792 return soap->error;
06793 }
06794 }
06795 else
06796 { if (offset && (soap_attribute(soap, "SOAP-ENC:offset", offset)))
06797 return soap->error;
06798 if (type && *type && (soap_attribute(soap, "SOAP-ENC:arrayType", type)))
06799 return soap->error;
06800 }
06801 #ifndef WITH_LEAN
06802 if (type && *type && (soap->mode & SOAP_XML_CANONICAL))
06803 { const char *s = strchr(type, ':');
06804 if (s)
06805 soap_utilize_ns(soap, type, s - type);
06806 }
06807 #endif
06808 return soap_element_start_end_out(soap, NULL);
06809 }
06810 #endif
06811
06812
06813 #ifndef PALM_1
06814 SOAP_FMAC1
06815 int
06816 SOAP_FMAC2
06817 soap_element_start_end_out(struct soap *soap, const char *tag)
06818 { register struct soap_attribute *tp;
06819 #ifndef WITH_LEAN
06820 if (soap->mode & SOAP_XML_CANONICAL)
06821 { struct soap_nlist *np;
06822 for (tp = soap->attributes; tp; tp = tp->next)
06823 { if (tp->visible && tp->name)
06824 { const char *s = strchr(tp->name, ':');
06825 if (s)
06826 soap_utilize_ns(soap, tp->name, s - tp->name);
06827 }
06828 }
06829 for (np = soap->nlist; np; np = np->next)
06830 { if (np->index == 1 && np->ns)
06831 { sprintf(soap->tmpbuf, "xmlns:%s", np->id);
06832 soap_set_attr(soap, soap->tmpbuf, np->ns);
06833 np->index = 2;
06834 }
06835 }
06836 }
06837 #endif
06838 #ifdef WITH_DOM
06839 if ((soap->mode & SOAP_XML_DOM) && soap->dom)
06840 { register struct soap_dom_attribute **att;
06841 att = &soap->dom->atts;
06842 for (tp = soap->attributes; tp; tp = tp->next)
06843 { if (tp->visible)
06844 { *att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute));
06845 if (!*att)
06846 return soap->error = SOAP_EOM;
06847 (*att)->next = NULL;
06848 (*att)->nstr = NULL;
06849 (*att)->name = soap_strdup(soap, tp->name);
06850 (*att)->data = soap_strdup(soap, tp->value);
06851 (*att)->wide = NULL;
06852 (*att)->soap = soap;
06853 att = &(*att)->next;
06854 tp->visible = 0;
06855 }
06856 }
06857 return SOAP_OK;
06858 }
06859 #endif
06860 for (tp = soap->attributes; tp; tp = tp->next)
06861 { if (tp->visible)
06862 {
06863 #ifdef WITH_XMLNS
06864 const char *s = strchr(tp->name, ':');
06865 if (s)
06866 { size_t n = s - tp->name;
06867 if (soap->nlist && !strncmp(soap->nlist->id, tp->name, n) && !soap->nlist->id[n])
06868 s++;
06869 else
06870 s = tp->name;
06871 if (soap_send(soap, " ") || soap_send(soap, s))
06872 return soap->error;
06873 }
06874 else
06875 #endif
06876 if (soap_send(soap, " ") || soap_send(soap, tp->name))
06877 return soap->error;
06878 if (tp->visible == 2 && tp->value)
06879 if (soap_send_raw(soap, "=\"", 2)
06880 || soap_string_out(soap, tp->value, 1)
06881 || soap_send_raw(soap, "\"", 1))
06882 return soap->error;
06883 tp->visible = 0;
06884 }
06885 }
06886 if (tag)
06887 {
06888 #ifndef WITH_LEAN
06889 if (soap->mode & SOAP_XML_CANONICAL)
06890 { if (soap_send_raw(soap, ">", 1)
06891 || soap_element_end_out(soap, tag))
06892 return soap->error;
06893 return SOAP_OK;
06894 }
06895 #endif
06896 soap->level--;
06897 if (soap_send_raw(soap, "/>", 2))
06898 return soap->error;
06899 return SOAP_OK;
06900 }
06901 return soap_send_raw(soap, ">", 1);
06902 }
06903 #endif
06904
06905
06906 #ifndef PALM_1
06907 SOAP_FMAC1
06908 int
06909 SOAP_FMAC2
06910 soap_element_end_out(struct soap *soap, const char *tag)
06911 { if (*tag == '-')
06912 return SOAP_OK;
06913 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element ending tag='%s'\n", tag));
06914 #ifdef WITH_DOM
06915 if ((soap->mode & SOAP_XML_DOM) && soap->dom)
06916 { if (soap->dom->prnt)
06917 soap->dom = soap->dom->prnt;
06918 return SOAP_OK;
06919 }
06920 #endif
06921 #ifndef WITH_LEAN
06922 if (soap->mode & SOAP_XML_CANONICAL)
06923 soap_pop_ns(soap);
06924 if (soap->mode & SOAP_XML_INDENT)
06925 { if (!soap->body)
06926 { if (soap_send_raw(soap, soap_indent, soap->level < sizeof(soap_indent) ? soap->level : sizeof(soap_indent) - 1))
06927 return soap->error;
06928 }
06929 soap->body = 0;
06930 }
06931 #endif
06932 #ifdef WITH_XMLNS
06933 { const char *s = strchr(tag, ':');
06934 if (s && strncmp(tag, "SOAP-ENV", s - tag))
06935 { soap_pop_ns(soap);
06936 tag = s + 1;
06937 }
06938 }
06939 #endif
06940 if (soap_send_raw(soap, "</", 2)
06941 || soap_send(soap, tag))
06942 return soap->error;
06943 soap->level--;
06944 return soap_send_raw(soap, ">", 1);
06945 }
06946 #endif
06947
06948
06949 #ifndef PALM_1
06950 SOAP_FMAC1
06951 int
06952 SOAP_FMAC2
06953 soap_element_ref(struct soap *soap, const char *tag, int id, int href)
06954 { register int n = 0;
06955 if (soap->version == 2)
06956 n = 1;
06957 sprintf(soap->href, "#_%d", href);
06958 return soap_element_href(soap, tag, id, "href" + n, soap->href + n);
06959 }
06960 #endif
06961
06962
06963 #ifndef PALM_1
06964 SOAP_FMAC1
06965 int
06966 SOAP_FMAC2
06967 soap_element_href(struct soap *soap, const char *tag, int id, const char *ref, const char *val)
06968 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element '%s' reference %s='%s'\n", tag, ref, val));
06969 if (soap_element(soap, tag, id, NULL)
06970 || soap_attribute(soap, ref, val)
06971 || soap_element_start_end_out(soap, tag))
06972 return soap->error;
06973 return SOAP_OK;
06974 }
06975 #endif
06976
06977
06978 #ifndef PALM_1
06979 SOAP_FMAC1
06980 int
06981 SOAP_FMAC2
06982 soap_element_null(struct soap *soap, const char *tag, int id, const char *type)
06983 { struct soap_attribute *tp;
06984 for (tp = soap->attributes; tp; tp = tp->next)
06985 if (tp->visible)
06986 break;
06987 if (tp || (soap->version == 2 && soap->position > 0) || id > 0 || (soap->mode & SOAP_XML_NIL))
06988 { if (soap_element(soap, tag, id, type))
06989 return soap->error;
06990 if (soap->part != SOAP_IN_HEADER && soap->encodingStyle)
06991 if (soap_attribute(soap, "xsi:nil", "true"))
06992 return soap->error;
06993 return soap_element_start_end_out(soap, tag);
06994 }
06995 soap->null = 1;
06996 soap->position = 0;
06997 soap->mustUnderstand = 0;
06998 return SOAP_OK;
06999 }
07000 #endif
07001
07002
07003 #ifndef PALM_1
07004 SOAP_FMAC1
07005 int
07006 SOAP_FMAC2
07007 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)
07008 { if (!p || (a && !a->__ptr))
07009 { soap_element_null(soap, tag, id, type);
07010 return -1;
07011 }
07012 #ifndef WITH_NOIDREF
07013 if (soap->mode & SOAP_XML_TREE)
07014 return 0;
07015 if (id < 0)
07016 { struct soap_plist *pp;
07017 if (a)
07018 id = soap_array_pointer_lookup(soap, p, a, n, t, &pp);
07019 else
07020 id = soap_pointer_lookup(soap, p, t, &pp);
07021 if (id)
07022 { if (soap_is_embedded(soap, pp))
07023 { soap_element_ref(soap, tag, 0, id);
07024 return -1;
07025 }
07026 if (soap_is_single(soap, pp))
07027 return 0;
07028 soap_set_embedded(soap, pp);
07029 }
07030 }
07031 return id;
07032 #else
07033 return 0;
07034 #endif
07035 }
07036 #endif
07037
07038
07039 #ifndef PALM_1
07040 SOAP_FMAC1
07041 int
07042 SOAP_FMAC2
07043 soap_element_result(struct soap *soap, const char *tag)
07044 { if (soap->version == 2 && soap->encodingStyle)
07045 if (soap_element(soap, "SOAP-RPC:result", 0, NULL)
07046 || soap_attribute(soap, "xmlns:SOAP-RPC", soap_rpc)
07047 || soap_element_start_end_out(soap, NULL)
07048 || soap_string_out(soap, tag, 0)
07049 || soap_element_end_out(soap, "SOAP-RPC:result"))
07050 return soap->error;
07051 return SOAP_OK;
07052 }
07053 #endif
07054
07055
07056 #ifndef PALM_1
07057 SOAP_FMAC1
07058 void
07059 SOAP_FMAC2
07060 soap_check_result(struct soap *soap, const char *tag)
07061 { if (soap->version == 2 && soap->encodingStyle)
07062 { soap_instring(soap, ":result", NULL, NULL, 0, 2, -1, -1);
07063
07064 }
07065 }
07066 #endif
07067
07068
07069 #ifndef PALM_2
07070 SOAP_FMAC1
07071 int
07072 SOAP_FMAC2
07073 soap_attribute(struct soap *soap, const char *name, const char *value)
07074 {
07075 #ifdef WITH_DOM
07076 if ((soap->mode & SOAP_XML_DOM) && !(soap->mode & SOAP_XML_CANONICAL) && soap->dom)
07077 { register struct soap_dom_attribute *a = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute));
07078 a->next = soap->dom->atts;
07079 a->nstr = NULL;
07080 a->name = soap_strdup(soap, name);
07081 a->data = soap_strdup(soap, value);
07082 a->wide = NULL;
07083 a->soap = soap;
07084 soap->dom->atts = a;
07085 return SOAP_OK;
07086 }
07087 #endif
07088 #ifndef WITH_LEAN
07089 if (soap->mode & SOAP_XML_CANONICAL)
07090 {
07091
07092
07093
07094
07095
07096
07097
07098 if (!strncmp(name, "xmlns:", 6))
07099 soap_push_ns(soap, name + 6, value, 0);
07100 else if (soap_set_attr(soap, name, value))
07101 return soap->error;
07102 }
07103 else
07104 #endif
07105 { if (soap_send(soap, " ") || soap_send(soap, name))
07106 return soap->error;
07107 if (value)
07108 if (soap_send_raw(soap, "=\"", 2)
07109 || soap_string_out(soap, value, 1)
07110 || soap_send_raw(soap, "\"", 1))
07111 return soap->error;
07112 }
07113 return SOAP_OK;
07114 }
07115 #endif
07116
07117
07118 #ifndef PALM_2
07119 SOAP_FMAC1
07120 int
07121 SOAP_FMAC2
07122 soap_element_begin_in(struct soap *soap, const char *tag, int nillable, const char *type)
07123 { if (!soap_peek_element(soap))
07124 { if (soap->other)
07125 return soap->error = SOAP_TAG_MISMATCH;
07126 if (tag && *tag == '-')
07127 return SOAP_OK;
07128 if (!(soap->error = soap_match_tag(soap, soap->tag, tag)))
07129 { soap->peeked = 0;
07130 if (soap->body)
07131 soap->level++;
07132 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag?tag:"" ));
07133 if (!nillable && soap->null && (soap->mode & SOAP_XML_STRICT))
07134 return soap->error = SOAP_NULL;
07135 if (type && *soap->type && soap_match_tag(soap, soap->type, type))
07136 return soap->error = SOAP_TYPE;
07137 }
07138 }
07139 else if (soap->error == SOAP_NO_TAG && tag && *tag == '-')
07140 soap->error = SOAP_OK;
07141 return soap->error;
07142 }
07143 #endif
07144
07145
07146 #ifndef PALM_2
07147 SOAP_FMAC1
07148 int
07149 SOAP_FMAC2
07150 soap_element_end_in(struct soap *soap, const char *tag)
07151 { register soap_wchar c;
07152 register char *s;
07153 register const char *t;
07154 register int n = 0;
07155 if (tag && *tag == '-')
07156 return SOAP_OK;
07157 soap->level--;
07158 soap_pop_namespace(soap);
07159 #ifdef WITH_DOM
07160
07161 if ((soap->mode & SOAP_XML_DOM) && soap->dom)
07162 { if (!soap->peeked && !soap_string_in(soap, 3, -1, -1))
07163 return soap->error;
07164 if (soap->dom->prnt)
07165 soap->dom = soap->dom->prnt;
07166 }
07167 #endif
07168 if (soap->peeked)
07169 { if (soap->error == SOAP_NO_TAG)
07170 soap->error = SOAP_OK;
07171 if (*soap->tag)
07172 n++;
07173 soap->peeked = 0;
07174 }
07175 do
07176 { while (((c = soap_get(soap)) != SOAP_TT))
07177 { if ((int)c == EOF)
07178 return soap->error = SOAP_EOF;
07179 if (c == SOAP_LT)
07180 n++;
07181 else if (c == '/')
07182 { c = soap_get(soap);
07183 if (c == SOAP_GT)
07184 n--;
07185 else
07186 soap_unget(soap, c);
07187 }
07188 }
07189 } while (n--);
07190 s = soap->tag;
07191 while (soap_notblank(c = soap_get(soap)))
07192 *s++ = (char)c;
07193 *s = '\0';
07194 if ((int)c == EOF)
07195 return soap->error = SOAP_EOF;
07196 while (soap_blank(c))
07197 c = soap_get(soap);
07198 if (c != SOAP_GT)
07199 return soap->error = SOAP_SYNTAX_ERROR;
07200 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag?tag:""));
07201 if (!tag || !*tag)
07202 return SOAP_OK;
07203 if ((s = strchr(soap->tag, ':')))
07204 s++;
07205 else
07206 s = soap->tag;
07207 if ((t = strchr(tag, ':')))
07208 t++;
07209 else
07210 t = tag;
07211 if (!SOAP_STRCMP(s, t))
07212 return SOAP_OK;
07213 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element tag name does not match\n"));
07214 return soap->error = SOAP_SYNTAX_ERROR;
07215 }
07216 #endif
07217
07218
07219 #ifndef PALM_2
07220 SOAP_FMAC1
07221 const char *
07222 SOAP_FMAC2
07223 soap_attr_value(struct soap *soap, const char *name, int flag)
07224 { register struct soap_attribute *tp;
07225 for (tp = soap->attributes; tp; tp = tp->next)
07226 { if (tp->visible && !soap_match_tag(soap, tp->name, name))
07227 break;
07228 }
07229 if (tp)
07230 { if (flag == 2 && (soap->mode & SOAP_XML_STRICT))
07231 soap->error = SOAP_PROHIBITED;
07232 else
07233 return tp->value;
07234 }
07235 else if (flag == 1 && (soap->mode & SOAP_XML_STRICT))
07236 soap->error = SOAP_REQUIRED;
07237 return NULL;
07238 }
07239 #endif
07240
07241
07242 #ifndef PALM_2
07243 SOAP_FMAC1
07244 int
07245 SOAP_FMAC2
07246 soap_set_attr(struct soap *soap, const char *name, const char *value)
07247 { register struct soap_attribute *tp;
07248 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set attribute %s='%s'\n", name, value?value:""));
07249 for (tp = soap->attributes; tp; tp = tp->next)
07250 { if (!strcmp(tp->name, name))
07251 break;
07252 }
07253 if (!tp)
07254 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Allocate attribute %s\n", name));
07255 if (!(tp = (struct soap_attribute*)SOAP_MALLOC(soap, sizeof(struct soap_attribute) + strlen(name))))
07256 return soap->error = SOAP_EOM;
07257 tp->ns = NULL;
07258 #ifndef WITH_LEAN
07259 if (soap->mode & SOAP_XML_CANONICAL)
07260 { struct soap_attribute **tpp = &soap->attributes;
07261 const char *s = strchr(name, ':');
07262 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inserting attribute %s for c14n\n", name))
07263 if (!strncmp(name, "xmlns", 5))
07264 { for (; *tpp; tpp = &(*tpp)->next)
07265 if (strncmp((*tpp)->name, "xmlns", 5) || strcmp((*tpp)->name + 5, name + 5) > 0)
07266 break;
07267 }
07268 else if (!s)
07269 { for (; *tpp; tpp = &(*tpp)->next)
07270 if (strncmp((*tpp)->name, "xmlns", 5) && ((*tpp)->ns || strcmp((*tpp)->name, name) > 0))
07271 break;
07272 }
07273 else
07274 { int k;
07275 for (; *tpp; tpp = &(*tpp)->next)
07276 { if (!strncmp((*tpp)->name, "xmlns:", 6) && !strncmp((*tpp)->name + 6, name, s - name) && !(*tpp)->name[6 + s - name])
07277 { if (!tp->ns)
07278 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Canonicalization: prefix %s=%p (%s)\n", name, (*tpp)->ns, (*tpp)->ns));
07279 tp->ns = (*tpp)->ns;
07280 }
07281 }
07282 else if (strncmp((*tpp)->name, "xmlns", 5) && (*tpp)->ns && tp->ns && ((k = strcmp((*tpp)->ns, tp->ns)) > 0 || (!k && strcmp((*tpp)->name, name) > 0)))
07283 break;
07284 }
07285 }
07286 tp->next = *tpp;
07287 *tpp = tp;
07288 }
07289 else
07290 #endif
07291 { tp->next = soap->attributes;
07292 soap->attributes = tp;
07293 }
07294 strcpy(tp->name, name);
07295 tp->value = NULL;
07296 }
07297 else if (tp->visible)
07298 { return SOAP_OK;
07299 }
07300 else if (value && tp->value && tp->size <= strlen(value))
07301 { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free attribute value of %s (free %p)\n", name, tp->value));
07302 SOAP_FREE(soap, tp->value);
07303 tp->value = NULL;
07304 tp->ns = NULL;
07305 }
07306 if (value)
07307 { if (!tp->value)
07308 { tp->size = strlen(value) + 1;
07309 if (!(tp->value = (char*)SOAP_MALLOC(soap, tp->size)))
07310 return soap->error = SOAP_EOM;
07311 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Allocate attribute value of %s (%p)\n", tp->name, tp->value));
07312 }
07313 strcpy(tp->value, value);
07314 if (!strncmp(tp->name, "xmlns:", 6))
07315 tp->ns = tp->value;
07316 tp->visible = 2;
07317 #ifndef WITH_LEAN
07318 if (!strcmp(name, "wsu:Id"))
07319 { soap->part = SOAP_BEGIN_SECURITY;
07320 strncpy(soap->id, value, sizeof(soap->id));
07321 soap->id[sizeof(soap->id)-1] = '\0';
07322 }
07323 #endif
07324 }
07325 else
07326 tp->visible = 1;
07327 return SOAP_OK;
07328 }
07329 #endif
07330
07331
07332 #ifndef PALM_2
07333 SOAP_FMAC1
07334 void
07335 SOAP_FMAC2
07336 soap_clr_attr(struct soap *soap)
07337 { register struct soap_attribute *tp;
07338 #ifndef WITH_LEAN
07339 if ((soap->mode & SOAP_XML_CANONICAL))
07340 { while (soap->attributes)
07341 { tp = soap->attributes->next;
07342 SOAP_FREE(soap, soap->attributes->value);
07343 SOAP_FREE(soap, soap->attributes);
07344 soap->attributes = tp;
07345 }
07346 }
07347 else
07348 #endif
07349 { for (tp = soap->attributes; tp; tp = tp->next)
07350 tp->visible = 0;
07351 }
07352 }
07353 #endif
07354
07355
07356 #ifndef PALM_2
07357 static int
07358 soap_getattrval(struct soap *soap, char *s, size_t n, soap_wchar d)
07359 { register size_t i;
07360 for (i = 0; i < n; i++)
07361 { register soap_wchar c = soap_get(soap);
07362 switch (c)
07363 {
07364 case SOAP_TT:
07365 *s++ = '<';
07366 soap_unget(soap, '/');
07367 break;
07368 case SOAP_LT:
07369 *s++ = '<';
07370 break;
07371 case SOAP_GT:
07372 if (d == ' ')
07373 { soap_unget(soap, c);
07374 *s = '\0';
07375 return SOAP_OK;
07376 }
07377 *s++ = '>';
07378 break;
07379 case SOAP_QT:
07380 if (c == d)
07381 { *s = '\0';
07382 return SOAP_OK;
07383 }
07384 *s++ = '"';
07385 break;
07386 case SOAP_AP:
07387 if (c == d)
07388 { *s = '\0';
07389 return SOAP_OK;
07390 }
07391 *s++ = '\'';
07392 break;
07393 case '\t':
07394 case '\n':
07395 case '\r':
07396 case ' ':
07397 case '/':
07398 if (d == ' ')
07399 { soap_unget(soap, c);
07400 *s = '\0';
07401 return SOAP_OK;
07402 }
07403 default:
07404 if ((int)c == EOF)
07405 return soap->error = SOAP_EOF;
07406 *s++ = (char)c;
07407 }
07408 }
07409 return soap->error = SOAP_EOM;
07410 }
07411 #endif
07412
07413
07414 #ifdef WITH_FAST
07415 #ifndef PALM_2
07416 SOAP_FMAC1
07417 int
07418 SOAP_FMAC2
07419 soap_store_lab(struct soap *soap, const char *s, size_t n)
07420 { soap->labidx = 0;
07421 return soap_append_lab(soap, s, n);
07422 }
07423 #endif
07424 #endif
07425
07426
07427 #ifdef WITH_FAST
07428 #ifndef PALM_2
07429 SOAP_FMAC1
07430 int
07431 SOAP_FMAC2
07432 soap_append_lab(struct soap *soap, const char *s, size_t n)
07433 { if (soap->labidx + n >= soap->lablen)
07434 { register char *t = soap->labbuf;
07435 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Enlarging look-aside buffer to append data, old size=%lu", (unsigned long)soap->lablen));
07436 if (soap->lablen == 0)
07437 soap->lablen = SOAP_LABLEN;
07438 while (soap->labidx + n >= soap->lablen)
07439 soap->lablen <<= 1;
07440 DBGLOG(TEST, SOAP_MESSAGE(fdebug, ", new size=%lu\n", (unsigned long)soap->lablen));
07441 soap->labbuf = (char*)SOAP_MALLOC(soap, soap->lablen);
07442 if (!soap->labbuf)
07443 { if (t)
07444 SOAP_FREE(soap, t);
07445 return soap->error = SOAP_EOM;
07446 }
07447 if (t)
07448 { memcpy(soap->labbuf, t, soap->labidx);
07449 SOAP_FREE(soap, t);
07450 }
07451 }
07452 if (s)
07453 { memcpy(soap->labbuf + soap->labidx, s, n);
07454 soap->labidx += n;
07455 }
07456 return SOAP_OK;
07457 }
07458 #endif
07459 #endif
07460
07461
07462 #ifndef PALM_2
07463 SOAP_FMAC1
07464 int
07465 SOAP_FMAC2
07466 soap_peek_element(struct soap *soap)
07467 {
07468 #ifdef WITH_DOM
07469 register struct soap_dom_attribute **att = NULL;
07470 register char *lead = NULL;
07471 #endif
07472 register struct soap_attribute *tp;
07473 const char *t;
07474 register char *s;
07475 register soap_wchar c;
07476 register int i;
07477 if (soap->peeked)
07478 { if (!*soap->tag)
07479 return soap->error = SOAP_NO_TAG;
07480 return SOAP_OK;
07481 }
07482 soap->peeked = 1;
07483 c = soap_getutf8(soap);
07484 #ifdef WITH_DOM
07485
07486 if (soap_blank(c))
07487 { soap->labidx = 0;
07488 do
07489 { if (soap_append_lab(soap, NULL, 0))
07490 return SOAP_EOM;
07491 s = soap->labbuf + soap->labidx;
07492 i = soap->lablen - soap->labidx;
07493 soap->labidx = soap->lablen;
07494 while (soap_blank(c) && i--)
07495 { *s++ = c;
07496 c = soap_getutf8(soap);
07497 }
07498 }
07499 while (soap_blank(c));
07500 *s = '\0';
07501 lead = soap_strdup(soap, soap->labbuf);
07502 }
07503 #else
07504 while (soap_blank(c))
07505 c = soap_getutf8(soap);
07506 #endif
07507 if (c != SOAP_LT)
07508 { *soap->tag = '\0';
07509 if ((int)c == EOF)
07510 return soap->error = SOAP_EOF;
07511 soap_unget(soap, c);
07512 #ifdef WITH_DOM
07513
07514 if ((soap->mode & SOAP_XML_DOM) && soap->dom)
07515 soap->dom->tail = soap_strdup(soap, lead);
07516 #endif
07517 return soap->error = SOAP_NO_TAG;
07518 }
07519 s = soap->tag;
07520 do c = soap_get1(soap);
07521 while (soap_blank(c));
07522 i = sizeof(soap->tag);
07523 while (c != '>' && c != '/' && soap_notblank(c) && (int)c != EOF)
07524 { if (--i > 0)
07525 *s++ = (char)c;
07526 c = soap_get1(soap);
07527 }
07528 while (soap_blank(c))
07529 c = soap_get1(soap);
07530 *s = '\0';
07531 soap->id[0] = '\0';
07532 soap->href[0] = '\0';
07533 soap->type[0] = '\0';
07534 soap->arrayType[0] = '\0';
07535 soap->arraySize[0] = '\0';
07536 soap->arrayOffset[0] = '\0';
07537 soap->other = 0;
07538 soap->root = -1;
07539 soap->position = 0;
07540 soap->null = 0;
07541 soap->mustUnderstand = 0;
07542 #ifdef WITH_DOM
07543 if (soap->mode & SOAP_XML_DOM)
07544 { register struct soap_dom_element *elt;
07545 elt = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element));
07546 if (!elt)
07547 return soap->error = SOAP_EOM;
07548 elt->next = NULL;
07549 elt->nstr = NULL;
07550 elt->name = soap_strdup(soap, soap->tag);
07551 elt->prnt = soap->dom;
07552 elt->elts = NULL;
07553 elt->atts = NULL;
07554 elt->data = NULL;
07555 elt->wide = NULL;
07556 elt->type = 0;
07557 elt->node = NULL;
07558 elt->head = lead;
07559 elt->tail = NULL;
07560 elt->soap = soap;
07561 if (soap->dom)
07562 { struct soap_dom_element *p = soap->dom->elts;
07563 if (p)
07564 { while (p->next)
07565 p = p->next;
07566 p->next = elt;
07567 }
07568 else
07569 soap->dom->elts = elt;
07570 }
07571 soap->dom = elt;
07572 att = &elt->atts;
07573 }
07574 #endif
07575 for (tp = soap->attributes; tp; tp = tp->next)
07576 tp->visible = 0;
07577 while ((int)c != EOF && c != '>' && c != '/')
07578 { s = soap->tmpbuf;
07579 i = sizeof(soap->tmpbuf);
07580 while (c != '=' && c != '>' && c != '/' && soap_notblank(c) && (int)c != EOF)
07581 { if (--i > 0)
07582 *s++ = (char)c;
07583 c = soap_get1(soap);
07584 }
07585 *s = '\0';
07586 if (i == sizeof(soap->tmpbuf))
07587 return soap->error = SOAP_SYNTAX_ERROR;
07588 #ifdef WITH_DOM
07589
07590 if (att)
07591 { *att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute));
07592 if (!*att)
07593 return soap->error = SOAP_EOM;
07594 (*att)->next = NULL;
07595 (*att)->nstr = NULL;
07596 (*att)->name = soap_strdup(soap, soap->tmpbuf);
07597 (*att)->data = NULL;
07598 (*att)->wide = NULL;
07599 (*att)->soap = soap;
07600 }
07601 #endif
07602 if (!strncmp(soap->tmpbuf, "xmlns", 5))
07603 { if (soap->tmpbuf[5] == ':')
07604 { soap->tmpbuf[5] = '\0';
07605 t = soap->tmpbuf + 6;
07606 }
07607 else if (soap->tmpbuf[5])
07608 t = NULL;
07609 else
07610 t = SOAP_STR_EOS;
07611 }
07612 else
07613 t = NULL;
07614 for (tp = soap->attributes; tp; tp = tp->next)
07615 { if (!SOAP_STRCMP(tp->name, soap->tmpbuf))
07616 break;
07617 }
07618 if (!tp)
07619 { tp = (struct soap_attribute*)SOAP_MALLOC(soap, sizeof(struct soap_attribute) + strlen(soap->tmpbuf));
07620 if (!tp)
07621 return soap->error = SOAP_EOM;
07622 strcpy(tp->name, soap->tmpbuf);
07623 tp->value = NULL;
07624 tp->size = 0;
07625 tp->next = soap->attributes;
07626 soap->attributes = tp;
07627 }
07628 while (soap_blank(c))
07629 c = soap_get1(soap);
07630 if (c == '=')
07631 { do c = soap_getutf8(soap);
07632 while (soap_blank(c));
07633 if (c != SOAP_QT && c != SOAP_AP)
07634 { soap_unget(soap, c);
07635 c = ' ';
07636 }
07637 if (soap_getattrval(soap, tp->value, tp->size, c))
07638 {
07639 #ifdef WITH_FAST
07640 if (soap->error != SOAP_EOM)
07641 return soap->error;
07642 soap->error = SOAP_OK;
07643 if (soap_store_lab(soap, tp->value, tp->size))
07644 return soap->error;
07645 if (tp->value)
07646 SOAP_FREE(soap, tp->value);
07647 for (;;)
07648 { if (soap_getattrval(soap, soap->labbuf + soap->labidx, soap->lablen - soap->labidx, c))
07649 { if (soap->error != SOAP_EOM)
07650 return soap->error;
07651 soap->error = SOAP_OK;
07652 soap->labidx = soap->lablen;
07653 if (soap_append_lab(soap, NULL, 0))
07654 return soap->error;
07655 }
07656 else
07657 break;
07658 }
07659 if (soap->labidx)
07660 tp->size = soap->lablen;
07661 else
07662 { tp->size = strlen(soap->labbuf) + 1;
07663 if (tp->size < SOAP_LABLEN)
07664 tp->size = SOAP_LABLEN;
07665 }
07666 if (!(tp->value = (char*)SOAP_MALLOC(soap, tp->size)))
07667 return soap->error = SOAP_EOM;
07668 strcpy(tp->value, soap->labbuf);
07669 #else
07670 size_t n;
07671 if (soap->error != SOAP_EOM)
07672 return soap->error;
07673 soap->error = SOAP_OK;
07674 if (soap_new_block(soap))
07675 return soap->error;
07676 for (;;)
07677 { if (!(s = (char*)soap_push_block(soap, SOAP_BLKLEN)))
07678 return soap->error;
07679 if (soap_getattrval(soap, s, SOAP_BLKLEN, c))
07680 { if (soap->error != SOAP_EOM)
07681 return soap->error;
07682 soap->error = SOAP_OK;
07683 }
07684 else
07685 break;
07686 }
07687 n = tp->size + soap->blist->size;
07688 if (!(s = (char*)SOAP_MALLOC(soap, n)))
07689 return soap->error = SOAP_EOM;
07690 if (tp->value)
07691 { memcpy(s, tp->value, tp->size);
07692 SOAP_FREE(soap, tp->value);
07693 }
07694 soap_save_block(soap, s + tp->size, 0);
07695 tp->value = s;
07696 tp->size = n;
07697 #endif
07698 }
07699 do c = soap_get1(soap);
07700 while (soap_blank(c));
07701 tp->visible = 2;
07702 #ifdef WITH_DOM
07703 if (att)
07704 (*att)->data = soap_strdup(soap, tp->value);
07705 #endif
07706 }
07707 else
07708 tp->visible = 1;
07709 #ifdef WITH_DOM
07710 if (att)
07711 att = &(*att)->next;
07712 #endif
07713 if (t && tp->value)
07714 { if (soap_push_namespace(soap, t, tp->value))
07715 return soap->error;
07716 tp->visible = 0;
07717 }
07718 }
07719 #ifdef WITH_DOM
07720 if (att)
07721 { soap->dom->nstr = soap_current_namespace(soap, soap->tag);
07722 for (att = &soap->dom->atts; *att; att = &(*att)->next)
07723 (*att)->nstr = soap_current_namespace(soap, (*att)->name);
07724 }
07725 #endif
07726 if ((int)c == EOF)
07727 return soap->error = SOAP_EOF;
07728 if (!(soap->body = (c != '/')))
07729 do c = soap_get1(soap);
07730 while (soap_blank(c));
07731 #ifdef WITH_DOM
07732 if (soap->mode & SOAP_XML_DOM)
07733 { if (!soap->body && soap->dom->prnt)
07734 soap->dom = soap->dom->prnt;
07735 }
07736 #endif
07737 for (tp = soap->attributes; tp; tp = tp->next)
07738 { if (tp->visible && tp->value)
07739 { if (!strcmp(tp->name, "id"))
07740 { *soap->id = '#';
07741 strncpy(soap->id + 1, tp->value, sizeof(soap->id) - 2);
07742 soap->id[sizeof(soap->id)-1] = '\0';
07743 }
07744 else if (!strcmp(tp->name, "href"))
07745 { strncpy(soap->href, tp->value, sizeof(soap->href) - 1);
07746 soap->href[sizeof(soap->href)-1] = '\0';
07747 }
07748 else if ((soap->version == 2 || (soap->mode & SOAP_XML_GRAPH)) && !strcmp(tp->name, "ref"))
07749 { *soap->href = '#';
07750 strncpy(soap->href + 1, tp->value, sizeof(soap->href) - 2);
07751 soap->href[sizeof(soap->href)-1] = '\0';
07752 }
07753 else if (!soap_match_tag(soap, tp->name, "xsi:type"))
07754 { strncpy(soap->type, tp->value, sizeof(soap->type) - 1);
07755 soap->type[sizeof(soap->type)-1] = '\0';
07756 }
07757 else if (soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENC:arrayType"))
07758 { s = soap_strrchr(tp->value, '[');
07759 if (s && (size_t)(s - tp->value) < sizeof(soap->arrayType))
07760 { strncpy(soap->arrayType, tp->value, s - tp->value);
07761 soap->arrayType[s - tp->value] = '\0';
07762 strncpy(soap->arraySize, s, sizeof(soap->arraySize) - 1);
07763 }
07764 else
07765 strncpy(soap->arrayType, tp->value, sizeof(soap->arrayType) - 1);
07766 soap->arraySize[sizeof(soap->arrayType)-1] = '\0';
07767 soap->arrayType[sizeof(soap->arrayType)-1] = '\0';
07768 }
07769 else if (soap->version == 2 && !soap_match_tag(soap, tp->name, "SOAP-ENC:itemType"))
07770 strncpy(soap->arrayType, tp->value, sizeof(soap->arrayType) - 1);
07771 else if (soap->version == 2 && !soap_match_tag(soap, tp->name, "SOAP-ENC:arraySize"))
07772 strncpy(soap->arraySize, tp->value, sizeof(soap->arraySize) - 1);
07773 else if (soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENC:offset"))
07774 strncpy(soap->arrayOffset, tp->value, sizeof(soap->arrayOffset));
07775 else if (soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENC:position"))
07776 soap->position = soap_getposition(tp->value, soap->positions);
07777 else if (soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENC:root"))
07778 soap->root = ((!strcmp(tp->value, "1") || !strcmp(tp->value, "true")));
07779 else if ((soap->version == 1 && !soap_match_tag(soap, tp->name, "SOAP-ENV:actor"))
07780 || (soap->version == 2 && !soap_match_tag(soap, tp->name, "SOAP-ENV:role")))
07781 { if ((!soap->actor || strcmp(soap->actor, tp->value))
07782 && strcmp(tp->value, "http://schemas.xmlsoap.org/soap/actor/next")
07783 && strcmp(tp->value, "http://www.w3.org/2003/05/soap-envelope/role/next"))
07784 soap->other = 1;
07785 }
07786 else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:mustUnderstand")
07787 && (!strcmp(tp->value, "1") || !strcmp(tp->value, "true")))
07788 soap->mustUnderstand = 1;
07789 else if ((!soap_match_tag(soap, tp->name, "xsi:null")
07790 || !soap_match_tag(soap, tp->name, "xsi:nil"))
07791 && (!strcmp(tp->value, "1")
07792 || !strcmp(tp->value, "true")))
07793 soap->null = 1;
07794 }
07795 }
07796 return soap->error = SOAP_OK;
07797 }
07798 #endif
07799
07800
07801 #ifndef PALM_2
07802 SOAP_FMAC1
07803 void
07804 SOAP_FMAC2
07805 soap_retry(struct soap *soap)
07806 { soap->error = SOAP_OK;
07807 soap_revert(soap);
07808 }
07809 #endif
07810
07811
07812 #ifndef PALM_2
07813 SOAP_FMAC1
07814 void
07815 SOAP_FMAC2
07816 soap_revert(struct soap *soap)
07817 { if (!soap->peeked)
07818 { soap->peeked = 1;
07819 if (soap->body)
07820 soap->level--;
07821 }
07822 DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Reverting last element (level=%u)\n", soap->level));
07823 }
07824 #endif
07825
07826
07827 #ifndef PALM_2
07828 SOAP_FMAC1
07829 int
07830 SOAP_FMAC2
07831 soap_string_out(struct soap *soap, const char *s, int flag)
07832 { register const char *t;
07833 register soap_wchar c;
07834 register soap_wchar mask = 0xFFFFFF80UL;
07835 #ifdef WITH_DOM
07836 if ((soap->mode & SOAP_XML_DOM) && soap->dom)
07837 { soap->dom->data = soap_strdup(soap, s);
07838 return SOAP_OK;
07839 }
07840 #endif
07841 if (soap->mode & SOAP_C_UTFSTRING)
07842 mask = 0;
07843 t = s;
07844 while ((c = *t++))
07845 { switch (c)
07846 {
07847 case 9:
07848 if (flag)
07849 { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "	", 5))
07850 return soap->error;
07851 s = t;
07852 }
07853 break;
07854 case 10:
07855 if (flag || !(soap->mode & SOAP_XML_CANONICAL))
07856 { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "
", 5))
07857 return soap->error;
07858 s = t;
07859 }
07860 break;
07861 case 13:
07862 if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "
", 5))
07863 return soap->error;
07864 s = t;
07865 break;
07866 case '&':
07867 if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&", 5))
07868 return soap->error;
07869 s = t;
07870 break;
07871 case '<':
07872 if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "<", 4))
07873 return soap->error;
07874 s = t;
07875 break;
07876 case '>':
07877 if (!flag)
07878 { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, ">", 4))
07879 return soap->error;
07880 s = t;
07881 }
07882 break;
07883 case '"':
07884 if (flag)
07885 { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, """, 6))
07886 return soap->error;
07887 s = t;
07888 }
07889 break;
07890 default:
07891 #ifndef WITH_LEANER
07892 #ifdef HAVE_MBTOWC
07893 if (soap->mode & SOAP_C_MBSTRING)
07894 { wchar_t wc;
07895 register int m = mbtowc(&wc, t - 1, MB_CUR_MAX);
07896 if (m > 0 && wc != c)
07897 { if (soap_send_raw(soap, s, t - s - 1) || soap_pututf8(soap, wc))
07898 return soap->error;
07899 s = t += m - 1;
07900 continue;
07901 }
07902 }
07903 #endif
07904 #endif
07905 if (c & mask)
07906 { if (soap_send_raw(soap, s, t - s - 1) || soap_pututf8(soap, (unsigned char)c))
07907 return soap->error;
07908 s = t;
07909 }
07910 }
07911 }
07912 return soap_send_raw(soap, s, t - s - 1);
07913 }
07914 #endif
07915
07916
07917 #ifndef PALM_2
07918 SOAP_FMAC1
07919 char *
07920 SOAP_FMAC2
07921 soap_string_in(struct soap *soap, int flag, long minlen, long maxlen)
07922 { register char *s;
07923 char *t = NULL;
07924 register size_t i;
07925 register long l = 0;
07926 register int n = 0;
07927 register int m = 0;
07928 register soap_wchar c;
07929 #if !defined(WITH_LEANER) && defined(HAVE_WCTOMB)
07930 char buf[MB_LEN_MAX > 8 ? MB_LEN_MAX : 8];
07931 #else
07932 char buf[8];
07933 #endif
07934 DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Reading string content\n"));
07935 if (soap->peeked)
07936 { if (!soap->body)
07937 return NULL;
07938 if (*soap->tag)
07939 { n = 1;
07940 soap->peeked = 0;
07941 #ifndef WITH_LEAN
07942 t = soap->tmpbuf;
07943 t[0] = '<';
07944 strncpy(t + 1, soap->tag, sizeof(soap->tmpbuf) - 1);
07945 strncat(t, ">", sizeof(soap->tmpbuf));
07946 m = strlen(soap->tag) + 2;
07947 #endif
07948 }
07949 }
07950 #ifdef WITH_CDATA
07951 if (!flag)
07952 { register int state = 0;
07953 #ifdef WITH_FAST
07954 soap->labidx = 0;
07955 #else
07956 if (soap_new_block(soap))
07957 return NULL;
07958 #endif
07959 for (;;)
07960 {
07961 #ifdef WITH_FAST
07962 register size_t k;
07963 if (soap_append_lab(soap, NULL, 0))
07964 return NULL;
07965 s = soap->labbuf + soap->labidx;
07966 k = soap->lablen - soap->labidx;
07967 soap->labidx = soap->lablen;
07968 #else
07969 register size_t k = SOAP_BLKLEN;
07970 if (!(s = (char*)soap_push_block(soap, k)))
07971 return NULL;
07972 #endif
07973 for (i = 0; i < k; i++)
07974 { if (m > 0)
07975 { *s++ = *t++;
07976 m--;
07977 continue;
07978 }
07979 c = soap_getchar(soap);
07980 if ((int)c == EOF)
07981 goto end;
07982 if (c >= 0x80 && !(soap->mode & SOAP_ENC_LATIN))
07983 { soap_unget(soap, c);
07984 c = soap_getutf8(soap);
07985 if (soap->mode & SOAP_C_UTFSTRING)
07986 { if ((c & 0x80000000) && c >= -0x7FFFFF80 && c < SOAP_AP)
07987 { c &= 0x7FFFFFFF;
07988 t = buf;
07989 if (c < 0x0800)
07990 *t++ = (char)(0xC0 | ((c >> 6) & 0x1F));
07991 else
07992 { if (c < 0x010000)
07993 *t++ = (char)(0xE0 | ((c >> 12) & 0x0F));
07994 else
07995 { if (c < 0x200000)
07996 *t++ = (char)(0xF0 | ((c >> 18) & 0x07));
07997 else
07998 { if (c < 0x04000000)
07999 *t++ = (char)(0xF8 | ((c >> 24) & 0x03));
08000 else
08001 { *t++ = (char)(0xFC | ((c >> 30) & 0x01));
08002 *t++ = (char)(0x80 | ((c >> 24) & 0x3F));
08003 }
08004 *t++ = (char)(0x80 | ((c >> 18) & 0x3F));
08005 }
08006 *t++ = (char)(0x80 | ((c >> 12) & 0x3F));
08007 }
08008 *t++ = (char)(0x80 | ((c >> 6) & 0x3F));
08009 }
08010 *t++ = (char)(0x80 | (c & 0x3F));
08011 m = (int)(t - buf) - 1;
08012 t = buf;
08013 *s++ = *t++;
08014 continue;
08015 }
08016 }
08017 }
08018 switch (state)
08019 { case 1:
08020 if (c == ']')
08021 state = 4;
08022 *s++ = c;
08023 continue;
08024 case 2:
08025 if (c == '-')
08026 state = 6;
08027 *s++ = c;
08028 continue;
08029 case 3:
08030 if (c == '?')
08031 state = 8;
08032 *s++ = c;
08033 continue;
08034
08035 case 4:
08036 if (c == ']')
08037 state = 5;
08038 else
08039 state = 1;
08040 *s++ = c;
08041 continue;
08042 case 5:
08043 if (c == '>')
08044 state = 0;
08045 else
08046 state = 1;
08047 *s++ = c;
08048 continue;
08049
08050 case 6:
08051 if (c == '-')
08052 state = 7;
08053 else
08054 state = 2;
08055 *s++ = c;
08056 continue;
08057 case 7:
08058 if (c == '>')
08059 state = 0;
08060 else
08061 state = 2;
08062 *s++ = c;
08063 continue;
08064
08065 case 8:
08066 if (c == '>')
08067 state = 0;
08068 else
08069 state = 3;
08070 *s++ = c;
08071 continue;
08072 }
08073 switch (c)
08074 {
08075 case '/':
08076 if (n > 0)
08077 { c = soap_getchar(soap);
08078 if (c == '>')
08079 n--;
08080 soap_unget(soap, c);
08081 }
08082 *s++ = '/';
08083 break;
08084 case '<':
08085 c = soap_getchar(soap);
08086 if (c == '/')
08087 { if (n == 0)
08088 { c = SOAP_TT;
08089 goto end;
08090 }
08091 n--;
08092 }
08093 else if (c == '!')
08094 { c = soap_getchar(soap);
08095 if (c == '[')
08096 { do c = soap_getchar(soap);
08097 while ((int)c != EOF && c != '[');
08098 if ((int)c == EOF)
08099 goto end;
08100 t = (char*)"![CDATA[";
08101 m = 8;
08102 state = 1;
08103 }
08104 else if (c == '-')
08105 { if ((c = soap_getchar(soap)) == '-')
08106 state = 2;
08107 t = (char*)"!-";
08108 m = 2;
08109 soap_unget(soap, c);
08110 }
08111 else
08112 { t = (char*)"!";
08113 m = 1;
08114 soap_unget(soap, c);
08115 }
08116 *s++ = '<';
08117 break;
08118 }
08119 else if (c == '?')
08120 state = 3;
08121 else
08122 n++;
08123 soap_unget(soap, c);
08124 *s++ = '<';
08125 break;
08126 case '>':
08127 *s++ = '>';
08128 break;
08129 case '"':
08130 *s++ = '"';
08131 break;
08132 default:
08133 #ifndef WITH_LEANER
08134 #ifdef HAVE_WCTOMB
08135 if (soap->mode & SOAP_C_MBSTRING)
08136 { m = wctomb(buf, c & 0x7FFFFFFF);
08137 if (m >= 1 && m <= (int)MB_CUR_MAX)
08138 { t = buf;
08139 *s++ = *t++;
08140 m--;
08141 }
08142 else
08143 { *s++ = SOAP_UNKNOWN_CHAR;
08144 m = 0;
08145 }
08146 }
08147 else
08148 #endif
08149 #endif
08150 *s++ = (char)(c & 0xFF);
08151 }
08152 l++;
08153 if ((soap->mode & SOAP_XML_STRICT) && maxlen >= 0 && l > maxlen)
08154 { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen));
08155 soap->error = SOAP_LENGTH;
08156 return NULL;
08157 }
08158 }
08159 }
08160 }
08161 #endif
08162 #ifdef WITH_FAST
08163 soap->labidx = 0;
08164 #else
08165 if (soap_new_block(soap))
08166 return NULL;
08167 #endif
08168 for (;;)
08169 {
08170 #ifdef WITH_FAST
08171 register size_t k;
08172 if (soap_append_lab(soap, NULL, 0))
08173 return NULL;
08174 s = soap->labbuf + soap->labidx;
08175 k = soap->lablen - soap->labidx;
08176 soap->labidx = soap->lablen;
08177 #else
08178 register size_t k = SOAP_BLKLEN;
08179 if (!(s = (char*)soap_push_block(soap, k)))
08180 return NULL;
08181 #endif
08182 for (i = 0; i < k; i++)
08183 { if (m > 0)
08184 { *s++ = *t++;
08185 m--;
08186 continue;
08187 }
08188 if (soap->mode & SOAP_C_UTFSTRING)
08189 { if (((c = soap_get(soap)) & 0x80000000) && c >= -0x7FFFFF80 && c < SOAP_AP)
08190 { c &= 0x7FFFFFFF;
08191 t = buf;
08192 if (c < 0x0800)
08193 *t++ = (char)(0xC0 | ((c >> 6) & 0x1F));
08194 else
08195 { if (c < 0x010000)
08196 *t++ = (char)(0xE0 | ((c >> 12) & 0x0F));
08197 else
08198 { if (c < 0x200000)
08199 *t++ = (char)(0xF0 | ((c >> 18) & 0x07));
08200 else
08201 { if (c < 0x04000000)
08202 *t++ = (char)(0xF8 | ((c >> 24) & 0x03));
08203 else
08204 { *t++ = (char)(0xFC | ((c >> 30) & 0x01));
08205 *t++ = (char)(0x80 | ((c >> 24) & 0x3F));
08206 }
08207 *t++ = (char)(0x80 | ((c >> 18) & 0x3F));
08208 }
08209 *t++ = (char)(0x80 | ((c >> 12) & 0x3F));
08210 }
08211 *t++ = (char)(0x80 | ((c >> 6) & 0x3F));
08212 }
08213 *t++ = (char)(0x80 | (c & 0x3F));
08214 m = (int)(t - buf) - 1;
08215 t = buf;
08216 *s++ = *t++;
08217 continue;
08218 }
08219 }
08220 else
08221 c = soap_getutf8(soap);
08222 switch (c)
08223 {
08224 case SOAP_TT:
08225 if (n == 0)
08226 goto end;
08227 n--;
08228 *s++ = '<';
08229 t = (char*)"/";
08230 m = 1;
08231 break;
08232 case SOAP_LT:
08233 n++;
08234 *s++ = '<';
08235 break;
08236 case SOAP_GT:
08237 *s++ = '>';
08238 break;
08239 case SOAP_QT:
08240 *s++ = '"';
08241 break;
08242 case SOAP_AP:
08243 *s++ = '\'';
08244 break;
08245 case '/':
08246 if (n > 0)
08247 { c = soap_get(soap);
08248 if (c == SOAP_GT)
08249 n--;
08250 soap_unget(soap, c);
08251 }
08252 *s++ = '/';
08253 break;
08254 case '<' | 0x80000000:
08255 if (flag)
08256 *s++ = '<';
08257 else
08258 { *s++ = '&';
08259 t = (char*)"lt;";
08260 m = 3;
08261 }
08262 break;
08263 case '>' | 0x80000000:
08264 if (flag)
08265 *s++ = '>';
08266 else
08267 { *s++ = '&';
08268 t = (char*)"gt;";
08269 m = 3;
08270 }
08271 break;
08272 case '&' | 0x80000000:
08273 if (flag)
08274 *s++ = '&';
08275 else
08276 { *s++ = '&';
08277 t = (char*)"amp;";
08278 m = 4;
08279 }
08280 break;
08281 case '"' | 0x80000000:
08282 if (flag)
08283 *s++ = '"';
08284 else
08285 { *s++ = '&';
08286 t = (char*)"quot;";
08287 m = 5;
08288 }
08289 break;
08290 case '\'' | 0x80000000:
08291 if (flag)
08292 *s++ = '\'';
08293 else
08294 { *s++ = '&';
08295 t = (char*)"apos;";
08296 m = 5;
08297 }
08298 break;
08299 default:
08300 if ((int)c == EOF)
08301 goto end;
08302 #ifndef WITH_LEANER
08303 #ifdef HAVE_WCTOMB
08304 if (soap->mode & SOAP_C_MBSTRING)
08305 { m = wctomb(buf, c & 0x7FFFFFFF);
08306 if (m >= 1 && m <= (int)MB_CUR_MAX)
08307 { t = buf;
08308 *s++ = *t++;
08309 m--;
08310 }
08311 else
08312 { *s++ = SOAP_UNKNOWN_CHAR;
08313 m = 0;
08314 }
08315 }
08316 else
08317 #endif
08318 #endif
08319 *s++ = (char)(c & 0xFF);
08320 }
08321 l++;
08322 if ((soap->mode & SOAP_XML_STRICT) && maxlen >= 0 && l > maxlen)
08323 { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen));
08324 soap->error = SOAP_LENGTH;
08325 return NULL;
08326 }
08327 }
08328 }
08329 end:
08330 soap_unget(soap, c);
08331 *s = '\0';
08332 #ifdef WITH_FAST
08333 t = soap_strdup(soap, soap->labbuf);
08334 #else
08335 soap_size_block(soap, i+1);
08336 t = soap_save_block(soap, NULL, 0);
08337 #endif
08338 if ((soap->mode & SOAP_XML_STRICT) && l < minlen)
08339 { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too short: %ld chars, minlen=%ld\n", l, minlen));
08340 soap->error = SOAP_LENGTH;
08341 return NULL;
08342 }
08343 #ifdef WITH_DOM
08344 if ((soap->mode & SOAP_XML_DOM) && soap->dom)
08345 { if (flag == 3)
08346 soap->dom->tail = t;
08347 else
08348 soap->dom->data = t;
08349 }
08350 #endif
08351 if (flag == 2)
08352 if (soap_s2QName(soap, t, &t))
08353 return NULL;
08354 return t;
08355 }
08356 #endif
08357
08358
08359 #ifndef WITH_LEANER
08360 #ifndef PALM_2
08361 SOAP_FMAC1
08362 int
08363 SOAP_FMAC2
08364 soap_wstring_out(struct soap *soap, const wchar_t *s, int flag)
08365 { const char *t;
08366 char tmp;
08367 register soap_wchar c;
08368 #ifdef WITH_DOM
08369 if ((soap->mode & SOAP_XML_DOM) && soap->dom)
08370 { wchar_t *r = (wchar_t*)s;
08371 int n = 1;
08372 while (*r++)
08373 n++;
08374 soap->dom->wide = r = (wchar_t*)soap_malloc(soap, n * sizeof(wchar_t));
08375 while (n--)
08376 *r++ = *s++;
08377 return SOAP_OK;
08378 }
08379 #endif
08380 while ((c = *s++))
08381 { switch (c)
08382 {
08383 case 9:
08384 if (flag)
08385 t = "	";
08386 else
08387 t = "\t";
08388 break;
08389 case 10:
08390 if (flag || !(soap->mode & SOAP_XML_CANONICAL))
08391 t = "
";
08392 else
08393 t = "\n";
08394 break;
08395 case 13:
08396 t = "
";
08397 break;
08398 case '&':
08399 t = "&";
08400 break;
08401 case '<':
08402 t = "<";
08403 break;
08404 case '>':
08405 if (flag)
08406 t = ">";
08407 else
08408 t = ">";
08409 break;
08410 case '"':
08411 if (flag)
08412 t = """;
08413 else
08414 t = "\"";
08415 break;
08416 default:
08417 if (c > 0 && c < 0x80)
08418 { tmp = (char)c;
08419 if (soap_send_raw(soap, &tmp, 1))
08420 return soap->error;
08421 }
08422 else if (soap_pututf8(soap, (unsigned long)c))
08423 return soap->error;
08424 continue;
08425 }
08426 if (soap_send(soap, t))
08427 return soap->error;
08428 }
08429 return SOAP_OK;
08430 }
08431 #endif
08432 #endif
08433
08434
08435 #ifndef WITH_LEANER
08436 #ifndef PALM_2
08437 SOAP_FMAC1
08438 wchar_t *
08439 SOAP_FMAC2
08440 soap_wstring_in(struct soap *soap, int flag, long minlen, long maxlen)
08441 { wchar_t *s;
08442 register int i, n = 0;
08443 register long l = 0;
08444 register soap_wchar c;
08445 const char *t = NULL;
08446 DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Reading wide string content\n"));
08447 if (soap->peeked)
08448 { if (!soap->body)
08449 return NULL;
08450 if (*soap->tag)
08451 { n = 1;
08452 soap->peeked = 0;
08453 }
08454 }
08455 if (soap_new_block(soap))
08456 return NULL;
08457 for (;;)
08458 { if (!(s = (wchar_t*)soap_push_block(soap, sizeof(wchar_t)*SOAP_BLKLEN)))
08459 return NULL;
08460 for (i = 0; i < SOAP_BLKLEN; i++)
08461 { if (t)
08462 { *s++ = (wchar_t)*t++;
08463 if (!*t)
08464 t = NULL;
08465 continue;
08466 }
08467 c = soap_getutf8(soap);
08468 switch (c)
08469 {
08470 case SOAP_TT:
08471 if (n == 0)
08472 goto end;
08473 n--;
08474 *s++ = '<';
08475 soap_unget(soap, '/');
08476 break;
08477 case SOAP_LT:
08478 n++;
08479 *s++ = '<';
08480 break;
08481 case SOAP_GT:
08482 *s++ = '>';
08483 break;
08484 case SOAP_QT:
08485 *s++ = '"';
08486 break;
08487 case SOAP_AP:
08488 *s++ = '\'';
08489 break;
08490 case '/':
08491 if (n > 0)
08492 { c = soap_getutf8(soap);
08493 if (c == SOAP_GT)
08494 n--;
08495 soap_unget(soap, c);
08496 }
08497 *s++ = '/';
08498 break;
08499 case '<':
08500 if (flag)
08501 *s++ = (soap_wchar)'<';
08502 else
08503 { *s++ = (soap_wchar)'&';
08504 t = "lt;";
08505 }
08506 break;
08507 case '>':
08508 if (flag)
08509 *s++ = (soap_wchar)'>';
08510 else
08511 { *s++ = (soap_wchar)'&';
08512 t = "gt;";
08513 }
08514 break;
08515 case '"':
08516 if (flag)
08517 *s++ = (soap_wchar)'"';
08518 else
08519 { *s++ = (soap_wchar)'&';
08520 t = "quot;";
08521 }
08522 break;
08523 default:
08524 if ((int)c == EOF)
08525 goto end;
08526 *s++ = (wchar_t)c & 0x7FFFFFFF;
08527 }
08528 l++;
08529 if ((soap->mode & SOAP_XML_STRICT) && maxlen >= 0 && l > maxlen)
08530 { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen));
08531 soap->error = SOAP_LENGTH;
08532 return NULL;
08533 }
08534 }
08535 }
08536 end:
08537 soap_unget(soap, c);
08538 *s = '\0';
08539 soap_size_block(soap, sizeof(wchar_t) * (i + 1));
08540 if ((soap->mode & SOAP_XML_STRICT) && l < minlen)
08541 { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too short: %ld chars, minlen=%ld\n", l, minlen));
08542 soap->error = SOAP_LENGTH;
08543 return NULL;
08544 }
08545 s = (wchar_t*)soap_save_block(soap, NULL, 0);
08546 #ifdef WITH_DOM
08547 if ((soap->mode & SOAP_XML_DOM) && soap->dom)
08548 soap->dom->wide = s;
08549 #endif
08550 return s;
08551 }
08552 #endif
08553 #endif
08554
08555
08556 #ifndef PALM_2
08557 SOAP_FMAC1
08558 const char*
08559 SOAP_FMAC2
08560 soap_int2s(struct soap *soap, int n)
08561 { return soap_long2s(soap, (long)n);
08562 }
08563 #endif
08564
08565
08566 #ifndef PALM_2
08567 SOAP_FMAC1
08568 int
08569 SOAP_FMAC2
08570 soap_outint(struct soap *soap, const char *tag, int id, const int *p, const char *type, int n)
08571 { if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
08572 || soap_string_out(soap, soap_long2s(soap, (long)*p), 0))
08573 return soap->error;
08574 return soap_element_end_out(soap, tag);
08575 }
08576 #endif
08577
08578
08579 #ifndef PALM_2
08580 SOAP_FMAC1
08581 int
08582 SOAP_FMAC2
08583 soap_s2int(struct soap *soap, const char *s, int *p)
08584 { if (s)
08585 { char *r;
08586 #ifndef WITH_NOIO
08587 #ifndef WITH_LEAN
08588 soap_reset_errno;
08589 #endif
08590 #endif
08591 *p = (int)soap_strtol(s, &r, 10);
08592 if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
08593 #ifndef WITH_NOIO
08594 #ifndef WITH_LEAN
08595 || soap_errno == SOAP_ERANGE
08596 #endif
08597 #endif
08598 )
08599 soap->error = SOAP_TYPE;
08600 }
08601 return soap->error;
08602 }
08603 #endif
08604
08605
08606 #ifndef PALM_2
08607 SOAP_FMAC1
08608 int *
08609 SOAP_FMAC2
08610 soap_inint(struct soap *soap, const char *tag, int *p, const char *type, int t)
08611 { if (soap_element_begin_in(soap, tag, 0, NULL))
08612 return NULL;
08613 #ifndef WITH_LEAN
08614 if (*soap->type
08615 && soap_match_tag(soap, soap->type, type)
08616 && soap_match_tag(soap, soap->type, ":int")
08617 && soap_match_tag(soap, soap->type, ":short")
08618 && soap_match_tag(soap, soap->type, ":byte"))
08619 { soap->error = SOAP_TYPE;
08620 soap_revert(soap);
08621 return NULL;
08622 }
08623 #endif
08624 p = (int*)soap_id_enter(soap, soap->id, p, t, sizeof(int), 0, NULL, NULL, NULL);
08625 if (*soap->href)
08626 p = (int*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(int), 0, NULL);
08627 else if (p)
08628 { if (soap_s2int(soap, soap_value(soap), p))
08629 return NULL;
08630 }
08631 if (soap->body && soap_element_end_in(soap, tag))
08632 return NULL;
08633 return p;
08634 }
08635 #endif
08636
08637
08638 #ifndef PALM_2
08639 SOAP_FMAC1
08640 const char*
08641 SOAP_FMAC2
08642 soap_long2s(struct soap *soap, long n)
08643 { sprintf(soap->tmpbuf, "%ld", n);
08644 return soap->tmpbuf;
08645 }
08646 #endif
08647
08648
08649 #ifndef PALM_2
08650 SOAP_FMAC1
08651 int
08652 SOAP_FMAC2
08653 soap_outlong(struct soap *soap, const char *tag, int id, const long *p, const char *type, int n)
08654 { if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
08655 || soap_string_out(soap, soap_long2s(soap, *p), 0))
08656 return soap->error;
08657 return soap_element_end_out(soap, tag);
08658 }
08659 #endif
08660
08661
08662 #ifndef PALM_2
08663 SOAP_FMAC1
08664 int
08665 SOAP_FMAC2
08666 soap_s2long(struct soap *soap, const char *s, long *p)
08667 { if (s)
08668 { char *r;
08669 #ifndef WITH_NOIO
08670 #ifndef WITH_LEAN
08671 soap_reset_errno;
08672 #endif
08673 #endif
08674 *p = soap_strtol(s, &r, 10);
08675 if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
08676 #ifndef WITH_NOIO
08677 #ifndef WITH_LEAN
08678 || soap_errno == SOAP_ERANGE
08679 #endif
08680 #endif
08681 )
08682 soap->error = SOAP_TYPE;
08683 }
08684 return soap->error;
08685 }
08686 #endif
08687
08688
08689 #ifndef PALM_2
08690 SOAP_FMAC1
08691 long *
08692 SOAP_FMAC2
08693 soap_inlong(struct soap *soap, const char *tag, long *p, const char *type, int t)
08694 { if (soap_element_begin_in(soap, tag, 0, NULL))
08695 return NULL;
08696 #ifndef WITH_LEAN
08697 if (*soap->type
08698 && soap_match_tag(soap, soap->type, type)
08699 && soap_match_tag(soap, soap->type, ":int")
08700 && soap_match_tag(soap, soap->type, ":short")
08701 && soap_match_tag(soap, soap->type, ":byte"))
08702 { soap->error = SOAP_TYPE;
08703 soap_revert(soap);
08704 return NULL;
08705 }
08706 #endif
08707 p = (long*)soap_id_enter(soap, soap->id, p, t, sizeof(long), 0, NULL, NULL, NULL);
08708 if (*soap->href)
08709 p = (long*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(long), 0, NULL);
08710 else if (p)
08711 { if (soap_s2long(soap, soap_value(soap), p))
08712 return NULL;
08713 }
08714 if (soap->body && soap_element_end_in(soap, tag))
08715 return NULL;
08716 return p;
08717 }
08718 #endif
08719
08720
08721 #ifndef WITH_LEAN
08722 SOAP_FMAC1
08723 const char*
08724 SOAP_FMAC2
08725 soap_LONG642s(struct soap *soap, LONG64 n)
08726 { sprintf(soap->tmpbuf, SOAP_LONG_FORMAT, n);
08727 return soap->tmpbuf;
08728 }
08729 #endif
08730
08731
08732 #ifndef WITH_LEAN
08733 SOAP_FMAC1
08734 int
08735 SOAP_FMAC2
08736 soap_outLONG64(struct soap *soap, const char *tag, int id, const LONG64 *p, const char *type, int n)
08737 { if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
08738 || soap_string_out(soap, soap_LONG642s(soap, *p), 0))
08739 return soap->error;
08740 return soap_element_end_out(soap, tag);
08741 }
08742 #endif
08743
08744
08745 #ifndef WITH_LEAN
08746 SOAP_FMAC1
08747 int
08748 SOAP_FMAC2
08749 soap_s2LONG64(struct soap *soap, const char *s, LONG64 *p)
08750 { if (s)
08751 {
08752 #ifdef HAVE_STRTOLL
08753 char *r;
08754 #ifndef WITH_NOIO
08755 #ifndef WITH_LEAN
08756 soap_reset_errno;
08757 #endif
08758 #endif
08759 *p = strtoll(s, &r, 10);
08760 if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
08761 #ifndef WITH_NOIO
08762 #ifndef WITH_LEAN
08763 || soap_errno == SOAP_ERANGE
08764 #endif
08765 #endif
08766 )
08767 #else
08768 # ifdef HAVE_SSCANF
08769 if (sscanf(s, SOAP_LONG_FORMAT, p) != 1)
08770 # endif
08771 #endif
08772 soap->error = SOAP_TYPE;
08773 }
08774 return soap->error;
08775 }
08776 #endif
08777
08778
08779 #ifndef WITH_LEAN
08780 SOAP_FMAC1
08781 LONG64 *
08782 SOAP_FMAC2
08783 soap_inLONG64(struct soap *soap, const char *tag, LONG64 *p, const char *type, int t)
08784 { if (soap_element_begin_in(soap, tag, 0, NULL))
08785 return NULL;
08786 #ifndef WITH_LEAN
08787 if (*soap->type
08788 && soap_match_tag(soap, soap->type, type)
08789 && soap_match_tag(soap, soap->type, ":integer")
08790 && soap_match_tag(soap, soap->type, ":positiveInteger")
08791 && soap_match_tag(soap, soap->type, ":negativeInteger")
08792 && soap_match_tag(soap, soap->type, ":nonPositiveInteger")
08793 && soap_match_tag(soap, soap->type, ":nonNegativeInteger")
08794 && soap_match_tag(soap, soap->type, ":long")
08795 && soap_match_tag(soap, soap->type, ":int")
08796 && soap_match_tag(soap, soap->type, ":short")
08797 && soap_match_tag(soap, soap->type, ":byte"))
08798 { soap->error = SOAP_TYPE;
08799 soap_revert(soap);
08800 return NULL;
08801 }
08802 #endif
08803 p = (LONG64*)soap_id_enter(soap, soap->id, p, t, sizeof(LONG64), 0, NULL, NULL, NULL);
08804 if (*soap->href)
08805 p = (LONG64*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(LONG64), 0, NULL);
08806 else if (p)
08807 { if (soap_s2LONG64(soap, soap_value(soap), p))
08808 return NULL;
08809 }
08810 if (soap->body && soap_element_end_in(soap, tag))
08811 return NULL;
08812 return p;
08813 }
08814 #endif
08815
08816
08817 #ifndef PALM_2
08818 SOAP_FMAC1
08819 const char*
08820 SOAP_FMAC2
08821 soap_byte2s(struct soap *soap, char n)
08822 { return soap_long2s(soap, (long)n);
08823 }
08824 #endif
08825
08826