~ifolder-dev/simias/trunk-packaging

« back to all changes in this revision

Viewing changes to tools/gsoap/gsoap-linux-2.7/samples/quote_MAC_ProjBuild/.svn/text-base/stdsoap2.c.svn-base

  • Committer: Jorge O. Castro
  • Date: 2007-12-03 06:56:46 UTC
  • Revision ID: jorge@ubuntu.com-20071203065646-mupcnjcwgm5mnhyt
* Remove a bunch of .svn directories we no longer need.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 
3
 
stdsoap2.c[pp] 2.7.9k
4
 
 
5
 
gSOAP runtime
6
 
 
7
 
gSOAP XML Web services tools
8
 
Copyright (C) 2000-2007, Robert van Engelen, Genivia Inc., All Rights Reserved.
9
 
This part of the software is released under one of the following licenses:
10
 
GPL, the gSOAP public license, or Genivia's license for commercial use.
11
 
--------------------------------------------------------------------------------
12
 
Contributors:
13
 
 
14
 
Wind River Systems Inc., for the following additions under gSOAP public license:
15
 
  - vxWorks compatible  (#define VXWORKS)
16
 
--------------------------------------------------------------------------------
17
 
gSOAP public license.
18
 
 
19
 
The contents of this file are subject to the gSOAP Public License Version 1.3
20
 
(the "License"); you may not use this file except in compliance with the
21
 
License. You may obtain a copy of the License at
22
 
http://www.cs.fsu.edu/~engelen/soaplicense.html
23
 
Software distributed under the License is distributed on an "AS IS" basis,
24
 
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
25
 
for the specific language governing rights and limitations under the License.
26
 
 
27
 
The Initial Developer of the Original Code is Robert A. van Engelen.
28
 
Copyright (C) 2000-2007, Robert van Engelen, Genivia Inc., All Rights Reserved.
29
 
--------------------------------------------------------------------------------
30
 
GPL license.
31
 
 
32
 
This program is free software; you can redistribute it and/or modify it under
33
 
the terms of the GNU General Public License as published by the Free Software
34
 
Foundation; either version 2 of the License, or (at your option) any later
35
 
version.
36
 
 
37
 
This program is distributed in the hope that it will be useful, but WITHOUT ANY
38
 
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
39
 
PARTICULAR PURPOSE. See the GNU General Public License for more details.
40
 
 
41
 
You should have received a copy of the GNU General Public License along with
42
 
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
43
 
Place, Suite 330, Boston, MA 02111-1307 USA
44
 
 
45
 
Author contact information:
46
 
engelen@genivia.com / engelen@acm.org
47
 
--------------------------------------------------------------------------------
48
 
A commercial use license is available from Genivia, Inc., contact@genivia.com
49
 
--------------------------------------------------------------------------------
50
 
 
51
 
Installation note:
52
 
 
53
 
Win32 build needs winsock.dll (Visual C++ "wsock32.lib")
54
 
To do this in Visual C++ 6.0, go to "Project", "settings", select the "Link"
55
 
tab (the project file needs to be selected in the file view) and add
56
 
"wsock32.lib" to the "Object/library modules" entry
57
 
 
58
 
On Mac OS X with gcc (GCC) 3.1 20020420 (prerelease) you MUST compile with
59
 
-fstack_check when using -O2 because gcc 3.1 has a bug that smashes the stack
60
 
when locally allocated data exceeds 64K.
61
 
 
62
 
*/
63
 
 
64
 
#ifdef AS400
65
 
# pragma convert(819)   /* EBCDIC to ASCII */
66
 
#endif
67
 
 
68
 
#include "stdsoap2.h"
69
 
 
70
 
#ifdef __BORLANDC__
71
 
# pragma warn -8060
72
 
#else
73
 
# ifdef WIN32
74
 
#  ifdef UNDER_CE
75
 
#   pragma comment(lib, "winsock.lib")
76
 
#  else
77
 
#   pragma comment(lib, "wsock32.lib")
78
 
#  endif
79
 
#  pragma warning(disable : 4996) // disable deprecation warnings
80
 
# endif
81
 
#endif
82
 
 
83
 
#ifdef __cplusplus
84
 
SOAP_SOURCE_STAMP("@(#) stdsoap2.cpp ver 2.7.9k 2007-08-21 00:00:00 GMT")
85
 
extern "C" {
86
 
#else
87
 
SOAP_SOURCE_STAMP("@(#) stdsoap2.c ver 2.7.9k 2007-08-21 00:00:00 GMT")
88
 
#endif
89
 
 
90
 
/* 8bit character representing unknown/nonrepresentable character data (e.g. not supported by current locale with multibyte support enabled) */
91
 
#ifndef SOAP_UNKNOWN_CHAR
92
 
#define SOAP_UNKNOWN_CHAR (127)
93
 
#endif
94
 
 
95
 
/*      EOF=-1 */
96
 
#define SOAP_LT (soap_wchar)(-2) /* XML character '<' */
97
 
#define SOAP_TT (soap_wchar)(-3) /* XML character '</' */
98
 
#define SOAP_GT (soap_wchar)(-4) /* XML character '>' */
99
 
#define SOAP_QT (soap_wchar)(-5) /* XML character '"' */
100
 
#define SOAP_AP (soap_wchar)(-6) /* XML character ''' */
101
 
 
102
 
#define soap_blank(c)           ((c) >= 0 && (c) <= 32)
103
 
#define soap_notblank(c)        ((c) > 32)
104
 
 
105
 
#if defined(WIN32) && !defined(UNDER_CE)
106
 
#define soap_hash_ptr(p)        ((PtrToUlong(p) >> 3) & (SOAP_PTRHASH - 1))
107
 
#else
108
 
#define soap_hash_ptr(p)        ((size_t)(((unsigned long)(p) >> 3) & (SOAP_PTRHASH-1)))
109
 
#endif
110
 
 
111
 
#ifdef SOAP_DEBUG
112
 
static void soap_init_logs(struct soap*);
113
 
static void soap_close_logfile(struct soap*, int);
114
 
static void soap_set_logfile(struct soap*, int, const char*);
115
 
#endif
116
 
 
117
 
#ifdef SOAP_MEM_DEBUG
118
 
static void soap_init_mht(struct soap*);
119
 
static void soap_free_mht(struct soap*);
120
 
static void soap_track_unlink(struct soap*, const void*);
121
 
#endif
122
 
 
123
 
#ifndef PALM_2
124
 
static int soap_set_error(struct soap*, const char*, const char*, const char*, const char*, int);
125
 
static int soap_copy_fault(struct soap*, const char*, const char*, const char*, const char*);
126
 
static int soap_getattrval(struct soap*, char*, size_t, soap_wchar);
127
 
#endif
128
 
 
129
 
#ifndef PALM_1
130
 
static soap_wchar soap_char(struct soap*);
131
 
static soap_wchar soap_get_pi(struct soap*);
132
 
static int soap_isxdigit(int);
133
 
static void *fplugin(struct soap*, const char*);
134
 
#ifndef WITH_NOIDREF
135
 
static void soap_update_ptrs(struct soap*, char*, char*, char*, char*);
136
 
static int soap_has_copies(struct soap*, const char*, const char*);
137
 
static void soap_init_iht(struct soap*);
138
 
static void soap_free_iht(struct soap*);
139
 
static void soap_init_pht(struct soap*);
140
 
static void soap_free_pht(struct soap*);
141
 
#endif
142
 
#endif
143
 
 
144
 
#ifndef WITH_LEAN
145
 
static const char *soap_set_validation_fault(struct soap*, const char*, const char*);
146
 
static int soap_isnumeric(struct soap*, const char*);
147
 
static struct soap_nlist *soap_push_ns(struct soap *soap, const char *id, const char *ns, short utilized);
148
 
static void soap_pop_ns(struct soap *soap);
149
 
static void soap_utilize_ns(struct soap *soap, const char *tag, size_t n);
150
 
#endif
151
 
 
152
 
#ifndef WITH_LEANER
153
 
#ifndef PALM_1
154
 
static struct soap_multipart *soap_new_multipart(struct soap*, struct soap_multipart**, struct soap_multipart**, char*, size_t);
155
 
static int soap_putdimefield(struct soap*, const char*, size_t);
156
 
static char *soap_getdimefield(struct soap*, size_t);
157
 
static void soap_select_mime_boundary(struct soap*);
158
 
static int soap_valid_mime_boundary(struct soap*);
159
 
static void soap_resolve_attachment(struct soap*, struct soap_multipart*);
160
 
#endif
161
 
#endif
162
 
 
163
 
#ifdef WITH_GZIP
164
 
static int soap_getgziphdr(struct soap*);
165
 
#endif
166
 
 
167
 
#ifdef WITH_OPENSSL
168
 
static int ssl_init_done = 0;
169
 
static int ssl_auth_init(struct soap*);
170
 
static int ssl_verify_callback(int, X509_STORE_CTX*);
171
 
static int ssl_password(char*, int, int, void *);
172
 
/* This callback is included for future references. It should not be deleted
173
 
static DH *ssl_tmp_dh(SSL*, int, int);
174
 
*/
175
 
#endif
176
 
 
177
 
#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER)
178
 
#ifndef PALM_1
179
 
static const char *soap_decode(char*, size_t, const char*, const char*);
180
 
#endif
181
 
#endif
182
 
 
183
 
#ifndef WITH_NOHTTP
184
 
#ifndef PALM_1
185
 
static soap_wchar soap_getchunkchar(struct soap*);
186
 
static const char *http_error(struct soap*, int);
187
 
static int http_post(struct soap*, const char*, const char*, int, const char*, const char*, size_t);
188
 
static int http_get(struct soap*);
189
 
static int http_send_header(struct soap*, const char*);
190
 
static int http_post_header(struct soap*, const char*, const char*);
191
 
static int http_response(struct soap*, int, size_t);
192
 
static int http_parse(struct soap*);
193
 
static int http_parse_header(struct soap*, const char*, const char*);
194
 
#endif
195
 
#endif
196
 
 
197
 
#ifndef WITH_NOIO
198
 
#ifndef PALM_1
199
 
static int fsend(struct soap*, const char*, size_t);
200
 
static size_t frecv(struct soap*, char*, size_t);
201
 
static int tcp_init(struct soap*);
202
 
static const char *tcp_error(struct soap*);
203
 
#ifndef WITH_LEAN
204
 
static size_t frecv_stop(struct soap*, char*, size_t);
205
 
#endif
206
 
#ifndef WITH_IPV6
207
 
static int tcp_gethost(struct soap*, const char *addr, struct in_addr *inaddr);
208
 
#endif
209
 
static SOAP_SOCKET tcp_connect(struct soap*, const char *endpoint, const char *host, int port);
210
 
static SOAP_SOCKET tcp_accept(struct soap*, SOAP_SOCKET, struct sockaddr*, int*);
211
 
static int tcp_disconnect(struct soap*);
212
 
static int tcp_closesocket(struct soap*, SOAP_SOCKET);
213
 
static int tcp_shutdownsocket(struct soap*, SOAP_SOCKET, int);
214
 
static const char *soap_strerror(struct soap*);
215
 
#endif
216
 
#endif
217
 
 
218
 
#if defined(PALM) && !defined(PALM_2)
219
 
unsigned short errno;
220
 
#endif
221
 
 
222
 
#ifndef PALM_1
223
 
static const char soap_env1[42] = "http://schemas.xmlsoap.org/soap/envelope/";
224
 
static const char soap_enc1[42] = "http://schemas.xmlsoap.org/soap/encoding/";
225
 
static const char soap_env2[40] = "http://www.w3.org/2003/05/soap-envelope";
226
 
static const char soap_enc2[40] = "http://www.w3.org/2003/05/soap-encoding";
227
 
static const char soap_rpc[35] = "http://www.w3.org/2003/05/soap-rpc";
228
 
#endif
229
 
 
230
 
#ifndef PALM_1
231
 
const struct soap_double_nan soap_double_nan = {0xFFFFFFFF, 0xFFFFFFFF};
232
 
static const char soap_base64o[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
233
 
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";
234
 
#endif
235
 
 
236
 
#ifndef WITH_LEAN
237
 
static const char soap_indent[11] = "\n\t\t\t\t\t\t\t\t\t";
238
 
/* Alternative indentation form for SOAP_XML_INDENT:
239
 
static const char soap_indent[21] = "\n                   ";
240
 
*/
241
 
#endif
242
 
 
243
 
#ifndef SOAP_CANARY
244
 
# define SOAP_CANARY (0xC0DE)
245
 
#endif
246
 
 
247
 
static const char soap_padding[4] = "\0\0\0";
248
 
#define SOAP_STR_PADDING (soap_padding)
249
 
#define SOAP_STR_EOS (soap_padding)
250
 
#define SOAP_NON_NULL (soap_padding)
251
 
 
252
 
#ifndef WITH_LEAN
253
 
static const struct soap_code_map html_entity_codes[] = /* entities for XHTML parsing */
254
 
{ { 160, "nbsp" },
255
 
  { 161, "iexcl" },
256
 
  { 162, "cent" },
257
 
  { 163, "pound" },
258
 
  { 164, "curren" },
259
 
  { 165, "yen" },
260
 
  { 166, "brvbar" },
261
 
  { 167, "sect" },
262
 
  { 168, "uml" },
263
 
  { 169, "copy" },
264
 
  { 170, "ordf" },
265
 
  { 171, "laquo" },
266
 
  { 172, "not" },
267
 
  { 173, "shy" },
268
 
  { 174, "reg" },
269
 
  { 175, "macr" },
270
 
  { 176, "deg" },
271
 
  { 177, "plusmn" },
272
 
  { 178, "sup2" },
273
 
  { 179, "sup3" },
274
 
  { 180, "acute" },
275
 
  { 181, "micro" },
276
 
  { 182, "para" },
277
 
  { 183, "middot" },
278
 
  { 184, "cedil" },
279
 
  { 185, "sup1" },
280
 
  { 186, "ordm" },
281
 
  { 187, "raquo" },
282
 
  { 188, "frac14" },
283
 
  { 189, "frac12" },
284
 
  { 190, "frac34" },
285
 
  { 191, "iquest" },
286
 
  { 192, "Agrave" },
287
 
  { 193, "Aacute" },
288
 
  { 194, "Acirc" },
289
 
  { 195, "Atilde" },
290
 
  { 196, "Auml" },
291
 
  { 197, "Aring" },
292
 
  { 198, "AElig" },
293
 
  { 199, "Ccedil" },
294
 
  { 200, "Egrave" },
295
 
  { 201, "Eacute" },
296
 
  { 202, "Ecirc" },
297
 
  { 203, "Euml" },
298
 
  { 204, "Igrave" },
299
 
  { 205, "Iacute" },
300
 
  { 206, "Icirc" },
301
 
  { 207, "Iuml" },
302
 
  { 208, "ETH" },
303
 
  { 209, "Ntilde" },
304
 
  { 210, "Ograve" },
305
 
  { 211, "Oacute" },
306
 
  { 212, "Ocirc" },
307
 
  { 213, "Otilde" },
308
 
  { 214, "Ouml" },
309
 
  { 215, "times" },
310
 
  { 216, "Oslash" },
311
 
  { 217, "Ugrave" },
312
 
  { 218, "Uacute" },
313
 
  { 219, "Ucirc" },
314
 
  { 220, "Uuml" },
315
 
  { 221, "Yacute" },
316
 
  { 222, "THORN" },
317
 
  { 223, "szlig" },
318
 
  { 224, "agrave" },
319
 
  { 225, "aacute" },
320
 
  { 226, "acirc" },
321
 
  { 227, "atilde" },
322
 
  { 228, "auml" },
323
 
  { 229, "aring" },
324
 
  { 230, "aelig" },
325
 
  { 231, "ccedil" },
326
 
  { 232, "egrave" },
327
 
  { 233, "eacute" },
328
 
  { 234, "ecirc" },
329
 
  { 235, "euml" },
330
 
  { 236, "igrave" },
331
 
  { 237, "iacute" },
332
 
  { 238, "icirc" },
333
 
  { 239, "iuml" },
334
 
  { 240, "eth" },
335
 
  { 241, "ntilde" },
336
 
  { 242, "ograve" },
337
 
  { 243, "oacute" },
338
 
  { 244, "ocirc" },
339
 
  { 245, "otilde" },
340
 
  { 246, "ouml" },
341
 
  { 247, "divide" },
342
 
  { 248, "oslash" },
343
 
  { 249, "ugrave" },
344
 
  { 250, "uacute" },
345
 
  { 251, "ucirc" },
346
 
  { 252, "uuml" },
347
 
  { 253, "yacute" },
348
 
  { 254, "thorn" },
349
 
  { 255, "yuml" },
350
 
  {   0, NULL }
351
 
};
352
 
#endif
353
 
 
354
 
#ifndef WITH_NOIO
355
 
#ifndef WITH_LEAN
356
 
static const struct soap_code_map h_error_codes[] =
357
 
{
358
 
#ifdef HOST_NOT_FOUND   
359
 
  { HOST_NOT_FOUND, "Host not found" },
360
 
#endif
361
 
#ifdef TRY_AGAIN
362
 
  { TRY_AGAIN, "Try Again" },
363
 
#endif
364
 
#ifdef NO_RECOVERY  
365
 
  { NO_RECOVERY, "No Recovery" },
366
 
#endif
367
 
#ifdef NO_DATA
368
 
  { NO_DATA, "No Data" },
369
 
#endif
370
 
#ifdef NO_ADDRESS
371
 
  { NO_ADDRESS, "No Address" },
372
 
#endif
373
 
  { 0, NULL }
374
 
};
375
 
#endif
376
 
#endif
377
 
 
378
 
#ifndef WITH_NOHTTP
379
 
#ifndef WITH_LEAN
380
 
static const struct soap_code_map h_http_error_codes[] =
381
 
{ { 200, "OK" },
382
 
  { 201, "Created" },
383
 
  { 202, "Accepted" },
384
 
  { 203, "Non-Authoritative Information" },
385
 
  { 204, "No Content" },
386
 
  { 205, "Reset Content" },
387
 
  { 206, "Partial Content" },
388
 
  { 300, "Multiple Choices" },
389
 
  { 301, "Moved Permanently" },
390
 
  { 302, "Found" },
391
 
  { 303, "See Other" },
392
 
  { 304, "Not Modified" },
393
 
  { 305, "Use Proxy" },
394
 
  { 307, "Temporary Redirect" },
395
 
  { 400, "Bad Request" },
396
 
  { 401, "Unauthorized" },
397
 
  { 402, "Payment Required" },
398
 
  { 403, "Forbidden" },
399
 
  { 404, "Not Found" },
400
 
  { 405, "Method Not Allowed" },
401
 
  { 406, "Not Acceptable" },
402
 
  { 407, "Proxy Authentication Required" },
403
 
  { 408, "Request Time-out" },
404
 
  { 409, "Conflict" },
405
 
  { 410, "Gone" },
406
 
  { 411, "Length Required" },
407
 
  { 412, "Precondition Failed" },
408
 
  { 413, "Request Entity Too Large" },
409
 
  { 414, "Request-URI Too Large" },
410
 
  { 415, "Unsupported Media Type" },
411
 
  { 416, "Requested range not satisfiable" },
412
 
  { 417, "Expectation Failed" },
413
 
  { 500, "Internal Server Error" },
414
 
  { 501, "Not Implemented" },
415
 
  { 502, "Bad Gateway" },
416
 
  { 503, "Service Unavailable" },
417
 
  { 504, "Gateway Time-out" },
418
 
  { 505, "HTTP Version not supported" },
419
 
  {   0, NULL }
420
 
};
421
 
#endif
422
 
#endif
423
 
 
424
 
#ifdef WITH_OPENSSL
425
 
static const struct soap_code_map h_ssl_error_codes[] =
426
 
{
427
 
#define _SSL_ERROR(e) { e, #e }
428
 
  _SSL_ERROR(SSL_ERROR_SSL),
429
 
  _SSL_ERROR(SSL_ERROR_ZERO_RETURN),
430
 
  _SSL_ERROR(SSL_ERROR_WANT_READ),
431
 
  _SSL_ERROR(SSL_ERROR_WANT_WRITE),
432
 
  _SSL_ERROR(SSL_ERROR_WANT_CONNECT),
433
 
  _SSL_ERROR(SSL_ERROR_WANT_X509_LOOKUP),
434
 
  _SSL_ERROR(SSL_ERROR_SYSCALL),
435
 
  { 0, NULL }
436
 
};
437
 
#endif
438
 
 
439
 
#ifndef WITH_LEANER
440
 
static const struct soap_code_map mime_codes[] =
441
 
{ { SOAP_MIME_7BIT,             "7bit" },
442
 
  { SOAP_MIME_8BIT,             "8bit" },
443
 
  { SOAP_MIME_BINARY,           "binary" },
444
 
  { SOAP_MIME_QUOTED_PRINTABLE, "quoted-printable" },
445
 
  { SOAP_MIME_BASE64,           "base64" },
446
 
  { SOAP_MIME_IETF_TOKEN,       "ietf-token" },
447
 
  { SOAP_MIME_X_TOKEN,          "x-token" },
448
 
  { 0,                          NULL }
449
 
};
450
 
#endif
451
 
 
452
 
#ifdef WIN32
453
 
static int tcp_done = 0;
454
 
#endif
455
 
 
456
 
/******************************************************************************/
457
 
#ifndef WITH_NOIO
458
 
#ifndef PALM_1
459
 
static int
460
 
fsend(struct soap *soap, const char *s, size_t n)
461
 
{ register int nwritten, err;
462
 
#if defined(__cplusplus) && !defined(WITH_LEAN)
463
 
  if (soap->os)
464
 
  { soap->os->write(s, (std::streamsize)n);
465
 
    if (soap->os->good())
466
 
      return SOAP_OK;
467
 
    return SOAP_EOF;
468
 
  }
469
 
#endif
470
 
  while (n)
471
 
  { if (soap_valid_socket(soap->socket))
472
 
    { 
473
 
#ifndef WITH_LEAN
474
 
      if (soap->send_timeout)
475
 
      {
476
 
#ifndef WIN32
477
 
        if ((int)soap->socket >= (int)FD_SETSIZE)
478
 
          return SOAP_FD_EXCEEDED;      /* Hint: MUST increase FD_SETSIZE */
479
 
#endif
480
 
        for (;;)
481
 
        { struct timeval timeout;
482
 
          fd_set fd;
483
 
          register int r;
484
 
          if (soap->send_timeout > 0)
485
 
          { timeout.tv_sec = soap->send_timeout;
486
 
            timeout.tv_usec = 0;
487
 
          }
488
 
          else
489
 
          { timeout.tv_sec = -soap->send_timeout/1000000;
490
 
            timeout.tv_usec = -soap->send_timeout%1000000;
491
 
          }
492
 
          FD_ZERO(&fd);
493
 
          FD_SET(soap->socket, &fd);
494
 
#ifdef WITH_OPENSSL
495
 
          if (soap->ssl)
496
 
            r = select((int)soap->socket + 1, &fd, &fd, &fd, &timeout);
497
 
          else
498
 
#endif
499
 
          r = select((int)soap->socket + 1, NULL, &fd, &fd, &timeout);
500
 
          if (r > 0)
501
 
            break;
502
 
          if (!r)
503
 
          { soap->errnum = 0;
504
 
            return SOAP_EOF;
505
 
          }
506
 
          err = soap_socket_errno(soap->socket);
507
 
          if (err != SOAP_EINTR && err != SOAP_EAGAIN)
508
 
          { soap->errnum = err;
509
 
            return SOAP_EOF;
510
 
          }
511
 
        }
512
 
      }
513
 
#endif
514
 
#ifdef WITH_OPENSSL
515
 
      if (soap->ssl)
516
 
        nwritten = SSL_write(soap->ssl, s, (int)n);
517
 
      else if (soap->bio)
518
 
        nwritten = BIO_write(soap->bio, s, (int)n);
519
 
      else
520
 
#endif
521
 
#ifdef WITH_UDP
522
 
      if ((soap->omode & SOAP_IO_UDP))
523
 
      { if (soap->peerlen)
524
 
          nwritten = sendto(soap->socket, s, n, soap->socket_flags, (struct sockaddr*)&soap->peer, soap->peerlen);
525
 
        else
526
 
          nwritten = send(soap->socket, s, n, soap->socket_flags);
527
 
        /* retry and back-off algorithm */
528
 
        /* TODO: this is not very clear from specs so verify and limit conditions under which we should loop (e.g. ENOBUFS) */
529
 
        if (nwritten < 0)
530
 
        { struct timeval timeout;
531
 
          fd_set fd;
532
 
          int udp_repeat;
533
 
          int udp_delay;
534
 
#ifndef WIN32
535
 
          if ((int)soap->socket >= (int)FD_SETSIZE)
536
 
            return SOAP_FD_EXCEEDED;    /* Hint: MUST increase FD_SETSIZE */
537
 
#endif
538
 
          if ((soap->connect_flags & SO_BROADCAST))
539
 
            udp_repeat = 3; /* SOAP-over-UDP MULTICAST_UDP_REPEAT - 1 */
540
 
          else
541
 
            udp_repeat = 1; /* SOAP-over-UDP UNICAST_UDP_REPEAT - 1 */
542
 
          udp_delay = (soap_random % 201) + 50; /* UDP_MIN_DELAY .. UDP_MAX_DELAY */
543
 
          do
544
 
          { timeout.tv_sec = 0;
545
 
            timeout.tv_usec = 1000 * udp_delay; /* ms */
546
 
            FD_ZERO(&fd);
547
 
            FD_SET(soap->socket, &fd);
548
 
            select((int)soap->socket + 1, NULL, NULL, &fd, &timeout);
549
 
            if (soap->peerlen)
550
 
              nwritten = sendto(soap->socket, s, n, soap->socket_flags, (struct sockaddr*)&soap->peer, soap->peerlen);
551
 
            else
552
 
              nwritten = send(soap->socket, s, n, soap->socket_flags);
553
 
            udp_delay <<= 1;
554
 
            if (udp_delay > 500) /* UDP_UPPER_DELAY */
555
 
              udp_delay = 500;
556
 
          }
557
 
          while (nwritten < 0 && --udp_repeat > 0);
558
 
        }
559
 
      }
560
 
      else
561
 
#endif
562
 
#if !defined(PALM) && !defined(AS400)
563
 
        nwritten = send(soap->socket, s, (int)n, soap->socket_flags);
564
 
#else
565
 
        nwritten = send(soap->socket, (void*)s, n, soap->socket_flags);
566
 
#endif
567
 
      if (nwritten <= 0)
568
 
      { register int r = 0;
569
 
#ifdef WITH_OPENSSL
570
 
        if (soap->ssl && (r = SSL_get_error(soap->ssl, nwritten)) != SSL_ERROR_NONE && r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE)
571
 
          return SOAP_EOF;
572
 
#endif
573
 
        err = soap_socket_errno(soap->socket);
574
 
        if (err == SOAP_EWOULDBLOCK || err == SOAP_EAGAIN)
575
 
        {
576
 
#ifndef WITH_LEAN
577
 
          struct timeval timeout;
578
 
          fd_set fd;
579
 
#ifndef WIN32
580
 
          if ((int)soap->socket >= (int)FD_SETSIZE)
581
 
            return SOAP_FD_EXCEEDED; /* Hint: MUST increase FD_SETSIZE */
582
 
#endif
583
 
          if (soap->send_timeout > 0)
584
 
          { timeout.tv_sec = soap->send_timeout;
585
 
            timeout.tv_usec = 0;
586
 
          }
587
 
          else if (soap->send_timeout < 0)
588
 
          { timeout.tv_sec = -soap->send_timeout/1000000;
589
 
            timeout.tv_usec = -soap->send_timeout%1000000;
590
 
          }
591
 
          else
592
 
          { timeout.tv_sec = 0;
593
 
            timeout.tv_usec = 10000;
594
 
          }
595
 
          FD_ZERO(&fd);
596
 
          FD_SET(soap->socket, &fd);
597
 
#ifdef WITH_OPENSSL
598
 
          if (soap->ssl && r == SSL_ERROR_WANT_READ)
599
 
            r = select((int)soap->socket + 1, &fd, NULL, &fd, &timeout);
600
 
          else
601
 
            r = select((int)soap->socket + 1, NULL, &fd, &fd, &timeout);
602
 
#else
603
 
          r = select((int)soap->socket + 1, NULL, &fd, &fd, &timeout);
604
 
#endif
605
 
          if (r < 0 && (r = soap_socket_errno(soap->socket)) != SOAP_EINTR)
606
 
          { soap->errnum = r;
607
 
            return SOAP_EOF;
608
 
          }
609
 
#endif
610
 
        }
611
 
        else if (err && err != SOAP_EINTR)
612
 
        { soap->errnum = err;
613
 
          return SOAP_EOF;
614
 
        }
615
 
        nwritten = 0; /* and call write() again */
616
 
      }
617
 
    }
618
 
    else
619
 
    {
620
 
#ifdef WITH_FASTCGI
621
 
      nwritten = fwrite((void*)s, 1, n, stdout);
622
 
      fflush(stdout);
623
 
#else
624
 
#ifdef UNDER_CE
625
 
      nwritten = fwrite(s, 1, n, soap->sendfd);
626
 
#else
627
 
#ifdef VXWORKS
628
 
#ifdef WMW_RPM_IO
629
 
      if (soap->rpmreqid)
630
 
        nwritten = (httpBlockPut(soap->rpmreqid, s, n) == 0) ? n : -1; 
631
 
      else
632
 
#endif
633
 
        nwritten = fwrite(s, sizeof(char), n, fdopen(soap->sendfd, "w"));
634
 
#else
635
 
      nwritten = write(soap->sendfd, s, (unsigned int)n);
636
 
#endif
637
 
#endif
638
 
#endif
639
 
      if (nwritten <= 0)
640
 
      { err = soap_errno;
641
 
        if (err && err != SOAP_EINTR && err != SOAP_EWOULDBLOCK && err != SOAP_EAGAIN)
642
 
        { soap->errnum = err;
643
 
          return SOAP_EOF;
644
 
        }
645
 
        nwritten = 0; /* and call write() again */
646
 
      }
647
 
    }
648
 
    n -= nwritten;
649
 
    s += nwritten;
650
 
  }
651
 
  return SOAP_OK;
652
 
}
653
 
#endif
654
 
#endif
655
 
 
656
 
/******************************************************************************/
657
 
#ifndef PALM_1
658
 
SOAP_FMAC1
659
 
int
660
 
SOAP_FMAC2
661
 
soap_send_raw(struct soap *soap, const char *s, size_t n)
662
 
{ if (!n)
663
 
    return SOAP_OK;
664
 
  if (soap->mode & SOAP_IO_LENGTH)
665
 
  { soap->count += n;
666
 
#ifndef WITH_LEANER
667
 
    if (soap->fpreparesend && (soap->mode & SOAP_IO) != SOAP_IO_STORE)
668
 
      return soap->error = soap->fpreparesend(soap, s, n);
669
 
#endif
670
 
    return SOAP_OK;
671
 
  }
672
 
  if (soap->mode & SOAP_IO)
673
 
  { register size_t i = SOAP_BUFLEN - soap->bufidx;
674
 
    while (n >= i)
675
 
    { memcpy(soap->buf + soap->bufidx, s, i);
676
 
      soap->bufidx = SOAP_BUFLEN;
677
 
      if (soap_flush(soap))
678
 
        return soap->error;
679
 
      s += i;
680
 
      n -= i;
681
 
      i = SOAP_BUFLEN;
682
 
    }
683
 
    memcpy(soap->buf + soap->bufidx, s, n);
684
 
    soap->bufidx += n;
685
 
    return SOAP_OK;
686
 
  }
687
 
  return soap_flush_raw(soap, s, n);
688
 
}
689
 
#endif
690
 
 
691
 
/******************************************************************************/
692
 
#ifndef PALM_1
693
 
SOAP_FMAC1
694
 
int
695
 
SOAP_FMAC2
696
 
soap_flush(struct soap *soap)
697
 
{ register size_t n = soap->bufidx;
698
 
  if (n)
699
 
  { soap->bufidx = 0;
700
 
#ifdef WITH_ZLIB
701
 
    if (soap->mode & SOAP_ENC_ZLIB)
702
 
    { soap->d_stream.next_in = (Byte*)soap->buf;
703
 
      soap->d_stream.avail_in = (unsigned int)n;
704
 
#ifdef WITH_GZIP
705
 
      soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)n);
706
 
#endif
707
 
      do
708
 
      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflating %u bytes\n", soap->d_stream.avail_in));
709
 
        if (deflate(&soap->d_stream, Z_NO_FLUSH) != Z_OK)
710
 
        { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to deflate: %s\n", soap->d_stream.msg?soap->d_stream.msg:""));
711
 
          return soap->error = SOAP_ZLIB_ERROR;
712
 
        }
713
 
        if (!soap->d_stream.avail_out)
714
 
        { if (soap_flush_raw(soap, soap->z_buf, SOAP_BUFLEN))
715
 
            return soap->error;
716
 
          soap->d_stream.next_out = (Byte*)soap->z_buf;
717
 
          soap->d_stream.avail_out = SOAP_BUFLEN;
718
 
        }
719
 
      } while (soap->d_stream.avail_in);
720
 
    }
721
 
    else
722
 
#endif
723
 
      return soap_flush_raw(soap, soap->buf, n);
724
 
  }
725
 
  return SOAP_OK;
726
 
}
727
 
#endif
728
 
 
729
 
/******************************************************************************/
730
 
#ifndef PALM_1
731
 
SOAP_FMAC1
732
 
int
733
 
SOAP_FMAC2
734
 
soap_flush_raw(struct soap *soap, const char *s, size_t n)
735
 
{ if ((soap->mode & SOAP_IO) == SOAP_IO_STORE)
736
 
  { register char *t;
737
 
    if (!(t = (char*)soap_push_block(soap, n)))
738
 
      return soap->error = SOAP_EOM;
739
 
    memcpy(t, s, n);
740
 
#ifndef WITH_LEANER
741
 
    if (soap->fpreparesend)
742
 
      return soap->error = soap->fpreparesend(soap, s, n);
743
 
#endif
744
 
    return SOAP_OK;
745
 
  }
746
 
#ifndef WITH_LEANER
747
 
  if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK)
748
 
  { char t[16];
749
 
    sprintf(t, "\r\n%lX\r\n" + (soap->chunksize ? 0 : 2), (unsigned long)n);
750
 
    DBGMSG(SENT, t, strlen(t));
751
 
    if ((soap->error = soap->fsend(soap, t, strlen(t))))
752
 
      return soap->error;
753
 
    soap->chunksize += n;
754
 
  }
755
 
  DBGMSG(SENT, s, n);
756
 
#endif
757
 
  return soap->error = soap->fsend(soap, s, n);
758
 
}
759
 
#endif
760
 
 
761
 
/******************************************************************************/
762
 
#ifndef PALM_1
763
 
SOAP_FMAC1
764
 
int
765
 
SOAP_FMAC2
766
 
soap_send(struct soap *soap, const char *s)
767
 
{ if (s)
768
 
    return soap_send_raw(soap, s, strlen(s));
769
 
  return SOAP_OK;
770
 
}
771
 
#endif
772
 
 
773
 
/******************************************************************************/
774
 
#ifndef WITH_LEANER
775
 
#ifndef PALM_1
776
 
SOAP_FMAC1
777
 
int
778
 
SOAP_FMAC2
779
 
soap_send2(struct soap *soap, const char *s1, const char *s2)
780
 
{ if (soap_send(soap, s1))
781
 
    return soap->error;
782
 
  return soap_send(soap, s2);
783
 
}
784
 
#endif
785
 
#endif
786
 
 
787
 
/******************************************************************************/
788
 
#ifndef WITH_LEANER
789
 
#ifndef PALM_1
790
 
SOAP_FMAC1
791
 
int
792
 
SOAP_FMAC2
793
 
soap_send3(struct soap *soap, const char *s1, const char *s2, const char *s3)
794
 
{ if (soap_send(soap, s1)
795
 
   || soap_send(soap, s2))
796
 
    return soap->error;
797
 
  return soap_send(soap, s3);
798
 
}
799
 
#endif
800
 
#endif
801
 
 
802
 
/******************************************************************************/
803
 
#ifndef WITH_NOIO
804
 
#ifndef PALM_1
805
 
static size_t
806
 
frecv(struct soap *soap, char *s, size_t n)
807
 
{ register int r;
808
 
#ifdef PALM
809
 
  register int timeouts = 6000; /* Palm: 1 min timeout for SSL */
810
 
#endif
811
 
  soap->errnum = 0;
812
 
#if defined(__cplusplus) && !defined(WITH_LEAN)
813
 
  if (soap->is)
814
 
  { if (soap->is->good())
815
 
      return soap->is->read(s, (std::streamsize)n).gcount();
816
 
    return 0;
817
 
  }
818
 
#endif
819
 
  if (soap_valid_socket(soap->socket))
820
 
  { for (;;)
821
 
    { 
822
 
#ifdef WITH_OPENSSL
823
 
      register int err = 0;
824
 
#endif
825
 
#ifndef WITH_LEAN
826
 
#ifdef WITH_OPENSSL
827
 
      if (soap->recv_timeout && !soap->ssl) /* SSL: sockets are nonblocking */
828
 
#else
829
 
      if (soap->recv_timeout)
830
 
#endif
831
 
      {
832
 
#ifndef WIN32
833
 
        if ((int)soap->socket >= (int)FD_SETSIZE)
834
 
        { soap->error = SOAP_FD_EXCEEDED;
835
 
          return 0;     /* Hint: MUST increase FD_SETSIZE */
836
 
        }
837
 
#endif
838
 
        for (;;)
839
 
        { struct timeval timeout;
840
 
          fd_set fd;
841
 
          if (soap->recv_timeout > 0)
842
 
          { timeout.tv_sec = soap->recv_timeout;
843
 
            timeout.tv_usec = 0;
844
 
          }
845
 
          else
846
 
          { timeout.tv_sec = -soap->recv_timeout/1000000;
847
 
            timeout.tv_usec = -soap->recv_timeout%1000000;
848
 
          }
849
 
          FD_ZERO(&fd);
850
 
          FD_SET(soap->socket, &fd);
851
 
          r = select((int)soap->socket + 1, &fd, NULL, &fd, &timeout);
852
 
          if (r > 0)
853
 
            break;
854
 
          if (!r)
855
 
          { soap->errnum = 0;
856
 
            return 0;
857
 
          }
858
 
          r = soap_socket_errno(soap->socket);
859
 
          if (r != SOAP_EINTR && r != SOAP_EAGAIN)
860
 
          { soap->errnum = r;
861
 
            return 0;
862
 
          }
863
 
        }
864
 
      }
865
 
#endif
866
 
#ifdef WITH_OPENSSL
867
 
      if (soap->ssl)
868
 
      { r = SSL_read(soap->ssl, s, (int)n);
869
 
        if (r > 0)
870
 
          return (size_t)r;
871
 
        err = SSL_get_error(soap->ssl, r);
872
 
        if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
873
 
          return 0;
874
 
      }
875
 
      else if (soap->bio)
876
 
      { r = BIO_read(soap->bio, s, (int)n);
877
 
        if (r > 0)
878
 
          return (size_t)r;
879
 
        return 0;
880
 
      }
881
 
      else
882
 
#endif
883
 
      { 
884
 
#ifdef WITH_UDP
885
 
        if ((soap->omode & SOAP_IO_UDP))
886
 
        { SOAP_SOCKLEN_T k = (SOAP_SOCKLEN_T)sizeof(soap->peer);
887
 
          memset((void*)&soap->peer, 0, sizeof(soap->peer));
888
 
          r = recvfrom(soap->socket, s, n, soap->socket_flags, (struct sockaddr*)&soap->peer, &k);      /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */
889
 
          soap->peerlen = (size_t)k;
890
 
#ifndef WITH_IPV6
891
 
          soap->ip = ntohl(soap->peer.sin_addr.s_addr);
892
 
#endif
893
 
        }
894
 
        else
895
 
#endif
896
 
          r = recv(soap->socket, s, (int)n, soap->socket_flags);
897
 
#ifdef PALM
898
 
        /* CycleSyncDisplay(curStatusMsg); */
899
 
#endif
900
 
        if (r >= 0)
901
 
          return (size_t)r;
902
 
        r = soap_socket_errno(soap->socket);
903
 
        if (r != SOAP_EINTR && r != SOAP_EAGAIN && r != SOAP_EWOULDBLOCK)
904
 
        { soap->errnum = r;
905
 
          return 0;
906
 
        }
907
 
      }
908
 
#ifndef WITH_LEAN
909
 
      { struct timeval timeout;
910
 
        fd_set fd;
911
 
        if (soap->recv_timeout > 0)
912
 
        { timeout.tv_sec = soap->recv_timeout;
913
 
          timeout.tv_usec = 0;
914
 
        }
915
 
        else if (soap->recv_timeout < 0)
916
 
        { timeout.tv_sec = -soap->recv_timeout/1000000;
917
 
          timeout.tv_usec = -soap->recv_timeout%1000000;
918
 
        }
919
 
        else
920
 
        { timeout.tv_sec = 0;
921
 
          timeout.tv_usec = 10000;
922
 
        }
923
 
#ifndef WIN32
924
 
        if ((int)soap->socket >= (int)FD_SETSIZE)
925
 
        { soap->error = SOAP_FD_EXCEEDED;
926
 
          return 0;     /* Hint: MUST increase FD_SETSIZE */
927
 
        }
928
 
#endif
929
 
        FD_ZERO(&fd);
930
 
        FD_SET(soap->socket, &fd);
931
 
#ifdef WITH_OPENSSL
932
 
        if (soap->ssl && err == SSL_ERROR_WANT_WRITE)
933
 
          r = select((int)soap->socket + 1, NULL, &fd, &fd, &timeout);
934
 
        else
935
 
          r = select((int)soap->socket + 1, &fd, NULL, &fd, &timeout);
936
 
#else
937
 
        r = select((int)soap->socket + 1, &fd, NULL, &fd, &timeout);
938
 
#endif
939
 
        if (r < 0 && (r = soap_socket_errno(soap->socket)) != SOAP_EINTR)
940
 
        { soap->errnum = r;
941
 
          return 0;
942
 
        }
943
 
        if (!r && soap->recv_timeout)
944
 
        { soap->errnum = 0;
945
 
          return 0;
946
 
        }
947
 
      }
948
 
#endif
949
 
#ifdef PALM
950
 
      r = soap_socket_errno(soap->socket);
951
 
      if (r != SOAP_EINTR && timeouts-- <= 0)
952
 
      { soap->errnum = r;
953
 
        return 0;
954
 
      }
955
 
#endif
956
 
    }
957
 
  }
958
 
#ifdef WITH_FASTCGI
959
 
  return fread(s, 1, n, stdin);
960
 
#else
961
 
#ifdef UNDER_CE
962
 
  return fread(s, 1, n, soap->recvfd);
963
 
#else
964
 
#ifdef WMW_RPM_IO
965
 
  if (soap->rpmreqid)
966
 
    r = httpBlockRead(soap->rpmreqid, s, n);
967
 
  else
968
 
#endif
969
 
    r = read(soap->recvfd, s, (unsigned int)n);
970
 
  if (r >= 0)
971
 
    return (size_t)r;
972
 
  soap->errnum = soap_errno;
973
 
  return 0;
974
 
#endif
975
 
#endif
976
 
}
977
 
#endif
978
 
#endif
979
 
 
980
 
/******************************************************************************/
981
 
#ifndef WITH_LEAN
982
 
#ifndef WITH_NOIO
983
 
#ifndef PALM_1
984
 
static size_t
985
 
frecv_stop(struct soap *soap, char *s, size_t n)
986
 
{ return 0;
987
 
}
988
 
#endif
989
 
#endif
990
 
#endif
991
 
 
992
 
/******************************************************************************/
993
 
#ifndef WITH_NOHTTP
994
 
#ifndef PALM_1
995
 
static soap_wchar
996
 
soap_getchunkchar(struct soap *soap)
997
 
{ if (soap->bufidx < soap->buflen)
998
 
    return soap->buf[soap->bufidx++];
999
 
  soap->bufidx = 0;
1000
 
  soap->buflen = soap->chunkbuflen = soap->frecv(soap, soap->buf, SOAP_BUFLEN);
1001
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes from socket %d\n", (unsigned int)soap->buflen, soap->socket));
1002
 
  DBGMSG(RECV, soap->buf, soap->buflen);
1003
 
  if (soap->buflen)
1004
 
    return soap->buf[soap->bufidx++];
1005
 
  return EOF;
1006
 
}
1007
 
#endif
1008
 
#endif
1009
 
 
1010
 
/******************************************************************************/
1011
 
#ifndef PALM_1
1012
 
static int
1013
 
soap_isxdigit(int c)
1014
 
{ return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
1015
 
}
1016
 
#endif
1017
 
 
1018
 
/******************************************************************************/
1019
 
#ifndef PALM_1
1020
 
SOAP_FMAC1
1021
 
int
1022
 
SOAP_FMAC2
1023
 
soap_recv_raw(struct soap *soap)
1024
 
{ register size_t ret;
1025
 
#ifdef WITH_ZLIB
1026
 
  if (soap->mode & SOAP_ENC_ZLIB)
1027
 
  { if (soap->d_stream.next_out == Z_NULL)
1028
 
      return EOF;
1029
 
    if (soap->d_stream.avail_in || !soap->d_stream.avail_out)
1030
 
    { register int r;
1031
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflating\n"));
1032
 
      soap->d_stream.next_out = (Byte*)soap->buf;
1033
 
      soap->d_stream.avail_out = SOAP_BUFLEN;
1034
 
      r = inflate(&soap->d_stream, Z_NO_FLUSH);
1035
 
      if (r == Z_OK || r == Z_STREAM_END)
1036
 
      { soap->bufidx = 0;
1037
 
        ret = soap->buflen = SOAP_BUFLEN - soap->d_stream.avail_out;
1038
 
        if (soap->zlib_in == SOAP_ZLIB_GZIP)
1039
 
          soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)ret);
1040
 
        if (r == Z_STREAM_END)
1041
 
        { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %lu->%lu bytes\n", soap->d_stream.total_in, soap->d_stream.total_out));
1042
 
          soap->z_ratio_in = (float)soap->d_stream.total_in / (float)soap->d_stream.total_out;
1043
 
          soap->d_stream.next_out = Z_NULL;
1044
 
        }
1045
 
        if (ret)
1046
 
        { soap->count += ret;
1047
 
          DBGLOG(RECV, SOAP_MESSAGE(fdebug, "\n---- decompressed ----\n"));
1048
 
          DBGMSG(RECV, soap->buf, ret);
1049
 
          DBGLOG(RECV, SOAP_MESSAGE(fdebug, "\n----\n"));
1050
 
          return SOAP_OK;
1051
 
        }
1052
 
      }
1053
 
      else if (r != Z_BUF_ERROR)
1054
 
      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflate error: %s\n", soap->d_stream.msg?soap->d_stream.msg:""));
1055
 
        soap->d_stream.next_out = Z_NULL;
1056
 
        soap->error = SOAP_ZLIB_ERROR;
1057
 
        return EOF;
1058
 
      }
1059
 
    }
1060
 
zlib_again:
1061
 
    if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK && !soap->chunksize)
1062
 
    { memcpy(soap->buf, soap->z_buf, SOAP_BUFLEN);
1063
 
      soap->buflen = soap->z_buflen;
1064
 
    }
1065
 
    DBGLOG(RECV, SOAP_MESSAGE(fdebug, "\n---- compressed ----\n"));
1066
 
  }
1067
 
#endif
1068
 
#ifndef WITH_NOHTTP
1069
 
  if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) /* read HTTP chunked transfer */
1070
 
  { 
1071
 
chunk_again:
1072
 
    if (soap->chunksize)
1073
 
    { soap->buflen = ret = soap->frecv(soap, soap->buf, soap->chunksize > SOAP_BUFLEN ? SOAP_BUFLEN : soap->chunksize);
1074
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Getting chunk: read %u bytes\n", (unsigned int)ret));
1075
 
      DBGMSG(RECV, soap->buf, ret);
1076
 
      soap->bufidx = 0;
1077
 
      soap->chunksize -= ret;
1078
 
    }
1079
 
    else
1080
 
    { register soap_wchar c;
1081
 
      char *t, tmp[8];
1082
 
      t = tmp;
1083
 
      if (!soap->chunkbuflen)
1084
 
      { soap->chunkbuflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN);
1085
 
        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes (chunked) from socket %d\n", (unsigned int)ret, soap->socket));
1086
 
        DBGMSG(RECV, soap->buf, ret);
1087
 
        soap->bufidx = 0;
1088
 
        if (!ret)
1089
 
          return soap->ahead = EOF;
1090
 
      }
1091
 
      else
1092
 
        soap->bufidx = soap->buflen;
1093
 
      soap->buflen = soap->chunkbuflen;
1094
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Getting chunk size (idx=%u len=%u)\n", (unsigned int)soap->bufidx, (unsigned int)soap->buflen));
1095
 
      while (!soap_isxdigit((int)(c = soap_getchunkchar(soap))))
1096
 
      { if ((int)c == EOF)
1097
 
          return soap->ahead = EOF;
1098
 
      }
1099
 
      do
1100
 
        *t++ = (char)c;
1101
 
      while (soap_isxdigit((int)(c = soap_getchunkchar(soap))) && t - tmp < 7);
1102
 
      while ((int)c != EOF && c != '\n')
1103
 
        c = soap_getchunkchar(soap);
1104
 
      if ((int)c == EOF)
1105
 
        return soap->ahead = EOF;
1106
 
      *t = '\0';
1107
 
      soap->chunksize = soap_strtoul(tmp, &t, 16);
1108
 
      if (!soap->chunksize)
1109
 
      { soap->chunkbuflen = 0;
1110
 
        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of chunked message\n"));
1111
 
        while ((int)c != EOF && c != '\n')
1112
 
          c = soap_getchunkchar(soap);
1113
 
        return soap->ahead = EOF;
1114
 
      }
1115
 
      soap->buflen = soap->bufidx + soap->chunksize;
1116
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Moving buf len to idx=%u len=%u (%s)\n", (unsigned int)soap->bufidx, (unsigned int)soap->buflen, tmp));
1117
 
      if (soap->buflen > soap->chunkbuflen)
1118
 
      { soap->buflen = soap->chunkbuflen;
1119
 
        soap->chunksize -= soap->buflen - soap->bufidx;
1120
 
        soap->chunkbuflen = 0;
1121
 
        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Passed end of buffer for chunked HTTP (%u bytes left)\n", (unsigned int)(soap->buflen - soap->bufidx)));
1122
 
      }
1123
 
      else if (soap->chunkbuflen)
1124
 
        soap->chunksize = 0;
1125
 
      ret = soap->buflen - soap->bufidx;
1126
 
      if (!ret)
1127
 
        goto chunk_again;
1128
 
    }
1129
 
  }
1130
 
  else
1131
 
#endif
1132
 
  { soap->bufidx = 0;
1133
 
    soap->buflen = ret = soap->frecv(soap, soap->buf, SOAP_BUFLEN);
1134
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Read %u bytes from socket %d\n", (unsigned int)ret, soap->socket));
1135
 
    DBGMSG(RECV, soap->buf, ret);
1136
 
  }
1137
 
#ifndef WITH_LEANER
1138
 
  if (soap->fpreparerecv && (soap->error = soap->fpreparerecv(soap, soap->buf, ret)))
1139
 
    return soap->error;
1140
 
#endif
1141
 
#ifdef WITH_ZLIB
1142
 
  if (soap->mode & SOAP_ENC_ZLIB)
1143
 
  { register int r;
1144
 
    memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN);
1145
 
    soap->d_stream.next_in = (Byte*)(soap->z_buf + soap->bufidx);
1146
 
    soap->d_stream.avail_in = (unsigned int)ret;
1147
 
    soap->d_stream.next_out = (Byte*)soap->buf;
1148
 
    soap->d_stream.avail_out = SOAP_BUFLEN;
1149
 
    r = inflate(&soap->d_stream, Z_NO_FLUSH);
1150
 
    if (r == Z_OK || r == Z_STREAM_END)
1151
 
    { soap->bufidx = 0;
1152
 
      soap->z_buflen = soap->buflen;
1153
 
      soap->buflen = ret = SOAP_BUFLEN - soap->d_stream.avail_out;
1154
 
      if (soap->zlib_in == SOAP_ZLIB_GZIP)
1155
 
        soap->z_crc = crc32(soap->z_crc, (Byte*)soap->buf, (unsigned int)soap->buflen);
1156
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %u bytes\n", (unsigned int)ret));
1157
 
      if (!ret)
1158
 
        goto zlib_again;
1159
 
      if (r == Z_STREAM_END)
1160
 
      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflated %lu->%lu bytes\n", soap->d_stream.total_in, soap->d_stream.total_out));
1161
 
        soap->z_ratio_in = (float)soap->d_stream.total_in / (float)soap->d_stream.total_out;
1162
 
        soap->d_stream.next_out = Z_NULL;
1163
 
      }
1164
 
      DBGLOG(RECV, SOAP_MESSAGE(fdebug, "\n---- decompressed ----\n"));
1165
 
      DBGMSG(RECV, soap->buf, ret);
1166
 
    }
1167
 
    else
1168
 
    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to inflate: (%d) %s\n", r, soap->d_stream.msg?soap->d_stream.msg:""));
1169
 
      soap->d_stream.next_out = Z_NULL;
1170
 
      soap->error = SOAP_ZLIB_ERROR;
1171
 
      return EOF;
1172
 
    }
1173
 
  }
1174
 
#endif
1175
 
  soap->count += ret;
1176
 
  return !ret;
1177
 
}
1178
 
#endif
1179
 
 
1180
 
/******************************************************************************/
1181
 
#ifndef PALM_1
1182
 
SOAP_FMAC1
1183
 
int
1184
 
SOAP_FMAC2
1185
 
soap_recv(struct soap *soap)
1186
 
1187
 
#ifndef WITH_LEANER
1188
 
  if (soap->mode & SOAP_ENC_DIME)
1189
 
  { if (soap->dime.buflen)
1190
 
    { char *s;
1191
 
      int i;
1192
 
      unsigned char tmp[12];
1193
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME hdr for chunked DIME is in buffer\n"));
1194
 
      soap->count += soap->dime.buflen - soap->buflen;
1195
 
      soap->buflen = soap->dime.buflen;
1196
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Skip padding (%ld bytes)\n", -(long)soap->dime.size&3));
1197
 
      for (i = -(long)soap->dime.size&3; i > 0; i--)
1198
 
      { soap->bufidx++;
1199
 
        if (soap->bufidx >= soap->buflen)
1200
 
          if (soap_recv_raw(soap))
1201
 
            return EOF;
1202
 
      }
1203
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME hdr for next chunk\n"));
1204
 
      s = (char*)tmp;
1205
 
      for (i = 12; i > 0; i--)
1206
 
      { *s++ = soap->buf[soap->bufidx++];
1207
 
        if (soap->bufidx >= soap->buflen)
1208
 
          if (soap_recv_raw(soap))
1209
 
            return EOF;
1210
 
      }
1211
 
      soap->dime.flags = tmp[0] & 0x7;
1212
 
      soap->dime.size = ((size_t)tmp[8] << 24) | ((size_t)tmp[9] << 16) | ((size_t)tmp[10] << 8) | ((size_t)tmp[11]);
1213
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME chunk (%u bytes)\n", (unsigned int)soap->dime.size));
1214
 
      if (soap->dime.flags & SOAP_DIME_CF)
1215
 
      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "More chunking\n"));
1216
 
        soap->dime.chunksize = soap->dime.size;
1217
 
        if (soap->buflen - soap->bufidx >= soap->dime.size)
1218
 
        { soap->dime.buflen = soap->buflen;
1219
 
          soap->buflen = soap->bufidx + soap->dime.chunksize;
1220
 
        }
1221
 
        else
1222
 
          soap->dime.chunksize -= soap->buflen - soap->bufidx;
1223
 
      }
1224
 
      else
1225
 
      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Last chunk\n"));
1226
 
        soap->dime.buflen = 0;
1227
 
        soap->dime.chunksize = 0;
1228
 
      }
1229
 
      soap->count = soap->buflen - soap->bufidx;
1230
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%u bytes remaining\n", (unsigned int)soap->count));
1231
 
      return SOAP_OK;
1232
 
    }
1233
 
    if (soap->dime.chunksize)
1234
 
    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get next DIME hdr for chunked DIME (%u bytes chunk)\n", (unsigned int)soap->dime.chunksize));
1235
 
      if (soap_recv_raw(soap))
1236
 
        return EOF;
1237
 
      if (soap->buflen - soap->bufidx >= soap->dime.chunksize)
1238
 
      { soap->dime.buflen = soap->buflen;
1239
 
        soap->count -= soap->buflen - soap->bufidx - soap->dime.chunksize;
1240
 
        soap->buflen = soap->bufidx + soap->dime.chunksize;
1241
 
      }
1242
 
      else
1243
 
        soap->dime.chunksize -= soap->buflen - soap->bufidx;
1244
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%lu bytes remaining, count=%u\n", (unsigned long)(soap->buflen-soap->bufidx), (unsigned int)soap->count));
1245
 
      return SOAP_OK;
1246
 
    }
1247
 
  }
1248
 
#endif
1249
 
  return soap_recv_raw(soap);
1250
 
}
1251
 
#endif
1252
 
 
1253
 
/******************************************************************************/
1254
 
#ifndef PALM_1
1255
 
SOAP_FMAC1
1256
 
soap_wchar
1257
 
SOAP_FMAC2
1258
 
soap_getchar(struct soap *soap)
1259
 
{ register soap_wchar c;
1260
 
  c = soap->ahead;
1261
 
  if (c)
1262
 
  { if (c != EOF)
1263
 
      soap->ahead = 0;
1264
 
    return c;
1265
 
  }
1266
 
  return soap_get1(soap);
1267
 
}
1268
 
#endif
1269
 
 
1270
 
/******************************************************************************/
1271
 
#ifndef PALM_1
1272
 
SOAP_FMAC1
1273
 
const struct soap_code_map*
1274
 
SOAP_FMAC2
1275
 
soap_code(const struct soap_code_map *code_map, const char *str)
1276
 
{ if (code_map && str)
1277
 
  { while (code_map->string)
1278
 
    { if (!strcmp(str, code_map->string)) /* case sensitive */
1279
 
        return code_map;
1280
 
      code_map++;
1281
 
    }
1282
 
  }
1283
 
  return NULL;
1284
 
}
1285
 
#endif
1286
 
 
1287
 
/******************************************************************************/
1288
 
#ifndef PALM_1
1289
 
SOAP_FMAC1
1290
 
long
1291
 
SOAP_FMAC2
1292
 
soap_code_int(const struct soap_code_map *code_map, const char *str, long other)
1293
 
{ if (code_map)
1294
 
  { while (code_map->string)
1295
 
    { if (!soap_tag_cmp(str, code_map->string)) /* case insensitive */
1296
 
        return code_map->code;
1297
 
      code_map++;
1298
 
    }
1299
 
  }
1300
 
  return other;
1301
 
}
1302
 
#endif
1303
 
 
1304
 
/******************************************************************************/
1305
 
#ifndef PALM_1
1306
 
SOAP_FMAC1
1307
 
const char*
1308
 
SOAP_FMAC2
1309
 
soap_code_str(const struct soap_code_map *code_map, long code)
1310
 
{ if (!code_map)
1311
 
    return NULL;
1312
 
  while (code_map->code != code && code_map->string)
1313
 
    code_map++;
1314
 
  return code_map->string;
1315
 
}
1316
 
#endif
1317
 
 
1318
 
/******************************************************************************/
1319
 
#ifndef PALM_1
1320
 
SOAP_FMAC1
1321
 
long
1322
 
SOAP_FMAC2
1323
 
soap_code_bits(const struct soap_code_map *code_map, const char *str)
1324
 
{ register long bits = 0;
1325
 
  if (code_map)
1326
 
  { while (str && *str)
1327
 
    { const struct soap_code_map *p;
1328
 
      for (p = code_map; p->string; p++)
1329
 
      { register size_t n = strlen(p->string);
1330
 
        if (!strncmp(p->string, str, n) && soap_blank(str[n]))
1331
 
        { bits |= p->code;
1332
 
          str += n;
1333
 
          while (*str > 0 && *str <= 32)
1334
 
            str++;
1335
 
          break;
1336
 
        }
1337
 
      }
1338
 
      if (!p->string)
1339
 
        return 0;
1340
 
    }
1341
 
  }
1342
 
  return bits;
1343
 
}
1344
 
#endif
1345
 
 
1346
 
/******************************************************************************/
1347
 
#ifndef PALM_1
1348
 
SOAP_FMAC1
1349
 
const char*
1350
 
SOAP_FMAC2
1351
 
soap_code_list(struct soap *soap, const struct soap_code_map *code_map, long code)
1352
 
{ register char *t = soap->tmpbuf;
1353
 
  if (code_map)
1354
 
  { while (code_map->string)
1355
 
    { if (code_map->code & code)
1356
 
      { register const char *s = code_map->string;
1357
 
        if (t != soap->tmpbuf)
1358
 
          *t++ = ' ';
1359
 
        while (*s && t < soap->tmpbuf + sizeof(soap->tmpbuf) - 1)
1360
 
          *t++ = *s++;
1361
 
        if (t == soap->tmpbuf + sizeof(soap->tmpbuf) - 1)
1362
 
          break;
1363
 
      }
1364
 
      code_map++;
1365
 
    }
1366
 
  }
1367
 
  *t = '\0';
1368
 
  return soap->tmpbuf;
1369
 
}
1370
 
#endif
1371
 
 
1372
 
/******************************************************************************/
1373
 
#ifndef PALM_1
1374
 
static soap_wchar
1375
 
soap_char(struct soap *soap)
1376
 
{ char tmp[8];
1377
 
  register int i;
1378
 
  register soap_wchar c;
1379
 
  register char *s = tmp;
1380
 
  for (i = 0; i < 7; i++)
1381
 
  { c = soap_get1(soap);
1382
 
    if (c == ';' || (int)c == EOF)
1383
 
      break;
1384
 
    *s++ = (char)c;
1385
 
  }
1386
 
  *s = '\0';
1387
 
  if (*tmp == '#')
1388
 
  { if (tmp[1] == 'x' || tmp[1] == 'X')
1389
 
      return soap_strtol(tmp + 2, NULL, 16);
1390
 
    return atol(tmp + 1);
1391
 
  }
1392
 
  if (!strcmp(tmp, "lt"))
1393
 
    return '<';
1394
 
  if (!strcmp(tmp, "gt"))
1395
 
    return '>';
1396
 
  if (!strcmp(tmp, "amp"))
1397
 
    return '&';
1398
 
  if (!strcmp(tmp, "quot"))
1399
 
    return '"';
1400
 
  if (!strcmp(tmp, "apos"))
1401
 
    return '\'';
1402
 
#ifndef WITH_LEAN
1403
 
  return (soap_wchar)soap_code_int(html_entity_codes, tmp, SOAP_UNKNOWN_CHAR);
1404
 
#else
1405
 
  return SOAP_UNKNOWN_CHAR; /* use this to represent unknown code */
1406
 
#endif
1407
 
}
1408
 
#endif
1409
 
 
1410
 
/******************************************************************************/
1411
 
#ifdef WITH_LEAN
1412
 
#ifndef PALM_1
1413
 
soap_wchar
1414
 
soap_get0(struct soap *soap)
1415
 
{ if (soap->bufidx >= soap->buflen && soap_recv(soap))
1416
 
    return EOF;
1417
 
  return (unsigned char)soap->buf[soap->bufidx];
1418
 
}
1419
 
#endif
1420
 
#endif
1421
 
 
1422
 
/******************************************************************************/
1423
 
#ifdef WITH_LEAN
1424
 
#ifndef PALM_1
1425
 
soap_wchar
1426
 
soap_get1(struct soap *soap)
1427
 
{ if (soap->bufidx >= soap->buflen && soap_recv(soap))
1428
 
    return EOF;
1429
 
  return (unsigned char)soap->buf[soap->bufidx++];
1430
 
}
1431
 
#endif
1432
 
#endif
1433
 
 
1434
 
/******************************************************************************/
1435
 
#ifndef PALM_1
1436
 
SOAP_FMAC1
1437
 
soap_wchar
1438
 
SOAP_FMAC2
1439
 
soap_get(struct soap *soap)
1440
 
{ register soap_wchar c;
1441
 
  c = soap->ahead;
1442
 
  if (c)
1443
 
  { if ((int)c != EOF)
1444
 
      soap->ahead = 0;
1445
 
  }
1446
 
  else
1447
 
    c = soap_get1(soap);
1448
 
  while ((int)c != EOF)
1449
 
  { if (soap->cdata)
1450
 
    { if (c == ']')
1451
 
      { c = soap_get1(soap);
1452
 
        if (c == ']')
1453
 
        { c = soap_get0(soap);
1454
 
          if (c == '>')
1455
 
          { soap->cdata = 0;
1456
 
            soap_get1(soap);
1457
 
            c = soap_get1(soap);
1458
 
          }
1459
 
          else
1460
 
          { soap_unget(soap, ']');
1461
 
            return ']';
1462
 
          }
1463
 
        }
1464
 
        else
1465
 
        { soap_revget1(soap);
1466
 
          return ']';
1467
 
        }
1468
 
      }
1469
 
      else
1470
 
        return c;
1471
 
    }
1472
 
    switch (c)
1473
 
    { case '<':
1474
 
        do c = soap_get1(soap);
1475
 
        while (soap_blank(c));
1476
 
        if (c == '!' || c == '?' || c == '%')
1477
 
        { register int k = 1;
1478
 
          if (c == '!')
1479
 
          { c = soap_get1(soap);
1480
 
            if (c == '[')
1481
 
            { do c = soap_get1(soap);
1482
 
              while ((int)c != EOF && c != '[');
1483
 
              if ((int)c == EOF)
1484
 
                break;
1485
 
              soap->cdata = 1;
1486
 
              c = soap_get1(soap);
1487
 
              continue;
1488
 
            }
1489
 
            if (c == '-' && (c = soap_get1(soap)) == '-')
1490
 
            { do
1491
 
              { c = soap_get1(soap);
1492
 
                if (c == '-' && (c = soap_get1(soap)) == '-')
1493
 
                  break;
1494
 
              } while ((int)c != EOF);
1495
 
            }
1496
 
          }
1497
 
          else if (c == '?')
1498
 
            c = soap_get_pi(soap);
1499
 
          while ((int)c != EOF)
1500
 
          { if (c == '<')
1501
 
              k++;
1502
 
            else if (c == '>')
1503
 
            { if (--k <= 0)
1504
 
                break;
1505
 
            }
1506
 
            c = soap_get1(soap);
1507
 
          }
1508
 
          if ((int)c == EOF)
1509
 
            break;
1510
 
          c = soap_get1(soap);
1511
 
          continue;
1512
 
        }
1513
 
        if (c == '/')
1514
 
          return SOAP_TT;
1515
 
        soap_revget1(soap);
1516
 
        return SOAP_LT;
1517
 
      case '>':
1518
 
        return SOAP_GT;
1519
 
      case '"':
1520
 
        return SOAP_QT;
1521
 
      case '\'':
1522
 
        return SOAP_AP;
1523
 
      case '&':
1524
 
        return soap_char(soap) | 0x80000000;
1525
 
    }
1526
 
    break;
1527
 
  }
1528
 
  return c;
1529
 
}
1530
 
#endif
1531
 
 
1532
 
/******************************************************************************/
1533
 
#ifndef PALM_1
1534
 
static soap_wchar
1535
 
soap_get_pi(struct soap *soap)
1536
 
{ char buf[64];
1537
 
  register char *s = buf;
1538
 
  register int i = sizeof(buf);
1539
 
  register soap_wchar c = soap_getchar(soap);
1540
 
  /* This is a quick way to parse XML PI and we could use a callback instead to
1541
 
   * enable applications to intercept processing instructions */
1542
 
  while ((int)c != EOF && c != '?')
1543
 
  { if (--i > 0)
1544
 
    { if (soap_blank(c))
1545
 
        c = ' ';
1546
 
      *s++ = (char)c;
1547
 
    }
1548
 
    c = soap_getchar(soap);
1549
 
  }
1550
 
  *s = '\0';
1551
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "XML PI <?%s?>\n", buf));
1552
 
  if (!strncmp(buf, "xml ", 4))
1553
 
  { s = strstr(buf, " encoding=");
1554
 
    if (s && s[10])
1555
 
    { if (!soap_tag_cmp(s + 11, "iso-8859-1*")
1556
 
       || !soap_tag_cmp(s + 11, "latin1*"))
1557
 
      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Switching to latin1 encoding\n"));
1558
 
        soap->mode |= SOAP_ENC_LATIN;
1559
 
      }
1560
 
      else if (!soap_tag_cmp(s + 11, "utf-8*"))
1561
 
      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Switching to utf-8 encoding\n"));
1562
 
        soap->mode &= ~SOAP_ENC_LATIN;
1563
 
      }
1564
 
    }
1565
 
  }
1566
 
  if ((int)c != EOF)
1567
 
    c = soap_getchar(soap);
1568
 
  return c;
1569
 
}
1570
 
#endif
1571
 
 
1572
 
/******************************************************************************/
1573
 
#ifndef WITH_LEANER
1574
 
#ifndef PALM_1
1575
 
SOAP_FMAC1
1576
 
int
1577
 
SOAP_FMAC2
1578
 
soap_move(struct soap *soap, long n)
1579
 
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Moving %ld bytes forward\n", (long)n));
1580
 
  for (; n > 0; n--)
1581
 
    if ((int)soap_getchar(soap) == EOF)
1582
 
      return SOAP_EOF;
1583
 
  return SOAP_OK;
1584
 
}
1585
 
#endif
1586
 
#endif
1587
 
 
1588
 
/******************************************************************************/
1589
 
#ifndef WITH_LEANER
1590
 
#ifndef PALM_1
1591
 
SOAP_FMAC1
1592
 
size_t
1593
 
SOAP_FMAC2
1594
 
soap_tell(struct soap *soap)
1595
 
{ return soap->count - soap->buflen + soap->bufidx - (soap->ahead != 0);
1596
 
}
1597
 
#endif
1598
 
#endif
1599
 
 
1600
 
/******************************************************************************/
1601
 
#ifndef PALM_1
1602
 
SOAP_FMAC1
1603
 
int
1604
 
SOAP_FMAC2
1605
 
soap_pututf8(struct soap *soap, register unsigned long c)
1606
 
{ char tmp[16];
1607
 
  if (c < 0x80 && c >= 0x20)
1608
 
  { *tmp = (char)c;
1609
 
    return soap_send_raw(soap, tmp, 1);
1610
 
  }
1611
 
#ifndef WITH_LEAN
1612
 
  if (c >= 0x80 && (soap->mode & SOAP_XML_CANONICAL))
1613
 
  { register char *t = tmp;
1614
 
    if (c < 0x0800)
1615
 
      *t++ = (char)(0xC0 | ((c >> 6) & 0x1F));
1616
 
    else
1617
 
    { if (c < 0x010000)
1618
 
        *t++ = (char)(0xE0 | ((c >> 12) & 0x0F));
1619
 
      else
1620
 
      { if (c < 0x200000)
1621
 
          *t++ = (char)(0xF0 | ((c >> 18) & 0x07));
1622
 
        else
1623
 
        { if (c < 0x04000000)
1624
 
            *t++ = (char)(0xF8 | ((c >> 24) & 0x03));
1625
 
          else
1626
 
          { *t++ = (char)(0xFC | ((c >> 30) & 0x01));
1627
 
            *t++ = (char)(0x80 | ((c >> 24) & 0x3F));
1628
 
          }
1629
 
          *t++ = (char)(0x80 | ((c >> 18) & 0x3F));
1630
 
        }     
1631
 
        *t++ = (char)(0x80 | ((c >> 12) & 0x3F));
1632
 
      }
1633
 
      *t++ = (char)(0x80 | ((c >> 6) & 0x3F));
1634
 
    }
1635
 
    *t++ = (char)(0x80 | (c & 0x3F));
1636
 
    *t = '\0';
1637
 
  }
1638
 
  else
1639
 
#endif
1640
 
    sprintf(tmp, "&#%lu;", c);
1641
 
  return soap_send(soap, tmp);
1642
 
}
1643
 
#endif
1644
 
 
1645
 
/******************************************************************************/
1646
 
#ifndef PALM_1
1647
 
SOAP_FMAC1
1648
 
soap_wchar
1649
 
SOAP_FMAC2
1650
 
soap_getutf8(struct soap *soap)
1651
 
{ register soap_wchar c, c1, c2, c3, c4;
1652
 
  c = soap->ahead;
1653
 
  if (c > 0xFF)
1654
 
  { soap->ahead = 0;
1655
 
    return c;
1656
 
  }
1657
 
again:
1658
 
  c = soap_get(soap);
1659
 
  if (c < 0x80 || (soap->mode & SOAP_ENC_LATIN))
1660
 
    return c;
1661
 
  c1 = soap_get1(soap);
1662
 
  if (c1 < 0x80)
1663
 
  { soap_revget1(soap); /* doesn't look like this is UTF8 */
1664
 
    return c;
1665
 
  }
1666
 
  c1 &= 0x3F;
1667
 
  if (c < 0xE0)
1668
 
    return ((soap_wchar)(c & 0x1F) << 6) | c1;
1669
 
  c2 = (soap_wchar)soap_get1(soap) & 0x3F;
1670
 
  if (c == 0xEF && c1 == 0x3B && c2 == 0x3F)    /* ignore UTF-8 BOM */
1671
 
    goto again;
1672
 
  if (c < 0xF0)
1673
 
    return ((soap_wchar)(c & 0x0F) << 12) | (c1 << 6) | c2;
1674
 
  c3 = (soap_wchar)soap_get1(soap) & 0x3F;
1675
 
  if (c < 0xF8)
1676
 
    return ((soap_wchar)(c & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3;
1677
 
  c4 = (soap_wchar)soap_get1(soap) & 0x3F;
1678
 
  if (c < 0xFC)
1679
 
    return ((soap_wchar)(c & 0x03) << 24) | (c1 << 18) | (c2 << 12) | (c3 << 6) | c4;
1680
 
  return ((soap_wchar)(c & 0x01) << 30) | (c1 << 24) | (c2 << 18) | (c3 << 12) | (c4 << 6) | (soap_wchar)(soap_get1(soap) & 0x3F);
1681
 
}
1682
 
#endif
1683
 
 
1684
 
/******************************************************************************/
1685
 
#ifndef PALM_1
1686
 
SOAP_FMAC1
1687
 
int
1688
 
SOAP_FMAC2
1689
 
soap_puthex(struct soap *soap, const unsigned char *s, int n)
1690
 
{ char d[2];
1691
 
  register int i;
1692
 
#ifdef WITH_DOM
1693
 
  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
1694
 
  { if (!(soap->dom->data = soap_s2hex(soap, s, NULL, n)))
1695
 
      return soap->error;
1696
 
    return SOAP_OK;
1697
 
  }
1698
 
#endif
1699
 
  for (i = 0; i < n; i++)
1700
 
  { register int m = *s++;
1701
 
    d[0] = (char)((m >> 4) + (m > 159 ? '7' : '0'));
1702
 
    m &= 0x0F;
1703
 
    d[1] = (char)(m + (m > 9 ? '7' : '0'));
1704
 
    if (soap_send_raw(soap, d, 2))
1705
 
      return soap->error;
1706
 
  }
1707
 
  return SOAP_OK;
1708
 
}
1709
 
#endif
1710
 
 
1711
 
/******************************************************************************/
1712
 
#ifndef PALM_1
1713
 
SOAP_FMAC1
1714
 
unsigned char*
1715
 
SOAP_FMAC2
1716
 
soap_gethex(struct soap *soap, int *n)
1717
 
{
1718
 
#ifdef WITH_DOM
1719
 
  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
1720
 
  { soap->dom->data = soap_string_in(soap, 0, -1, -1);
1721
 
    return (unsigned char*)soap_hex2s(soap, soap->dom->data, NULL, 0, n);
1722
 
  }
1723
 
#endif
1724
 
#ifdef WITH_FAST
1725
 
  soap->labidx = 0;
1726
 
  for (;;)
1727
 
  { register char *s;
1728
 
    register size_t i, k;
1729
 
    if (soap_append_lab(soap, NULL, 0))
1730
 
      return NULL;
1731
 
    s = soap->labbuf + soap->labidx;
1732
 
    k = soap->lablen - soap->labidx;
1733
 
    soap->labidx = soap->lablen;
1734
 
    for (i = 0; i < k; i++)
1735
 
    { register char d1, d2;
1736
 
      register soap_wchar c;
1737
 
      c = soap_get(soap);
1738
 
      if (soap_isxdigit(c))
1739
 
      { d1 = (char)c;
1740
 
        c = soap_get(soap); 
1741
 
        if (soap_isxdigit(c))
1742
 
          d2 = (char)c;
1743
 
        else 
1744
 
        { soap->error = SOAP_TYPE;
1745
 
          return NULL;
1746
 
        }
1747
 
      }
1748
 
      else
1749
 
      { unsigned char *p;
1750
 
        soap_unget(soap, c);
1751
 
        if (n)
1752
 
          *n = (int)(soap->lablen + i - k);
1753
 
        p = (unsigned char*)soap_malloc(soap, soap->lablen + i - k);
1754
 
        if (p)
1755
 
          memcpy(p, soap->labbuf, soap->lablen + i - k);
1756
 
        return p;
1757
 
      }
1758
 
      *s++ = ((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0');
1759
 
    }
1760
 
  }
1761
 
#else
1762
 
  if (soap_new_block(soap))
1763
 
    return NULL;
1764
 
  for (;;)
1765
 
  { register int i;
1766
 
    register char *s = (char*)soap_push_block(soap, SOAP_BLKLEN);
1767
 
    if (!s)
1768
 
    { soap_end_block(soap);
1769
 
      return NULL;
1770
 
    }
1771
 
    for (i = 0; i < SOAP_BLKLEN; i++)
1772
 
    { register char d1, d2;
1773
 
      register soap_wchar c = soap_get(soap);
1774
 
      if (soap_isxdigit(c))
1775
 
      { d1 = (char)c;
1776
 
        c = soap_get(soap); 
1777
 
        if (soap_isxdigit(c))
1778
 
          d2 = (char)c;
1779
 
        else 
1780
 
        { soap_end_block(soap);
1781
 
          soap->error = SOAP_TYPE;
1782
 
          return NULL;
1783
 
        }
1784
 
      }
1785
 
      else
1786
 
      { unsigned char *p;
1787
 
        soap_unget(soap, c);
1788
 
        if (n)
1789
 
          *n = (int)soap_size_block(soap, i);
1790
 
        p = (unsigned char*)soap_save_block(soap, NULL, 0);
1791
 
        return p;
1792
 
      }
1793
 
      *s++ = ((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0');
1794
 
    }
1795
 
  }
1796
 
#endif
1797
 
}
1798
 
#endif
1799
 
 
1800
 
/******************************************************************************/
1801
 
#ifndef PALM_1
1802
 
SOAP_FMAC1
1803
 
int
1804
 
SOAP_FMAC2
1805
 
soap_putbase64(struct soap *soap, const unsigned char *s, int n)
1806
 
{ register int i;
1807
 
  register unsigned long m;
1808
 
  char d[4];
1809
 
  if (!s)
1810
 
    return SOAP_OK;
1811
 
#ifdef WITH_DOM
1812
 
  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
1813
 
  { if (!(soap->dom->data = soap_s2base64(soap, s, NULL, n)))
1814
 
      return soap->error;
1815
 
    return SOAP_OK;
1816
 
  }
1817
 
#endif
1818
 
  for (; n > 2; n -= 3, s += 3)
1819
 
  { m = s[0];
1820
 
    m = (m << 8) | s[1];
1821
 
    m = (m << 8) | s[2];
1822
 
    for (i = 4; i > 0; m >>= 6)
1823
 
      d[--i] = soap_base64o[m & 0x3F];
1824
 
    if (soap_send_raw(soap, d, 4))
1825
 
      return soap->error;
1826
 
  }
1827
 
  if (n > 0)
1828
 
  { m = 0;
1829
 
    for (i = 0; i < n; i++)
1830
 
      m = (m << 8) | *s++;
1831
 
    for (; i < 3; i++)
1832
 
      m <<= 8;
1833
 
    for (i++; i > 0; m >>= 6)
1834
 
      d[--i] = soap_base64o[m & 0x3F];
1835
 
    for (i = 3; i > n; i--)
1836
 
      d[i] = '=';
1837
 
    if (soap_send_raw(soap, d, 4))
1838
 
      return soap->error;
1839
 
  }
1840
 
  return SOAP_OK;
1841
 
}
1842
 
#endif
1843
 
 
1844
 
/******************************************************************************/
1845
 
#ifndef PALM_1
1846
 
SOAP_FMAC1
1847
 
unsigned char*
1848
 
SOAP_FMAC2
1849
 
soap_getbase64(struct soap *soap, int *n, int malloc_flag)
1850
 
1851
 
#ifdef WITH_DOM
1852
 
  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
1853
 
  { soap->dom->data = soap_string_in(soap, 0, -1, -1);
1854
 
    return (unsigned char*)soap_base642s(soap, soap->dom->data, NULL, 0, n);
1855
 
  }
1856
 
#endif
1857
 
#ifdef WITH_FAST
1858
 
  soap->labidx = 0;
1859
 
  for (;;)
1860
 
  { register size_t i, k;
1861
 
    register char *s;
1862
 
    if (soap_append_lab(soap, NULL, 2))
1863
 
      return NULL;
1864
 
    s = soap->labbuf + soap->labidx;
1865
 
    k = soap->lablen - soap->labidx;
1866
 
    soap->labidx = 3 * (soap->lablen / 3);
1867
 
    if (!s)
1868
 
      return NULL;
1869
 
    if (k > 2)
1870
 
    { for (i = 0; i < k - 2; i += 3)
1871
 
      { register unsigned long m = 0;
1872
 
        register int j = 0;
1873
 
        do
1874
 
        { register soap_wchar c = soap_get(soap);
1875
 
          if (c == '=' || c < 0)
1876
 
          { unsigned char *p;
1877
 
            switch (j)
1878
 
            { case 2:
1879
 
                *s++ = (char)((m >> 4) & 0xFF);
1880
 
                i++;
1881
 
                break;
1882
 
              case 3:
1883
 
                *s++ = (char)((m >> 10) & 0xFF);
1884
 
                *s++ = (char)((m >> 2) & 0xFF);
1885
 
                i += 2;
1886
 
            }
1887
 
            if (n)
1888
 
              *n = (int)(soap->lablen + i - k);
1889
 
            p = (unsigned char*)soap_malloc(soap, soap->lablen + i - k);
1890
 
            if (p)
1891
 
              memcpy(p, soap->labbuf, soap->lablen + i - k);
1892
 
            if (c >= 0)
1893
 
            { while ((int)((c = soap_get(soap)) != EOF) && c != SOAP_LT && c != SOAP_TT)
1894
 
                ;
1895
 
            }
1896
 
            soap_unget(soap, c);
1897
 
            return p;
1898
 
          }
1899
 
          c -= '+';
1900
 
          if (c >= 0 && c <= 79)
1901
 
          { register int b = soap_base64i[c];
1902
 
            if (b >= 64)
1903
 
            { soap->error = SOAP_TYPE;
1904
 
              return NULL;  
1905
 
            }
1906
 
            m = (m << 6) + b;
1907
 
            j++;
1908
 
          }
1909
 
          else if (!soap_blank(c + '+'))
1910
 
          { soap->error = SOAP_TYPE;
1911
 
            return NULL;  
1912
 
          }
1913
 
        } while (j < 4);
1914
 
        *s++ = (char)((m >> 16) & 0xFF);
1915
 
        *s++ = (char)((m >> 8) & 0xFF);
1916
 
        *s++ = (char)(m & 0xFF);
1917
 
      }
1918
 
    }
1919
 
  }
1920
 
#else
1921
 
  if (soap_new_block(soap))
1922
 
    return NULL;
1923
 
  for (;;)
1924
 
  { register int i;
1925
 
    register char *s = (char*)soap_push_block(soap, 3 * SOAP_BLKLEN); /* must be multiple of 3 */
1926
 
    if (!s)
1927
 
    { soap_end_block(soap);
1928
 
      return NULL;
1929
 
    }
1930
 
    for (i = 0; i < SOAP_BLKLEN; i++)
1931
 
    { register unsigned long m = 0;
1932
 
      register int j = 0;
1933
 
      do
1934
 
      { register soap_wchar c = soap_get(soap);
1935
 
        if (c == '=' || c < 0)
1936
 
        { unsigned char *p;
1937
 
          i *= 3;
1938
 
          switch (j)
1939
 
          { case 2:
1940
 
              *s++ = (char)((m >> 4) & 0xFF);
1941
 
              i++;
1942
 
              break;
1943
 
            case 3:
1944
 
              *s++ = (char)((m >> 10) & 0xFF);
1945
 
              *s++ = (char)((m >> 2) & 0xFF);
1946
 
              i += 2;
1947
 
          }
1948
 
          if (n)
1949
 
            *n = (int)soap_size_block(soap, i);
1950
 
          p = (unsigned char*)soap_save_block(soap, NULL, 0);
1951
 
          if (c >= 0)
1952
 
          { while ((int)((c = soap_get(soap)) != EOF) && c != SOAP_LT && c != SOAP_TT)
1953
 
              ;
1954
 
          }
1955
 
          soap_unget(soap, c);
1956
 
          return p;
1957
 
        }
1958
 
        c -= '+';
1959
 
        if (c >= 0 && c <= 79)
1960
 
        { int b = soap_base64i[c];
1961
 
          if (b >= 64)
1962
 
          { soap->error = SOAP_TYPE;
1963
 
            return NULL;  
1964
 
          }
1965
 
          m = (m << 6) + b;
1966
 
          j++;
1967
 
        }
1968
 
        else if (!soap_blank(c))
1969
 
        { soap->error = SOAP_TYPE;
1970
 
          return NULL;  
1971
 
        }
1972
 
      } while (j < 4);
1973
 
      *s++ = (char)((m >> 16) & 0xFF);
1974
 
      *s++ = (char)((m >> 8) & 0xFF);
1975
 
      *s++ = (char)(m & 0xFF);
1976
 
    }
1977
 
  }
1978
 
#endif
1979
 
}
1980
 
#endif
1981
 
 
1982
 
/******************************************************************************/
1983
 
#ifndef WITH_LEANER
1984
 
#ifndef PALM_1
1985
 
SOAP_FMAC1
1986
 
int
1987
 
SOAP_FMAC2
1988
 
soap_xop_forward(struct soap *soap, unsigned char **ptr, int *size, char **id, char **type, char **options)
1989
 
{ /* Check MTOM xop:Include element (within hex/base64Binary) */
1990
 
  /* TODO: this code to be obsoleted with new import/xop.h conventions */
1991
 
  int body = soap->body; /* should save type too? */
1992
 
  if (!soap_peek_element(soap))
1993
 
  { if (!soap_element_begin_in(soap, "xop:Include", 0, NULL) && *soap->href)
1994
 
    { if (soap_dime_forward(soap, ptr, size, id, type, options))
1995
 
        return soap->error;
1996
 
    }
1997
 
    if (soap->body && soap_element_end_in(soap, NULL))
1998
 
      return soap->error;
1999
 
  }
2000
 
  soap->body = body;
2001
 
  return SOAP_OK;
2002
 
}
2003
 
#endif
2004
 
#endif
2005
 
 
2006
 
/******************************************************************************/
2007
 
#ifndef WITH_LEANER
2008
 
#ifndef PALM_1
2009
 
SOAP_FMAC1
2010
 
int
2011
 
SOAP_FMAC2
2012
 
soap_dime_forward(struct soap *soap, unsigned char **ptr, int *size, char **id, char **type, char **options)
2013
 
{ struct soap_xlist *xp = (struct soap_xlist*)SOAP_MALLOC(soap, sizeof(struct soap_xlist));
2014
 
  *ptr = NULL;
2015
 
  *size = 0;
2016
 
  *id = soap_strdup(soap, soap->href);
2017
 
  *type = NULL;
2018
 
  *options = NULL;
2019
 
  if (!xp)
2020
 
    return soap->error = SOAP_EOM;
2021
 
  xp->next = soap->xlist;
2022
 
  xp->ptr = ptr;
2023
 
  xp->size = size;
2024
 
  xp->id = *id;
2025
 
  xp->type = type;
2026
 
  xp->options = options;
2027
 
  soap->xlist = xp;
2028
 
  return SOAP_OK;
2029
 
}
2030
 
#endif
2031
 
#endif
2032
 
 
2033
 
/******************************************************************************/
2034
 
#ifndef PALM_1
2035
 
SOAP_FMAC1
2036
 
char *
2037
 
SOAP_FMAC2
2038
 
soap_strdup(struct soap *soap, const char *s)
2039
 
{ char *t = NULL;
2040
 
  if (s && (t = (char*)soap_malloc(soap, strlen(s) + 1)))
2041
 
    strcpy(t, s);
2042
 
  return t;
2043
 
}
2044
 
#endif
2045
 
 
2046
 
/******************************************************************************/
2047
 
#ifndef PALM_1
2048
 
SOAP_FMAC1
2049
 
int
2050
 
SOAP_FMAC2
2051
 
soap_new_block(struct soap *soap)
2052
 
{ struct soap_blist *p;
2053
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "New block sequence (prev=%p)\n", soap->blist));
2054
 
  if (!(p = (struct soap_blist*)SOAP_MALLOC(soap, sizeof(struct soap_blist))))
2055
 
    return SOAP_EOM;   
2056
 
  p->next = soap->blist; 
2057
 
  p->ptr = NULL;
2058
 
  p->size = 0;
2059
 
  soap->blist = p;
2060
 
  return SOAP_OK;
2061
 
}
2062
 
#endif
2063
 
 
2064
 
/******************************************************************************/
2065
 
#ifndef PALM_1
2066
 
SOAP_FMAC1
2067
 
void*
2068
 
SOAP_FMAC2
2069
 
soap_push_block(struct soap *soap, size_t n)
2070
 
{ char *p;
2071
 
  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));
2072
 
  if (!(p = (char*)SOAP_MALLOC(soap, n + sizeof(char*) + sizeof(size_t))))
2073
 
  { soap->error = SOAP_EOM;
2074
 
    return NULL;
2075
 
  }
2076
 
  *(char**)p = soap->blist->ptr;
2077
 
  *(size_t*)(p + sizeof(char*)) = n;
2078
 
  soap->blist->ptr = p;
2079
 
  soap->blist->size += n;
2080
 
  return p + sizeof(char*) + sizeof(size_t);
2081
 
}
2082
 
#endif
2083
 
 
2084
 
/******************************************************************************/
2085
 
#ifndef PALM_1
2086
 
SOAP_FMAC1
2087
 
void
2088
 
SOAP_FMAC2
2089
 
soap_pop_block(struct soap *soap)
2090
 
{ char *p;
2091
 
  if (!soap->blist->ptr)
2092
 
    return;
2093
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Pop block\n"));
2094
 
  p = soap->blist->ptr;
2095
 
  soap->blist->size -= *(size_t*)(p + sizeof(char*));
2096
 
  soap->blist->ptr = *(char**)p;
2097
 
  SOAP_FREE(soap, p);
2098
 
}
2099
 
#endif
2100
 
 
2101
 
/******************************************************************************/
2102
 
#ifndef WITH_NOIDREF
2103
 
#ifndef PALM_1
2104
 
static void
2105
 
soap_update_ptrs(struct soap *soap, char *start, char *end, char *p1, char *p2)
2106
 
{ int i;
2107
 
  register struct soap_ilist *ip = NULL;
2108
 
  register struct soap_flist *fp = NULL;
2109
 
#ifndef WITH_LEANER
2110
 
  register struct soap_xlist *xp = NULL;
2111
 
#endif
2112
 
  register void *p, **q;
2113
 
  for (i = 0; i < SOAP_IDHASH; i++)
2114
 
  { for (ip = soap->iht[i]; ip; ip = ip->next)
2115
 
    { if (ip->ptr && (char*)ip->ptr >= start && (char*)ip->ptr < end)
2116
 
      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update id='%s' %p -> %p\n", ip->id, ip->ptr, (char*)ip->ptr + (p1-p2)));
2117
 
        ip->ptr = (char*)ip->ptr + (p1-p2);
2118
 
      }
2119
 
      for (q = &ip->link; q; q = (void**)p)
2120
 
      { p = *q;
2121
 
        if (p && (char*)p >= start && (char*)p < end)
2122
 
        { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Link update id='%s' %p\n", ip->id, p));
2123
 
          *q = (char*)p + (p1-p2);
2124
 
        }
2125
 
      }
2126
 
      for (q = &ip->copy; q; q = (void**)p)
2127
 
      { p = *q;
2128
 
        if (p && (char*)p >= start && (char*)p < end)
2129
 
        { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy chain update id='%s' %p\n", ip->id, p));
2130
 
          *q = (char*)p + (p1-p2);
2131
 
        }
2132
 
      }
2133
 
      for (fp = ip->flist; fp; fp = fp->next)
2134
 
      { if ((char*)fp->ptr >= start && (char*)fp->ptr < end)
2135
 
        { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy list update id='%s' %p\n", ip->id, fp));
2136
 
          fp->ptr = (char*)fp->ptr + (p1-p2);
2137
 
        }
2138
 
      }
2139
 
    }
2140
 
  }
2141
 
#ifndef WITH_LEANER
2142
 
  for (xp = soap->xlist; xp; xp = xp->next)
2143
 
  { if (xp->ptr && (char*)xp->ptr >= start && (char*)xp->ptr < end)
2144
 
    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Update id='%s' %p -> %p\n", xp->id?xp->id:"", xp->ptr, (char*)xp->ptr + (p1-p2)));
2145
 
      xp->ptr = (unsigned char**)((char*)xp->ptr + (p1-p2));
2146
 
      xp->size = (int*)((char*)xp->size + (p1-p2));
2147
 
      xp->type = (char**)((char*)xp->type + (p1-p2));
2148
 
      xp->options = (char**)((char*)xp->options + (p1-p2));
2149
 
    }
2150
 
  }
2151
 
#endif
2152
 
}
2153
 
#endif
2154
 
#endif
2155
 
 
2156
 
/******************************************************************************/
2157
 
#ifndef WITH_NOIDREF
2158
 
#ifndef PALM_1
2159
 
static int
2160
 
soap_has_copies(struct soap *soap, register const char *start, register const char *end)
2161
 
{ register int i;
2162
 
  register struct soap_ilist *ip = NULL;
2163
 
  register struct soap_flist *fp = NULL;
2164
 
  register const char *p;
2165
 
  for (i = 0; i < SOAP_IDHASH; i++)
2166
 
  { for (ip = soap->iht[i]; ip; ip = ip->next)
2167
 
    { for (p = (const char*)ip->copy; p; p = *(const char**)p)
2168
 
        if (p >= start && p < end)
2169
 
          return SOAP_ERR;
2170
 
      for (fp = ip->flist; fp; fp = fp->next)
2171
 
        if ((const char*)fp->ptr >= start && (const char*)fp->ptr < end)
2172
 
          return SOAP_ERR;
2173
 
    }
2174
 
  }
2175
 
  return SOAP_OK;
2176
 
}
2177
 
#endif
2178
 
#endif
2179
 
 
2180
 
/******************************************************************************/
2181
 
#ifndef WITH_NOIDREF
2182
 
#ifndef PALM_1
2183
 
SOAP_FMAC1
2184
 
int
2185
 
SOAP_FMAC2
2186
 
soap_resolve(struct soap *soap)
2187
 
{ register int i;
2188
 
  register struct soap_ilist *ip = NULL;
2189
 
  register struct soap_flist *fp = NULL;
2190
 
  short flag;
2191
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving forwarded data\n"));
2192
 
  for (i = 0; i < SOAP_IDHASH; i++)
2193
 
  { for (ip = soap->iht[i]; ip; ip = ip->next)
2194
 
    { if (ip->ptr)
2195
 
      { register void *p, **q, *r;
2196
 
        q = (void**)ip->link;
2197
 
        ip->link = NULL;
2198
 
        r = ip->ptr;
2199
 
        DBGLOG(TEST, if (q) SOAP_MESSAGE(fdebug, "Traversing link chain to resolve id='%s'\n", ip->id));
2200
 
        while (q)
2201
 
        { p = *q;
2202
 
          *q = r;
2203
 
          DBGLOG(TEST,SOAP_MESSAGE(fdebug, "... link %p -> %p\n", q, r));
2204
 
          q = (void**)p;
2205
 
        }
2206
 
      }
2207
 
      else if (*ip->id == '#')
2208
 
      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Missing data for id='%s'\n", ip->id));
2209
 
        strcpy(soap->id, ip->id + 1);
2210
 
        return soap->error = SOAP_MISSING_ID;
2211
 
      }
2212
 
    }
2213
 
  }
2214
 
  do
2215
 
  { flag = 0;
2216
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolution phase\n"));
2217
 
    for (i = 0; i < SOAP_IDHASH; i++)
2218
 
    { for (ip = soap->iht[i]; ip; ip = ip->next)
2219
 
      { if (ip->ptr && !soap_has_copies(soap, (const char*)ip->ptr, (const char*)ip->ptr + ip->size))
2220
 
        { if (ip->copy)
2221
 
          { register void *p, **q = (void**)ip->copy;
2222
 
            DBGLOG(TEST, if (q) SOAP_MESSAGE(fdebug, "Traversing copy chain to resolve id='%s'\n", ip->id));
2223
 
            ip->copy = NULL;
2224
 
            do
2225
 
            { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "... copy %p -> %p (%u bytes)\n", ip->ptr, q, (unsigned int)ip->size));
2226
 
              p = *q;
2227
 
              memcpy(q, ip->ptr, ip->size);
2228
 
              q = (void**)p;
2229
 
            } while (q);
2230
 
            flag = 1;
2231
 
          }
2232
 
          for (fp = ip->flist; fp; fp = ip->flist)
2233
 
          { register unsigned int k = fp->level;
2234
 
            register void *p = ip->ptr;
2235
 
            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));
2236
 
            while (ip->level < k)
2237
 
            { register void **q = (void**)soap_malloc(soap, sizeof(void*));  
2238
 
              if (!q)
2239
 
                return soap->error;
2240
 
              *q = p;
2241
 
              DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level, new location=%p holds=%p...\n", q, *q));
2242
 
              p = (void*)q;
2243
 
              k--;
2244
 
            }
2245
 
            if (fp->fcopy)
2246
 
              fp->fcopy(soap, ip->type, fp->type, fp->ptr, fp->len, p, ip->size);
2247
 
            else
2248
 
              soap_fcopy(soap, ip->type, fp->type, fp->ptr, fp->len, p, ip->size);
2249
 
            ip->flist = fp->next;
2250
 
            SOAP_FREE(soap, fp);
2251
 
            flag = 1;
2252
 
          }
2253
 
        }
2254
 
      }
2255
 
    }
2256
 
  } while (flag);
2257
 
#ifdef SOAP_DEBUG
2258
 
  for (i = 0; i < SOAP_IDHASH; i++)
2259
 
  { for (ip = soap->iht[i]; ip; ip = ip->next)
2260
 
    { if (ip->copy || ip->flist)
2261
 
      { 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));
2262
 
      }
2263
 
    }
2264
 
  }
2265
 
#endif
2266
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolution done\n"));
2267
 
  return SOAP_OK;
2268
 
}
2269
 
#endif
2270
 
#endif
2271
 
 
2272
 
/******************************************************************************/
2273
 
#ifndef PALM_1
2274
 
SOAP_FMAC1
2275
 
size_t
2276
 
SOAP_FMAC2
2277
 
soap_size_block(struct soap *soap, size_t n)
2278
 
{ if (soap->blist->ptr)
2279
 
  { soap->blist->size -= *(size_t*)(soap->blist->ptr + sizeof(char*)) - n;
2280
 
    *(size_t*)(soap->blist->ptr + sizeof(char*)) = n;
2281
 
  }
2282
 
  return soap->blist->size;
2283
 
}
2284
 
#endif
2285
 
 
2286
 
/******************************************************************************/
2287
 
#ifndef PALM_1
2288
 
SOAP_FMAC1
2289
 
char*
2290
 
SOAP_FMAC2
2291
 
soap_first_block(struct soap *soap)
2292
 
{ char *p, *q, *r;
2293
 
  p = soap->blist->ptr;
2294
 
  if (!p)
2295
 
    return NULL;
2296
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "First block\n"));
2297
 
  r = NULL;
2298
 
  do
2299
 
  { q = *(char**)p;
2300
 
    *(char**)p = r;
2301
 
    r = p;
2302
 
    p = q;
2303
 
  } while (p);
2304
 
  soap->blist->ptr = r;
2305
 
  return r + sizeof(char*) + sizeof(size_t);
2306
 
}
2307
 
#endif
2308
 
 
2309
 
/******************************************************************************/
2310
 
#ifndef PALM_1
2311
 
SOAP_FMAC1
2312
 
char*
2313
 
SOAP_FMAC2
2314
 
soap_next_block(struct soap *soap)
2315
 
{ char *p;
2316
 
  p = soap->blist->ptr;
2317
 
  if (p)
2318
 
  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Next block\n"));
2319
 
    soap->blist->ptr = *(char**)p;
2320
 
    SOAP_FREE(soap, p);
2321
 
    if (soap->blist->ptr)
2322
 
      return soap->blist->ptr + sizeof(char*) + sizeof(size_t);
2323
 
  }
2324
 
  return NULL;
2325
 
}
2326
 
#endif
2327
 
 
2328
 
/******************************************************************************/
2329
 
#ifndef PALM_1
2330
 
SOAP_FMAC1
2331
 
size_t
2332
 
SOAP_FMAC2
2333
 
soap_block_size(struct soap *soap)
2334
 
{ return *(size_t*)(soap->blist->ptr + sizeof(char*));
2335
 
}
2336
 
#endif
2337
 
 
2338
 
/******************************************************************************/
2339
 
#ifndef PALM_1
2340
 
SOAP_FMAC1
2341
 
void
2342
 
SOAP_FMAC2
2343
 
soap_end_block(struct soap *soap)
2344
 
{ struct soap_blist *bp;
2345
 
  char *p, *q;
2346
 
  bp = soap->blist;
2347
 
  if (bp)
2348
 
  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of block sequence, free all remaining blocks\n"));
2349
 
    for (p = bp->ptr; p; p = q)
2350
 
    { q = *(char**)p;
2351
 
      SOAP_FREE(soap, p);
2352
 
    }
2353
 
    soap->blist = bp->next;
2354
 
    SOAP_FREE(soap, bp);
2355
 
  }
2356
 
  DBGLOG(TEST, if (soap->blist) SOAP_MESSAGE(fdebug, "Restore previous block sequence\n"));
2357
 
}
2358
 
#endif
2359
 
 
2360
 
/******************************************************************************/
2361
 
#ifndef PALM_1
2362
 
SOAP_FMAC1
2363
 
char*
2364
 
SOAP_FMAC2
2365
 
soap_save_block(struct soap *soap, char *p, int flag)
2366
 
{ register size_t n;
2367
 
  register char *q, *s;
2368
 
  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));
2369
 
  if (soap->blist->size)
2370
 
  { if (!p)
2371
 
      p = (char*)soap_malloc(soap, soap->blist->size);
2372
 
    if (p)
2373
 
    { for (s = p, q = soap_first_block(soap); q; q = soap_next_block(soap))
2374
 
      { n = soap_block_size(soap);
2375
 
#ifndef WITH_NOIDREF
2376
 
        if (flag)
2377
 
          soap_update_ptrs(soap, q, q + n, s, q);
2378
 
#endif
2379
 
        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copy %u bytes from %p to %p\n", (unsigned int)n, q, s));
2380
 
        memcpy(s, q, n);
2381
 
        s += n;
2382
 
      }
2383
 
    }
2384
 
    else
2385
 
      soap->error = SOAP_EOM;
2386
 
  }
2387
 
  soap_end_block(soap);
2388
 
  return p;
2389
 
}
2390
 
#endif
2391
 
 
2392
 
/******************************************************************************/
2393
 
#ifndef PALM_2
2394
 
SOAP_FMAC1
2395
 
char *
2396
 
SOAP_FMAC2
2397
 
soap_putsize(struct soap *soap, const char *type, int size)
2398
 
{ return soap_putsizes(soap, type, &size, 1);
2399
 
}
2400
 
#endif
2401
 
 
2402
 
/******************************************************************************/
2403
 
#ifndef PALM_2
2404
 
SOAP_FMAC1
2405
 
char *
2406
 
SOAP_FMAC2
2407
 
soap_putsizes(struct soap *soap, const char *type, const int *size, int dim)
2408
 
{ return soap_putsizesoffsets(soap, type, size, NULL, dim);
2409
 
}
2410
 
#endif
2411
 
 
2412
 
/******************************************************************************/
2413
 
#ifndef PALM_2
2414
 
SOAP_FMAC1
2415
 
char *
2416
 
SOAP_FMAC2
2417
 
soap_putsizesoffsets(struct soap *soap, const char *type, const int *size, const int *offset, int dim)
2418
 
{ int i;
2419
 
  if (!type)
2420
 
    return NULL;
2421
 
  if (soap->version == 2)
2422
 
  { sprintf(soap->type, "%s[%d", type, size[0]);
2423
 
    for (i = 1; i < dim; i++)
2424
 
      sprintf(soap->type + strlen(soap->type), " %d", size[i]);
2425
 
  }
2426
 
  else
2427
 
  { if (offset)
2428
 
    { sprintf(soap->type, "%s[%d", type, size[0] + offset[0]);
2429
 
      for (i = 1; i < dim; i++)
2430
 
        sprintf(soap->type + strlen(soap->type), ",%d", size[i] + offset[i]);
2431
 
    }
2432
 
    else
2433
 
    { sprintf(soap->type, "%s[%d", type, size[0]);
2434
 
      for (i = 1; i < dim; i++)
2435
 
        sprintf(soap->type + strlen(soap->type), ",%d", size[i]);
2436
 
    }
2437
 
    strcat(soap->type, "]");
2438
 
  }
2439
 
  return soap->type;
2440
 
}
2441
 
#endif
2442
 
 
2443
 
/******************************************************************************/
2444
 
#ifndef PALM_2
2445
 
SOAP_FMAC1
2446
 
char *
2447
 
SOAP_FMAC2
2448
 
soap_putoffset(struct soap *soap, int offset)
2449
 
{ return soap_putoffsets(soap, &offset, 1);
2450
 
}
2451
 
#endif
2452
 
 
2453
 
/******************************************************************************/
2454
 
#ifndef PALM_2
2455
 
SOAP_FMAC1
2456
 
char *
2457
 
SOAP_FMAC2
2458
 
soap_putoffsets(struct soap *soap, const int *offset, int dim)
2459
 
{ register int i;
2460
 
  sprintf(soap->arrayOffset, "[%d", offset[0]);
2461
 
  for (i = 1; i < dim; i++)
2462
 
    sprintf(soap->arrayOffset + strlen(soap->arrayOffset), ",%d", offset[i]);
2463
 
  strcat(soap->arrayOffset, "]");
2464
 
  return soap->arrayOffset;
2465
 
}
2466
 
#endif
2467
 
 
2468
 
/******************************************************************************/
2469
 
#ifndef PALM_2
2470
 
SOAP_FMAC1
2471
 
int
2472
 
SOAP_FMAC2
2473
 
soap_size(const int *size, int dim)
2474
 
{ register int i, n = size[0];
2475
 
  for (i = 1; i < dim; i++)
2476
 
    n *= size[i];
2477
 
  return n;
2478
 
}
2479
 
#endif
2480
 
 
2481
 
/******************************************************************************/
2482
 
#ifndef PALM_2
2483
 
SOAP_FMAC1
2484
 
int
2485
 
SOAP_FMAC2
2486
 
soap_getoffsets(const char *attr, const int *size, int *offset, int dim)
2487
 
{ register int i, j = 0;
2488
 
  if (offset)
2489
 
    for (i = 0; i < dim && attr && *attr; i++)
2490
 
    { attr++;
2491
 
      j *= size[i];
2492
 
      j += offset[i] = (int)atol(attr);
2493
 
      attr = strchr(attr, ',');
2494
 
    }
2495
 
  else
2496
 
    for (i = 0; i < dim && attr && *attr; i++)
2497
 
    { attr++;
2498
 
      j *= size[i];
2499
 
      j += (int)atol(attr);
2500
 
      attr = strchr(attr, ',');
2501
 
    }
2502
 
  return j;
2503
 
}
2504
 
#endif
2505
 
 
2506
 
/******************************************************************************/
2507
 
#ifndef PALM_2
2508
 
SOAP_FMAC1
2509
 
int
2510
 
SOAP_FMAC2
2511
 
soap_getsize(const char *attr1, const char *attr2, int *j)
2512
 
{ register int n, k;
2513
 
  char *s;
2514
 
  *j = 0;
2515
 
  if (!*attr1)
2516
 
    return -1;
2517
 
  if (*attr1 == '[')
2518
 
    attr1++;
2519
 
  n = 1;
2520
 
  for (;;)
2521
 
  { k = (int)soap_strtol(attr1, &s, 10);
2522
 
    n *= k;
2523
 
    if (k < 0 || n > SOAP_MAXARRAYSIZE || s == attr1)
2524
 
      return -1;
2525
 
    attr1 = strchr(s, ',');
2526
 
    if (!attr1)
2527
 
      attr1 = strchr(s, ' ');
2528
 
    if (attr2 && *attr2)
2529
 
    { attr2++;
2530
 
      *j *= k;
2531
 
      k = (int)soap_strtol(attr2, &s, 10);
2532
 
      *j += k;
2533
 
      if (k < 0)
2534
 
        return -1;
2535
 
      attr2 = s;
2536
 
    }
2537
 
    if (!attr1)
2538
 
      break;
2539
 
    attr1++;
2540
 
  }
2541
 
  return n - *j;
2542
 
}
2543
 
#endif
2544
 
 
2545
 
/******************************************************************************/
2546
 
#ifndef PALM_2
2547
 
SOAP_FMAC1
2548
 
int
2549
 
SOAP_FMAC2
2550
 
soap_getsizes(const char *attr, int *size, int dim)
2551
 
{ register int i, k, n;
2552
 
  if (!*attr)
2553
 
    return -1;
2554
 
  i = (int)strlen(attr);
2555
 
  n = 1;
2556
 
  do
2557
 
  { for (i = i-1; i >= 0; i--)
2558
 
      if (attr[i] == '[' || attr[i] == ',' || attr[i] == ' ')
2559
 
        break;
2560
 
    k = (int)atol(attr + i + 1);
2561
 
    n *= size[--dim] = k;
2562
 
    if (k < 0 || n > SOAP_MAXARRAYSIZE)
2563
 
      return -1;
2564
 
  } while (i >= 0 && attr[i] != '[');
2565
 
  return n;
2566
 
}
2567
 
#endif
2568
 
 
2569
 
/******************************************************************************/
2570
 
#ifndef PALM_2
2571
 
SOAP_FMAC1
2572
 
int
2573
 
SOAP_FMAC2
2574
 
soap_getposition(const char *attr, int *pos)
2575
 
{ register int i, n;
2576
 
  if (!*attr)
2577
 
    return -1;
2578
 
  n = 0;
2579
 
  i = 1;
2580
 
  do
2581
 
  { pos[n++] = (int)atol(attr + i);
2582
 
    while (attr[i] && attr[i] != ',' && attr[i] != ']')
2583
 
      i++;
2584
 
    if (attr[i] == ',')
2585
 
      i++;
2586
 
  } while (n < SOAP_MAXDIMS && attr[i] && attr[i] != ']');
2587
 
  return n;
2588
 
}
2589
 
#endif
2590
 
 
2591
 
/******************************************************************************/
2592
 
#ifndef PALM_2
2593
 
SOAP_FMAC1
2594
 
int
2595
 
SOAP_FMAC2
2596
 
soap_push_namespace(struct soap *soap, const char *id, const char *ns)
2597
 
{ register struct soap_nlist *np;
2598
 
  register struct Namespace *p;
2599
 
  register short i = -1;
2600
 
  register size_t n, k;
2601
 
  n = strlen(id);
2602
 
  k = strlen(ns) + 1;
2603
 
  p = soap->local_namespaces;
2604
 
  if (p)
2605
 
  { for (i = 0; p->id; p++, i++)
2606
 
    { if (p->ns && !strcmp(ns, p->ns))
2607
 
      { if (p->out)
2608
 
        { SOAP_FREE(soap, p->out);
2609
 
          p->out = NULL;
2610
 
        }
2611
 
        break;
2612
 
      }
2613
 
      if (p->out)
2614
 
      { if (!strcmp(ns, p->out))
2615
 
          break;
2616
 
      }
2617
 
      else if (p->in)
2618
 
      { if (!soap_tag_cmp(ns, p->in))
2619
 
        { if ((p->out = (char*)SOAP_MALLOC(soap, k)))
2620
 
            strcpy(p->out, ns);
2621
 
          break;
2622
 
        }
2623
 
      }
2624
 
    }
2625
 
    if (!p || !p->id)
2626
 
      i = -1;
2627
 
  }
2628
 
  if (i >= 0)
2629
 
    k = 0;
2630
 
  np = (struct soap_nlist*)SOAP_MALLOC(soap, sizeof(struct soap_nlist) + n + k);
2631
 
  if (!np)
2632
 
    return soap->error = SOAP_EOM;
2633
 
  np->next = soap->nlist;
2634
 
  soap->nlist = np;
2635
 
  np->level = soap->level;
2636
 
  np->index = i;
2637
 
  strcpy(np->id, id);
2638
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push namespace binding (level=%u) '%s' '%s'\n", soap->level, id, ns));
2639
 
  if (i < 0)
2640
 
  { np->ns = np->id + n + 1;
2641
 
    strcpy(np->ns, ns);
2642
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push NOT OK: no match found for '%s' in namespace mapping table (added to stack anyway)\n", ns));
2643
 
  }
2644
 
  else
2645
 
  { np->ns = NULL;
2646
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Push OK ('%s' matches '%s' in namespace table)\n", id, p->id));
2647
 
  }
2648
 
  return SOAP_OK;
2649
 
}
2650
 
#endif
2651
 
 
2652
 
/******************************************************************************/
2653
 
#ifndef PALM_2
2654
 
SOAP_FMAC1
2655
 
void
2656
 
SOAP_FMAC2
2657
 
soap_pop_namespace(struct soap *soap)
2658
 
{ register struct soap_nlist *np, *nq;
2659
 
  for (np = soap->nlist; np && np->level >= soap->level; np = nq)
2660
 
  { nq = np->next;
2661
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Pop namespace binding (level=%u) '%s'\n", soap->level, np->id));
2662
 
    SOAP_FREE(soap, np);
2663
 
  }
2664
 
  soap->nlist = np;
2665
 
}
2666
 
#endif
2667
 
 
2668
 
/******************************************************************************/
2669
 
#ifndef PALM_2
2670
 
SOAP_FMAC1
2671
 
int
2672
 
SOAP_FMAC2
2673
 
soap_match_namespace(struct soap *soap, const char *id1, const char *id2, size_t n1, size_t n2) 
2674
 
{ register struct soap_nlist *np = soap->nlist;
2675
 
  while (np && (strncmp(np->id, id1, n1) || np->id[n1]))
2676
 
    np = np->next;
2677
 
  if (np)
2678
 
  { if (np->index < 0
2679
 
     || (soap->local_namespaces[np->index].id
2680
 
      && (strncmp(soap->local_namespaces[np->index].id, id2, n2)
2681
 
       || soap->local_namespaces[np->index].id[n2])))
2682
 
      return SOAP_NAMESPACE;
2683
 
    return SOAP_OK;
2684
 
  }
2685
 
  if (n1 == 3 && n1 == n2 && !strcmp(id1, "xml") && !strcmp(id1, id2))
2686
 
    return SOAP_OK;
2687
 
  return soap->error = SOAP_SYNTAX_ERROR; 
2688
 
}
2689
 
#endif
2690
 
 
2691
 
/******************************************************************************/
2692
 
#ifndef PALM_2
2693
 
SOAP_FMAC1
2694
 
const char*
2695
 
SOAP_FMAC2
2696
 
soap_current_namespace(struct soap *soap, const char *tag)
2697
 
{ register struct soap_nlist *np;
2698
 
  register const char *s;
2699
 
  np = soap->nlist;
2700
 
  if (!(s = strchr(tag, ':')))
2701
 
  { while (np && *np->id) /* find default namespace, if present */
2702
 
      np = np->next;
2703
 
  }
2704
 
  else
2705
 
  { while (np && (strncmp(np->id, tag, s - tag) || np->id[s - tag]))
2706
 
      np = np->next;
2707
 
    if (!np)
2708
 
      soap->error = SOAP_NAMESPACE;
2709
 
  }
2710
 
  if (np)
2711
 
  { if (np->index >= 0)
2712
 
      return soap->namespaces[np->index].ns;
2713
 
    if (np->ns)
2714
 
      return soap_strdup(soap, np->ns);
2715
 
  }
2716
 
  return NULL;
2717
 
}
2718
 
#endif
2719
 
 
2720
 
/******************************************************************************/
2721
 
#ifndef PALM_2
2722
 
SOAP_FMAC1
2723
 
int
2724
 
SOAP_FMAC2
2725
 
soap_tag_cmp(const char *s, const char *t)
2726
 
{ for (;;)
2727
 
  { register int c1 = *s;
2728
 
    register int c2 = *t;
2729
 
    if (!c1 || c1 == '"')
2730
 
      break;
2731
 
    if (c2 != '-')
2732
 
    { if (c1 != c2)
2733
 
      { if (c1 >= 'A' && c1 <= 'Z')
2734
 
          c1 += 'a' - 'A';
2735
 
        if (c2 >= 'A' && c2 <= 'Z')
2736
 
          c2 += 'a' - 'A';
2737
 
      }
2738
 
      if (c1 != c2)
2739
 
      { if (c2 != '*')
2740
 
          return 1;
2741
 
        c2 = *++t;
2742
 
        if (!c2)
2743
 
          return 0;
2744
 
        if (c2 >= 'A' && c2 <= 'Z')
2745
 
          c2 += 'a' - 'A';
2746
 
        for (;;)
2747
 
        { c1 = *s;
2748
 
          if (!c1 || c1 == '"')
2749
 
            break;
2750
 
          if (c1 >= 'A' && c1 <= 'Z')
2751
 
            c1 += 'a' - 'A';
2752
 
          if (c1 == c2 && !soap_tag_cmp(s + 1, t + 1))
2753
 
            return 0;
2754
 
          s++;
2755
 
        }
2756
 
        break;
2757
 
      }
2758
 
    }
2759
 
    s++;
2760
 
    t++;
2761
 
  }
2762
 
  if (*t == '*' && !t[1])
2763
 
    return 0;
2764
 
  return *t;
2765
 
}
2766
 
#endif
2767
 
 
2768
 
/******************************************************************************/
2769
 
#ifndef PALM_2
2770
 
SOAP_FMAC1
2771
 
int
2772
 
SOAP_FMAC2
2773
 
soap_match_tag(struct soap *soap, const char *tag1, const char *tag2)
2774
 
{ register const char *s, *t;
2775
 
  register int err;
2776
 
  if (!tag1 || !tag2 || !*tag2)
2777
 
    return SOAP_OK;
2778
 
  s = strchr(tag1, ':');
2779
 
  t = strchr(tag2, ':');
2780
 
  if (t)
2781
 
  { if (s)
2782
 
    { if (t[1] && SOAP_STRCMP(s + 1, t + 1))
2783
 
        return SOAP_TAG_MISMATCH;
2784
 
      if (t != tag2 && (err = soap_match_namespace(soap, tag1, tag2, s - tag1, t - tag2)))
2785
 
      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags '%s' and '%s' match but namespaces differ\n", tag1, tag2));
2786
 
        if (err == SOAP_NAMESPACE)
2787
 
          return SOAP_TAG_MISMATCH;
2788
 
        return err;
2789
 
      }
2790
 
    } 
2791
 
    else if (SOAP_STRCMP(tag1, t + 1))
2792
 
    { return SOAP_TAG_MISMATCH;
2793
 
    }
2794
 
    else if (t != tag2 && (err = soap_match_namespace(soap, tag1, tag2, 0, t - tag2)))
2795
 
    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags '%s' and '%s' match but namespaces differ\n", tag1, tag2));
2796
 
      if (err == SOAP_NAMESPACE)
2797
 
        return SOAP_TAG_MISMATCH;
2798
 
      return err;
2799
 
    }
2800
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags and (default) namespaces match: '%s' '%s'\n", tag1, tag2));
2801
 
    return SOAP_OK;
2802
 
  }
2803
 
  if (s)
2804
 
  { if (SOAP_STRCMP(s + 1, tag2))
2805
 
      return SOAP_TAG_MISMATCH;
2806
 
  }
2807
 
  else if (SOAP_STRCMP(tag1, tag2))
2808
 
    return SOAP_TAG_MISMATCH;
2809
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Tags match: '%s' '%s'\n", tag1, tag2));
2810
 
  return SOAP_OK;
2811
 
}
2812
 
#endif
2813
 
 
2814
 
/******************************************************************************/
2815
 
#ifndef PALM_2
2816
 
SOAP_FMAC1
2817
 
int
2818
 
SOAP_FMAC2
2819
 
soap_match_array(struct soap *soap, const char *type)
2820
 
{ if (*soap->arrayType)
2821
 
    if (soap_match_tag(soap, soap->arrayType, type)
2822
 
     && soap_match_tag(soap, soap->arrayType, "xsd:anyType")
2823
 
     && soap_match_tag(soap, soap->arrayType, "xsd:ur-type")
2824
 
    )
2825
 
    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array type mismatch: '%s' '%s'\n", soap->arrayType, type));
2826
 
      return SOAP_TAG_MISMATCH;
2827
 
    }
2828
 
  return SOAP_OK;
2829
 
}
2830
 
#endif
2831
 
 
2832
 
/******************************************************************************\
2833
 
 *
2834
 
 *      SSL
2835
 
 *
2836
 
\******************************************************************************/
2837
 
 
2838
 
#ifdef WITH_OPENSSL
2839
 
/******************************************************************************/
2840
 
#ifndef PALM_2
2841
 
SOAP_FMAC1
2842
 
int
2843
 
SOAP_FMAC2
2844
 
soap_rand()
2845
 
{ unsigned char buf[4];
2846
 
  if (!ssl_init_done)
2847
 
    soap_ssl_init();
2848
 
  RAND_pseudo_bytes(buf, 4);
2849
 
  return *(int*)buf;
2850
 
}
2851
 
#endif
2852
 
 
2853
 
/******************************************************************************/
2854
 
#ifndef PALM_2
2855
 
SOAP_FMAC1
2856
 
int
2857
 
SOAP_FMAC2
2858
 
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)
2859
 
{ int err;
2860
 
  soap->keyfile = keyfile;
2861
 
  soap->password = password;
2862
 
  soap->cafile = cafile;
2863
 
  soap->capath = capath;
2864
 
  soap->dhfile = dhfile;
2865
 
  soap->randfile = randfile;
2866
 
  soap->ssl_flags = flags | (dhfile == NULL ? SOAP_SSL_RSA : 0);
2867
 
  if (!(err = soap->fsslauth(soap)))
2868
 
  { if (sid)
2869
 
      SSL_CTX_set_session_id_context(soap->ctx, (unsigned char*)sid, (unsigned int)strlen(sid));
2870
 
  }
2871
 
  return err; 
2872
 
}
2873
 
#endif
2874
 
 
2875
 
/******************************************************************************/
2876
 
#ifndef PALM_2
2877
 
SOAP_FMAC1
2878
 
int
2879
 
SOAP_FMAC2
2880
 
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)
2881
 
{ soap->keyfile = keyfile;
2882
 
  soap->password = password;
2883
 
  soap->cafile = cafile;
2884
 
  soap->capath = capath;
2885
 
  soap->dhfile = NULL;
2886
 
  soap->ssl_flags = flags;
2887
 
  soap->randfile = randfile;
2888
 
  return soap->fsslauth(soap);
2889
 
}
2890
 
#endif
2891
 
 
2892
 
/******************************************************************************/
2893
 
#ifndef PALM_2
2894
 
SOAP_FMAC1
2895
 
void
2896
 
SOAP_FMAC2
2897
 
soap_ssl_init()
2898
 
{ /* Note: for MT systems, the main program MUST call soap_ssl_init() before any threads are started */
2899
 
  if (!ssl_init_done)
2900
 
  { ssl_init_done = 1;
2901
 
    SSL_library_init();
2902
 
#ifndef WITH_LEAN
2903
 
    SSL_load_error_strings();
2904
 
#endif
2905
 
    if (!RAND_load_file("/dev/urandom", 1024))
2906
 
    { char buf[1024];
2907
 
      RAND_seed(buf, sizeof(buf));
2908
 
      while (!RAND_status())
2909
 
      { int r = rand();
2910
 
        RAND_seed(&r, sizeof(int));
2911
 
      }
2912
 
    }
2913
 
  }
2914
 
}
2915
 
#endif
2916
 
 
2917
 
/******************************************************************************/
2918
 
#ifndef PALM_1
2919
 
SOAP_FMAC1
2920
 
const char *
2921
 
SOAP_FMAC2
2922
 
soap_ssl_error(struct soap *soap, int ret)
2923
 
{ int err = SSL_get_error(soap->ssl, ret);
2924
 
  const char *msg = soap_code_str(h_ssl_error_codes, err);
2925
 
  if (msg)
2926
 
    strcpy(soap->msgbuf, msg);
2927
 
  else
2928
 
    return ERR_error_string(err, soap->msgbuf);
2929
 
  if (ERR_peek_error())
2930
 
  { unsigned long r;
2931
 
    strcat(soap->msgbuf, "\n");
2932
 
    while ((r = ERR_get_error()))
2933
 
      ERR_error_string_n(r, soap->msgbuf + strlen(soap->msgbuf), sizeof(soap->msgbuf) - strlen(soap->msgbuf));
2934
 
  } 
2935
 
  else
2936
 
  { switch (ret)
2937
 
    { case 0:
2938
 
        strcpy(soap->msgbuf, "EOF was observed that violates the protocol. The client probably provided invalid authentication information.");
2939
 
        break;
2940
 
      case -1:
2941
 
        sprintf(soap->msgbuf, "Error observed by underlying BIO: %s", strerror(errno));  
2942
 
        break;
2943
 
    }
2944
 
  }
2945
 
  return soap->msgbuf;
2946
 
}
2947
 
#endif
2948
 
 
2949
 
/******************************************************************************/
2950
 
#ifndef PALM_1
2951
 
static int
2952
 
ssl_password(char *buf, int num, int rwflag, void *userdata)
2953
 
{ if (num < (int)strlen((char*)userdata) + 1)
2954
 
    return 0;
2955
 
  return (int)strlen(strcpy(buf, (char*)userdata));
2956
 
}
2957
 
#endif
2958
 
 
2959
 
/******************************************************************************/
2960
 
/* This callback is included for future references. It should not be deleted
2961
 
#ifndef PALM_2
2962
 
static DH *
2963
 
ssl_tmp_dh(SSL *ssl, int is_export, int keylength)
2964
 
{ static DH *dh512 = NULL;
2965
 
  static DH *dh1024 = NULL;
2966
 
  DH *dh;
2967
 
  switch (keylength)
2968
 
  { case 512:
2969
 
      if (!dh512)
2970
 
      { BIO *bio = BIO_new_file("dh512.pem", "r");
2971
 
        if (bio)
2972
 
        { dh512 = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
2973
 
          BIO_free(bio);
2974
 
          return dh512;
2975
 
        }
2976
 
      }
2977
 
      else
2978
 
        return dh512;
2979
 
    default:
2980
 
      if (!dh1024)
2981
 
      { BIO *bio = BIO_new_file("dh1024.pem", "r");
2982
 
        if (bio)
2983
 
        { dh1024 = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
2984
 
          BIO_free(bio);
2985
 
        }
2986
 
      }
2987
 
      dh = dh1024;
2988
 
  }
2989
 
  return dh;
2990
 
}
2991
 
#endif
2992
 
*/
2993
 
 
2994
 
/******************************************************************************/
2995
 
#ifndef PALM_1
2996
 
static int
2997
 
ssl_auth_init(struct soap *soap)
2998
 
{ long flags;
2999
 
  int mode;
3000
 
  if (!ssl_init_done)
3001
 
    soap_ssl_init();
3002
 
  if (!soap->ctx)
3003
 
  { if (!(soap->ctx = SSL_CTX_new(SSLv23_method())))
3004
 
      return soap_set_receiver_error(soap, "SSL error", "Can't setup context", SOAP_SSL_ERROR);
3005
 
    /* Alters the behavior of SSL read/write:
3006
 
    SSL_CTX_set_mode(soap->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_AUTO_RETRY);
3007
 
    */
3008
 
  }
3009
 
  if (soap->randfile)
3010
 
  { if (!RAND_load_file(soap->randfile, -1))
3011
 
      return soap_set_receiver_error(soap, "SSL error", "Can't load randomness", SOAP_SSL_ERROR);
3012
 
  }
3013
 
  if (soap->cafile || soap->capath)
3014
 
  { if (!SSL_CTX_load_verify_locations(soap->ctx, soap->cafile, soap->capath))
3015
 
      return soap_set_receiver_error(soap, "SSL error", "Can't read CA file and directory", SOAP_SSL_ERROR);
3016
 
    if (soap->cafile && (soap->ssl_flags & SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION))
3017
 
      SSL_CTX_set_client_CA_list(soap->ctx, SSL_load_client_CA_file(soap->cafile));
3018
 
  }
3019
 
  if (!SSL_CTX_set_default_verify_paths(soap->ctx))
3020
 
    return soap_set_receiver_error(soap, "SSL error", "Can't read default CA file and/or directory", SOAP_SSL_ERROR);
3021
 
/* This code assumes a typical scenario, see alternative code below */
3022
 
  if (soap->keyfile)
3023
 
  { if (!SSL_CTX_use_certificate_chain_file(soap->ctx, soap->keyfile))
3024
 
      return soap_set_receiver_error(soap, "SSL error", "Can't read certificate key file", SOAP_SSL_ERROR);
3025
 
    if (soap->password)
3026
 
    { SSL_CTX_set_default_passwd_cb_userdata(soap->ctx, (void*)soap->password);
3027
 
      SSL_CTX_set_default_passwd_cb(soap->ctx, ssl_password);
3028
 
    }
3029
 
    if (!SSL_CTX_use_PrivateKey_file(soap->ctx, soap->keyfile, SSL_FILETYPE_PEM))
3030
 
      return soap_set_receiver_error(soap, "SSL error", "Can't read key file", SOAP_SSL_ERROR);
3031
 
  }
3032
 
/* Suggested alternative approach to check the key file for certs (cafile=NULL):
3033
 
  if (soap->password)
3034
 
  { SSL_CTX_set_default_passwd_cb_userdata(soap->ctx, (void*)soap->password);
3035
 
    SSL_CTX_set_default_passwd_cb(soap->ctx, ssl_password);
3036
 
  }
3037
 
  if (!soap->cafile || !SSL_CTX_use_certificate_chain_file(soap->ctx, soap->cafile))
3038
 
  { if (soap->keyfile)
3039
 
    { if (!SSL_CTX_use_certificate_chain_file(soap->ctx, soap->keyfile))
3040
 
        return soap_set_receiver_error(soap, "SSL error", "Can't read certificate or key file", SOAP_SSL_ERROR);
3041
 
      if (!SSL_CTX_use_PrivateKey_file(soap->ctx, soap->keyfile, SSL_FILETYPE_PEM))
3042
 
        return soap_set_receiver_error(soap, "SSL error", "Can't read key file", SOAP_SSL_ERROR);
3043
 
    }
3044
 
  }
3045
 
*/
3046
 
  if ((soap->ssl_flags & SOAP_SSL_RSA))
3047
 
  { RSA *rsa = RSA_generate_key(1024, RSA_F4, NULL, NULL);
3048
 
    if (!SSL_CTX_set_tmp_rsa(soap->ctx, rsa))
3049
 
    { if (rsa)
3050
 
        RSA_free(rsa);
3051
 
      return soap_set_receiver_error(soap, "SSL error", "Can't set RSA key", SOAP_SSL_ERROR);
3052
 
    }
3053
 
    RSA_free(rsa);
3054
 
  }
3055
 
  else if (soap->dhfile)
3056
 
  { DH *dh = 0;
3057
 
    BIO *bio;
3058
 
    bio = BIO_new_file(soap->dhfile, "r");
3059
 
    if (!bio)
3060
 
      return soap_set_receiver_error(soap, "SSL error", "Can't read DH file", SOAP_SSL_ERROR);
3061
 
    dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
3062
 
    BIO_free(bio);
3063
 
    if (SSL_CTX_set_tmp_dh(soap->ctx, dh) < 0)
3064
 
    { if (dh)
3065
 
        DH_free(dh);
3066
 
      return soap_set_receiver_error(soap, "SSL error", "Can't set DH parameters", SOAP_SSL_ERROR);
3067
 
    }
3068
 
    DH_free(dh);
3069
 
  }
3070
 
  flags = (SSL_OP_ALL | SSL_OP_NO_SSLv2);
3071
 
  if ((soap->ssl_flags & SOAP_SSLv3))
3072
 
    flags |= SSL_OP_NO_TLSv1;
3073
 
  if ((soap->ssl_flags & SOAP_TLSv1))
3074
 
    flags |= SSL_OP_NO_SSLv3;
3075
 
  SSL_CTX_set_options(soap->ctx, flags);
3076
 
  if ((soap->ssl_flags & SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION))
3077
 
    mode = (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
3078
 
  else if ((soap->ssl_flags & SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION))
3079
 
    mode = SSL_VERIFY_PEER;
3080
 
  else
3081
 
    mode = SSL_VERIFY_NONE;
3082
 
  SSL_CTX_set_verify(soap->ctx, mode, soap->fsslverify);
3083
 
#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
3084
 
  SSL_CTX_set_verify_depth(soap->ctx, 1); 
3085
 
#else
3086
 
  SSL_CTX_set_verify_depth(soap->ctx, 9); 
3087
 
#endif  
3088
 
  return SOAP_OK;
3089
 
}
3090
 
#endif
3091
 
 
3092
 
/******************************************************************************/
3093
 
#ifndef PALM_1
3094
 
static int
3095
 
ssl_verify_callback(int ok, X509_STORE_CTX *store)
3096
 
{
3097
 
#ifdef SOAP_DEBUG
3098
 
  if (!ok) 
3099
 
  { char data[256];
3100
 
    X509 *cert = X509_STORE_CTX_get_current_cert(store);
3101
 
    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)));
3102
 
    X509_NAME_oneline(X509_get_issuer_name(cert), data, sizeof(data));
3103
 
    fprintf(stderr, "certificate issuer %s\n", data);
3104
 
    X509_NAME_oneline(X509_get_subject_name(cert), data, sizeof(data));
3105
 
    fprintf(stderr, "certificate subject %s\n", data);
3106
 
  }
3107
 
#endif
3108
 
  /* Note: return 1 to continue, but unsafe progress will be terminated by SSL */
3109
 
  return ok;
3110
 
}
3111
 
#endif
3112
 
 
3113
 
/******************************************************************************/
3114
 
#ifndef PALM_1
3115
 
SOAP_FMAC1
3116
 
int
3117
 
SOAP_FMAC2
3118
 
soap_ssl_accept(struct soap *soap)
3119
 
{ BIO *bio;
3120
 
  int timeouts, r, s;
3121
 
  if (!soap_valid_socket(soap->socket))
3122
 
    return soap_set_receiver_error(soap, "SSL error", "No socket in soap_ssl_accept()", SOAP_SSL_ERROR);
3123
 
  if (!soap->ctx && (soap->error = soap->fsslauth(soap)))
3124
 
    return SOAP_INVALID_SOCKET;
3125
 
  if (!soap->ssl)
3126
 
  { soap->ssl = SSL_new(soap->ctx);
3127
 
    if (!soap->ssl)
3128
 
      return soap_set_receiver_error(soap, "SSL error", "SSL_new() failed in soap_ssl_accept()", SOAP_SSL_ERROR);
3129
 
  }
3130
 
  else
3131
 
    SSL_clear(soap->ssl);
3132
 
  soap->imode |= SOAP_ENC_SSL;
3133
 
  soap->omode |= SOAP_ENC_SSL;
3134
 
  /* Set SSL sockets to non-blocking */
3135
 
#if defined(WIN32)
3136
 
  { u_long nonblocking = 1;
3137
 
    ioctlsocket(soap->socket, FIONBIO, &nonblocking);
3138
 
  }
3139
 
#elif defined(VXWORKS)
3140
 
  { u_long nonblocking = 1;
3141
 
    ioctl(soap->socket, FIONBIO, (int)&nonblocking);
3142
 
  }
3143
 
#else
3144
 
  fcntl(soap->socket, F_SETFL, fcntl(soap->socket, F_GETFL)|O_NONBLOCK);
3145
 
#endif
3146
 
  bio = BIO_new_socket(soap->socket, BIO_NOCLOSE);
3147
 
  SSL_set_bio(soap->ssl, bio, bio);
3148
 
  timeouts = 100; /* 10 sec retries, 100 times 0.1 sec */
3149
 
  while ((r = SSL_accept(soap->ssl)) <= 0)
3150
 
  { int err = SSL_get_error(soap->ssl, r);
3151
 
    if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
3152
 
    { struct timeval timeout;
3153
 
      fd_set fd;
3154
 
#ifndef WIN32
3155
 
      if ((int)soap->socket >= (int)FD_SETSIZE)
3156
 
        return SOAP_FD_EXCEEDED;        /* Hint: MUST increase FD_SETSIZE */
3157
 
#endif
3158
 
      timeout.tv_sec = 0;
3159
 
      timeout.tv_usec = 100000;
3160
 
      FD_ZERO(&fd);
3161
 
      FD_SET(soap->socket, &fd);
3162
 
      if (err == SSL_ERROR_WANT_READ)
3163
 
        s = select((int)soap->socket + 1, &fd, NULL, &fd, &timeout);
3164
 
      else
3165
 
        s = select((int)soap->socket + 1, NULL, &fd, &fd, &timeout);
3166
 
      if (s < 0 && (s = soap_socket_errno(soap->socket)) != SOAP_EINTR)
3167
 
      { soap->errnum = s;
3168
 
        break;
3169
 
      }
3170
 
    }
3171
 
    else
3172
 
    { soap->errnum = err;
3173
 
      break;
3174
 
    }
3175
 
    if (timeouts-- <= 0)
3176
 
      break;
3177
 
  }
3178
 
  if (r <= 0)
3179
 
  { soap_set_receiver_error(soap, soap_ssl_error(soap, r), "SSL_accept() failed in soap_ssl_accept()", SOAP_SSL_ERROR);
3180
 
    soap_closesock(soap);
3181
 
    return SOAP_SSL_ERROR;
3182
 
  }
3183
 
  if ((soap->ssl_flags & SOAP_SSL_REQUIRE_CLIENT_AUTHENTICATION))
3184
 
  { X509 *peer;
3185
 
    int err;
3186
 
    if ((err = SSL_get_verify_result(soap->ssl)) != X509_V_OK)
3187
 
    { soap_closesock(soap);
3188
 
      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);
3189
 
    }
3190
 
    peer = SSL_get_peer_certificate(soap->ssl);
3191
 
    if (!peer)
3192
 
    { soap_closesock(soap);
3193
 
      return soap_set_sender_error(soap, "SSL error", "No SSL certificate was presented by the peer in soap_ssl_accept()", SOAP_SSL_ERROR);
3194
 
    }
3195
 
    X509_free(peer);
3196
 
  }
3197
 
  return SOAP_OK;
3198
 
}
3199
 
#endif
3200
 
 
3201
 
/******************************************************************************/
3202
 
#endif /* WITH_OPENSSL */
3203
 
 
3204
 
/******************************************************************************/
3205
 
#ifndef WITH_NOIO
3206
 
#ifndef PALM_1
3207
 
static int
3208
 
tcp_init(struct soap *soap)
3209
 
{ soap->errmode = 1;
3210
 
#ifdef WIN32
3211
 
  if (tcp_done)
3212
 
    return 0;
3213
 
  else
3214
 
  { WSADATA w;
3215
 
    if (WSAStartup(MAKEWORD(1, 1), &w))
3216
 
      return -1;
3217
 
    tcp_done = 1;
3218
 
  }
3219
 
#endif
3220
 
  return 0;
3221
 
}
3222
 
#endif
3223
 
#endif
3224
 
 
3225
 
/******************************************************************************/
3226
 
#ifndef PALM_1
3227
 
SOAP_FMAC1
3228
 
void
3229
 
SOAP_FMAC2
3230
 
soap_done(struct soap *soap)
3231
 
3232
 
#ifdef SOAP_DEBUG
3233
 
  int i;
3234
 
#endif
3235
 
  if (soap_check_state(soap))
3236
 
    return;
3237
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Done with context\n"));
3238
 
  soap_free_temp(soap);
3239
 
  while (soap->clist)
3240
 
  { struct soap_clist *p = soap->clist->next;
3241
 
    SOAP_FREE(soap, soap->clist);
3242
 
    soap->clist = p;
3243
 
  }
3244
 
  soap->keep_alive = 0; /* to force close the socket */
3245
 
  soap_closesock(soap);
3246
 
#ifdef WITH_COOKIES
3247
 
  soap_free_cookies(soap);
3248
 
#endif
3249
 
  while (soap->plugins)
3250
 
  { register struct soap_plugin *p = soap->plugins->next;
3251
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Removing plugin '%s'\n", soap->plugins->id));
3252
 
    if (soap->plugins->fcopy || soap->state == SOAP_INIT)
3253
 
      soap->plugins->fdelete(soap, soap->plugins);
3254
 
    SOAP_FREE(soap, soap->plugins);
3255
 
    soap->plugins = p;
3256
 
  }
3257
 
  soap->fplugin = fplugin;
3258
 
  soap->fmalloc = NULL;
3259
 
#ifndef WITH_NOHTTP
3260
 
  soap->fpost = http_post;
3261
 
  soap->fget = http_get;
3262
 
  soap->fform = NULL;
3263
 
  soap->fposthdr = http_post_header;
3264
 
  soap->fresponse = http_response;
3265
 
  soap->fparse = http_parse;
3266
 
  soap->fparsehdr = http_parse_header;
3267
 
#endif
3268
 
  soap->fheader = NULL;
3269
 
#ifndef WITH_NOIO
3270
 
#ifndef WITH_IPV6
3271
 
  soap->fresolve = tcp_gethost;
3272
 
#else
3273
 
  soap->fresolve = NULL;
3274
 
#endif
3275
 
  soap->faccept = tcp_accept;
3276
 
  soap->fopen = tcp_connect;
3277
 
  soap->fclose = tcp_disconnect;
3278
 
  soap->fclosesocket = tcp_closesocket;
3279
 
  soap->fshutdownsocket = tcp_shutdownsocket;
3280
 
  soap->fsend = fsend;
3281
 
  soap->frecv = frecv;
3282
 
  soap->fpoll = soap_poll;
3283
 
#else
3284
 
  soap->fopen = NULL;
3285
 
  soap->fclose = NULL;
3286
 
  soap->fpoll = NULL;
3287
 
#endif
3288
 
#ifndef WITH_LEANER
3289
 
  soap->fprepareinit = NULL;
3290
 
  soap->fpreparesend = NULL;
3291
 
  soap->fpreparerecv = NULL;
3292
 
  soap->fpreparefinal = NULL;
3293
 
#endif
3294
 
  soap->fseterror = NULL;
3295
 
  soap->fignore = NULL;
3296
 
  soap->fserveloop = NULL;
3297
 
#ifdef WITH_OPENSSL
3298
 
  if (soap->session)
3299
 
  { SSL_SESSION_free(soap->session);
3300
 
    soap->session = NULL;
3301
 
  }
3302
 
#endif
3303
 
  if (soap->state == SOAP_INIT)
3304
 
  { if (soap_valid_socket(soap->master))
3305
 
    { soap->fclosesocket(soap, soap->master);
3306
 
      soap->master = SOAP_INVALID_SOCKET;
3307
 
    }
3308
 
#ifdef WITH_OPENSSL
3309
 
    if (soap->ctx)
3310
 
    { SSL_CTX_free(soap->ctx);
3311
 
      soap->ctx = NULL;
3312
 
    }
3313
 
#endif
3314
 
  }
3315
 
#ifdef SOAP_DEBUG
3316
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free logfiles\n"));
3317
 
  for (i = 0; i < SOAP_MAXLOGS; i++)
3318
 
  { if (soap->logfile[i])
3319
 
    { SOAP_FREE(soap, (void*)soap->logfile[i]);
3320
 
      soap->logfile[i] = NULL;
3321
 
    }
3322
 
    soap_close_logfile(soap, i);
3323
 
  }
3324
 
  soap->state = 0;
3325
 
#endif
3326
 
#ifdef SOAP_MEM_DEBUG
3327
 
  soap_free_mht(soap);
3328
 
#endif
3329
 
}
3330
 
#endif
3331
 
 
3332
 
/******************************************************************************/
3333
 
#ifndef WITH_NOIO
3334
 
#ifndef PALM_2
3335
 
SOAP_FMAC1
3336
 
void
3337
 
SOAP_FMAC2
3338
 
soap_cleanup(struct soap *soap)
3339
 
{ soap_done(soap);
3340
 
#ifdef WIN32
3341
 
  if (!tcp_done)
3342
 
    return;
3343
 
  tcp_done = 0;
3344
 
  WSACleanup();
3345
 
#endif
3346
 
}
3347
 
#endif
3348
 
#endif
3349
 
 
3350
 
/******************************************************************************/
3351
 
#ifndef WITH_NOIO
3352
 
#ifndef PALM_1
3353
 
static const char*
3354
 
tcp_error(struct soap *soap)
3355
 
{ register const char *msg = NULL;
3356
 
  switch (soap->errmode)
3357
 
  { case 0:
3358
 
      msg = soap_strerror(soap);
3359
 
      break;
3360
 
    case 1:
3361
 
      msg = "WSAStartup failed";
3362
 
      break;
3363
 
    case 2:
3364
 
    {
3365
 
#ifndef WITH_LEAN
3366
 
      msg = soap_code_str(h_error_codes, soap->errnum);
3367
 
      if (!msg)
3368
 
#endif
3369
 
      { sprintf(soap->msgbuf, "TCP/UDP IP error %d", soap->errnum);
3370
 
        msg = soap->msgbuf;
3371
 
      }
3372
 
    }
3373
 
  }
3374
 
  return msg;
3375
 
}
3376
 
#endif
3377
 
#endif
3378
 
 
3379
 
/******************************************************************************/
3380
 
#ifndef WITH_NOHTTP
3381
 
#ifndef PALM_1
3382
 
static const char*
3383
 
http_error(struct soap *soap, int status)
3384
 
{ register const char *msg = SOAP_STR_EOS;
3385
 
#ifndef WITH_LEAN
3386
 
  msg = soap_code_str(h_http_error_codes, status);
3387
 
  if (!msg)
3388
 
    msg = SOAP_STR_EOS;
3389
 
#endif
3390
 
  return msg;
3391
 
}
3392
 
#endif
3393
 
#endif
3394
 
 
3395
 
/******************************************************************************/
3396
 
#ifndef WITH_IPV6
3397
 
#ifndef WITH_NOIO
3398
 
#ifndef PALM_1
3399
 
static int
3400
 
tcp_gethost(struct soap *soap, const char *addr, struct in_addr *inaddr)
3401
 
{ soap_int32 iadd = -1;
3402
 
  struct hostent hostent, *host = &hostent;
3403
 
#ifdef VXWORKS
3404
 
  int hostint;
3405
 
  /* inet_addr(), and hostGetByName() expect "char *"; addr is a "const char *". */
3406
 
  iadd = inet_addr((char*)addr);
3407
 
#else
3408
 
#if defined(_AIX43) || defined(TRU64)
3409
 
  struct hostent_data ht_data;
3410
 
#endif
3411
 
#ifdef AS400
3412
 
  iadd = inet_addr((void*)addr);
3413
 
#else
3414
 
  iadd = inet_addr(addr);
3415
 
#endif
3416
 
#endif
3417
 
  if (iadd != -1)
3418
 
  { memcpy(inaddr, &iadd, sizeof(iadd));
3419
 
    return SOAP_OK;
3420
 
  }
3421
 
#if defined(__GLIBC__) || (defined(HAVE_GETHOSTBYNAME_R) && (defined(FREEBSD) || defined(__FreeBSD__)))
3422
 
  if (gethostbyname_r(addr, &hostent, soap->buf, SOAP_BUFLEN, &host, &soap->errnum) < 0)
3423
 
    host = NULL;
3424
 
#elif defined(_AIX43) || defined(TRU64)
3425
 
  memset((void*)&ht_data, 0, sizeof(ht_data));
3426
 
  if (gethostbyname_r(addr, &hostent, &ht_data) < 0)
3427
 
  { host = NULL;
3428
 
    soap->errnum = h_errno;
3429
 
  }
3430
 
#elif defined(HAVE_GETHOSTBYNAME_R)
3431
 
  host = gethostbyname_r(addr, &hostent, soap->buf, SOAP_BUFLEN, &soap->errnum);
3432
 
#elif defined(VXWORKS)
3433
 
  /* If the DNS resolver library resolvLib has been configured in the vxWorks
3434
 
   * image, a query for the host IP address is sent to the DNS server, if the
3435
 
   * name was not found in the local host table. */
3436
 
  hostint = hostGetByName((char*)addr);
3437
 
  if (hostint == ERROR)
3438
 
  { host = NULL;
3439
 
    soap->errnum = soap_errno; 
3440
 
  }
3441
 
#else
3442
 
#ifdef AS400
3443
 
  if (!(host = gethostbyname((void*)addr)))
3444
 
    soap->errnum = h_errno;
3445
 
#else
3446
 
  if (!(host = gethostbyname(addr)))
3447
 
    soap->errnum = h_errno;
3448
 
#endif
3449
 
#endif
3450
 
  if (!host)
3451
 
  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Host name not found\n"));
3452
 
    return SOAP_ERR;
3453
 
  }
3454
 
#ifdef VXWORKS
3455
 
  inaddr->s_addr = hostint;
3456
 
#else
3457
 
  memcpy(inaddr, host->h_addr, host->h_length);
3458
 
#endif
3459
 
  return SOAP_OK;
3460
 
}
3461
 
#endif
3462
 
#endif
3463
 
#endif
3464
 
 
3465
 
/******************************************************************************/
3466
 
#ifndef WITH_NOIO
3467
 
#ifndef PALM_1
3468
 
static SOAP_SOCKET
3469
 
tcp_connect(struct soap *soap, const char *endpoint, const char *host, int port)
3470
 
{
3471
 
#ifdef WITH_IPV6
3472
 
  struct addrinfo hints, *res, *ressave;
3473
 
#endif
3474
 
  SOAP_SOCKET fd;
3475
 
  int err = 0;
3476
 
#ifndef WITH_LEAN
3477
 
  int retry = 10;
3478
 
  int len = SOAP_BUFLEN;
3479
 
  int set = 1;
3480
 
#endif
3481
 
  if (soap_valid_socket(soap->socket))
3482
 
    soap->fclosesocket(soap, soap->socket);
3483
 
  soap->socket = SOAP_INVALID_SOCKET;
3484
 
  if (tcp_init(soap))
3485
 
  { soap->errnum = 0;
3486
 
    soap_set_sender_error(soap, tcp_error(soap), "TCP init failed in tcp_connect()", SOAP_TCP_ERROR);
3487
 
    return SOAP_INVALID_SOCKET;
3488
 
  }
3489
 
  soap->errmode = 0;
3490
 
#ifdef WITH_IPV6
3491
 
  memset((void*)&hints, 0, sizeof(hints));
3492
 
  hints.ai_family = PF_UNSPEC;
3493
 
#ifdef WITH_UDP
3494
 
  if ((soap->omode & SOAP_IO_UDP))
3495
 
    hints.ai_socktype = SOCK_DGRAM;
3496
 
  else
3497
 
#endif
3498
 
    hints.ai_socktype = SOCK_STREAM;
3499
 
  soap->errmode = 2;
3500
 
  if (soap->proxy_host)
3501
 
    err = getaddrinfo(soap->proxy_host, soap_int2s(soap, soap->proxy_port), &hints, &res);
3502
 
  else
3503
 
    err = getaddrinfo(host, soap_int2s(soap, port), &hints, &res);
3504
 
  if (err)
3505
 
  { soap_set_sender_error(soap, SOAP_GAI_STRERROR(err), "getaddrinfo failed in tcp_connect()", SOAP_TCP_ERROR);
3506
 
    return SOAP_INVALID_SOCKET;
3507
 
  }
3508
 
  ressave = res;
3509
 
again:
3510
 
  fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
3511
 
  soap->errmode = 0;
3512
 
#else
3513
 
#ifndef WITH_LEAN
3514
 
again:
3515
 
#endif
3516
 
#ifdef WITH_UDP
3517
 
  if ((soap->omode & SOAP_IO_UDP))
3518
 
    fd = socket(AF_INET, SOCK_DGRAM, 0);
3519
 
  else
3520
 
#endif
3521
 
    fd = socket(AF_INET, SOCK_STREAM, 0);
3522
 
#endif
3523
 
  if (!soap_valid_socket(fd))
3524
 
  { soap->errnum = soap_socket_errno(fd);
3525
 
    soap_set_sender_error(soap, tcp_error(soap), "socket failed in tcp_connect()", SOAP_TCP_ERROR);
3526
 
#ifdef WITH_IPV6
3527
 
    freeaddrinfo(ressave);
3528
 
#endif
3529
 
    return SOAP_INVALID_SOCKET;
3530
 
  }
3531
 
#ifdef SOCKET_CLOSE_ON_EXEC
3532
 
#ifdef WIN32
3533
 
#ifndef UNDER_CE
3534
 
  SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0);
3535
 
#endif
3536
 
#else
3537
 
  fcntl(fd, F_SETFD, 1);
3538
 
#endif
3539
 
#endif
3540
 
#ifndef WITH_LEAN
3541
 
  if (soap->connect_flags == SO_LINGER)
3542
 
  { struct linger linger;
3543
 
    memset((void*)&linger, 0, sizeof(linger));
3544
 
    linger.l_onoff = 1;
3545
 
    linger.l_linger = 0;
3546
 
    if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger)))
3547
 
    { soap->errnum = soap_socket_errno(fd);
3548
 
      soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_LINGER failed in tcp_connect()", SOAP_TCP_ERROR);
3549
 
      soap->fclosesocket(soap, fd);
3550
 
#ifdef WITH_IPV6
3551
 
      freeaddrinfo(ressave);
3552
 
#endif
3553
 
      return SOAP_INVALID_SOCKET;
3554
 
    }
3555
 
  }
3556
 
  else if (soap->connect_flags && setsockopt(fd, SOL_SOCKET, soap->connect_flags, (char*)&set, sizeof(int)))
3557
 
  { soap->errnum = soap_socket_errno(fd);
3558
 
    soap_set_sender_error(soap, tcp_error(soap), "setsockopt failed in tcp_connect()", SOAP_TCP_ERROR);
3559
 
    soap->fclosesocket(soap, fd);
3560
 
#ifdef WITH_IPV6
3561
 
    freeaddrinfo(ressave);
3562
 
#endif
3563
 
    return SOAP_INVALID_SOCKET;
3564
 
  }
3565
 
  if ((soap->keep_alive || soap->tcp_keep_alive) && setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int)))
3566
 
  { soap->errnum = soap_socket_errno(fd);
3567
 
    soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in tcp_connect()", SOAP_TCP_ERROR);
3568
 
    soap->fclosesocket(soap, fd);
3569
 
#ifdef WITH_IPV6
3570
 
    freeaddrinfo(ressave);
3571
 
#endif
3572
 
    return SOAP_INVALID_SOCKET;
3573
 
  }
3574
 
  if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int)))
3575
 
  { soap->errnum = soap_socket_errno(fd);
3576
 
    soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in tcp_connect()", SOAP_TCP_ERROR);
3577
 
    soap->fclosesocket(soap, fd);
3578
 
#ifdef WITH_IPV6
3579
 
    freeaddrinfo(ressave);
3580
 
#endif
3581
 
    return SOAP_INVALID_SOCKET;
3582
 
  }
3583
 
  if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int)))
3584
 
  { soap->errnum = soap_socket_errno(fd);
3585
 
    soap_set_sender_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in tcp_connect()", SOAP_TCP_ERROR);
3586
 
    soap->fclosesocket(soap, fd);
3587
 
#ifdef WITH_IPV6
3588
 
    freeaddrinfo(ressave);
3589
 
#endif
3590
 
    return SOAP_INVALID_SOCKET;
3591
 
  }
3592
 
#ifdef TCP_KEEPIDLE
3593
 
  if (soap->tcp_keep_idle && setsockopt((SOAP_SOCKET)fd, IPPROTO_TCP, TCP_KEEPIDLE, (unsigned int*)&(soap->tcp_keep_idle), sizeof(int)))
3594
 
  { soap->errnum = soap_socket_errno(fd);
3595
 
    soap_set_sender_error(soap, tcp_error(soap), "setsockopt TCP_KEEPIDLE failed in tcp_connect()", SOAP_TCP_ERROR);
3596
 
    soap->fclosesocket(soap, (SOAP_SOCKET)fd);
3597
 
#ifdef WITH_IPV6
3598
 
    freeaddrinfo(ressave);
3599
 
#endif
3600
 
    return SOAP_INVALID_SOCKET;
3601
 
  }
3602
 
#endif
3603
 
#ifdef TCP_KEEPINTVL
3604
 
  if (soap->tcp_keep_intvl && setsockopt((SOAP_SOCKET)fd, IPPROTO_TCP, TCP_KEEPINTVL, (unsigned int*)&(soap->tcp_keep_intvl), sizeof(int)))
3605
 
  { soap->errnum = soap_socket_errno(fd);
3606
 
    soap_set_sender_error(soap, tcp_error(soap), "setsockopt TCP_KEEPINTVL failed in tcp_connect()", SOAP_TCP_ERROR);
3607
 
    soap->fclosesocket(soap, (SOAP_SOCKET)fd);
3608
 
#ifdef WITH_IPV6
3609
 
    freeaddrinfo(ressave);
3610
 
#endif
3611
 
    return SOAP_INVALID_SOCKET;
3612
 
  }
3613
 
#endif
3614
 
#ifdef TCP_KEEPCNT
3615
 
  if (soap->tcp_keep_cnt && setsockopt((SOAP_SOCKET)fd, IPPROTO_TCP, TCP_KEEPCNT, (unsigned int*)&(soap->tcp_keep_cnt), sizeof(int)))
3616
 
  { soap->errnum = soap_socket_errno(fd);
3617
 
    soap_set_sender_error(soap, tcp_error(soap), "setsockopt TCP_KEEPCNT failed in tcp_connect()", SOAP_TCP_ERROR);
3618
 
    soap->fclosesocket(soap, (SOAP_SOCKET)fd);
3619
 
#ifdef WITH_IPV6
3620
 
    freeaddrinfo(ressave);
3621
 
#endif
3622
 
    return SOAP_INVALID_SOCKET;
3623
 
  }
3624
 
#endif
3625
 
#ifdef TCP_NODELAY
3626
 
  if (!(soap->omode & SOAP_IO_UDP) && setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int)))
3627
 
  { soap->errnum = soap_socket_errno(fd);
3628
 
    soap_set_sender_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in tcp_connect()", SOAP_TCP_ERROR);
3629
 
    soap->fclosesocket(soap, fd);
3630
 
#ifdef WITH_IPV6
3631
 
    freeaddrinfo(ressave);
3632
 
#endif
3633
 
    return SOAP_INVALID_SOCKET;
3634
 
  }
3635
 
#endif
3636
 
#endif
3637
 
  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Opening socket %d to host='%s' port=%d\n", fd, host, port));
3638
 
#ifndef WITH_IPV6
3639
 
  soap->peerlen = sizeof(soap->peer);
3640
 
  memset((void*)&soap->peer, 0, sizeof(soap->peer));
3641
 
  soap->peer.sin_family = AF_INET;
3642
 
  soap->errmode = 2;
3643
 
  if (soap->proxy_host)
3644
 
  { if (soap->fresolve(soap, soap->proxy_host, &soap->peer.sin_addr))
3645
 
    { soap_set_sender_error(soap, tcp_error(soap), "get proxy host by name failed in tcp_connect()", SOAP_TCP_ERROR);
3646
 
      soap->fclosesocket(soap, fd);
3647
 
#ifdef WITH_IPV6
3648
 
      freeaddrinfo(ressave);
3649
 
#endif
3650
 
      return SOAP_INVALID_SOCKET;
3651
 
    }
3652
 
    soap->peer.sin_port = htons((short)soap->proxy_port);
3653
 
  }
3654
 
  else
3655
 
  { if (soap->fresolve(soap, host, &soap->peer.sin_addr))
3656
 
    { soap_set_sender_error(soap, tcp_error(soap), "get host by name failed in tcp_connect()", SOAP_TCP_ERROR);
3657
 
      soap->fclosesocket(soap, fd);
3658
 
#ifdef WITH_IPV6
3659
 
      freeaddrinfo(ressave);
3660
 
#endif
3661
 
      return SOAP_INVALID_SOCKET;
3662
 
    }
3663
 
    soap->peer.sin_port = htons((short)port);
3664
 
  }
3665
 
  soap->errmode = 0;
3666
 
  if ((soap->omode & SOAP_IO_UDP))
3667
 
  {
3668
 
#ifdef WITH_IPV6
3669
 
    freeaddrinfo(ressave);
3670
 
#endif
3671
 
    return fd;
3672
 
  }
3673
 
#endif
3674
 
#ifndef WITH_LEAN
3675
 
  if (soap->connect_timeout)
3676
 
#if defined(WIN32)
3677
 
  { u_long nonblocking = 1;
3678
 
    ioctlsocket(fd, FIONBIO, &nonblocking);
3679
 
  }
3680
 
#elif defined(VXWORKS)
3681
 
  { u_long nonblocking = 1;
3682
 
    ioctl(fd, FIONBIO, (int)(&nonblocking)); /* modified to use fd */
3683
 
  }
3684
 
#else
3685
 
    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)|O_NONBLOCK);
3686
 
#endif
3687
 
  else
3688
 
#if defined(WIN32)
3689
 
  { u_long blocking = 0;
3690
 
    ioctlsocket(fd, FIONBIO, &blocking);
3691
 
  }
3692
 
#elif defined(VXWORKS)
3693
 
  { u_long blocking = 0;
3694
 
    ioctl(fd, FIONBIO, (int)(&blocking));
3695
 
  }
3696
 
#else
3697
 
    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)&~O_NONBLOCK);
3698
 
#endif
3699
 
#endif
3700
 
  for (;;)
3701
 
  { 
3702
 
#ifdef WITH_IPV6
3703
 
    if (connect(fd, res->ai_addr, (int)res->ai_addrlen))
3704
 
#else
3705
 
    if (connect(fd, (struct sockaddr*)&soap->peer, sizeof(soap->peer)))
3706
 
#endif
3707
 
    { err = soap_socket_errno(fd);
3708
 
#ifndef WITH_LEAN
3709
 
      if (err == SOAP_EADDRINUSE)
3710
 
      { soap->fclosesocket(soap, fd);
3711
 
        if (retry-- > 0)
3712
 
          goto again;
3713
 
      }
3714
 
      else if (soap->connect_timeout && (err == SOAP_EINPROGRESS || err == SOAP_EWOULDBLOCK))
3715
 
      {
3716
 
        SOAP_SOCKLEN_T k;
3717
 
#ifndef WIN32
3718
 
        if ((int)soap->socket >= (int)FD_SETSIZE)
3719
 
        { soap->error = SOAP_FD_EXCEEDED;
3720
 
#ifdef WITH_IPV6
3721
 
          freeaddrinfo(ressave);
3722
 
#endif
3723
 
          return SOAP_INVALID_SOCKET;   /* Hint: MUST increase FD_SETSIZE */
3724
 
        }
3725
 
#endif
3726
 
        for (;;)
3727
 
        { struct timeval timeout;
3728
 
          fd_set fds;
3729
 
          register int r;
3730
 
          if (soap->connect_timeout > 0)
3731
 
          { timeout.tv_sec = soap->connect_timeout;
3732
 
            timeout.tv_usec = 0;
3733
 
          }
3734
 
          else
3735
 
          { timeout.tv_sec = -soap->connect_timeout/1000000;
3736
 
            timeout.tv_usec = -soap->connect_timeout%1000000;
3737
 
          }
3738
 
          FD_ZERO(&fds);
3739
 
          FD_SET(fd, &fds);
3740
 
          r = select((int)fd + 1, NULL, &fds, NULL, &timeout);
3741
 
          if (r > 0)
3742
 
            break;
3743
 
          if (!r)
3744
 
          { soap->errnum = 0;
3745
 
            DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connect timeout\n"));
3746
 
            soap_set_sender_error(soap, "Timeout", "connect failed in tcp_connect()", SOAP_TCP_ERROR);
3747
 
            soap->fclosesocket(soap, fd);
3748
 
#ifdef WITH_IPV6
3749
 
            freeaddrinfo(ressave);
3750
 
#endif
3751
 
            return SOAP_INVALID_SOCKET;
3752
 
          }
3753
 
          r = soap_socket_errno(fd);
3754
 
          if (r != SOAP_EINTR)
3755
 
          { soap->errnum = r;
3756
 
            DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
3757
 
            soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR);
3758
 
            soap->fclosesocket(soap, fd);
3759
 
#ifdef WITH_IPV6
3760
 
            freeaddrinfo(ressave);
3761
 
#endif
3762
 
            return SOAP_INVALID_SOCKET;
3763
 
          }
3764
 
        }
3765
 
        k = (SOAP_SOCKLEN_T)sizeof(soap->errnum);
3766
 
        if (!getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&soap->errnum, &k) && !soap->errnum)   /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */
3767
 
          break;
3768
 
        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
3769
 
        if (!soap->errnum)
3770
 
          soap->errnum = soap_socket_errno(fd);
3771
 
        soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR);
3772
 
        soap->fclosesocket(soap, fd);
3773
 
#ifdef WITH_IPV6
3774
 
        freeaddrinfo(ressave);
3775
 
#endif
3776
 
        return SOAP_INVALID_SOCKET;
3777
 
      }
3778
 
#endif
3779
 
#ifdef WITH_IPV6
3780
 
      if (res->ai_next)
3781
 
      { res = res->ai_next;
3782
 
        soap->fclosesocket(soap, fd);
3783
 
        goto again;
3784
 
      }
3785
 
#endif
3786
 
      if (err && err != SOAP_EINTR)
3787
 
      { soap->errnum = err;
3788
 
        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
3789
 
        soap_set_sender_error(soap, tcp_error(soap), "connect failed in tcp_connect()", SOAP_TCP_ERROR);
3790
 
        soap->fclosesocket(soap, fd);
3791
 
#ifdef WITH_IPV6
3792
 
        freeaddrinfo(ressave);
3793
 
#endif
3794
 
        return SOAP_INVALID_SOCKET;
3795
 
      }
3796
 
    }  
3797
 
    else
3798
 
      break;
3799
 
  }
3800
 
#ifdef WITH_IPV6
3801
 
  soap->peerlen = 0; /* IPv6: already connected so use send() */
3802
 
  freeaddrinfo(ressave);
3803
 
#endif
3804
 
#ifndef WITH_LEAN
3805
 
  if (soap->connect_timeout)
3806
 
#if defined(WIN32)
3807
 
  { u_long blocking = 0;
3808
 
    ioctlsocket(fd, FIONBIO, &blocking);
3809
 
  }
3810
 
#elif defined(VXWORKS)
3811
 
  { u_long blocking = 0;
3812
 
    ioctl(fd, FIONBIO, (int)(&blocking));
3813
 
  }
3814
 
#else
3815
 
    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)&~O_NONBLOCK);
3816
 
#endif
3817
 
#endif
3818
 
  soap->socket = fd;
3819
 
  soap->imode &= ~SOAP_ENC_SSL;
3820
 
  soap->omode &= ~SOAP_ENC_SSL;
3821
 
  if (!soap_tag_cmp(endpoint, "https:*"))
3822
 
  {
3823
 
#ifdef WITH_OPENSSL
3824
 
    BIO *bio;
3825
 
    int r;
3826
 
    if (soap->proxy_host)
3827
 
    { unsigned int k = soap->omode; /* make sure we only parse HTTP */
3828
 
      size_t n = soap->count; /* save the content length */
3829
 
      char *userid, *passwd;
3830
 
      soap->omode &= ~SOAP_ENC; /* mask IO and ENC */
3831
 
      soap->omode |= SOAP_IO_BUFFER;
3832
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connecting to %s proxy server\n", soap->proxy_http_version));
3833
 
      sprintf(soap->tmpbuf, "CONNECT %s:%d HTTP/%s", host, port, soap->proxy_http_version);
3834
 
      if (soap_begin_send(soap)
3835
 
       || (soap->error = soap->fposthdr(soap, soap->tmpbuf, NULL)))
3836
 
      { soap->fclosesocket(soap, fd);
3837
 
        return SOAP_INVALID_SOCKET;
3838
 
      }
3839
 
#ifndef WITH_LEAN
3840
 
      if (soap->proxy_userid && soap->proxy_passwd && strlen(soap->proxy_userid) + strlen(soap->proxy_passwd) < 761)
3841
 
      { sprintf(soap->tmpbuf + 262, "%s:%s", soap->proxy_userid, soap->proxy_passwd);
3842
 
        strcpy(soap->tmpbuf, "Basic ");
3843
 
        soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, (int)strlen(soap->tmpbuf + 262));
3844
 
        if ((soap->error = soap->fposthdr(soap, "Proxy-Authorization", soap->tmpbuf)))
3845
 
        { soap->fclosesocket(soap, fd);
3846
 
          return soap->error;
3847
 
        }
3848
 
      }
3849
 
#endif
3850
 
      if ((soap->error = soap->fposthdr(soap, NULL, NULL))
3851
 
       || soap_flush(soap))
3852
 
      { soap->fclosesocket(soap, fd);
3853
 
        return SOAP_INVALID_SOCKET;
3854
 
      }
3855
 
      soap->omode = k;
3856
 
      k = soap->imode;
3857
 
      soap->imode &= ~SOAP_ENC; /* mask IO and ENC */
3858
 
      userid = soap->userid; /* preserve */
3859
 
      passwd = soap->passwd; /* preserve */
3860
 
      if ((soap->error = soap->fparse(soap)))
3861
 
      { soap->fclosesocket(soap, fd);
3862
 
        return SOAP_INVALID_SOCKET;
3863
 
      }
3864
 
      soap->userid = userid; /* restore */
3865
 
      soap->passwd = passwd; /* restore */
3866
 
      soap->imode = k; /* restore */
3867
 
      soap->count = n; /* restore */
3868
 
      if (soap_begin_send(soap))
3869
 
      { soap->fclosesocket(soap, fd);
3870
 
        return SOAP_INVALID_SOCKET;
3871
 
      }
3872
 
      if (endpoint)
3873
 
        strncpy(soap->endpoint, endpoint, sizeof(soap->endpoint)-1); /* restore */
3874
 
    }
3875
 
    if (!soap->ctx && (soap->error = soap->fsslauth(soap)))
3876
 
    { soap_set_sender_error(soap, "SSL error", "SSL authentication failed in tcp_connect(): check password, key file, and ca file.", SOAP_SSL_ERROR);
3877
 
      soap->fclosesocket(soap, fd);
3878
 
      return SOAP_INVALID_SOCKET;
3879
 
    }
3880
 
    soap->ssl = SSL_new(soap->ctx);
3881
 
    if (!soap->ssl)
3882
 
    { soap->fclosesocket(soap, fd);
3883
 
      soap->error = SOAP_SSL_ERROR;
3884
 
      return SOAP_INVALID_SOCKET;
3885
 
    }
3886
 
    if (soap->session)
3887
 
    { if (!strcmp(soap->session_host, host) && soap->session_port == port)
3888
 
        SSL_set_session(soap->ssl, soap->session);
3889
 
      SSL_SESSION_free(soap->session);
3890
 
      soap->session = NULL;
3891
 
    }
3892
 
    soap->imode |= SOAP_ENC_SSL;
3893
 
    soap->omode |= SOAP_ENC_SSL;
3894
 
    bio = BIO_new_socket(fd, BIO_NOCLOSE);
3895
 
    SSL_set_bio(soap->ssl, bio, bio);
3896
 
    /* Connect timeout: set SSL sockets to non-blocking */
3897
 
#ifndef WITH_LEAN
3898
 
    if (soap->connect_timeout)
3899
 
#if defined(WIN32)
3900
 
    { u_long nonblocking = 1;
3901
 
      ioctlsocket(fd, FIONBIO, &nonblocking);
3902
 
    }
3903
 
#elif defined(VXWORKS)
3904
 
    { u_long nonblocking = 1;
3905
 
      ioctl(fd, FIONBIO, (int)(&nonblocking));
3906
 
    }
3907
 
#else
3908
 
      fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)|O_NONBLOCK);
3909
 
#endif
3910
 
#endif
3911
 
    /* Try connecting until success or timeout */
3912
 
    for (;;)
3913
 
    { if ((r = SSL_connect(soap->ssl)) <= 0)
3914
 
      { int err = SSL_get_error(soap->ssl, r);
3915
 
        if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
3916
 
        { soap_set_sender_error(soap, soap_ssl_error(soap, r), "SSL connect failed in tcp_connect()", SOAP_SSL_ERROR);
3917
 
          soap->fclosesocket(soap, fd);
3918
 
          return SOAP_INVALID_SOCKET;
3919
 
        }
3920
 
        if (soap->connect_timeout)
3921
 
        {
3922
 
#ifndef WIN32
3923
 
          if ((int)soap->socket >= (int)FD_SETSIZE)
3924
 
          { soap->error = SOAP_FD_EXCEEDED;
3925
 
            return SOAP_INVALID_SOCKET; /* Hint: MUST increase FD_SETSIZE */
3926
 
          }
3927
 
#endif
3928
 
          for (;;)
3929
 
          { struct timeval timeout;
3930
 
            fd_set fds;
3931
 
            register int r;
3932
 
            if (soap->connect_timeout > 0)
3933
 
            { timeout.tv_sec = soap->connect_timeout;
3934
 
              timeout.tv_usec = 0;
3935
 
            }
3936
 
            else
3937
 
            { timeout.tv_sec = -soap->connect_timeout/1000000;
3938
 
              timeout.tv_usec = -soap->connect_timeout%1000000;
3939
 
            }
3940
 
            FD_ZERO(&fds);
3941
 
            FD_SET(fd, &fds);
3942
 
            r = select((int)fd + 1, &fds, NULL, &fds, &timeout);
3943
 
            if (r > 0)
3944
 
              break;
3945
 
            if (!r)
3946
 
            { soap->errnum = 0;
3947
 
              DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connect timeout\n"));
3948
 
              soap_set_sender_error(soap, "Timeout", "connect failed in tcp_connect()", SOAP_TCP_ERROR);
3949
 
              soap->fclosesocket(soap, fd);
3950
 
              return SOAP_INVALID_SOCKET;
3951
 
            }
3952
 
          }
3953
 
          continue;
3954
 
        }
3955
 
      }
3956
 
      break;
3957
 
    }
3958
 
    /* Set SSL sockets to non-blocking */
3959
 
#ifndef WITH_LEAN
3960
 
#if defined(WIN32)
3961
 
    { u_long nonblocking = 1;
3962
 
      ioctlsocket(fd, FIONBIO, &nonblocking);
3963
 
    }
3964
 
#elif defined(VXWORKS)
3965
 
    { u_long nonblocking = 1;
3966
 
      ioctl(fd, FIONBIO, (int)(&nonblocking));
3967
 
    }
3968
 
#else
3969
 
    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)|O_NONBLOCK);
3970
 
#endif
3971
 
#endif
3972
 
    /* Check server credentials when required */
3973
 
    if ((soap->ssl_flags & SOAP_SSL_REQUIRE_SERVER_AUTHENTICATION))
3974
 
    { int err;
3975
 
      if ((err = SSL_get_verify_result(soap->ssl)) != X509_V_OK)
3976
 
      { 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);
3977
 
        soap->fclosesocket(soap, fd);
3978
 
        return SOAP_INVALID_SOCKET;
3979
 
      }
3980
 
      if (!(soap->ssl_flags & SOAP_SSL_SKIP_HOST_CHECK))
3981
 
      { X509_NAME *subj;
3982
 
        int ext_count;
3983
 
        int ok = 0;
3984
 
        X509 *peer;
3985
 
        peer = SSL_get_peer_certificate(soap->ssl);
3986
 
        if (!peer)
3987
 
        { soap_set_sender_error(soap, "SSL error", "No SSL certificate was presented by the peer in tcp_connect()", SOAP_SSL_ERROR);
3988
 
          soap->fclosesocket(soap, fd);
3989
 
          return SOAP_INVALID_SOCKET;
3990
 
        }
3991
 
        ext_count = X509_get_ext_count(peer);
3992
 
        if (ext_count > 0)
3993
 
        { int i;
3994
 
          for (i = 0; i < ext_count; i++)
3995
 
          { X509_EXTENSION *ext = X509_get_ext(peer, i);
3996
 
            const char *ext_str = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
3997
 
            if (ext_str && !strcmp(ext_str, "subjectAltName"))
3998
 
            { X509V3_EXT_METHOD *meth = X509V3_EXT_get(ext);
3999
 
              void *ext_data;
4000
 
#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
4001
 
              const unsigned char *data;
4002
 
#else
4003
 
              unsigned char *data;
4004
 
#endif
4005
 
              STACK_OF(CONF_VALUE) *val;
4006
 
              int j;
4007
 
              if (!meth)
4008
 
                break;
4009
 
              data = ext->value->data;
4010
 
#if (OPENSSL_VERSION_NUMBER > 0x00907000L)
4011
 
              if (meth->it) 
4012
 
                ext_data = ASN1_item_d2i(NULL, &data, ext->value->length, ASN1_ITEM_ptr(meth->it));
4013
 
              else
4014
 
              { /* OpenSSL not perfectly portable at this point (?):
4015
 
                   Some compilers appear to prefer
4016
 
                   meth->d2i(NULL, (const unsigned char**)&data, ...
4017
 
                   or
4018
 
                   meth->d2i(NULL, &data, ext->value->length);
4019
 
                */
4020
 
                ext_data = meth->d2i(NULL, &data, ext->value->length);
4021
 
              }
4022
 
#else
4023
 
              ext_data = meth->d2i(NULL, &data, ext->value->length);
4024
 
#endif
4025
 
              val = meth->i2v(meth, ext_data, NULL);
4026
 
              for (j = 0; j < sk_CONF_VALUE_num(val); j++)
4027
 
              { CONF_VALUE *nval = sk_CONF_VALUE_value(val, j);
4028
 
                if (nval && !strcmp(nval->name, "DNS") && !strcmp(nval->value, host))
4029
 
                { ok = 1;
4030
 
                  break;
4031
 
                }
4032
 
              }
4033
 
            }
4034
 
            if (ok)
4035
 
              break;
4036
 
          }
4037
 
        }
4038
 
        if (!ok && (subj = X509_get_subject_name(peer)))
4039
 
        { int i = -1;
4040
 
          do
4041
 
          { ASN1_STRING *name;
4042
 
            i = X509_NAME_get_index_by_NID(subj, NID_commonName, i);
4043
 
            if (i == -1)
4044
 
              break;
4045
 
            name = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subj, i));
4046
 
            if (name)
4047
 
            { if (!soap_tag_cmp(host, (const char*)name))
4048
 
                ok = 1;
4049
 
              else
4050
 
              { unsigned char *tmp = NULL;
4051
 
                ASN1_STRING_to_UTF8(&tmp, name);
4052
 
                if (tmp)
4053
 
                { if (!soap_tag_cmp(host, (const char*)tmp))
4054
 
                    ok = 1;
4055
 
                  OPENSSL_free(tmp);
4056
 
                }
4057
 
              }
4058
 
            }
4059
 
          } while (!ok);
4060
 
        }
4061
 
        X509_free(peer);
4062
 
        if (!ok)
4063
 
        { soap_set_sender_error(soap, "SSL error", "SSL certificate host name mismatch in tcp_connect()", SOAP_SSL_ERROR);
4064
 
          soap->fclosesocket(soap, fd);
4065
 
          return SOAP_INVALID_SOCKET;
4066
 
        }
4067
 
      }
4068
 
    }
4069
 
#else
4070
 
    soap->fclosesocket(soap, fd);
4071
 
    soap->error = SOAP_SSL_ERROR;
4072
 
    return SOAP_INVALID_SOCKET;
4073
 
#endif
4074
 
  }
4075
 
  return fd;
4076
 
}
4077
 
#endif
4078
 
#endif
4079
 
 
4080
 
/******************************************************************************/
4081
 
#ifndef WITH_NOIO
4082
 
#ifndef PALM_1
4083
 
SOAP_FMAC1
4084
 
SOAP_SOCKET
4085
 
SOAP_FMAC2
4086
 
soap_bind(struct soap *soap, const char *host, int port, int backlog)
4087
 
{
4088
 
#ifdef WITH_IPV6
4089
 
  struct addrinfo *addrinfo = NULL;
4090
 
  struct addrinfo hints;
4091
 
  struct addrinfo res;
4092
 
  int err;
4093
 
#endif
4094
 
#ifndef WITH_LEAN
4095
 
  int len = SOAP_BUFLEN;
4096
 
  int set = 1;
4097
 
#endif
4098
 
  if (soap_valid_socket(soap->master))
4099
 
  { soap->fclosesocket(soap, soap->master);
4100
 
    soap->master = SOAP_INVALID_SOCKET;
4101
 
  }
4102
 
  soap->socket = SOAP_INVALID_SOCKET;
4103
 
  soap->errmode = 1;
4104
 
  if (tcp_init(soap))
4105
 
  { soap_set_receiver_error(soap, tcp_error(soap), "TCP init failed in soap_bind()", SOAP_TCP_ERROR);
4106
 
    return SOAP_INVALID_SOCKET;
4107
 
  }
4108
 
#ifdef WITH_IPV6
4109
 
  memset((void*)&hints, 0, sizeof(hints));
4110
 
  hints.ai_family = PF_UNSPEC;
4111
 
#ifdef WITH_UDP
4112
 
  if ((soap->omode & SOAP_IO_UDP))
4113
 
    hints.ai_socktype = SOCK_DGRAM;
4114
 
  else
4115
 
#endif
4116
 
    hints.ai_socktype = SOCK_STREAM;
4117
 
  hints.ai_flags = AI_PASSIVE;
4118
 
  soap->errmode = 2;
4119
 
  err = getaddrinfo(host, soap_int2s(soap, port), &hints, &addrinfo);
4120
 
  if (addrinfo)
4121
 
  { res = *addrinfo;
4122
 
    memcpy(&soap->peer, addrinfo->ai_addr, addrinfo->ai_addrlen);
4123
 
    soap->peerlen = addrinfo->ai_addrlen;
4124
 
    res.ai_addr = (struct sockaddr*)&soap->peer;
4125
 
    res.ai_addrlen = soap->peerlen;
4126
 
    freeaddrinfo(addrinfo);
4127
 
  }
4128
 
  if (err || !addrinfo)
4129
 
  { soap_set_receiver_error(soap, SOAP_GAI_STRERROR(err), "getaddrinfo failed in soap_bind()", SOAP_TCP_ERROR);
4130
 
    return SOAP_INVALID_SOCKET;
4131
 
  }
4132
 
  soap->master = (int)socket(res.ai_family, res.ai_socktype, res.ai_protocol);
4133
 
#else
4134
 
#ifdef WITH_UDP
4135
 
  if ((soap->omode & SOAP_IO_UDP))
4136
 
    soap->master = (int)socket(AF_INET, SOCK_DGRAM, 0);
4137
 
  else
4138
 
#endif
4139
 
    soap->master = (int)socket(AF_INET, SOCK_STREAM, 0);
4140
 
#endif
4141
 
  soap->errmode = 0;
4142
 
  if (!soap_valid_socket(soap->master))
4143
 
  { soap->errnum = soap_socket_errno(soap->master);
4144
 
    soap_set_receiver_error(soap, tcp_error(soap), "socket failed in soap_bind()", SOAP_TCP_ERROR);
4145
 
    return SOAP_INVALID_SOCKET;
4146
 
  }
4147
 
#ifdef WITH_UDP
4148
 
  if ((soap->omode & SOAP_IO_UDP))
4149
 
    soap->socket = soap->master;
4150
 
#endif
4151
 
#ifdef SOCKET_CLOSE_ON_EXEC
4152
 
#ifdef WIN32
4153
 
#ifndef UNDER_CE
4154
 
  SetHandleInformation((HANDLE)soap->master, HANDLE_FLAG_INHERIT, 0);
4155
 
#endif
4156
 
#else
4157
 
  fcntl(soap->master, F_SETFD, 1);
4158
 
#endif
4159
 
#endif
4160
 
#ifndef WITH_LEAN
4161
 
  if (soap->bind_flags && setsockopt(soap->master, SOL_SOCKET, soap->bind_flags, (char*)&set, sizeof(int)))
4162
 
  { soap->errnum = soap_socket_errno(soap->master);
4163
 
    soap_set_receiver_error(soap, tcp_error(soap), "setsockopt failed in soap_bind()", SOAP_TCP_ERROR);
4164
 
    return SOAP_INVALID_SOCKET;
4165
 
  }
4166
 
  if (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) && setsockopt(soap->master, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int)))
4167
 
  { soap->errnum = soap_socket_errno(soap->master);
4168
 
    soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in soap_bind()", SOAP_TCP_ERROR);
4169
 
    return SOAP_INVALID_SOCKET;
4170
 
  }
4171
 
  if (setsockopt(soap->master, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int)))
4172
 
  { soap->errnum = soap_socket_errno(soap->master);
4173
 
    soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in soap_bind()", SOAP_TCP_ERROR);
4174
 
    return SOAP_INVALID_SOCKET;
4175
 
  }
4176
 
  if (setsockopt(soap->master, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int)))
4177
 
  { soap->errnum = soap_socket_errno(soap->master);
4178
 
    soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in soap_bind()", SOAP_TCP_ERROR);
4179
 
    return SOAP_INVALID_SOCKET;
4180
 
  }
4181
 
#ifdef TCP_NODELAY
4182
 
  if (!(soap->omode & SOAP_IO_UDP) && setsockopt(soap->master, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int)))
4183
 
  { soap->errnum = soap_socket_errno(soap->master);
4184
 
    soap_set_receiver_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in soap_bind()", SOAP_TCP_ERROR);
4185
 
    return SOAP_INVALID_SOCKET;
4186
 
  }
4187
 
#endif
4188
 
#endif
4189
 
#ifdef WITH_IPV6
4190
 
  soap->errmode = 0;
4191
 
  if (bind(soap->master, res.ai_addr, (int)res.ai_addrlen))
4192
 
  { soap->errnum = soap_socket_errno(soap->master);
4193
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n"));
4194
 
    soap_closesock(soap);
4195
 
    soap_set_receiver_error(soap, tcp_error(soap), "bind failed in soap_bind()", SOAP_TCP_ERROR);
4196
 
    return SOAP_INVALID_SOCKET;
4197
 
  }  
4198
 
#else
4199
 
  soap->peerlen = sizeof(soap->peer);
4200
 
  memset((void*)&soap->peer, 0, sizeof(soap->peer));
4201
 
  soap->peer.sin_family = AF_INET;
4202
 
  soap->errmode = 2;
4203
 
  if (host)
4204
 
  { if (soap->fresolve(soap, host, &soap->peer.sin_addr))
4205
 
    { soap_set_receiver_error(soap, tcp_error(soap), "get host by name failed in soap_bind()", SOAP_TCP_ERROR);
4206
 
      return SOAP_INVALID_SOCKET;
4207
 
    }
4208
 
  }
4209
 
  else
4210
 
    soap->peer.sin_addr.s_addr = htonl(INADDR_ANY);
4211
 
  soap->peer.sin_port = htons((short)port);
4212
 
  soap->errmode = 0;
4213
 
  if (bind(soap->master, (struct sockaddr*)&soap->peer, (int)soap->peerlen))
4214
 
  { soap->errnum = soap_socket_errno(soap->master);
4215
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n"));
4216
 
    soap_closesock(soap);
4217
 
    soap_set_receiver_error(soap, tcp_error(soap), "bind failed in soap_bind()", SOAP_TCP_ERROR);
4218
 
    return SOAP_INVALID_SOCKET;
4219
 
  }
4220
 
#endif
4221
 
  if (!(soap->omode & SOAP_IO_UDP) && listen(soap->master, backlog))
4222
 
  { soap->errnum = soap_socket_errno(soap->master);
4223
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not bind to host\n"));
4224
 
    soap_closesock(soap);
4225
 
    soap_set_receiver_error(soap, tcp_error(soap), "listen failed in soap_bind()", SOAP_TCP_ERROR);
4226
 
    return SOAP_INVALID_SOCKET;
4227
 
  }  
4228
 
  return soap->master;
4229
 
}
4230
 
#endif
4231
 
#endif
4232
 
 
4233
 
/******************************************************************************/
4234
 
#ifndef WITH_NOIO
4235
 
#ifndef PALM_1
4236
 
SOAP_FMAC1
4237
 
int
4238
 
SOAP_FMAC2
4239
 
soap_poll(struct soap *soap)
4240
 
4241
 
#ifndef WITH_LEAN
4242
 
  struct timeval timeout;
4243
 
  fd_set rfd, sfd, xfd;
4244
 
  register int r;
4245
 
#ifndef WIN32
4246
 
  if ((int)soap->socket >= (int)FD_SETSIZE)
4247
 
    return SOAP_FD_EXCEEDED;    /* Hint: MUST increase FD_SETSIZE */
4248
 
#endif
4249
 
  timeout.tv_sec = 0;
4250
 
  timeout.tv_usec = 0;
4251
 
  FD_ZERO(&rfd);
4252
 
  FD_ZERO(&sfd);
4253
 
  FD_ZERO(&xfd);
4254
 
  if (soap_valid_socket(soap->socket))
4255
 
  { FD_SET(soap->socket, &rfd);
4256
 
    FD_SET(soap->socket, &sfd);
4257
 
    FD_SET(soap->socket, &xfd);
4258
 
    r = select((int)soap->socket + 1, &rfd, &sfd, &xfd, &timeout);
4259
 
    if (r > 0 && FD_ISSET(soap->socket, &xfd))
4260
 
      r = -1;
4261
 
  }
4262
 
  else if (soap_valid_socket(soap->master))
4263
 
  { FD_SET(soap->master, &sfd);
4264
 
    r = select((int)soap->master + 1, NULL, &sfd, NULL, &timeout);
4265
 
  }
4266
 
  else
4267
 
    return SOAP_OK;
4268
 
  if (r > 0)
4269
 
  {
4270
 
#ifdef WITH_OPENSSL
4271
 
    if (soap->imode & SOAP_ENC_SSL)
4272
 
    {
4273
 
      if (soap_valid_socket(soap->socket)
4274
 
       && FD_ISSET(soap->socket, &sfd)
4275
 
       && (!FD_ISSET(soap->socket, &rfd)
4276
 
        || SSL_peek(soap->ssl, soap->tmpbuf, 1) > 0))
4277
 
        return SOAP_OK;
4278
 
    }
4279
 
    else
4280
 
#endif
4281
 
      if (soap_valid_socket(soap->socket)
4282
 
       && FD_ISSET(soap->socket, &sfd)
4283
 
       && (!FD_ISSET(soap->socket, &rfd)
4284
 
        || recv(soap->socket, soap->tmpbuf, 1, MSG_PEEK) > 0))
4285
 
        return SOAP_OK;
4286
 
  }
4287
 
  else if (r < 0)
4288
 
  { soap->errnum = soap_socket_errno(soap->master);
4289
 
    if ((soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) && soap_socket_errno(soap->master) != SOAP_EINTR)
4290
 
    { soap_set_receiver_error(soap, tcp_error(soap), "select failed in soap_poll()", SOAP_TCP_ERROR);
4291
 
      return soap->error = SOAP_TCP_ERROR;
4292
 
    }
4293
 
  }
4294
 
  else
4295
 
    soap->errnum = 0;
4296
 
  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Polling: other end down on socket=%d select=%d\n", soap->socket, r));
4297
 
  return SOAP_EOF;
4298
 
#else
4299
 
  return SOAP_OK;
4300
 
#endif
4301
 
}
4302
 
#endif
4303
 
#endif
4304
 
 
4305
 
/******************************************************************************/
4306
 
#ifndef WITH_NOIO
4307
 
#ifndef PALM_1
4308
 
static SOAP_SOCKET
4309
 
tcp_accept(struct soap *soap, SOAP_SOCKET s, struct sockaddr *a, int *n)
4310
 
{ SOAP_SOCKET fd;
4311
 
  fd = accept(s, a, (SOAP_SOCKLEN_T*)n);        /* portability note: see SOAP_SOCKLEN_T definition in stdsoap2.h */
4312
 
#ifdef SOCKET_CLOSE_ON_EXEC
4313
 
#ifdef WIN32
4314
 
#ifndef UNDER_CE
4315
 
  SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0);
4316
 
#endif
4317
 
#else
4318
 
  fcntl(fd, F_SETFD, FD_CLOEXEC);
4319
 
#endif
4320
 
#endif
4321
 
  return fd;
4322
 
}
4323
 
#endif
4324
 
#endif
4325
 
 
4326
 
/******************************************************************************/
4327
 
#ifndef WITH_NOIO
4328
 
#ifndef PALM_1
4329
 
SOAP_FMAC1
4330
 
SOAP_SOCKET
4331
 
SOAP_FMAC2
4332
 
soap_accept(struct soap *soap)
4333
 
{ int n = (int)sizeof(soap->peer);
4334
 
#ifndef WITH_LEAN
4335
 
  int len = SOAP_BUFLEN;
4336
 
  int set = 1;
4337
 
#endif
4338
 
  soap->error = SOAP_OK;
4339
 
#ifdef WITH_UDP
4340
 
  if ((soap->omode & SOAP_IO_UDP))
4341
 
    return soap->socket = soap->master;
4342
 
#endif
4343
 
  memset((void*)&soap->peer, 0, sizeof(soap->peer));
4344
 
  soap->socket = SOAP_INVALID_SOCKET;
4345
 
  soap->errmode = 0;
4346
 
  soap->keep_alive = 0;
4347
 
  if (soap_valid_socket(soap->master))
4348
 
  { register int err;
4349
 
    for (;;)
4350
 
    { 
4351
 
#ifndef WITH_LEAN
4352
 
      if (soap->accept_timeout)
4353
 
      {
4354
 
#ifndef WIN32
4355
 
        if ((int)soap->socket >= (int)FD_SETSIZE)
4356
 
        { soap->error = SOAP_FD_EXCEEDED;
4357
 
          return SOAP_INVALID_SOCKET;   /* Hint: MUST increase FD_SETSIZE */
4358
 
        }
4359
 
#endif
4360
 
        for (;;)
4361
 
        { struct timeval timeout;
4362
 
          fd_set fd;
4363
 
          register int r;
4364
 
          if (soap->accept_timeout > 0)
4365
 
          { timeout.tv_sec = soap->accept_timeout;
4366
 
            timeout.tv_usec = 0;
4367
 
          }
4368
 
          else
4369
 
          { timeout.tv_sec = -soap->accept_timeout/1000000;
4370
 
            timeout.tv_usec = -soap->accept_timeout%1000000;
4371
 
          }
4372
 
          FD_ZERO(&fd);
4373
 
          FD_SET(soap->master, &fd);
4374
 
          r = select((int)soap->master + 1, &fd, &fd, &fd, &timeout);
4375
 
          if (r > 0)
4376
 
            break;
4377
 
          if (!r)
4378
 
          { soap->errnum = 0;
4379
 
            soap_set_receiver_error(soap, "Timeout", "accept failed in soap_accept()", SOAP_TCP_ERROR);
4380
 
            return SOAP_INVALID_SOCKET;
4381
 
          }
4382
 
          r = soap_socket_errno(soap->master);
4383
 
          if (r != SOAP_EINTR)
4384
 
          { soap->errnum = r;
4385
 
            soap_closesock(soap);
4386
 
            soap_set_sender_error(soap, tcp_error(soap), "accept failed in soap_accept()", SOAP_TCP_ERROR);
4387
 
            return SOAP_INVALID_SOCKET;
4388
 
          }
4389
 
        }
4390
 
#if defined(WIN32)
4391
 
        { u_long nonblocking = 1;
4392
 
          ioctlsocket(soap->master, FIONBIO, &nonblocking);
4393
 
        }
4394
 
#elif defined(VXWORKS)
4395
 
        { u_long nonblocking = 1;
4396
 
          ioctl(soap->master, FIONBIO, (int)(&nonblocking));
4397
 
        }
4398
 
#else
4399
 
        fcntl(soap->master, F_SETFL, fcntl(soap->master, F_GETFL)|O_NONBLOCK);
4400
 
#endif
4401
 
      }
4402
 
      else
4403
 
#if defined(WIN32)
4404
 
      { u_long blocking = 0;
4405
 
        ioctlsocket(soap->master, FIONBIO, &blocking);
4406
 
      }
4407
 
#elif defined(VXWORKS)
4408
 
      { u_long blocking = 0;
4409
 
        ioctl(soap->master, FIONBIO, (int)(&blocking));
4410
 
      }
4411
 
#else
4412
 
        fcntl(soap->master, F_SETFL, fcntl(soap->master, F_GETFL)&~O_NONBLOCK);
4413
 
#endif
4414
 
#endif
4415
 
      soap->socket = soap->faccept(soap, soap->master, (struct sockaddr*)&soap->peer, &n);
4416
 
      soap->peerlen = (size_t)n;
4417
 
      if (soap_valid_socket(soap->socket))
4418
 
      {
4419
 
#ifdef WITH_IPV6
4420
 
/* Use soap->host to store the numeric form of the remote host */
4421
 
        getnameinfo((struct sockaddr*)&soap->peer, n, soap->host, sizeof(soap->host), NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV); 
4422
 
        DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept socket %d from %s\n", soap->socket, soap->host));
4423
 
        soap->ip = 0; /* info stored in soap->peer and soap->host */
4424
 
        soap->port = 0; /* info stored in soap->peer and soap->host */
4425
 
#else
4426
 
        soap->ip = ntohl(soap->peer.sin_addr.s_addr);
4427
 
        soap->port = (int)ntohs(soap->peer.sin_port); /* does not return port number on some systems */
4428
 
        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));
4429
 
#endif
4430
 
#ifndef WITH_LEAN
4431
 
        if (soap->accept_flags == SO_LINGER)
4432
 
        { struct linger linger;
4433
 
          memset((void*)&linger, 0, sizeof(linger));
4434
 
          linger.l_onoff = 1;
4435
 
          linger.l_linger = 0;
4436
 
          if (setsockopt(soap->socket, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(struct linger)))
4437
 
          { soap->errnum = soap_socket_errno(soap->socket);
4438
 
            soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_LINGER failed in soap_accept()", SOAP_TCP_ERROR);
4439
 
            soap_closesock(soap);
4440
 
            return SOAP_INVALID_SOCKET;
4441
 
          }
4442
 
        }
4443
 
        else if (soap->accept_flags && setsockopt(soap->socket, SOL_SOCKET, soap->accept_flags, (char*)&set, sizeof(int)))
4444
 
        { soap->errnum = soap_socket_errno(soap->socket);
4445
 
          soap_set_receiver_error(soap, tcp_error(soap), "setsockopt failed in soap_accept()", SOAP_TCP_ERROR);
4446
 
          soap_closesock(soap);
4447
 
          return SOAP_INVALID_SOCKET;
4448
 
        }
4449
 
        if (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) && setsockopt(soap->socket, SOL_SOCKET, SO_KEEPALIVE, (char*)&set, sizeof(int)))
4450
 
        { soap->errnum = soap_socket_errno(soap->socket);
4451
 
          soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_KEEPALIVE failed in soap_accept()", SOAP_TCP_ERROR);
4452
 
          soap_closesock(soap);
4453
 
          return SOAP_INVALID_SOCKET;
4454
 
        }
4455
 
        if (setsockopt(soap->socket, SOL_SOCKET, SO_SNDBUF, (char*)&len, sizeof(int)))
4456
 
        { soap->errnum = soap_socket_errno(soap->socket);
4457
 
          soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_SNDBUF failed in soap_accept()", SOAP_TCP_ERROR);
4458
 
          soap_closesock(soap);
4459
 
          return SOAP_INVALID_SOCKET;
4460
 
        }
4461
 
        if (setsockopt(soap->socket, SOL_SOCKET, SO_RCVBUF, (char*)&len, sizeof(int)))
4462
 
        { soap->errnum = soap_socket_errno(soap->socket);
4463
 
          soap_set_receiver_error(soap, tcp_error(soap), "setsockopt SO_RCVBUF failed in soap_accept()", SOAP_TCP_ERROR);
4464
 
          soap_closesock(soap);
4465
 
          return SOAP_INVALID_SOCKET;
4466
 
        }
4467
 
#ifdef TCP_NODELAY
4468
 
        if (!(soap->omode & SOAP_IO_UDP) && setsockopt(soap->socket, IPPROTO_TCP, TCP_NODELAY, (char*)&set, sizeof(int)))
4469
 
        { soap->errnum = soap_socket_errno(soap->socket);
4470
 
          soap_set_receiver_error(soap, tcp_error(soap), "setsockopt TCP_NODELAY failed in soap_accept()", SOAP_TCP_ERROR);
4471
 
          soap_closesock(soap);
4472
 
          return SOAP_INVALID_SOCKET;
4473
 
        }
4474
 
#endif
4475
 
#endif
4476
 
        if (soap->accept_timeout)
4477
 
        {
4478
 
#if defined(WIN32)
4479
 
          u_long blocking = 0;
4480
 
          ioctlsocket(soap->master, FIONBIO, &blocking);
4481
 
          ioctlsocket(soap->socket, FIONBIO, &blocking);
4482
 
#elif defined(VXWORKS)
4483
 
          u_long blocking = 0;
4484
 
          ioctl(soap->master, FIONBIO, (int)(&blocking));
4485
 
          ioctl(soap->socket, FIONBIO, (int)(&blocking));
4486
 
#elif defined(PALM)
4487
 
          fcntl(soap->master, F_SETFL, fcntl(soap->master, F_GETFL,0)&~O_NONBLOCK);
4488
 
          fcntl(soap->socket, F_SETFL, fcntl(soap->socket, F_GETFL,0)&~O_NONBLOCK);
4489
 
#elif defined(SYMBIAN)
4490
 
          long blocking = 0;
4491
 
          ioctl(soap->master, 0/*FIONBIO*/, &blocking);
4492
 
#else
4493
 
          fcntl(soap->master, F_SETFL, fcntl(soap->master, F_GETFL)&~O_NONBLOCK);
4494
 
          fcntl(soap->socket, F_SETFL, fcntl(soap->socket, F_GETFL)&~O_NONBLOCK);
4495
 
#endif
4496
 
        }
4497
 
        soap->keep_alive = (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) != 0);
4498
 
        return soap->socket;
4499
 
      }
4500
 
      err = soap_socket_errno(soap->socket);
4501
 
      if (err != 0 && err != SOAP_EINTR && err != SOAP_EAGAIN)
4502
 
      { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Accept failed from %s\n", soap->host));
4503
 
        soap->errnum = err;
4504
 
        soap_set_receiver_error(soap, tcp_error(soap), "accept failed in soap_accept()", SOAP_TCP_ERROR);
4505
 
        soap_closesock(soap);
4506
 
        return SOAP_INVALID_SOCKET;
4507
 
      }
4508
 
    }
4509
 
  }
4510
 
  else
4511
 
  { soap->errnum = 0;
4512
 
    soap_set_receiver_error(soap, tcp_error(soap), "no master socket in soap_accept()", SOAP_TCP_ERROR);
4513
 
    return SOAP_INVALID_SOCKET;
4514
 
  }
4515
 
}
4516
 
#endif
4517
 
#endif
4518
 
 
4519
 
/******************************************************************************/
4520
 
#ifndef WITH_NOIO
4521
 
#ifndef PALM_1
4522
 
static int
4523
 
tcp_disconnect(struct soap *soap)
4524
 
{
4525
 
#ifdef WITH_OPENSSL
4526
 
  if (soap->ssl)
4527
 
  { int r, s = 0;
4528
 
    if (soap->session)
4529
 
    { SSL_SESSION_free(soap->session);
4530
 
      soap->session = NULL;
4531
 
    }
4532
 
    if (*soap->host)
4533
 
    { soap->session = SSL_get1_session(soap->ssl);
4534
 
      if (soap->session)
4535
 
      { strcpy(soap->session_host, soap->host);
4536
 
        soap->session_port = soap->port;
4537
 
      }
4538
 
    }
4539
 
    r = SSL_shutdown(soap->ssl);
4540
 
    if (r == 0)
4541
 
    { if (soap_valid_socket(soap->socket))
4542
 
      { struct timeval timeout;
4543
 
        fd_set fd;
4544
 
        if (soap->fshutdownsocket(soap, soap->socket, 1))
4545
 
        { /*
4546
 
          wait up to 10 seconds for close_notify to be sent by peer (if peer not
4547
 
          present, this avoids calling SSL_shutdown() which has a lengthy return
4548
 
          timeout)
4549
 
          */
4550
 
#ifndef WIN32
4551
 
          if ((int)soap->socket < (int)FD_SETSIZE)
4552
 
          {
4553
 
#endif
4554
 
            timeout.tv_sec = 10;
4555
 
            timeout.tv_usec = 0;
4556
 
            FD_ZERO(&fd);
4557
 
            FD_SET(soap->socket, &fd);
4558
 
            r = select((int)soap->socket + 1, &fd, NULL, &fd, &timeout);
4559
 
            if (r <= 0 && soap_socket_errno(soap->socket) != SOAP_EINTR)
4560
 
            { soap->errnum = 0;
4561
 
              DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connection lost...\n"));
4562
 
              soap->fclosesocket(soap, soap->socket);
4563
 
              soap->socket = SOAP_INVALID_SOCKET;
4564
 
              SSL_free(soap->ssl);
4565
 
              soap->ssl = NULL;
4566
 
              ERR_remove_state(0);
4567
 
              return SOAP_OK;
4568
 
            }
4569
 
#ifndef WIN32
4570
 
          }
4571
 
#endif
4572
 
        }
4573
 
      }
4574
 
      r = SSL_shutdown(soap->ssl);
4575
 
    }
4576
 
    if (r != 1)
4577
 
    { s = ERR_get_error();
4578
 
      if (s)
4579
 
      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Shutdown failed: %d\n", SSL_get_error(soap->ssl, r)));
4580
 
        if (soap_valid_socket(soap->socket) && !(soap->omode & SOAP_IO_UDP))
4581
 
        { soap->fclosesocket(soap, soap->socket);
4582
 
          soap->socket = SOAP_INVALID_SOCKET;
4583
 
        }
4584
 
        SSL_free(soap->ssl);
4585
 
        soap->ssl = NULL;
4586
 
        ERR_remove_state(0);
4587
 
        return SOAP_SSL_ERROR;
4588
 
      }
4589
 
    }
4590
 
    SSL_free(soap->ssl);
4591
 
    soap->ssl = NULL;
4592
 
    ERR_remove_state(0);
4593
 
  }
4594
 
#endif
4595
 
  if (soap_valid_socket(soap->socket) && !(soap->omode & SOAP_IO_UDP))
4596
 
  { soap->fshutdownsocket(soap, soap->socket, 2);
4597
 
    soap->fclosesocket(soap, soap->socket);
4598
 
    soap->socket = SOAP_INVALID_SOCKET;
4599
 
  }
4600
 
  return SOAP_OK;
4601
 
}
4602
 
#endif
4603
 
#endif
4604
 
 
4605
 
/******************************************************************************/
4606
 
#ifndef WITH_NOIO
4607
 
#ifndef PALM_1
4608
 
static int
4609
 
tcp_closesocket(struct soap *soap, SOAP_SOCKET fd)
4610
 
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Close socket %d\n", (int)fd));
4611
 
  return soap_closesocket(fd);
4612
 
}
4613
 
#endif
4614
 
#endif
4615
 
 
4616
 
/******************************************************************************/
4617
 
#ifndef WITH_NOIO
4618
 
#ifndef PALM_1
4619
 
static int
4620
 
tcp_shutdownsocket(struct soap *soap, SOAP_SOCKET fd, int how)
4621
 
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Shutdown socket %d how=%d\n", (int)fd, how));
4622
 
  return shutdown(fd, how);
4623
 
}
4624
 
#endif
4625
 
#endif
4626
 
 
4627
 
/******************************************************************************/
4628
 
#ifndef PALM_1
4629
 
SOAP_FMAC1
4630
 
int
4631
 
SOAP_FMAC2
4632
 
soap_closesock(struct soap *soap)
4633
 
{ register int status = soap->error;
4634
 
  if (status == SOAP_EOF || status == SOAP_TCP_ERROR || status == SOAP_SSL_ERROR || !soap->keep_alive)
4635
 
  { if (soap->fclose && (soap->error = soap->fclose(soap)))
4636
 
      return soap->error;
4637
 
    soap->keep_alive = 0;
4638
 
  }
4639
 
#ifdef WITH_ZLIB
4640
 
  if (soap->zlib_state == SOAP_ZLIB_DEFLATE)
4641
 
    deflateEnd(&soap->d_stream);
4642
 
  else if (soap->zlib_state == SOAP_ZLIB_INFLATE)
4643
 
    inflateEnd(&soap->d_stream);
4644
 
  soap->zlib_state = SOAP_ZLIB_NONE;
4645
 
#endif
4646
 
  return soap->error = status;
4647
 
}
4648
 
#endif
4649
 
 
4650
 
/******************************************************************************/
4651
 
#ifndef WITH_NOIDREF
4652
 
#ifndef PALM_2
4653
 
SOAP_FMAC1
4654
 
size_t
4655
 
SOAP_FMAC2
4656
 
soap_hash(register const char *s)
4657
 
{ register size_t h = 0;
4658
 
  while (*s)
4659
 
    h = 65599*h + *s++;
4660
 
  return h % SOAP_IDHASH;
4661
 
}
4662
 
#endif
4663
 
#endif
4664
 
 
4665
 
/******************************************************************************/
4666
 
#ifndef WITH_NOIDREF
4667
 
#ifndef PALM_1
4668
 
static void
4669
 
soap_init_pht(struct soap *soap)
4670
 
{ register int i;
4671
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing pointer hashtable\n"));
4672
 
  soap->pblk = NULL;
4673
 
  soap->pidx = 0;
4674
 
  for (i = 0; i < (int)SOAP_PTRHASH; i++)
4675
 
    soap->pht[i] = NULL;
4676
 
}
4677
 
#endif
4678
 
#endif
4679
 
 
4680
 
/******************************************************************************/
4681
 
#ifndef PALM_1
4682
 
SOAP_FMAC1
4683
 
struct soap*
4684
 
SOAP_FMAC2
4685
 
soap_new1(soap_mode mode)
4686
 
{ return soap_new2(mode, mode);
4687
 
}
4688
 
#endif
4689
 
 
4690
 
/******************************************************************************/
4691
 
#ifndef PALM_1
4692
 
SOAP_FMAC1
4693
 
struct soap*
4694
 
SOAP_FMAC2
4695
 
soap_new()
4696
 
{ return soap_new2(SOAP_IO_DEFAULT, SOAP_IO_DEFAULT);
4697
 
}
4698
 
#endif
4699
 
 
4700
 
/******************************************************************************/
4701
 
#ifndef PALM_1
4702
 
SOAP_FMAC1
4703
 
struct soap*
4704
 
SOAP_FMAC2
4705
 
soap_new2(soap_mode imode, soap_mode omode)
4706
 
{ struct soap *soap = (struct soap*)malloc(sizeof(struct soap));
4707
 
  if (soap)
4708
 
    soap_init2(soap, imode, omode);
4709
 
  return soap;
4710
 
}
4711
 
#endif
4712
 
 
4713
 
/******************************************************************************/
4714
 
#ifndef PALM_1
4715
 
SOAP_FMAC1
4716
 
void
4717
 
SOAP_FMAC2
4718
 
soap_free(struct soap *soap)
4719
 
{ soap_done(soap);
4720
 
  free(soap);
4721
 
}
4722
 
#endif
4723
 
 
4724
 
/******************************************************************************/
4725
 
#ifndef PALM_1
4726
 
SOAP_FMAC1
4727
 
void
4728
 
SOAP_FMAC2
4729
 
soap_del(struct soap *soap)
4730
 
{ free(soap);
4731
 
}
4732
 
#endif
4733
 
 
4734
 
/******************************************************************************/
4735
 
#ifndef WITH_NOIDREF
4736
 
#ifndef PALM_1
4737
 
static void
4738
 
soap_free_pht(struct soap *soap)
4739
 
{ register struct soap_pblk *pb, *next;
4740
 
  register int i;
4741
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free pointer hashtable\n"));
4742
 
  for (pb = soap->pblk; pb; pb = next)
4743
 
  { next = pb->next;
4744
 
    SOAP_FREE(soap, pb);
4745
 
  }
4746
 
  soap->pblk = NULL;
4747
 
  soap->pidx = 0;
4748
 
  for (i = 0; i < (int)SOAP_PTRHASH; i++)
4749
 
    soap->pht[i] = NULL;
4750
 
}
4751
 
#endif
4752
 
#endif
4753
 
 
4754
 
/******************************************************************************/
4755
 
#ifndef WITH_NOIDREF
4756
 
#ifndef PALM_2
4757
 
SOAP_FMAC1
4758
 
int
4759
 
SOAP_FMAC2
4760
 
soap_embed(struct soap *soap, const void *p, const struct soap_array *a, int n, const char *tag, int type)
4761
 
{ register int i;
4762
 
  struct soap_plist *pp;
4763
 
  if (soap->version != 1)
4764
 
    soap->encoding = 1;
4765
 
  if (a)
4766
 
    i = soap_array_pointer_lookup(soap, p, a, n, type, &pp);
4767
 
  else
4768
 
    i = soap_pointer_lookup(soap, p, type, &pp);
4769
 
  if (i)
4770
 
  { if (soap_is_embedded(soap, pp)
4771
 
     || soap_is_single(soap, pp))
4772
 
      return 0;
4773
 
    soap_set_embedded(soap, pp);
4774
 
  }
4775
 
  return i;
4776
 
}
4777
 
#endif
4778
 
#endif
4779
 
 
4780
 
/******************************************************************************/
4781
 
#ifndef WITH_NOIDREF
4782
 
#ifndef PALM_2
4783
 
SOAP_FMAC1
4784
 
int
4785
 
SOAP_FMAC2
4786
 
soap_pointer_lookup(struct soap *soap, const void *p, int type, struct soap_plist **ppp)
4787
 
{ register struct soap_plist *pp;
4788
 
  *ppp = NULL;
4789
 
  if (p)
4790
 
  { for (pp = soap->pht[soap_hash_ptr(p)]; pp; pp = pp->next)
4791
 
    { if (pp->ptr == p && pp->type == type)
4792
 
      { *ppp = pp;
4793
 
        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup location=%p type=%d id=%d\n", p, type, pp->id));
4794
 
        return pp->id;
4795
 
      }
4796
 
    }
4797
 
  }
4798
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup location=%p type=%d: not found\n", p, type));
4799
 
  return 0;
4800
 
}
4801
 
#endif
4802
 
#endif
4803
 
 
4804
 
/******************************************************************************/
4805
 
#ifndef WITH_NOIDREF
4806
 
#ifndef PALM_2
4807
 
SOAP_FMAC1
4808
 
int
4809
 
SOAP_FMAC2
4810
 
soap_pointer_enter(struct soap *soap, const void *p, const struct soap_array *a, int n, int type, struct soap_plist **ppp)
4811
 
{ register size_t h;
4812
 
  register struct soap_plist *pp;
4813
 
  if (!soap->pblk || soap->pidx >= SOAP_PTRBLK)
4814
 
  { register struct soap_pblk *pb = (struct soap_pblk*)SOAP_MALLOC(soap, sizeof(struct soap_pblk));
4815
 
    if (!pb)
4816
 
    { soap->error = SOAP_EOM;
4817
 
      return 0;
4818
 
    }
4819
 
    pb->next = soap->pblk;
4820
 
    soap->pblk = pb;
4821
 
    soap->pidx = 0;
4822
 
  }
4823
 
  *ppp = pp = &soap->pblk->plist[soap->pidx++];
4824
 
  if (a)
4825
 
    h = soap_hash_ptr(a->__ptr);
4826
 
  else
4827
 
    h = soap_hash_ptr(p);
4828
 
  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));
4829
 
  pp->next = soap->pht[h];
4830
 
  pp->type = type;
4831
 
  pp->mark1 = 0;
4832
 
  pp->mark2 = 0;
4833
 
  pp->ptr = p;
4834
 
  pp->array = a;
4835
 
  soap->pht[h] = pp;
4836
 
  pp->id = ++soap->idnum;
4837
 
  return pp->id;
4838
 
}
4839
 
#endif
4840
 
#endif
4841
 
 
4842
 
/******************************************************************************/
4843
 
#ifndef WITH_NOIDREF
4844
 
#ifndef PALM_2
4845
 
SOAP_FMAC1
4846
 
int
4847
 
SOAP_FMAC2
4848
 
soap_array_pointer_lookup(struct soap *soap, const void *p, const struct soap_array *a, int n, int type, struct soap_plist **ppp)
4849
 
{ register struct soap_plist *pp;
4850
 
  *ppp = NULL;
4851
 
  if (!p || !a->__ptr)
4852
 
    return 0;
4853
 
  for (pp = soap->pht[soap_hash_ptr(a->__ptr)]; pp; pp = pp->next)
4854
 
  { if (pp->type == type && pp->array && pp->array->__ptr == a->__ptr)
4855
 
    { register int i;
4856
 
      for (i = 0; i < n; i++)
4857
 
        if (((const int*)&pp->array->__size)[i] != ((const int*)&a->__size)[i])
4858
 
          break;
4859
 
      if (i == n)
4860
 
      { *ppp = pp;
4861
 
        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array lookup location=%p type=%d id=%d\n", a->__ptr, type, pp->id));
4862
 
        return pp->id;
4863
 
      }
4864
 
    }
4865
 
  }
4866
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Array lookup location=%p type=%d: not found\n", a->__ptr, type));
4867
 
  return 0;
4868
 
}
4869
 
#endif
4870
 
#endif
4871
 
 
4872
 
/******************************************************************************/
4873
 
#ifndef PALM_1
4874
 
SOAP_FMAC1
4875
 
int
4876
 
SOAP_FMAC2
4877
 
soap_begin_count(struct soap *soap)
4878
 
{
4879
 
#ifndef WITH_LEANER
4880
 
  if ((soap->mode & SOAP_ENC_DIME) || (soap->omode & SOAP_ENC_DIME))
4881
 
    soap->mode = soap->omode | SOAP_IO_LENGTH | SOAP_ENC_DIME;
4882
 
  else
4883
 
#endif
4884
 
  { soap->mode = soap->omode;
4885
 
    if ((soap->mode & SOAP_IO) == SOAP_IO_STORE
4886
 
     || (((soap->mode & SOAP_IO) == SOAP_IO_CHUNK || (soap->mode & SOAP_ENC_XML))
4887
 
#ifndef WITH_LEANER
4888
 
      && !soap->fpreparesend
4889
 
#endif
4890
 
      ))
4891
 
      soap->mode &= ~SOAP_IO_LENGTH;
4892
 
    else
4893
 
      soap->mode |= SOAP_IO_LENGTH;
4894
 
  }
4895
 
#ifdef WITH_ZLIB
4896
 
  if ((soap->mode & SOAP_ENC_ZLIB) && (soap->mode & SOAP_IO) == SOAP_IO_FLUSH)
4897
 
  { if (!(soap->mode & SOAP_ENC_DIME))
4898
 
      soap->mode &= ~SOAP_IO_LENGTH;
4899
 
    if (soap->mode & SOAP_ENC_XML)
4900
 
      soap->mode |= SOAP_IO_BUFFER;
4901
 
    else
4902
 
      soap->mode |= SOAP_IO_STORE;
4903
 
  }
4904
 
#endif
4905
 
  if (!soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH))
4906
 
    soap->mode |= SOAP_XML_TREE;
4907
 
#ifndef WITH_LEANER
4908
 
  if ((soap->mode & SOAP_ENC_MTOM) && (soap->mode & SOAP_ENC_DIME))
4909
 
    soap->mode |= SOAP_ENC_MIME;
4910
 
  else
4911
 
    soap->mode &= ~SOAP_ENC_MTOM;
4912
 
  if (soap->mode & SOAP_ENC_MIME)
4913
 
    soap_select_mime_boundary(soap);
4914
 
  soap->dime.list = soap->dime.last;    /* keep track of last DIME attachment */
4915
 
#endif
4916
 
  soap->count = 0;
4917
 
  soap->ns = 0;
4918
 
  soap->null = 0;
4919
 
  soap->position = 0;
4920
 
  soap->mustUnderstand = 0;
4921
 
  soap->encoding = 0;
4922
 
  soap->part = SOAP_BEGIN;
4923
 
  soap->idnum = 0;
4924
 
  soap_clr_attr(soap);
4925
 
  soap_set_local_namespaces(soap);
4926
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin count phase (socket=%d mode=0x%x count=%lu)\n", soap->socket, soap->mode, (unsigned long)soap->count));
4927
 
#ifndef WITH_LEANER
4928
 
  soap->dime.count = 0; /* count # of attachments */
4929
 
  soap->dime.size = 0; /* accumulate total size of attachments */
4930
 
  if (soap->fprepareinit && (soap->mode & SOAP_IO) != SOAP_IO_STORE)
4931
 
    return soap->error = soap->fprepareinit(soap);   
4932
 
#endif
4933
 
  return SOAP_OK;
4934
 
}
4935
 
#endif
4936
 
 
4937
 
/******************************************************************************/
4938
 
#ifndef PALM_1
4939
 
SOAP_FMAC1
4940
 
int
4941
 
SOAP_FMAC2
4942
 
soap_end_count(struct soap *soap)
4943
 
4944
 
#ifndef WITH_LEANER
4945
 
  if (soap->fpreparefinal)
4946
 
    return soap->error = soap->fpreparefinal(soap);
4947
 
#endif
4948
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of count phase\n"));
4949
 
  return SOAP_OK;
4950
 
}
4951
 
#endif
4952
 
 
4953
 
/******************************************************************************/
4954
 
#ifndef PALM_1
4955
 
SOAP_FMAC1
4956
 
int
4957
 
SOAP_FMAC2
4958
 
soap_begin_send(struct soap *soap)
4959
 
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing for output\n"));
4960
 
  soap->error = SOAP_OK;
4961
 
  soap->mode = soap->omode | (soap->mode & (SOAP_IO_LENGTH | SOAP_ENC_DIME));
4962
 
#ifdef WITH_ZLIB
4963
 
  if ((soap->mode & SOAP_ENC_ZLIB) && (soap->mode & SOAP_IO) == SOAP_IO_FLUSH)
4964
 
  { if (soap->mode & SOAP_ENC_XML)
4965
 
      soap->mode |= SOAP_IO_BUFFER;
4966
 
    else
4967
 
      soap->mode |= SOAP_IO_STORE;
4968
 
  }
4969
 
#endif
4970
 
#ifdef WITH_UDP
4971
 
  if ((soap->mode & SOAP_IO_UDP))
4972
 
  { soap->mode |= SOAP_ENC_XML;
4973
 
    if (soap->count > SOAP_BUFLEN)
4974
 
      return soap->error = SOAP_UDP_ERROR;
4975
 
  }
4976
 
#endif
4977
 
  if ((soap->mode & SOAP_IO) == SOAP_IO_FLUSH && soap_valid_socket(soap->socket))
4978
 
  { if (soap->count || (soap->mode & SOAP_IO_LENGTH) || (soap->mode & SOAP_ENC_XML))
4979
 
      soap->mode |= SOAP_IO_BUFFER;
4980
 
    else
4981
 
      soap->mode |= SOAP_IO_STORE;
4982
 
  }
4983
 
  soap->mode &= ~SOAP_IO_LENGTH;
4984
 
  if ((soap->mode & SOAP_IO) == SOAP_IO_STORE)
4985
 
    soap_new_block(soap);
4986
 
  if (!(soap->mode & SOAP_IO_KEEPALIVE))
4987
 
    soap->keep_alive = 0;
4988
 
  if (!soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH))
4989
 
    soap->mode |= SOAP_XML_TREE;
4990
 
#ifndef WITH_LEANER
4991
 
  if ((soap->mode & SOAP_ENC_MTOM) && (soap->mode & SOAP_ENC_DIME))
4992
 
  { soap->mode |= SOAP_ENC_MIME;
4993
 
    soap->mode &= ~SOAP_ENC_DIME;
4994
 
  }
4995
 
  else
4996
 
    soap->mode &= ~SOAP_ENC_MTOM;
4997
 
  if (soap->mode & SOAP_ENC_MIME)
4998
 
    soap_select_mime_boundary(soap);
4999
 
#ifdef WIN32
5000
 
#ifndef UNDER_CE
5001
 
#ifndef WITH_FASTCGI
5002
 
  if (!soap_valid_socket(soap->socket)) /* Set win32 stdout or soap->sendfd to BINARY, e.g. to support DIME */
5003
 
#ifdef __BORLANDC__
5004
 
    setmode(soap->sendfd, O_BINARY);
5005
 
#else
5006
 
    _setmode(soap->sendfd, _O_BINARY);
5007
 
#endif
5008
 
#endif
5009
 
#endif
5010
 
#endif
5011
 
#endif
5012
 
  if (soap->mode & SOAP_IO)
5013
 
  { soap->bufidx = 0;
5014
 
    soap->buflen = 0;
5015
 
  }
5016
 
  soap->chunksize = 0;
5017
 
  soap->ns = 0;
5018
 
  soap->null = 0;
5019
 
  soap->position = 0;
5020
 
  soap->mustUnderstand = 0;
5021
 
  soap->encoding = 0;
5022
 
  soap->idnum = 0;
5023
 
  soap->level = 0;
5024
 
  soap_clr_attr(soap);
5025
 
  soap_set_local_namespaces(soap);
5026
 
#ifdef WITH_ZLIB
5027
 
  soap->z_ratio_out = 1.0;
5028
 
  if ((soap->mode & SOAP_ENC_ZLIB) && soap->zlib_state != SOAP_ZLIB_DEFLATE)
5029
 
  { soap->d_stream.next_out = (Byte*)soap->z_buf;
5030
 
    soap->d_stream.avail_out = SOAP_BUFLEN;
5031
 
#ifdef WITH_GZIP
5032
 
    if (soap->zlib_out != SOAP_ZLIB_DEFLATE)
5033
 
    { memcpy(soap->z_buf, "\37\213\10\0\0\0\0\0\0\377", 10);
5034
 
      soap->d_stream.next_out = (Byte*)soap->z_buf + 10;
5035
 
      soap->d_stream.avail_out = SOAP_BUFLEN - 10;
5036
 
      soap->z_crc = crc32(0L, NULL, 0);
5037
 
      soap->zlib_out = SOAP_ZLIB_GZIP;
5038
 
      if (deflateInit2(&soap->d_stream, soap->z_level, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY) != Z_OK)
5039
 
        return soap->error = SOAP_ZLIB_ERROR;
5040
 
    }
5041
 
    else
5042
 
#endif
5043
 
    if (deflateInit(&soap->d_stream, soap->z_level) != Z_OK)
5044
 
      return soap->error = SOAP_ZLIB_ERROR;
5045
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflate initialized\n"));
5046
 
    soap->zlib_state = SOAP_ZLIB_DEFLATE;
5047
 
  }
5048
 
#endif
5049
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin send phase (socket=%d mode=0x%x count=%lu)\n", soap->socket, soap->mode, (unsigned long)soap->count));
5050
 
  soap->part = SOAP_BEGIN;
5051
 
#ifndef WITH_LEANER
5052
 
  if (soap->fprepareinit && (soap->mode & SOAP_IO) == SOAP_IO_STORE)
5053
 
    soap->fprepareinit(soap);   
5054
 
#endif
5055
 
  return SOAP_OK;
5056
 
}
5057
 
#endif
5058
 
 
5059
 
/******************************************************************************/
5060
 
#ifndef WITH_NOIDREF
5061
 
#ifndef PALM_2
5062
 
SOAP_FMAC1
5063
 
void
5064
 
SOAP_FMAC2
5065
 
soap_embedded(struct soap *soap, const void *p, int t)
5066
 
{ struct soap_plist *pp;
5067
 
  if (soap_pointer_lookup(soap, p, t, &pp))
5068
 
  { pp->mark1 = 1;
5069
 
    pp->mark2 = 1;
5070
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded %p type=%d mark set to 1\n", p, t));
5071
 
  }
5072
 
}
5073
 
#endif
5074
 
#endif
5075
 
 
5076
 
/******************************************************************************/
5077
 
#ifndef WITH_NOIDREF
5078
 
#ifndef PALM_2
5079
 
SOAP_FMAC1
5080
 
int
5081
 
SOAP_FMAC2
5082
 
soap_reference(struct soap *soap, const void *p, int t)
5083
 
{ struct soap_plist *pp;
5084
 
  if (!p || (soap->mode & SOAP_XML_TREE))
5085
 
    return 1;
5086
 
  if (soap_pointer_lookup(soap, p, t, &pp))
5087
 
  { if (pp->mark1 == 0)
5088
 
    { pp->mark1 = 2;
5089
 
      pp->mark2 = 2;
5090
 
    }
5091
 
  }
5092
 
  else if (soap_pointer_enter(soap, p, NULL, 0, t, &pp))
5093
 
  { pp->mark1 = 0;
5094
 
    pp->mark2 = 0;
5095
 
  }
5096
 
  else
5097
 
    return 1;
5098
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Reference %p type=%d (%d %d)\n", p, t, (int)pp->mark1, (int)pp->mark2));
5099
 
  return pp->mark1;
5100
 
}
5101
 
#endif
5102
 
#endif
5103
 
 
5104
 
/******************************************************************************/
5105
 
#ifndef WITH_NOIDREF
5106
 
#ifndef PALM_2
5107
 
SOAP_FMAC1
5108
 
int
5109
 
SOAP_FMAC2
5110
 
soap_array_reference(struct soap *soap, const void *p, const struct soap_array *a, int n, int t)
5111
 
{ register int i;
5112
 
  struct soap_plist *pp;
5113
 
  if (!p || !a->__ptr)
5114
 
    return 1;
5115
 
  i = soap_array_pointer_lookup(soap, p, a, n, t, &pp);
5116
 
  if (i)
5117
 
  { if (pp->mark1 == 0)
5118
 
    { pp->mark1 = 2;
5119
 
      pp->mark2 = 2;
5120
 
    }
5121
 
  }
5122
 
  else if (!soap_pointer_enter(soap, p, a, n, t, &pp))
5123
 
    return 1;
5124
 
  else
5125
 
  { pp->mark1 = 0;
5126
 
    pp->mark2 = 0;
5127
 
  }
5128
 
  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));
5129
 
  return pp->mark1;
5130
 
}
5131
 
#endif
5132
 
#endif
5133
 
 
5134
 
/******************************************************************************/
5135
 
#ifndef WITH_NOIDREF
5136
 
#ifndef PALM_2
5137
 
SOAP_FMAC1
5138
 
int
5139
 
SOAP_FMAC2
5140
 
soap_embedded_id(struct soap *soap, int id, const void *p, int t)
5141
 
{ struct soap_plist *pp = NULL;
5142
 
  if (soap->mode & SOAP_XML_TREE)
5143
 
    return id;
5144
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Embedded_id %p type=%d id=%d\n", p, t, id));
5145
 
  if (soap->version == 1 && soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH) && soap->part != SOAP_IN_HEADER)
5146
 
  { if (id < 0)
5147
 
    { id = soap_pointer_lookup(soap, p, t, &pp);
5148
 
      if (id)
5149
 
      { if (soap->mode & SOAP_IO_LENGTH)
5150
 
          pp->mark1 = 2;
5151
 
        else
5152
 
          pp->mark2 = 2;
5153
 
        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));
5154
 
      }
5155
 
      return -1;
5156
 
    }
5157
 
    return id;
5158
 
  }
5159
 
  if (id < 0)
5160
 
    id = soap_pointer_lookup(soap, p, t, &pp);
5161
 
  else if (id && !soap_pointer_lookup(soap, p, t, &pp))
5162
 
    return 0;
5163
 
  if (id && pp)
5164
 
  { if (soap->mode & SOAP_IO_LENGTH)
5165
 
      pp->mark1 = 1;
5166
 
    else
5167
 
      pp->mark2 = 1;
5168
 
    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));
5169
 
  }
5170
 
  return id;
5171
 
}
5172
 
#endif
5173
 
#endif
5174
 
 
5175
 
/******************************************************************************/
5176
 
#ifndef WITH_NOIDREF
5177
 
#ifndef PALM_2
5178
 
SOAP_FMAC1
5179
 
int
5180
 
SOAP_FMAC2
5181
 
soap_is_embedded(struct soap *soap, struct soap_plist *pp)
5182
 
{ if (!pp)
5183
 
    return 0;
5184
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Is embedded? %d %d\n", (int)pp->mark1, (int)pp->mark2));
5185
 
  if (soap->version == 1 && soap->encodingStyle && !(soap->mode & SOAP_XML_GRAPH) && soap->part != SOAP_IN_HEADER)
5186
 
  { if (soap->mode & SOAP_IO_LENGTH)
5187
 
      return pp->mark1 != 0;
5188
 
    return pp->mark2 != 0;
5189
 
  }
5190
 
  if (soap->mode & SOAP_IO_LENGTH)
5191
 
    return pp->mark1 == 1;
5192
 
  return pp->mark2 == 1;
5193
 
}
5194
 
#endif
5195
 
#endif
5196
 
 
5197
 
/******************************************************************************/
5198
 
#ifndef WITH_NOIDREF
5199
 
#ifndef PALM_2
5200
 
SOAP_FMAC1
5201
 
int
5202
 
SOAP_FMAC2
5203
 
soap_is_single(struct soap *soap, struct soap_plist *pp)
5204
 
{ if (soap->part == SOAP_IN_HEADER)
5205
 
    return 1;
5206
 
  if (!pp)
5207
 
    return 0;
5208
 
  if (soap->mode & SOAP_IO_LENGTH)
5209
 
    return pp->mark1 == 0;
5210
 
  return pp->mark2 == 0;
5211
 
}
5212
 
#endif
5213
 
#endif
5214
 
 
5215
 
/******************************************************************************/
5216
 
#ifndef WITH_NOIDREF
5217
 
#ifndef PALM_2
5218
 
SOAP_FMAC1
5219
 
void
5220
 
SOAP_FMAC2
5221
 
soap_set_embedded(struct soap *soap, struct soap_plist *pp)
5222
 
{ if (!pp)
5223
 
    return;
5224
 
  if (soap->mode & SOAP_IO_LENGTH)
5225
 
    pp->mark1 = 1;
5226
 
  else
5227
 
    pp->mark2 = 1;
5228
 
}
5229
 
#endif
5230
 
#endif
5231
 
 
5232
 
/******************************************************************************/
5233
 
#ifndef WITH_LEANER
5234
 
#ifndef PALM_1
5235
 
SOAP_FMAC1
5236
 
int
5237
 
SOAP_FMAC2
5238
 
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) 
5239
 
{
5240
 
#ifndef WITH_NOIDREF
5241
 
  struct soap_plist *pp;
5242
 
  int i;
5243
 
  if (!p || !a->__ptr || (!aid && !atype))
5244
 
    return soap_element_id(soap, tag, id, p, a, n, type, t);
5245
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Attachment tag='%s' id='%s' (%d) type='%s'\n", tag, aid?aid:"", id, atype?atype:""));
5246
 
  i = soap_array_pointer_lookup(soap, p, a, n, t, &pp);
5247
 
  if (!i)
5248
 
  { i = soap_pointer_enter(soap, p, a, n, t, &pp);
5249
 
    if (!i)
5250
 
    { soap->error = SOAP_EOM;
5251
 
      return -1;
5252
 
    }
5253
 
  }
5254
 
  if (id <= 0)
5255
 
    id = i;
5256
 
  if (!aid)
5257
 
  { sprintf(soap->tmpbuf, soap->dime_id_format, id);
5258
 
    aid = soap_strdup(soap, soap->tmpbuf);
5259
 
  }
5260
 
  /* Add MTOM xop:Include element when necessary */
5261
 
  /* TODO: this code to be obsoleted with new import/xop.h conventions */
5262
 
  if ((soap->mode & SOAP_ENC_MTOM) && strcmp(tag, "xop:Include"))
5263
 
  { if (soap_element_begin_out(soap, tag, 0, type)
5264
 
     || soap_element_href(soap, "xop:Include", 0, "href", aid)
5265
 
     || soap_element_end_out(soap, tag))
5266
 
      return soap->error;
5267
 
  }
5268
 
  else if (soap_element_href(soap, tag, 0, "href", aid))
5269
 
    return soap->error;
5270
 
  if (soap->mode & SOAP_IO_LENGTH)
5271
 
  { if (pp->mark1 != 3)
5272
 
    { struct soap_multipart *content;
5273
 
      if (soap->mode & SOAP_ENC_MTOM)
5274
 
        content = soap_new_multipart(soap, &soap->mime.first, &soap->mime.last, (char*)a->__ptr, a->__size);
5275
 
      else
5276
 
        content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, (char*)a->__ptr, a->__size);
5277
 
      if (!content)
5278
 
      { soap->error = SOAP_EOM;
5279
 
        return -1;
5280
 
      }
5281
 
      if (!strncmp(aid, "cid:", 4)) /* RFC 2111 */
5282
 
      { if (soap->mode & SOAP_ENC_MTOM)
5283
 
        { char *s = (char*)soap_malloc(soap, strlen(aid) - 1);
5284
 
          if (s)
5285
 
          { *s = '<';
5286
 
            strcpy(s + 1, aid + 4);
5287
 
            strcat(s, ">");
5288
 
            content->id = s;
5289
 
          }
5290
 
        }
5291
 
        else
5292
 
          content->id = aid + 4;
5293
 
      }
5294
 
      else
5295
 
        content->id = aid;
5296
 
      content->type = atype;
5297
 
      content->options = aoptions;
5298
 
      content->encoding = SOAP_MIME_BINARY;
5299
 
      pp->mark1 = 3;
5300
 
    }
5301
 
  }
5302
 
  else
5303
 
    pp->mark2 = 3;
5304
 
#endif
5305
 
  return -1;
5306
 
}
5307
 
#endif
5308
 
#endif
5309
 
 
5310
 
/******************************************************************************/
5311
 
#ifndef WITH_NOIDREF
5312
 
#ifndef PALM_1
5313
 
static void
5314
 
soap_init_iht(struct soap *soap)
5315
 
{ register int i;
5316
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing ID hashtable\n"));
5317
 
  for (i = 0; i < SOAP_IDHASH; i++)
5318
 
    soap->iht[i] = NULL;
5319
 
}
5320
 
#endif
5321
 
#endif
5322
 
 
5323
 
/******************************************************************************/
5324
 
#ifndef WITH_NOIDREF
5325
 
#ifndef PALM_1
5326
 
static void
5327
 
soap_free_iht(struct soap *soap)
5328
 
{ register int i;
5329
 
  register struct soap_ilist *ip = NULL, *p = NULL;
5330
 
  register struct soap_flist *fp = NULL, *fq = NULL;
5331
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free ID hashtable\n"));
5332
 
  for (i = 0; i < SOAP_IDHASH; i++)
5333
 
  { for (ip = soap->iht[i]; ip; ip = p)
5334
 
    { for (fp = ip->flist; fp; fp = fq)
5335
 
      { fq = fp->next;
5336
 
        SOAP_FREE(soap, fp);
5337
 
      }
5338
 
      p = ip->next;
5339
 
      SOAP_FREE(soap, ip);
5340
 
    }
5341
 
    soap->iht[i] = NULL;
5342
 
  }
5343
 
}
5344
 
#endif
5345
 
#endif
5346
 
 
5347
 
/******************************************************************************/
5348
 
#ifndef WITH_NOIDREF
5349
 
#ifndef PALM_2
5350
 
SOAP_FMAC1
5351
 
struct soap_ilist *
5352
 
SOAP_FMAC2
5353
 
soap_lookup(struct soap *soap, const char *id)
5354
 
{ register struct soap_ilist *ip = NULL;
5355
 
  for (ip = soap->iht[soap_hash(id)]; ip; ip = ip->next)
5356
 
    if (!strcmp(ip->id, id))
5357
 
      return ip;
5358
 
  return NULL;
5359
 
}
5360
 
#endif
5361
 
#endif
5362
 
 
5363
 
/******************************************************************************/
5364
 
#ifndef WITH_NOIDREF
5365
 
#ifndef PALM_2
5366
 
SOAP_FMAC1
5367
 
struct soap_ilist *
5368
 
SOAP_FMAC2
5369
 
soap_enter(struct soap *soap, const char *id)
5370
 
{ register size_t h;
5371
 
  register struct soap_ilist *ip;
5372
 
  ip = (struct soap_ilist*)SOAP_MALLOC(soap, sizeof(struct soap_ilist) + strlen(id));
5373
 
  if (ip)
5374
 
  { h = soap_hash(id);
5375
 
    strcpy(ip->id, id);
5376
 
    ip->next = soap->iht[h];
5377
 
    soap->iht[h] = ip;
5378
 
    return ip;
5379
 
  }
5380
 
  return NULL;
5381
 
}
5382
 
#endif
5383
 
#endif
5384
 
 
5385
 
/******************************************************************************/
5386
 
#ifndef PALM_2
5387
 
SOAP_FMAC1
5388
 
void*
5389
 
SOAP_FMAC2
5390
 
soap_malloc(struct soap *soap, size_t n)
5391
 
{ register char *p;
5392
 
  if (!n)
5393
 
    return (void*)SOAP_NON_NULL;
5394
 
  if (!soap)
5395
 
    return SOAP_MALLOC(soap, n);
5396
 
  if (soap->fmalloc)
5397
 
    p = (char*)soap->fmalloc(soap, n);
5398
 
  else
5399
 
  { n += sizeof(short);
5400
 
    n += (-(long)n) & (sizeof(void*)-1); /* align at 4-, 8- or 16-byte boundary */
5401
 
    if (!(p = (char*)SOAP_MALLOC(soap, n + sizeof(void*) + sizeof(size_t))))
5402
 
    { soap->error = SOAP_EOM;
5403
 
      return NULL;
5404
 
    }
5405
 
    /* set the canary to detect corruption */
5406
 
    *(short*)(p + n - sizeof(short)) = (short)SOAP_CANARY;
5407
 
    /* keep chain of alloced cells for destruction */
5408
 
    *(void**)(p + n) = soap->alist;
5409
 
    *(size_t*)(p + n + sizeof(void*)) = n;
5410
 
    soap->alist = p + n;
5411
 
  }
5412
 
  soap->alloced = 1;
5413
 
  return p;
5414
 
}
5415
 
#endif
5416
 
 
5417
 
/******************************************************************************/
5418
 
#ifdef SOAP_MEM_DEBUG
5419
 
static void
5420
 
soap_init_mht(struct soap *soap)
5421
 
{ register int i;
5422
 
  for (i = 0; i < (int)SOAP_PTRHASH; i++)
5423
 
    soap->mht[i] = NULL;
5424
 
}
5425
 
#endif
5426
 
 
5427
 
/******************************************************************************/
5428
 
#ifdef SOAP_MEM_DEBUG
5429
 
static void
5430
 
soap_free_mht(struct soap *soap)
5431
 
{ register int i;
5432
 
  register struct soap_mlist *mp, *mq;
5433
 
  for (i = 0; i < (int)SOAP_PTRHASH; i++)
5434
 
  { for (mp = soap->mht[i]; mp; mp = mq)
5435
 
    { mq = mp->next;
5436
 
      if (mp->live)
5437
 
        fprintf(stderr, "%s(%d): malloc() = %p not freed (memory leak or forgot to call soap_end()?)\n", mp->file, mp->line, mp->ptr);
5438
 
      free(mp);
5439
 
    }
5440
 
    soap->mht[i] = NULL;
5441
 
  }
5442
 
}
5443
 
#endif
5444
 
 
5445
 
/******************************************************************************/
5446
 
#ifdef SOAP_MEM_DEBUG
5447
 
SOAP_FMAC1
5448
 
void*
5449
 
SOAP_FMAC2
5450
 
soap_track_malloc(struct soap *soap, const char *file, int line, size_t size)
5451
 
{ register void *p = malloc(size);
5452
 
  if (soap)
5453
 
  { register size_t h = soap_hash_ptr(p);
5454
 
    register struct soap_mlist *mp = (struct soap_mlist*)malloc(sizeof(struct soap_mlist));
5455
 
    if (soap->fdebug[SOAP_INDEX_TEST])
5456
 
    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): malloc(%lu) = %p\n", file, line, (unsigned long)size, p));
5457
 
    }
5458
 
    mp->next = soap->mht[h];
5459
 
    mp->ptr = p;
5460
 
    mp->file = file;
5461
 
    mp->line = line;
5462
 
    mp->live = 1;
5463
 
    soap->mht[h] = mp;
5464
 
  }
5465
 
  return p;
5466
 
}
5467
 
#endif
5468
 
 
5469
 
/******************************************************************************/
5470
 
#ifdef SOAP_MEM_DEBUG
5471
 
SOAP_FMAC1
5472
 
void
5473
 
SOAP_FMAC2
5474
 
soap_track_free(struct soap *soap, const char *file, int line, void *p)
5475
 
{ register size_t h = soap_hash_ptr(p);
5476
 
  register struct soap_mlist *mp;
5477
 
  for (mp = soap->mht[h]; mp; mp = mp->next)
5478
 
    if (mp->ptr == p)
5479
 
      break;
5480
 
  if (mp)
5481
 
  { if (mp->live)
5482
 
    { free(p);
5483
 
      if (soap->fdebug[SOAP_INDEX_TEST])
5484
 
      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "%s(%d): free(%p)\n", file, line, p));
5485
 
      }
5486
 
      mp->live = 0;
5487
 
    }
5488
 
    else
5489
 
      fprintf(stderr, "%s(%d): free(%p) double free of pointer malloced at %s(%d)\n", file, line, p, mp->file, mp->line);
5490
 
  }
5491
 
  else
5492
 
    fprintf(stderr, "%s(%d): free(%p) pointer not malloced\n", file, line, p);
5493
 
}
5494
 
#endif
5495
 
 
5496
 
/******************************************************************************/
5497
 
#ifdef SOAP_MEM_DEBUG
5498
 
static void
5499
 
soap_track_unlink(struct soap *soap, const void *p)
5500
 
{ register size_t h = soap_hash_ptr(p);
5501
 
  register struct soap_mlist *mp;
5502
 
  for (mp = soap->mht[h]; mp; mp = mp->next)
5503
 
    if (mp->ptr == p)
5504
 
      break;
5505
 
  if (mp)
5506
 
    mp->live = 0;
5507
 
}
5508
 
#endif
5509
 
 
5510
 
/******************************************************************************/
5511
 
#ifndef PALM_2
5512
 
SOAP_FMAC1
5513
 
void
5514
 
SOAP_FMAC2
5515
 
soap_dealloc(struct soap *soap, void *p)
5516
 
{ if (soap_check_state(soap))
5517
 
    return;
5518
 
  if (p)
5519
 
  { register char **q;
5520
 
    for (q = (char**)&soap->alist; *q; q = *(char***)q)
5521
 
    { 
5522
 
      if (*(short*)(char*)(*q - sizeof(short)) != (short)SOAP_CANARY)
5523
 
      {
5524
 
#ifdef SOAP_MEM_DEBUG
5525
 
        fprintf(stderr, "Data corruption in dynamic allocation (see logs)\n");
5526
 
#endif
5527
 
        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Data corruption:\n"));
5528
 
        DBGHEX(TEST, *q - 200, 200);
5529
 
        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n"));
5530
 
        soap->error = SOAP_MOE;
5531
 
        return;
5532
 
      }
5533
 
      if (p == (void*)(*q - *(size_t*)(*q + sizeof(void*))))
5534
 
      { *q = **(char***)q;
5535
 
        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Freed data at %p\n", p));
5536
 
        SOAP_FREE(soap, p);
5537
 
        return;
5538
 
      }
5539
 
    }
5540
 
    soap_delete(soap, p);
5541
 
  }
5542
 
  else
5543
 
  { register char *q;
5544
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free all soap_malloc() data\n"));
5545
 
    while (soap->alist)
5546
 
    { q = (char*)soap->alist;
5547
 
      if (*(short*)(char*)(q - sizeof(short)) != (short)SOAP_CANARY)
5548
 
      {
5549
 
#ifdef SOAP_MEM_DEBUG
5550
 
        fprintf(stderr, "Data corruption in dynamic allocation (see logs)\n");
5551
 
#endif
5552
 
        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Data corruption:\n"));
5553
 
        DBGHEX(TEST, q - 200, 200);
5554
 
        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "\n"));
5555
 
        soap->error = SOAP_MOE;
5556
 
        return;
5557
 
      }
5558
 
      soap->alist = *(void**)q;
5559
 
      q -= *(size_t*)(q + sizeof(void*));
5560
 
      SOAP_FREE(soap, q);
5561
 
    }
5562
 
    /* we must assume these were deallocated: */
5563
 
    soap->action = NULL;
5564
 
    soap->fault = NULL;
5565
 
    soap->header = NULL;
5566
 
    soap->userid = NULL;
5567
 
    soap->passwd = NULL;
5568
 
    soap->authrealm = NULL;
5569
 
    soap->http_content = NULL;
5570
 
#ifndef WITH_LEANER
5571
 
    soap_clr_mime(soap);
5572
 
#endif
5573
 
  }
5574
 
}
5575
 
#endif
5576
 
 
5577
 
/******************************************************************************/
5578
 
#ifndef PALM_2
5579
 
SOAP_FMAC1
5580
 
void
5581
 
SOAP_FMAC2
5582
 
soap_delete(struct soap *soap, void *p)
5583
 
{ register struct soap_clist **cp;
5584
 
  if (soap_check_state(soap))
5585
 
    return;
5586
 
  cp = &soap->clist;
5587
 
  if (p)
5588
 
  { while (*cp)
5589
 
    { if (p == (*cp)->ptr)
5590
 
      { register struct soap_clist *q = *cp;
5591
 
        *cp = q->next;
5592
 
        if (q->fdelete(q))
5593
 
        { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not dealloc data %p: deletion callback failed for object type %d\n", q->ptr, q->type));
5594
 
#ifdef SOAP_MEM_DEBUG
5595
 
          fprintf(stderr, "new(object type = %d) = %p not freed: deletion callback failed\n", q->type, q->ptr);
5596
 
#endif
5597
 
        }
5598
 
        SOAP_FREE(soap, q);
5599
 
        return;
5600
 
      }
5601
 
      cp = &(*cp)->next;
5602
 
    }
5603
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not dealloc data %p: address not in list\n", p));
5604
 
  }
5605
 
  else
5606
 
  { while (*cp)
5607
 
    { register struct soap_clist *q = *cp;
5608
 
      *cp = q->next;
5609
 
      if (q->fdelete(q))
5610
 
      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not dealloc data %p: deletion callback failed for object type %d\n", q->ptr, q->type));
5611
 
#ifdef SOAP_MEM_DEBUG
5612
 
        fprintf(stderr, "new(object type = %d) = %p not freed: deletion callback failed\n", q->type, q->ptr);
5613
 
#endif
5614
 
      }
5615
 
      SOAP_FREE(soap, q);
5616
 
    }
5617
 
  }
5618
 
  soap->fault = NULL; /* this was possibly deallocated */
5619
 
  soap->header = NULL; /* this was possibly deallocated */
5620
 
}
5621
 
#endif
5622
 
 
5623
 
/******************************************************************************/
5624
 
#ifndef PALM_2
5625
 
SOAP_FMAC1
5626
 
struct soap_clist *
5627
 
SOAP_FMAC2
5628
 
soap_link(struct soap *soap, void *p, int t, int n, int (*fdelete)(struct soap_clist*))
5629
 
{ register struct soap_clist *cp;
5630
 
  if ((cp = (struct soap_clist*)SOAP_MALLOC(soap, sizeof(struct soap_clist))))
5631
 
  { cp->next = soap->clist;
5632
 
    cp->type = t;
5633
 
    cp->size = n; 
5634
 
    cp->ptr = p;
5635
 
    cp->fdelete = fdelete;
5636
 
    soap->clist = cp;
5637
 
  }
5638
 
  return cp;
5639
 
}
5640
 
#endif
5641
 
 
5642
 
/******************************************************************************/
5643
 
#ifndef PALM_2
5644
 
SOAP_FMAC1
5645
 
void
5646
 
SOAP_FMAC2
5647
 
soap_unlink(struct soap *soap, const void *p)
5648
 
{ register char **q;
5649
 
  register struct soap_clist **cp;
5650
 
  if (!soap || !p)
5651
 
    return;
5652
 
  for (q = (char**)&soap->alist; *q; q = *(char***)q)
5653
 
  { if (p == (void*)(*q - *(size_t*)(*q + sizeof(void*))))
5654
 
    { *q = **(char***)q;
5655
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unlinked data %p\n", p));
5656
 
#ifdef SOAP_MEM_DEBUG
5657
 
      soap_track_unlink(soap, p);
5658
 
#endif
5659
 
      return;
5660
 
    }
5661
 
  }
5662
 
  for (cp = &soap->clist; *cp; cp = &(*cp)->next)
5663
 
  { if (p == (*cp)->ptr)
5664
 
    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unlinked class instance %p\n", p));
5665
 
      q = (char**)*cp;
5666
 
      *cp = (*cp)->next;
5667
 
      SOAP_FREE(soap, q);
5668
 
      return;
5669
 
    }
5670
 
  }
5671
 
}
5672
 
#endif
5673
 
 
5674
 
/******************************************************************************/
5675
 
#ifndef WITH_NOIDREF
5676
 
#ifndef PALM_2
5677
 
SOAP_FMAC1
5678
 
int
5679
 
SOAP_FMAC2
5680
 
soap_lookup_type(struct soap *soap, const char *id)
5681
 
{ register struct soap_ilist *ip;
5682
 
  if (id && *id)
5683
 
  { ip = soap_lookup(soap, id);
5684
 
    if (ip)
5685
 
    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Lookup id='%s' type=%d\n", id, ip->type));
5686
 
      return ip->type;
5687
 
    }
5688
 
  }
5689
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "lookup type id='%s' NOT FOUND! Need to get it from xsi:type\n", id));
5690
 
  return 0;
5691
 
}
5692
 
#endif
5693
 
#endif
5694
 
 
5695
 
/******************************************************************************/
5696
 
#ifndef WITH_NOIDREF
5697
 
#ifndef PALM_2
5698
 
SOAP_FMAC1
5699
 
void*
5700
 
SOAP_FMAC2
5701
 
soap_id_lookup(struct soap *soap, const char *id, void **p, int t, size_t n, unsigned int k)
5702
 
{ struct soap_ilist *ip;
5703
 
  void **q;
5704
 
  if (!p || !id || !*id)
5705
 
    return p;
5706
 
  ip = soap_lookup(soap, id); /* lookup pointer to hash table entry for string id */
5707
 
  if (!ip)
5708
 
  { ip = soap_enter(soap, id); /* new hash table entry for string id */
5709
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding first href='%s' type=%d %p (%u bytes)\n", id, t, p, (unsigned int)n));
5710
 
    ip->type = t;
5711
 
    ip->size = n; 
5712
 
    ip->link = p;
5713
 
    ip->copy = NULL;
5714
 
    ip->flist = NULL;
5715
 
    ip->ptr = NULL;
5716
 
    ip->level = k;
5717
 
    *p = NULL;
5718
 
  }
5719
 
  else if (ip->ptr)
5720
 
  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolved href='%s' type=%d location=%p (%u bytes)\n", id, t, ip->ptr, (unsigned int)n));
5721
 
    if (ip->type != t)
5722
 
    { strcpy(soap->id, id);
5723
 
      soap->error = SOAP_HREF;
5724
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Type incompatibility: href='%s' id-type=%d href-type=%d\n", id, ip->type, t));
5725
 
      return NULL;
5726
 
    }
5727
 
    while (ip->level < k)
5728
 
    { q = (void**)soap_malloc(soap, sizeof(void*));  
5729
 
      if (!q)
5730
 
        return NULL;
5731
 
      *p = (void*)q;
5732
 
      p = q;
5733
 
      k--;
5734
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n"));
5735
 
    }
5736
 
    *p = ip->ptr;
5737
 
  }
5738
 
  else if (ip->level > k)
5739
 
  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving level %u pointers to href='%s'\n", ip->level, id));
5740
 
    while (ip->level > k)
5741
 
    { void *s, **r = &ip->link;
5742
 
      q = (void**)ip->link;
5743
 
      while (q)
5744
 
      { *r = (void*)soap_malloc(soap, sizeof(void*));
5745
 
        s = *q;
5746
 
        *q = *r;
5747
 
        r = (void**)*r;
5748
 
        q = (void**)s;
5749
 
      }
5750
 
      *r = NULL;
5751
 
      ip->size = n; 
5752
 
      ip->copy = NULL;
5753
 
      ip->level = ip->level - 1;
5754
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n"));
5755
 
    }
5756
 
    q = (void**)ip->link;
5757
 
    ip->link = p;
5758
 
    *p = (void*)q;
5759
 
  }
5760
 
  else
5761
 
  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarded href='%s' type=%d location=%p (%u bytes)\n", id, t, p, (unsigned int)n));
5762
 
    while (ip->level < k)
5763
 
    { q = (void**)soap_malloc(soap, sizeof(void*));  
5764
 
      *p = q;
5765
 
      p = q;
5766
 
      k--;
5767
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Descending one level...\n"));
5768
 
    }
5769
 
    q = (void**)ip->link;
5770
 
    ip->link = p;
5771
 
    *p = (void*)q;
5772
 
  }
5773
 
  return p;
5774
 
}
5775
 
#endif
5776
 
#endif
5777
 
 
5778
 
/******************************************************************************/
5779
 
#ifndef WITH_NOIDREF
5780
 
#ifndef PALM_2
5781
 
SOAP_FMAC1
5782
 
void*
5783
 
SOAP_FMAC2
5784
 
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))
5785
 
{ struct soap_ilist *ip;
5786
 
  if (!p || !href || !*href)
5787
 
    return p;
5788
 
  ip = soap_lookup(soap, href); /* lookup pointer to hash table entry for string id */
5789
 
  if (!ip)
5790
 
  { ip = soap_enter(soap, href); /* new hash table entry for string id */
5791
 
    ip->type = st;
5792
 
    ip->size = n;
5793
 
    ip->link = NULL;
5794
 
    ip->copy = NULL;
5795
 
    ip->ptr = NULL;
5796
 
    ip->level = 0;
5797
 
    ip->flist = NULL;
5798
 
    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));
5799
 
  }
5800
 
  else if (ip->type != st || (ip->level == k && ip->size != n))
5801
 
  { 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));
5802
 
    strcpy(soap->id, href);
5803
 
    soap->error = SOAP_HREF;
5804
 
    return NULL;
5805
 
  }
5806
 
  if (fcopy || n < sizeof(void*) || *href != '#')
5807
 
  { register struct soap_flist *fp = (struct soap_flist*)SOAP_MALLOC(soap, sizeof(struct soap_flist));
5808
 
    if (!fp)
5809
 
    { soap->error = SOAP_EOM;
5810
 
      return NULL;
5811
 
    }
5812
 
    fp->next = ip->flist;
5813
 
    fp->type = tt;
5814
 
    fp->ptr = p;
5815
 
    fp->level = k;
5816
 
    fp->len = len;
5817
 
    if (fcopy)
5818
 
      fp->fcopy = fcopy;
5819
 
    else
5820
 
      fp->fcopy = soap_fcopy;
5821
 
    ip->flist = fp;
5822
 
    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));
5823
 
  }
5824
 
  else
5825
 
  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Forwarding copying address %p for type=%d href='%s'\n", p, st, href));
5826
 
    *(void**)p = ip->copy;
5827
 
    ip->copy = p;
5828
 
  }
5829
 
  return p;
5830
 
}
5831
 
#endif
5832
 
#endif
5833
 
 
5834
 
/******************************************************************************/
5835
 
#ifndef PALM_2
5836
 
SOAP_FMAC1
5837
 
void*
5838
 
SOAP_FMAC2
5839
 
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*))
5840
 
{
5841
 
#ifndef WITH_NOIDREF
5842
 
  struct soap_ilist *ip;
5843
 
#endif
5844
 
  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Enter id='%s' type=%d loc=%p size=%lu level=%u\n", id, t, p, (unsigned long)n, k));
5845
 
  soap->alloced = 0;
5846
 
  if (!p)
5847
 
  { if (finstantiate)
5848
 
      p = finstantiate(soap, t, type, arrayType, &n);
5849
 
    else
5850
 
      p = soap_malloc(soap, n);
5851
 
    if (p)
5852
 
      soap->alloced = 1;
5853
 
  }
5854
 
#ifndef WITH_NOIDREF
5855
 
  if (!id || !*id)
5856
 
#endif
5857
 
    return p;
5858
 
#ifndef WITH_NOIDREF
5859
 
  ip = soap_lookup(soap, id); /* lookup pointer to hash table entry for string id */
5860
 
  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Lookup entry id='%s for location=%p'\n", id, p));
5861
 
  if (!ip)
5862
 
  { ip = soap_enter(soap, id); /* new hash table entry for string id */
5863
 
    ip->type = t;
5864
 
    ip->link = NULL;
5865
 
    ip->copy = NULL;
5866
 
    ip->flist = NULL;
5867
 
    ip->size = n;
5868
 
    ip->ptr = p;
5869
 
    ip->level = k;
5870
 
    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));
5871
 
  }
5872
 
  else if ((ip->type != t || (ip->level == k && ip->size != n)) && (ip->copy || ip->flist))
5873
 
  { 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));
5874
 
    strcpy(soap->id, id);
5875
 
    soap->error = SOAP_HREF;
5876
 
    return NULL;
5877
 
  }
5878
 
  else if (ip->ptr)
5879
 
  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Multiply defined id='%s'\n", id));
5880
 
    strcpy(soap->id, id);
5881
 
    soap->error = SOAP_DUPLICATE_ID;
5882
 
    return NULL;
5883
 
  }
5884
 
  else 
5885
 
  { ip->size = n;
5886
 
    ip->ptr = p;
5887
 
    ip->level = k;
5888
 
    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));
5889
 
  }
5890
 
  return ip->ptr;
5891
 
#endif
5892
 
}
5893
 
#endif
5894
 
 
5895
 
/******************************************************************************/
5896
 
#ifndef PALM_2
5897
 
SOAP_FMAC1
5898
 
void
5899
 
SOAP_FMAC2
5900
 
soap_fcopy(struct soap *soap, int st, int tt, void *p, size_t len, const void *q, size_t n)
5901
 
{ DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Copying data type=%d (target type=%d) %p -> %p (%lu bytes)\n", st, tt, q, p, (unsigned long)n));
5902
 
  memcpy(p, q, n);
5903
 
}
5904
 
#endif
5905
 
 
5906
 
/******************************************************************************/
5907
 
#ifndef PALM_1
5908
 
SOAP_FMAC1
5909
 
int
5910
 
SOAP_FMAC2
5911
 
soap_end_send(struct soap *soap)
5912
 
5913
 
#ifndef WITH_LEANER
5914
 
  if (soap->dime.list)
5915
 
  { /* SOAP body referenced attachments must appear first */
5916
 
    soap->dime.last->next = soap->dime.first;
5917
 
    soap->dime.first = soap->dime.list->next;
5918
 
    soap->dime.list->next = NULL;
5919
 
    soap->dime.last = soap->dime.list;
5920
 
  }
5921
 
  if (soap_putdime(soap) || soap_putmime(soap))
5922
 
    return soap->error;
5923
 
  soap->mime.list = NULL;
5924
 
  soap->mime.first = NULL;
5925
 
  soap->mime.last = NULL;
5926
 
  soap->dime.list = NULL;
5927
 
  soap->dime.first = NULL;
5928
 
  soap->dime.last = NULL;
5929
 
#endif
5930
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End send\n"));
5931
 
  if (soap->mode & SOAP_IO) /* need to flush the remaining data in buffer */
5932
 
  { if (soap_flush(soap))
5933
 
#ifdef WITH_ZLIB
5934
 
    { if (soap->mode & SOAP_ENC_ZLIB && soap->zlib_state == SOAP_ZLIB_DEFLATE)
5935
 
      { soap->zlib_state = SOAP_ZLIB_NONE;
5936
 
        deflateEnd(&soap->d_stream);
5937
 
      }
5938
 
      return soap->error;
5939
 
    }
5940
 
#else
5941
 
      return soap->error;
5942
 
#endif
5943
 
#ifdef WITH_ZLIB
5944
 
    if (soap->mode & SOAP_ENC_ZLIB)
5945
 
    { int r;
5946
 
      soap->d_stream.avail_in = 0;
5947
 
      do
5948
 
      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflating remainder\n"));
5949
 
        r = deflate(&soap->d_stream, Z_FINISH);
5950
 
        if (soap->d_stream.avail_out != SOAP_BUFLEN)
5951
 
        { if (soap_flush_raw(soap, soap->z_buf, SOAP_BUFLEN - soap->d_stream.avail_out))
5952
 
          { soap->zlib_state = SOAP_ZLIB_NONE;
5953
 
            deflateEnd(&soap->d_stream);
5954
 
            return soap->error;
5955
 
          }
5956
 
          soap->d_stream.next_out = (Byte*)soap->z_buf;
5957
 
          soap->d_stream.avail_out = SOAP_BUFLEN;
5958
 
        }
5959
 
      } while (r == Z_OK);
5960
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Deflated %lu->%lu bytes\n", soap->d_stream.total_in, soap->d_stream.total_out));
5961
 
      soap->z_ratio_out = (float)soap->d_stream.total_out / (float)soap->d_stream.total_in;
5962
 
      soap->mode &= ~SOAP_ENC_ZLIB;
5963
 
      soap->zlib_state = SOAP_ZLIB_NONE;
5964
 
      if (deflateEnd(&soap->d_stream) != Z_OK || r != Z_STREAM_END)
5965
 
      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Unable to end deflate: %s\n", soap->d_stream.msg?soap->d_stream.msg:""));
5966
 
        return soap->error = SOAP_ZLIB_ERROR;
5967
 
      }
5968
 
#ifdef WITH_GZIP
5969
 
      if (soap->zlib_out != SOAP_ZLIB_DEFLATE)
5970
 
      { soap->z_buf[0] = soap->z_crc & 0xFF;
5971
 
        soap->z_buf[1] = (soap->z_crc >> 8) & 0xFF;
5972
 
        soap->z_buf[2] = (soap->z_crc >> 16) & 0xFF;
5973
 
        soap->z_buf[3] = (soap->z_crc >> 24) & 0xFF;
5974
 
        soap->z_buf[4] = soap->d_stream.total_in & 0xFF;
5975
 
        soap->z_buf[5] = (soap->d_stream.total_in >> 8) & 0xFF;
5976
 
        soap->z_buf[6] = (soap->d_stream.total_in >> 16) & 0xFF;
5977
 
        soap->z_buf[7] = (soap->d_stream.total_in >> 24) & 0xFF;
5978
 
        if (soap_flush_raw(soap, soap->z_buf, 8))
5979
 
          return soap->error;
5980
 
        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip crc32=%lu\n", (unsigned long)soap->z_crc));
5981
 
      }
5982
 
#endif
5983
 
    }
5984
 
#endif
5985
 
    if ((soap->mode & SOAP_IO) == SOAP_IO_STORE)
5986
 
    { char *p;
5987
 
#ifndef WITH_NOHTTP
5988
 
      if (!(soap->mode & SOAP_ENC_XML))
5989
 
      { soap->mode--;
5990
 
        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Sending buffered message of length %u\n", (unsigned int)soap->blist->size));
5991
 
        if (soap->status >= SOAP_POST)
5992
 
          soap->error = soap->fpost(soap, soap->endpoint, soap->host, soap->port, soap->path, soap->action, soap->blist->size);
5993
 
        else if (soap->status != SOAP_STOP)
5994
 
          soap->error = soap->fresponse(soap, soap->status, soap->blist->size);
5995
 
        if (soap->error || soap_flush(soap))
5996
 
          return soap->error;
5997
 
        soap->mode++;
5998
 
      }
5999
 
#endif
6000
 
      for (p = soap_first_block(soap); p; p = soap_next_block(soap))
6001
 
      { DBGMSG(SENT, p, soap_block_size(soap));
6002
 
        if ((soap->error = soap->fsend(soap, p, soap_block_size(soap))))
6003
 
        { soap_end_block(soap);
6004
 
          return soap->error;
6005
 
        }
6006
 
      }
6007
 
      soap_end_block(soap);
6008
 
    }
6009
 
#ifndef WITH_LEANER
6010
 
    else if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK)
6011
 
    { DBGMSG(SENT, "\r\n0\r\n\r\n", 7);
6012
 
      if ((soap->error = soap->fsend(soap, "\r\n0\r\n\r\n", 7)))
6013
 
        return soap->error;
6014
 
    }
6015
 
#endif
6016
 
  }
6017
 
#ifdef WITH_TCPFIN
6018
 
#ifdef WITH_OPENSSL
6019
 
  if (!soap->ssl && soap_valid_socket(soap->socket) && !soap->keep_alive && !(soap->omode & SOAP_IO_UDP))
6020
 
    soap->fshutdownsocket(soap, soap->socket, 1); /* Send TCP FIN */
6021
 
#else
6022
 
  if (soap_valid_socket(soap->socket) && !soap->keep_alive && !(soap->omode & SOAP_IO_UDP))
6023
 
    soap->fshutdownsocket(soap, soap->socket, 1); /* Send TCP FIN */
6024
 
#endif
6025
 
#endif
6026
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of send phase\n"));
6027
 
  soap->omode &= ~SOAP_XML_SEC;
6028
 
  soap->count = 0;
6029
 
  soap->part = SOAP_END;
6030
 
  return SOAP_OK;
6031
 
}
6032
 
#endif
6033
 
 
6034
 
/******************************************************************************/
6035
 
#ifndef PALM_1
6036
 
SOAP_FMAC1
6037
 
int
6038
 
SOAP_FMAC2
6039
 
soap_end_recv(struct soap *soap)
6040
 
{ soap->part = SOAP_END;
6041
 
#ifndef WITH_LEANER
6042
 
  if ((soap->mode & SOAP_ENC_DIME) && soap_getdime(soap))
6043
 
  { soap->dime.first = NULL;
6044
 
    soap->dime.last = NULL;
6045
 
    return soap->error;
6046
 
  }
6047
 
  soap->dime.list = soap->dime.first;
6048
 
  soap->dime.first = NULL;
6049
 
  soap->dime.last = NULL;
6050
 
  /* Check if MIME attachments and mime-post-check flag is set, if set call soap_resolve() and return */
6051
 
  if (soap->mode & SOAP_ENC_MIME)
6052
 
  { 
6053
 
#ifndef WITH_NOIDREF
6054
 
    if (soap->mode & SOAP_MIME_POSTCHECK)
6055
 
    { soap_resolve(soap);
6056
 
      return SOAP_OK;
6057
 
    }
6058
 
#endif
6059
 
    if (soap_getmime(soap))
6060
 
      return soap->error;
6061
 
  }
6062
 
  soap->mime.list = soap->mime.first;
6063
 
  soap->mime.first = NULL;
6064
 
  soap->mime.last = NULL;
6065
 
  soap->mime.boundary = NULL;
6066
 
  if (soap->xlist)
6067
 
  { struct soap_multipart *content;
6068
 
    for (content = soap->mime.list; content; content = content->next)
6069
 
      soap_resolve_attachment(soap, content);
6070
 
  }
6071
 
#endif
6072
 
  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "End of receive message ok\n"));
6073
 
#ifdef WITH_ZLIB
6074
 
  if (soap->mode & SOAP_ENC_ZLIB)
6075
 
  { /* Make sure end of compressed content is reached */
6076
 
    while (soap->d_stream.next_out != Z_NULL)
6077
 
      if ((int)soap_get1(soap) == EOF)
6078
 
        break;
6079
 
    soap->mode &= ~SOAP_ENC_ZLIB;
6080
 
    memcpy(soap->buf, soap->z_buf, SOAP_BUFLEN);
6081
 
    soap->bufidx = (char*)soap->d_stream.next_in - soap->z_buf;
6082
 
    soap->buflen = soap->z_buflen;
6083
 
    soap->zlib_state = SOAP_ZLIB_NONE;
6084
 
    if (inflateEnd(&soap->d_stream) != Z_OK)
6085
 
      return soap->error = SOAP_ZLIB_ERROR;
6086
 
    DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Inflate end ok\n"));
6087
 
#ifdef WITH_GZIP
6088
 
    if (soap->zlib_in == SOAP_ZLIB_GZIP)
6089
 
    { soap_wchar c;
6090
 
      short i;
6091
 
      DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Inflate gzip crc check\n"));
6092
 
      for (i = 0; i < 8; i++)
6093
 
      { if ((int)(c = soap_get1(soap)) == EOF)
6094
 
          return soap->error = SOAP_EOF;
6095
 
        soap->z_buf[i] = (char)c;
6096
 
      }
6097
 
      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)))
6098
 
      { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Gzip error: crc check failed, message corrupted? (crc32=%lu)\n", (unsigned long)soap->z_crc));
6099
 
        return soap->error = SOAP_ZLIB_ERROR;
6100
 
      }
6101
 
      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)))
6102
 
      { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Gzip error: incorrect message length\n"));
6103
 
        return soap->error = SOAP_ZLIB_ERROR;
6104
 
      }
6105
 
    }
6106
 
    soap->zlib_in = SOAP_ZLIB_NONE;
6107
 
#endif
6108
 
  }
6109
 
#endif
6110
 
  if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK)
6111
 
    while ((int)soap_getchar(soap) != EOF) /* advance to last chunk */
6112
 
      ;
6113
 
  if (soap->fdisconnect && (soap->error = soap->fdisconnect(soap)))
6114
 
    return soap->error;
6115
 
#ifndef WITH_NOIDREF
6116
 
  if (soap_resolve(soap))
6117
 
    return soap->error;
6118
 
#endif
6119
 
#ifndef WITH_LEANER
6120
 
  if (soap->xlist)
6121
 
  { if (soap->mode & SOAP_ENC_MTOM)
6122
 
      return soap->error = SOAP_MIME_HREF;
6123
 
    return soap->error = SOAP_DIME_HREF;
6124
 
  }
6125
 
#endif
6126
 
  soap_free_temp(soap);
6127
 
  return SOAP_OK;
6128
 
}
6129
 
#endif
6130
 
 
6131
 
/******************************************************************************/
6132
 
#ifndef PALM_1
6133
 
SOAP_FMAC1
6134
 
void
6135
 
SOAP_FMAC2
6136
 
soap_free_temp(struct soap *soap)
6137
 
{ register struct soap_nlist *np, *nq;
6138
 
  register struct soap_attribute *tp, *tq;
6139
 
  register struct Namespace *ns;
6140
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free namespace stack\n"));
6141
 
  for (np = soap->nlist; np; np = nq)
6142
 
  { nq = np->next;
6143
 
    SOAP_FREE(soap, np);
6144
 
  }
6145
 
  soap->nlist = NULL;
6146
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free any remaining temp blocks\n"));
6147
 
  while (soap->blist)
6148
 
    soap_end_block(soap);
6149
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free attribute storage\n"));
6150
 
  for (tp = soap->attributes; tp; tp = tq)
6151
 
  { tq = tp->next;
6152
 
    if (tp->value)
6153
 
      SOAP_FREE(soap, tp->value);
6154
 
    SOAP_FREE(soap, tp);
6155
 
  }
6156
 
  soap->attributes = NULL;
6157
 
#ifdef WITH_FAST
6158
 
  if (soap->labbuf)
6159
 
    SOAP_FREE(soap, soap->labbuf);
6160
 
  soap->labbuf = NULL;
6161
 
  soap->lablen = 0;
6162
 
  soap->labidx = 0;
6163
 
#endif
6164
 
  ns = soap->local_namespaces;
6165
 
  if (ns)
6166
 
  { for (; ns->id; ns++)
6167
 
    { if (ns->out)
6168
 
      { if (soap->encodingStyle == ns->out)
6169
 
          soap->encodingStyle = SOAP_STR_EOS;
6170
 
        SOAP_FREE(soap, ns->out);
6171
 
        ns->out = NULL;
6172
 
      }
6173
 
      if (soap->encodingStyle == ns->ns)
6174
 
        soap->encodingStyle = SOAP_STR_EOS;
6175
 
    }
6176
 
    SOAP_FREE(soap, soap->local_namespaces);
6177
 
    soap->local_namespaces = NULL;
6178
 
  }
6179
 
#ifndef WITH_LEANER
6180
 
  while (soap->xlist)
6181
 
  { struct soap_xlist *xp = soap->xlist->next;
6182
 
    SOAP_FREE(soap, soap->xlist);
6183
 
    soap->xlist = xp;
6184
 
  }
6185
 
#endif
6186
 
#ifndef WITH_NOIDREF
6187
 
  soap_free_pht(soap);
6188
 
  soap_free_iht(soap);
6189
 
#endif
6190
 
}
6191
 
#endif
6192
 
 
6193
 
/******************************************************************************/
6194
 
#ifdef SOAP_DEBUG
6195
 
static void
6196
 
soap_init_logs(struct soap *soap)
6197
 
{ int i;
6198
 
  for (i = 0; i < SOAP_MAXLOGS; i++)
6199
 
  { soap->logfile[i] = NULL;
6200
 
    soap->fdebug[i] = NULL;
6201
 
  }
6202
 
}
6203
 
#endif
6204
 
 
6205
 
/******************************************************************************/
6206
 
#if !defined(WITH_LEAN) || defined(SOAP_DEBUG)
6207
 
SOAP_FMAC1
6208
 
void
6209
 
SOAP_FMAC2
6210
 
soap_open_logfile(struct soap *soap, int i)
6211
 
{ if (soap->logfile[i])
6212
 
    soap->fdebug[i] = fopen(soap->logfile[i], i < 2 ? "ab" : "a");
6213
 
}
6214
 
#endif
6215
 
 
6216
 
/******************************************************************************/
6217
 
#ifdef SOAP_DEBUG
6218
 
static void
6219
 
soap_close_logfile(struct soap *soap, int i)
6220
 
{ if (soap->fdebug[i])
6221
 
  { fclose(soap->fdebug[i]);
6222
 
    soap->fdebug[i] = NULL;
6223
 
  }
6224
 
}
6225
 
#endif
6226
 
 
6227
 
/******************************************************************************/
6228
 
#ifdef SOAP_DEBUG
6229
 
SOAP_FMAC1
6230
 
void
6231
 
SOAP_FMAC2
6232
 
soap_close_logfiles(struct soap *soap)
6233
 
{ int i;
6234
 
  for (i = 0; i < SOAP_MAXLOGS; i++)
6235
 
    soap_close_logfile(soap, i);
6236
 
}
6237
 
#endif
6238
 
 
6239
 
/******************************************************************************/
6240
 
#ifdef SOAP_DEBUG
6241
 
static void
6242
 
soap_set_logfile(struct soap *soap, int i, const char *logfile)
6243
 
{ const char *s;
6244
 
  char *t = NULL;
6245
 
  soap_close_logfile(soap, i);
6246
 
  s = soap->logfile[i];
6247
 
  soap->logfile[i] = logfile;
6248
 
  if (s)
6249
 
    SOAP_FREE(soap, (void*)s);
6250
 
  if (logfile)
6251
 
    if ((t = (char*)SOAP_MALLOC(soap, strlen(logfile) + 1)))
6252
 
      strcpy(t, logfile);
6253
 
  soap->logfile[i] = t;
6254
 
}
6255
 
#endif
6256
 
 
6257
 
/******************************************************************************/
6258
 
#ifdef SOAP_DEBUG
6259
 
SOAP_FMAC1
6260
 
void
6261
 
SOAP_FMAC2
6262
 
soap_set_recv_logfile(struct soap *soap, const char *logfile)
6263
 
{ soap_set_logfile(soap, SOAP_INDEX_RECV, logfile);
6264
 
}
6265
 
#endif
6266
 
 
6267
 
/******************************************************************************/
6268
 
#ifdef SOAP_DEBUG
6269
 
SOAP_FMAC1
6270
 
void
6271
 
SOAP_FMAC2
6272
 
soap_set_sent_logfile(struct soap *soap, const char *logfile)
6273
 
{ soap_set_logfile(soap, SOAP_INDEX_SENT, logfile);
6274
 
}
6275
 
#endif
6276
 
 
6277
 
/******************************************************************************/
6278
 
#ifdef SOAP_DEBUG
6279
 
SOAP_FMAC1
6280
 
void
6281
 
SOAP_FMAC2
6282
 
soap_set_test_logfile(struct soap *soap, const char *logfile)
6283
 
{ soap_set_logfile(soap, SOAP_INDEX_TEST, logfile);
6284
 
}
6285
 
#endif
6286
 
 
6287
 
/******************************************************************************/
6288
 
#ifndef PALM_1
6289
 
SOAP_FMAC1
6290
 
struct soap*
6291
 
SOAP_FMAC2
6292
 
soap_copy(struct soap *soap)
6293
 
{ return soap_copy_context((struct soap*)malloc(sizeof(struct soap)), soap);
6294
 
}
6295
 
#endif
6296
 
 
6297
 
/******************************************************************************/
6298
 
#ifndef PALM_1
6299
 
SOAP_FMAC1
6300
 
struct soap*
6301
 
SOAP_FMAC2
6302
 
soap_copy_context(struct soap *copy, struct soap *soap)
6303
 
{ if (soap_check_state(soap))
6304
 
    return NULL;
6305
 
  if (copy)
6306
 
  { register struct soap_plugin *p = NULL;
6307
 
    memcpy(copy, soap, sizeof(struct soap));
6308
 
    copy->state = SOAP_COPY;
6309
 
    copy->error = SOAP_OK;
6310
 
    copy->userid = NULL;
6311
 
    copy->passwd = NULL;
6312
 
    copy->nlist = NULL;
6313
 
    copy->blist = NULL;
6314
 
    copy->clist = NULL;
6315
 
    copy->alist = NULL;
6316
 
    copy->attributes = NULL;
6317
 
    copy->labbuf = NULL;
6318
 
    copy->lablen = 0;
6319
 
    copy->labidx = 0;
6320
 
#ifdef SOAP_MEM_DEBUG
6321
 
    soap_init_mht(copy);
6322
 
#endif
6323
 
#ifdef SOAP_DEBUG
6324
 
    soap_init_logs(copy);
6325
 
    soap_set_recv_logfile(copy, soap->logfile[SOAP_INDEX_RECV]);
6326
 
    soap_set_sent_logfile(copy, soap->logfile[SOAP_INDEX_SENT]);
6327
 
    soap_set_test_logfile(copy, soap->logfile[SOAP_INDEX_TEST]);
6328
 
#endif
6329
 
    copy->local_namespaces = NULL;
6330
 
#ifndef WITH_NOIDREF
6331
 
    soap_init_iht(copy);
6332
 
    soap_init_pht(copy);
6333
 
#endif
6334
 
    copy->header = NULL;
6335
 
    copy->fault = NULL;
6336
 
    copy->action = NULL;
6337
 
#ifndef WITH_LEAN
6338
 
#ifdef WITH_COOKIES
6339
 
    copy->cookies = soap_copy_cookies(copy, soap);
6340
 
#else
6341
 
    copy->cookies = NULL;
6342
 
#endif
6343
 
#endif
6344
 
    copy->plugins = NULL;
6345
 
    for (p = soap->plugins; p; p = p->next)
6346
 
    { register struct soap_plugin *q = (struct soap_plugin*)SOAP_MALLOC(copy, sizeof(struct soap_plugin));
6347
 
      if (!q)
6348
 
        return NULL;
6349
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Copying plugin '%s'\n", p->id));
6350
 
      *q = *p;
6351
 
      if (p->fcopy && (soap->error = p->fcopy(copy, q, p)))
6352
 
      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not copy plugin '%s'\n", p->id));
6353
 
        SOAP_FREE(copy, q);
6354
 
        return NULL;
6355
 
      }
6356
 
      q->next = copy->plugins;
6357
 
      copy->plugins = q;
6358
 
    }
6359
 
  }
6360
 
  else
6361
 
    soap->error = SOAP_EOM;
6362
 
  return copy;
6363
 
}
6364
 
#endif
6365
 
 
6366
 
/******************************************************************************/
6367
 
#ifndef PALM_1
6368
 
SOAP_FMAC1
6369
 
void
6370
 
SOAP_FMAC2
6371
 
soap_copy_stream(struct soap *copy, struct soap *soap)
6372
 
{ copy->mode = soap->mode;
6373
 
  copy->imode = soap->imode;
6374
 
  copy->omode = soap->omode;
6375
 
  copy->socket = soap->socket;
6376
 
  copy->recv_timeout = soap->recv_timeout;
6377
 
  copy->send_timeout = soap->send_timeout;
6378
 
#if defined(__cplusplus) && !defined(WITH_LEAN)
6379
 
  copy->os = soap->os;
6380
 
  copy->is = soap->is;
6381
 
#endif
6382
 
  copy->sendfd = soap->sendfd;
6383
 
  copy->recvfd = soap->recvfd;
6384
 
  copy->bufidx = soap->bufidx;
6385
 
  copy->buflen = soap->buflen;
6386
 
  copy->ahead = soap->ahead;
6387
 
  copy->cdata = soap->cdata;
6388
 
  copy->chunksize = soap->chunksize;
6389
 
  copy->chunkbuflen = soap->chunkbuflen;
6390
 
  copy->keep_alive = soap->keep_alive;
6391
 
  copy->tcp_keep_alive = soap->tcp_keep_alive;
6392
 
  copy->tcp_keep_idle = soap->tcp_keep_idle;
6393
 
  copy->tcp_keep_intvl = soap->tcp_keep_intvl;
6394
 
  copy->tcp_keep_cnt = soap->tcp_keep_cnt;
6395
 
  copy->max_keep_alive = soap->max_keep_alive;
6396
 
#ifndef WITH_NOIO
6397
 
  copy->peer = soap->peer;
6398
 
  copy->peerlen = soap->peerlen;
6399
 
#endif
6400
 
#ifdef WITH_OPENSSL
6401
 
  copy->bio = soap->bio;
6402
 
  copy->ssl = soap->ssl;
6403
 
  copy->ctx = soap->ctx;
6404
 
#endif
6405
 
#ifdef WITH_ZLIB
6406
 
  copy->zlib_state = soap->zlib_state;
6407
 
  copy->zlib_in = soap->zlib_in;
6408
 
  copy->zlib_out = soap->zlib_out;
6409
 
  copy->d_stream = soap->d_stream;
6410
 
  copy->z_buflen = soap->z_buflen;
6411
 
  copy->z_level = soap->z_level;
6412
 
  copy->z_crc = soap->z_crc;
6413
 
  copy->z_ratio_in = soap->z_ratio_in;
6414
 
  copy->z_ratio_out = soap->z_ratio_out;
6415
 
  memcpy(copy->z_buf, soap->z_buf, sizeof(soap->z_buf));
6416
 
#endif
6417
 
  memcpy(copy->buf, soap->buf, sizeof(soap->buf));
6418
 
}
6419
 
#endif
6420
 
 
6421
 
/******************************************************************************/
6422
 
#ifndef PALM_1
6423
 
SOAP_FMAC1
6424
 
void
6425
 
SOAP_FMAC2
6426
 
soap_init(struct soap *soap)
6427
 
{ soap->state = SOAP_INIT;
6428
 
  soap->version = 0;
6429
 
  soap_imode(soap, SOAP_IO_DEFAULT);
6430
 
  soap_omode(soap, SOAP_IO_DEFAULT);
6431
 
  soap->plugins = NULL;
6432
 
  soap->user = NULL;
6433
 
  soap->userid = NULL;
6434
 
  soap->passwd = NULL;
6435
 
#ifndef WITH_NOHTTP
6436
 
  soap->fpost = http_post;
6437
 
  soap->fget = http_get;
6438
 
  soap->fform = NULL;
6439
 
  soap->fposthdr = http_post_header;
6440
 
  soap->fresponse = http_response;
6441
 
  soap->fparse = http_parse;
6442
 
  soap->fparsehdr = http_parse_header;
6443
 
#endif
6444
 
  soap->fheader = NULL;
6445
 
  soap->fconnect = NULL;
6446
 
  soap->fdisconnect = NULL;
6447
 
#ifndef WITH_NOIO
6448
 
#ifndef WITH_IPV6
6449
 
  soap->fresolve = tcp_gethost;
6450
 
#else
6451
 
  soap->fresolve = NULL;
6452
 
#endif
6453
 
  soap->faccept = tcp_accept;
6454
 
  soap->fopen = tcp_connect;
6455
 
  soap->fclose = tcp_disconnect;
6456
 
  soap->fclosesocket = tcp_closesocket;
6457
 
  soap->fshutdownsocket = tcp_shutdownsocket;
6458
 
  soap->fsend = fsend;
6459
 
  soap->frecv = frecv;
6460
 
  soap->fpoll = soap_poll;
6461
 
#else
6462
 
  soap->fopen = NULL;
6463
 
  soap->fclose = NULL;
6464
 
  soap->fpoll = NULL;
6465
 
#endif
6466
 
  soap->fseterror = NULL;
6467
 
  soap->fignore = NULL;
6468
 
  soap->fserveloop = NULL;
6469
 
  soap->fplugin = fplugin;
6470
 
  soap->fmalloc = NULL;
6471
 
#ifndef WITH_LEANER
6472
 
  soap->fprepareinit = NULL;
6473
 
  soap->fpreparesend = NULL;
6474
 
  soap->fpreparerecv = NULL;
6475
 
  soap->fpreparefinal = NULL;
6476
 
  soap->fdimereadopen = NULL;
6477
 
  soap->fdimewriteopen = NULL;
6478
 
  soap->fdimereadclose = NULL;
6479
 
  soap->fdimewriteclose = NULL;
6480
 
  soap->fdimeread = NULL;
6481
 
  soap->fdimewrite = NULL;
6482
 
  soap->fmimereadopen = NULL;
6483
 
  soap->fmimewriteopen = NULL;
6484
 
  soap->fmimereadclose = NULL;
6485
 
  soap->fmimewriteclose = NULL;
6486
 
  soap->fmimeread = NULL;
6487
 
  soap->fmimewrite = NULL;
6488
 
#endif
6489
 
  soap->float_format = "%.9G"; /* Alternative: use "%G" */
6490
 
  soap->double_format = "%.17lG"; /* Alternative: use "%lG" */
6491
 
  soap->dime_id_format = "cid:id%d"; /* default DIME id format */
6492
 
  soap->http_version = "1.1";
6493
 
  soap->proxy_http_version = "1.0";
6494
 
  soap->http_content = NULL;
6495
 
  soap->actor = NULL;
6496
 
  soap->keep_alive = 0;
6497
 
  soap->tcp_keep_alive = 0;
6498
 
  soap->tcp_keep_idle = 0;
6499
 
  soap->tcp_keep_intvl = 0;
6500
 
  soap->tcp_keep_cnt = 0;
6501
 
  soap->max_keep_alive = SOAP_MAXKEEPALIVE;
6502
 
  soap->recv_timeout = 0;
6503
 
  soap->send_timeout = 0;
6504
 
  soap->connect_timeout = 0;
6505
 
  soap->accept_timeout = 0;
6506
 
  soap->socket_flags = 0;
6507
 
  soap->connect_flags = 0;
6508
 
  soap->bind_flags = 0;
6509
 
  soap->accept_flags = 0;
6510
 
  soap->ip = 0;
6511
 
  soap->labbuf = NULL;
6512
 
  soap->lablen = 0;
6513
 
  soap->labidx = 0;
6514
 
  soap->encodingStyle = SOAP_STR_EOS;
6515
 
#ifndef WITH_NONAMESPACES
6516
 
  soap->namespaces = namespaces;
6517
 
#else
6518
 
  soap->namespaces = NULL;
6519
 
#endif
6520
 
  soap->local_namespaces = NULL;
6521
 
  soap->nlist = NULL;
6522
 
  soap->blist = NULL;
6523
 
  soap->clist = NULL;
6524
 
  soap->alist = NULL;
6525
 
  soap->attributes = NULL;
6526
 
  soap->header = NULL;
6527
 
  soap->fault = NULL;
6528
 
  soap->master = SOAP_INVALID_SOCKET;
6529
 
  soap->socket = SOAP_INVALID_SOCKET;
6530
 
  soap->os = NULL;
6531
 
  soap->is = NULL;
6532
 
#ifndef WITH_LEANER
6533
 
  soap->dom = NULL;
6534
 
  soap->dime.list = NULL;
6535
 
  soap->dime.first = NULL;
6536
 
  soap->dime.last = NULL;
6537
 
  soap->mime.list = NULL;
6538
 
  soap->mime.first = NULL;
6539
 
  soap->mime.last = NULL;
6540
 
  soap->mime.boundary = NULL;
6541
 
  soap->mime.start = NULL;
6542
 
  soap->xlist = NULL;
6543
 
#endif
6544
 
#ifndef UNDER_CE
6545
 
  soap->recvfd = 0;
6546
 
  soap->sendfd = 1;
6547
 
#else
6548
 
  soap->recvfd = stdin;
6549
 
  soap->sendfd = stdout;
6550
 
#endif 
6551
 
  soap->host[0] = '\0';
6552
 
  soap->port = 0;
6553
 
  soap->action = NULL;
6554
 
  soap->proxy_host = NULL;
6555
 
  soap->proxy_port = 8080;
6556
 
  soap->proxy_userid = NULL;
6557
 
  soap->proxy_passwd = NULL;
6558
 
  soap->authrealm = NULL;
6559
 
  soap->prolog = NULL;
6560
 
#ifdef WITH_ZLIB
6561
 
  soap->zlib_state = SOAP_ZLIB_NONE;
6562
 
  soap->zlib_in = SOAP_ZLIB_NONE;
6563
 
  soap->zlib_out = SOAP_ZLIB_NONE;
6564
 
  soap->d_stream.zalloc = NULL;
6565
 
  soap->d_stream.zfree = NULL;
6566
 
  soap->d_stream.opaque = NULL;
6567
 
  soap->z_level = 6;
6568
 
#endif
6569
 
#ifndef WITH_LEAN
6570
 
  soap->c14ninclude = NULL;
6571
 
  soap->c14nexclude = NULL;
6572
 
  soap->cookies = NULL;
6573
 
  soap->cookie_domain = NULL;
6574
 
  soap->cookie_path = NULL;
6575
 
  soap->cookie_max = 32;
6576
 
#endif
6577
 
#ifdef SOAP_MEM_DEBUG
6578
 
  soap_init_mht(soap);
6579
 
#endif
6580
 
#ifdef SOAP_DEBUG
6581
 
  soap_init_logs(soap);
6582
 
#endif
6583
 
#ifdef WMW_RPM_IO
6584
 
  soap->rpmreqid = NULL;
6585
 
#endif
6586
 
#ifdef PALM
6587
 
  palmNetLibOpen();
6588
 
#endif
6589
 
#ifndef WITH_NOIDREF
6590
 
  soap_init_iht(soap);
6591
 
  soap_init_pht(soap);
6592
 
#endif
6593
 
#ifdef SOAP_DEBUG
6594
 
  soap_set_recv_logfile(soap, "RECV.log");
6595
 
  soap_set_sent_logfile(soap, "SENT.log");
6596
 
  soap_set_test_logfile(soap, "TEST.log");
6597
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing context\n"));
6598
 
#endif
6599
 
#ifdef WITH_OPENSSL
6600
 
  if (!ssl_init_done)
6601
 
  { soap_ssl_init();
6602
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing OpenSSL, version=%ld\n", (long)OPENSSL_VERSION_NUMBER));
6603
 
  }
6604
 
  soap->fsslauth = ssl_auth_init;
6605
 
  soap->fsslverify = ssl_verify_callback;
6606
 
  soap->bio = NULL;
6607
 
  soap->ssl = NULL;
6608
 
  soap->ctx = NULL;
6609
 
  soap->ssl_flags = SOAP_SSL_DEFAULT;
6610
 
  soap->keyfile = NULL;
6611
 
  soap->password = NULL;
6612
 
  soap->dhfile = NULL;
6613
 
  soap->cafile = NULL;
6614
 
  soap->capath = NULL;
6615
 
  soap->crlfile = NULL;
6616
 
  soap->randfile = NULL;
6617
 
  soap->session = NULL;
6618
 
#endif
6619
 
  soap_begin(soap);
6620
 
}
6621
 
#endif
6622
 
 
6623
 
/******************************************************************************/
6624
 
#ifndef PALM_1
6625
 
SOAP_FMAC1
6626
 
void
6627
 
SOAP_FMAC2
6628
 
soap_init1(struct soap *soap, soap_mode mode)
6629
 
{ soap_init2(soap, mode, mode);
6630
 
}
6631
 
#endif
6632
 
 
6633
 
/******************************************************************************/
6634
 
#ifndef PALM_1
6635
 
SOAP_FMAC1
6636
 
void
6637
 
SOAP_FMAC2
6638
 
soap_init2(struct soap *soap, soap_mode imode, soap_mode omode)
6639
 
{ soap_init(soap);
6640
 
  soap_imode(soap, imode);
6641
 
  soap_omode(soap, omode);
6642
 
}
6643
 
#endif
6644
 
 
6645
 
/******************************************************************************/
6646
 
#ifndef PALM_2
6647
 
SOAP_FMAC1
6648
 
void
6649
 
SOAP_FMAC2
6650
 
soap_begin(struct soap *soap)
6651
 
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Reinitializing context\n"));
6652
 
  if (!soap->keep_alive)
6653
 
  { soap->buflen = 0;
6654
 
    soap->bufidx = 0;
6655
 
  }
6656
 
  soap->keep_alive = (((soap->imode | soap->omode) & SOAP_IO_KEEPALIVE) != 0);
6657
 
  soap->null = 0;
6658
 
  soap->position = 0;
6659
 
  soap->encoding = 0;
6660
 
  soap->mustUnderstand = 0;
6661
 
  soap->mode = 0;
6662
 
  soap->ns = 0;
6663
 
  soap->part = SOAP_END;
6664
 
  soap->alloced = 0;
6665
 
  soap->count = 0;
6666
 
  soap->length = 0;
6667
 
  soap->cdata = 0;
6668
 
  soap->error = SOAP_OK;
6669
 
  soap->peeked = 0;
6670
 
  soap->ahead = 0;
6671
 
  soap->idnum = 0;
6672
 
  soap->level = 0;
6673
 
  soap->endpoint[0] = '\0';
6674
 
#ifndef WITH_LEANER
6675
 
  soap->dime.chunksize = 0;
6676
 
  soap->dime.buflen = 0;
6677
 
#endif
6678
 
  soap_free_temp(soap);
6679
 
}
6680
 
#endif
6681
 
 
6682
 
/******************************************************************************/
6683
 
#ifndef PALM_2
6684
 
SOAP_FMAC1
6685
 
void
6686
 
SOAP_FMAC2
6687
 
soap_end(struct soap *soap)
6688
 
{ if (soap_check_state(soap))
6689
 
    return;
6690
 
  soap_free_temp(soap);
6691
 
  soap_dealloc(soap, NULL);
6692
 
  while (soap->clist)
6693
 
  { register struct soap_clist *cp = soap->clist->next;
6694
 
    SOAP_FREE(soap, soap->clist);
6695
 
    soap->clist = cp;
6696
 
  }
6697
 
  soap_closesock(soap);
6698
 
#ifdef SOAP_DEBUG
6699
 
  soap_close_logfiles(soap);
6700
 
#endif
6701
 
#ifdef PALM
6702
 
  palmNetLibClose();
6703
 
#endif
6704
 
}
6705
 
#endif
6706
 
 
6707
 
/******************************************************************************/
6708
 
#ifndef PALM_1
6709
 
SOAP_FMAC1
6710
 
int
6711
 
SOAP_FMAC2
6712
 
soap_set_namespaces(struct soap *soap, const struct Namespace *p)
6713
 
{ register struct Namespace *ns = soap->local_namespaces;
6714
 
  register struct soap_nlist *np, *nq, *nr;
6715
 
  register unsigned int level = soap->level;
6716
 
  soap->namespaces = p;
6717
 
  soap->local_namespaces = NULL;
6718
 
  soap_set_local_namespaces(soap);
6719
 
  /* reverse the namespace list */
6720
 
  np = soap->nlist;
6721
 
  soap->nlist = NULL;
6722
 
  if (np)
6723
 
  { nq = np->next;
6724
 
    np->next = NULL;
6725
 
    while (nq)
6726
 
    { nr = nq->next;
6727
 
      nq->next = np;
6728
 
      np = nq;
6729
 
      nq = nr;
6730
 
    }
6731
 
  }
6732
 
  /* then push on new stack */
6733
 
  while (np)
6734
 
  { register const char *s;
6735
 
    soap->level = np->level; /* preserve element nesting level */
6736
 
    s = np->ns;
6737
 
    if (!s && np->index >= 0 && ns)
6738
 
    { s = ns[np->index].out;
6739
 
      if (!s)
6740
 
        s = ns[np->index].ns;
6741
 
    }
6742
 
    if (s && soap_push_namespace(soap, np->id, s))
6743
 
      return soap->error;
6744
 
    nq = np;
6745
 
    np = np->next;
6746
 
    SOAP_FREE(soap, nq);
6747
 
  }
6748
 
  if (ns)
6749
 
  { register int i;
6750
 
    for (i = 0; ns[i].id; i++)
6751
 
    { if (ns[i].out)
6752
 
      { SOAP_FREE(soap, ns[i].out);
6753
 
        ns[i].out = NULL;
6754
 
      }
6755
 
    }
6756
 
    SOAP_FREE(soap, ns);
6757
 
  }
6758
 
  soap->level = level; /* restore level */
6759
 
  return SOAP_OK;
6760
 
}
6761
 
#endif
6762
 
 
6763
 
/******************************************************************************/
6764
 
#ifndef PALM_1
6765
 
SOAP_FMAC1
6766
 
void
6767
 
SOAP_FMAC2
6768
 
soap_set_local_namespaces(struct soap *soap)
6769
 
{ if (soap->namespaces && !soap->local_namespaces)
6770
 
  { register const struct Namespace *ns1;
6771
 
    register struct Namespace *ns2;
6772
 
    register size_t n = 1;
6773
 
    for (ns1 = soap->namespaces; ns1->id; ns1++)
6774
 
      n++;
6775
 
    n *= sizeof(struct Namespace);
6776
 
    ns2 = (struct Namespace*)SOAP_MALLOC(soap, n);
6777
 
    if (ns2)
6778
 
    { memcpy(ns2, soap->namespaces, n);
6779
 
      if (ns2[0].ns)
6780
 
      { if (!strcmp(ns2[0].ns, soap_env1))
6781
 
          soap->version = 1;
6782
 
        else
6783
 
          soap->version = 2;
6784
 
      }
6785
 
      soap->local_namespaces = ns2;
6786
 
    }
6787
 
  }
6788
 
}
6789
 
#endif
6790
 
 
6791
 
/******************************************************************************/
6792
 
#ifndef WITH_LEAN
6793
 
#ifndef PALM_1
6794
 
SOAP_FMAC1
6795
 
const char *
6796
 
SOAP_FMAC2
6797
 
soap_strsearch(const char *big, const char *little)
6798
 
{ size_t n = strlen(little);
6799
 
  const char *s = big;
6800
 
  while (s) 
6801
 
  { if (!strncmp(s, little, n) && (s[n] == '\0' || s[n] == ' '))
6802
 
      return s;
6803
 
    s = strchr(s, ' ');
6804
 
    if (s)
6805
 
      s++;
6806
 
  }
6807
 
  return NULL;
6808
 
}
6809
 
#endif
6810
 
#endif
6811
 
 
6812
 
/******************************************************************************/
6813
 
#ifndef WITH_LEAN
6814
 
#ifndef PALM_1
6815
 
SOAP_FMAC1
6816
 
struct soap_nlist *
6817
 
SOAP_FMAC2
6818
 
soap_lookup_ns(struct soap *soap, const char *tag, size_t n)
6819
 
{ register struct soap_nlist *np;
6820
 
  for (np = soap->nlist; np; np = np->next)
6821
 
  { if (!strncmp(np->id, tag, n) && !np->id[n])
6822
 
      return np;
6823
 
  }
6824
 
  return NULL;
6825
 
}
6826
 
#endif
6827
 
#endif
6828
 
 
6829
 
/******************************************************************************/
6830
 
#ifndef WITH_LEAN
6831
 
static struct soap_nlist *
6832
 
soap_push_ns(struct soap *soap, const char *id, const char *ns, short utilized)
6833
 
{ register struct soap_nlist *np;
6834
 
  size_t n, k;
6835
 
  if (soap_strsearch(soap->c14nexclude, id))
6836
 
    return NULL;
6837
 
  if (!utilized)
6838
 
  { for (np = soap->nlist; np; np = np->next)
6839
 
    { if (!strcmp(np->id, id) && (!np->ns || !strcmp(np->ns, ns)))
6840
 
        break;
6841
 
    }
6842
 
    if (np)
6843
 
    { if ((np->level < soap->level || !np->ns) && np->index == 1)
6844
 
        utilized = 1;
6845
 
      else
6846
 
        return NULL;
6847
 
    }
6848
 
  }
6849
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Adding namespace binding (level=%u) '%s' '%s' utilized=%d\n", soap->level, id, ns?ns:"(null)", utilized));
6850
 
  n = strlen(id);
6851
 
  if (ns)
6852
 
    k = strlen(ns);
6853
 
  else
6854
 
    k = 0;
6855
 
  np = (struct soap_nlist*)SOAP_MALLOC(soap, sizeof(struct soap_nlist) + n + k + 1);
6856
 
  if (!np)
6857
 
  { soap->error = SOAP_EOM;
6858
 
    return NULL;
6859
 
  }
6860
 
  np->next = soap->nlist;
6861
 
  soap->nlist = np;
6862
 
  strcpy(np->id, id);
6863
 
  if (ns)
6864
 
  { np->ns = np->id + n + 1;
6865
 
    strcpy(np->ns, ns);
6866
 
  }
6867
 
  else
6868
 
    np->ns = NULL;
6869
 
  np->level = soap->level;
6870
 
  np->index = utilized;
6871
 
  return np;
6872
 
}
6873
 
#endif
6874
 
 
6875
 
/******************************************************************************/
6876
 
#ifndef WITH_LEAN
6877
 
static void
6878
 
soap_utilize_ns(struct soap *soap, const char *tag, size_t n)
6879
 
{ register struct soap_nlist *np = soap_lookup_ns(soap, tag, n);
6880
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Utilizing namespace of '%s'\n", tag));
6881
 
  if (np)
6882
 
  { if (np->index == 0)
6883
 
      soap_push_ns(soap, np->id, np->ns, 1);
6884
 
  }
6885
 
  else if (strncmp(tag, "xml", 3))
6886
 
  { strncpy(soap->tmpbuf, tag, n);
6887
 
    soap->tmpbuf[n] = '\0';
6888
 
    soap_push_ns(soap, soap->tmpbuf, NULL, 1);
6889
 
  }
6890
 
}
6891
 
#endif
6892
 
 
6893
 
/******************************************************************************/
6894
 
#ifndef WITH_LEAN
6895
 
static void
6896
 
soap_pop_ns(struct soap *soap)
6897
 
{ soap_pop_namespace(soap);
6898
 
}
6899
 
#endif
6900
 
 
6901
 
/******************************************************************************/
6902
 
#ifndef PALM_2
6903
 
SOAP_FMAC1
6904
 
int
6905
 
SOAP_FMAC2
6906
 
soap_element(struct soap *soap, const char *tag, int id, const char *type)
6907
 
{
6908
 
#ifdef WITH_XMLNS
6909
 
  register const char *s;
6910
 
#endif
6911
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element begin tag='%s' id='%d' type='%s'\n", tag, id, type?type:""));
6912
 
#ifdef WITH_DOM
6913
 
  if (soap->part == SOAP_BEGIN_SECURITY && (soap->mode & SOAP_XML_CANONICAL) && !(soap->mode & SOAP_DOM_ASIS))
6914
 
  { register struct soap_nlist *np;
6915
 
    /* wsu:Id found: clear xmlns renderings, so re-emit them for exc-c14n */
6916
 
    for (np = soap->nlist; np; np = np->next)
6917
 
    { if (np->index == 2)
6918
 
        np->index = 0;
6919
 
    }
6920
 
  }
6921
 
  if (soap->mode & SOAP_XML_DOM)
6922
 
  { register struct soap_dom_element *elt = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element));
6923
 
    if (!elt)
6924
 
      return soap->error = SOAP_EOM;
6925
 
    elt->soap = soap;
6926
 
    elt->next = NULL;
6927
 
    elt->prnt = soap->dom;
6928
 
    elt->name = soap_strdup(soap, tag);
6929
 
    elt->elts = NULL;
6930
 
    elt->atts = NULL;
6931
 
    elt->nstr = NULL;
6932
 
    elt->data = NULL;
6933
 
    elt->wide = NULL;
6934
 
    elt->node = NULL;
6935
 
    elt->type = 0;
6936
 
    elt->head = NULL;
6937
 
    elt->tail = NULL;
6938
 
    if (soap->dom)
6939
 
    { struct soap_dom_element *p = soap->dom->elts;
6940
 
      if (p)
6941
 
      { while (p->next)
6942
 
          p = p->next;
6943
 
        p->next = elt;
6944
 
      }
6945
 
      else
6946
 
        soap->dom->elts = elt;
6947
 
    }
6948
 
    soap->dom = elt;
6949
 
  }
6950
 
  else
6951
 
  {
6952
 
#endif
6953
 
    soap->level++;
6954
 
#ifndef WITH_LEAN
6955
 
    if (!soap->ns)
6956
 
    { if (!(soap->mode & SOAP_XML_CANONICAL)
6957
 
       && soap_send(soap, soap->prolog ? soap->prolog : "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"))
6958
 
        return soap->error;
6959
 
    }
6960
 
    else if (soap->mode & SOAP_XML_INDENT)
6961
 
    { if (soap->ns == 1 && soap_send_raw(soap, soap_indent, soap->level < sizeof(soap_indent) ? soap->level : sizeof(soap_indent) - 1))
6962
 
        return soap->error;
6963
 
      soap->body = 1;
6964
 
    }
6965
 
#endif
6966
 
#ifdef WITH_XMLNS
6967
 
    s = strchr(tag, ':');
6968
 
    if (s && strncmp(tag, "SOAP-ENV", s - tag))
6969
 
    { struct Namespace *ns = soap->local_namespaces;
6970
 
      size_t n = s - tag;
6971
 
      if (soap_send_raw(soap, "<", 1)
6972
 
       || soap_send(soap, s + 1))
6973
 
        return soap->error;
6974
 
      if (soap->nlist && !strncmp(soap->nlist->id, tag, n) && !soap->nlist->id[n])
6975
 
        ns = NULL;
6976
 
      for (; ns && ns->id; ns++)
6977
 
      { if (*ns->id && (ns->out || ns->ns) && !strncmp(ns->id, tag, n) && !ns->id[n])
6978
 
        { soap_push_ns(soap, ns->id, ns->out ? ns->out : ns->ns, 0);
6979
 
          if (soap_attribute(soap, "xmlns", ns->out ? ns->out : ns->ns))
6980
 
            return soap->error;
6981
 
          break;
6982
 
        }
6983
 
      }   
6984
 
    }
6985
 
    else
6986
 
#endif
6987
 
    if (soap_send_raw(soap, "<", 1)
6988
 
     || soap_send(soap, tag))
6989
 
      return soap->error;
6990
 
#ifdef WITH_DOM
6991
 
  }
6992
 
#endif
6993
 
  if (!soap->ns)
6994
 
  { struct Namespace *ns;
6995
 
    for (ns = soap->local_namespaces; ns && ns->id; ns++)
6996
 
    { if (*ns->id && (ns->out || ns->ns))
6997
 
      { sprintf(soap->tmpbuf, "xmlns:%s", ns->id);
6998
 
        if (soap_attribute(soap, soap->tmpbuf, ns->out ? ns->out : ns->ns))
6999
 
          return soap->error;
7000
 
      }
7001
 
    }   
7002
 
  }
7003
 
  soap->ns = 1; /* start with 0 or 2, but should be one to continue */
7004
 
#ifndef WITH_LEAN
7005
 
  if (soap->mode & SOAP_XML_CANONICAL)
7006
 
  { const char *t = strchr(tag, ':');
7007
 
    if (t)
7008
 
      soap_utilize_ns(soap, tag, t - tag);
7009
 
  }
7010
 
#endif
7011
 
  if (id > 0)
7012
 
  { sprintf(soap->tmpbuf, "_%d", id);
7013
 
    if (soap_attribute(soap, "id", soap->tmpbuf))
7014
 
      return soap->error;
7015
 
  }
7016
 
  if (type && *type && (!(soap->mode & SOAP_XML_SEC) || soap->part == SOAP_IN_BODY))
7017
 
  { if (soap_attribute(soap, "xsi:type", type))
7018
 
      return soap->error;
7019
 
#ifndef WITH_LEAN
7020
 
    if (soap->mode & SOAP_XML_CANONICAL)
7021
 
    { const char *t = strchr(type, ':');
7022
 
      if (t)
7023
 
        soap_utilize_ns(soap, type, t - type);
7024
 
    }
7025
 
#endif
7026
 
  }
7027
 
  if (soap->null && soap->position > 0)
7028
 
  { register int i;
7029
 
    sprintf(soap->tmpbuf, "[%d", soap->positions[0]);
7030
 
    for (i = 1; i < soap->position; i++)
7031
 
      sprintf(soap->tmpbuf + strlen(soap->tmpbuf), ",%d", soap->positions[i]);
7032
 
    strcat(soap->tmpbuf, "]");
7033
 
    if (soap_attribute(soap, "SOAP-ENC:position", soap->tmpbuf))
7034
 
      return soap->error;
7035
 
  }
7036
 
  if (soap->mustUnderstand)
7037
 
  { if (soap->actor && *soap->actor)
7038
 
    { if (soap_attribute(soap, soap->version == 2 ? "SOAP-ENV:role" : "SOAP-ENV:actor", soap->actor))
7039
 
        return soap->error;
7040
 
    }
7041
 
    if (soap_attribute(soap, "SOAP-ENV:mustUnderstand", soap->version == 2 ? "true" : "1"))
7042
 
      return soap->error;
7043
 
    soap->mustUnderstand = 0;
7044
 
  }
7045
 
  if (soap->encoding)
7046
 
  { if (soap->encodingStyle && soap->local_namespaces)
7047
 
    { if (!*soap->encodingStyle)
7048
 
      { if (soap->local_namespaces[1].out)
7049
 
          soap->encodingStyle = soap->local_namespaces[1].out;
7050
 
        else
7051
 
          soap->encodingStyle = soap->local_namespaces[1].ns;
7052
 
      }
7053
 
      if (soap_attribute(soap, "SOAP-ENV:encodingStyle", soap->encodingStyle))
7054
 
        return soap->error;
7055
 
    }
7056
 
    soap->encoding = 0;
7057
 
  }
7058
 
  soap->null = 0;
7059
 
  soap->position = 0;
7060
 
  if (soap->part == SOAP_BEGIN_SECURITY && (soap->mode & SOAP_XML_CANONICAL))
7061
 
    soap->part = SOAP_IN_SECURITY;
7062
 
  return SOAP_OK;
7063
 
}
7064
 
#endif
7065
 
 
7066
 
/******************************************************************************/
7067
 
#ifndef PALM_2
7068
 
SOAP_FMAC1
7069
 
int
7070
 
SOAP_FMAC2
7071
 
soap_element_begin_out(struct soap *soap, const char *tag, int id, const char *type)
7072
 
{ if (*tag == '-')
7073
 
    return SOAP_OK;
7074
 
  if (soap_element(soap, tag, id, type))
7075
 
    return soap->error;
7076
 
  return soap_element_start_end_out(soap, NULL);
7077
 
}
7078
 
#endif
7079
 
 
7080
 
/******************************************************************************/
7081
 
#ifndef PALM_2
7082
 
#ifndef HAVE_STRRCHR
7083
 
SOAP_FMAC1
7084
 
char*
7085
 
SOAP_FMAC2
7086
 
soap_strrchr(const char *s, int t)
7087
 
{ register char *r = NULL;
7088
 
  while (*s)
7089
 
    if (*s++ == t)
7090
 
      r = (char*)s - 1;
7091
 
  return r;
7092
 
}
7093
 
#endif
7094
 
#endif
7095
 
 
7096
 
/******************************************************************************/
7097
 
#ifndef PALM_2
7098
 
#ifndef HAVE_STRTOL
7099
 
SOAP_FMAC1
7100
 
long
7101
 
SOAP_FMAC2
7102
 
soap_strtol(const char *s, char **t, int b)
7103
 
{ register long n = 0;
7104
 
  register int c;
7105
 
  while (*s > 0 && *s <= 32)
7106
 
    s++;
7107
 
  if (b == 10)
7108
 
  { short neg = 0;
7109
 
    if (*s == '-')
7110
 
    { s++;
7111
 
      neg = 1;
7112
 
    }
7113
 
    else if (*s == '+')
7114
 
      s++;
7115
 
    while ((c = *s) && c >= '0' && c <= '9')
7116
 
    { if (n >= 214748364 && (n > 214748364 || c >= '8'))
7117
 
        break;
7118
 
      n *= 10;
7119
 
      n += c - '0';
7120
 
      s++;
7121
 
    }
7122
 
    if (neg)
7123
 
      n = -n;
7124
 
  }
7125
 
  else /* b == 16 and value is always positive */
7126
 
  { while ((c = *s))
7127
 
    { if (c >= '0' && c <= '9')
7128
 
        c -= '0';
7129
 
      else if (c >= 'A' && c <= 'F')
7130
 
        c -= 'A' - 10;
7131
 
      else if (c >= 'a' && c <= 'f')
7132
 
        c -= 'a' - 10;
7133
 
      if (n > 0x07FFFFFF)
7134
 
        break;
7135
 
      n <<= 4;
7136
 
      n += c;
7137
 
      s++;
7138
 
    }
7139
 
  }
7140
 
  if (t)
7141
 
    *t = (char*)s;
7142
 
  return n;
7143
 
}
7144
 
#endif
7145
 
#endif
7146
 
 
7147
 
/******************************************************************************/
7148
 
#ifndef PALM_2
7149
 
#ifndef HAVE_STRTOUL
7150
 
SOAP_FMAC1
7151
 
unsigned long
7152
 
SOAP_FMAC2
7153
 
soap_strtoul(const char *s, char **t, int b)
7154
 
{ unsigned long n = 0;
7155
 
  register int c;
7156
 
  while (*s > 0 && *s <= 32)
7157
 
    s++;
7158
 
  if (b == 10)
7159
 
  { if (*s == '+')
7160
 
      s++;
7161
 
    while ((c = *s) && c >= '0' && c <= '9')
7162
 
    { if (n >= 429496729 && (n > 429496729 || c >= '6'))
7163
 
        break;
7164
 
      n *= 10;
7165
 
      n += c - '0';
7166
 
      s++;
7167
 
    }
7168
 
  }
7169
 
  else /* b == 16 */
7170
 
  { while ((c = *s))
7171
 
    { if (c >= '0' && c <= '9')
7172
 
        c -= '0';
7173
 
      else if (c >= 'A' && c <= 'F')
7174
 
        c -= 'A' - 10;
7175
 
      else if (c >= 'a' && c <= 'f')
7176
 
        c -= 'a' - 10;
7177
 
      if (n > 0x0FFFFFFF)
7178
 
        break;
7179
 
      n <<= 4;
7180
 
      n += c;
7181
 
      s++;
7182
 
    }
7183
 
  }
7184
 
  if (t)
7185
 
    *t = (char*)s;
7186
 
  return n;
7187
 
}
7188
 
#endif
7189
 
#endif
7190
 
 
7191
 
/******************************************************************************/
7192
 
#ifndef PALM_1
7193
 
SOAP_FMAC1
7194
 
int
7195
 
SOAP_FMAC2
7196
 
soap_array_begin_out(struct soap *soap, const char *tag, int id, const char *type, const char *offset)
7197
 
{ if (soap_element(soap, tag, id, "SOAP-ENC:Array"))
7198
 
    return soap->error;
7199
 
  if (soap->version == 2)
7200
 
  { const char *s;
7201
 
    s = soap_strrchr(type, '[');
7202
 
    if ((size_t)(s - type) < sizeof(soap->tmpbuf))
7203
 
    { strncpy(soap->tmpbuf, type, s - type);
7204
 
      soap->tmpbuf[s - type] = '\0';
7205
 
      if (type && *type && (soap_attribute(soap, "SOAP-ENC:itemType", soap->tmpbuf)))
7206
 
        return soap->error;
7207
 
      if (s && (soap_attribute(soap, "SOAP-ENC:arraySize", s + 1)))
7208
 
        return soap->error;
7209
 
    }
7210
 
  }
7211
 
  else
7212
 
  { if (offset && (soap_attribute(soap, "SOAP-ENC:offset", offset)))
7213
 
      return soap->error;
7214
 
    if (type && *type && (soap_attribute(soap, "SOAP-ENC:arrayType", type)))
7215
 
      return soap->error;
7216
 
  }
7217
 
#ifndef WITH_LEAN
7218
 
  if (type && *type && (soap->mode & SOAP_XML_CANONICAL))
7219
 
  { const char *s = strchr(type, ':');
7220
 
    if (s)
7221
 
      soap_utilize_ns(soap, type, s - type);
7222
 
  }
7223
 
#endif
7224
 
  return soap_element_start_end_out(soap, NULL);
7225
 
}
7226
 
#endif
7227
 
 
7228
 
/******************************************************************************/
7229
 
#ifndef PALM_1
7230
 
SOAP_FMAC1
7231
 
int
7232
 
SOAP_FMAC2
7233
 
soap_element_start_end_out(struct soap *soap, const char *tag)
7234
 
{ register struct soap_attribute *tp;
7235
 
#ifndef WITH_LEAN
7236
 
  if (soap->mode & SOAP_XML_CANONICAL)
7237
 
  { struct soap_nlist *np;
7238
 
    for (tp = soap->attributes; tp; tp = tp->next)
7239
 
    { if (tp->visible && tp->name)
7240
 
      { const char *s = strchr(tp->name, ':');
7241
 
        if (s)
7242
 
          soap_utilize_ns(soap, tp->name, s - tp->name);
7243
 
      }
7244
 
    }
7245
 
    for (np = soap->nlist; np; np = np->next)
7246
 
    { if (np->index == 1 && np->ns)
7247
 
      { sprintf(soap->tmpbuf, "xmlns:%s", np->id);
7248
 
        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Enabling utilized binding (level=%u) %s='%s'\n", np->level, soap->tmpbuf, np->ns));
7249
 
        soap_set_attr(soap, soap->tmpbuf, np->ns);
7250
 
        np->index = 2;
7251
 
      }
7252
 
    }
7253
 
  }
7254
 
#endif
7255
 
#ifdef WITH_DOM
7256
 
  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
7257
 
  { register struct soap_dom_attribute **att;
7258
 
    att = &soap->dom->atts;
7259
 
    for (tp = soap->attributes; tp; tp = tp->next)
7260
 
    { if (tp->visible)
7261
 
      { *att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute));
7262
 
        if (!*att)
7263
 
          return soap->error = SOAP_EOM;
7264
 
        (*att)->next = NULL;
7265
 
        (*att)->nstr = NULL;
7266
 
        (*att)->name = soap_strdup(soap, tp->name);
7267
 
        (*att)->data = soap_strdup(soap, tp->value);
7268
 
        (*att)->wide = NULL;
7269
 
        (*att)->soap = soap;
7270
 
        att = &(*att)->next;
7271
 
        tp->visible = 0;
7272
 
      }
7273
 
    }
7274
 
    return SOAP_OK;
7275
 
  }
7276
 
#endif
7277
 
  for (tp = soap->attributes; tp; tp = tp->next)
7278
 
  { if (tp->visible)
7279
 
    {
7280
 
#ifdef WITH_XMLNS
7281
 
      const char *s = strchr(tp->name, ':');
7282
 
      if (s)
7283
 
      { size_t n = s - tp->name;
7284
 
        if (soap->nlist && !strncmp(soap->nlist->id, tp->name, n) && !soap->nlist->id[n])
7285
 
          s++;
7286
 
        else
7287
 
          s = tp->name;
7288
 
        if (soap_send(soap, " ") || soap_send(soap, s))
7289
 
          return soap->error;
7290
 
      }
7291
 
      else
7292
 
#endif
7293
 
      if (soap_send(soap, " ") || soap_send(soap, tp->name))
7294
 
        return soap->error;
7295
 
      if (tp->visible == 2 && tp->value)
7296
 
        if (soap_send_raw(soap, "=\"", 2)
7297
 
         || soap_string_out(soap, tp->value, 1)
7298
 
         || soap_send_raw(soap, "\"", 1))
7299
 
          return soap->error;
7300
 
      tp->visible = 0;
7301
 
    }
7302
 
  }
7303
 
  if (tag)
7304
 
  { 
7305
 
#ifndef WITH_LEAN
7306
 
    if (soap->mode & SOAP_XML_CANONICAL)
7307
 
    { if (soap_send_raw(soap, ">", 1)
7308
 
       || soap_element_end_out(soap, tag))
7309
 
        return soap->error;
7310
 
      return SOAP_OK;
7311
 
    }
7312
 
#endif
7313
 
    soap->level--;      /* decrement level just before /> */
7314
 
    if (soap_send_raw(soap, "/>", 2))
7315
 
      return soap->error;
7316
 
    return SOAP_OK;
7317
 
  }
7318
 
  return soap_send_raw(soap, ">", 1);
7319
 
}
7320
 
#endif
7321
 
 
7322
 
/******************************************************************************/
7323
 
#ifndef PALM_1
7324
 
SOAP_FMAC1
7325
 
int
7326
 
SOAP_FMAC2
7327
 
soap_element_end_out(struct soap *soap, const char *tag)
7328
 
{ if (*tag == '-')
7329
 
    return SOAP_OK;
7330
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element ending tag='%s'\n", tag));
7331
 
#ifdef WITH_DOM
7332
 
  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
7333
 
  { if (soap->dom->prnt)
7334
 
      soap->dom = soap->dom->prnt;
7335
 
    return SOAP_OK;
7336
 
  }
7337
 
#endif
7338
 
#ifndef WITH_LEAN
7339
 
  if (soap->mode & SOAP_XML_CANONICAL)
7340
 
    soap_pop_ns(soap);
7341
 
  if (soap->mode & SOAP_XML_INDENT)
7342
 
  { if (!soap->body)
7343
 
    { if (soap_send_raw(soap, soap_indent, soap->level < sizeof(soap_indent) ? soap->level : sizeof(soap_indent) - 1))
7344
 
        return soap->error;
7345
 
    }
7346
 
    soap->body = 0;
7347
 
  }
7348
 
#endif
7349
 
#ifdef WITH_XMLNS
7350
 
  { const char *s = strchr(tag, ':');
7351
 
    if (s && strncmp(tag, "SOAP-ENV", s - tag))
7352
 
    { soap_pop_ns(soap);
7353
 
      tag = s + 1;
7354
 
    }
7355
 
  }
7356
 
#endif
7357
 
  if (soap_send_raw(soap, "</", 2)
7358
 
   || soap_send(soap, tag))
7359
 
    return soap->error;
7360
 
  soap->level--;        /* decrement level just before > */
7361
 
  return soap_send_raw(soap, ">", 1);
7362
 
}
7363
 
#endif
7364
 
 
7365
 
/******************************************************************************/
7366
 
#ifndef PALM_1
7367
 
SOAP_FMAC1
7368
 
int
7369
 
SOAP_FMAC2
7370
 
soap_element_ref(struct soap *soap, const char *tag, int id, int href)
7371
 
{ register int n = 0;
7372
 
  const char *s = "href";
7373
 
  if (soap->version == 2)
7374
 
  { s = "SOAP-ENC:ref";
7375
 
    n = 1;
7376
 
  }
7377
 
  sprintf(soap->href, "#_%d", href);
7378
 
  return soap_element_href(soap, tag, id, s, soap->href + n);
7379
 
}
7380
 
#endif
7381
 
 
7382
 
/******************************************************************************/
7383
 
#ifndef PALM_1
7384
 
SOAP_FMAC1
7385
 
int
7386
 
SOAP_FMAC2
7387
 
soap_element_href(struct soap *soap, const char *tag, int id, const char *ref, const char *val)
7388
 
{ DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element '%s' reference %s='%s'\n", tag, ref, val));
7389
 
  if (soap_element(soap, tag, id, NULL)
7390
 
   || soap_attribute(soap, ref, val)
7391
 
   || soap_element_start_end_out(soap, tag))
7392
 
    return soap->error;
7393
 
  return SOAP_OK;
7394
 
}
7395
 
#endif
7396
 
 
7397
 
/******************************************************************************/
7398
 
#ifndef PALM_1
7399
 
SOAP_FMAC1
7400
 
int
7401
 
SOAP_FMAC2
7402
 
soap_element_null(struct soap *soap, const char *tag, int id, const char *type)
7403
 
{ struct soap_attribute *tp;
7404
 
  for (tp = soap->attributes; tp; tp = tp->next)
7405
 
    if (tp->visible)
7406
 
      break;
7407
 
  if (tp || (soap->version == 2 && soap->position > 0) || id > 0 || (soap->mode & SOAP_XML_NIL))
7408
 
  { if (soap_element(soap, tag, id, type))
7409
 
      return soap->error;
7410
 
    if (soap->part != SOAP_IN_HEADER && soap->encodingStyle)
7411
 
      if (soap_attribute(soap, "xsi:nil", "true"))
7412
 
        return soap->error;
7413
 
    return soap_element_start_end_out(soap, tag);
7414
 
  }
7415
 
  soap->null = 1;
7416
 
  soap->position = 0;
7417
 
  soap->mustUnderstand = 0;
7418
 
  return SOAP_OK;
7419
 
}
7420
 
#endif
7421
 
 
7422
 
/******************************************************************************/
7423
 
#ifndef PALM_1
7424
 
SOAP_FMAC1
7425
 
int
7426
 
SOAP_FMAC2
7427
 
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) 
7428
 
{ if (!p || (a && !a->__ptr))
7429
 
  { soap_element_null(soap, tag, id, type);
7430
 
    return -1;
7431
 
  }
7432
 
#ifndef WITH_NOIDREF
7433
 
  if (soap->mode & SOAP_XML_TREE)
7434
 
    return 0;
7435
 
  if (id < 0)
7436
 
  { struct soap_plist *pp;
7437
 
    if (a)
7438
 
      id = soap_array_pointer_lookup(soap, p, a, n, t, &pp);
7439
 
    else
7440
 
      id = soap_pointer_lookup(soap, p, t, &pp);
7441
 
    if (id)
7442
 
    { if (soap_is_embedded(soap, pp))
7443
 
      { soap_element_ref(soap, tag, 0, id);
7444
 
        return -1;
7445
 
      }
7446
 
      if (soap_is_single(soap, pp))
7447
 
        return 0;
7448
 
      soap_set_embedded(soap, pp);
7449
 
    }
7450
 
  }
7451
 
  return id;
7452
 
#else
7453
 
  return 0;
7454
 
#endif
7455
 
}
7456
 
#endif
7457
 
 
7458
 
/******************************************************************************/
7459
 
#ifndef PALM_1
7460
 
SOAP_FMAC1
7461
 
int
7462
 
SOAP_FMAC2
7463
 
soap_element_result(struct soap *soap, const char *tag)
7464
 
{ if (soap->version == 2 && soap->encodingStyle)
7465
 
  { if (soap_element(soap, "SOAP-RPC:result", 0, NULL)
7466
 
     || soap_attribute(soap, "xmlns:SOAP-RPC", soap_rpc)
7467
 
     || soap_element_start_end_out(soap, NULL)
7468
 
     || soap_string_out(soap, tag, 0)
7469
 
     || soap_element_end_out(soap, "SOAP-RPC:result"))
7470
 
      return soap->error;
7471
 
  }
7472
 
  return SOAP_OK;
7473
 
}
7474
 
#endif
7475
 
 
7476
 
/******************************************************************************/
7477
 
#ifndef PALM_1
7478
 
SOAP_FMAC1
7479
 
void
7480
 
SOAP_FMAC2
7481
 
soap_check_result(struct soap *soap, const char *tag)
7482
 
{ if (soap->version == 2 && soap->encodingStyle)
7483
 
  { soap_instring(soap, ":result", NULL, NULL, 0, 2, -1, -1);
7484
 
    /* just ignore content for compliance reasons, but should compare tag to element's QName value? */
7485
 
  }
7486
 
}
7487
 
#endif
7488
 
 
7489
 
/******************************************************************************/
7490
 
#ifndef PALM_2
7491
 
SOAP_FMAC1
7492
 
int
7493
 
SOAP_FMAC2
7494
 
soap_attribute(struct soap *soap, const char *name, const char *value)
7495
 
7496
 
#ifdef WITH_DOM
7497
 
  if ((soap->mode & SOAP_XML_DOM) && !(soap->mode & SOAP_XML_CANONICAL) && soap->dom)
7498
 
  { register struct soap_dom_attribute *a = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute));
7499
 
    a->next = soap->dom->atts;
7500
 
    a->nstr = NULL;
7501
 
    a->name = soap_strdup(soap, name);
7502
 
    a->data = soap_strdup(soap, value);
7503
 
    a->wide = NULL;
7504
 
    a->soap = soap;
7505
 
    soap->dom->atts = a;
7506
 
    return SOAP_OK;
7507
 
  }
7508
 
#endif
7509
 
#ifndef WITH_LEAN
7510
 
  if (soap->mode & SOAP_XML_CANONICAL)
7511
 
  { /* TODO: consider using this code to handle default namespace bindings
7512
 
    if (!strncmp(name, "xmlns", 5) && (name[5] == ':' || name[5] == '\0'))
7513
 
    { if (name[5] == ':')
7514
 
        soap_push_ns(soap, name + 6, value, 0);
7515
 
      else
7516
 
        soap_push_ns(soap, "", value, 0);
7517
 
    }
7518
 
    */
7519
 
    if (!strncmp(name, "xmlns:", 6))
7520
 
      soap_push_ns(soap, name + 6, value, 0);
7521
 
    else if (soap_set_attr(soap, name, value))
7522
 
      return soap->error;
7523
 
  }
7524
 
  else
7525
 
#endif
7526
 
  { if (soap_send(soap, " ") || soap_send(soap, name))
7527
 
      return soap->error;
7528
 
    if (value)
7529
 
      if (soap_send_raw(soap, "=\"", 2)
7530
 
       || soap_string_out(soap, value, 1)
7531
 
       || soap_send_raw(soap, "\"", 1))
7532
 
        return soap->error;
7533
 
  }
7534
 
  return SOAP_OK;
7535
 
}
7536
 
#endif
7537
 
 
7538
 
/******************************************************************************/
7539
 
#ifndef PALM_2
7540
 
SOAP_FMAC1
7541
 
int
7542
 
SOAP_FMAC2
7543
 
soap_element_begin_in(struct soap *soap, const char *tag, int nillable, const char *type)
7544
 
{ if (!soap_peek_element(soap))
7545
 
  { if (soap->other)
7546
 
      return soap->error = SOAP_TAG_MISMATCH;
7547
 
    if (tag && *tag == '-')
7548
 
      return SOAP_OK;
7549
 
    if (!(soap->error = soap_match_tag(soap, soap->tag, tag)))
7550
 
    { soap->peeked = 0;
7551
 
      if (type && *soap->type && soap_match_tag(soap, soap->type, type))
7552
 
        return soap->error = SOAP_TYPE;
7553
 
      if (!nillable && soap->null && (soap->mode & SOAP_XML_STRICT))
7554
 
        return soap->error = SOAP_NULL;
7555
 
      if (soap->body)
7556
 
        soap->level++;
7557
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Begin element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag?tag:"" ));
7558
 
    }
7559
 
  }
7560
 
  else if (soap->error == SOAP_NO_TAG && tag && *tag == '-')
7561
 
    soap->error = SOAP_OK;
7562
 
  return soap->error;
7563
 
}
7564
 
#endif
7565
 
 
7566
 
/******************************************************************************/
7567
 
#ifndef PALM_2
7568
 
SOAP_FMAC1
7569
 
int
7570
 
SOAP_FMAC2
7571
 
soap_element_end_in(struct soap *soap, const char *tag)  
7572
 
{ register soap_wchar c;
7573
 
  register char *s;
7574
 
  register int n = 0;
7575
 
  if (tag && *tag == '-')
7576
 
    return SOAP_OK;
7577
 
  if (soap->error == SOAP_NO_TAG)
7578
 
    soap->error = SOAP_OK;
7579
 
#ifdef WITH_DOM
7580
 
  /* this whitespace or mixed content is not insignificant for DOM */
7581
 
  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
7582
 
  { if (!soap->peeked && !soap_string_in(soap, 3, -1, -1))
7583
 
      return soap->error;
7584
 
    if (soap->dom->prnt)
7585
 
      soap->dom = soap->dom->prnt;
7586
 
  }
7587
 
#endif
7588
 
  if (soap->peeked)
7589
 
  { if (*soap->tag)
7590
 
      n++;
7591
 
    soap->peeked = 0;
7592
 
  }
7593
 
  do
7594
 
  { while (((c = soap_get(soap)) != SOAP_TT))
7595
 
    { if ((int)c == EOF)
7596
 
        return soap->error = SOAP_EOF;
7597
 
      if (c == SOAP_LT)
7598
 
        n++;
7599
 
      else if (c == '/')
7600
 
      { c = soap_get(soap);
7601
 
        if (c == SOAP_GT)
7602
 
          n--;
7603
 
        else
7604
 
          soap_unget(soap, c);
7605
 
      }
7606
 
    }
7607
 
  } while (n--);
7608
 
  s = soap->tag;
7609
 
  n = sizeof(soap->tag);
7610
 
  while (soap_notblank(c = soap_get(soap)))
7611
 
  { if (--n > 0)
7612
 
      *s++ = (char)c;
7613
 
  }
7614
 
  *s = '\0';
7615
 
  if ((int)c == EOF)
7616
 
    return soap->error = SOAP_EOF;
7617
 
  while (soap_blank(c))
7618
 
    c = soap_get(soap);
7619
 
  if (c != SOAP_GT)
7620
 
    return soap->error = SOAP_SYNTAX_ERROR;
7621
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element found (level=%u) '%s'='%s'\n", soap->level, soap->tag, tag?tag:""));
7622
 
#ifndef WITH_LEAN
7623
 
  if (tag && (soap->mode & SOAP_XML_STRICT))
7624
 
  { soap_pop_namespace(soap);
7625
 
    if (soap_match_tag(soap, soap->tag, tag))
7626
 
    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End element tag name does not match\n"));
7627
 
      return soap->error = SOAP_SYNTAX_ERROR;
7628
 
    }
7629
 
  }
7630
 
#endif
7631
 
  soap->level--;
7632
 
  return SOAP_OK;
7633
 
}
7634
 
#endif
7635
 
 
7636
 
/******************************************************************************/
7637
 
#ifndef PALM_2
7638
 
SOAP_FMAC1
7639
 
const char *
7640
 
SOAP_FMAC2
7641
 
soap_attr_value(struct soap *soap, const char *name, int flag)
7642
 
{ register struct soap_attribute *tp;
7643
 
  if (*name == '-')
7644
 
    return SOAP_STR_EOS;
7645
 
  for (tp = soap->attributes; tp; tp = tp->next)
7646
 
  { if (tp->visible && !soap_match_tag(soap, tp->name, name))
7647
 
      break;
7648
 
  }
7649
 
  if (tp)
7650
 
  { if (flag == 2 && (soap->mode & SOAP_XML_STRICT))
7651
 
      soap->error = SOAP_PROHIBITED;
7652
 
    else
7653
 
      return tp->value;
7654
 
  }
7655
 
  else if (flag == 1 && (soap->mode & SOAP_XML_STRICT))
7656
 
    soap->error = SOAP_REQUIRED;
7657
 
  return NULL;
7658
 
}
7659
 
#endif
7660
 
 
7661
 
/******************************************************************************/
7662
 
#ifndef PALM_2
7663
 
SOAP_FMAC1
7664
 
int
7665
 
SOAP_FMAC2
7666
 
soap_set_attr(struct soap *soap, const char *name, const char *value)
7667
 
{ register struct soap_attribute *tp;
7668
 
  if (*name == '-')
7669
 
    return SOAP_OK;
7670
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set attribute %s='%s'\n", name, value?value:""));
7671
 
  for (tp = soap->attributes; tp; tp = tp->next)
7672
 
  { if (!strcmp(tp->name, name))
7673
 
      break;
7674
 
  }
7675
 
  if (!tp)
7676
 
  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Allocate attribute %s\n", name));
7677
 
    if (!(tp = (struct soap_attribute*)SOAP_MALLOC(soap, sizeof(struct soap_attribute) + strlen(name))))
7678
 
      return soap->error = SOAP_EOM;
7679
 
    tp->ns = NULL;
7680
 
#ifndef WITH_LEAN
7681
 
    if (soap->mode & SOAP_XML_CANONICAL)
7682
 
    { struct soap_attribute **tpp = &soap->attributes;
7683
 
      const char *s = strchr(name, ':');
7684
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inserting attribute %s for c14n\n", name))
7685
 
      if (!strncmp(name, "xmlns", 5))
7686
 
      { for (; *tpp; tpp = &(*tpp)->next)
7687
 
          if (strncmp((*tpp)->name, "xmlns", 5) || strcmp((*tpp)->name + 5, name + 5) > 0)
7688
 
            break;
7689
 
      }
7690
 
      else if (!s)
7691
 
      { for (; *tpp; tpp = &(*tpp)->next)
7692
 
          if (strncmp((*tpp)->name, "xmlns", 5) && ((*tpp)->ns || strcmp((*tpp)->name, name) > 0))
7693
 
            break;
7694
 
      }
7695
 
      else
7696
 
      { int k;
7697
 
        for (; *tpp; tpp = &(*tpp)->next)
7698
 
        { if (!strncmp((*tpp)->name, "xmlns:", 6) && !strncmp((*tpp)->name + 6, name, s - name) && !(*tpp)->name[6 + s - name])
7699
 
          { if (!tp->ns)
7700
 
            { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Canonicalization: prefix %s=%p (%s)\n", name, (*tpp)->ns, (*tpp)->ns));
7701
 
              tp->ns = (*tpp)->ns;
7702
 
            }
7703
 
          }
7704
 
          else if (strncmp((*tpp)->name, "xmlns", 5) && (*tpp)->ns && tp->ns && ((k = strcmp((*tpp)->ns, tp->ns)) > 0 || (!k && strcmp((*tpp)->name, name) > 0)))
7705
 
            break;
7706
 
        }
7707
 
      }
7708
 
      tp->next = *tpp;
7709
 
      *tpp = tp;
7710
 
    }
7711
 
    else
7712
 
#endif
7713
 
    { tp->next = soap->attributes;
7714
 
      soap->attributes = tp;
7715
 
    }
7716
 
    strcpy(tp->name, name);
7717
 
    tp->value = NULL;
7718
 
  }
7719
 
  else if (tp->visible)
7720
 
  { return SOAP_OK;
7721
 
  }
7722
 
  else if (value && tp->value && tp->size <= strlen(value))
7723
 
  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Free attribute value of %s (free %p)\n", name, tp->value));
7724
 
    SOAP_FREE(soap, tp->value);
7725
 
    tp->value = NULL;
7726
 
    tp->ns = NULL;
7727
 
  }
7728
 
  if (value)
7729
 
  { if (!tp->value)
7730
 
    { tp->size = strlen(value) + 1;
7731
 
      if (!(tp->value = (char*)SOAP_MALLOC(soap, tp->size)))
7732
 
        return soap->error = SOAP_EOM;
7733
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Allocate attribute value for %s (%p)\n", tp->name, tp->value));
7734
 
    }
7735
 
    strcpy(tp->value, value);
7736
 
    if (!strncmp(tp->name, "xmlns:", 6))
7737
 
      tp->ns = tp->value;
7738
 
    tp->visible = 2;
7739
 
#ifndef WITH_LEAN
7740
 
    if (!strcmp(name, "wsu:Id"))
7741
 
    { soap->part = SOAP_BEGIN_SECURITY;
7742
 
      strncpy(soap->id, value, sizeof(soap->id));
7743
 
      soap->id[sizeof(soap->id)-1] = '\0';
7744
 
    }
7745
 
#endif
7746
 
  }
7747
 
  else
7748
 
    tp->visible = 1;
7749
 
  return SOAP_OK;
7750
 
}
7751
 
#endif
7752
 
 
7753
 
/******************************************************************************/
7754
 
#ifndef PALM_2
7755
 
SOAP_FMAC1
7756
 
void
7757
 
SOAP_FMAC2
7758
 
soap_clr_attr(struct soap *soap)
7759
 
{ register struct soap_attribute *tp;
7760
 
#ifndef WITH_LEAN
7761
 
  if ((soap->mode & SOAP_XML_CANONICAL))
7762
 
  { while (soap->attributes)
7763
 
    { tp = soap->attributes->next;
7764
 
      if (soap->attributes->value)
7765
 
        SOAP_FREE(soap, soap->attributes->value);
7766
 
      SOAP_FREE(soap, soap->attributes);
7767
 
      soap->attributes = tp;
7768
 
    }
7769
 
  }
7770
 
  else
7771
 
#endif
7772
 
  { for (tp = soap->attributes; tp; tp = tp->next)
7773
 
      tp->visible = 0;
7774
 
  }
7775
 
}
7776
 
#endif
7777
 
 
7778
 
/******************************************************************************/
7779
 
#ifndef PALM_2
7780
 
static int
7781
 
soap_getattrval(struct soap *soap, char *s, size_t n, soap_wchar d)
7782
 
{ register size_t i;
7783
 
  for (i = 0; i < n; i++)
7784
 
  { register soap_wchar c = soap_get(soap);
7785
 
    switch (c)
7786
 
    {
7787
 
    case SOAP_TT:
7788
 
      *s++ = '<';
7789
 
      soap_unget(soap, '/');
7790
 
      break;
7791
 
    case SOAP_LT:
7792
 
      *s++ = '<';
7793
 
      break;
7794
 
    case SOAP_GT:
7795
 
      if (d == ' ')
7796
 
      { soap_unget(soap, c);
7797
 
        *s = '\0';
7798
 
        return SOAP_OK;
7799
 
      }
7800
 
      *s++ = '>';
7801
 
      break;
7802
 
    case SOAP_QT:
7803
 
      if (c == d)
7804
 
      { *s = '\0';
7805
 
        return SOAP_OK;
7806
 
      }
7807
 
      *s++ = '"';
7808
 
      break;
7809
 
    case SOAP_AP:
7810
 
      if (c == d)
7811
 
      { *s = '\0';
7812
 
        return SOAP_OK;
7813
 
      }
7814
 
      *s++ = '\'';
7815
 
      break;
7816
 
    case '\t':
7817
 
    case '\n':
7818
 
    case '\r':
7819
 
    case ' ':
7820
 
    case '/':
7821
 
      if (d == ' ')
7822
 
      { soap_unget(soap, c);
7823
 
        *s = '\0';
7824
 
        return SOAP_OK;
7825
 
      }
7826
 
    default:
7827
 
      if ((int)c == EOF)
7828
 
        return soap->error = SOAP_EOF;
7829
 
      *s++ = (char)c;
7830
 
    }
7831
 
  }
7832
 
  return soap->error = SOAP_EOM;
7833
 
}
7834
 
#endif
7835
 
 
7836
 
/******************************************************************************/
7837
 
#ifdef WITH_FAST
7838
 
#ifndef PALM_2
7839
 
SOAP_FMAC1
7840
 
int
7841
 
SOAP_FMAC2
7842
 
soap_store_lab(struct soap *soap, const char *s, size_t n)
7843
 
{ soap->labidx = 0;
7844
 
  return soap_append_lab(soap, s, n);
7845
 
}
7846
 
#endif
7847
 
#endif
7848
 
 
7849
 
/******************************************************************************/
7850
 
#ifdef WITH_FAST
7851
 
#ifndef PALM_2
7852
 
SOAP_FMAC1
7853
 
int
7854
 
SOAP_FMAC2
7855
 
soap_append_lab(struct soap *soap, const char *s, size_t n)
7856
 
{ if (soap->labidx + n >= soap->lablen)
7857
 
  { register char *t = soap->labbuf;
7858
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Enlarging look-aside buffer to append data, old size=%lu", (unsigned long)soap->lablen));
7859
 
    if (soap->lablen == 0)
7860
 
      soap->lablen = SOAP_LABLEN;
7861
 
    while (soap->labidx + n >= soap->lablen)
7862
 
      soap->lablen <<= 1;
7863
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, ", new size=%lu\n", (unsigned long)soap->lablen));
7864
 
    soap->labbuf = (char*)SOAP_MALLOC(soap, soap->lablen);
7865
 
    if (!soap->labbuf)
7866
 
    { if (t)
7867
 
        SOAP_FREE(soap, t);
7868
 
      return soap->error = SOAP_EOM;
7869
 
    }
7870
 
    if (t)
7871
 
    { memcpy(soap->labbuf, t, soap->labidx);
7872
 
      SOAP_FREE(soap, t);
7873
 
    }
7874
 
  }
7875
 
  if (s)
7876
 
  { memcpy(soap->labbuf + soap->labidx, s, n);
7877
 
    soap->labidx += n;
7878
 
  }
7879
 
  return SOAP_OK;
7880
 
}
7881
 
#endif
7882
 
#endif
7883
 
 
7884
 
/******************************************************************************/
7885
 
#ifndef PALM_2
7886
 
SOAP_FMAC1
7887
 
int
7888
 
SOAP_FMAC2
7889
 
soap_peek_element(struct soap *soap)
7890
 
{
7891
 
#ifdef WITH_DOM
7892
 
  register struct soap_dom_attribute **att = NULL;
7893
 
  register char *lead = NULL;
7894
 
#endif
7895
 
  register struct soap_attribute *tp, *tq = NULL;
7896
 
  const char *t;
7897
 
  register char *s;
7898
 
  register soap_wchar c;
7899
 
  register int i;
7900
 
  if (soap->peeked)
7901
 
  { if (!*soap->tag)
7902
 
      return soap->error = SOAP_NO_TAG;
7903
 
    return SOAP_OK;
7904
 
  }
7905
 
  soap->peeked = 1;
7906
 
  soap->id[0] = '\0';
7907
 
  soap->href[0] = '\0';
7908
 
  soap->type[0] = '\0';
7909
 
  soap->arrayType[0] = '\0';
7910
 
  soap->arraySize[0] = '\0';
7911
 
  soap->arrayOffset[0] = '\0';
7912
 
  soap->other = 0;
7913
 
  soap->root = -1;
7914
 
  soap->position = 0;
7915
 
  soap->null = 0;
7916
 
  soap->mustUnderstand = 0;
7917
 
  c = soap_getutf8(soap);
7918
 
#ifdef WITH_DOM
7919
 
  /* whitespace leading to start tag is not insignificant for DOM */
7920
 
  if (soap_blank(c))
7921
 
  { soap->labidx = 0;
7922
 
    do
7923
 
    { if (soap_append_lab(soap, NULL, 0))
7924
 
        return SOAP_EOM;
7925
 
      s = soap->labbuf + soap->labidx;
7926
 
      i = soap->lablen - soap->labidx;
7927
 
      soap->labidx = soap->lablen;
7928
 
      while (soap_blank(c) && i--)
7929
 
      { *s++ = c;
7930
 
        c = soap_getutf8(soap);
7931
 
      }
7932
 
    }
7933
 
    while (soap_blank(c));
7934
 
    *s = '\0';
7935
 
    lead = soap_strdup(soap, soap->labbuf);
7936
 
  }
7937
 
#else
7938
 
  while (soap_blank(c))
7939
 
    c = soap_getutf8(soap);
7940
 
#endif
7941
 
  if (c != SOAP_LT)
7942
 
  { *soap->tag = '\0';
7943
 
    if ((int)c == EOF)
7944
 
      return soap->error = SOAP_EOF;
7945
 
    soap_unget(soap, c);
7946
 
#ifdef WITH_DOM
7947
 
    /* whitespace leading to end tag is not insignificant for DOM */
7948
 
    if ((soap->mode & SOAP_XML_DOM) && soap->dom)
7949
 
      soap->dom->tail = soap_strdup(soap, lead);
7950
 
#endif
7951
 
    return soap->error = SOAP_NO_TAG;
7952
 
  }
7953
 
  s = soap->tag;
7954
 
  do c = soap_get1(soap);
7955
 
  while (soap_blank(c));
7956
 
  i = sizeof(soap->tag);
7957
 
  while (c != '>' && c != '/' && soap_notblank(c) && (int)c != EOF)
7958
 
  { if (--i > 0)
7959
 
      *s++ = (char)c;
7960
 
    c = soap_get1(soap);
7961
 
  }
7962
 
  while (soap_blank(c))
7963
 
    c = soap_get1(soap);
7964
 
  *s = '\0';
7965
 
#ifdef WITH_DOM
7966
 
  if (soap->mode & SOAP_XML_DOM)
7967
 
  { register struct soap_dom_element *elt;
7968
 
    elt = (struct soap_dom_element*)soap_malloc(soap, sizeof(struct soap_dom_element));
7969
 
    if (!elt)
7970
 
      return soap->error = SOAP_EOM;
7971
 
    elt->next = NULL;
7972
 
    elt->nstr = NULL;
7973
 
    elt->name = soap_strdup(soap, soap->tag);
7974
 
    elt->prnt = soap->dom;
7975
 
    elt->elts = NULL;
7976
 
    elt->atts = NULL;
7977
 
    elt->data = NULL;
7978
 
    elt->wide = NULL;
7979
 
    elt->type = 0;
7980
 
    elt->node = NULL;
7981
 
    elt->head = lead;
7982
 
    elt->tail = NULL;
7983
 
    elt->soap = soap;
7984
 
    if (soap->dom)
7985
 
    { struct soap_dom_element *p = soap->dom->elts;
7986
 
      if (p)
7987
 
      { while (p->next)
7988
 
          p = p->next;
7989
 
        p->next = elt;
7990
 
      }
7991
 
      else
7992
 
        soap->dom->elts = elt;
7993
 
    }
7994
 
    soap->dom = elt;
7995
 
    att = &elt->atts;
7996
 
  }
7997
 
#endif
7998
 
  soap_pop_namespace(soap);
7999
 
  for (tp = soap->attributes; tp; tp = tp->next)
8000
 
    tp->visible = 0;
8001
 
  while ((int)c != EOF && c != '>' && c != '/')
8002
 
  { s = soap->tmpbuf;
8003
 
    i = sizeof(soap->tmpbuf);
8004
 
    while (c != '=' && c != '>' && c != '/' && soap_notblank(c) && (int)c != EOF)
8005
 
    { if (--i > 0)
8006
 
        *s++ = (char)c;
8007
 
      c = soap_get1(soap);
8008
 
    }
8009
 
    *s = '\0';
8010
 
    if (i == sizeof(soap->tmpbuf))
8011
 
      return soap->error = SOAP_SYNTAX_ERROR;
8012
 
#ifdef WITH_DOM
8013
 
    /* add attribute name to dom */
8014
 
    if (att)
8015
 
    { *att = (struct soap_dom_attribute*)soap_malloc(soap, sizeof(struct soap_dom_attribute));
8016
 
       if (!*att)
8017
 
         return soap->error = SOAP_EOM;
8018
 
       (*att)->next = NULL;
8019
 
       (*att)->nstr = NULL;
8020
 
       (*att)->name = soap_strdup(soap, soap->tmpbuf);
8021
 
       (*att)->data = NULL;
8022
 
       (*att)->wide = NULL;
8023
 
       (*att)->soap = soap;
8024
 
    }
8025
 
#endif
8026
 
    if (!strncmp(soap->tmpbuf, "xmlns", 5))
8027
 
    { if (soap->tmpbuf[5] == ':')
8028
 
      { soap->tmpbuf[5] = '\0';
8029
 
        t = soap->tmpbuf + 6;
8030
 
      }
8031
 
      else if (soap->tmpbuf[5])
8032
 
        t = NULL;
8033
 
      else
8034
 
        t = SOAP_STR_EOS;
8035
 
    }
8036
 
    else
8037
 
      t = NULL;
8038
 
    tq = NULL;
8039
 
    for (tp = soap->attributes; tp; tq = tp, tp = tp->next)
8040
 
    { if (!SOAP_STRCMP(tp->name, soap->tmpbuf))
8041
 
        break;
8042
 
    }
8043
 
    if (!tp)
8044
 
    { tp = (struct soap_attribute*)SOAP_MALLOC(soap, sizeof(struct soap_attribute) + strlen(soap->tmpbuf));
8045
 
      if (!tp)
8046
 
        return soap->error = SOAP_EOM;
8047
 
      strcpy(tp->name, soap->tmpbuf);
8048
 
      tp->value = NULL;
8049
 
      tp->size = 0;
8050
 
      /* if attribute name is qualified, append it to the list */
8051
 
      if (tq && strchr(soap->tmpbuf, ':'))
8052
 
      { tq->next = tp;
8053
 
        tp->next = NULL;
8054
 
      }
8055
 
      else
8056
 
      { tp->next = soap->attributes;
8057
 
        soap->attributes = tp;
8058
 
      }
8059
 
    }
8060
 
    while (soap_blank(c))
8061
 
      c = soap_get1(soap);
8062
 
    if (c == '=')
8063
 
    { do c = soap_getutf8(soap);
8064
 
      while (soap_blank(c));
8065
 
      if (c != SOAP_QT && c != SOAP_AP)
8066
 
      { soap_unget(soap, c);
8067
 
        c = ' '; /* blank delimiter */
8068
 
      }
8069
 
      if (soap_getattrval(soap, tp->value, tp->size, c))
8070
 
      {
8071
 
#ifdef WITH_FAST
8072
 
        if (soap->error != SOAP_EOM)
8073
 
          return soap->error;
8074
 
        soap->error = SOAP_OK;
8075
 
        if (soap_store_lab(soap, tp->value, tp->size))
8076
 
          return soap->error;
8077
 
        if (tp->value)
8078
 
          SOAP_FREE(soap, tp->value);
8079
 
        for (;;)
8080
 
        { if (soap_getattrval(soap, soap->labbuf + soap->labidx, soap->lablen - soap->labidx, c))
8081
 
          { if (soap->error != SOAP_EOM)
8082
 
              return soap->error;
8083
 
            soap->error = SOAP_OK;
8084
 
            soap->labidx = soap->lablen;
8085
 
            if (soap_append_lab(soap, NULL, 0))
8086
 
              return soap->error;
8087
 
          }
8088
 
          else
8089
 
            break;
8090
 
        }
8091
 
        if (soap->labidx)
8092
 
          tp->size = soap->lablen;
8093
 
        else
8094
 
        { tp->size = strlen(soap->labbuf) + 1;
8095
 
          if (tp->size < SOAP_LABLEN)
8096
 
            tp->size = SOAP_LABLEN;
8097
 
        }
8098
 
        if (!(tp->value = (char*)SOAP_MALLOC(soap, tp->size)))
8099
 
          return soap->error = SOAP_EOM;
8100
 
        strcpy(tp->value, soap->labbuf);
8101
 
#else
8102
 
        size_t n;
8103
 
        if (soap->error != SOAP_EOM)
8104
 
          return soap->error;
8105
 
        soap->error = SOAP_OK;
8106
 
        if (soap_new_block(soap))
8107
 
          return soap->error;
8108
 
        for (;;)
8109
 
        { if (!(s = (char*)soap_push_block(soap, SOAP_BLKLEN)))
8110
 
            return soap->error;
8111
 
          if (soap_getattrval(soap, s, SOAP_BLKLEN, c))
8112
 
          { if (soap->error != SOAP_EOM)
8113
 
              return soap->error;
8114
 
            soap->error = SOAP_OK;
8115
 
          }
8116
 
          else
8117
 
            break;
8118
 
        }
8119
 
        n = tp->size + soap->blist->size;
8120
 
        if (!(s = (char*)SOAP_MALLOC(soap, n)))
8121
 
          return soap->error = SOAP_EOM;
8122
 
        if (tp->value)
8123
 
        { memcpy(s, tp->value, tp->size);
8124
 
          SOAP_FREE(soap, tp->value);
8125
 
        }
8126
 
        soap_save_block(soap, s + tp->size, 0);
8127
 
        tp->value = s;
8128
 
        tp->size = n;
8129
 
#endif
8130
 
      }
8131
 
      do c = soap_get1(soap);
8132
 
      while (soap_blank(c));
8133
 
      tp->visible = 2; /* seen this attribute w/ value */
8134
 
#ifdef WITH_DOM
8135
 
      if (att)
8136
 
        (*att)->data = soap_strdup(soap, tp->value);
8137
 
#endif
8138
 
    }
8139
 
    else
8140
 
      tp->visible = 1; /* seen this attribute w/o value */
8141
 
#ifdef WITH_DOM
8142
 
    if (att)
8143
 
      att = &(*att)->next;
8144
 
#endif
8145
 
    if (t && tp->value)
8146
 
    { if (soap_push_namespace(soap, t, tp->value))
8147
 
        return soap->error;
8148
 
      tp->visible = 0;
8149
 
    }
8150
 
  }
8151
 
#ifdef WITH_DOM
8152
 
  if (att)
8153
 
  { soap->dom->nstr = soap_current_namespace(soap, soap->tag);
8154
 
    for (att = &soap->dom->atts; *att; att = &(*att)->next)
8155
 
      (*att)->nstr = soap_current_namespace(soap, (*att)->name);
8156
 
  }
8157
 
#endif
8158
 
  if ((int)c == EOF)
8159
 
    return soap->error = SOAP_EOF;
8160
 
  if (!(soap->body = (c != '/')))
8161
 
    do c = soap_get1(soap);
8162
 
    while (soap_blank(c));
8163
 
#ifdef WITH_DOM
8164
 
  if (soap->mode & SOAP_XML_DOM)
8165
 
  { if (!soap->body && soap->dom->prnt)
8166
 
      soap->dom = soap->dom->prnt;
8167
 
  }
8168
 
#endif
8169
 
  for (tp = soap->attributes; tp; tp = tp->next)
8170
 
  { if (tp->visible && tp->value)
8171
 
    { 
8172
 
#ifndef WITH_NOIDREF
8173
 
      if (!strcmp(tp->name, "id"))
8174
 
      { if (soap->version > 0
8175
 
         || (soap->mode & SOAP_XML_GRAPH))
8176
 
        { *soap->id = '#';
8177
 
          strncpy(soap->id + 1, tp->value, sizeof(soap->id) - 2);
8178
 
          soap->id[sizeof(soap->id)-1] = '\0';
8179
 
        }
8180
 
      }
8181
 
      else if (!strcmp(tp->name, "href"))
8182
 
      { if (soap->version == 1
8183
 
         || (soap->mode & SOAP_XML_GRAPH)
8184
 
         || (soap->mode & SOAP_ENC_MTOM))
8185
 
        { strncpy(soap->href, tp->value, sizeof(soap->href) - 1);
8186
 
          soap->href[sizeof(soap->href)-1] = '\0';
8187
 
        }
8188
 
      }
8189
 
      else
8190
 
#endif
8191
 
      if (!soap_match_tag(soap, tp->name, "xsi:type"))
8192
 
      { strncpy(soap->type, tp->value, sizeof(soap->type) - 1);
8193
 
        soap->type[sizeof(soap->type)-1] = '\0';
8194
 
      }
8195
 
      else if ((!soap_match_tag(soap, tp->name, "xsi:null")
8196
 
             || !soap_match_tag(soap, tp->name, "xsi:nil"))
8197
 
            && (!strcmp(tp->value, "1")
8198
 
             || !strcmp(tp->value, "true")))
8199
 
      { soap->null = 1;
8200
 
      }
8201
 
      else if (soap->version == 1)
8202
 
      { if (!soap_match_tag(soap, tp->name, "SOAP-ENC:arrayType"))
8203
 
        { s = soap_strrchr(tp->value, '[');
8204
 
          if (s && (size_t)(s - tp->value) < sizeof(soap->arrayType))
8205
 
          { strncpy(soap->arrayType, tp->value, s - tp->value);
8206
 
            soap->arrayType[s - tp->value] = '\0';
8207
 
            strncpy(soap->arraySize, s, sizeof(soap->arraySize) - 1);
8208
 
          }
8209
 
          else
8210
 
            strncpy(soap->arrayType, tp->value, sizeof(soap->arrayType) - 1);
8211
 
          soap->arraySize[sizeof(soap->arrayType)-1] = '\0';
8212
 
          soap->arrayType[sizeof(soap->arrayType)-1] = '\0';
8213
 
        }
8214
 
        else if (!soap_match_tag(soap, tp->name, "SOAP-ENC:offset"))
8215
 
          strncpy(soap->arrayOffset, tp->value, sizeof(soap->arrayOffset));
8216
 
        else if (!soap_match_tag(soap, tp->name, "SOAP-ENC:position"))
8217
 
          soap->position = soap_getposition(tp->value, soap->positions);
8218
 
        else if (!soap_match_tag(soap, tp->name, "SOAP-ENC:root"))
8219
 
          soap->root = ((!strcmp(tp->value, "1") || !strcmp(tp->value, "true")));
8220
 
        else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:mustUnderstand")
8221
 
              && (!strcmp(tp->value, "1") || !strcmp(tp->value, "true")))
8222
 
          soap->mustUnderstand = 1;
8223
 
        else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:actor"))
8224
 
        { if ((!soap->actor || strcmp(soap->actor, tp->value))
8225
 
           && strcmp(tp->value, "http://schemas.xmlsoap.org/soap/actor/next"))
8226
 
            soap->other = 1;
8227
 
        }
8228
 
      }
8229
 
      else if (soap->version == 2)
8230
 
      { if (!strcmp(tp->name, "ref")
8231
 
         || !soap_match_tag(soap, tp->name, "SOAP-ENC:ref"))
8232
 
        { *soap->href = '#';
8233
 
          strncpy(soap->href + 1, tp->value, sizeof(soap->href) - 2);
8234
 
          soap->href[sizeof(soap->href)-1] = '\0';
8235
 
        }
8236
 
        else if (!soap_match_tag(soap, tp->name, "SOAP-ENC:itemType"))
8237
 
          strncpy(soap->arrayType, tp->value, sizeof(soap->arrayType) - 1);
8238
 
        else if (!soap_match_tag(soap, tp->name, "SOAP-ENC:arraySize"))
8239
 
          strncpy(soap->arraySize, tp->value, sizeof(soap->arraySize) - 1);
8240
 
        else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:mustUnderstand")
8241
 
              && (!strcmp(tp->value, "1") || !strcmp(tp->value, "true")))
8242
 
          soap->mustUnderstand = 1;
8243
 
        else if (!soap_match_tag(soap, tp->name, "SOAP-ENV:role"))
8244
 
        { if ((!soap->actor || strcmp(soap->actor, tp->value))
8245
 
           && strcmp(tp->value, "http://www.w3.org/2003/05/soap-envelope/role/next"))
8246
 
            soap->other = 1;
8247
 
        }
8248
 
      }
8249
 
    }
8250
 
  }
8251
 
  return soap->error = SOAP_OK;
8252
 
}
8253
 
#endif
8254
 
 
8255
 
/******************************************************************************/
8256
 
#ifndef PALM_2
8257
 
SOAP_FMAC1
8258
 
void
8259
 
SOAP_FMAC2
8260
 
soap_retry(struct soap *soap)
8261
 
{ soap->error = SOAP_OK;
8262
 
  soap_revert(soap);
8263
 
}
8264
 
#endif
8265
 
 
8266
 
/******************************************************************************/
8267
 
#ifndef PALM_2
8268
 
SOAP_FMAC1
8269
 
void
8270
 
SOAP_FMAC2
8271
 
soap_revert(struct soap *soap)
8272
 
{ if (!soap->peeked)
8273
 
  { soap->peeked = 1;
8274
 
    if (soap->body)
8275
 
      soap->level--;
8276
 
  }
8277
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Reverting last element (level=%u)\n", soap->level));
8278
 
}
8279
 
#endif
8280
 
 
8281
 
/******************************************************************************/
8282
 
#ifndef PALM_2
8283
 
SOAP_FMAC1
8284
 
int
8285
 
SOAP_FMAC2
8286
 
soap_string_out(struct soap *soap, const char *s, int flag)
8287
 
{ register const char *t;
8288
 
  register soap_wchar c;
8289
 
  register soap_wchar mask = 0xFFFFFF80UL;
8290
 
#ifdef WITH_DOM
8291
 
  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
8292
 
  { soap->dom->data = soap_strdup(soap, s);
8293
 
    return SOAP_OK;
8294
 
  }
8295
 
#endif
8296
 
  if (soap->mode & SOAP_C_UTFSTRING)
8297
 
    mask = 0;
8298
 
  t = s;
8299
 
  while ((c = *t++))
8300
 
  { switch (c)
8301
 
    { 
8302
 
    case 0x09:
8303
 
      if (flag)
8304
 
      { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&#x9;", 5))
8305
 
          return soap->error;
8306
 
        s = t;
8307
 
      }
8308
 
      break;
8309
 
    case 0x0A:
8310
 
      if (flag || !(soap->mode & SOAP_XML_CANONICAL))
8311
 
      { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&#xA;", 5))
8312
 
          return soap->error;
8313
 
        s = t;
8314
 
      }
8315
 
      break;
8316
 
    case 0x0D:
8317
 
      if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&#xD;", 5))
8318
 
        return soap->error;
8319
 
      s = t;
8320
 
      break;
8321
 
    case '&':
8322
 
      if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&amp;", 5))
8323
 
        return soap->error;
8324
 
      s = t;
8325
 
      break;
8326
 
    case '<':
8327
 
      if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&lt;", 4))
8328
 
        return soap->error;
8329
 
      s = t;
8330
 
      break;
8331
 
    case '>':
8332
 
      if (!flag)
8333
 
      { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&gt;", 4))
8334
 
          return soap->error;
8335
 
        s = t;
8336
 
      }
8337
 
      break;
8338
 
    case '"':
8339
 
      if (flag)
8340
 
      { if (soap_send_raw(soap, s, t - s - 1) || soap_send_raw(soap, "&quot;", 6))
8341
 
          return soap->error;
8342
 
        s = t;
8343
 
      }
8344
 
      break;
8345
 
    default:
8346
 
#ifndef WITH_LEANER
8347
 
#ifdef HAVE_MBTOWC
8348
 
      if (soap->mode & SOAP_C_MBSTRING)
8349
 
      { wchar_t wc;
8350
 
        register int m = mbtowc(&wc, t - 1, MB_CUR_MAX);
8351
 
        if (m > 0 && wc != c)
8352
 
        { if (soap_send_raw(soap, s, t - s - 1) || soap_pututf8(soap, wc))
8353
 
            return soap->error;
8354
 
          s = t += m - 1;
8355
 
          continue;
8356
 
        }
8357
 
      }
8358
 
#endif
8359
 
#endif
8360
 
      if ((c & mask) || !(c & 0xFFFFFFE0UL))
8361
 
      { if (soap_send_raw(soap, s, t - s - 1) || soap_pututf8(soap, (unsigned char)c))
8362
 
          return soap->error;
8363
 
        s = t;
8364
 
      }
8365
 
    }
8366
 
  }
8367
 
  return soap_send_raw(soap, s, t - s - 1);
8368
 
}
8369
 
#endif
8370
 
 
8371
 
/******************************************************************************/
8372
 
#ifndef PALM_2
8373
 
SOAP_FMAC1
8374
 
char *
8375
 
SOAP_FMAC2
8376
 
soap_string_in(struct soap *soap, int flag, long minlen, long maxlen)
8377
 
{ register char *s;
8378
 
  char *t = NULL;
8379
 
  register size_t i;
8380
 
  register long l = 0;
8381
 
  register int n = 0;
8382
 
  register int m = 0;
8383
 
  register soap_wchar c;
8384
 
#if !defined(WITH_LEANER) && defined(HAVE_WCTOMB)
8385
 
  char buf[MB_LEN_MAX > 8 ? MB_LEN_MAX : 8];
8386
 
#else
8387
 
  char buf[8];
8388
 
#endif
8389
 
  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Reading string content\n"));
8390
 
  if (soap->peeked)
8391
 
  { if (!soap->body)
8392
 
      return NULL;
8393
 
    if (*soap->tag)
8394
 
    {
8395
 
#ifndef WITH_LEAN
8396
 
      struct soap_attribute *tp;
8397
 
      t = soap->tmpbuf;
8398
 
      *t = '<';
8399
 
      t[sizeof(soap->tmpbuf)-1] = '\0';
8400
 
      strncpy(t + 1, soap->tag, sizeof(soap->tmpbuf) - 2);
8401
 
      t += strlen(t);
8402
 
      for (tp = soap->attributes; tp; tp = tp->next)
8403
 
      { if (tp->visible)
8404
 
        { if (t >= soap->tmpbuf + sizeof(soap->tmpbuf) - 2)
8405
 
            break;
8406
 
          *t++ = ' ';
8407
 
          strcpy(t, tp->name);
8408
 
          t += strlen(t);
8409
 
          if (t >= soap->tmpbuf + sizeof(soap->tmpbuf) - 2)
8410
 
            break;
8411
 
          if (tp->value)
8412
 
          { *t++ = '=';
8413
 
            *t++ = '"';
8414
 
            strcpy(t, tp->value);
8415
 
            t += strlen(t);
8416
 
            *t++ = '"';
8417
 
          }
8418
 
        }
8419
 
      }
8420
 
      *t++ = '>';
8421
 
      *t = '\0';
8422
 
      t = soap->tmpbuf;
8423
 
      m = (int)strlen(soap->tmpbuf);
8424
 
#endif
8425
 
      n = 1;
8426
 
      soap->peeked = 0;
8427
 
    }
8428
 
  }
8429
 
#ifdef WITH_CDATA
8430
 
  if (!flag)
8431
 
  { register int state = 0;
8432
 
#ifdef WITH_FAST
8433
 
    soap->labidx = 0;                   /* use look-aside buffer */
8434
 
#else
8435
 
    if (soap_new_block(soap))
8436
 
      return NULL;
8437
 
#endif
8438
 
    for (;;)
8439
 
    { 
8440
 
#ifdef WITH_FAST
8441
 
      register size_t k;
8442
 
      if (soap_append_lab(soap, NULL, 0))       /* allocate more space in look-aside buffer if necessary */
8443
 
        return NULL;
8444
 
      s = soap->labbuf + soap->labidx;  /* space to populate */
8445
 
      k = soap->lablen - soap->labidx;  /* number of bytes available */
8446
 
      soap->labidx = soap->lablen;      /* claim this space */
8447
 
#else
8448
 
      register size_t k = SOAP_BLKLEN;
8449
 
      if (!(s = (char*)soap_push_block(soap, k)))
8450
 
        return NULL;
8451
 
#endif
8452
 
      for (i = 0; i < k; i++)
8453
 
      { if (m > 0)
8454
 
        { *s++ = *t++;  /* copy multibyte characters */
8455
 
          m--;
8456
 
          continue;
8457
 
        }
8458
 
        c = soap_getchar(soap);
8459
 
        if ((int)c == EOF)
8460
 
          goto end;
8461
 
        if (c >= 0x80 && !(soap->mode & SOAP_ENC_LATIN))
8462
 
        { soap_unget(soap, c);
8463
 
          c = soap_getutf8(soap);
8464
 
          if (soap->mode & SOAP_C_UTFSTRING)
8465
 
          { if ((c & 0x80000000) && c >= -0x7FFFFF80 && c < SOAP_AP)
8466
 
            { c &= 0x7FFFFFFF;
8467
 
              t = buf;
8468
 
              if (c < 0x0800)
8469
 
                *t++ = (char)(0xC0 | ((c >> 6) & 0x1F));
8470
 
              else
8471
 
              { if (c < 0x010000)
8472
 
                  *t++ = (char)(0xE0 | ((c >> 12) & 0x0F));
8473
 
                else
8474
 
                { if (c < 0x200000)
8475
 
                    *t++ = (char)(0xF0 | ((c >> 18) & 0x07));
8476
 
                  else
8477
 
                  { if (c < 0x04000000)
8478
 
                      *t++ = (char)(0xF8 | ((c >> 24) & 0x03));
8479
 
                    else
8480
 
                    { *t++ = (char)(0xFC | ((c >> 30) & 0x01));
8481
 
                      *t++ = (char)(0x80 | ((c >> 24) & 0x3F));
8482
 
                    }
8483
 
                    *t++ = (char)(0x80 | ((c >> 18) & 0x3F));
8484
 
                  }     
8485
 
                  *t++ = (char)(0x80 | ((c >> 12) & 0x3F));
8486
 
                }
8487
 
                *t++ = (char)(0x80 | ((c >> 6) & 0x3F));
8488
 
              }
8489
 
              *t++ = (char)(0x80 | (c & 0x3F));
8490
 
              m = (int)(t - buf) - 1;
8491
 
              t = buf;
8492
 
              *s++ = *t++;
8493
 
              continue;
8494
 
            }
8495
 
          }
8496
 
        }
8497
 
        switch (state)
8498
 
        { case 1:
8499
 
            if (c == ']')
8500
 
              state = 4;
8501
 
            *s++ = c;
8502
 
            continue;
8503
 
          case 2:
8504
 
            if (c == '-')
8505
 
              state = 6;
8506
 
            *s++ = c;
8507
 
            continue;
8508
 
          case 3:
8509
 
            if (c == '?')
8510
 
              state = 8;
8511
 
            *s++ = c;
8512
 
            continue;
8513
 
          /* CDATA */
8514
 
          case 4:
8515
 
            if (c == ']')
8516
 
              state = 5;
8517
 
            else
8518
 
              state = 1;
8519
 
            *s++ = c;
8520
 
            continue;
8521
 
          case 5:
8522
 
            if (c == '>')
8523
 
              state = 0;
8524
 
            else
8525
 
              state = 1;
8526
 
            *s++ = c;
8527
 
            continue;
8528
 
          /* comment */
8529
 
          case 6:
8530
 
            if (c == '-')
8531
 
              state = 7;
8532
 
            else
8533
 
              state = 2;
8534
 
            *s++ = c;
8535
 
            continue;
8536
 
          case 7:
8537
 
            if (c == '>')
8538
 
              state = 0;
8539
 
            else
8540
 
              state = 2;
8541
 
            *s++ = c;
8542
 
            continue;
8543
 
          /* PI */
8544
 
          case 8:
8545
 
            if (c == '>')
8546
 
              state = 0;
8547
 
            else
8548
 
              state = 3;
8549
 
            *s++ = c;
8550
 
            continue;
8551
 
        }
8552
 
        switch (c)
8553
 
        {
8554
 
        case '/':
8555
 
          if (n > 0)
8556
 
          { c = soap_getchar(soap);
8557
 
            if (c == '>')
8558
 
              n--;
8559
 
            soap_unget(soap, c);
8560
 
          }
8561
 
          *s++ = '/';
8562
 
          break;
8563
 
        case '<':
8564
 
          c = soap_getchar(soap);
8565
 
          if (c == '/')
8566
 
          { if (n == 0)
8567
 
            { c = SOAP_TT;
8568
 
              goto end;
8569
 
            }
8570
 
            n--;
8571
 
          }
8572
 
          else if (c == '!')
8573
 
          { c = soap_getchar(soap);
8574
 
            if (c == '[')
8575
 
            { do c = soap_getchar(soap);
8576
 
              while ((int)c != EOF && c != '[');
8577
 
              if ((int)c == EOF)
8578
 
                 goto end;
8579
 
              t = (char*)"![CDATA[";
8580
 
              m = 8;
8581
 
              state = 1;
8582
 
            }
8583
 
            else if (c == '-')
8584
 
            { if ((c = soap_getchar(soap)) == '-')
8585
 
                state = 2;
8586
 
              t = (char*)"!-";
8587
 
              m = 2;
8588
 
              soap_unget(soap, c);
8589
 
            }
8590
 
            else
8591
 
            { t = (char*)"!";
8592
 
              m = 1;
8593
 
              soap_unget(soap, c);
8594
 
            }
8595
 
            *s++ = '<';
8596
 
            break;
8597
 
          }
8598
 
          else if (c == '?')
8599
 
            state = 3;
8600
 
          else
8601
 
            n++;
8602
 
          soap_unget(soap, c);
8603
 
          *s++ = '<';
8604
 
          break;
8605
 
        case '>':
8606
 
          *s++ = '>';
8607
 
          break;
8608
 
        case '"':
8609
 
          *s++ = '"';
8610
 
          break;
8611
 
        default:
8612
 
#ifndef WITH_LEANER
8613
 
#ifdef HAVE_WCTOMB
8614
 
          if (soap->mode & SOAP_C_MBSTRING)
8615
 
          { m = wctomb(buf, c & 0x7FFFFFFF);
8616
 
            if (m >= 1 && m <= (int)MB_CUR_MAX)
8617
 
            { t = buf;
8618
 
              *s++ = *t++;
8619
 
              m--;
8620
 
            }
8621
 
            else
8622
 
            { *s++ = SOAP_UNKNOWN_CHAR;
8623
 
              m = 0;
8624
 
            }
8625
 
          }
8626
 
          else
8627
 
#endif
8628
 
#endif
8629
 
            *s++ = (char)(c & 0xFF);
8630
 
        }
8631
 
        l++;
8632
 
        if ((soap->mode & SOAP_XML_STRICT) && maxlen >= 0 && l > maxlen)
8633
 
        { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen));
8634
 
          soap->error = SOAP_LENGTH;
8635
 
          return NULL;
8636
 
        }
8637
 
      }
8638
 
    }
8639
 
  }
8640
 
#endif
8641
 
#ifdef WITH_FAST
8642
 
  soap->labidx = 0;                     /* use look-aside buffer */
8643
 
#else
8644
 
  if (soap_new_block(soap))
8645
 
    return NULL;
8646
 
#endif
8647
 
  for (;;)
8648
 
  { 
8649
 
#ifdef WITH_FAST
8650
 
    register size_t k;
8651
 
    if (soap_append_lab(soap, NULL, 0)) /* allocate more space in look-aside buffer if necessary */
8652
 
      return NULL;
8653
 
    s = soap->labbuf + soap->labidx;    /* space to populate */
8654
 
    k = soap->lablen - soap->labidx;    /* number of bytes available */
8655
 
    soap->labidx = soap->lablen;        /* claim this space */
8656
 
#else
8657
 
    register size_t k = SOAP_BLKLEN;
8658
 
    if (!(s = (char*)soap_push_block(soap, k)))
8659
 
      return NULL;
8660
 
#endif
8661
 
    for (i = 0; i < k; i++)
8662
 
    { if (m > 0)
8663
 
      { *s++ = *t++;    /* copy multibyte characters */
8664
 
        m--;
8665
 
        continue;
8666
 
      }
8667
 
      if (soap->mode & SOAP_C_UTFSTRING)
8668
 
      { if (((c = soap_get(soap)) & 0x80000000) && c >= -0x7FFFFF80 && c < SOAP_AP)
8669
 
        { c &= 0x7FFFFFFF;
8670
 
          t = buf;
8671
 
          if (c < 0x0800)
8672
 
            *t++ = (char)(0xC0 | ((c >> 6) & 0x1F));
8673
 
          else
8674
 
          { if (c < 0x010000)
8675
 
              *t++ = (char)(0xE0 | ((c >> 12) & 0x0F));
8676
 
            else
8677
 
            { if (c < 0x200000)
8678
 
                *t++ = (char)(0xF0 | ((c >> 18) & 0x07));
8679
 
              else
8680
 
              { if (c < 0x04000000)
8681
 
                  *t++ = (char)(0xF8 | ((c >> 24) & 0x03));
8682
 
                else
8683
 
                { *t++ = (char)(0xFC | ((c >> 30) & 0x01));
8684
 
                  *t++ = (char)(0x80 | ((c >> 24) & 0x3F));
8685
 
                }
8686
 
                *t++ = (char)(0x80 | ((c >> 18) & 0x3F));
8687
 
              }     
8688
 
              *t++ = (char)(0x80 | ((c >> 12) & 0x3F));
8689
 
            }
8690
 
            *t++ = (char)(0x80 | ((c >> 6) & 0x3F));
8691
 
          }
8692
 
          *t++ = (char)(0x80 | (c & 0x3F));
8693
 
          m = (int)(t - buf) - 1;
8694
 
          t = buf;
8695
 
          *s++ = *t++;
8696
 
          continue;
8697
 
        }
8698
 
      }
8699
 
      else
8700
 
        c = soap_getutf8(soap);
8701
 
      switch (c)
8702
 
      {
8703
 
      case SOAP_TT:
8704
 
        if (n == 0)
8705
 
          goto end;
8706
 
        n--;
8707
 
        *s++ = '<';
8708
 
        t = (char*)"/";
8709
 
        m = 1;
8710
 
        break;
8711
 
      case SOAP_LT:
8712
 
        n++;
8713
 
        *s++ = '<';
8714
 
        break;
8715
 
      case SOAP_GT:
8716
 
        *s++ = '>';
8717
 
        break;
8718
 
      case SOAP_QT:
8719
 
        *s++ = '"';
8720
 
        break;
8721
 
      case SOAP_AP:
8722
 
        *s++ = '\'';
8723
 
        break;
8724
 
      case '/':
8725
 
        if (n > 0)
8726
 
        { c = soap_get(soap);
8727
 
          if (c == SOAP_GT)
8728
 
            n--;
8729
 
          soap_unget(soap, c);
8730
 
        }
8731
 
        *s++ = '/';
8732
 
        break;
8733
 
      case (soap_wchar)('<' | 0x80000000):
8734
 
        if (flag)
8735
 
          *s++ = '<';
8736
 
        else
8737
 
        { *s++ = '&';
8738
 
          t = (char*)"lt;";
8739
 
          m = 3;
8740
 
        }
8741
 
        break;
8742
 
      case (soap_wchar)('>' | 0x80000000):
8743
 
        if (flag)
8744
 
          *s++ = '>';
8745
 
        else
8746
 
        { *s++ = '&';
8747
 
          t = (char*)"gt;";
8748
 
          m = 3;
8749
 
        }
8750
 
        break;
8751
 
      case (soap_wchar)('&' | 0x80000000):
8752
 
        if (flag)
8753
 
          *s++ = '&';
8754
 
        else
8755
 
        { *s++ = '&';
8756
 
          t = (char*)"amp;";
8757
 
          m = 4;
8758
 
        }
8759
 
        break;
8760
 
      case (soap_wchar)('"' | 0x80000000):
8761
 
        if (flag)
8762
 
          *s++ = '"';
8763
 
        else
8764
 
        { *s++ = '&';
8765
 
          t = (char*)"quot;";
8766
 
          m = 5;
8767
 
        }
8768
 
        break;
8769
 
      case (soap_wchar)('\'' | 0x80000000):
8770
 
        if (flag)
8771
 
          *s++ = '\'';
8772
 
        else
8773
 
        { *s++ = '&';
8774
 
          t = (char*)"apos;";
8775
 
          m = 5;
8776
 
        }
8777
 
        break;
8778
 
      default:
8779
 
        if ((int)c == EOF)
8780
 
          goto end;
8781
 
#ifndef WITH_LEANER
8782
 
#ifdef HAVE_WCTOMB
8783
 
        if (soap->mode & SOAP_C_MBSTRING)
8784
 
        { m = wctomb(buf, c & 0x7FFFFFFF);
8785
 
          if (m >= 1 && m <= (int)MB_CUR_MAX)
8786
 
          { t = buf;
8787
 
            *s++ = *t++;
8788
 
            m--;
8789
 
          }
8790
 
          else
8791
 
          { *s++ = SOAP_UNKNOWN_CHAR;
8792
 
            m = 0;
8793
 
          }
8794
 
        }
8795
 
        else
8796
 
#endif
8797
 
#endif
8798
 
          *s++ = (char)(c & 0xFF);
8799
 
      }
8800
 
      l++;
8801
 
      if ((soap->mode & SOAP_XML_STRICT) && maxlen >= 0 && l > maxlen)
8802
 
      { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen));
8803
 
        soap->error = SOAP_LENGTH;
8804
 
        return NULL;
8805
 
      }
8806
 
    }
8807
 
  }
8808
 
end:
8809
 
  soap_unget(soap, c);
8810
 
  *s = '\0';
8811
 
#ifdef WITH_FAST
8812
 
  t = soap_strdup(soap, soap->labbuf);
8813
 
#else
8814
 
  soap_size_block(soap, i+1);
8815
 
  t = soap_save_block(soap, NULL, 0);
8816
 
#endif
8817
 
  if ((soap->mode & SOAP_XML_STRICT) && l < minlen)
8818
 
  { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too short: %ld chars, minlen=%ld\n", l, minlen));
8819
 
    soap->error = SOAP_LENGTH;
8820
 
    return NULL;
8821
 
  }
8822
 
#ifdef WITH_DOM
8823
 
  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
8824
 
  { if (flag == 3)
8825
 
      soap->dom->tail = t;
8826
 
    else
8827
 
      soap->dom->data = t;
8828
 
  }
8829
 
#endif
8830
 
  if (flag == 2)
8831
 
    if (soap_s2QName(soap, t, &t))
8832
 
      return NULL;
8833
 
  return t;
8834
 
}
8835
 
#endif
8836
 
 
8837
 
/******************************************************************************/
8838
 
#ifndef WITH_LEANER
8839
 
#ifndef PALM_2
8840
 
SOAP_FMAC1
8841
 
int
8842
 
SOAP_FMAC2
8843
 
soap_wstring_out(struct soap *soap, const wchar_t *s, int flag)
8844
 
{ const char *t;
8845
 
  char tmp;
8846
 
  register soap_wchar c;
8847
 
#ifdef WITH_DOM
8848
 
  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
8849
 
  { wchar_t *r = (wchar_t*)s;
8850
 
    int n = 1;
8851
 
    while (*r++)
8852
 
      n++;
8853
 
    soap->dom->wide = r = (wchar_t*)soap_malloc(soap, n * sizeof(wchar_t));
8854
 
    while (n--)
8855
 
      *r++ = *s++;
8856
 
    return SOAP_OK;
8857
 
  }
8858
 
#endif
8859
 
  while ((c = *s++))
8860
 
  { switch (c)
8861
 
    { 
8862
 
    case 0x09:
8863
 
      if (flag)
8864
 
        t = "&#x9;";
8865
 
      else
8866
 
        t = "\t";
8867
 
      break;
8868
 
    case 0x0A:
8869
 
      if (flag || !(soap->mode & SOAP_XML_CANONICAL))
8870
 
        t = "&#xA;";
8871
 
      else
8872
 
        t = "\n";
8873
 
      break;
8874
 
    case 0x0D:
8875
 
      t = "&#xD;";
8876
 
      break;
8877
 
    case '&':
8878
 
      t = "&amp;";
8879
 
      break;
8880
 
    case '<':
8881
 
      t = "&lt;";
8882
 
      break;
8883
 
    case '>':
8884
 
      if (flag)
8885
 
        t = ">";
8886
 
      else
8887
 
        t = "&gt;";
8888
 
      break;
8889
 
    case '"':
8890
 
      if (flag)
8891
 
        t = "&quot;";
8892
 
      else
8893
 
        t = "\"";
8894
 
      break;
8895
 
    default:
8896
 
      if (c >= 0x20 && c < 0x80)
8897
 
      { tmp = (char)c;
8898
 
        if (soap_send_raw(soap, &tmp, 1))
8899
 
          return soap->error;
8900
 
      }
8901
 
      else if (soap_pututf8(soap, (unsigned long)c))
8902
 
        return soap->error;
8903
 
      continue;
8904
 
    }
8905
 
    if (soap_send(soap, t))
8906
 
      return soap->error;
8907
 
  }
8908
 
  return SOAP_OK;
8909
 
}
8910
 
#endif
8911
 
#endif
8912
 
 
8913
 
/******************************************************************************/
8914
 
#ifndef WITH_LEANER
8915
 
#ifndef PALM_2
8916
 
SOAP_FMAC1
8917
 
wchar_t *
8918
 
SOAP_FMAC2
8919
 
soap_wstring_in(struct soap *soap, int flag, long minlen, long maxlen)
8920
 
{ wchar_t *s;
8921
 
  register int i, n = 0;
8922
 
  register long l = 0;
8923
 
  register soap_wchar c;
8924
 
  char *t = NULL;
8925
 
  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Reading wide string content\n"));
8926
 
  if (soap->peeked)
8927
 
  { if (!soap->body)
8928
 
      return NULL;
8929
 
    if (*soap->tag)
8930
 
    {
8931
 
#ifndef WITH_LEAN
8932
 
      struct soap_attribute *tp;
8933
 
      t = soap->tmpbuf;
8934
 
      *t = '<';
8935
 
      t[sizeof(soap->tmpbuf)-1] = '\0';
8936
 
      strncpy(t + 1, soap->tag, sizeof(soap->tmpbuf) - 2);
8937
 
      t += strlen(t);
8938
 
      for (tp = soap->attributes; tp; tp = tp->next)
8939
 
      { if (tp->visible)
8940
 
        { if (t >= soap->tmpbuf + sizeof(soap->tmpbuf) - 2)
8941
 
            break;
8942
 
          *t++ = ' ';
8943
 
          strcpy(t, tp->name);
8944
 
          t += strlen(t);
8945
 
          if (t >= soap->tmpbuf + sizeof(soap->tmpbuf) - 2)
8946
 
            break;
8947
 
          if (tp->value)
8948
 
          { *t++ = '=';
8949
 
            *t++ = '"';
8950
 
            strcpy(t, tp->value);
8951
 
            t += strlen(t);
8952
 
            *t++ = '"';
8953
 
          }
8954
 
        }
8955
 
      }
8956
 
      *t++ = '>';
8957
 
      *t = '\0';
8958
 
      t = soap->tmpbuf;
8959
 
#endif
8960
 
      n = 1;
8961
 
      soap->peeked = 0;
8962
 
    }
8963
 
  }
8964
 
  if (soap_new_block(soap))
8965
 
    return NULL;
8966
 
  for (;;)
8967
 
  { if (!(s = (wchar_t*)soap_push_block(soap, sizeof(wchar_t)*SOAP_BLKLEN)))
8968
 
      return NULL;
8969
 
    for (i = 0; i < SOAP_BLKLEN; i++)
8970
 
    { if (t)
8971
 
      { *s++ = (wchar_t)*t++;
8972
 
        if (!*t)
8973
 
          t = NULL;
8974
 
        continue;
8975
 
      }
8976
 
      c = soap_getutf8(soap);
8977
 
      switch (c)
8978
 
      {
8979
 
      case SOAP_TT:
8980
 
        if (n == 0)
8981
 
          goto end;
8982
 
        n--;
8983
 
        *s++ = '<';
8984
 
        soap_unget(soap, '/');
8985
 
        break;
8986
 
      case SOAP_LT:
8987
 
        n++;
8988
 
        *s++ = '<';
8989
 
        break;
8990
 
      case SOAP_GT:
8991
 
        *s++ = '>';
8992
 
        break;
8993
 
      case SOAP_QT:
8994
 
        *s++ = '"';
8995
 
        break;
8996
 
      case SOAP_AP:
8997
 
        *s++ = '\'';
8998
 
        break;
8999
 
      case '/':
9000
 
        if (n > 0)
9001
 
        { c = soap_getutf8(soap);
9002
 
          if (c == SOAP_GT)
9003
 
            n--;
9004
 
          soap_unget(soap, c);
9005
 
        }
9006
 
        *s++ = '/';
9007
 
        break;
9008
 
      case '<':
9009
 
        if (flag)
9010
 
          *s++ = (soap_wchar)'<';
9011
 
        else
9012
 
        { *s++ = (soap_wchar)'&';
9013
 
          t = "lt;";
9014
 
        }
9015
 
        break;
9016
 
      case '>':
9017
 
        if (flag)
9018
 
          *s++ = (soap_wchar)'>';
9019
 
        else
9020
 
        { *s++ = (soap_wchar)'&';
9021
 
          t = "gt;";
9022
 
        }
9023
 
        break;
9024
 
      case '"':
9025
 
        if (flag)
9026
 
          *s++ = (soap_wchar)'"';
9027
 
        else
9028
 
        { *s++ = (soap_wchar)'&';
9029
 
          t = "quot;";
9030
 
        }
9031
 
        break;
9032
 
      default:
9033
 
        if ((int)c == EOF)
9034
 
          goto end;
9035
 
        *s++ = (wchar_t)c & 0x7FFFFFFF;
9036
 
      }
9037
 
      l++;
9038
 
      if ((soap->mode & SOAP_XML_STRICT) && maxlen >= 0 && l > maxlen)
9039
 
      { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too long: maxlen=%ld\n", maxlen));
9040
 
        soap->error = SOAP_LENGTH;
9041
 
        return NULL;
9042
 
      }
9043
 
    }
9044
 
  }
9045
 
end:
9046
 
  soap_unget(soap, c);
9047
 
  *s = '\0';
9048
 
  soap_size_block(soap, sizeof(wchar_t) * (i + 1));
9049
 
  if ((soap->mode & SOAP_XML_STRICT) && l < minlen)
9050
 
  { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "String too short: %ld chars, minlen=%ld\n", l, minlen));
9051
 
    soap->error = SOAP_LENGTH;
9052
 
    return NULL;
9053
 
  }
9054
 
  s = (wchar_t*)soap_save_block(soap, NULL, 0);
9055
 
#ifdef WITH_DOM
9056
 
  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
9057
 
    soap->dom->wide = s;
9058
 
#endif
9059
 
  return s;
9060
 
}
9061
 
#endif
9062
 
#endif
9063
 
 
9064
 
/******************************************************************************/
9065
 
#ifndef PALM_2
9066
 
SOAP_FMAC1
9067
 
const char*
9068
 
SOAP_FMAC2
9069
 
soap_int2s(struct soap *soap, int n)
9070
 
{ return soap_long2s(soap, (long)n);
9071
 
}
9072
 
#endif
9073
 
 
9074
 
/******************************************************************************/
9075
 
#ifndef PALM_2
9076
 
SOAP_FMAC1
9077
 
int
9078
 
SOAP_FMAC2
9079
 
soap_outint(struct soap *soap, const char *tag, int id, const int *p, const char *type, int n)
9080
 
{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
9081
 
   || soap_string_out(soap, soap_long2s(soap, (long)*p), 0))
9082
 
    return soap->error;
9083
 
  return soap_element_end_out(soap, tag);
9084
 
}
9085
 
#endif
9086
 
 
9087
 
/******************************************************************************/
9088
 
#ifndef PALM_2
9089
 
SOAP_FMAC1
9090
 
int
9091
 
SOAP_FMAC2
9092
 
soap_s2int(struct soap *soap, const char *s, int *p)
9093
 
{ if (s)
9094
 
  { char *r;
9095
 
#ifndef WITH_NOIO
9096
 
#ifndef WITH_LEAN
9097
 
    soap_reset_errno;
9098
 
#endif
9099
 
#endif
9100
 
    *p = (int)soap_strtol(s, &r, 10);
9101
 
    if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
9102
 
#ifndef WITH_NOIO
9103
 
#ifndef WITH_LEAN
9104
 
     || soap_errno == SOAP_ERANGE
9105
 
#endif
9106
 
#endif
9107
 
    )
9108
 
      soap->error = SOAP_TYPE;
9109
 
  }
9110
 
  return soap->error;
9111
 
}
9112
 
#endif
9113
 
 
9114
 
/******************************************************************************/
9115
 
#ifndef PALM_2
9116
 
SOAP_FMAC1
9117
 
int *
9118
 
SOAP_FMAC2
9119
 
soap_inint(struct soap *soap, const char *tag, int *p, const char *type, int t)
9120
 
{ if (soap_element_begin_in(soap, tag, 0, NULL))
9121
 
    return NULL;
9122
 
#ifndef WITH_LEAN
9123
 
  if (*soap->type
9124
 
   && soap_match_tag(soap, soap->type, type)
9125
 
   && soap_match_tag(soap, soap->type, ":int")
9126
 
   && soap_match_tag(soap, soap->type, ":short")
9127
 
   && soap_match_tag(soap, soap->type, ":byte"))
9128
 
  { soap->error = SOAP_TYPE;
9129
 
    soap_revert(soap);
9130
 
    return NULL;
9131
 
  }
9132
 
#endif
9133
 
  p = (int*)soap_id_enter(soap, soap->id, p, t, sizeof(int), 0, NULL, NULL, NULL);
9134
 
  if (*soap->href)
9135
 
    p = (int*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(int), 0, NULL);
9136
 
  else if (p)
9137
 
  { if (soap_s2int(soap, soap_value(soap), p))
9138
 
      return NULL;
9139
 
  }
9140
 
  if (soap->body && soap_element_end_in(soap, tag))
9141
 
    return NULL;
9142
 
  return p;
9143
 
}
9144
 
#endif
9145
 
 
9146
 
/******************************************************************************/
9147
 
#ifndef PALM_2
9148
 
SOAP_FMAC1
9149
 
const char*
9150
 
SOAP_FMAC2
9151
 
soap_long2s(struct soap *soap, long n)
9152
 
{ sprintf(soap->tmpbuf, "%ld", n);
9153
 
  return soap->tmpbuf;
9154
 
}
9155
 
#endif
9156
 
 
9157
 
/******************************************************************************/
9158
 
#ifndef PALM_2
9159
 
SOAP_FMAC1
9160
 
int
9161
 
SOAP_FMAC2
9162
 
soap_outlong(struct soap *soap, const char *tag, int id, const long *p, const char *type, int n)
9163
 
{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
9164
 
   || soap_string_out(soap, soap_long2s(soap, *p), 0))
9165
 
    return soap->error;
9166
 
  return soap_element_end_out(soap, tag);
9167
 
}
9168
 
#endif
9169
 
 
9170
 
/******************************************************************************/
9171
 
#ifndef PALM_2
9172
 
SOAP_FMAC1
9173
 
int
9174
 
SOAP_FMAC2
9175
 
soap_s2long(struct soap *soap, const char *s, long *p)
9176
 
{ if (s)
9177
 
  { char *r;
9178
 
#ifndef WITH_NOIO
9179
 
#ifndef WITH_LEAN
9180
 
    soap_reset_errno;
9181
 
#endif
9182
 
#endif
9183
 
    *p = soap_strtol(s, &r, 10);
9184
 
    if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
9185
 
#ifndef WITH_NOIO
9186
 
#ifndef WITH_LEAN
9187
 
     || soap_errno == SOAP_ERANGE
9188
 
#endif
9189
 
#endif
9190
 
    )
9191
 
      soap->error = SOAP_TYPE;
9192
 
  }
9193
 
  return soap->error;
9194
 
}
9195
 
#endif
9196
 
 
9197
 
/******************************************************************************/
9198
 
#ifndef PALM_2
9199
 
SOAP_FMAC1
9200
 
long *
9201
 
SOAP_FMAC2
9202
 
soap_inlong(struct soap *soap, const char *tag, long *p, const char *type, int t)
9203
 
{ if (soap_element_begin_in(soap, tag, 0, NULL))
9204
 
    return NULL;
9205
 
#ifndef WITH_LEAN
9206
 
  if (*soap->type
9207
 
   && soap_match_tag(soap, soap->type, type)
9208
 
   && soap_match_tag(soap, soap->type, ":int")
9209
 
   && soap_match_tag(soap, soap->type, ":short")
9210
 
   && soap_match_tag(soap, soap->type, ":byte"))
9211
 
  { soap->error = SOAP_TYPE;
9212
 
    soap_revert(soap);
9213
 
    return NULL;
9214
 
  }
9215
 
#endif
9216
 
  p = (long*)soap_id_enter(soap, soap->id, p, t, sizeof(long), 0, NULL, NULL, NULL);
9217
 
  if (*soap->href)
9218
 
    p = (long*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(long), 0, NULL);
9219
 
  else if (p)
9220
 
  { if (soap_s2long(soap, soap_value(soap), p))
9221
 
      return NULL;
9222
 
  }
9223
 
  if (soap->body && soap_element_end_in(soap, tag))
9224
 
    return NULL;
9225
 
  return p;
9226
 
}
9227
 
#endif
9228
 
 
9229
 
/******************************************************************************/
9230
 
#ifndef WITH_LEAN
9231
 
SOAP_FMAC1
9232
 
const char*
9233
 
SOAP_FMAC2
9234
 
soap_LONG642s(struct soap *soap, LONG64 n)
9235
 
{ sprintf(soap->tmpbuf, SOAP_LONG_FORMAT, n);
9236
 
  return soap->tmpbuf;
9237
 
}
9238
 
#endif
9239
 
 
9240
 
/******************************************************************************/
9241
 
#ifndef WITH_LEAN
9242
 
SOAP_FMAC1
9243
 
int
9244
 
SOAP_FMAC2
9245
 
soap_outLONG64(struct soap *soap, const char *tag, int id, const LONG64 *p, const char *type, int n)
9246
 
{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
9247
 
   || soap_string_out(soap, soap_LONG642s(soap, *p), 0))
9248
 
    return soap->error;
9249
 
  return soap_element_end_out(soap, tag);
9250
 
}
9251
 
#endif
9252
 
 
9253
 
/******************************************************************************/
9254
 
#ifndef WITH_LEAN
9255
 
SOAP_FMAC1
9256
 
int
9257
 
SOAP_FMAC2
9258
 
soap_s2LONG64(struct soap *soap, const char *s, LONG64 *p)
9259
 
{ if (s)
9260
 
  {
9261
 
#ifdef HAVE_STRTOLL
9262
 
    char *r;
9263
 
#ifndef WITH_NOIO
9264
 
#ifndef WITH_LEAN
9265
 
    soap_reset_errno;
9266
 
#endif
9267
 
#endif
9268
 
    *p = strtoll(s, &r, 10);
9269
 
    if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
9270
 
#ifndef WITH_NOIO
9271
 
#ifndef WITH_LEAN
9272
 
       || soap_errno == SOAP_ERANGE
9273
 
#endif
9274
 
#endif
9275
 
      )
9276
 
#else
9277
 
# ifdef HAVE_SSCANF
9278
 
    if (sscanf(s, SOAP_LONG_FORMAT, p) != 1)
9279
 
# endif
9280
 
#endif
9281
 
      soap->error = SOAP_TYPE;
9282
 
  }
9283
 
  return soap->error;
9284
 
}
9285
 
#endif
9286
 
 
9287
 
/******************************************************************************/
9288
 
#ifndef WITH_LEAN
9289
 
SOAP_FMAC1
9290
 
LONG64 *
9291
 
SOAP_FMAC2
9292
 
soap_inLONG64(struct soap *soap, const char *tag, LONG64 *p, const char *type, int t)
9293
 
{ if (soap_element_begin_in(soap, tag, 0, NULL))
9294
 
    return NULL;
9295
 
#ifndef WITH_LEAN
9296
 
  if (*soap->type
9297
 
   && soap_match_tag(soap, soap->type, type)
9298
 
   && soap_match_tag(soap, soap->type, ":integer")
9299
 
   && soap_match_tag(soap, soap->type, ":positiveInteger")
9300
 
   && soap_match_tag(soap, soap->type, ":negativeInteger")
9301
 
   && soap_match_tag(soap, soap->type, ":nonPositiveInteger")
9302
 
   && soap_match_tag(soap, soap->type, ":nonNegativeInteger")
9303
 
   && soap_match_tag(soap, soap->type, ":long")
9304
 
   && soap_match_tag(soap, soap->type, ":int")
9305
 
   && soap_match_tag(soap, soap->type, ":short")
9306
 
   && soap_match_tag(soap, soap->type, ":byte"))
9307
 
  { soap->error = SOAP_TYPE;
9308
 
    soap_revert(soap);
9309
 
    return NULL;
9310
 
  }
9311
 
#endif
9312
 
  p = (LONG64*)soap_id_enter(soap, soap->id, p, t, sizeof(LONG64), 0, NULL, NULL, NULL);
9313
 
  if (*soap->href)
9314
 
    p = (LONG64*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(LONG64), 0, NULL);
9315
 
  else if (p)
9316
 
  { if (soap_s2LONG64(soap, soap_value(soap), p))
9317
 
      return NULL;
9318
 
  }
9319
 
  if (soap->body && soap_element_end_in(soap, tag))
9320
 
    return NULL;
9321
 
  return p;
9322
 
}
9323
 
#endif
9324
 
 
9325
 
/******************************************************************************/
9326
 
#ifndef PALM_2
9327
 
SOAP_FMAC1
9328
 
const char*
9329
 
SOAP_FMAC2
9330
 
soap_byte2s(struct soap *soap, char n)
9331
 
{ return soap_long2s(soap, (long)n);
9332
 
}
9333
 
#endif
9334
 
 
9335
 
/******************************************************************************/
9336
 
#ifndef PALM_2
9337
 
SOAP_FMAC1
9338
 
int
9339
 
SOAP_FMAC2
9340
 
soap_outbyte(struct soap *soap, const char *tag, int id, const char *p, const char *type, int n)
9341
 
{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
9342
 
   || soap_string_out(soap, soap_long2s(soap, (long)*p), 0))
9343
 
    return soap->error;
9344
 
  return soap_element_end_out(soap, tag);
9345
 
}
9346
 
#endif
9347
 
 
9348
 
/******************************************************************************/
9349
 
#ifndef PALM_2
9350
 
SOAP_FMAC1
9351
 
int
9352
 
SOAP_FMAC2
9353
 
soap_s2byte(struct soap *soap, const char *s, char *p)
9354
 
{ if (s)
9355
 
  { long n;
9356
 
    char *r;
9357
 
    n = soap_strtol(s, &r, 10);
9358
 
    if (s == r || *r || n < -128 || n > 127)
9359
 
      soap->error = SOAP_TYPE;
9360
 
    *p = (char)n;
9361
 
  }
9362
 
  return soap->error;
9363
 
}
9364
 
#endif
9365
 
 
9366
 
/******************************************************************************/
9367
 
#ifndef PALM_2
9368
 
SOAP_FMAC1
9369
 
char *
9370
 
SOAP_FMAC2
9371
 
soap_inbyte(struct soap *soap, const char *tag, char *p, const char *type, int t)
9372
 
{ if (soap_element_begin_in(soap, tag, 0, NULL))
9373
 
    return NULL;
9374
 
#ifndef WITH_LEAN
9375
 
  if (*soap->type
9376
 
   && soap_match_tag(soap, soap->type, type)
9377
 
   && soap_match_tag(soap, soap->type, ":byte"))
9378
 
  { soap->error = SOAP_TYPE;
9379
 
    soap_revert(soap);
9380
 
    return NULL;
9381
 
  }
9382
 
#endif
9383
 
  p = (char*)soap_id_enter(soap, soap->id, p, t, sizeof(char), 0, NULL, NULL, NULL);
9384
 
  if (*soap->href)
9385
 
    p = (char*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(char), 0, NULL);
9386
 
  else if (p)
9387
 
  { if (soap_s2byte(soap, soap_value(soap), p))
9388
 
      return NULL;
9389
 
  }
9390
 
  if (soap->body && soap_element_end_in(soap, tag))
9391
 
    return NULL;
9392
 
  return p;
9393
 
}
9394
 
#endif
9395
 
 
9396
 
/******************************************************************************/
9397
 
#ifndef PALM_2
9398
 
SOAP_FMAC1
9399
 
const char*
9400
 
SOAP_FMAC2
9401
 
soap_short2s(struct soap *soap, short n)
9402
 
{ return soap_long2s(soap, (long)n);
9403
 
}
9404
 
#endif
9405
 
 
9406
 
/******************************************************************************/
9407
 
#ifndef PALM_2
9408
 
SOAP_FMAC1
9409
 
int
9410
 
SOAP_FMAC2
9411
 
soap_outshort(struct soap *soap, const char *tag, int id, const short *p, const char *type, int n)
9412
 
{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
9413
 
   || soap_string_out(soap, soap_long2s(soap, (long)*p), 0))
9414
 
    return soap->error;
9415
 
  return soap_element_end_out(soap, tag);
9416
 
}
9417
 
#endif
9418
 
 
9419
 
/******************************************************************************/
9420
 
#ifndef PALM_2
9421
 
SOAP_FMAC1
9422
 
int
9423
 
SOAP_FMAC2
9424
 
soap_s2short(struct soap *soap, const char *s, short *p)
9425
 
{ if (s)
9426
 
  { long n;
9427
 
    char *r;
9428
 
    n = soap_strtol(s, &r, 10);
9429
 
    if (s == r || *r || n < -32768 || n > 32767)
9430
 
      soap->error = SOAP_TYPE;
9431
 
    *p = (short)n;
9432
 
  }
9433
 
  return soap->error;
9434
 
}
9435
 
#endif
9436
 
 
9437
 
/******************************************************************************/
9438
 
#ifndef PALM_2
9439
 
SOAP_FMAC1
9440
 
short *
9441
 
SOAP_FMAC2
9442
 
soap_inshort(struct soap *soap, const char *tag, short *p, const char *type, int t)
9443
 
{ if (soap_element_begin_in(soap, tag, 0, NULL))
9444
 
    return NULL;
9445
 
#ifndef WITH_LEAN
9446
 
  if (*soap->type
9447
 
   && soap_match_tag(soap, soap->type, type)
9448
 
   && soap_match_tag(soap, soap->type, ":short")
9449
 
   && soap_match_tag(soap, soap->type, ":byte"))
9450
 
  { soap->error = SOAP_TYPE;
9451
 
    soap_revert(soap);
9452
 
    return NULL;
9453
 
  }
9454
 
#endif
9455
 
  p = (short*)soap_id_enter(soap, soap->id, p, t, sizeof(short), 0, NULL, NULL, NULL);
9456
 
  if (*soap->href)
9457
 
    p = (short*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(short), 0, NULL);
9458
 
  else if (p)
9459
 
  { if (soap_s2short(soap, soap_value(soap), p))
9460
 
      return NULL;
9461
 
  }
9462
 
  if (soap->body && soap_element_end_in(soap, tag))
9463
 
    return NULL;
9464
 
  return p;
9465
 
}
9466
 
#endif
9467
 
 
9468
 
/******************************************************************************/
9469
 
#ifndef PALM_2
9470
 
SOAP_FMAC1
9471
 
const char*
9472
 
SOAP_FMAC2
9473
 
soap_float2s(struct soap *soap, float n)
9474
 
{ char *s, *t;
9475
 
  if (soap_isnan((double)n))
9476
 
    return "NaN";
9477
 
  if (soap_ispinff(n))
9478
 
    return "INF";
9479
 
  if (soap_isninff(n))
9480
 
    return "-INF";
9481
 
  s = soap->tmpbuf;
9482
 
  sprintf(soap->tmpbuf, soap->float_format, n);
9483
 
  t = strchr(s, ',');   /* convert decimal comma to DP */
9484
 
  if (t)
9485
 
    *t = '.';
9486
 
  return s;
9487
 
}
9488
 
#endif
9489
 
 
9490
 
/******************************************************************************/
9491
 
#ifndef PALM_2
9492
 
SOAP_FMAC1
9493
 
int
9494
 
SOAP_FMAC2
9495
 
soap_outfloat(struct soap *soap, const char *tag, int id, const float *p, const char *type, int n)
9496
 
{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
9497
 
   || soap_string_out(soap, soap_float2s(soap, *p), 0))
9498
 
    return soap->error;
9499
 
  return soap_element_end_out(soap, tag);
9500
 
}
9501
 
#endif
9502
 
 
9503
 
/******************************************************************************/
9504
 
#ifndef PALM_2
9505
 
SOAP_FMAC1
9506
 
int
9507
 
SOAP_FMAC2
9508
 
soap_s2float(struct soap *soap, const char *s, float *p)
9509
 
{ if (s)
9510
 
  { if (!*s)
9511
 
      return soap->error = SOAP_TYPE;
9512
 
    if (!soap_tag_cmp(s, "INF"))
9513
 
      *p = FLT_PINFTY;
9514
 
    else if (!soap_tag_cmp(s, "+INF"))
9515
 
      *p = FLT_PINFTY;
9516
 
    else if (!soap_tag_cmp(s, "-INF"))
9517
 
      *p = FLT_NINFTY;
9518
 
    else if (!soap_tag_cmp(s, "NaN"))
9519
 
      *p = FLT_NAN;
9520
 
    else
9521
 
    {
9522
 
/* On some systems, strtof appears to be broken or doesn't link: use with caution */
9523
 
#if defined(HAVE_STRTOF)
9524
 
      char *r;
9525
 
      *p = strtof((char*)s, &r);
9526
 
      if (*r)
9527
 
#elif defined(HAVE_STRTOD)
9528
 
      char *r;
9529
 
      *p = (float)strtod(s, &r);
9530
 
      if (*r)
9531
 
#endif
9532
 
#ifdef HAVE_SSCANF
9533
 
        if (sscanf(s, "%g", p) != 1)
9534
 
          soap->error = SOAP_TYPE;
9535
 
#else
9536
 
        soap->error = SOAP_TYPE;
9537
 
#endif
9538
 
    }
9539
 
  }
9540
 
  return soap->error;
9541
 
}
9542
 
#endif
9543
 
 
9544
 
/******************************************************************************/
9545
 
#ifndef WITH_LEAN
9546
 
static int soap_isnumeric(struct soap *soap, const char *type)
9547
 
{ if (soap_match_tag(soap, soap->type, type)
9548
 
   && soap_match_tag(soap, soap->type, ":float")
9549
 
   && soap_match_tag(soap, soap->type, ":double")
9550
 
   && soap_match_tag(soap, soap->type, ":decimal")
9551
 
   && soap_match_tag(soap, soap->type, ":integer")
9552
 
   && soap_match_tag(soap, soap->type, ":positiveInteger")
9553
 
   && soap_match_tag(soap, soap->type, ":negativeInteger")
9554
 
   && soap_match_tag(soap, soap->type, ":nonPositiveInteger")
9555
 
   && soap_match_tag(soap, soap->type, ":nonNegativeInteger")
9556
 
   && soap_match_tag(soap, soap->type, ":long")
9557
 
   && soap_match_tag(soap, soap->type, ":int")
9558
 
   && soap_match_tag(soap, soap->type, ":short")
9559
 
   && soap_match_tag(soap, soap->type, ":byte")
9560
 
   && soap_match_tag(soap, soap->type, ":unsignedLong")
9561
 
   && soap_match_tag(soap, soap->type, ":unsignedInt")
9562
 
   && soap_match_tag(soap, soap->type, ":unsignedShort")
9563
 
   && soap_match_tag(soap, soap->type, ":unsignedByte"))
9564
 
  { soap->error = SOAP_TYPE;
9565
 
    soap_revert(soap);
9566
 
    return SOAP_ERR;
9567
 
  }
9568
 
  return SOAP_OK;
9569
 
}
9570
 
#endif
9571
 
 
9572
 
/******************************************************************************/
9573
 
#ifndef PALM_2
9574
 
SOAP_FMAC1
9575
 
float *
9576
 
SOAP_FMAC2
9577
 
soap_infloat(struct soap *soap, const char *tag, float *p, const char *type, int t)
9578
 
{ if (soap_element_begin_in(soap, tag, 0, NULL))
9579
 
    return NULL;
9580
 
#ifndef WITH_LEAN
9581
 
  if (*soap->type != '\0' && soap_isnumeric(soap, type))
9582
 
    return NULL;
9583
 
#endif
9584
 
  p = (float*)soap_id_enter(soap, soap->id, p, t, sizeof(float), 0, NULL, NULL, NULL);
9585
 
  if (*soap->href)
9586
 
    p = (float*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(float), 0, NULL);
9587
 
  else if (p)
9588
 
  { if (soap_s2float(soap, soap_value(soap), p))
9589
 
      return NULL;
9590
 
  }
9591
 
  if (soap->body && soap_element_end_in(soap, tag))
9592
 
    return NULL;
9593
 
  return p;
9594
 
}
9595
 
#endif
9596
 
 
9597
 
/******************************************************************************/
9598
 
#ifndef PALM_2
9599
 
SOAP_FMAC1
9600
 
const char*
9601
 
SOAP_FMAC2
9602
 
soap_double2s(struct soap *soap, double n)
9603
 
{ char *s, *t;
9604
 
  if (soap_isnan(n))
9605
 
    return "NaN";
9606
 
  if (soap_ispinfd(n))
9607
 
    return "INF";
9608
 
  if (soap_isninfd(n))
9609
 
    return "-INF";
9610
 
  s = soap->tmpbuf;
9611
 
  sprintf(soap->tmpbuf, soap->double_format, n);
9612
 
  t = strchr(s, ',');   /* convert decimal comma to DP */
9613
 
  if (t)
9614
 
    *t = '.';
9615
 
  return s;
9616
 
}
9617
 
#endif
9618
 
 
9619
 
/******************************************************************************/
9620
 
#ifndef PALM_2
9621
 
SOAP_FMAC1
9622
 
int
9623
 
SOAP_FMAC2
9624
 
soap_outdouble(struct soap *soap, const char *tag, int id, const double *p, const char *type, int n)
9625
 
{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
9626
 
   || soap_string_out(soap, soap_double2s(soap, *p), 0))
9627
 
    return soap->error;
9628
 
  return soap_element_end_out(soap, tag);
9629
 
}
9630
 
#endif
9631
 
 
9632
 
/******************************************************************************/
9633
 
#ifndef PALM_2
9634
 
SOAP_FMAC1
9635
 
int
9636
 
SOAP_FMAC2
9637
 
soap_s2double(struct soap *soap, const char *s, double *p)
9638
 
{ if (s)
9639
 
  { if (!*s)
9640
 
      return soap->error = SOAP_TYPE;
9641
 
    if (!soap_tag_cmp(s, "INF"))
9642
 
      *p = DBL_PINFTY;
9643
 
    else if (!soap_tag_cmp(s, "+INF"))
9644
 
      *p = DBL_PINFTY;
9645
 
    else if (!soap_tag_cmp(s, "-INF"))
9646
 
      *p = DBL_NINFTY;
9647
 
    else if (!soap_tag_cmp(s, "NaN"))
9648
 
      *p = DBL_NAN;
9649
 
    else
9650
 
    {
9651
 
#ifdef HAVE_STRTOD
9652
 
      char *r;
9653
 
      *p = strtod(s, &r);
9654
 
      if (*r)
9655
 
#endif
9656
 
#ifdef HAVE_SSCANF
9657
 
        if (sscanf(s, "%lg", p) != 1)
9658
 
          soap->error = SOAP_TYPE;
9659
 
#else
9660
 
        soap->error = SOAP_TYPE;
9661
 
#endif
9662
 
    }
9663
 
  }
9664
 
  return soap->error;
9665
 
}
9666
 
#endif
9667
 
 
9668
 
/******************************************************************************/
9669
 
#ifndef PALM_2
9670
 
SOAP_FMAC1
9671
 
double *
9672
 
SOAP_FMAC2
9673
 
soap_indouble(struct soap *soap, const char *tag, double *p, const char *type, int t)
9674
 
{ if (soap_element_begin_in(soap, tag, 0, NULL))
9675
 
    return NULL;
9676
 
#ifndef WITH_LEAN
9677
 
  if (*soap->type != '\0' && soap_isnumeric(soap, type))
9678
 
    return NULL;
9679
 
#endif
9680
 
  p = (double*)soap_id_enter(soap, soap->id, p, t, sizeof(double), 0, NULL, NULL, NULL);
9681
 
  if (*soap->href)
9682
 
    p = (double*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(double), 0, NULL);
9683
 
  else if (p)
9684
 
  { if (soap_s2double(soap, soap_value(soap), p))
9685
 
      return NULL;
9686
 
  }
9687
 
  if (soap->body && soap_element_end_in(soap, tag))
9688
 
    return NULL;
9689
 
  return p;
9690
 
}
9691
 
#endif
9692
 
 
9693
 
/******************************************************************************/
9694
 
#ifndef PALM_2
9695
 
SOAP_FMAC1
9696
 
const char*
9697
 
SOAP_FMAC2
9698
 
soap_unsignedByte2s(struct soap *soap, unsigned char n)
9699
 
{ return soap_unsignedLong2s(soap, (unsigned long)n);
9700
 
}
9701
 
#endif
9702
 
 
9703
 
/******************************************************************************/
9704
 
#ifndef PALM_2
9705
 
SOAP_FMAC1
9706
 
int
9707
 
SOAP_FMAC2
9708
 
soap_outunsignedByte(struct soap *soap, const char *tag, int id, const unsigned char *p, const char *type, int n)
9709
 
{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
9710
 
   || soap_string_out(soap, soap_unsignedLong2s(soap, (unsigned long)*p), 0))
9711
 
    return soap->error;
9712
 
  return soap_element_end_out(soap, tag);
9713
 
}
9714
 
#endif
9715
 
 
9716
 
/******************************************************************************/
9717
 
#ifndef PALM_2
9718
 
SOAP_FMAC1
9719
 
int
9720
 
SOAP_FMAC2
9721
 
soap_s2unsignedByte(struct soap *soap, const char *s, unsigned char *p)
9722
 
{ if (s)
9723
 
  { unsigned long n;
9724
 
    char *r;
9725
 
    n = soap_strtoul(s, &r, 10);
9726
 
    if (s == r || *r || n > 255)
9727
 
      soap->error = SOAP_TYPE;
9728
 
    *p = (unsigned char)n;
9729
 
  }
9730
 
  return soap->error;
9731
 
}
9732
 
#endif
9733
 
 
9734
 
/******************************************************************************/
9735
 
#ifndef PALM_2
9736
 
SOAP_FMAC1
9737
 
unsigned char *
9738
 
SOAP_FMAC2
9739
 
soap_inunsignedByte(struct soap *soap, const char *tag, unsigned char *p, const char *type, int t)
9740
 
{ if (soap_element_begin_in(soap, tag, 0, NULL))
9741
 
    return NULL;
9742
 
#ifndef WITH_LEAN
9743
 
  if (*soap->type
9744
 
   && soap_match_tag(soap, soap->type, type)
9745
 
   && soap_match_tag(soap, soap->type, ":unsignedByte"))
9746
 
  { soap->error = SOAP_TYPE;
9747
 
    soap_revert(soap);
9748
 
    return NULL;
9749
 
  }
9750
 
#endif
9751
 
  p = (unsigned char*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned char), 0, NULL, NULL, NULL);
9752
 
  if (*soap->href)
9753
 
    p = (unsigned char*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(unsigned char), 0, NULL);
9754
 
  else if (p)
9755
 
  { if (soap_s2unsignedByte(soap, soap_value(soap), p))
9756
 
      return NULL;
9757
 
  }
9758
 
  if (soap->body && soap_element_end_in(soap, tag))
9759
 
    return NULL;
9760
 
  return p;
9761
 
}
9762
 
#endif
9763
 
 
9764
 
/******************************************************************************/
9765
 
#ifndef PALM_2
9766
 
SOAP_FMAC1
9767
 
const char*
9768
 
SOAP_FMAC2
9769
 
soap_unsignedShort2s(struct soap *soap, unsigned short n)
9770
 
{ return soap_unsignedLong2s(soap, (unsigned long)n);
9771
 
}
9772
 
#endif
9773
 
 
9774
 
/******************************************************************************/
9775
 
#ifndef PALM_2
9776
 
SOAP_FMAC1
9777
 
int
9778
 
SOAP_FMAC2
9779
 
soap_outunsignedShort(struct soap *soap, const char *tag, int id, const unsigned short *p, const char *type, int n)
9780
 
{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
9781
 
   || soap_string_out(soap, soap_unsignedLong2s(soap, (unsigned long)*p), 0))
9782
 
    return soap->error;
9783
 
  return soap_element_end_out(soap, tag);
9784
 
}
9785
 
#endif
9786
 
 
9787
 
/******************************************************************************/
9788
 
#ifndef PALM_2
9789
 
SOAP_FMAC1
9790
 
int
9791
 
SOAP_FMAC2
9792
 
soap_s2unsignedShort(struct soap *soap, const char *s, unsigned short *p)
9793
 
{ if (s)
9794
 
  { unsigned long n;
9795
 
    char *r;
9796
 
    n = soap_strtoul(s, &r, 10);
9797
 
    if (s == r || *r || n > 65535)
9798
 
      soap->error = SOAP_TYPE;
9799
 
    *p = (unsigned short)n;
9800
 
  }
9801
 
  return soap->error;
9802
 
}
9803
 
#endif
9804
 
 
9805
 
/******************************************************************************/
9806
 
#ifndef PALM_2
9807
 
SOAP_FMAC1
9808
 
unsigned short *
9809
 
SOAP_FMAC2
9810
 
soap_inunsignedShort(struct soap *soap, const char *tag, unsigned short *p, const char *type, int t)
9811
 
{ if (soap_element_begin_in(soap, tag, 0, NULL))
9812
 
    return NULL;
9813
 
#ifndef WITH_LEAN
9814
 
  if (*soap->type
9815
 
   && soap_match_tag(soap, soap->type, type)
9816
 
   && soap_match_tag(soap, soap->type, ":unsignedShort")
9817
 
   && soap_match_tag(soap, soap->type, ":unsignedByte"))
9818
 
  { soap->error = SOAP_TYPE;
9819
 
    soap_revert(soap);
9820
 
    return NULL;
9821
 
  }
9822
 
#endif
9823
 
  p = (unsigned short*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned short), 0, NULL, NULL, NULL);
9824
 
  if (*soap->href)
9825
 
    p = (unsigned short*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(unsigned short), 0, NULL);
9826
 
  else if (p)
9827
 
  { if (soap_s2unsignedShort(soap, soap_value(soap), p))
9828
 
      return NULL;
9829
 
  }
9830
 
  if (soap->body && soap_element_end_in(soap, tag))
9831
 
    return NULL;
9832
 
  return p;
9833
 
}
9834
 
#endif
9835
 
 
9836
 
/******************************************************************************/
9837
 
#ifndef PALM_2
9838
 
SOAP_FMAC1
9839
 
const char*
9840
 
SOAP_FMAC2
9841
 
soap_unsignedInt2s(struct soap *soap, unsigned int n)
9842
 
{ return soap_unsignedLong2s(soap, (unsigned long)n);
9843
 
}
9844
 
#endif
9845
 
 
9846
 
/******************************************************************************/
9847
 
#ifndef PALM_2
9848
 
SOAP_FMAC1
9849
 
int
9850
 
SOAP_FMAC2
9851
 
soap_outunsignedInt(struct soap *soap, const char *tag, int id, const unsigned int *p, const char *type, int n)
9852
 
{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
9853
 
   || soap_string_out(soap, soap_unsignedLong2s(soap, (unsigned long)*p), 0))
9854
 
    return soap->error;
9855
 
  return soap_element_end_out(soap, tag);
9856
 
}
9857
 
#endif
9858
 
 
9859
 
/******************************************************************************/
9860
 
#ifndef PALM_2
9861
 
SOAP_FMAC1
9862
 
int
9863
 
SOAP_FMAC2
9864
 
soap_s2unsignedInt(struct soap *soap, const char *s, unsigned int *p)
9865
 
{ if (s)
9866
 
  { char *r;
9867
 
#ifndef WITH_NOIO
9868
 
#ifndef WITH_LEAN
9869
 
    soap_reset_errno;
9870
 
#endif
9871
 
#endif
9872
 
    *p = (unsigned int)soap_strtoul(s, &r, 10);
9873
 
    if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
9874
 
#ifndef WITH_NOIO
9875
 
#ifndef WITH_LEAN
9876
 
     || soap_errno == SOAP_ERANGE
9877
 
#endif
9878
 
#endif
9879
 
    )
9880
 
      soap->error = SOAP_TYPE;
9881
 
  }
9882
 
  return soap->error;
9883
 
}
9884
 
#endif
9885
 
 
9886
 
/******************************************************************************/
9887
 
#ifndef PALM_2
9888
 
SOAP_FMAC1
9889
 
unsigned int *
9890
 
SOAP_FMAC2
9891
 
soap_inunsignedInt(struct soap *soap, const char *tag, unsigned int *p, const char *type, int t)
9892
 
{ if (soap_element_begin_in(soap, tag, 0, NULL))
9893
 
    return NULL;
9894
 
#ifndef WITH_LEAN
9895
 
  if (*soap->type
9896
 
   && soap_match_tag(soap, soap->type, type)
9897
 
   && soap_match_tag(soap, soap->type, ":unsignedInt")
9898
 
   && soap_match_tag(soap, soap->type, ":unsignedShort")
9899
 
   && soap_match_tag(soap, soap->type, ":unsignedByte"))
9900
 
  { soap->error = SOAP_TYPE;
9901
 
    soap_revert(soap);
9902
 
    return NULL;
9903
 
  }
9904
 
#endif
9905
 
  p = (unsigned int*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned int), 0, NULL, NULL, NULL);
9906
 
  if (*soap->href)
9907
 
    p = (unsigned int*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(unsigned int), 0, NULL);
9908
 
  else if (p)
9909
 
  { if (soap_s2unsignedInt(soap, soap_value(soap), p))
9910
 
      return NULL;
9911
 
  }
9912
 
  if (soap->body && soap_element_end_in(soap, tag))
9913
 
    return NULL;
9914
 
  return p;
9915
 
}
9916
 
#endif
9917
 
 
9918
 
/******************************************************************************/
9919
 
#ifndef PALM_2
9920
 
SOAP_FMAC1
9921
 
const char*
9922
 
SOAP_FMAC2
9923
 
soap_unsignedLong2s(struct soap *soap, unsigned long n)
9924
 
{ sprintf(soap->tmpbuf, "%lu", n);
9925
 
  return soap->tmpbuf;
9926
 
}
9927
 
#endif
9928
 
 
9929
 
/******************************************************************************/
9930
 
#ifndef PALM_2
9931
 
SOAP_FMAC1
9932
 
int
9933
 
SOAP_FMAC2
9934
 
soap_outunsignedLong(struct soap *soap, const char *tag, int id, const unsigned long *p, const char *type, int n)
9935
 
{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
9936
 
   || soap_string_out(soap, soap_unsignedLong2s(soap, *p), 0))
9937
 
    return soap->error;
9938
 
  return soap_element_end_out(soap, tag);
9939
 
}
9940
 
#endif
9941
 
 
9942
 
/******************************************************************************/
9943
 
#ifndef PALM_2
9944
 
SOAP_FMAC1
9945
 
int
9946
 
SOAP_FMAC2
9947
 
soap_s2unsignedLong(struct soap *soap, const char *s, unsigned long *p)
9948
 
{ if (s)
9949
 
  { char *r;
9950
 
#ifndef WITH_NOIO
9951
 
#ifndef WITH_LEAN
9952
 
    soap_reset_errno;
9953
 
#endif
9954
 
#endif
9955
 
    *p = soap_strtoul(s, &r, 10);
9956
 
    if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
9957
 
#ifndef WITH_NOIO
9958
 
#ifndef WITH_LEAN
9959
 
     || soap_errno == SOAP_ERANGE
9960
 
#endif
9961
 
#endif
9962
 
    )
9963
 
      soap->error = SOAP_TYPE;
9964
 
  }
9965
 
  return soap->error;
9966
 
}
9967
 
#endif
9968
 
 
9969
 
/******************************************************************************/
9970
 
#ifndef PALM_2
9971
 
SOAP_FMAC1
9972
 
unsigned long *
9973
 
SOAP_FMAC2
9974
 
soap_inunsignedLong(struct soap *soap, const char *tag, unsigned long *p, const char *type, int t)
9975
 
{ if (soap_element_begin_in(soap, tag, 0, NULL))
9976
 
    return NULL;
9977
 
#ifndef WITH_LEAN
9978
 
  if (*soap->type
9979
 
   && soap_match_tag(soap, soap->type, type)
9980
 
   && soap_match_tag(soap, soap->type, ":unsignedInt")
9981
 
   && soap_match_tag(soap, soap->type, ":unsignedShort")
9982
 
   && soap_match_tag(soap, soap->type, ":unsignedByte"))
9983
 
  { soap->error = SOAP_TYPE;
9984
 
    soap_revert(soap);
9985
 
    return NULL;
9986
 
  }
9987
 
#endif
9988
 
  p = (unsigned long*)soap_id_enter(soap, soap->id, p, t, sizeof(unsigned long), 0, NULL, NULL, NULL);
9989
 
  if (*soap->href)
9990
 
    p = (unsigned long*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(unsigned long), 0, NULL);
9991
 
  else if (p)
9992
 
  { if (soap_s2unsignedLong(soap, soap_value(soap), p))
9993
 
      return NULL;
9994
 
  }
9995
 
  if (soap->body && soap_element_end_in(soap, tag))
9996
 
    return NULL;
9997
 
  return p;
9998
 
}
9999
 
#endif
10000
 
 
10001
 
/******************************************************************************/
10002
 
#ifndef WITH_LEAN
10003
 
SOAP_FMAC1
10004
 
const char*
10005
 
SOAP_FMAC2
10006
 
soap_ULONG642s(struct soap *soap, ULONG64 n)
10007
 
{ sprintf(soap->tmpbuf, SOAP_ULONG_FORMAT, n);
10008
 
  return soap->tmpbuf;
10009
 
}
10010
 
#endif
10011
 
 
10012
 
/******************************************************************************/
10013
 
#ifndef WITH_LEAN
10014
 
SOAP_FMAC1
10015
 
int
10016
 
SOAP_FMAC2
10017
 
soap_outULONG64(struct soap *soap, const char *tag, int id, const ULONG64 *p, const char *type, int n)
10018
 
{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
10019
 
   || soap_string_out(soap, soap_ULONG642s(soap, *p), 0))
10020
 
    return soap->error;
10021
 
  return soap_element_end_out(soap, tag);
10022
 
}
10023
 
#endif
10024
 
 
10025
 
/******************************************************************************/
10026
 
#ifndef WITH_LEAN
10027
 
SOAP_FMAC1
10028
 
int
10029
 
SOAP_FMAC2
10030
 
soap_s2ULONG64(struct soap *soap, const char *s, ULONG64 *p)
10031
 
{ if (s)
10032
 
  {
10033
 
#ifdef HAVE_STRTOULL
10034
 
    char *r;
10035
 
#ifndef WITH_NOIO
10036
 
#ifndef WITH_LEAN
10037
 
    soap_reset_errno;
10038
 
#endif
10039
 
#endif
10040
 
    *p = strtoull(s, &r, 10);
10041
 
    if ((s == r && (soap->mode & SOAP_XML_STRICT)) || *r
10042
 
#ifndef WITH_NOIO
10043
 
#ifndef WITH_LEAN
10044
 
       || soap_errno == SOAP_ERANGE
10045
 
#endif
10046
 
#endif
10047
 
      )
10048
 
#else
10049
 
# ifdef HAVE_SSCANF
10050
 
    if (sscanf(s, SOAP_ULONG_FORMAT, p) != 1)
10051
 
# endif
10052
 
#endif
10053
 
      soap->error = SOAP_TYPE;
10054
 
  }
10055
 
  return soap->error;
10056
 
}
10057
 
#endif
10058
 
 
10059
 
/******************************************************************************/
10060
 
#ifndef WITH_LEAN
10061
 
SOAP_FMAC1
10062
 
ULONG64 *
10063
 
SOAP_FMAC2
10064
 
soap_inULONG64(struct soap *soap, const char *tag, ULONG64 *p, const char *type, int t)
10065
 
{ if (soap_element_begin_in(soap, tag, 0, NULL))
10066
 
    return NULL;
10067
 
  if (*soap->type
10068
 
   && soap_match_tag(soap, soap->type, type)
10069
 
   && soap_match_tag(soap, soap->type, ":positiveInteger")
10070
 
   && soap_match_tag(soap, soap->type, ":nonNegativeInteger")
10071
 
   && soap_match_tag(soap, soap->type, ":unsignedLong")
10072
 
   && soap_match_tag(soap, soap->type, ":unsignedInt")
10073
 
   && soap_match_tag(soap, soap->type, ":unsignedShort")
10074
 
   && soap_match_tag(soap, soap->type, ":unsignedByte"))
10075
 
  { soap->error = SOAP_TYPE;
10076
 
    soap_revert(soap);
10077
 
    return NULL;
10078
 
  }
10079
 
  p = (ULONG64*)soap_id_enter(soap, soap->id, p, t, sizeof(ULONG64), 0, NULL, NULL, NULL);
10080
 
  if (*soap->href)
10081
 
    p = (ULONG64*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(ULONG64), 0, NULL);
10082
 
  else if (p)
10083
 
  { if (soap_s2ULONG64(soap, soap_value(soap), p))
10084
 
      return NULL;
10085
 
  }
10086
 
  if (soap->body && soap_element_end_in(soap, tag))
10087
 
    return NULL;
10088
 
  return p;
10089
 
}
10090
 
#endif
10091
 
 
10092
 
/******************************************************************************/
10093
 
#ifndef PALM_2
10094
 
SOAP_FMAC1
10095
 
int
10096
 
SOAP_FMAC2
10097
 
soap_s2string(struct soap *soap, const char *s, char **t)
10098
 
{ *t = NULL;
10099
 
  if (s)
10100
 
  { if (!(*t = soap_strdup(soap, s)))
10101
 
      return soap->error = SOAP_EOM;
10102
 
    if (!(soap->mode & (SOAP_ENC_LATIN | SOAP_C_UTFSTRING)))
10103
 
    { /* TODO: consider truncating UTF8 to ASCII for regular XML attribute strings? */
10104
 
    }
10105
 
  }
10106
 
  return soap->error;
10107
 
}
10108
 
#endif
10109
 
 
10110
 
/******************************************************************************/
10111
 
#ifndef PALM_2
10112
 
SOAP_FMAC1
10113
 
int
10114
 
SOAP_FMAC2
10115
 
soap_s2QName(struct soap *soap, const char *s, char **t)
10116
 
{ if (s)
10117
 
  { struct soap_nlist *np = soap->nlist;
10118
 
    const char *p;
10119
 
    /* if there is no namespace stack, or prefix is "xml" then pass string */
10120
 
    if (!np || !strncmp(s, "xml:", 4))
10121
 
    { *t = soap_strdup(soap, s);
10122
 
      return SOAP_OK;
10123
 
    }
10124
 
    /* else we normalize the QName by replacing its prefix */
10125
 
    p = strchr(s, ':');
10126
 
    if (p)
10127
 
    { register size_t n = p - s;
10128
 
      while (np && (strncmp(np->id, s, n) || np->id[n]))
10129
 
        np = np->next;
10130
 
      p++;
10131
 
    }
10132
 
    else
10133
 
    { while (np && *np->id)
10134
 
        np = np->next;
10135
 
      p = s;
10136
 
    }
10137
 
    if (np)
10138
 
    { if (np->index >= 0 && soap->local_namespaces)
10139
 
      { register const char *q = soap->local_namespaces[np->index].id;
10140
 
        if (q)
10141
 
        { if ((*t = (char*)soap_malloc(soap, strlen(p) + strlen(q) + 2)))
10142
 
            sprintf(*t, "%s:%s", q, p);
10143
 
          return SOAP_OK;
10144
 
        }
10145
 
      }
10146
 
      if (np->ns)
10147
 
      { if ((*t = (char*)soap_malloc(soap, strlen(p) + strlen(np->ns) + 4)))
10148
 
          sprintf(*t, "\"%s\":%s", np->ns, p);
10149
 
        return SOAP_OK;
10150
 
      }
10151
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Namespace prefix of '%s' not defined (index=%d, URI=%s)\n", s, np->index, np->ns?np->ns:""));
10152
 
      return soap->error = SOAP_NAMESPACE; 
10153
 
    }
10154
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Namespace prefix of '%s' not defined, assuming empty namespace\n", s));
10155
 
    if ((*t = (char*)soap_malloc(soap, strlen(p) + 4)))
10156
 
      sprintf(*t, "\"\":%s", p);
10157
 
  }
10158
 
  else
10159
 
    *t = NULL;
10160
 
  return soap->error;
10161
 
}
10162
 
#endif
10163
 
 
10164
 
/******************************************************************************/
10165
 
#ifndef PALM_2
10166
 
SOAP_FMAC1
10167
 
const char*
10168
 
SOAP_FMAC2
10169
 
soap_QName2s(struct soap *soap, const char *s)
10170
 
{ register struct Namespace *p;
10171
 
  register char *t;
10172
 
  register size_t n;
10173
 
  if (!s || *s != '"')
10174
 
  {
10175
 
#ifndef WITH_LEAN
10176
 
    if (s && (soap->mode & SOAP_XML_CANONICAL))
10177
 
    { t = (char*)strchr(s, ':');
10178
 
      if (t)
10179
 
        soap_utilize_ns(soap, s, t - s);
10180
 
    }
10181
 
#endif
10182
 
    return s;
10183
 
  }
10184
 
  s++;
10185
 
  if ((p = soap->local_namespaces))
10186
 
  { for (; p->id; p++)
10187
 
    { if (p->ns)
10188
 
        if (!soap_tag_cmp(s, p->ns))
10189
 
          break;
10190
 
      if (p->in)
10191
 
        if (!soap_tag_cmp(s, p->in))
10192
 
          break;
10193
 
    }
10194
 
    if (p && p->id)
10195
 
    { s = strchr(s, '"');
10196
 
      if (s)
10197
 
      { t = (char*)soap_malloc(soap, strlen(p->id) + strlen(s));
10198
 
        strcpy(t, p->id);
10199
 
        strcat(t, s + 1);
10200
 
        return t;
10201
 
      }
10202
 
    }
10203
 
  }
10204
 
  t = (char*)strchr(s, '"');
10205
 
  if (t)
10206
 
    n = t - s;
10207
 
  else
10208
 
    n = 0;
10209
 
  t = soap_strdup(soap, s);
10210
 
  t[n] = '\0';
10211
 
  sprintf(soap->tmpbuf, "xmlns:_%d", soap->idnum++);
10212
 
  soap_set_attr(soap, soap->tmpbuf, t);
10213
 
  s = strchr(s, '"');
10214
 
  if (s)
10215
 
  { t = (char*)soap_malloc(soap, strlen(soap->tmpbuf) + strlen(s) - 6);
10216
 
    strcpy(t, soap->tmpbuf + 6);
10217
 
    strcat(t, s + 1);
10218
 
  }
10219
 
  return t;
10220
 
}
10221
 
#endif
10222
 
 
10223
 
/******************************************************************************/
10224
 
#ifndef WITH_LEAN
10225
 
SOAP_FMAC1
10226
 
int
10227
 
SOAP_FMAC2
10228
 
soap_s2wchar(struct soap *soap, const char *s, wchar_t **t)
10229
 
{ wchar_t *r;
10230
 
  if (!s)
10231
 
    *t = NULL;
10232
 
  else
10233
 
  { *t = r = (wchar_t*)soap_malloc(soap, sizeof(wchar_t) * (strlen(s) + 1));
10234
 
    if (!r)
10235
 
      return soap->error;
10236
 
    if (soap->mode & SOAP_ENC_LATIN)
10237
 
    { while (*s)
10238
 
        *r++ = (wchar_t)*s++;
10239
 
    }
10240
 
    else
10241
 
    { /* Convert UTF8 to wchar */
10242
 
      while (*s)
10243
 
      { register soap_wchar c, c1, c2, c3, c4;
10244
 
        c = *s++;
10245
 
        if (c < 0x80)
10246
 
          *r++ = (wchar_t)c;
10247
 
        else
10248
 
        { c1 = (soap_wchar)*s++ & 0x3F;
10249
 
          if (c < 0xE0)
10250
 
            *r++ = (wchar_t)(((soap_wchar)(c & 0x1F) << 6) | c1);
10251
 
          else
10252
 
          { c2 = (soap_wchar)*s++ & 0x3F;
10253
 
            if (c < 0xF0)
10254
 
              *r++ = (wchar_t)(((soap_wchar)(c & 0x0F) << 12) | (c1 << 6) | c2);
10255
 
            else
10256
 
            { c3 = (soap_wchar)*s++ & 0x3F;
10257
 
              if (c < 0xF8)
10258
 
                *r++ = (wchar_t)(((soap_wchar)(c & 0x07) << 18) | (c1 << 12) | (c2 << 6) | c3);
10259
 
              else
10260
 
              { c4 = (soap_wchar)*s++ & 0x3F;
10261
 
                if (c < 0xFC)
10262
 
                  *r++ = (wchar_t)(((soap_wchar)(c & 0x03) << 24) | (c1 << 18) | (c2 << 12) | (c3 << 6) | c4);
10263
 
                else
10264
 
                  *r++ = (wchar_t)(((soap_wchar)(c & 0x01) << 30) | (c1 << 24) | (c2 << 18) | (c3 << 12) | (c4 << 6) | (soap_wchar)(*s++ & 0x3F));
10265
 
              }
10266
 
            }
10267
 
          }
10268
 
        }
10269
 
      }
10270
 
    }
10271
 
    *r = L'\0';
10272
 
  }
10273
 
  return SOAP_OK;
10274
 
}
10275
 
#endif
10276
 
 
10277
 
/******************************************************************************/
10278
 
#ifndef WITH_LEAN
10279
 
SOAP_FMAC1
10280
 
const char*
10281
 
SOAP_FMAC2
10282
 
soap_wchar2s(struct soap *soap, const wchar_t *s)
10283
 
{ register soap_wchar c;
10284
 
  register char *r, *t;
10285
 
  const wchar_t *q = s;
10286
 
  size_t n = 0;
10287
 
  while ((c = *q++))
10288
 
  { if (c > 0 && c < 0x80)
10289
 
      n++;
10290
 
    else
10291
 
      n += 6;
10292
 
  }
10293
 
  r = t = (char*)soap_malloc(soap, n + 1);
10294
 
  if (r)
10295
 
  { /* Convert wchar to UTF8 */
10296
 
    while ((c = *s++))
10297
 
    { if (c > 0 && c < 0x80)
10298
 
        *t++ = (char)c;
10299
 
      else
10300
 
      { if (c < 0x0800)
10301
 
          *t++ = (char)(0xC0 | ((c >> 6) & 0x1F));
10302
 
        else
10303
 
        { if (c < 0x010000)
10304
 
            *t++ = (char)(0xE0 | ((c >> 12) & 0x0F));
10305
 
          else
10306
 
          { if (c < 0x200000)
10307
 
              *t++ = (char)(0xF0 | ((c >> 18) & 0x07));
10308
 
            else
10309
 
            { if (c < 0x04000000)
10310
 
                *t++ = (char)(0xF8 | ((c >> 24) & 0x03));
10311
 
              else
10312
 
              { *t++ = (char)(0xFC | ((c >> 30) & 0x01));
10313
 
                *t++ = (char)(0x80 | ((c >> 24) & 0x3F));
10314
 
              }
10315
 
              *t++ = (char)(0x80 | ((c >> 18) & 0x3F));
10316
 
            }     
10317
 
            *t++ = (char)(0x80 | ((c >> 12) & 0x3F));
10318
 
          }
10319
 
          *t++ = (char)(0x80 | ((c >> 6) & 0x3F));
10320
 
        }
10321
 
        *t++ = (char)(0x80 | (c & 0x3F));
10322
 
      }
10323
 
    }
10324
 
    *t = '\0';
10325
 
  }
10326
 
  return r;
10327
 
}
10328
 
#endif
10329
 
 
10330
 
/******************************************************************************/
10331
 
#ifndef PALM_2
10332
 
SOAP_FMAC1
10333
 
int
10334
 
SOAP_FMAC2
10335
 
soap_outstring(struct soap *soap, const char *tag, int id, char *const*p, const char *type, int n) 
10336
 
{ id = soap_element_id(soap, tag, id, *p, NULL, 0, type, n);
10337
 
  if (id < 0)
10338
 
    return soap->error;
10339
 
  if (!**p && (soap->mode & SOAP_C_NILSTRING))
10340
 
    return soap_element_null(soap, tag, id, type);
10341
 
  if (soap_element_begin_out(soap, tag, id, type)
10342
 
   || soap_string_out(soap, *p, 0)
10343
 
   || soap_element_end_out(soap, tag))
10344
 
    return soap->error;
10345
 
  return SOAP_OK;
10346
 
}
10347
 
#endif
10348
 
 
10349
 
/******************************************************************************/
10350
 
#ifndef PALM_2
10351
 
SOAP_FMAC1
10352
 
char **
10353
 
SOAP_FMAC2
10354
 
soap_instring(struct soap *soap, const char *tag, char **p, const char *type, int t, int flag, long minlen, long maxlen)
10355
 
{ if (soap_element_begin_in(soap, tag, 1, NULL))
10356
 
  { if (!tag || *tag != '-' || soap->error != SOAP_NO_TAG)
10357
 
      return NULL;
10358
 
    soap->error = SOAP_OK;
10359
 
  }
10360
 
  if (!p)
10361
 
  { if (!(p = (char**)soap_malloc(soap, sizeof(char*))))
10362
 
      return NULL;
10363
 
  }
10364
 
  if (soap->body)
10365
 
  { *p = soap_string_in(soap, flag, minlen, maxlen);
10366
 
    if (!*p || !(char*)soap_id_enter(soap, soap->id, *p, t, sizeof(char*), 0, NULL, NULL, NULL))
10367
 
      return NULL;
10368
 
    if (!**p && tag && *tag == '-')
10369
 
    { soap->error = SOAP_NO_TAG;
10370
 
      return NULL;
10371
 
    }
10372
 
  }
10373
 
  else if (tag && *tag == '-')
10374
 
  { soap->error = SOAP_NO_TAG;
10375
 
    return NULL;
10376
 
  }
10377
 
  else if (soap->null)
10378
 
    *p = NULL;
10379
 
  else
10380
 
    *p = (char*)SOAP_STR_EOS;
10381
 
  if (*soap->href)
10382
 
    p = (char**)soap_id_lookup(soap, soap->href, (void**)p, t, sizeof(char**), 0);
10383
 
  if (soap->body && soap_element_end_in(soap, tag))
10384
 
    return NULL;
10385
 
  return p;
10386
 
}
10387
 
#endif
10388
 
 
10389
 
/******************************************************************************/
10390
 
#ifndef WITH_LEANER
10391
 
#ifndef PALM_2
10392
 
SOAP_FMAC1
10393
 
int
10394
 
SOAP_FMAC2
10395
 
soap_outwstring(struct soap *soap, const char *tag, int id, wchar_t *const*p, const char *type, int n) 
10396
 
{ id = soap_element_id(soap, tag, id, *p, NULL, 0, type, n);
10397
 
  if (id < 0)
10398
 
    return soap->error;
10399
 
  if (!**p && (soap->mode & SOAP_C_NILSTRING))
10400
 
    return soap_element_null(soap, tag, id, type);
10401
 
  if (soap_element_begin_out(soap, tag, id, type)
10402
 
   || soap_wstring_out(soap, *p, 0)
10403
 
   || soap_element_end_out(soap, tag))
10404
 
    return soap->error;
10405
 
  return SOAP_OK;
10406
 
}
10407
 
#endif
10408
 
#endif
10409
 
 
10410
 
/******************************************************************************/
10411
 
#ifndef WITH_LEANER
10412
 
#ifndef PALM_2
10413
 
SOAP_FMAC1
10414
 
wchar_t **
10415
 
SOAP_FMAC2
10416
 
soap_inwstring(struct soap *soap, const char *tag, wchar_t **p, const char *type, int t, long minlen, long maxlen)
10417
 
{ if (soap_element_begin_in(soap, tag, 1, NULL))
10418
 
  { if (!tag || *tag != '-' || soap->error != SOAP_NO_TAG)
10419
 
      return NULL;
10420
 
    soap->error = SOAP_OK;
10421
 
  }
10422
 
  if (!p)
10423
 
  { if (!(p = (wchar_t**)soap_malloc(soap, sizeof(wchar_t*))))
10424
 
      return NULL;
10425
 
  }
10426
 
  if (soap->body)
10427
 
  { *p = soap_wstring_in(soap, 1, minlen, maxlen);
10428
 
    if (!*p || !(wchar_t*)soap_id_enter(soap, soap->id, *p, t, sizeof(wchar_t*), 0, NULL, NULL, NULL))
10429
 
      return NULL;
10430
 
    if (!**p && tag && *tag == '-')
10431
 
    { soap->error = SOAP_NO_TAG;
10432
 
      return NULL;
10433
 
    }
10434
 
  }
10435
 
  else if (tag && *tag == '-')
10436
 
  { soap->error = SOAP_NO_TAG;
10437
 
    return NULL;
10438
 
  }
10439
 
  else if (soap->null)
10440
 
    *p = NULL;
10441
 
  else
10442
 
    *p = (wchar_t*)SOAP_STR_EOS;
10443
 
  if (*soap->href)
10444
 
    p = (wchar_t**)soap_id_lookup(soap, soap->href, (void**)p, t, sizeof(wchar_t**), 0);
10445
 
  if (soap->body && soap_element_end_in(soap, tag))
10446
 
    return NULL;
10447
 
  return p;
10448
 
}
10449
 
#endif
10450
 
#endif
10451
 
 
10452
 
/******************************************************************************/
10453
 
#ifndef WITH_LEAN
10454
 
SOAP_FMAC1
10455
 
time_t
10456
 
SOAP_FMAC2
10457
 
soap_timegm(struct tm *T)
10458
 
{
10459
 
#if defined(HAVE_TIMEGM)
10460
 
  return timegm(T);
10461
 
#else
10462
 
  time_t t, g, z;
10463
 
  struct tm tm;
10464
 
  t = mktime(T);
10465
 
  if (t == -1)
10466
 
    return -1;
10467
 
#ifdef HAVE_GMTIME_R
10468
 
  gmtime_r(&t, &tm);
10469
 
#else
10470
 
  tm = *gmtime(&t);
10471
 
#endif
10472
 
  tm.tm_isdst = 0;
10473
 
  g = mktime(&tm);
10474
 
  if (g == -1)
10475
 
    return -1;
10476
 
  z = g - t;
10477
 
  return t - z;
10478
 
#endif
10479
 
}
10480
 
#endif
10481
 
 
10482
 
/******************************************************************************/
10483
 
#ifndef WITH_LEAN
10484
 
SOAP_FMAC1
10485
 
const char*
10486
 
SOAP_FMAC2
10487
 
soap_dateTime2s(struct soap *soap, time_t n)
10488
 
{ struct tm T, *pT = &T;
10489
 
#if defined(HAVE_GMTIME_R)
10490
 
  if (gmtime_r(&n, pT))
10491
 
    strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT);
10492
 
  /* The following defines were added for VxWorks*/
10493
 
#elif defined(HAVE_PGMTIME_R)
10494
 
  if (gmtime_r(&n, pT))
10495
 
    strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT);
10496
 
#elif defined(HAVE_PGMTIME)
10497
 
  if (gmtime(&n, pT))
10498
 
    strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT);
10499
 
#elif defined(HAVE_GMTIME)
10500
 
  if ((pT = gmtime(&n)))
10501
 
    strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%SZ", pT);
10502
 
#elif defined(HAVE_GETTIMEOFDAY)
10503
 
  struct timezone tz;
10504
 
  memset((void*)&tz, 0, sizeof(tz));
10505
 
# if defined(HAVE_LOCALTIME_R)
10506
 
  if (localtime_r(&n, pT))
10507
 
  { struct timeval tv;
10508
 
    gettimeofday(&tv, &tz);
10509
 
    strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
10510
 
    sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -tz.tz_minuteswest/60+(pT->tm_isdst!=0), abs(tz.tz_minuteswest)%60);
10511
 
  }
10512
 
# else
10513
 
  if ((pT = localtime(&n)))
10514
 
  { struct timeval tv;
10515
 
    gettimeofday(&tv, &tz);
10516
 
    strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
10517
 
    sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -tz.tz_minuteswest/60+(pT->tm_isdst!=0), abs(tz.tz_minuteswest)%60);
10518
 
  }
10519
 
#endif
10520
 
#elif defined(HAVE_FTIME)
10521
 
  struct timeb t;
10522
 
  memset((void*)&t, 0, sizeof(t));
10523
 
# if defined(HAVE_LOCALTIME_R)
10524
 
  if (localtime_r(&n, pT))
10525
 
  {
10526
 
#ifdef __BORLANDC__
10527
 
    ::ftime(&t);
10528
 
#else
10529
 
    ftime(&t);
10530
 
#endif
10531
 
    strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
10532
 
    sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -t.timezone/60+(pT->tm_isdst!=0), abs(t.timezone)%60);
10533
 
  }
10534
 
  /* The following defines were added for VxWorks*/
10535
 
# elif defined(HAVE_PLOCALTIME_R)
10536
 
  if (localtime_r(&n, pT))
10537
 
  { strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
10538
 
    sprintf(soap->tmpbuf+strlen(soap->tmpbuf), "%+03d:%02d", t.timezone/60, abs(t.timezone)%60);
10539
 
  }
10540
 
# else
10541
 
  if ((pT = localtime(&n)))
10542
 
  {
10543
 
#ifdef __BORLANDC__
10544
 
    ::ftime(&t);
10545
 
#else
10546
 
    ftime(&t);
10547
 
#endif
10548
 
    strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
10549
 
    sprintf(soap->tmpbuf + strlen(soap->tmpbuf), "%+03d:%02d", -t.timezone/60+(pT->tm_isdst!=0), abs(t.timezone)%60);
10550
 
  }
10551
 
# endif
10552
 
#elif defined(HAVE_LOCALTIME_R)
10553
 
  if (localtime_r(&n, pT))
10554
 
    strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
10555
 
  /* The following defines were added for VxWorks*/
10556
 
#elif defined(HAVE_PLOCALTIME_R)
10557
 
  if (localtime_r(&n, pT))
10558
 
    strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
10559
 
#else
10560
 
  if ((pT = localtime(&n)))
10561
 
    strftime(soap->tmpbuf, sizeof(soap->tmpbuf), "%Y-%m-%dT%H:%M:%S", pT);
10562
 
#endif
10563
 
  else
10564
 
    strcpy(soap->tmpbuf, "1969-12-31T23:59:59Z");
10565
 
  return soap->tmpbuf;
10566
 
}
10567
 
#endif
10568
 
 
10569
 
/******************************************************************************/
10570
 
#ifndef WITH_LEAN
10571
 
SOAP_FMAC1
10572
 
int
10573
 
SOAP_FMAC2
10574
 
soap_outdateTime(struct soap *soap, const char *tag, int id, const time_t *p, const char *type, int n)
10575
 
{ if (soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, p, n), type)
10576
 
   || soap_string_out(soap, soap_dateTime2s(soap, *p), 0))
10577
 
    return soap->error;
10578
 
  return soap_element_end_out(soap, tag);
10579
 
}
10580
 
#endif
10581
 
 
10582
 
/******************************************************************************/
10583
 
#ifndef WITH_LEAN
10584
 
SOAP_FMAC1
10585
 
int
10586
 
SOAP_FMAC2
10587
 
soap_s2dateTime(struct soap *soap, const char *s, time_t *p)
10588
 
{ if (s)
10589
 
  { struct tm T;
10590
 
    char zone[32];
10591
 
    const char *t;
10592
 
    memset((void*)&T, 0, sizeof(T));
10593
 
    zone[sizeof(zone)-1] = '\0';
10594
 
    if (strchr(s, '-'))
10595
 
      t = "%d-%d-%dT%d:%d:%d%31s";
10596
 
    else if (strchr(s, ':'))
10597
 
      t = "%4d%2d%2dT%d:%d:%d%31s";
10598
 
    else /* parse non-XSD-standard alternative ISO 8601 format */
10599
 
      t = "%4d%2d%2dT%2d%2d%2d%31s";
10600
 
    sscanf(s, t, &T.tm_year, &T.tm_mon, &T.tm_mday, &T.tm_hour, &T.tm_min, &T.tm_sec, zone);
10601
 
    if (T.tm_year == 1)
10602
 
      T.tm_year = 70;
10603
 
    else
10604
 
      T.tm_year -= 1900;
10605
 
    T.tm_mon--;
10606
 
    if (*zone)
10607
 
    { if (*zone == '.')
10608
 
      { for (s = zone + 1; *s; s++)
10609
 
          if (*s < '0' || *s > '9')
10610
 
            break;
10611
 
      }
10612
 
      else
10613
 
        s = zone;
10614
 
      if (*s == '+' || *s == '-')
10615
 
      { int h = 0, m = 0;
10616
 
        if (s[3] == ':')
10617
 
        { sscanf(s, "%d:%d", &h, &m);
10618
 
          if (h < 0)
10619
 
            m = -m;
10620
 
        }
10621
 
        else
10622
 
        { m = (int)atol(s);
10623
 
          h = m / 100;
10624
 
          m = m % 100;
10625
 
        }
10626
 
        T.tm_hour -= h;
10627
 
        T.tm_min -= m;
10628
 
      }
10629
 
      T.tm_isdst = 0;
10630
 
      *p = soap_timegm(&T);
10631
 
    }
10632
 
    else
10633
 
    { T.tm_isdst = -1;
10634
 
      *p = mktime(&T); /* no time zone: suppose it is localtime? */
10635
 
    }
10636
 
  }
10637
 
  return soap->error;
10638
 
}
10639
 
#endif
10640
 
 
10641
 
/******************************************************************************/
10642
 
#ifndef WITH_LEAN
10643
 
SOAP_FMAC1
10644
 
time_t *
10645
 
SOAP_FMAC2
10646
 
soap_indateTime(struct soap *soap, const char *tag, time_t *p, const char *type, int t)
10647
 
{ if (soap_element_begin_in(soap, tag, 0, NULL))
10648
 
    return NULL;
10649
 
  if (*soap->type
10650
 
   && soap_match_tag(soap, soap->type, type)
10651
 
   && soap_match_tag(soap, soap->type, ":dateTime"))
10652
 
  { soap->error = SOAP_TYPE;
10653
 
    soap_revert(soap);
10654
 
    return NULL;
10655
 
  }
10656
 
  p = (time_t*)soap_id_enter(soap, soap->id, p, t, sizeof(time_t), 0, NULL, NULL, NULL);
10657
 
  if (*soap->href)
10658
 
    p = (time_t*)soap_id_forward(soap, soap->href, p, 0, t, 0, sizeof(time_t), 0, NULL);
10659
 
  else if (p)
10660
 
  { if (soap_s2dateTime(soap, soap_value(soap), p))
10661
 
      return NULL;
10662
 
  }
10663
 
  if (soap->body && soap_element_end_in(soap, tag))
10664
 
    return NULL;
10665
 
  return p;
10666
 
}
10667
 
#endif
10668
 
 
10669
 
/******************************************************************************/
10670
 
#ifndef PALM_2
10671
 
SOAP_FMAC1
10672
 
int
10673
 
SOAP_FMAC2
10674
 
soap_outliteral(struct soap *soap, const char *tag, char *const*p, const char *type)
10675
 
{ int i;
10676
 
  const char *t = NULL;
10677
 
  if (tag && *tag != '-')
10678
 
  { if (soap->local_namespaces && (t = strchr(tag, ':')))
10679
 
    { strncpy(soap->tmpbuf, tag, t-tag);
10680
 
      soap->tmpbuf[t-tag] = '\0';
10681
 
      for (i = 0; soap->local_namespaces[i].id; i++)
10682
 
        if (!strcmp(soap->tmpbuf, soap->local_namespaces[i].id))
10683
 
          break;
10684
 
      t++;
10685
 
      if (soap_element(soap, t, 0, type)
10686
 
       || soap_attribute(soap, "xmlns", soap->local_namespaces[i].ns ? soap->local_namespaces[i].ns : SOAP_STR_EOS)
10687
 
       || soap_element_start_end_out(soap, NULL))
10688
 
        return soap->error;
10689
 
    }
10690
 
    else
10691
 
    { t = tag;
10692
 
      if (soap_element_begin_out(soap, t, 0, type))
10693
 
        return soap->error;
10694
 
    }
10695
 
  }
10696
 
  if (p && *p)
10697
 
  { if (soap_send(soap, *p))
10698
 
      return soap->error;
10699
 
  }
10700
 
  if (t)
10701
 
    return soap_element_end_out(soap, t);
10702
 
  return SOAP_OK;
10703
 
}
10704
 
#endif
10705
 
 
10706
 
/******************************************************************************/
10707
 
#ifndef PALM_2
10708
 
SOAP_FMAC1
10709
 
char **
10710
 
SOAP_FMAC2
10711
 
soap_inliteral(struct soap *soap, const char *tag, char **p)
10712
 
{ if (soap_element_begin_in(soap, tag, 1, NULL))
10713
 
  { if (soap->error != SOAP_NO_TAG || soap_unget(soap, soap_get(soap)) == SOAP_TT)
10714
 
      return NULL;
10715
 
    soap->error = SOAP_OK;
10716
 
  }
10717
 
  if (!p)
10718
 
  { if (!(p = (char**)soap_malloc(soap, sizeof(char*))))
10719
 
      return NULL;
10720
 
  }
10721
 
  if (soap->body)
10722
 
  { *p = soap_string_in(soap, 0, -1, -1);
10723
 
    if (!*p)
10724
 
      return NULL;
10725
 
    if (!**p && tag && *tag == '-')
10726
 
    { soap->error = SOAP_NO_TAG;
10727
 
      return NULL;
10728
 
    }
10729
 
  }
10730
 
  else if (tag && *tag == '-')
10731
 
  { soap->error = SOAP_NO_TAG;
10732
 
    return NULL;
10733
 
  }
10734
 
  else if (soap->null)
10735
 
    *p = NULL;
10736
 
  else
10737
 
    *p = (char*)SOAP_STR_EOS;
10738
 
  if (soap->body && soap_element_end_in(soap, tag))
10739
 
    return NULL;
10740
 
  return p;
10741
 
}
10742
 
#endif
10743
 
 
10744
 
/******************************************************************************/
10745
 
#ifndef WITH_LEANER
10746
 
#ifndef PALM_2
10747
 
SOAP_FMAC1
10748
 
int
10749
 
SOAP_FMAC2
10750
 
soap_outwliteral(struct soap *soap, const char *tag, wchar_t *const*p, const char *type)
10751
 
{ int i;
10752
 
  const char *t = NULL;
10753
 
  if (tag && *tag != '-')
10754
 
  { if (soap->local_namespaces && (t = strchr(tag, ':')))
10755
 
    { strncpy(soap->tmpbuf, tag, t-tag);
10756
 
      soap->tmpbuf[t-tag] = '\0';
10757
 
      for (i = 0; soap->local_namespaces[i].id; i++)
10758
 
        if (!strcmp(soap->tmpbuf, soap->local_namespaces[i].id))
10759
 
          break;
10760
 
      t++;
10761
 
      if (soap_element(soap, t, 0, type)
10762
 
       || soap_attribute(soap, "xmlns", soap->local_namespaces[i].ns ? soap->local_namespaces[i].ns : SOAP_STR_EOS)
10763
 
       || soap_element_start_end_out(soap, NULL))
10764
 
        return soap->error;
10765
 
    }
10766
 
    else
10767
 
    { t = tag;
10768
 
      if (soap_element_begin_out(soap, t, 0, type))
10769
 
        return soap->error;
10770
 
    }
10771
 
    if (soap_send(soap, soap->tmpbuf))
10772
 
      return soap->error;
10773
 
  }
10774
 
  if (p)
10775
 
  { wchar_t c;
10776
 
    const wchar_t *s = *p;
10777
 
    while ((c = *s++))
10778
 
    { if (soap_pututf8(soap, (unsigned long)c))
10779
 
        return soap->error;
10780
 
    }
10781
 
  }
10782
 
  if (t)
10783
 
    return soap_element_end_out(soap, t);
10784
 
  return SOAP_OK;
10785
 
}
10786
 
#endif
10787
 
#endif
10788
 
 
10789
 
/******************************************************************************/
10790
 
#ifndef WITH_LEANER
10791
 
#ifndef PALM_2
10792
 
SOAP_FMAC1
10793
 
wchar_t **
10794
 
SOAP_FMAC2
10795
 
soap_inwliteral(struct soap *soap, const char *tag, wchar_t **p)
10796
 
{ if (soap_element_begin_in(soap, tag, 1, NULL))
10797
 
  { if (soap->error != SOAP_NO_TAG || soap_unget(soap, soap_get(soap)) == SOAP_TT)
10798
 
      return NULL;
10799
 
    soap->error = SOAP_OK;
10800
 
  }
10801
 
  if (!p)
10802
 
  { if (!(p = (wchar_t**)soap_malloc(soap, sizeof(wchar_t*))))
10803
 
      return NULL;
10804
 
  }
10805
 
  if (soap->body)
10806
 
  { *p = soap_wstring_in(soap, 0, -1, -1);
10807
 
    if (!*p)
10808
 
      return NULL;
10809
 
    if (!**p && tag && *tag == '-')
10810
 
    { soap->error = SOAP_NO_TAG;
10811
 
      return NULL;
10812
 
    }
10813
 
  }
10814
 
  else if (tag && *tag == '-')
10815
 
  { soap->error = SOAP_NO_TAG;
10816
 
    return NULL;
10817
 
  }
10818
 
  else if (soap->null)
10819
 
    *p = NULL;
10820
 
  else
10821
 
    *p = (wchar_t*)SOAP_STR_EOS;
10822
 
  if (soap->body && soap_element_end_in(soap, tag))
10823
 
    return NULL;
10824
 
  return p;
10825
 
}
10826
 
#endif
10827
 
#endif
10828
 
 
10829
 
/******************************************************************************/
10830
 
#ifndef PALM_2
10831
 
SOAP_FMAC1
10832
 
const char *
10833
 
SOAP_FMAC2
10834
 
soap_value(struct soap *soap)
10835
 
{ register size_t i;
10836
 
  register soap_wchar c = 0;
10837
 
  register char *s = soap->tmpbuf;
10838
 
  if (!soap->body)
10839
 
    return SOAP_STR_EOS;
10840
 
  do c = soap_get(soap);
10841
 
  while (soap_blank(c));
10842
 
  for (i = 0; i < sizeof(soap->tmpbuf) - 1; i++)
10843
 
  { if (c == SOAP_TT || (int)c == EOF)
10844
 
      break;
10845
 
    *s++ = (char)c;
10846
 
    c = soap_get(soap);
10847
 
  }
10848
 
  for (s--; i > 0; i--, s--)
10849
 
  { if (!soap_blank(*s))
10850
 
      break;
10851
 
  }
10852
 
  s[1] = '\0';
10853
 
  if ((int)c == EOF || c == SOAP_TT)
10854
 
    soap_unget(soap, c);
10855
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Element content value='%s'\n", soap->tmpbuf));
10856
 
#ifdef WITH_DOM
10857
 
  if ((soap->mode & SOAP_XML_DOM) && soap->dom)
10858
 
    soap->dom->data = soap_strdup(soap, soap->tmpbuf);
10859
 
#endif
10860
 
  return soap->tmpbuf; /* return non-null pointer */
10861
 
}
10862
 
#endif
10863
 
 
10864
 
/******************************************************************************/
10865
 
#if !defined(WITH_LEANER) || !defined(WITH_NOHTTP)
10866
 
#ifndef PALM_2
10867
 
SOAP_FMAC1
10868
 
int
10869
 
SOAP_FMAC2
10870
 
soap_getline(struct soap *soap, char *s, int len)
10871
 
{ int i = len;
10872
 
  soap_wchar c = 0;
10873
 
  for (;;)
10874
 
  { while (--i > 0)
10875
 
    { c = soap_getchar(soap);
10876
 
      if (c == '\r' || c == '\n')
10877
 
        break;
10878
 
      if ((int)c == EOF)
10879
 
        return soap->error = SOAP_EOF;
10880
 
      *s++ = (char)c;
10881
 
    }
10882
 
    if (c != '\n')
10883
 
      c = soap_getchar(soap); /* got \r or something else, now get \n */
10884
 
    if (c == '\n')
10885
 
    { *s = '\0';
10886
 
      if (i+1 == len) /* empty line: end of HTTP/MIME header */
10887
 
        break;
10888
 
      c = soap_unget(soap, soap_getchar(soap));
10889
 
      if (c != ' ' && c != '\t') /* HTTP line continuation? */
10890
 
        break;
10891
 
    }
10892
 
    else if ((int)c == EOF)
10893
 
      return soap->error = SOAP_EOF;
10894
 
  }
10895
 
  if (i < 0)
10896
 
    return soap->error = SOAP_HDR;
10897
 
  return SOAP_OK;
10898
 
}
10899
 
#endif
10900
 
#endif
10901
 
 
10902
 
/******************************************************************************/
10903
 
#ifndef PALM_1
10904
 
static size_t
10905
 
soap_count_attachments(struct soap *soap)
10906
 
10907
 
#ifndef WITH_LEANER
10908
 
  register struct soap_multipart *content;
10909
 
  register size_t count = soap->count;
10910
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the message size with attachments, current count=%lu\n", (unsigned long)count));
10911
 
  if ((soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM))
10912
 
  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the size of DIME attachments\n"));
10913
 
    for (content = soap->dime.first; content; content = content->next)
10914
 
    { count += 12 + ((content->size+3)&(~3));
10915
 
      if (content->id)
10916
 
        count += ((strlen(content->id)+3)&(~3));
10917
 
      if (content->type)
10918
 
        count += ((strlen(content->type)+3)&(~3));
10919
 
      if (content->options)
10920
 
        count += ((((unsigned char)content->options[2] << 8) | ((unsigned char)content->options[3]))+7)&(~3);
10921
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Size of DIME attachment content is %lu bytes\n", (unsigned long)content->size));
10922
 
    }
10923
 
  }
10924
 
  if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary)
10925
 
  { register size_t n = strlen(soap->mime.boundary);
10926
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Calculating the size of MIME attachments\n"));
10927
 
    for (content = soap->mime.first; content; content = content->next)
10928
 
    { register const char *s;
10929
 
      /* count \r\n--boundary\r\n */
10930
 
      count += 6 + n;
10931
 
      /* count Content-Type: ...\r\n */
10932
 
      if (content->type)
10933
 
        count += 16 + strlen(content->type);
10934
 
      /* count Content-Transfer-Encoding: ...\r\n */
10935
 
      s = soap_code_str(mime_codes, content->encoding);
10936
 
      if (s)
10937
 
        count += 29 + strlen(s);
10938
 
      /* count Content-ID: ...\r\n */
10939
 
      if (content->id)
10940
 
        count += 14 + strlen(content->id);
10941
 
      /* count Content-Location: ...\r\n */
10942
 
      if (content->location)
10943
 
        count += 20 + strlen(content->location);
10944
 
      /* count Content-Description: ...\r\n */
10945
 
      if (content->description)
10946
 
        count += 23 + strlen(content->description);
10947
 
      /* count \r\n...content */
10948
 
      count += 2 + content->size;
10949
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Size of MIME attachment content is %lu bytes\n", (unsigned long)content->size));
10950
 
    }
10951
 
    /* count \r\n--boundary-- */
10952
 
    count += 6 + n;
10953
 
  }
10954
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "New count is %lu bytes\n", (unsigned long)count));
10955
 
  return count;
10956
 
#else
10957
 
  return soap->count;
10958
 
#endif
10959
 
}
10960
 
#endif
10961
 
 
10962
 
/******************************************************************************/
10963
 
#ifndef WITH_LEANER
10964
 
#ifndef PALM_1
10965
 
static int
10966
 
soap_putdimefield(struct soap *soap, const char *s, size_t n)
10967
 
{ if (soap_send_raw(soap, s, n))
10968
 
    return soap->error;
10969
 
  return soap_send_raw(soap, SOAP_STR_PADDING, -(long)n&3);
10970
 
}
10971
 
#endif
10972
 
#endif
10973
 
 
10974
 
/******************************************************************************/
10975
 
#ifndef WITH_LEANER
10976
 
#ifndef PALM_1
10977
 
SOAP_FMAC1
10978
 
char *
10979
 
SOAP_FMAC2
10980
 
soap_dime_option(struct soap *soap, unsigned short optype, const char *option)
10981
 
{ size_t n;
10982
 
  char *s = NULL;
10983
 
  if (option)
10984
 
  { n = strlen(option);
10985
 
    s = (char*)soap_malloc(soap, n + 5);
10986
 
    if (s)
10987
 
    { s[0] = (char)(optype >> 8);
10988
 
      s[1] = (char)(optype & 0xFF);
10989
 
      s[2] = (char)(n >> 8);
10990
 
      s[3] = (char)(n & 0xFF);
10991
 
      strcpy(s + 4, option);
10992
 
    }
10993
 
  }
10994
 
  return s;
10995
 
}
10996
 
#endif
10997
 
#endif
10998
 
 
10999
 
/******************************************************************************/
11000
 
#ifndef WITH_LEANER
11001
 
#ifndef PALM_1
11002
 
SOAP_FMAC1
11003
 
int
11004
 
SOAP_FMAC2
11005
 
soap_putdimehdr(struct soap *soap)
11006
 
{ unsigned char tmp[12];
11007
 
  size_t optlen = 0, idlen = 0, typelen = 0;
11008
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Put DIME header id='%s'\n", soap->dime.id?soap->dime.id:""));
11009
 
  if (soap->dime.options)
11010
 
    optlen = (((unsigned char)soap->dime.options[2] << 8) | ((unsigned char)soap->dime.options[3])) + 4;
11011
 
  if (soap->dime.id)
11012
 
  { idlen = strlen(soap->dime.id);
11013
 
    if (idlen > 0x0000FFFF)
11014
 
      idlen = 0x0000FFFF;
11015
 
  }
11016
 
  if (soap->dime.type)
11017
 
  { typelen = strlen(soap->dime.type);
11018
 
    if (typelen > 0x0000FFFF)
11019
 
      typelen = 0x0000FFFF;
11020
 
  }
11021
 
  tmp[0] = SOAP_DIME_VERSION | (soap->dime.flags & 0x7);
11022
 
  tmp[1] = soap->dime.flags & 0xF0;
11023
 
  tmp[2] = (char)(optlen >> 8);
11024
 
  tmp[3] = (char)(optlen & 0xFF);
11025
 
  tmp[4] = (char)(idlen >> 8);
11026
 
  tmp[5] = (char)(idlen & 0xFF);
11027
 
  tmp[6] = (char)(typelen >> 8);
11028
 
  tmp[7] = (char)(typelen & 0xFF);
11029
 
  tmp[8] = (char)(soap->dime.size >> 24);
11030
 
  tmp[9] = (char)((soap->dime.size >> 16) & 0xFF);
11031
 
  tmp[10] = (char)((soap->dime.size >> 8) & 0xFF);
11032
 
  tmp[11] = (char)(soap->dime.size & 0xFF);
11033
 
  if (soap_send_raw(soap, (char*)tmp, 12)
11034
 
   || soap_putdimefield(soap, soap->dime.options, optlen)
11035
 
   || soap_putdimefield(soap, soap->dime.id, idlen)
11036
 
   || soap_putdimefield(soap, soap->dime.type, typelen))
11037
 
    return soap->error;
11038
 
  return SOAP_OK;
11039
 
}
11040
 
#endif
11041
 
#endif
11042
 
 
11043
 
/******************************************************************************/
11044
 
#ifndef WITH_LEANER
11045
 
#ifndef PALM_1
11046
 
SOAP_FMAC1
11047
 
int
11048
 
SOAP_FMAC2
11049
 
soap_putdime(struct soap *soap)
11050
 
{ struct soap_multipart *content;
11051
 
  if (!(soap->mode & SOAP_ENC_DIME))
11052
 
    return SOAP_OK;
11053
 
  for (content = soap->dime.first; content; content = content->next)
11054
 
  { void *handle;
11055
 
    soap->dime.size = content->size;
11056
 
    soap->dime.id = content->id;
11057
 
    soap->dime.type = content->type;
11058
 
    soap->dime.options = content->options;
11059
 
    soap->dime.flags = SOAP_DIME_VERSION | SOAP_DIME_MEDIA;
11060
 
    if (soap->fdimereadopen && ((handle = soap->fdimereadopen(soap, (void*)content->ptr, content->id, content->type, content->options)) || soap->error))
11061
 
    { size_t size = content->size;
11062
 
      if (!handle)
11063
 
      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimereadopen failed\n"));
11064
 
        return soap->error;
11065
 
      }
11066
 
      if (!size && ((soap->mode & SOAP_ENC_XML) || (soap->mode & SOAP_IO) == SOAP_IO_CHUNK || (soap->mode & SOAP_IO) == SOAP_IO_STORE))
11067
 
      { size_t chunksize = sizeof(soap->tmpbuf);
11068
 
        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunked streaming DIME\n"));
11069
 
        do 
11070
 
        { size = soap->fdimeread(soap, handle, soap->tmpbuf, chunksize);
11071
 
          DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimeread returned %lu bytes\n", (unsigned long)size));
11072
 
          if (size < chunksize)
11073
 
          { soap->dime.flags &= ~SOAP_DIME_CF;
11074
 
            if (!content->next)
11075
 
              soap->dime.flags |= SOAP_DIME_ME;
11076
 
          }
11077
 
          else
11078
 
            soap->dime.flags |= SOAP_DIME_CF;
11079
 
          soap->dime.size = size;
11080
 
          if (soap_putdimehdr(soap)
11081
 
           || soap_putdimefield(soap, soap->tmpbuf, size))
11082
 
            break;
11083
 
          if (soap->dime.id)
11084
 
          { soap->dime.flags &= ~(SOAP_DIME_MB | SOAP_DIME_MEDIA);
11085
 
            soap->dime.id = NULL;
11086
 
            soap->dime.type = NULL;
11087
 
            soap->dime.options = NULL;
11088
 
          }  
11089
 
        } while (size >= chunksize);
11090
 
      }
11091
 
      else
11092
 
      { if (!content->next)
11093
 
          soap->dime.flags |= SOAP_DIME_ME;
11094
 
        if (soap_putdimehdr(soap))
11095
 
          return soap->error;
11096
 
        do
11097
 
        { size_t bufsize;
11098
 
          if (size < sizeof(soap->tmpbuf))
11099
 
            bufsize = size;
11100
 
          else
11101
 
            bufsize = sizeof(soap->tmpbuf);
11102
 
          if (!(bufsize = soap->fdimeread(soap, handle, soap->tmpbuf, bufsize)))
11103
 
          { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimeread failed: insufficient data (%lu bytes remaining from %lu bytes)\n", (unsigned long)size, (unsigned long)content->size));
11104
 
            soap->error = SOAP_EOF;
11105
 
            break;
11106
 
          }
11107
 
          if (soap_send_raw(soap, soap->tmpbuf, bufsize))
11108
 
            break;
11109
 
          size -= bufsize;
11110
 
        } while (size);
11111
 
        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimereadclose\n"));
11112
 
        soap_send_raw(soap, SOAP_STR_PADDING, -(long)soap->dime.size&3);
11113
 
      }
11114
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fdimereadclose\n"));
11115
 
      if (soap->fdimereadclose)
11116
 
        soap->fdimereadclose(soap, handle);
11117
 
    }
11118
 
    else
11119
 
    { if (!content->next)
11120
 
        soap->dime.flags |= SOAP_DIME_ME;
11121
 
      if (soap_putdimehdr(soap)
11122
 
       || soap_putdimefield(soap, (char*)content->ptr, content->size))
11123
 
        return soap->error;
11124
 
    }
11125
 
  }
11126
 
  return SOAP_OK;
11127
 
}
11128
 
#endif
11129
 
#endif
11130
 
 
11131
 
/******************************************************************************/
11132
 
#ifndef WITH_LEANER
11133
 
#ifndef PALM_1
11134
 
static char *
11135
 
soap_getdimefield(struct soap *soap, size_t n)
11136
 
{ register soap_wchar c;
11137
 
  register size_t i;
11138
 
  register char *s;
11139
 
  register char *p = NULL;
11140
 
  if (n)
11141
 
  { p = (char*)soap_malloc(soap, n + 1);
11142
 
    if (p)
11143
 
    { s = p;
11144
 
      for (i = n; i > 0; i--)
11145
 
      { if ((int)(c = soap_get1(soap)) == EOF)
11146
 
        { soap->error = SOAP_EOF;
11147
 
          return NULL;
11148
 
        }
11149
 
        *s++ = (char)c;
11150
 
      }
11151
 
      *s = '\0';
11152
 
      if ((soap->error = soap_move(soap, -(long)n&3)))
11153
 
        return NULL;
11154
 
    }
11155
 
    else
11156
 
      soap->error = SOAP_EOM;
11157
 
  }
11158
 
  return p;
11159
 
}
11160
 
#endif
11161
 
#endif
11162
 
 
11163
 
/******************************************************************************/
11164
 
#ifndef WITH_LEANER
11165
 
#ifndef PALM_1
11166
 
SOAP_FMAC1
11167
 
int
11168
 
SOAP_FMAC2
11169
 
soap_getdimehdr(struct soap *soap)
11170
 
{ register soap_wchar c;
11171
 
  register char *s;
11172
 
  register int i;
11173
 
  unsigned char tmp[12];
11174
 
  size_t optlen, idlen, typelen;
11175
 
  if (!(soap->mode & SOAP_ENC_DIME))
11176
 
    return soap->error = SOAP_DIME_END;
11177
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get DIME header\n"));
11178
 
  if (soap->dime.buflen || soap->dime.chunksize)
11179
 
  { if (soap_move(soap, (long)(soap->dime.size - soap_tell(soap))))
11180
 
      return soap->error = SOAP_EOF;
11181
 
    soap_unget(soap, soap_getchar(soap)); /* skip padding and get hdr */
11182
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "... From chunked\n"));
11183
 
    return SOAP_OK;
11184
 
  }
11185
 
  s = (char*)tmp;
11186
 
  for (i = 12; i > 0; i--)
11187
 
  { if ((int)(c = soap_getchar(soap)) == EOF)
11188
 
      return soap->error = SOAP_EOF;
11189
 
    *s++ = (char)c;
11190
 
  }
11191
 
  if ((tmp[0] & 0xF8) != SOAP_DIME_VERSION)
11192
 
    return soap->error = SOAP_DIME_MISMATCH;
11193
 
  soap->dime.flags = (tmp[0] & 0x7) | (tmp[1] & 0xF0);
11194
 
  optlen = (tmp[2] << 8) | tmp[3];
11195
 
  idlen = (tmp[4] << 8) | tmp[5];
11196
 
  typelen = (tmp[6] << 8) | tmp[7];
11197
 
  soap->dime.size = (tmp[8] << 24) | (tmp[9] << 16) | (tmp[10] << 8) | tmp[11];
11198
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME size=%lu flags=0x%X\n", (unsigned long)soap->dime.size, soap->dime.flags));
11199
 
  if (!(soap->dime.options = soap_getdimefield(soap, optlen)) && soap->error)
11200
 
    return soap->error;
11201
 
  if (!(soap->dime.id = soap_getdimefield(soap, idlen)) && soap->error)
11202
 
    return soap->error;
11203
 
  if (!(soap->dime.type = soap_getdimefield(soap, typelen)) && soap->error)
11204
 
    return soap->error;
11205
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DIME id=%s, type=%s, options=%s\n", soap->dime.id?soap->dime.id:"", soap->dime.type?soap->dime.type:"", soap->dime.options?soap->dime.options+4:""));
11206
 
  if (soap->dime.flags & SOAP_DIME_ME)
11207
 
    soap->mode &= ~SOAP_ENC_DIME;
11208
 
  return SOAP_OK;
11209
 
}
11210
 
#endif
11211
 
#endif
11212
 
 
11213
 
/******************************************************************************/
11214
 
#ifndef WITH_LEANER
11215
 
#ifndef PALM_1
11216
 
SOAP_FMAC1
11217
 
int
11218
 
SOAP_FMAC2
11219
 
soap_getdime(struct soap *soap)
11220
 
{ while (soap->dime.flags & SOAP_DIME_CF)
11221
 
  { if (soap_getdimehdr(soap))
11222
 
      return soap->error;
11223
 
    if (soap_move(soap, (long)soap->dime.size))
11224
 
      return soap->error = SOAP_EOF;
11225
 
  }
11226
 
  if (soap_move(soap, (long)(((soap->dime.size+3)&(~3))-soap_tell(soap))))
11227
 
    return soap->error = SOAP_EOF;
11228
 
  for (;;)
11229
 
  { register struct soap_multipart *content;
11230
 
    if (soap_getdimehdr(soap))
11231
 
      break;
11232
 
    if (soap->fdimewriteopen && ((soap->dime.ptr = (char*)soap->fdimewriteopen(soap, soap->dime.id, soap->dime.type, soap->dime.options)) || soap->error))
11233
 
    { const char *id, *type, *options;
11234
 
      size_t size, n;
11235
 
      if (!soap->dime.ptr)
11236
 
        return soap->error;
11237
 
      id = soap->dime.id;
11238
 
      type = soap->dime.type;
11239
 
      options = soap->dime.options;
11240
 
      for (;;)
11241
 
      { size = soap->dime.size;
11242
 
        for (;;)
11243
 
        { n = soap->buflen - soap->bufidx;
11244
 
          if (size < n)
11245
 
            n = size;
11246
 
          if ((soap->error = soap->fdimewrite(soap, (void*)soap->dime.ptr, soap->buf + soap->bufidx, n)))
11247
 
            break;
11248
 
          size -= n;
11249
 
          if (!size)
11250
 
          { soap->bufidx += n;
11251
 
            break;
11252
 
          }
11253
 
          if (soap_recv(soap))
11254
 
          { soap->error = SOAP_EOF;
11255
 
            goto end;
11256
 
          }
11257
 
        }
11258
 
        if (soap_move(soap, -(long)soap->dime.size&3))
11259
 
        { soap->error = SOAP_EOF;
11260
 
          break;
11261
 
        }
11262
 
        if (!(soap->dime.flags & SOAP_DIME_CF))
11263
 
          break;
11264
 
        if (soap_getdimehdr(soap))
11265
 
          break;
11266
 
      }
11267
 
end:
11268
 
      if (soap->fdimewriteclose)
11269
 
        soap->fdimewriteclose(soap, (void*)soap->dime.ptr);
11270
 
      soap->dime.size = 0;
11271
 
      soap->dime.id = id;
11272
 
      soap->dime.type = type;
11273
 
      soap->dime.options = options;
11274
 
    }
11275
 
    else if (soap->dime.flags & SOAP_DIME_CF)
11276
 
    { const char *id, *type, *options;
11277
 
      id = soap->dime.id;
11278
 
      type = soap->dime.type;
11279
 
      options = soap->dime.options;
11280
 
      if (soap_new_block(soap))
11281
 
        return SOAP_EOM;
11282
 
      for (;;)
11283
 
      { register soap_wchar c;
11284
 
        register size_t i;
11285
 
        register char *s;
11286
 
        s = (char*)soap_push_block(soap, soap->dime.size);
11287
 
        if (!s)
11288
 
          return soap->error = SOAP_EOM;
11289
 
        for (i = soap->dime.size; i > 0; i--)
11290
 
        { if ((int)(c = soap_get1(soap)) == EOF)
11291
 
            return soap->error = SOAP_EOF;
11292
 
          *s++ = (char)c;
11293
 
        }
11294
 
        if (soap_move(soap, -(long)soap->dime.size&3))
11295
 
          return soap->error = SOAP_EOF;
11296
 
        if (!(soap->dime.flags & SOAP_DIME_CF))
11297
 
          break;
11298
 
        if (soap_getdimehdr(soap))
11299
 
          return soap->error;
11300
 
      }
11301
 
      soap->dime.size = soap->blist->size++; /* allocate one more for '\0' */
11302
 
      if (!(soap->dime.ptr = soap_save_block(soap, NULL, 0)))
11303
 
        return soap->error;
11304
 
      soap->dime.ptr[soap->dime.size] = '\0'; /* force 0-terminated */
11305
 
      soap->dime.id = id;
11306
 
      soap->dime.type = type;
11307
 
      soap->dime.options = options;
11308
 
    }
11309
 
    else
11310
 
      soap->dime.ptr = soap_getdimefield(soap, soap->dime.size);
11311
 
    content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, soap->dime.ptr, soap->dime.size);
11312
 
    if (!content)
11313
 
      return soap->error = SOAP_EOM;
11314
 
    content->id = soap->dime.id;
11315
 
    content->type = soap->dime.type;
11316
 
    content->options = soap->dime.options;
11317
 
    if (soap->error)
11318
 
      return soap->error;
11319
 
    soap_resolve_attachment(soap, content);
11320
 
  }
11321
 
  if (soap->error != SOAP_DIME_END)
11322
 
    return soap->error;
11323
 
  return soap->error = SOAP_OK;
11324
 
}
11325
 
#endif
11326
 
#endif
11327
 
 
11328
 
/******************************************************************************/
11329
 
#ifndef WITH_LEANER
11330
 
#ifndef PALM_1
11331
 
SOAP_FMAC1
11332
 
int
11333
 
SOAP_FMAC2
11334
 
soap_getmimehdr(struct soap *soap)
11335
 
{ struct soap_multipart *content;
11336
 
  do
11337
 
  { if (soap_getline(soap, soap->msgbuf, sizeof(soap->msgbuf)))
11338
 
      return soap->error;
11339
 
  }
11340
 
  while (!*soap->msgbuf);
11341
 
  if (soap->msgbuf[0] == '-' && soap->msgbuf[1] == '-')
11342
 
  { char *s = soap->msgbuf + strlen(soap->msgbuf) - 1;
11343
 
    /* remove white space */
11344
 
    while (soap_blank(*s))
11345
 
      s--;
11346
 
    s[1] = '\0';
11347
 
    if (soap->mime.boundary)
11348
 
    { if (strcmp(soap->msgbuf + 2, soap->mime.boundary))
11349
 
        return soap->error = SOAP_MIME_ERROR;
11350
 
    }
11351
 
    else
11352
 
      soap->mime.boundary = soap_strdup(soap, soap->msgbuf + 2);
11353
 
    if (soap_getline(soap, soap->msgbuf, sizeof(soap->msgbuf)))
11354
 
      return soap->error;
11355
 
  }
11356
 
  if (soap_set_mime_attachment(soap, NULL, 0, SOAP_MIME_NONE, NULL, NULL, NULL, NULL))
11357
 
    return soap->error = SOAP_EOM;
11358
 
  content = soap->mime.last;
11359
 
  for (;;)
11360
 
  { register char *key = soap->msgbuf;
11361
 
    register char *val;
11362
 
    if (!*key)
11363
 
      break;
11364
 
    DBGLOG(TEST,SOAP_MESSAGE(fdebug, "MIME header: %s\n", key));
11365
 
    val = strchr(soap->msgbuf, ':');
11366
 
    if (val)
11367
 
    { *val = '\0';
11368
 
      do val++;
11369
 
      while (*val && *val <= 32);
11370
 
      if (!soap_tag_cmp(key, "Content-ID"))
11371
 
        content->id = soap_strdup(soap, val);
11372
 
      else if (!soap_tag_cmp(key, "Content-Location"))
11373
 
        content->location = soap_strdup(soap, val);
11374
 
      else if (!soap_tag_cmp(key, "Content-Disposition"))
11375
 
        content->id = soap_strdup(soap, soap_get_header_attribute(soap, val, "name"));
11376
 
      else if (!soap_tag_cmp(key, "Content-Type"))
11377
 
        content->type = soap_strdup(soap, val);
11378
 
      else if (!soap_tag_cmp(key, "Content-Description"))
11379
 
        content->description = soap_strdup(soap, val);
11380
 
      else if (!soap_tag_cmp(key, "Content-Transfer-Encoding"))
11381
 
        content->encoding = (enum soap_mime_encoding)soap_code_int(mime_codes, val, (long)SOAP_MIME_NONE);
11382
 
    }
11383
 
    if (soap_getline(soap, key, sizeof(soap->msgbuf)))
11384
 
      return soap->error;
11385
 
  }
11386
 
  return SOAP_OK;
11387
 
}
11388
 
#endif
11389
 
#endif
11390
 
 
11391
 
/******************************************************************************/
11392
 
#ifndef WITH_LEANER
11393
 
#ifndef PALM_1
11394
 
SOAP_FMAC1
11395
 
int
11396
 
SOAP_FMAC2
11397
 
soap_getmime(struct soap *soap)
11398
 
{ while (soap_get_mime_attachment(soap, NULL))
11399
 
    ;
11400
 
  return soap->error;
11401
 
}
11402
 
#endif
11403
 
#endif
11404
 
 
11405
 
/******************************************************************************/
11406
 
#ifndef WITH_LEANER
11407
 
#ifndef PALM_1
11408
 
SOAP_FMAC1
11409
 
void
11410
 
SOAP_FMAC2
11411
 
soap_post_check_mime_attachments(struct soap *soap)
11412
 
{ soap->imode |= SOAP_MIME_POSTCHECK;
11413
 
}
11414
 
#endif
11415
 
#endif
11416
 
 
11417
 
/******************************************************************************/
11418
 
#ifndef WITH_LEANER
11419
 
#ifndef PALM_1
11420
 
SOAP_FMAC1
11421
 
int
11422
 
SOAP_FMAC2
11423
 
soap_check_mime_attachments(struct soap *soap)
11424
 
{ if (soap->mode & SOAP_MIME_POSTCHECK)
11425
 
    return soap_get_mime_attachment(soap, NULL) != NULL;
11426
 
  return 0;
11427
 
}
11428
 
#endif
11429
 
#endif
11430
 
 
11431
 
/******************************************************************************/
11432
 
#ifndef WITH_LEANER
11433
 
#ifndef PALM_1
11434
 
SOAP_FMAC1
11435
 
struct soap_multipart *
11436
 
SOAP_FMAC2
11437
 
soap_get_mime_attachment(struct soap *soap, void *handle)
11438
 
{ register soap_wchar c = 0;
11439
 
  register size_t i, m = 0;
11440
 
  register char *s, *t = NULL;
11441
 
  register struct soap_multipart *content;
11442
 
  register short flag = 0;
11443
 
  if (!(soap->mode & SOAP_ENC_MIME))
11444
 
    return NULL;
11445
 
  content = soap->mime.last;
11446
 
  if (!content)
11447
 
  { if (soap_getmimehdr(soap))
11448
 
      return NULL;
11449
 
    content = soap->mime.last;
11450
 
  }
11451
 
  else if (content != soap->mime.first)
11452
 
  { if (soap->fmimewriteopen && ((content->ptr = (char*)soap->fmimewriteopen(soap, (void*)handle, content->id, content->type, content->description, content->encoding)) || soap->error))
11453
 
    { if (!content->ptr)
11454
 
        return NULL;
11455
 
    }
11456
 
  }
11457
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Parsing MIME content id=%s type=%s\n", content->id?content->id:"", content->type?content->type:""));
11458
 
  if (!content->ptr && soap_new_block(soap))
11459
 
  { soap->error = SOAP_EOM;
11460
 
    return NULL;
11461
 
  }
11462
 
  for (;;)
11463
 
  { if (content->ptr)
11464
 
      s = soap->tmpbuf;
11465
 
    else if (!(s = (char*)soap_push_block(soap, sizeof(soap->tmpbuf))))
11466
 
    { soap->error = SOAP_EOM;
11467
 
      return NULL;
11468
 
    }
11469
 
    for (i = 0; i < sizeof(soap->tmpbuf); i++)
11470
 
    { if (m > 0)
11471
 
      { *s++ = *t++;
11472
 
        m--;
11473
 
      }
11474
 
      else
11475
 
      { if (!flag)
11476
 
        { c = soap_get1(soap);
11477
 
          if ((int)c == EOF)
11478
 
          { soap->error = SOAP_EOF;
11479
 
            return NULL;
11480
 
          }
11481
 
        }
11482
 
        if (flag || c == '\r')
11483
 
        { t = soap->msgbuf;
11484
 
          memset(t, 0, sizeof(soap->msgbuf));
11485
 
          strcpy(t, "\n--");
11486
 
          if (soap->mime.boundary)
11487
 
            strncat(t, soap->mime.boundary, sizeof(soap->msgbuf)-4);
11488
 
          do c = soap_getchar(soap);
11489
 
          while (c == *t++);
11490
 
          if ((int)c == EOF)
11491
 
          { soap->error = SOAP_EOF;
11492
 
            return NULL;
11493
 
          }
11494
 
          if (!*--t)
11495
 
            goto end;
11496
 
          *t = (char)c;
11497
 
          flag = (c == '\r');
11498
 
          m = t - soap->msgbuf + 1 - flag;
11499
 
          t = soap->msgbuf;
11500
 
          c = '\r';
11501
 
        }
11502
 
        *s++ = (char)c;
11503
 
      }
11504
 
    }
11505
 
    if (content->ptr && soap->fmimewrite)
11506
 
    { if ((soap->error = soap->fmimewrite(soap, (void*)content->ptr, soap->tmpbuf, i)))
11507
 
        break;
11508
 
    }
11509
 
  }
11510
 
end:
11511
 
  *s = '\0'; /* force 0-terminated */
11512
 
  if (content->ptr)
11513
 
  { if (!soap->error && soap->fmimewrite)
11514
 
      soap->error = soap->fmimewrite(soap, (void*)content->ptr, soap->tmpbuf, i);
11515
 
    if (soap->fmimewriteclose)
11516
 
      soap->fmimewriteclose(soap, (void*)content->ptr);
11517
 
    if (soap->error)
11518
 
      return NULL;
11519
 
  }
11520
 
  else
11521
 
  { content->size = soap_size_block(soap, i+1)-1;
11522
 
    content->ptr = soap_save_block(soap, NULL, 0);
11523
 
  }
11524
 
  soap_resolve_attachment(soap, content);
11525
 
  if (c == '-' && soap_getchar(soap) == '-')
11526
 
  { soap->mode &= ~SOAP_ENC_MIME;
11527
 
    if ((soap->mode & SOAP_MIME_POSTCHECK) && soap_end_recv(soap))
11528
 
      return NULL;
11529
 
  }
11530
 
  else
11531
 
  { while (c != '\r' && (int)c != EOF && soap_blank(c))
11532
 
      c = soap_getchar(soap);
11533
 
    if (c != '\r' || soap_getchar(soap) != '\n')
11534
 
    { soap->error = SOAP_MIME_ERROR;
11535
 
      return NULL;
11536
 
    }
11537
 
    if (soap_getmimehdr(soap))
11538
 
      return NULL;
11539
 
  }
11540
 
  return content;
11541
 
}
11542
 
#endif
11543
 
#endif
11544
 
 
11545
 
/******************************************************************************/
11546
 
#ifndef WITH_LEANER
11547
 
#ifndef PALM_1
11548
 
SOAP_FMAC1
11549
 
int
11550
 
SOAP_FMAC2
11551
 
soap_match_cid(struct soap *soap, const char *s, const char *t)
11552
 
{ register size_t n;
11553
 
  if (!s)
11554
 
    return 1;
11555
 
  if (!strcmp(s, t))
11556
 
    return 0;
11557
 
  if (!strncmp(s, "cid:", 4))
11558
 
    s += 4;
11559
 
  n = strlen(t);
11560
 
  if (*t == '<')
11561
 
  { t++;
11562
 
    n -= 2;
11563
 
  }
11564
 
  if (!strncmp(s, t, n) && !s[n])
11565
 
    return 0;
11566
 
  soap_decode(soap->tmpbuf, sizeof(soap->tmpbuf), s, SOAP_STR_EOS);
11567
 
  if (!strncmp(soap->tmpbuf, t, n) && !soap->tmpbuf[n])
11568
 
    return 0;
11569
 
  return 1;
11570
 
}
11571
 
#endif
11572
 
#endif
11573
 
 
11574
 
/******************************************************************************/
11575
 
#ifndef WITH_LEANER
11576
 
#ifndef PALM_1
11577
 
static void
11578
 
soap_resolve_attachment(struct soap *soap, struct soap_multipart *content)
11579
 
{ if (content->id)
11580
 
  { register struct soap_xlist **xp = &soap->xlist;
11581
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Resolving attachment data for id=%s\n", content->id));
11582
 
    while (*xp)
11583
 
    { register struct soap_xlist *xq = *xp;
11584
 
      if (!soap_match_cid(soap, xq->id, content->id))
11585
 
      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Found matching attachment %s for content id=%s\n", xq->id, content->id));
11586
 
        *xp = xq->next;
11587
 
        *xq->ptr = (unsigned char*)content->ptr;
11588
 
        *xq->size = (int)content->size;
11589
 
        *xq->type = (char*)content->type;
11590
 
        if (content->options)
11591
 
          *xq->options = (char*)content->options;
11592
 
        else
11593
 
          *xq->options = (char*)content->description;
11594
 
        SOAP_FREE(soap, xq);
11595
 
      }
11596
 
      else
11597
 
        xp = &(*xp)->next;
11598
 
    }
11599
 
  }
11600
 
}
11601
 
#endif
11602
 
#endif
11603
 
 
11604
 
/******************************************************************************/
11605
 
#ifndef WITH_LEANER
11606
 
#ifndef PALM_1
11607
 
SOAP_FMAC1
11608
 
int
11609
 
SOAP_FMAC2
11610
 
soap_putmimehdr(struct soap *soap, struct soap_multipart *content)
11611
 
{ const char *s;
11612
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "MIME attachment type=%s\n", content->type?content->type:""));
11613
 
  if (soap_send3(soap, "\r\n--", soap->mime.boundary, "\r\n"))
11614
 
    return soap->error;
11615
 
  if (content->type && soap_send3(soap, "Content-Type: ", content->type, "\r\n"))
11616
 
    return soap->error;
11617
 
  s = soap_code_str(mime_codes, content->encoding);
11618
 
  if (s && soap_send3(soap, "Content-Transfer-Encoding: ", s, "\r\n"))
11619
 
    return soap->error;
11620
 
  if (content->id && soap_send3(soap, "Content-ID: ", content->id, "\r\n"))
11621
 
    return soap->error;
11622
 
  if (content->location && soap_send3(soap, "Content-Location: ", content->location, "\r\n"))
11623
 
    return soap->error;
11624
 
  if (content->description && soap_send3(soap, "Content-Description: ", content->description, "\r\n"))
11625
 
    return soap->error;
11626
 
  return soap_send_raw(soap, "\r\n", 2);
11627
 
}
11628
 
#endif
11629
 
#endif
11630
 
 
11631
 
/******************************************************************************/
11632
 
#ifndef WITH_LEANER
11633
 
#ifndef PALM_1
11634
 
SOAP_FMAC1
11635
 
int
11636
 
SOAP_FMAC2
11637
 
soap_putmime(struct soap *soap)
11638
 
{ struct soap_multipart *content;
11639
 
  if (!(soap->mode & SOAP_ENC_MIME) || !soap->mime.boundary)
11640
 
    return SOAP_OK;
11641
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Sending MIME attachments\n"));
11642
 
  for (content = soap->mime.first; content; content = content->next)
11643
 
  { void *handle;
11644
 
    if (soap->fmimereadopen && ((handle = soap->fmimereadopen(soap, (void*)content->ptr, content->id, content->type, content->description)) || soap->error))
11645
 
    { size_t size = content->size;
11646
 
      if (!handle)
11647
 
      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fmimereadopen failed\n"));
11648
 
        return soap->error;
11649
 
      }
11650
 
      if (soap_putmimehdr(soap, content))
11651
 
        return soap->error;
11652
 
      if (!size)
11653
 
      { if ((soap->mode & SOAP_ENC_XML) || (soap->mode & SOAP_IO) == SOAP_IO_CHUNK || (soap->mode & SOAP_IO) == SOAP_IO_STORE)
11654
 
        { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunked streaming MIME\n"));
11655
 
          do 
11656
 
          { size = soap->fmimeread(soap, handle, soap->tmpbuf, sizeof(soap->tmpbuf));
11657
 
            DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fmimeread returned %lu bytes\n", (unsigned long)size));
11658
 
            if (soap_send_raw(soap, soap->tmpbuf, size))
11659
 
              break;
11660
 
          } while (size); 
11661
 
        }
11662
 
        else
11663
 
        { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error: cannot chunk streaming MIME (no HTTP chunking)\n"));
11664
 
        }
11665
 
      }
11666
 
      else
11667
 
      { do
11668
 
        { size_t bufsize;
11669
 
          if (size < sizeof(soap->tmpbuf))
11670
 
            bufsize = size;
11671
 
          else
11672
 
            bufsize = sizeof(soap->tmpbuf);
11673
 
          if (!(bufsize = soap->fmimeread(soap, handle, soap->tmpbuf, bufsize)))
11674
 
          { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "fmimeread failed: insufficient data (%lu bytes remaining from %lu bytes)\n", (unsigned long)size, (unsigned long)content->size));
11675
 
            soap->error = SOAP_EOF;
11676
 
            break;
11677
 
          }
11678
 
          if (soap_send_raw(soap, soap->tmpbuf, bufsize))
11679
 
            break;
11680
 
          size -= bufsize;
11681
 
        } while (size);
11682
 
      }
11683
 
      if (soap->fmimereadclose)
11684
 
        soap->fmimereadclose(soap, handle);
11685
 
    }
11686
 
    else
11687
 
    { if (soap_putmimehdr(soap, content)
11688
 
       || soap_send_raw(soap, content->ptr, content->size))
11689
 
        return soap->error;
11690
 
    }
11691
 
  }
11692
 
  return soap_send3(soap, "\r\n--", soap->mime.boundary, "--");
11693
 
}
11694
 
#endif
11695
 
#endif
11696
 
 
11697
 
/******************************************************************************/
11698
 
#ifndef WITH_LEANER
11699
 
#ifndef PALM_1
11700
 
SOAP_FMAC1
11701
 
void
11702
 
SOAP_FMAC2
11703
 
soap_set_dime(struct soap *soap)
11704
 
{ soap->omode |= SOAP_ENC_DIME;
11705
 
  soap->dime.first = NULL;
11706
 
  soap->dime.last = NULL;
11707
 
}
11708
 
#endif
11709
 
#endif
11710
 
 
11711
 
/******************************************************************************/
11712
 
#ifndef WITH_LEANER
11713
 
#ifndef PALM_1
11714
 
SOAP_FMAC1
11715
 
void
11716
 
SOAP_FMAC2
11717
 
soap_set_mime(struct soap *soap, const char *boundary, const char *start)
11718
 
{ soap->omode |= SOAP_ENC_MIME;
11719
 
  soap->mime.first = NULL;
11720
 
  soap->mime.last = NULL;
11721
 
  soap->mime.boundary = soap_strdup(soap, boundary);
11722
 
  soap->mime.start = soap_strdup(soap, start);
11723
 
}
11724
 
#endif
11725
 
#endif
11726
 
 
11727
 
/******************************************************************************/
11728
 
#ifndef WITH_LEANER
11729
 
#ifndef PALM_1
11730
 
SOAP_FMAC1
11731
 
void
11732
 
SOAP_FMAC2
11733
 
soap_clr_dime(struct soap *soap)
11734
 
{ soap->omode &= ~SOAP_ENC_DIME;
11735
 
  soap->dime.first = NULL;
11736
 
  soap->dime.last = NULL;
11737
 
}
11738
 
#endif
11739
 
#endif
11740
 
 
11741
 
/******************************************************************************/
11742
 
#ifndef WITH_LEANER
11743
 
#ifndef PALM_1
11744
 
SOAP_FMAC1
11745
 
void
11746
 
SOAP_FMAC2
11747
 
soap_clr_mime(struct soap *soap)
11748
 
{ soap->omode &= ~SOAP_ENC_MIME;
11749
 
  soap->mime.first = NULL;
11750
 
  soap->mime.last = NULL;
11751
 
  soap->mime.boundary = NULL;
11752
 
  soap->mime.start = NULL;
11753
 
}
11754
 
#endif
11755
 
#endif
11756
 
 
11757
 
/******************************************************************************/
11758
 
#ifndef WITH_LEANER
11759
 
#ifndef PALM_1
11760
 
static struct soap_multipart*
11761
 
soap_new_multipart(struct soap *soap, struct soap_multipart **first, struct soap_multipart **last, char *ptr, size_t size)
11762
 
{ struct soap_multipart *content;
11763
 
  content = (struct soap_multipart*)soap_malloc(soap, sizeof(struct soap_multipart));
11764
 
  if (content)
11765
 
  { content->next = NULL;
11766
 
    content->ptr = ptr;
11767
 
    content->size = size;
11768
 
    content->id = NULL;
11769
 
    content->type = NULL;
11770
 
    content->options = NULL;
11771
 
    content->encoding = SOAP_MIME_NONE;
11772
 
    content->location = NULL;
11773
 
    content->description = NULL;
11774
 
    if (!*first)
11775
 
      *first = content;
11776
 
    if (*last)
11777
 
      (*last)->next = content;
11778
 
    *last = content;
11779
 
  }
11780
 
  return content;
11781
 
}
11782
 
#endif
11783
 
#endif
11784
 
 
11785
 
/******************************************************************************/
11786
 
#ifndef WITH_LEANER
11787
 
#ifndef PALM_1
11788
 
SOAP_FMAC1
11789
 
int
11790
 
SOAP_FMAC2
11791
 
soap_set_dime_attachment(struct soap *soap, char *ptr, size_t size, const char *type, const char *id, unsigned short optype, const char *option)
11792
 
{ struct soap_multipart *content = soap_new_multipart(soap, &soap->dime.first, &soap->dime.last, ptr, size);
11793
 
  if (!content)
11794
 
    return SOAP_EOM;
11795
 
  content->id = soap_strdup(soap, id);
11796
 
  content->type = soap_strdup(soap, type);
11797
 
  content->options = soap_dime_option(soap, optype, option);
11798
 
  return SOAP_OK;
11799
 
}
11800
 
#endif
11801
 
#endif
11802
 
 
11803
 
/******************************************************************************/
11804
 
#ifndef WITH_LEANER
11805
 
#ifndef PALM_1
11806
 
SOAP_FMAC1
11807
 
int
11808
 
SOAP_FMAC2
11809
 
soap_set_mime_attachment(struct soap *soap, char *ptr, size_t size, enum soap_mime_encoding encoding, const char *type, const char *id, const char *location, const char *description)
11810
 
{ struct soap_multipart *content = soap_new_multipart(soap, &soap->mime.first, &soap->mime.last, ptr, size);
11811
 
  if (!content)
11812
 
    return SOAP_EOM;
11813
 
  content->id = soap_strdup(soap, id);
11814
 
  content->type = soap_strdup(soap, type);
11815
 
  content->encoding = encoding;
11816
 
  content->location = soap_strdup(soap, location);
11817
 
  content->description = soap_strdup(soap, description);
11818
 
  return SOAP_OK;
11819
 
}
11820
 
#endif
11821
 
#endif
11822
 
 
11823
 
/******************************************************************************/
11824
 
#ifndef WITH_LEANER
11825
 
#ifndef PALM_1
11826
 
SOAP_FMAC1
11827
 
struct soap_multipart*
11828
 
SOAP_FMAC2
11829
 
soap_next_multipart(struct soap_multipart *content)
11830
 
{ if (content)
11831
 
    return content->next;
11832
 
  return NULL;
11833
 
}
11834
 
#endif
11835
 
#endif
11836
 
 
11837
 
/******************************************************************************/
11838
 
#ifndef WITH_LEANER
11839
 
#ifndef PALM_1
11840
 
static void
11841
 
soap_select_mime_boundary(struct soap *soap)
11842
 
{ while (!soap->mime.boundary || soap_valid_mime_boundary(soap))
11843
 
  { register char *s = soap->mime.boundary;
11844
 
    register size_t n = 0;
11845
 
    if (s)
11846
 
      n = strlen(s);
11847
 
    if (n < 16)
11848
 
    { n = 64;
11849
 
      s = soap->mime.boundary = (char*)soap_malloc(soap, n + 1);
11850
 
      if (!s)
11851
 
        return;
11852
 
    }
11853
 
    strcpy(s, "==");
11854
 
    s += 2;
11855
 
    n -= 4;
11856
 
    while (n)
11857
 
    { *s++ = soap_base64o[soap_random & 0x3F];
11858
 
      n--;
11859
 
    }
11860
 
    strcpy(s, "==");
11861
 
  }
11862
 
  if (!soap->mime.start)
11863
 
    soap->mime.start = "<SOAP-ENV:Envelope>";
11864
 
}
11865
 
#endif
11866
 
#endif
11867
 
 
11868
 
/******************************************************************************/
11869
 
#ifndef WITH_LEANER
11870
 
#ifndef PALM_1
11871
 
static int
11872
 
soap_valid_mime_boundary(struct soap *soap)
11873
 
{ register struct soap_multipart *content;
11874
 
  register size_t k;
11875
 
  if (soap->fmimeread)
11876
 
    return SOAP_OK;
11877
 
  k = strlen(soap->mime.boundary);
11878
 
  for (content = soap->mime.first; content; content = content->next)
11879
 
  { if (content->ptr && content->size >= k)
11880
 
    { register const char *p = (const char*)content->ptr; 
11881
 
      register size_t i;
11882
 
      for (i = 0; i < content->size - k; i++, p++)
11883
 
      { if (!strncmp(p, soap->mime.boundary, k))
11884
 
          return SOAP_ERR;
11885
 
      }
11886
 
    }
11887
 
  }
11888
 
  return SOAP_OK;
11889
 
}
11890
 
#endif
11891
 
#endif
11892
 
 
11893
 
/******************************************************************************\
11894
 
 *
11895
 
 *      HTTP cookie handling
11896
 
 *
11897
 
\******************************************************************************/
11898
 
 
11899
 
#ifdef WITH_COOKIES
11900
 
/******************************************************************************/
11901
 
SOAP_FMAC1
11902
 
size_t
11903
 
SOAP_FMAC2
11904
 
soap_encode_cookie(const char *s, char *t, size_t len)
11905
 
{ register int c;
11906
 
  register size_t n = len;
11907
 
  while ((c = *s++) && --n > 0)
11908
 
  { if (c > ' ' && c < 128 && !strchr("()<>@,;:\\\"/[]?={}", c))
11909
 
      *t++ = c;
11910
 
    else if (n > 2)
11911
 
    { *t++ = '%';
11912
 
      *t++ = (c >> 4) + (c > 159 ? '7' : '0');
11913
 
      c &= 0xF;
11914
 
      *t++ = c + (c > 9 ? '7' : '0');
11915
 
      n -= 2;
11916
 
    }
11917
 
    else
11918
 
      break;
11919
 
  }
11920
 
  *t = '\0';
11921
 
  return len - n;
11922
 
}
11923
 
 
11924
 
/******************************************************************************/
11925
 
SOAP_FMAC1
11926
 
struct soap_cookie*
11927
 
SOAP_FMAC2
11928
 
soap_cookie(struct soap *soap, const char *name, const char *domain, const char *path)
11929
 
{ struct soap_cookie *p;
11930
 
  size_t n;
11931
 
  if (!domain)
11932
 
    domain = soap->cookie_domain;
11933
 
  if (!path)
11934
 
    path = soap->cookie_path;
11935
 
  if (!path)
11936
 
    path = SOAP_STR_EOS;
11937
 
  else if (*path == '/')
11938
 
    path++;
11939
 
  n = strlen(path);
11940
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Search cookie %s domain=%s path=%s\n", name, domain?domain:"(null)", path?path:"(null)"));
11941
 
  for (p = soap->cookies; p; p = p->next)
11942
 
  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie in database: %s=%s domain=%s path=%s env=%hd\n", p->name, p->value?p->value:"(null)", p->domain?p->domain:"(null)", p->path?p->path:"(null)", p->env));
11943
 
    if (!strcmp(p->name, name)
11944
 
     && p->domain
11945
 
     && p->path
11946
 
     && !strcmp(p->domain, domain)
11947
 
     && !strncmp(p->path, path, n))
11948
 
      break;
11949
 
  }
11950
 
  return p;
11951
 
}
11952
 
 
11953
 
/******************************************************************************/
11954
 
SOAP_FMAC1
11955
 
struct soap_cookie*
11956
 
SOAP_FMAC2
11957
 
soap_set_cookie(struct soap *soap, const char *name, const char *value, const char *domain, const char *path)
11958
 
{ struct soap_cookie **p, *q;
11959
 
  int n;
11960
 
  if (!domain)
11961
 
    domain = soap->cookie_domain;
11962
 
  if (!path)
11963
 
    path = soap->cookie_path;
11964
 
  if (!path)
11965
 
    path = SOAP_STR_EOS;
11966
 
  else if (*path == '/')
11967
 
    path++;
11968
 
  q = soap_cookie(soap, name, domain, path);
11969
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set %scookie: %s=%s domain=%s path=%s\n", q ? "" : "new ", name, value?value:"(null)", domain?domain:"(null)", path?path:"(null)"));
11970
 
  if (!q)
11971
 
  { if ((q = (struct soap_cookie*)SOAP_MALLOC(soap, sizeof(struct soap_cookie))))
11972
 
    { if ((q->name = (char*)SOAP_MALLOC(soap, strlen(name)+1)))
11973
 
        strcpy(q->name, name);
11974
 
      q->value = NULL;
11975
 
      q->domain = NULL;
11976
 
      q->path = NULL;
11977
 
      q->expire = 0;
11978
 
      q->maxage = -1;
11979
 
      q->version = 1;
11980
 
      q->secure = 0;
11981
 
      q->modified = 0;
11982
 
      for (p = &soap->cookies, n = soap->cookie_max; *p && n; p = &(*p)->next, n--)
11983
 
        if (!strcmp((*p)->name, name) && (*p)->path && path && strcmp((*p)->path, path) < 0)
11984
 
          break;
11985
 
      if (n)
11986
 
      { q->next = *p;
11987
 
        *p = q;
11988
 
      }
11989
 
      else
11990
 
      { SOAP_FREE(soap, q->name);
11991
 
        SOAP_FREE(soap, q);
11992
 
        q = NULL;
11993
 
      }
11994
 
    }
11995
 
  }
11996
 
  else
11997
 
    q->modified = 1;
11998
 
  if (q)
11999
 
  { if (q->value)
12000
 
    { SOAP_FREE(soap, q->value);
12001
 
      q->value = NULL;
12002
 
    }
12003
 
    if (q->domain)
12004
 
    { SOAP_FREE(soap, q->domain);
12005
 
      q->domain = NULL;
12006
 
    }
12007
 
    if (q->path)
12008
 
    { SOAP_FREE(soap, q->path);
12009
 
      q->path = NULL;
12010
 
    }
12011
 
    if (value && *value && (q->value = (char*)SOAP_MALLOC(soap, strlen(value)+1)))
12012
 
      strcpy(q->value, value);
12013
 
    if (domain && (q->domain = (char*)SOAP_MALLOC(soap, strlen(domain)+1)))
12014
 
      strcpy(q->domain, domain);
12015
 
    if (path && (q->path = (char*)SOAP_MALLOC(soap, strlen(path)+1)))
12016
 
      strcpy(q->path, path);
12017
 
    q->session = 1;
12018
 
    q->env = 0;
12019
 
  }
12020
 
  return q;
12021
 
}
12022
 
 
12023
 
/******************************************************************************/
12024
 
SOAP_FMAC1
12025
 
void
12026
 
SOAP_FMAC2
12027
 
soap_clr_cookie(struct soap *soap, const char *name, const char *domain, const char *path)
12028
 
{ struct soap_cookie **p, *q;
12029
 
  if (!domain)
12030
 
    domain = soap->cookie_domain;
12031
 
  if (!domain)
12032
 
  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error in clear cookie %s: cookie domain not set\n", name?name:"(null)"));
12033
 
    return;
12034
 
  }
12035
 
  if (!path)
12036
 
    path = soap->cookie_path;
12037
 
  if (!path)
12038
 
  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error in clear cookie %s: cookie path not set\n", name?name:"(null)"));
12039
 
    return;
12040
 
  }
12041
 
  if (*path == '/')
12042
 
    path++;
12043
 
  for (p = &soap->cookies, q = *p; q; q = *p)
12044
 
  { if (!strcmp(q->name, name) && !strcmp(q->domain, domain) && !strncmp(q->path, path, strlen(q->path)))
12045
 
    { if (q->value)
12046
 
        SOAP_FREE(soap, q->value);
12047
 
      if (q->domain)
12048
 
        SOAP_FREE(soap, q->domain);
12049
 
      if (q->path)
12050
 
        SOAP_FREE(soap, q->path);
12051
 
      *p = q->next;
12052
 
      SOAP_FREE(soap, q);
12053
 
    }
12054
 
    else
12055
 
      p = &q->next;
12056
 
  }
12057
 
}
12058
 
 
12059
 
/******************************************************************************/
12060
 
SOAP_FMAC1
12061
 
char *
12062
 
SOAP_FMAC2
12063
 
soap_cookie_value(struct soap *soap, const char *name, const char *domain, const char *path)
12064
 
{ struct soap_cookie *p;
12065
 
  if ((p = soap_cookie(soap, name, domain, path)))
12066
 
    return p->value;
12067
 
  return NULL;
12068
 
}
12069
 
 
12070
 
/******************************************************************************/
12071
 
SOAP_FMAC1
12072
 
char *
12073
 
SOAP_FMAC2
12074
 
soap_env_cookie_value(struct soap *soap, const char *name, const char *domain, const char *path)
12075
 
{ struct soap_cookie *p;
12076
 
  if ((p = soap_cookie(soap, name, domain, path)) && p->env)
12077
 
    return p->value;
12078
 
  return NULL;
12079
 
}
12080
 
 
12081
 
/******************************************************************************/
12082
 
SOAP_FMAC1
12083
 
time_t
12084
 
SOAP_FMAC2
12085
 
soap_cookie_expire(struct soap *soap, const char *name, const char *domain, const char *path)
12086
 
{ struct soap_cookie *p;
12087
 
  if ((p = soap_cookie(soap, name, domain, path)))
12088
 
    return p->expire;
12089
 
  return -1;
12090
 
}
12091
 
 
12092
 
/******************************************************************************/
12093
 
SOAP_FMAC1
12094
 
int
12095
 
SOAP_FMAC2
12096
 
soap_set_cookie_expire(struct soap *soap, const char *name, long expire, const char *domain, const char *path)
12097
 
{ struct soap_cookie *p;
12098
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set cookie expiration max-age %ld: %s domain=%s path=%s\n", expire, name, domain?domain:"(null)", path?path:"(null)"));
12099
 
  if ((p = soap_cookie(soap, name, domain, path)))
12100
 
  { p->maxage = expire;
12101
 
    p->modified = 1;
12102
 
    return SOAP_OK;
12103
 
  }
12104
 
  return SOAP_ERR;
12105
 
}
12106
 
 
12107
 
/******************************************************************************/
12108
 
SOAP_FMAC1
12109
 
int
12110
 
SOAP_FMAC2
12111
 
soap_set_cookie_session(struct soap *soap, const char *name, const char *domain, const char *path)
12112
 
{ struct soap_cookie *p;
12113
 
  if ((p = soap_cookie(soap, name, domain, path)))
12114
 
  { p->session = 1;
12115
 
    p->modified = 1;
12116
 
    return SOAP_OK;
12117
 
  }
12118
 
  return SOAP_ERR;
12119
 
}
12120
 
 
12121
 
/******************************************************************************/
12122
 
SOAP_FMAC1
12123
 
int
12124
 
SOAP_FMAC2
12125
 
soap_clr_cookie_session(struct soap *soap, const char *name, const char *domain, const char *path)
12126
 
{ struct soap_cookie *p;
12127
 
  if ((p = soap_cookie(soap, name, domain, path)))
12128
 
  { p->session = 0;
12129
 
    p->modified = 1;
12130
 
    return SOAP_OK;
12131
 
  }
12132
 
  return SOAP_ERR;
12133
 
}
12134
 
 
12135
 
/******************************************************************************/
12136
 
SOAP_FMAC1
12137
 
int
12138
 
SOAP_FMAC2
12139
 
soap_putsetcookies(struct soap *soap)
12140
 
{ struct soap_cookie *p;
12141
 
  char *s, tmp[4096];
12142
 
  const char *t;
12143
 
  for (p = soap->cookies; p; p = p->next)
12144
 
  {
12145
 
    if (p->modified
12146
 
#ifdef WITH_OPENSSL
12147
 
     || (!p->env && !soap->ssl == !p->secure)
12148
 
#endif
12149
 
       )
12150
 
    { s = tmp;
12151
 
      if (p->name)
12152
 
        s += soap_encode_cookie(p->name, s, tmp-s+4064);
12153
 
      if (p->value && *p->value)
12154
 
      { *s++ = '=';
12155
 
        s += soap_encode_cookie(p->value, s, tmp-s+4064);
12156
 
      }
12157
 
      if (p->domain && (int)strlen(p->domain) < tmp-s+4064)
12158
 
      { strcpy(s, ";Domain=");
12159
 
        strcat(s, p->domain);
12160
 
      }
12161
 
      else if (soap->cookie_domain && (int)strlen(soap->cookie_domain) < tmp-s+4064)
12162
 
      { strcpy(s, ";Domain=");
12163
 
        strcat(s, soap->cookie_domain);
12164
 
      }
12165
 
      strcat(s, ";Path=/");
12166
 
      s += strlen(s);
12167
 
      if (p->path)
12168
 
        t = p->path;
12169
 
      else
12170
 
        t = soap->cookie_path;
12171
 
      if (t)
12172
 
      { if (*t == '/')
12173
 
          t++;
12174
 
        if ((int)strlen(t) < tmp-s+4064)
12175
 
        { if (strchr(t, '%'))   /* already URL encoded? */
12176
 
          { strcpy(s, t);
12177
 
            s += strlen(s);
12178
 
          }
12179
 
          else
12180
 
            s += soap_encode_cookie(t, s, tmp-s+4064);
12181
 
        }
12182
 
      }
12183
 
      if (p->version > 0 && s-tmp < 4060)
12184
 
      { sprintf(s, ";Version=%u", p->version);
12185
 
        s += strlen(s);
12186
 
      }
12187
 
      if (p->maxage >= 0 && s-tmp < 4060)
12188
 
      { sprintf(s, ";Max-Age=%ld", p->maxage);
12189
 
        s += strlen(s);
12190
 
      }
12191
 
      if (s-tmp < 4073
12192
 
       && (p->secure
12193
 
#ifdef WITH_OPENSSL
12194
 
       || soap->ssl
12195
 
#endif
12196
 
         ))
12197
 
        strcpy(s, ";Secure");
12198
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Set-Cookie: %s\n", tmp));
12199
 
      if ((soap->error = soap->fposthdr(soap, "Set-Cookie", tmp)))
12200
 
        return soap->error;
12201
 
    }
12202
 
  }
12203
 
  return SOAP_OK;
12204
 
}
12205
 
 
12206
 
/******************************************************************************/
12207
 
SOAP_FMAC1
12208
 
int
12209
 
SOAP_FMAC2
12210
 
soap_putcookies(struct soap *soap, const char *domain, const char *path, int secure)
12211
 
{ struct soap_cookie **p, *q;
12212
 
  unsigned int version = 0;
12213
 
  time_t now = time(NULL);
12214
 
  char *s, tmp[4096];
12215
 
  p = &soap->cookies;
12216
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Sending cookies for domain=%s path=%s\n", domain, path));
12217
 
  if (*path == '/')
12218
 
    path++;
12219
 
  while ((q = *p))
12220
 
  { if (q->expire && now > q->expire)
12221
 
    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie %s expired\n", q->name));
12222
 
      SOAP_FREE(soap, q->name);
12223
 
      if (q->value)
12224
 
        SOAP_FREE(soap, q->value);
12225
 
      if (q->domain)
12226
 
        SOAP_FREE(soap, q->domain);
12227
 
      if (q->path)
12228
 
        SOAP_FREE(soap, q->path);
12229
 
      *p = q->next;
12230
 
      SOAP_FREE(soap, q);
12231
 
    }
12232
 
    else
12233
 
    { int flag;
12234
 
      char *t = q->domain;
12235
 
      size_t n = 0;
12236
 
      if (!t)
12237
 
        flag = 1;
12238
 
      else
12239
 
      { const char *r = strchr(t, ':');
12240
 
        if (r)
12241
 
          n = r - t;
12242
 
        else
12243
 
          n = strlen(t);
12244
 
        flag = !strncmp(t, domain, n);
12245
 
      }
12246
 
      /* domain-level cookies */
12247
 
      if (!flag)
12248
 
      { struct hostent *hostent = gethostbyname((char*)domain);
12249
 
        if (hostent)
12250
 
        { char *r = strchr(hostent->h_name, '.');
12251
 
          if (!r)
12252
 
            r = hostent->h_name;
12253
 
          flag = !strncmp(t, r, n);
12254
 
        }
12255
 
      }
12256
 
      if (flag
12257
 
          && (!q->path || !strncmp(q->path, path, strlen(q->path)))
12258
 
          && (!q->secure || secure))
12259
 
      { s = tmp;
12260
 
        if (q->version != version)
12261
 
        { sprintf(s, "$Version=%u;", q->version);
12262
 
          version = q->version;
12263
 
        }
12264
 
        if (q->name)
12265
 
          s += soap_encode_cookie(q->name, s, tmp-s+4080);
12266
 
        if (q->value && *q->value)
12267
 
        { *s++ = '=';
12268
 
          s += soap_encode_cookie(q->value, s, tmp-s+4080);
12269
 
        }
12270
 
        if (q->path && *q->path && (int)strlen(q->path) < tmp-s+4080)
12271
 
        { sprintf(s, ";$Path=\"/%s\"", (*q->path == '/' ? q->path + 1 : q->path));
12272
 
          s += strlen(s);
12273
 
        }
12274
 
        if (q->domain && (int)strlen(q->domain) < tmp-s+4080)
12275
 
          sprintf(s, ";$Domain=\"%s\"", q->domain);
12276
 
        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Cookie: %s\n", tmp));
12277
 
        if ((soap->error = soap->fposthdr(soap, "Cookie", tmp)))
12278
 
          return soap->error;
12279
 
      }
12280
 
      p = &q->next;
12281
 
    }
12282
 
  }
12283
 
  return SOAP_OK;
12284
 
}
12285
 
 
12286
 
/******************************************************************************/
12287
 
SOAP_FMAC1
12288
 
void
12289
 
SOAP_FMAC2
12290
 
soap_getcookies(struct soap *soap, const char *val)
12291
 
{ struct soap_cookie *p = NULL, *q;
12292
 
  const char *s;
12293
 
  char *t, tmp[4096]; /* cookie size is up to 4096 bytes [RFC2109] */
12294
 
  char *domain = NULL;
12295
 
  char *path = NULL;
12296
 
  unsigned int version = 0;
12297
 
  time_t now = time(NULL);
12298
 
  if (!val)
12299
 
    return;
12300
 
  s = val;
12301
 
  while (*s)
12302
 
  { s = soap_decode_key(tmp, sizeof(tmp), s);
12303
 
    if (!soap_tag_cmp(tmp, "$Version"))
12304
 
    { if ((s = soap_decode_val(tmp, sizeof(tmp), s)))
12305
 
      { if (p)
12306
 
          p->version = (int)atol(tmp);
12307
 
        else
12308
 
          version = (int)atol(tmp);
12309
 
      }
12310
 
    }
12311
 
    else if (!soap_tag_cmp(tmp, "$Path"))
12312
 
    { s = soap_decode_val(tmp, sizeof(tmp), s);
12313
 
      if (*tmp)
12314
 
      { if ((t = (char*)SOAP_MALLOC(soap, strlen(tmp)+1)))
12315
 
          strcpy(t, tmp);
12316
 
      }
12317
 
      else
12318
 
        t = NULL;
12319
 
      if (p)
12320
 
      { if (p->path)
12321
 
          SOAP_FREE(soap, p->path);
12322
 
        p->path = t;
12323
 
      }
12324
 
      else
12325
 
      { if (path)
12326
 
          SOAP_FREE(soap, path);
12327
 
        path = t;
12328
 
      }
12329
 
    }
12330
 
    else if (!soap_tag_cmp(tmp, "$Domain"))
12331
 
    { s = soap_decode_val(tmp, sizeof(tmp), s);
12332
 
      if (*tmp)
12333
 
      { if ((t = (char*)SOAP_MALLOC(soap, strlen(tmp)+1)))
12334
 
          strcpy(t, tmp);
12335
 
      }
12336
 
      else
12337
 
        t = NULL;
12338
 
      if (p)
12339
 
      { if (p->domain)
12340
 
          SOAP_FREE(soap, p->domain);
12341
 
        p->domain = t;
12342
 
      }
12343
 
      else
12344
 
      { if (domain)
12345
 
          SOAP_FREE(soap, domain);
12346
 
        domain = t;
12347
 
      }
12348
 
    }
12349
 
    else if (p && !soap_tag_cmp(tmp, "Path"))
12350
 
    { if (p->path)
12351
 
        SOAP_FREE(soap, p->path);
12352
 
      s = soap_decode_val(tmp, sizeof(tmp), s);
12353
 
      if (*tmp)
12354
 
      { if ((p->path = (char*)SOAP_MALLOC(soap, strlen(tmp)+1)))
12355
 
          strcpy(p->path, tmp);
12356
 
      }
12357
 
      else
12358
 
        p->path = NULL;
12359
 
    }
12360
 
    else if (p && !soap_tag_cmp(tmp, "Domain"))
12361
 
    { if (p->domain)
12362
 
        SOAP_FREE(soap, p->domain);
12363
 
      s = soap_decode_val(tmp, sizeof(tmp), s);
12364
 
      if (*tmp)
12365
 
      { if ((p->domain = (char*)SOAP_MALLOC(soap, strlen(tmp)+1)))
12366
 
          strcpy(p->domain, tmp);
12367
 
      }
12368
 
      else
12369
 
        p->domain = NULL;
12370
 
    }
12371
 
    else if (p && !soap_tag_cmp(tmp, "Version"))
12372
 
    { s = soap_decode_val(tmp, sizeof(tmp), s);
12373
 
      p->version = (unsigned int)atol(tmp);
12374
 
    }
12375
 
    else if (p && !soap_tag_cmp(tmp, "Max-Age"))
12376
 
    { s = soap_decode_val(tmp, sizeof(tmp), s);
12377
 
      p->expire = now + atol(tmp);
12378
 
    }
12379
 
    else if (p && !soap_tag_cmp(tmp, "Expires"))
12380
 
    { struct tm T;
12381
 
      char a[3]; 
12382
 
      static const char mns[] = "anebarprayunulugepctovec";
12383
 
      s = soap_decode_val(tmp, sizeof(tmp), s);
12384
 
      if (strlen(tmp) > 20)
12385
 
      { memset((void*)&T, 0, sizeof(T));
12386
 
        a[0] = tmp[4];
12387
 
        a[1] = tmp[5];
12388
 
        a[2] = '\0';
12389
 
        T.tm_mday = (int)atol(a);
12390
 
        a[0] = tmp[8];
12391
 
        a[1] = tmp[9];
12392
 
        T.tm_mon = (int)(strstr(mns, a) - mns) / 2;
12393
 
        a[0] = tmp[11];
12394
 
        a[1] = tmp[12];
12395
 
        T.tm_year = 100 + (int)atol(a);
12396
 
        a[0] = tmp[13];
12397
 
        a[1] = tmp[14];
12398
 
        T.tm_hour = (int)atol(a);
12399
 
        a[0] = tmp[16];
12400
 
        a[1] = tmp[17];
12401
 
        T.tm_min = (int)atol(a);
12402
 
        a[0] = tmp[19];
12403
 
        a[1] = tmp[20];
12404
 
        T.tm_sec = (int)atol(a);
12405
 
        p->expire = soap_timegm(&T);
12406
 
      }
12407
 
    }
12408
 
    else if (p && !soap_tag_cmp(tmp, "Secure"))
12409
 
      p->secure = 1;
12410
 
    else
12411
 
    { if (p)
12412
 
      { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Got environment cookie %s=%s domain=%s path=%s expire=%ld secure=%d\n", p->name, p->value?p->value:"(null)", p->domain?p->domain:"(null)", p->path?p->path:"(null)", p->expire, p->secure));
12413
 
        if ((q = soap_set_cookie(soap, p->name, p->value, p->domain, p->path)))
12414
 
        { q->version = p->version;
12415
 
          q->expire = p->expire;
12416
 
          q->secure = p->secure;
12417
 
          q->env = 1;
12418
 
        }
12419
 
        if (p->name)
12420
 
          SOAP_FREE(soap, p->name);
12421
 
        if (p->value)
12422
 
          SOAP_FREE(soap, p->value);
12423
 
        if (p->domain)
12424
 
          SOAP_FREE(soap, p->domain);
12425
 
        if (p->path)
12426
 
          SOAP_FREE(soap, p->path);
12427
 
        SOAP_FREE(soap, p);
12428
 
      }
12429
 
      if ((p = (struct soap_cookie*)SOAP_MALLOC(soap, sizeof(struct soap_cookie))))
12430
 
      { p->name = (char*)SOAP_MALLOC(soap, strlen(tmp)+1);
12431
 
        strcpy(p->name, tmp);
12432
 
        s = soap_decode_val(tmp, sizeof(tmp), s);
12433
 
        if (*tmp)
12434
 
        { p->value = (char*)SOAP_MALLOC(soap, strlen(tmp)+1);
12435
 
          strcpy(p->value, tmp);
12436
 
        }
12437
 
        else
12438
 
          p->value = NULL;
12439
 
        if (domain)
12440
 
          p->domain = domain;
12441
 
        else if (*soap->host)
12442
 
        { p->domain = (char*)SOAP_MALLOC(soap, strlen(soap->host)+1);
12443
 
          strcpy(p->domain, soap->host);
12444
 
        }
12445
 
        else
12446
 
          p->domain = NULL;
12447
 
        if (path)
12448
 
          p->path = path;
12449
 
        else if (soap->path && *soap->path)
12450
 
        { p->path = (char*)SOAP_MALLOC(soap, strlen(soap->path)+1);
12451
 
          strcpy(p->path, soap->path);
12452
 
        }
12453
 
        else
12454
 
        { p->path = (char*)SOAP_MALLOC(soap, 2);
12455
 
          strcpy(p->path, "/");
12456
 
        }
12457
 
        p->expire = 0;
12458
 
        p->secure = 0;
12459
 
        p->version = version;
12460
 
      }
12461
 
    }
12462
 
  }
12463
 
  if (p)
12464
 
  { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Got environment cookie %s=%s domain=%s path=%s expire=%ld secure=%d\n", p->name, p->value?p->value:"(null)", p->domain?p->domain:"(null)", p->path?p->path:"(null)", p->expire, p->secure));
12465
 
    if ((q = soap_set_cookie(soap, p->name, p->value, p->domain, p->path)))
12466
 
    { q->version = p->version;
12467
 
      q->expire = p->expire;
12468
 
      q->secure = p->secure;
12469
 
      q->env = 1;
12470
 
    }
12471
 
    if (p->name)
12472
 
      SOAP_FREE(soap, p->name);
12473
 
    if (p->value)
12474
 
      SOAP_FREE(soap, p->value);
12475
 
    if (p->domain)
12476
 
      SOAP_FREE(soap, p->domain);
12477
 
    if (p->path)
12478
 
      SOAP_FREE(soap, p->path);
12479
 
    SOAP_FREE(soap, p);
12480
 
  }
12481
 
  if (domain)
12482
 
    SOAP_FREE(soap, domain);
12483
 
  if (path)
12484
 
    SOAP_FREE(soap, path);
12485
 
}
12486
 
 
12487
 
/******************************************************************************/
12488
 
SOAP_FMAC1
12489
 
int
12490
 
SOAP_FMAC2
12491
 
soap_getenv_cookies(struct soap *soap)
12492
 
{ struct soap_cookie *p;
12493
 
  const char *s;
12494
 
  char key[4096], val[4096]; /* cookie size is up to 4096 bytes [RFC2109] */
12495
 
  if (!(s = getenv("HTTP_COOKIE")))
12496
 
    return SOAP_ERR;
12497
 
  do
12498
 
  { s = soap_decode_key(key, sizeof(key), s);
12499
 
    s = soap_decode_val(val, sizeof(val), s);
12500
 
    p = soap_set_cookie(soap, key, val, NULL, NULL);
12501
 
    if (p)
12502
 
      p->env = 1;
12503
 
  } while (*s);
12504
 
  return SOAP_OK;
12505
 
}
12506
 
 
12507
 
/******************************************************************************/
12508
 
SOAP_FMAC1
12509
 
struct soap_cookie*
12510
 
SOAP_FMAC2
12511
 
soap_copy_cookies(struct soap *copy, struct soap *soap)
12512
 
{ struct soap_cookie *p, **q, *r;
12513
 
  q = &r;
12514
 
  for (p = soap->cookies; p; p = p->next)
12515
 
  { if (!(*q = (struct soap_cookie*)SOAP_MALLOC(copy, sizeof(struct soap_cookie))))
12516
 
      return r;
12517
 
    **q = *p;
12518
 
    if (p->name)
12519
 
    { if (((*q)->name = (char*)SOAP_MALLOC(copy, strlen(p->name)+1)))
12520
 
        strcpy((*q)->name, p->name);
12521
 
    }
12522
 
    if (p->value)
12523
 
    { if (((*q)->value = (char*)SOAP_MALLOC(copy, strlen(p->value)+1)))
12524
 
        strcpy((*q)->value, p->value);
12525
 
    }
12526
 
    if (p->domain)
12527
 
    { if (((*q)->domain = (char*)SOAP_MALLOC(copy, strlen(p->domain)+1)))
12528
 
        strcpy((*q)->domain, p->domain);
12529
 
    }
12530
 
    if (p->path)
12531
 
    { if (((*q)->path = (char*)SOAP_MALLOC(copy, strlen(p->path)+1)))
12532
 
        strcpy((*q)->path, p->path);
12533
 
    }
12534
 
    q = &(*q)->next;
12535
 
  }
12536
 
  *q = NULL;
12537
 
  return r;
12538
 
}
12539
 
 
12540
 
/******************************************************************************/
12541
 
SOAP_FMAC1
12542
 
void
12543
 
SOAP_FMAC2
12544
 
soap_free_cookies(struct soap *soap)
12545
 
{ struct soap_cookie *p;
12546
 
  for (p = soap->cookies; p; p = soap->cookies)
12547
 
  { soap->cookies = p->next;
12548
 
    SOAP_FREE(soap, p->name);
12549
 
    if (p->value)
12550
 
      SOAP_FREE(soap, p->value);
12551
 
    if (p->domain)
12552
 
      SOAP_FREE(soap, p->domain);
12553
 
    if (p->path)
12554
 
      SOAP_FREE(soap, p->path);
12555
 
    SOAP_FREE(soap, p);
12556
 
  }
12557
 
}
12558
 
 
12559
 
/******************************************************************************/
12560
 
#endif /* WITH_COOKIES */
12561
 
 
12562
 
/******************************************************************************/
12563
 
#ifdef WITH_GZIP
12564
 
#ifndef PALM_1
12565
 
static int
12566
 
soap_getgziphdr(struct soap *soap)
12567
 
{ int i;
12568
 
  soap_wchar c = 0, f = 0;
12569
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Get gzip header\n"));
12570
 
  for (i = 0; i < 9; i++)
12571
 
  { if ((int)(c = soap_get1(soap) == EOF))
12572
 
      return soap->error = SOAP_EOF;
12573
 
    if (i == 2)
12574
 
      f = c;
12575
 
  }
12576
 
  if (f & 0x04) /* FEXTRA */
12577
 
  { for (i = soap_get1(soap) | (soap_get1(soap) << 8); i; i--)
12578
 
    { if ((int)soap_get1(soap) == EOF)
12579
 
        return soap->error = SOAP_EOF;
12580
 
    }
12581
 
  }
12582
 
  if (f & 0x08) /* FNAME */
12583
 
  { do
12584
 
      c = soap_get1(soap);
12585
 
    while (c && (int)c != EOF);
12586
 
  }
12587
 
  if ((int)c != EOF && (f & 0x10)) /* FCOMMENT */
12588
 
  { do
12589
 
      c = soap_get1(soap);
12590
 
    while (c && (int)c != EOF);
12591
 
  }
12592
 
  if ((int)c != EOF && (f & 0x01)) /* FHCRC */
12593
 
  { if ((int)(c = soap_get1(soap)) != EOF)
12594
 
      c = soap_get1(soap);
12595
 
  }
12596
 
  if ((int)c == EOF)
12597
 
    return soap->error = SOAP_EOF;
12598
 
  return SOAP_OK;
12599
 
}
12600
 
#endif
12601
 
#endif
12602
 
 
12603
 
/******************************************************************************/
12604
 
#ifndef PALM_1
12605
 
SOAP_FMAC1
12606
 
int
12607
 
SOAP_FMAC2
12608
 
soap_begin_recv(struct soap *soap)
12609
 
{ soap_wchar c;
12610
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Initializing for input\n"));
12611
 
  soap->error = SOAP_OK;
12612
 
  soap_free_temp(soap);
12613
 
  soap_set_local_namespaces(soap);
12614
 
  soap->version = 0;    /* don't assume we're parsing SOAP content by default */
12615
 
#ifndef WITH_NOIDREF
12616
 
  soap_free_iht(soap);
12617
 
#endif
12618
 
  if ((soap->imode & SOAP_IO) == SOAP_IO_CHUNK)
12619
 
    soap->omode |= SOAP_IO_CHUNK;
12620
 
  soap->imode &= ~SOAP_IO;
12621
 
  soap->mode = soap->imode;
12622
 
  if (!soap->keep_alive)
12623
 
  { soap->buflen = 0;
12624
 
    soap->bufidx = 0;
12625
 
  }
12626
 
  if (!(soap->mode & SOAP_IO_KEEPALIVE))
12627
 
    soap->keep_alive = 0;
12628
 
  soap->ahead = 0;
12629
 
  soap->peeked = 0;
12630
 
  soap->level = 0;
12631
 
  soap->part = SOAP_BEGIN;
12632
 
  soap->alloced = 0;
12633
 
  soap->count = 0;
12634
 
  soap->length = 0;
12635
 
  soap->cdata = 0;
12636
 
  *soap->endpoint = '\0';
12637
 
  soap->action = NULL;
12638
 
  soap->status = 0;
12639
 
#ifndef WITH_LEANER
12640
 
  soap->dom = NULL;
12641
 
  soap->dime.chunksize = 0;
12642
 
  soap->dime.buflen = 0;
12643
 
  soap->dime.list = NULL;
12644
 
  soap->dime.first = NULL;
12645
 
  soap->dime.last = NULL;
12646
 
  soap->mime.list = NULL;
12647
 
  soap->mime.first = NULL;
12648
 
  soap->mime.last = NULL;
12649
 
  soap->mime.boundary = NULL;
12650
 
  soap->mime.start = NULL;
12651
 
  soap->xlist = NULL;
12652
 
#endif
12653
 
#ifdef WIN32
12654
 
#ifndef UNDER_CE
12655
 
#ifndef WITH_FASTCGI
12656
 
  if (!soap_valid_socket(soap->socket))
12657
 
#ifdef __BORLANDC__
12658
 
    setmode(soap->recvfd, O_BINARY);
12659
 
#else
12660
 
    _setmode(soap->recvfd, _O_BINARY);
12661
 
#endif
12662
 
#endif
12663
 
#endif
12664
 
#endif
12665
 
#ifdef WITH_ZLIB
12666
 
  soap->mode &= ~SOAP_ENC_ZLIB;
12667
 
  soap->zlib_in = SOAP_ZLIB_NONE;
12668
 
  soap->zlib_out = SOAP_ZLIB_NONE;
12669
 
  soap->d_stream.next_in = Z_NULL;
12670
 
  soap->d_stream.avail_in = 0;
12671
 
  soap->d_stream.next_out = (Byte*)soap->buf;
12672
 
  soap->d_stream.avail_out = SOAP_BUFLEN;
12673
 
  soap->z_ratio_in = 1.0;
12674
 
#endif
12675
 
#ifndef WITH_LEANER
12676
 
  if (soap->fprepareinit)
12677
 
    soap->fprepareinit(soap);
12678
 
#endif
12679
 
  c = soap_getchar(soap);
12680
 
#ifdef WITH_GZIP
12681
 
  if (c == 0x1F)
12682
 
  { if (soap_getgziphdr(soap))
12683
 
      return soap->error;
12684
 
    if (inflateInit2(&soap->d_stream, -MAX_WBITS) != Z_OK)
12685
 
      return soap->error = SOAP_ZLIB_ERROR;
12686
 
    soap->zlib_state = SOAP_ZLIB_INFLATE;
12687
 
    soap->mode |= SOAP_ENC_ZLIB;
12688
 
    soap->zlib_in = SOAP_ZLIB_GZIP;
12689
 
    soap->z_crc = crc32(0L, NULL, 0);
12690
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip initialized\n"));
12691
 
    memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN);
12692
 
    /* should not chunk over plain transport, so why bother to check? */
12693
 
    /* if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK) */
12694
 
    /*   soap->z_buflen = soap->bufidx; */
12695
 
    /* else */
12696
 
    soap->d_stream.next_in = (Byte*)(soap->z_buf + soap->bufidx);
12697
 
    soap->d_stream.avail_in = soap->buflen - soap->bufidx;
12698
 
    soap->z_buflen = soap->buflen;
12699
 
    soap->buflen = soap->bufidx;
12700
 
    c = soap_getchar(soap);
12701
 
  }  
12702
 
#endif
12703
 
#ifndef WITH_LEANER
12704
 
  if (c == '-' && soap_get0(soap) == '-')
12705
 
    soap->mode |= SOAP_ENC_MIME;
12706
 
  else if ((c & 0xFFFC) == (SOAP_DIME_VERSION | SOAP_DIME_MB) && (soap_get0(soap) & 0xFFF0) == 0x20)
12707
 
    soap->mode |= SOAP_ENC_DIME;
12708
 
  else
12709
 
#endif
12710
 
  { while (soap_blank(c))
12711
 
      c = soap_getchar(soap);
12712
 
  }
12713
 
  if ((int)c == EOF)
12714
 
    return soap->error = SOAP_EOF;
12715
 
  soap_unget(soap, c);
12716
 
#ifndef WITH_NOHTTP
12717
 
  /* if not XML or (start of)BOM or MIME/DIME/ZLIB, assume HTTP header */
12718
 
  if (c != '<' && c != 0xEF && !(soap->mode & (SOAP_ENC_MIME | SOAP_ENC_DIME | SOAP_ENC_ZLIB)))
12719
 
  { soap->mode &= ~SOAP_IO;
12720
 
    soap->error = soap->fparse(soap);
12721
 
    if (soap->error && soap->error < SOAP_STOP)
12722
 
    { soap->keep_alive = 0; /* force close later */
12723
 
      return soap->error;
12724
 
    }
12725
 
    if (soap->error == SOAP_STOP)
12726
 
      return soap->error;
12727
 
    if ((soap->mode & SOAP_IO) == SOAP_IO_CHUNK)
12728
 
    { soap->chunkbuflen = soap->buflen;
12729
 
      soap->buflen = soap->bufidx;
12730
 
      soap->chunksize = 0;
12731
 
    }
12732
 
#ifndef WITH_LEANER
12733
 
    else if (soap->fpreparerecv && soap->buflen != soap->bufidx)
12734
 
      soap->fpreparerecv(soap, soap->buf + soap->bufidx, soap->buflen - soap->bufidx);
12735
 
#endif
12736
 
    /* Note: fparse should not use soap_unget to push back last char */
12737
 
    if (soap_get0(soap) == (int)EOF)
12738
 
    { if (soap->status == 200)
12739
 
        return soap->error = SOAP_NO_DATA;
12740
 
      return soap->error = soap->status;
12741
 
    }
12742
 
#ifdef WITH_ZLIB
12743
 
    if (soap->zlib_in != SOAP_ZLIB_NONE)
12744
 
    {
12745
 
#ifdef WITH_GZIP
12746
 
      if (soap->zlib_in != SOAP_ZLIB_DEFLATE)
12747
 
      { c = soap_get1(soap);
12748
 
        if (c == 0x1F)
12749
 
        { if (soap_getgziphdr(soap))
12750
 
            return soap->error;
12751
 
          if (inflateInit2(&soap->d_stream, -MAX_WBITS) != Z_OK)
12752
 
            return soap->error = SOAP_ZLIB_ERROR;
12753
 
          soap->z_crc = crc32(0L, NULL, 0);
12754
 
          DBGLOG(TEST, SOAP_MESSAGE(fdebug, "gzip initialized\n"));
12755
 
        }
12756
 
        else
12757
 
        { soap_revget1(soap);
12758
 
          if (inflateInit(&soap->d_stream) != Z_OK)
12759
 
            return soap->error = SOAP_ZLIB_ERROR;
12760
 
          soap->zlib_in = SOAP_ZLIB_DEFLATE;
12761
 
        }
12762
 
      }
12763
 
      else
12764
 
#endif
12765
 
      if (inflateInit(&soap->d_stream) != Z_OK)
12766
 
        return soap->error = SOAP_ZLIB_ERROR;
12767
 
      soap->zlib_state = SOAP_ZLIB_INFLATE;
12768
 
      DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Inflate initialized\n"));
12769
 
      soap->mode |= SOAP_ENC_ZLIB;
12770
 
      memcpy(soap->z_buf, soap->buf, SOAP_BUFLEN);
12771
 
      soap->d_stream.next_in = (Byte*)(soap->z_buf + soap->bufidx);
12772
 
      soap->d_stream.avail_in = soap->buflen - soap->bufidx;
12773
 
      soap->z_buflen = soap->buflen;
12774
 
      soap->buflen = soap->bufidx;
12775
 
    }
12776
 
#endif
12777
 
    if (soap->error)
12778
 
    { if (soap->error == SOAP_FORM && soap->fform)
12779
 
      { soap->error = soap->fform(soap);
12780
 
        if (soap->error == SOAP_OK)
12781
 
          soap->error = SOAP_STOP; /* prevents further processing */
12782
 
      }
12783
 
      return soap->error;
12784
 
    }
12785
 
  }
12786
 
#endif
12787
 
#ifndef WITH_LEANER
12788
 
  if (soap->mode & SOAP_ENC_MIME)
12789
 
  { if (soap_getmimehdr(soap))
12790
 
      return soap->error;
12791
 
    if (soap->mime.start)
12792
 
    { do
12793
 
      { if (!soap->mime.last->id)
12794
 
          break;
12795
 
        if (!soap_match_cid(soap, soap->mime.start, soap->mime.last->id))
12796
 
          break;
12797
 
      } while (soap_get_mime_attachment(soap, NULL));
12798
 
    }
12799
 
    if (soap_get_header_attribute(soap, soap->mime.first->type, "application/dime"))
12800
 
      soap->mode |= SOAP_ENC_DIME;
12801
 
  }
12802
 
  if (soap->mode & SOAP_ENC_DIME)
12803
 
  { if (soap_getdimehdr(soap))
12804
 
      return soap->error;
12805
 
    if (soap->dime.flags & SOAP_DIME_CF)
12806
 
    { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Chunked DIME SOAP message\n"));
12807
 
      soap->dime.chunksize = soap->dime.size;
12808
 
      if (soap->buflen - soap->bufidx >= soap->dime.chunksize)
12809
 
      { soap->dime.buflen = soap->buflen;
12810
 
        soap->buflen = soap->bufidx + soap->dime.chunksize;
12811
 
      }
12812
 
      else
12813
 
        soap->dime.chunksize -= soap->buflen - soap->bufidx;
12814
 
    }
12815
 
    soap->count = soap->buflen - soap->bufidx;
12816
 
  }
12817
 
#endif
12818
 
  return SOAP_OK;
12819
 
}
12820
 
#endif
12821
 
 
12822
 
/******************************************************************************/
12823
 
#ifndef WITH_NOHTTP
12824
 
#ifndef PALM_1
12825
 
static int
12826
 
http_parse(struct soap *soap)
12827
 
{ char header[SOAP_HDRLEN], *s;
12828
 
  unsigned short get = 0, status = 0, k = 0;
12829
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Waiting for HTTP request/response...\n"));
12830
 
  *soap->endpoint = '\0';
12831
 
  soap->length = 0;
12832
 
  soap->userid = NULL;
12833
 
  soap->passwd = NULL;
12834
 
  soap->action = NULL;
12835
 
  soap->authrealm = NULL;
12836
 
  soap->proxy_from = NULL;
12837
 
  soap->http_content = NULL;
12838
 
  soap->status = 0;
12839
 
  do
12840
 
  { if (soap_getline(soap, soap->msgbuf, sizeof(soap->msgbuf)))
12841
 
    { if (soap->error == SOAP_EOF)
12842
 
        return SOAP_EOF;
12843
 
      return soap->error = 414;
12844
 
    }
12845
 
    DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP status: %s\n", soap->msgbuf));
12846
 
    for (;;)
12847
 
    { if (soap_getline(soap, header, SOAP_HDRLEN))
12848
 
      { if (soap->error == SOAP_EOF)
12849
 
        { soap->error = SOAP_OK;
12850
 
          DBGLOG(TEST,SOAP_MESSAGE(fdebug, "EOF in HTTP header, continue anyway\n"));
12851
 
          break;
12852
 
        }
12853
 
        return soap->error;
12854
 
      }
12855
 
      if (!*header)
12856
 
        break;
12857
 
      DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP header: %s\n", header));
12858
 
      s = strchr(header, ':');
12859
 
      if (s)
12860
 
      { char *t;
12861
 
        *s = '\0';
12862
 
        do s++;
12863
 
        while (*s && *s <= 32);
12864
 
        if (*s == '"')
12865
 
          s++;
12866
 
        t = s + strlen(s) - 1;
12867
 
        while (t > s && *t <= 32)
12868
 
          t--;
12869
 
        if (t >= s && *t == '"')
12870
 
          t--;
12871
 
        t[1] = '\0';
12872
 
        if ((soap->error = soap->fparsehdr(soap, header, s)))
12873
 
        { if (soap->error < SOAP_STOP)
12874
 
            return soap->error;
12875
 
          status = soap->error;
12876
 
          soap->error = SOAP_OK;
12877
 
        }
12878
 
      }
12879
 
    }
12880
 
    if ((s = strchr(soap->msgbuf, ' ')))
12881
 
    { k = (unsigned short)soap_strtoul(s, &s, 10);
12882
 
      if (!soap_blank(*s))
12883
 
        k = 0;
12884
 
    }
12885
 
    else
12886
 
      k = 0;
12887
 
  } while (k == 100);
12888
 
  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Finished HTTP header parsing, status = %d\n", k));
12889
 
  s = strstr(soap->msgbuf, "HTTP/");
12890
 
  if (s && s[7] != '1')
12891
 
  { if (soap->keep_alive == 1)
12892
 
      soap->keep_alive = 0;
12893
 
    if (k == 0 && (soap->omode & SOAP_IO) == SOAP_IO_CHUNK) /* k == 0 for HTTP request */
12894
 
    { soap->imode |= SOAP_IO_CHUNK;
12895
 
      soap->omode = (soap->omode & ~SOAP_IO) | SOAP_IO_STORE;
12896
 
    }
12897
 
  }
12898
 
  if (soap->keep_alive < 0)
12899
 
    soap->keep_alive = 1;
12900
 
  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Keep alive connection = %d\n", soap->keep_alive));
12901
 
  if (k == 0)
12902
 
  { if (s && (((get = !strncmp(soap->msgbuf, "GET ", 4))) || !strncmp(soap->msgbuf, "POST ", 5)))
12903
 
    { size_t m = strlen(soap->endpoint);
12904
 
      size_t n = m + (s - soap->msgbuf) - 5 - (!get);
12905
 
      if (m > n)
12906
 
        m = n;
12907
 
      if (n >= sizeof(soap->endpoint))
12908
 
        n = sizeof(soap->endpoint) - 1;
12909
 
      strncpy(soap->path, soap->msgbuf + 4 + (!get), n - m);
12910
 
      soap->path[n - m] = '\0';
12911
 
      strcat(soap->endpoint, soap->path);
12912
 
      DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Target endpoint='%s'\n", soap->endpoint));
12913
 
      if (get)
12914
 
      { soap->error = soap->fget(soap);
12915
 
        if (soap->error == SOAP_OK)
12916
 
          soap->error = SOAP_STOP; /* prevents further processing */
12917
 
        return soap->error;
12918
 
      }
12919
 
      if (status)
12920
 
        return soap->error = status;
12921
 
    }
12922
 
    else if (status)
12923
 
      return soap->error = status;
12924
 
    else if (s)
12925
 
      return soap->error = 405;
12926
 
  }
12927
 
  soap->status = k;
12928
 
  /* Status OK (HTTP 200) */
12929
 
  if (k == 0 || k == 200)
12930
 
    return SOAP_OK;
12931
 
  /* Status 201 (Created), 202 (Accepted), ... and HTTP 400 and 500 errors.
12932
 
     Only keep parsing HTTP body when content-length>0 or chunked is set.
12933
 
  */
12934
 
  if (((k > 200 && k <= 299) || k == 400 || k == 500) && (soap->length > 0 || (soap->imode & SOAP_IO) == SOAP_IO_CHUNK))
12935
 
    return SOAP_OK;
12936
 
  /* HTTP 400 and 500 headers are supposed to set content-length or chunked.
12937
 
     For those that don't we keep parsing the body only if content type is
12938
 
     given and connection closes.
12939
 
  */
12940
 
  if ((k == 400 || k == 500) && (soap->http_content || soap->keep_alive == 0))
12941
 
    return SOAP_OK;
12942
 
  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "HTTP error %d\n", k));
12943
 
  return soap_set_receiver_error(soap, "HTTP Error", soap->msgbuf, k);
12944
 
}
12945
 
#endif
12946
 
#endif
12947
 
 
12948
 
/******************************************************************************/
12949
 
#ifndef WITH_NOHTTP
12950
 
#ifndef PALM_1
12951
 
static int
12952
 
http_parse_header(struct soap *soap, const char *key, const char *val)
12953
 
{ if (!soap_tag_cmp(key, "Host"))
12954
 
  { 
12955
 
#ifdef WITH_OPENSSL
12956
 
    if (soap->imode & SOAP_ENC_SSL)
12957
 
      strcpy(soap->endpoint, "https://");
12958
 
    else
12959
 
#endif
12960
 
      strcpy(soap->endpoint, "http://");
12961
 
    strncat(soap->endpoint, val, sizeof(soap->endpoint) - 8);
12962
 
    soap->endpoint[sizeof(soap->endpoint) - 1] = '\0';
12963
 
  }
12964
 
#ifndef WITH_LEANER
12965
 
  else if (!soap_tag_cmp(key, "Content-Type"))
12966
 
  { soap->http_content = soap_strdup(soap, val);
12967
 
    if (soap_get_header_attribute(soap, val, "application/dime"))
12968
 
      soap->mode |= SOAP_ENC_DIME;
12969
 
    else if (soap_get_header_attribute(soap, val, "multipart/related")
12970
 
          || soap_get_header_attribute(soap, val, "multipart/form-data"))
12971
 
    { soap->mime.boundary = soap_strdup(soap, soap_get_header_attribute(soap, val, "boundary"));
12972
 
      soap->mime.start = soap_strdup(soap, soap_get_header_attribute(soap, val, "start"));
12973
 
      soap->mode |= SOAP_ENC_MIME;
12974
 
    }
12975
 
  }
12976
 
#endif
12977
 
  else if (!soap_tag_cmp(key, "Content-Length"))
12978
 
  { soap->length = soap_strtoul(val, NULL, 10);
12979
 
  }
12980
 
  else if (!soap_tag_cmp(key, "Content-Encoding"))
12981
 
  { if (!soap_tag_cmp(val, "deflate"))
12982
 
#ifdef WITH_ZLIB
12983
 
      soap->zlib_in = SOAP_ZLIB_DEFLATE;
12984
 
#else
12985
 
      return SOAP_ZLIB_ERROR;
12986
 
#endif
12987
 
    else if (!soap_tag_cmp(val, "gzip"))
12988
 
#ifdef WITH_GZIP
12989
 
      soap->zlib_in = SOAP_ZLIB_GZIP;
12990
 
#else
12991
 
      return SOAP_ZLIB_ERROR;
12992
 
#endif
12993
 
  }
12994
 
#ifdef WITH_ZLIB
12995
 
  else if (!soap_tag_cmp(key, "Accept-Encoding"))
12996
 
  {
12997
 
#ifdef WITH_GZIP
12998
 
    if (strchr(val, '*') || soap_get_header_attribute(soap, val, "gzip"))
12999
 
      soap->zlib_out = SOAP_ZLIB_GZIP;
13000
 
    else
13001
 
#endif
13002
 
    if (strchr(val, '*') || soap_get_header_attribute(soap, val, "deflate"))
13003
 
      soap->zlib_out = SOAP_ZLIB_DEFLATE;
13004
 
    else
13005
 
      soap->zlib_out = SOAP_ZLIB_NONE;
13006
 
  }
13007
 
#endif
13008
 
  else if (!soap_tag_cmp(key, "Transfer-Encoding"))
13009
 
  { soap->mode &= ~SOAP_IO;
13010
 
    if (!soap_tag_cmp(val, "chunked"))
13011
 
      soap->mode |= SOAP_IO_CHUNK;
13012
 
  }
13013
 
  else if (!soap_tag_cmp(key, "Connection"))
13014
 
  { if (!soap_tag_cmp(val, "keep-alive"))
13015
 
      soap->keep_alive = -soap->keep_alive;
13016
 
    else if (!soap_tag_cmp(val, "close"))
13017
 
      soap->keep_alive = 0;
13018
 
  }
13019
 
#ifndef WITH_LEAN
13020
 
  else if (!soap_tag_cmp(key, "Authorization"))
13021
 
  { if (!soap_tag_cmp(val, "Basic *"))
13022
 
    { int n;
13023
 
      char *s;
13024
 
      soap_base642s(soap, val + 6, soap->tmpbuf, sizeof(soap->tmpbuf) - 1, &n);
13025
 
      soap->tmpbuf[n] = '\0';
13026
 
      if ((s = strchr(soap->tmpbuf, ':')))
13027
 
      { *s = '\0';
13028
 
        soap->userid = soap_strdup(soap, soap->tmpbuf);
13029
 
        soap->passwd = soap_strdup(soap, s + 1);
13030
 
      }
13031
 
    }
13032
 
  }
13033
 
  else if (!soap_tag_cmp(key, "WWW-Authenticate"))
13034
 
  { soap->authrealm = soap_strdup(soap, soap_get_header_attribute(soap, val + 6, "realm"));
13035
 
  }
13036
 
  else if (!soap_tag_cmp(key, "Expect"))
13037
 
  { if (!soap_tag_cmp(val, "100-continue"))
13038
 
    { if ((soap->error = soap->fposthdr(soap, "HTTP/1.1 100 Continue", NULL))
13039
 
       || (soap->error = soap->fposthdr(soap, NULL, NULL)))
13040
 
        return soap->error;
13041
 
    }
13042
 
  }
13043
 
#endif
13044
 
  else if (!soap_tag_cmp(key, "SOAPAction"))
13045
 
  { if (*val == '"')
13046
 
    { soap->action = soap_strdup(soap, val + 1);
13047
 
      soap->action[strlen(soap->action) - 1] = '\0';
13048
 
    }
13049
 
    else
13050
 
      soap->action = soap_strdup(soap, val);
13051
 
  }
13052
 
  else if (!soap_tag_cmp(key, "Location"))
13053
 
  { strncpy(soap->endpoint, val, sizeof(soap->endpoint));
13054
 
    soap->endpoint[sizeof(soap->endpoint) - 1] = '\0';
13055
 
  }
13056
 
  else if (!soap_tag_cmp(key, "X-Forwarded-For"))
13057
 
  { soap->proxy_from = soap_strdup(soap, val);
13058
 
  }
13059
 
#ifdef WITH_COOKIES
13060
 
  else if (!soap_tag_cmp(key, "Cookie")
13061
 
   || !soap_tag_cmp(key, "Cookie2")
13062
 
   || !soap_tag_cmp(key, "Set-Cookie")
13063
 
   || !soap_tag_cmp(key, "Set-Cookie2"))
13064
 
  { soap_getcookies(soap, val);
13065
 
  }
13066
 
#endif
13067
 
  return SOAP_OK;
13068
 
}
13069
 
#endif
13070
 
#endif
13071
 
 
13072
 
/******************************************************************************/
13073
 
#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER)
13074
 
#ifndef PALM_1
13075
 
SOAP_FMAC1
13076
 
const char*
13077
 
SOAP_FMAC2
13078
 
soap_get_header_attribute(struct soap *soap, const char *line, const char *key)
13079
 
{ register const char *s = line;
13080
 
  if (s)
13081
 
  { while (*s)
13082
 
    { register short flag;
13083
 
      s = soap_decode_key(soap->tmpbuf, sizeof(soap->tmpbuf), s);
13084
 
      flag = soap_tag_cmp(soap->tmpbuf, key);
13085
 
      s = soap_decode_val(soap->tmpbuf, sizeof(soap->tmpbuf), s);
13086
 
      if (!flag)
13087
 
        return soap->tmpbuf;
13088
 
    }
13089
 
  }
13090
 
  return NULL;
13091
 
}
13092
 
#endif
13093
 
#endif
13094
 
 
13095
 
/******************************************************************************/
13096
 
#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER)
13097
 
#ifndef PALM_1
13098
 
SOAP_FMAC1
13099
 
const char*
13100
 
SOAP_FMAC2
13101
 
soap_decode_key(char *buf, size_t len, const char *val)
13102
 
{ return soap_decode(buf, len, val, "=,;");
13103
 
}
13104
 
#endif
13105
 
#endif
13106
 
 
13107
 
/******************************************************************************/
13108
 
#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER)
13109
 
#ifndef PALM_1
13110
 
SOAP_FMAC1
13111
 
const char*
13112
 
SOAP_FMAC2
13113
 
soap_decode_val(char *buf, size_t len, const char *val)
13114
 
{ if (*val != '=')
13115
 
  { *buf = '\0';
13116
 
    return val;
13117
 
  }
13118
 
  return soap_decode(buf, len, val + 1, ",;");
13119
 
}
13120
 
#endif
13121
 
#endif
13122
 
 
13123
 
/******************************************************************************/
13124
 
#if !defined(WITH_NOHTTP) || !defined(WITH_LEANER)
13125
 
#ifndef PALM_1
13126
 
static const char*
13127
 
soap_decode(char *buf, size_t len, const char *val, const char *sep)
13128
 
{ const char *s;
13129
 
  char *t = buf;
13130
 
  for (s = val; *s; s++)
13131
 
    if (*s != ' ' && *s != '\t' && !strchr(sep, *s))
13132
 
      break;
13133
 
  if (*s == '"')
13134
 
  { s++;
13135
 
    while (*s && *s != '"' && --len)
13136
 
      *t++ = *s++;
13137
 
  }
13138
 
  else
13139
 
  { while (soap_notblank(*s) && !strchr(sep, *s) && --len)
13140
 
    { if (*s == '%')
13141
 
      { *t++ = ((s[1] >= 'A' ? (s[1] & 0x7) + 9 : s[1] - '0') << 4)
13142
 
              + (s[2] >= 'A' ? (s[2] & 0x7) + 9 : s[2] - '0');
13143
 
        s += 3;
13144
 
      }
13145
 
      else
13146
 
        *t++ = *s++;
13147
 
    }
13148
 
  }
13149
 
  *t = '\0';
13150
 
  while (*s && !strchr(sep, *s))
13151
 
    s++;
13152
 
  return s;
13153
 
}
13154
 
#endif
13155
 
#endif
13156
 
 
13157
 
/******************************************************************************/
13158
 
#ifndef PALM_2
13159
 
SOAP_FMAC1
13160
 
int
13161
 
SOAP_FMAC2
13162
 
soap_envelope_begin_out(struct soap *soap)
13163
 
{
13164
 
#ifndef WITH_LEANER
13165
 
  size_t n = 0;
13166
 
  if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary && soap->mime.start && strlen(soap->mime.boundary) + strlen(soap->mime.start) < sizeof(soap->tmpbuf) - 80 )
13167
 
  { const char *s;
13168
 
    if ((soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM))
13169
 
      s = "application/dime";
13170
 
    else if (soap->version == 2)
13171
 
    { if (soap->mode & SOAP_ENC_MTOM)
13172
 
        s = "application/xop+xml; charset=utf-8; type=application/soap+xml";
13173
 
      else
13174
 
        s = "application/soap+xml; charset=utf-8";
13175
 
    }
13176
 
    else
13177
 
      s = "text/xml; charset=utf-8";
13178
 
    sprintf(soap->tmpbuf, "--%s\r\nContent-Type: %s\r\nContent-Transfer-Encoding: binary\r\nContent-ID: %s\r\n\r\n", soap->mime.boundary, s, soap->mime.start);
13179
 
    n = strlen(soap->tmpbuf);
13180
 
    if (soap_send_raw(soap, soap->tmpbuf, n))
13181
 
      return soap->error;
13182
 
  }
13183
 
  if (soap->mode & SOAP_IO_LENGTH)
13184
 
    soap->dime.size = soap->count;      /* DIME in MIME correction */
13185
 
  if (!(soap->mode & SOAP_IO_LENGTH) && (soap->mode & SOAP_ENC_DIME))
13186
 
  { if (soap_putdimehdr(soap))
13187
 
      return soap->error;
13188
 
  }
13189
 
#endif
13190
 
  soap->part = SOAP_IN_ENVELOPE;
13191
 
  return soap_element_begin_out(soap, "SOAP-ENV:Envelope", 0, NULL);
13192
 
}
13193
 
#endif
13194
 
 
13195
 
/******************************************************************************/
13196
 
#ifndef PALM_2
13197
 
SOAP_FMAC1
13198
 
int
13199
 
SOAP_FMAC2
13200
 
soap_envelope_end_out(struct soap *soap)
13201
 
{ if (soap_element_end_out(soap, "SOAP-ENV:Envelope"))
13202
 
    return soap->error;
13203
 
#ifndef WITH_LEANER
13204
 
  if ((soap->mode & SOAP_IO_LENGTH) && (soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM))
13205
 
  { soap->dime.size = soap->count - soap->dime.size;    /* DIME in MIME correction */
13206
 
    sprintf(soap->id, soap->dime_id_format, 0);
13207
 
    soap->dime.id = soap->id;
13208
 
    if (soap->local_namespaces)
13209
 
    { if (soap->local_namespaces[0].out)
13210
 
        soap->dime.type = (char*)soap->local_namespaces[0].out;
13211
 
      else
13212
 
        soap->dime.type = (char*)soap->local_namespaces[0].ns;
13213
 
    }
13214
 
    soap->dime.options = NULL;
13215
 
    soap->dime.flags = SOAP_DIME_MB | SOAP_DIME_ABSURI;
13216
 
    if (!soap->dime.first)
13217
 
      soap->dime.flags |= SOAP_DIME_ME;
13218
 
    soap->count += 12 + ((strlen(soap->dime.id)+3)&(~3)) + (soap->dime.type ? ((strlen(soap->dime.type)+3)&(~3)) : 0);
13219
 
  }
13220
 
  if ((soap->mode & SOAP_ENC_DIME) && !(soap->mode & SOAP_ENC_MTOM))
13221
 
    return soap_send_raw(soap, SOAP_STR_PADDING, -(long)soap->dime.size&3);
13222
 
#endif
13223
 
  soap->part = SOAP_END_ENVELOPE;
13224
 
  return SOAP_OK;
13225
 
13226
 
#endif
13227
 
 
13228
 
/******************************************************************************/
13229
 
#ifndef PALM_1
13230
 
SOAP_FMAC1
13231
 
int
13232
 
SOAP_FMAC2
13233
 
soap_envelope_begin_in(struct soap *soap)
13234
 
{ register struct Namespace *p;
13235
 
  soap->part = SOAP_IN_ENVELOPE;
13236
 
  if (soap_element_begin_in(soap, "SOAP-ENV:Envelope", 0, NULL))
13237
 
  { 
13238
 
#ifndef WITH_LEAN
13239
 
    if (soap->error == SOAP_TAG_MISMATCH && !soap_element_begin_in(soap, "html", 0, NULL))
13240
 
    { /* get HTML from buffer, stop receiving to avoid HTML parsing issues */
13241
 
      char *s;
13242
 
#ifndef WITH_NOIO
13243
 
      size_t (*f)(struct soap*, char*, size_t) = soap->frecv;
13244
 
      soap->frecv = frecv_stop;
13245
 
#endif
13246
 
      soap_revert(soap);
13247
 
      s = soap_string_in(soap, 1, -1, -1);
13248
 
#ifndef WITH_NOIO
13249
 
      soap->frecv = f;
13250
 
#endif
13251
 
      return soap_set_receiver_error(soap, "HTTP Error", s, SOAP_HTTP_ERROR);
13252
 
    }
13253
 
#endif
13254
 
    if (soap->error == SOAP_TAG_MISMATCH)
13255
 
      return soap->error = SOAP_VERSIONMISMATCH;
13256
 
    return soap->error;
13257
 
  }
13258
 
  p = soap->local_namespaces;
13259
 
  if (p)
13260
 
  { const char *ns = p[0].out;
13261
 
    if (!ns)
13262
 
      ns = p[0].ns;
13263
 
    if (!strcmp(ns, soap_env1))
13264
 
    { soap->version = 1; /* make sure we use SOAP 1.1 */
13265
 
      if (p[1].out)
13266
 
        SOAP_FREE(soap, p[1].out);
13267
 
      if ((p[1].out = (char*)SOAP_MALLOC(soap, sizeof(soap_enc1))))
13268
 
        strcpy(p[1].out, soap_enc1);
13269
 
    }
13270
 
    else if (!strcmp(ns, soap_env2))
13271
 
    { soap->version = 2; /* make sure we use SOAP 1.2 */
13272
 
      if (p[1].out)
13273
 
        SOAP_FREE(soap, p[1].out);
13274
 
      if ((p[1].out = (char*)SOAP_MALLOC(soap, sizeof(soap_enc2))))
13275
 
        strcpy(p[1].out, soap_enc2);
13276
 
    }
13277
 
  }
13278
 
  return SOAP_OK;
13279
 
}
13280
 
#endif
13281
 
 
13282
 
/******************************************************************************/
13283
 
#ifndef PALM_1
13284
 
SOAP_FMAC1
13285
 
int
13286
 
SOAP_FMAC2
13287
 
soap_envelope_end_in(struct soap *soap)
13288
 
{ soap->part = SOAP_END_ENVELOPE;
13289
 
  return soap_element_end_in(soap, "SOAP-ENV:Envelope");
13290
 
}
13291
 
#endif
13292
 
 
13293
 
/******************************************************************************/
13294
 
#ifndef PALM_2
13295
 
SOAP_FMAC1
13296
 
int
13297
 
SOAP_FMAC2
13298
 
soap_body_begin_out(struct soap *soap)
13299
 
{ soap->part = SOAP_IN_BODY;
13300
 
  if (soap->version == 1)
13301
 
    soap->encoding = 1;
13302
 
#ifndef WITH_LEAN
13303
 
  if ((soap->mode & SOAP_XML_SEC) && soap_set_attr(soap, "wsu:Id", "Body"))
13304
 
    return soap->error;
13305
 
#endif
13306
 
  if (soap_element(soap, "SOAP-ENV:Body", 0, NULL))
13307
 
    return soap->error;
13308
 
  return soap_element_start_end_out(soap, NULL);
13309
 
}
13310
 
#endif
13311
 
 
13312
 
/******************************************************************************/
13313
 
#ifndef PALM_2
13314
 
SOAP_FMAC1
13315
 
int
13316
 
SOAP_FMAC2
13317
 
soap_body_end_out(struct soap *soap)
13318
 
{ if (soap_element_end_out(soap, "SOAP-ENV:Body"))
13319
 
    return soap->error;
13320
 
  soap->part = SOAP_END_BODY;
13321
 
  return SOAP_OK;
13322
 
}
13323
 
#endif
13324
 
 
13325
 
/******************************************************************************/
13326
 
#ifndef PALM_2
13327
 
SOAP_FMAC1
13328
 
int
13329
 
SOAP_FMAC2
13330
 
soap_body_begin_in(struct soap *soap)
13331
 
{ soap->part = SOAP_IN_BODY;
13332
 
  if (soap_element_begin_in(soap, "SOAP-ENV:Body", 0, NULL))
13333
 
    return soap->error;
13334
 
  if (!soap->body)
13335
 
    soap->part = SOAP_NO_BODY;
13336
 
  return SOAP_OK;
13337
 
}
13338
 
#endif
13339
 
 
13340
 
/******************************************************************************/
13341
 
#ifndef PALM_2
13342
 
SOAP_FMAC1
13343
 
int
13344
 
SOAP_FMAC2
13345
 
soap_body_end_in(struct soap *soap)
13346
 
{ if (soap->part == SOAP_NO_BODY)
13347
 
    return SOAP_OK;
13348
 
  soap->part = SOAP_END_BODY;
13349
 
  return soap_element_end_in(soap, "SOAP-ENV:Body");
13350
 
}
13351
 
#endif
13352
 
 
13353
 
/******************************************************************************/
13354
 
#ifndef PALM_2
13355
 
SOAP_FMAC1
13356
 
int
13357
 
SOAP_FMAC2
13358
 
soap_recv_header(struct soap *soap)
13359
 
{ if (soap_getheader(soap) && soap->error == SOAP_TAG_MISMATCH)
13360
 
    soap->error = SOAP_OK;
13361
 
  else if (soap->error == SOAP_OK && soap->fheader)
13362
 
    soap->error = soap->fheader(soap);
13363
 
  return soap->error;
13364
 
}
13365
 
#endif
13366
 
 
13367
 
/******************************************************************************/
13368
 
#ifndef PALM_1
13369
 
SOAP_FMAC1
13370
 
void
13371
 
SOAP_FMAC2
13372
 
soap_set_endpoint(struct soap *soap, const char *endpoint)
13373
 
{ register const char *s;
13374
 
  register size_t i, n;
13375
 
  soap->endpoint[0] = '\0';
13376
 
  soap->host[0] = '\0';
13377
 
  soap->path[0] = '/';
13378
 
  soap->path[1] = '\0';
13379
 
  soap->port = 80;
13380
 
  if (!endpoint || !*endpoint)
13381
 
    return;
13382
 
#ifdef WITH_OPENSSL
13383
 
  if (!soap_tag_cmp(endpoint, "https:*"))
13384
 
    soap->port = 443;
13385
 
#endif
13386
 
  strncpy(soap->endpoint, endpoint, sizeof(soap->endpoint) - 1);
13387
 
  soap->endpoint[sizeof(soap->endpoint) - 1] = '\0';
13388
 
  s = strchr(endpoint, ':');
13389
 
  if (s && s[1] == '/' && s[2] == '/')
13390
 
    s += 3;
13391
 
  else
13392
 
    s = endpoint;
13393
 
  n = strlen(s);
13394
 
  if (n >= sizeof(soap->host))
13395
 
    n = sizeof(soap->host) - 1;
13396
 
#ifdef WITH_IPV6
13397
 
  if (s[0] == '[')
13398
 
  { s++;
13399
 
    for (i = 0; i < n; i++)
13400
 
    { if (s[i] == ']')
13401
 
      { s++;
13402
 
        --n;
13403
 
        break; 
13404
 
      }
13405
 
      soap->host[i] = s[i];
13406
 
    }
13407
 
  }
13408
 
  else
13409
 
  { for (i = 0; i < n; i++)
13410
 
    { soap->host[i] = s[i];
13411
 
      if (s[i] == '/' || s[i] == ':')
13412
 
        break; 
13413
 
    }
13414
 
  }
13415
 
#else
13416
 
  for (i = 0; i < n; i++)
13417
 
  { soap->host[i] = s[i];
13418
 
    if (s[i] == '/' || s[i] == ':')
13419
 
      break; 
13420
 
  }
13421
 
#endif
13422
 
  soap->host[i] = '\0';
13423
 
  if (s[i] == ':')
13424
 
  { soap->port = (int)atol(s + i + 1);
13425
 
    for (i++; i < n; i++)
13426
 
      if (s[i] == '/')
13427
 
        break;
13428
 
  }
13429
 
  if (i < n && s[i])
13430
 
  { strncpy(soap->path, s + i, sizeof(soap->path));
13431
 
    soap->path[sizeof(soap->path) - 1] = '\0';
13432
 
  }
13433
 
}
13434
 
#endif
13435
 
 
13436
 
/******************************************************************************/
13437
 
#ifndef PALM_1
13438
 
SOAP_FMAC1
13439
 
int
13440
 
SOAP_FMAC2
13441
 
soap_connect(struct soap *soap, const char *endpoint, const char *action)
13442
 
{ return soap_connect_command(soap, SOAP_POST, endpoint, action);
13443
 
}
13444
 
#endif
13445
 
 
13446
 
/******************************************************************************/
13447
 
#ifndef PALM_1
13448
 
SOAP_FMAC1
13449
 
int
13450
 
SOAP_FMAC2
13451
 
soap_connect_command(struct soap *soap, int http_command, const char *endpoint, const char *action)
13452
 
{ char host[sizeof(soap->host)];
13453
 
  int port;
13454
 
  size_t count;
13455
 
  soap->error = SOAP_OK;
13456
 
  strcpy(host, soap->host); /* save to compare */
13457
 
  port = soap->port; /* save to compare */
13458
 
  soap_set_endpoint(soap, endpoint);
13459
 
#ifndef WITH_LEANER
13460
 
  if (soap->fconnect)
13461
 
  { if ((soap->error = soap->fconnect(soap, endpoint, soap->host, soap->port)))
13462
 
      return soap->error;
13463
 
  }
13464
 
  else
13465
 
#endif
13466
 
  if (soap->fopen && *soap->host)
13467
 
  { soap->status = http_command;
13468
 
    if (!soap->keep_alive || !soap_valid_socket(soap->socket) || strcmp(soap->host, host) || soap->port != port || !soap->fpoll || soap->fpoll(soap))
13469
 
    { soap->keep_alive = 0; /* to force close */
13470
 
      soap->omode &= ~SOAP_IO_UDP; /* to force close */
13471
 
      soap_closesock(soap);
13472
 
      DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Connect/reconnect to host='%s' path='%s' port=%d\n", soap->host, soap->path, soap->port));
13473
 
#ifdef WITH_UDP
13474
 
      if (!strncmp(endpoint, "soap.udp:", 9))
13475
 
        soap->omode |= SOAP_IO_UDP;
13476
 
#endif
13477
 
      soap->socket = soap->fopen(soap, endpoint, soap->host, soap->port);
13478
 
      if (soap->error)
13479
 
        return soap->error;
13480
 
      soap->keep_alive = ((soap->omode & SOAP_IO_KEEPALIVE) != 0);
13481
 
    }
13482
 
  }
13483
 
  count = soap_count_attachments(soap);
13484
 
  if (soap_begin_send(soap))
13485
 
    return soap->error;
13486
 
  if (http_command != SOAP_POST)
13487
 
  { soap->mode &= ~SOAP_IO;
13488
 
    soap->mode |= SOAP_IO_BUFFER;
13489
 
  }
13490
 
#ifndef WITH_NOHTTP
13491
 
  soap->action = soap_strdup(soap, action);
13492
 
  if ((soap->mode & SOAP_IO) != SOAP_IO_STORE && !(soap->mode & SOAP_ENC_XML) && endpoint)
13493
 
  { unsigned int k = soap->mode;
13494
 
    soap->mode &= ~(SOAP_IO | SOAP_ENC_ZLIB);
13495
 
    if ((k & SOAP_IO) != SOAP_IO_FLUSH)
13496
 
      soap->mode |= SOAP_IO_BUFFER;
13497
 
    if ((soap->error = soap->fpost(soap, endpoint, soap->host, soap->port, soap->path, action, count)))
13498
 
      return soap->error;
13499
 
#ifndef WITH_LEANER
13500
 
    if ((k & SOAP_IO) == SOAP_IO_CHUNK)
13501
 
    { if (soap_flush(soap))
13502
 
        return soap->error;
13503
 
    }
13504
 
#endif
13505
 
    soap->mode = k;
13506
 
  }
13507
 
  if (http_command != SOAP_POST)
13508
 
    return soap_end_send(soap);
13509
 
#endif
13510
 
  return SOAP_OK;
13511
 
}
13512
 
#endif
13513
 
 
13514
 
/******************************************************************************/
13515
 
#ifndef WITH_LEAN
13516
 
SOAP_FMAC1
13517
 
char*
13518
 
SOAP_FMAC2
13519
 
soap_s2base64(struct soap *soap, const unsigned char *s, char *t, int n)
13520
 
{ register int i;
13521
 
  register unsigned long m;
13522
 
  register char *p;
13523
 
  if (!t)
13524
 
    t = (char*)soap_malloc(soap, (n + 2) / 3 * 4 + 1);
13525
 
  if (!t)
13526
 
  { soap->error = SOAP_EOM;
13527
 
    return NULL;
13528
 
  }
13529
 
  p = t;
13530
 
  t[0] = '\0';
13531
 
  if (!s)
13532
 
    return p;
13533
 
  for (; n > 2; n -= 3, s += 3)
13534
 
  { m = s[0];
13535
 
    m = (m << 8) | s[1];
13536
 
    m = (m << 8) | s[2];
13537
 
    for (i = 4; i > 0; m >>= 6)
13538
 
      t[--i] = soap_base64o[m & 0x3F];
13539
 
    t += 4;
13540
 
  }
13541
 
  t[0] = '\0';
13542
 
  if (n > 0)
13543
 
  { m = 0;
13544
 
    for (i = 0; i < n; i++)
13545
 
      m = (m << 8) | *s++;
13546
 
    for (; i < 3; i++)
13547
 
      m <<= 8;
13548
 
    for (i++; i > 0; m >>= 6)
13549
 
      t[--i] = soap_base64o[m & 0x3F];
13550
 
    for (i = 3; i > n; i--)
13551
 
      t[i] = '=';
13552
 
    t[4] = '\0';
13553
 
  }
13554
 
  return p;
13555
 
}
13556
 
#endif
13557
 
 
13558
 
/******************************************************************************/
13559
 
#ifndef WITH_LEAN
13560
 
SOAP_FMAC1
13561
 
const char*
13562
 
SOAP_FMAC2
13563
 
soap_base642s(struct soap *soap, const char *s, char *t, size_t l, int *n)
13564
 
{ register int i, j, c;
13565
 
  register unsigned long m;
13566
 
  register const char *p;
13567
 
  if (!s || !*s)
13568
 
  { if (n)
13569
 
      *n = 0;
13570
 
    if (soap->error)
13571
 
      return NULL;
13572
 
    return SOAP_NON_NULL;
13573
 
  }
13574
 
  if (!t)
13575
 
  { l = (strlen(s) + 3) / 4 * 3;
13576
 
    t = (char*)soap_malloc(soap, l);
13577
 
  }
13578
 
  if (!t)
13579
 
  { soap->error = SOAP_EOM;
13580
 
    return NULL;
13581
 
  }
13582
 
  p = t;
13583
 
  if (n)
13584
 
    *n = 0;
13585
 
  for (;;)
13586
 
  { for (i = 0; i < SOAP_BLKLEN; i++)
13587
 
    { m = 0;
13588
 
      j = 0;
13589
 
      while (j < 4)
13590
 
      { c = *s++;
13591
 
        if (c == '=' || !c)
13592
 
        { i *= 3;
13593
 
          switch (j)
13594
 
          { case 2:
13595
 
              *t++ = (char)((m >> 4) & 0xFF);
13596
 
              i++;
13597
 
              break;
13598
 
            case 3:
13599
 
              *t++ = (char)((m >> 10) & 0xFF);
13600
 
              *t++ = (char)((m >> 2) & 0xFF);
13601
 
              i += 2;
13602
 
          }
13603
 
          if (n)
13604
 
            *n += i;
13605
 
          return p;
13606
 
        }
13607
 
        c -= '+';
13608
 
        if (c >= 0 && c <= 79)
13609
 
        { int b = soap_base64i[c];
13610
 
          if (b >= 64)
13611
 
          { soap->error = SOAP_TYPE;
13612
 
            return NULL;  
13613
 
          }
13614
 
          m = (m << 6) + b;
13615
 
          j++;
13616
 
        }
13617
 
        else if (!soap_blank(c + '+'))
13618
 
        { soap->error = SOAP_TYPE;
13619
 
          return NULL;  
13620
 
        }
13621
 
      }
13622
 
      *t++ = (char)((m >> 16) & 0xFF);
13623
 
      *t++ = (char)((m >> 8) & 0xFF);
13624
 
      *t++ = (char)(m & 0xFF);
13625
 
      if (l < 3)
13626
 
      { if (n)
13627
 
          *n += i;
13628
 
        return p;
13629
 
      }
13630
 
      l -= 3;
13631
 
    }
13632
 
    if (n)
13633
 
      *n += 3 * SOAP_BLKLEN;
13634
 
  }
13635
 
}
13636
 
#endif
13637
 
 
13638
 
/******************************************************************************/
13639
 
#ifndef WITH_LEAN
13640
 
SOAP_FMAC1
13641
 
char*
13642
 
SOAP_FMAC2
13643
 
soap_s2hex(struct soap *soap, const unsigned char *s, char *t, int n)
13644
 
{ register char *p;
13645
 
  if (!t)
13646
 
    t = (char*)soap_malloc(soap, 2 * n + 1);
13647
 
  if (!t)
13648
 
  { soap->error = SOAP_EOM;
13649
 
    return NULL;
13650
 
  }
13651
 
  p = t;
13652
 
  t[0] = '\0';
13653
 
  if (s)
13654
 
  { for (; n > 0; n--)
13655
 
    { register int m = *s++;
13656
 
      *t++ = (char)((m >> 4) + (m > 159 ? 'a' - 10 : '0'));
13657
 
      m &= 0x0F;
13658
 
      *t++ = (char)(m + (m > 9 ? 'a' - 10 : '0'));
13659
 
    }
13660
 
  }
13661
 
  *t++ = '\0';
13662
 
  return p;
13663
 
}
13664
 
#endif
13665
 
 
13666
 
/******************************************************************************/
13667
 
#ifndef WITH_LEAN
13668
 
SOAP_FMAC1
13669
 
const char*
13670
 
SOAP_FMAC2
13671
 
soap_hex2s(struct soap *soap, const char *s, char *t, size_t l, int *n)
13672
 
{ register const char *p;
13673
 
  if (!s || !*s)
13674
 
  { if (n)
13675
 
      *n = 0;
13676
 
    if (soap->error)
13677
 
      return NULL;
13678
 
    return SOAP_NON_NULL;
13679
 
  }
13680
 
  if (!t)
13681
 
  { l = strlen(s) / 2;
13682
 
    t = (char*)soap_malloc(soap, l);
13683
 
  }
13684
 
  if (!t)
13685
 
  { soap->error = SOAP_EOM;
13686
 
    return NULL;
13687
 
  }
13688
 
  p = t;
13689
 
  while (l)
13690
 
  { register int d1, d2;
13691
 
    d1 = *s++;
13692
 
    if (!d1)
13693
 
      break;
13694
 
    d2 = *s++;
13695
 
    if (!d2)
13696
 
      break;
13697
 
    *t++ = ((d1 >= 'A' ? (d1 & 0x7) + 9 : d1 - '0') << 4) + (d2 >= 'A' ? (d2 & 0x7) + 9 : d2 - '0');
13698
 
    l--;
13699
 
  }
13700
 
  if (n)
13701
 
    *n = (int)(t - p);
13702
 
  return p;
13703
 
}
13704
 
#endif
13705
 
 
13706
 
/******************************************************************************/
13707
 
#ifndef WITH_NOHTTP
13708
 
#ifndef PALM_1
13709
 
SOAP_FMAC1
13710
 
int
13711
 
SOAP_FMAC2
13712
 
soap_puthttphdr(struct soap *soap, int status, size_t count)
13713
 
{ if (soap->status != SOAP_GET)
13714
 
  { register const char *s = "text/xml; charset=utf-8";
13715
 
    register int err = SOAP_OK;
13716
 
#ifndef WITH_LEANER
13717
 
    register const char *r = NULL;
13718
 
#endif
13719
 
    if (status == SOAP_FILE && soap->http_content)
13720
 
      s = soap->http_content;
13721
 
    else if (status == SOAP_HTML)
13722
 
      s = "text/html; charset=utf-8";
13723
 
    else if (count || ((soap->omode & SOAP_IO) == SOAP_IO_CHUNK))
13724
 
    { if (soap->version == 2)
13725
 
        s = "application/soap+xml; charset=utf-8";
13726
 
    }
13727
 
#ifndef WITH_LEANER
13728
 
    if (soap->mode & (SOAP_ENC_DIME | SOAP_ENC_MTOM))
13729
 
    { if (soap->mode & SOAP_ENC_MTOM)
13730
 
      { r = s;
13731
 
        s = "application/xop+xml; charset=utf-8";
13732
 
      }
13733
 
      else
13734
 
        s = "application/dime";
13735
 
    }
13736
 
    if ((soap->mode & SOAP_ENC_MIME) && soap->mime.boundary && strlen(soap->mime.boundary) + strlen(soap->mime.start ? soap->mime.start : SOAP_STR_EOS) < sizeof(soap->tmpbuf) - 80)
13737
 
    { register const char *t = strchr(s, ';');
13738
 
      sprintf(soap->tmpbuf, "multipart/related; boundary=\"%s\"; type=\"", soap->mime.boundary);
13739
 
      if (t)
13740
 
        strncat(soap->tmpbuf, s, t - s);
13741
 
      else
13742
 
        strcat(soap->tmpbuf, s);
13743
 
      if (soap->mime.start)
13744
 
      { strcat(soap->tmpbuf, "\"; start=\"");
13745
 
        strcat(soap->tmpbuf, soap->mime.start);
13746
 
      }
13747
 
      strcat(soap->tmpbuf, "\"");
13748
 
      if (r)
13749
 
      { strcat(soap->tmpbuf, "; start-info=\"");
13750
 
        strcat(soap->tmpbuf, r);
13751
 
        strcat(soap->tmpbuf, "\"");
13752
 
      }
13753
 
      s = soap->tmpbuf;
13754
 
    }
13755
 
#endif
13756
 
    if (s && (err = soap->fposthdr(soap, "Content-Type", s)))
13757
 
      return err;
13758
 
#ifdef WITH_ZLIB
13759
 
    if (soap->omode & SOAP_ENC_ZLIB)
13760
 
    { 
13761
 
#ifdef WITH_GZIP
13762
 
      err = soap->fposthdr(soap, "Content-Encoding", soap->zlib_out == SOAP_ZLIB_DEFLATE ? "deflate" : "gzip");
13763
 
#else
13764
 
      err = soap->fposthdr(soap, "Content-Encoding", "deflate");
13765
 
#endif
13766
 
      if (err)
13767
 
        return err;
13768
 
    }
13769
 
#endif
13770
 
#ifndef WITH_LEANER
13771
 
    if ((soap->omode & SOAP_IO) == SOAP_IO_CHUNK)
13772
 
      err = soap->fposthdr(soap, "Transfer-Encoding", "chunked");
13773
 
    else
13774
 
#endif
13775
 
    if (s)
13776
 
    { sprintf(soap->tmpbuf, "%lu", (unsigned long)count);
13777
 
      err = soap->fposthdr(soap, "Content-Length", soap->tmpbuf);
13778
 
    }
13779
 
    if (err)
13780
 
      return err;
13781
 
  }
13782
 
  return soap->fposthdr(soap, "Connection", soap->keep_alive ? "keep-alive" : "close");
13783
 
}
13784
 
#endif
13785
 
#endif
13786
 
 
13787
 
/******************************************************************************/
13788
 
#ifndef WITH_NOHTTP
13789
 
#ifndef PALM_1
13790
 
static int
13791
 
http_get(struct soap *soap)
13792
 
{ return SOAP_GET_METHOD;
13793
 
}
13794
 
#endif
13795
 
#endif
13796
 
 
13797
 
/******************************************************************************/
13798
 
#ifndef WITH_NOHTTP
13799
 
#ifndef PALM_1
13800
 
static int
13801
 
http_post(struct soap *soap, const char *endpoint, const char *host, int port, const char *path, const char *action, size_t count)
13802
 
{ register const char *s;
13803
 
  register int err;
13804
 
  if (soap->status == SOAP_GET)
13805
 
    s = "GET";
13806
 
  else
13807
 
    s = "POST";
13808
 
#ifdef PALM
13809
 
  if (!endpoint || (soap_tag_cmp(endpoint, "http:*") && soap_tag_cmp(endpoint, "https:*") && strncmp(endpoint, "httpg:", 6)) && strncmp(endpoint, "_beam:", 6) && strncmp(endpoint, "_local:", 7) && strncmp(endpoint, "_btobex:", 8))
13810
 
#else
13811
 
  if (!endpoint || (soap_tag_cmp(endpoint, "http:*") && soap_tag_cmp(endpoint, "https:*") && strncmp(endpoint, "httpg:", 6)))
13812
 
#endif
13813
 
    return SOAP_OK;
13814
 
  if (strlen(endpoint) + strlen(soap->http_version) > sizeof(soap->tmpbuf) - 80)
13815
 
    return soap->error = SOAP_EOM;
13816
 
  if (soap->proxy_host && soap_tag_cmp(endpoint, "https:*"))
13817
 
    sprintf(soap->tmpbuf, "%s %s HTTP/%s", s, endpoint, soap->http_version);
13818
 
  else
13819
 
    sprintf(soap->tmpbuf, "%s /%s HTTP/%s", s, (*path == '/' ? path + 1 : path), soap->http_version);
13820
 
  if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL)))
13821
 
    return err;
13822
 
#ifdef WITH_OPENSSL
13823
 
  if ((soap->ssl && soap->port != 443) || (!soap->ssl && soap->port != 80))
13824
 
    sprintf(soap->tmpbuf, "%s:%d", host, port);
13825
 
  else
13826
 
    strcpy(soap->tmpbuf, host); 
13827
 
#else
13828
 
  if (port != 80)
13829
 
    sprintf(soap->tmpbuf, "%s:%d", host, port);
13830
 
  else
13831
 
    strcpy(soap->tmpbuf, host); 
13832
 
#endif
13833
 
  if ((err = soap->fposthdr(soap, "Host", soap->tmpbuf))
13834
 
   || (err = soap->fposthdr(soap, "User-Agent", "gSOAP/2.7"))
13835
 
   || (err = soap_puthttphdr(soap, SOAP_OK, count)))
13836
 
    return err;
13837
 
#ifdef WITH_ZLIB
13838
 
#ifdef WITH_GZIP
13839
 
  if ((err = soap->fposthdr(soap, "Accept-Encoding", "gzip, deflate")))
13840
 
#else
13841
 
  if ((err = soap->fposthdr(soap, "Accept-Encoding", "deflate")))
13842
 
#endif
13843
 
    return err;
13844
 
#endif
13845
 
#ifndef WITH_LEAN
13846
 
  if (soap->userid && soap->passwd && strlen(soap->userid) + strlen(soap->passwd) < 761)
13847
 
  { sprintf(soap->tmpbuf + 262, "%s:%s", soap->userid, soap->passwd);
13848
 
    strcpy(soap->tmpbuf, "Basic ");
13849
 
    soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, (int)strlen(soap->tmpbuf + 262));
13850
 
    if ((err = soap->fposthdr(soap, "Authorization", soap->tmpbuf)))
13851
 
      return err;
13852
 
  }
13853
 
  if (soap->proxy_userid && soap->proxy_passwd && strlen(soap->proxy_userid) + strlen(soap->proxy_passwd) < 761)
13854
 
  { sprintf(soap->tmpbuf + 262, "%s:%s", soap->proxy_userid, soap->proxy_passwd);
13855
 
    strcpy(soap->tmpbuf, "Basic ");
13856
 
    soap_s2base64(soap, (const unsigned char*)(soap->tmpbuf + 262), soap->tmpbuf + 6, (int)strlen(soap->tmpbuf + 262));
13857
 
    if ((err = soap->fposthdr(soap, "Proxy-Authorization", soap->tmpbuf)))
13858
 
      return err;
13859
 
  }
13860
 
#endif
13861
 
#ifdef WITH_COOKIES
13862
 
#ifdef WITH_OPENSSL
13863
 
  if (soap_putcookies(soap, host, path, soap->ssl != NULL))
13864
 
    return soap->error;
13865
 
#else
13866
 
  if (soap_putcookies(soap, host, path, 0))
13867
 
    return soap->error;
13868
 
#endif
13869
 
#endif
13870
 
  if (soap->status != SOAP_GET && (soap->version == 1 || (action && *action && strlen(action) < sizeof(soap->tmpbuf) - 2)))
13871
 
  { sprintf(soap->tmpbuf, "\"%s\"", action?action:"");
13872
 
    if ((err = soap->fposthdr(soap, "SOAPAction", soap->tmpbuf)))
13873
 
      return err;
13874
 
  }
13875
 
  return soap->fposthdr(soap, NULL, NULL);
13876
 
}
13877
 
#endif
13878
 
#endif
13879
 
 
13880
 
/******************************************************************************/
13881
 
#ifndef WITH_NOHTTP
13882
 
#ifndef PALM_1
13883
 
static int
13884
 
http_send_header(struct soap *soap, const char *s)
13885
 
{ register const char *t;
13886
 
  do
13887
 
  { t = strchr(s, '\n'); /* disallow \n in HTTP headers */
13888
 
    if (!t)
13889
 
      t = s + strlen(s);
13890
 
    if (soap_send_raw(soap, s, t - s))
13891
 
      return soap->error;
13892
 
    s = t + 1;
13893
 
  } while (*t);
13894
 
  return SOAP_OK;
13895
 
}
13896
 
#endif
13897
 
#endif
13898
 
 
13899
 
/******************************************************************************/
13900
 
#ifndef WITH_NOHTTP
13901
 
#ifndef PALM_1
13902
 
static int
13903
 
http_post_header(struct soap *soap, const char *key, const char *val)
13904
 
{ if (key)
13905
 
  { if (http_send_header(soap, key))
13906
 
      return soap->error;
13907
 
    if (val && (soap_send_raw(soap, ": ", 2) || http_send_header(soap, val)))
13908
 
      return soap->error;
13909
 
  }
13910
 
  return soap_send_raw(soap, "\r\n", 2);
13911
 
}
13912
 
#endif
13913
 
#endif
13914
 
 
13915
 
/******************************************************************************/
13916
 
#ifndef WITH_NOHTTP
13917
 
#ifndef PALM_1
13918
 
static int
13919
 
http_response(struct soap *soap, int status, size_t count)
13920
 
{ register int err;
13921
 
#ifdef WMW_RPM_IO
13922
 
  if (soap->rpmreqid)
13923
 
    httpOutputEnable(soap->rpmreqid);
13924
 
#endif
13925
 
  if (strlen(soap->http_version) > 4)
13926
 
    return soap->error = SOAP_EOM;
13927
 
  if (!status || status == SOAP_HTML || status == SOAP_FILE)
13928
 
  { const char *s;
13929
 
    if (count || ((soap->omode & SOAP_IO) == SOAP_IO_CHUNK))
13930
 
      s = "200 OK";
13931
 
    else
13932
 
      s = "202 ACCEPTED";
13933
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Status = %s\n", s));
13934
 
#ifdef WMW_RPM_IO
13935
 
    if (soap->rpmreqid || soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* RPM behaves as if standalone */
13936
 
#else
13937
 
    if (soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* standalone application */
13938
 
#endif
13939
 
    { sprintf(soap->tmpbuf, "HTTP/%s %s", soap->http_version, s);
13940
 
      if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL)))
13941
 
        return err;
13942
 
    }
13943
 
    else if ((err = soap->fposthdr(soap, "Status", s)))
13944
 
      return err;
13945
 
  }
13946
 
  else if (status >= 200 && status < 600)
13947
 
  { sprintf(soap->tmpbuf, "HTTP/%s %d %s", soap->http_version, status, http_error(soap, status));
13948
 
    if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL)))
13949
 
      return err;
13950
 
#ifndef WITH_LEAN 
13951
 
    if (status == 401)
13952
 
    { sprintf(soap->tmpbuf, "Basic realm=\"%s\"", (soap->authrealm ? strlen(soap->authrealm) : 18) < sizeof(soap->tmpbuf) - 14 ? soap->authrealm : "gSOAP Web Service");
13953
 
      if ((err = soap->fposthdr(soap, "WWW-Authenticate", soap->tmpbuf)))
13954
 
        return err;
13955
 
    }
13956
 
    else if ((status >= 301 && status <= 303) || status == 307)
13957
 
    { if ((err = soap->fposthdr(soap, "Location", soap->endpoint)))
13958
 
        return err;
13959
 
    }
13960
 
#endif
13961
 
  }
13962
 
  else
13963
 
  { const char *s = *soap_faultcode(soap);
13964
 
    if (soap->version == 2 && (!s || !strcmp(s, "SOAP-ENV:Sender")))
13965
 
      s = "400 Bad Request";
13966
 
    else
13967
 
      s = "500 Internal Server Error";
13968
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Error %s (status=%d)\n", s, status));
13969
 
#ifdef WMW_RPM_IO
13970
 
    if (soap->rpmreqid || soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* RPM behaves as if standalone */
13971
 
#else
13972
 
    if (soap_valid_socket(soap->master) || soap_valid_socket(soap->socket)) /* standalone application */
13973
 
#endif
13974
 
    { sprintf(soap->tmpbuf, "HTTP/%s %s", soap->http_version, s);
13975
 
      if ((err = soap->fposthdr(soap, soap->tmpbuf, NULL)))
13976
 
        return err;
13977
 
    }
13978
 
    else if ((err = soap->fposthdr(soap, "Status", s))) /* CGI */
13979
 
      return err;
13980
 
  }
13981
 
  if ((err = soap->fposthdr(soap, "Server", "gSOAP/2.7"))
13982
 
   || (err = soap_puthttphdr(soap, status, count)))
13983
 
    return err;
13984
 
#ifdef WITH_COOKIES
13985
 
  if (soap_putsetcookies(soap))
13986
 
    return soap->error;
13987
 
#endif
13988
 
  return soap->fposthdr(soap, NULL, NULL);
13989
 
}
13990
 
#endif
13991
 
#endif
13992
 
 
13993
 
/******************************************************************************/
13994
 
#ifndef PALM_1
13995
 
SOAP_FMAC1
13996
 
int
13997
 
SOAP_FMAC2
13998
 
soap_response(struct soap *soap, int status)
13999
 
{ register size_t count;
14000
 
  if (!(soap->omode & (SOAP_ENC_XML | SOAP_IO_STORE /* this tests for chunking too */))
14001
 
   && (status == SOAP_HTML || status == SOAP_FILE))
14002
 
  { soap->omode &= ~SOAP_IO;
14003
 
    soap->omode |= SOAP_IO_STORE;
14004
 
  }
14005
 
  soap->status = status;
14006
 
  count = soap_count_attachments(soap);
14007
 
  if (soap_begin_send(soap))
14008
 
    return soap->error;
14009
 
#ifndef WITH_NOHTTP
14010
 
  if ((soap->mode & SOAP_IO) != SOAP_IO_STORE && !(soap->mode & SOAP_ENC_XML))
14011
 
  { register int n = soap->mode;
14012
 
    soap->mode &= ~(SOAP_IO | SOAP_ENC_ZLIB);
14013
 
    if ((n & SOAP_IO) != SOAP_IO_FLUSH)
14014
 
      soap->mode |= SOAP_IO_BUFFER;
14015
 
    if ((soap->error = soap->fresponse(soap, status, count)))
14016
 
      return soap->error;
14017
 
#ifndef WITH_LEANER
14018
 
    if ((n & SOAP_IO) == SOAP_IO_CHUNK)
14019
 
    { if (soap_flush(soap))
14020
 
        return soap->error;
14021
 
    }
14022
 
#endif
14023
 
    soap->mode = n;
14024
 
  }
14025
 
#endif
14026
 
  return SOAP_OK;
14027
 
}
14028
 
#endif
14029
 
 
14030
 
/******************************************************************************/
14031
 
#ifndef WITH_LEAN
14032
 
static const char*
14033
 
soap_set_validation_fault(struct soap *soap, const char *s, const char *t)
14034
 
{ if (*soap->tag)
14035
 
    sprintf(soap->msgbuf, "Validation constraint violation: %s%s in element <%s>", s, t?t:SOAP_STR_EOS, soap->tag);
14036
 
  else
14037
 
    sprintf(soap->msgbuf, "Validation constraint violation: %s%s", s, t?t:SOAP_STR_EOS);
14038
 
  return soap->msgbuf;
14039
 
}
14040
 
#endif
14041
 
 
14042
 
/******************************************************************************/
14043
 
#ifndef PALM_1
14044
 
SOAP_FMAC1
14045
 
void
14046
 
SOAP_FMAC2
14047
 
soap_set_fault(struct soap *soap)
14048
 
{ const char **c = soap_faultcode(soap);
14049
 
  const char **s = soap_faultstring(soap);
14050
 
  if (soap->fseterror)
14051
 
    soap->fseterror(soap, c, s);
14052
 
  if (!*c)
14053
 
  { if (soap->version == 2)
14054
 
      *c = "SOAP-ENV:Sender";
14055
 
    else
14056
 
      *c = "SOAP-ENV:Client";
14057
 
  }
14058
 
  if (*s)
14059
 
    return;
14060
 
  switch (soap->error)
14061
 
  {
14062
 
#ifndef WITH_LEAN
14063
 
    case SOAP_CLI_FAULT:
14064
 
      *s = "Client fault";
14065
 
      break;
14066
 
    case SOAP_SVR_FAULT:
14067
 
      *s = "Server fault";
14068
 
      break;
14069
 
    case SOAP_TAG_MISMATCH:
14070
 
      *s = soap_set_validation_fault(soap, "tag name or namespace mismatch", NULL);
14071
 
      break;
14072
 
    case SOAP_TYPE:
14073
 
      *s = soap_set_validation_fault(soap, "data type mismatch ", soap->type);
14074
 
      break;
14075
 
    case SOAP_SYNTAX_ERROR:
14076
 
      *s = "Well-formedness violation";
14077
 
      break;
14078
 
    case SOAP_NO_TAG:
14079
 
      *s = "No XML element tag";
14080
 
      break;
14081
 
    case SOAP_MUSTUNDERSTAND:
14082
 
      *c = "SOAP-ENV:MustUnderstand";
14083
 
      sprintf(soap->msgbuf, "The data in element '%s' must be understood but cannot be handled", soap->tag);
14084
 
      *s = soap->msgbuf;
14085
 
      break;
14086
 
    case SOAP_VERSIONMISMATCH:
14087
 
      *c = "SOAP-ENV:VersionMismatch";
14088
 
      *s = "Invalid SOAP message or SOAP version mismatch";
14089
 
      break;
14090
 
    case SOAP_DATAENCODINGUNKNOWN:
14091
 
      *c = "SOAP-ENV:DataEncodingUnknown";
14092
 
      *s = "Unsupported SOAP data encoding";
14093
 
      break;
14094
 
    case SOAP_NAMESPACE:
14095
 
      *s = soap_set_validation_fault(soap, "namespace error", NULL);
14096
 
      break;
14097
 
    case SOAP_USER_ERROR:
14098
 
      *s = "User error";
14099
 
      break;
14100
 
    case SOAP_FATAL_ERROR:
14101
 
      *s = "Fatal error";
14102
 
      break;
14103
 
    case SOAP_NO_METHOD:
14104
 
      sprintf(soap->msgbuf, "Method '%s' not implemented: method name or namespace not recognized", soap->tag);
14105
 
      *s = soap->msgbuf;
14106
 
      break;
14107
 
    case SOAP_NO_DATA:
14108
 
      *s = "Data required for operation";
14109
 
      break;
14110
 
    case SOAP_GET_METHOD:
14111
 
      *s = "HTTP GET method not implemented";
14112
 
      break;
14113
 
    case SOAP_EOM:
14114
 
      *s = "Out of memory";
14115
 
      break;
14116
 
    case SOAP_MOE:
14117
 
      *s = "Memory overflow or memory corruption error";
14118
 
      break;
14119
 
    case SOAP_HDR:
14120
 
      *s = "Header line too long";
14121
 
      break;
14122
 
    case SOAP_IOB:
14123
 
      *s = "Array index out of bounds";
14124
 
      break;
14125
 
    case SOAP_NULL:
14126
 
      *s = soap_set_validation_fault(soap, "nil not allowed", NULL);
14127
 
      break;
14128
 
    case SOAP_DUPLICATE_ID:
14129
 
      *s = soap_set_validation_fault(soap, "multiple definitions of id ", soap->id);
14130
 
      if (soap->version == 2)
14131
 
        *soap_faultsubcode(soap) = "SOAP-ENC:DuplicateID";
14132
 
      break;
14133
 
    case SOAP_MISSING_ID:
14134
 
      *s = soap_set_validation_fault(soap, "missing id for ref ", soap->id);
14135
 
      if (soap->version == 2)
14136
 
        *soap_faultsubcode(soap) = "SOAP-ENC:MissingID";
14137
 
      break;
14138
 
    case SOAP_HREF:
14139
 
      *s = soap_set_validation_fault(soap, "incompatible object type ref/id pair ", soap->id);
14140
 
      break;
14141
 
    case SOAP_FAULT:
14142
 
      break;
14143
 
#ifndef WITH_NOIO
14144
 
    case SOAP_UDP_ERROR:
14145
 
      *s = "Message too large for UDP packet";
14146
 
      break;
14147
 
    case SOAP_TCP_ERROR:
14148
 
      *s = tcp_error(soap);
14149
 
      break;
14150
 
#endif
14151
 
    case SOAP_HTTP_ERROR:
14152
 
      *s = "An HTTP processing error occurred";
14153
 
      break;
14154
 
    case SOAP_SSL_ERROR:
14155
 
#ifdef WITH_OPENSSL
14156
 
      *s = "SSL error";
14157
 
#else
14158
 
      *s = "OpenSSL not installed: recompile with -DWITH_OPENSSL";
14159
 
#endif
14160
 
      break;
14161
 
    case SOAP_PLUGIN_ERROR:
14162
 
      *s = "Plugin registry error";
14163
 
      break;
14164
 
    case SOAP_DIME_ERROR:
14165
 
      *s = "DIME format error";
14166
 
      break;
14167
 
    case SOAP_DIME_HREF:
14168
 
      *s = "DIME href to missing attachment";
14169
 
      break;
14170
 
    case SOAP_DIME_MISMATCH:
14171
 
      *s = "DIME version/transmission error";
14172
 
      break;
14173
 
    case SOAP_DIME_END:
14174
 
      *s = "End of DIME error";
14175
 
      break;
14176
 
    case SOAP_MIME_ERROR:
14177
 
      *s = "MIME format error";
14178
 
      break;
14179
 
    case SOAP_MIME_HREF:
14180
 
      *s = "MIME href to missing attachment";
14181
 
      break;
14182
 
    case SOAP_MIME_END:
14183
 
      *s = "End of MIME error";
14184
 
      break;
14185
 
    case SOAP_ZLIB_ERROR:
14186
 
#ifdef WITH_ZLIB
14187
 
      sprintf(soap->msgbuf, "Zlib/gzip error: '%s'", soap->d_stream.msg?soap->d_stream.msg:"");
14188
 
      *s = soap->msgbuf;
14189
 
#else
14190
 
      *s = "Zlib/gzip not installed for (de)compression: recompile with -DWITH_GZIP";
14191
 
#endif
14192
 
      break;
14193
 
    case SOAP_REQUIRED:
14194
 
      *s = soap_set_validation_fault(soap, "missing required attribute", NULL);
14195
 
      break;
14196
 
    case SOAP_PROHIBITED:
14197
 
      *s = soap_set_validation_fault(soap, "prohibited attribute present", NULL);
14198
 
      break;
14199
 
    case SOAP_OCCURS:
14200
 
      *s = soap_set_validation_fault(soap, "occurrence violation", NULL);
14201
 
      break;
14202
 
    case SOAP_LENGTH:
14203
 
      *s = soap_set_validation_fault(soap, "content length violation", NULL);
14204
 
      break;
14205
 
    case SOAP_FD_EXCEEDED:
14206
 
      *s = "Maximum number of open connections was reached";
14207
 
      break;
14208
 
    case SOAP_STOP:
14209
 
      *s = "Stopped: no response sent";
14210
 
      break;
14211
 
#endif
14212
 
    case SOAP_EOF:
14213
 
#ifndef WITH_NOIO
14214
 
      strcpy(soap->msgbuf, soap_strerror(soap));
14215
 
#ifndef WITH_LEAN
14216
 
      if (strlen(soap->msgbuf) + 25 < sizeof(soap->msgbuf))
14217
 
      { memmove(soap->msgbuf + 25, soap->msgbuf, strlen(soap->msgbuf) + 1);
14218
 
        memcpy(soap->msgbuf, "End of file or no input: ", 25);
14219
 
      }
14220
 
#endif
14221
 
      *s = soap->msgbuf;
14222
 
      break;
14223
 
#else
14224
 
      *s = "End of file or no input";
14225
 
      break;
14226
 
#endif
14227
 
    default:
14228
 
#ifndef WITH_NOHTTP
14229
 
#ifndef WITH_LEAN
14230
 
      if (soap->error > 200 && soap->error < 600)
14231
 
      { sprintf(soap->msgbuf, "HTTP Error: %d %s", soap->error, http_error(soap, soap->error));
14232
 
        *s = soap->msgbuf;
14233
 
      }
14234
 
      else
14235
 
#endif
14236
 
#endif
14237
 
      { sprintf(soap->msgbuf, "Error %d", soap->error);
14238
 
        *s = soap->msgbuf;
14239
 
      }
14240
 
    }
14241
 
}
14242
 
#endif
14243
 
 
14244
 
/******************************************************************************/
14245
 
#ifndef PALM_1
14246
 
SOAP_FMAC1
14247
 
int
14248
 
SOAP_FMAC2
14249
 
soap_send_fault(struct soap *soap)
14250
 
{ register int status = soap->error;
14251
 
  int r = 1;
14252
 
  if (status == SOAP_STOP)
14253
 
    return status;
14254
 
  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Sending back fault struct for error code %d\n", soap->error));
14255
 
  soap->keep_alive = 0; /* to terminate connection */
14256
 
  soap_set_fault(soap);
14257
 
#ifndef WITH_NOIO
14258
 
#ifndef WITH_LEAN
14259
 
  if (soap_valid_socket(soap->socket))
14260
 
  { struct timeval timeout;
14261
 
    fd_set rfd, sfd;
14262
 
    timeout.tv_sec = 0;
14263
 
    timeout.tv_usec = 0;
14264
 
    FD_ZERO(&rfd);
14265
 
    FD_ZERO(&sfd);
14266
 
    FD_SET(soap->socket, &rfd);
14267
 
    FD_SET(soap->socket, &sfd);
14268
 
    r = select((int)soap->socket + 1, &rfd, &sfd, NULL, &timeout);
14269
 
    if (r > 0)
14270
 
    { if (!FD_ISSET(soap->socket, &sfd)
14271
 
       || (FD_ISSET(soap->socket, &rfd)
14272
 
        && recv(soap->socket, soap->tmpbuf, 1, MSG_PEEK) < 0))
14273
 
        r = 0;
14274
 
    }
14275
 
  }
14276
 
#endif
14277
 
#endif
14278
 
  if ((status != SOAP_EOF || (!soap->recv_timeout && !soap->send_timeout)) && r > 0)
14279
 
  { soap->error = SOAP_OK;
14280
 
    soap_serializeheader(soap);
14281
 
    soap_serializefault(soap);
14282
 
    soap_begin_count(soap);
14283
 
    if (soap->mode & SOAP_IO_LENGTH)
14284
 
    { soap_envelope_begin_out(soap);
14285
 
      soap_putheader(soap);
14286
 
      soap_body_begin_out(soap);
14287
 
      soap_putfault(soap);
14288
 
      soap_body_end_out(soap);
14289
 
      soap_envelope_end_out(soap);
14290
 
    }
14291
 
    soap_end_count(soap);
14292
 
    if (soap_response(soap, status)
14293
 
     || soap_envelope_begin_out(soap)
14294
 
     || soap_putheader(soap)
14295
 
     || soap_body_begin_out(soap)
14296
 
     || soap_putfault(soap)
14297
 
     || soap_body_end_out(soap)
14298
 
     || soap_envelope_end_out(soap))
14299
 
      return soap_closesock(soap);
14300
 
    soap_end_send(soap);
14301
 
  }
14302
 
  soap->error = status;
14303
 
  return soap_closesock(soap);
14304
 
}
14305
 
#endif
14306
 
 
14307
 
/******************************************************************************/
14308
 
#ifndef PALM_1
14309
 
SOAP_FMAC1
14310
 
int
14311
 
SOAP_FMAC2
14312
 
soap_recv_fault(struct soap *soap)
14313
 
{ register int status = soap->error;
14314
 
  DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Receiving SOAP Fault\n"));
14315
 
  soap->error = SOAP_OK;
14316
 
  if (soap_getfault(soap))
14317
 
  { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Error: soap_get_soapfault() failed. Is this a SOAP message at all?\n"));
14318
 
    *soap_faultcode(soap) = (soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client");
14319
 
    soap->error = status;
14320
 
    soap_set_fault(soap);
14321
 
  }
14322
 
  else
14323
 
  { register const char *s = *soap_faultcode(soap);
14324
 
    if (!soap_match_tag(soap, s, "SOAP-ENV:Server") || !soap_match_tag(soap, s, "SOAP-ENV:Receiver"))
14325
 
      status = SOAP_SVR_FAULT; 
14326
 
    else if (!soap_match_tag(soap, s, "SOAP-ENV:Client") || !soap_match_tag(soap, s, "SOAP-ENV:Sender"))
14327
 
      status = SOAP_CLI_FAULT;
14328
 
    else if (!soap_match_tag(soap, s, "SOAP-ENV:MustUnderstand"))
14329
 
      status = SOAP_MUSTUNDERSTAND;
14330
 
    else if (!soap_match_tag(soap, s, "SOAP-ENV:VersionMismatch"))
14331
 
      status = SOAP_VERSIONMISMATCH;
14332
 
    else
14333
 
    { DBGLOG(TEST,SOAP_MESSAGE(fdebug, "Fault code %s\n", s));
14334
 
      status = SOAP_FAULT;
14335
 
    }
14336
 
    if (soap_body_end_in(soap)
14337
 
     || soap_envelope_end_in(soap)
14338
 
     || soap_end_recv(soap))
14339
 
      return soap_closesock(soap);
14340
 
    soap->error = status;
14341
 
  }
14342
 
  return soap_closesock(soap);
14343
 
}
14344
 
#endif
14345
 
 
14346
 
/******************************************************************************/
14347
 
#ifndef WITH_NOHTTP
14348
 
#ifndef PALM_1
14349
 
SOAP_FMAC1
14350
 
int
14351
 
SOAP_FMAC2
14352
 
soap_send_empty_response(struct soap *soap, int status)
14353
 
{ register soap_mode m = soap->omode;
14354
 
  soap->count = 0;
14355
 
  if ((m & SOAP_IO) == SOAP_IO_CHUNK)
14356
 
  { soap->omode &= ~SOAP_IO_CHUNK;
14357
 
    soap->omode |= SOAP_IO_BUFFER;
14358
 
  }
14359
 
  if (soap_response(soap, status) || soap_end_send(soap))
14360
 
  { soap->omode = m;
14361
 
    return soap_closesock(soap);
14362
 
  }
14363
 
  soap->omode = m;
14364
 
  return SOAP_OK;
14365
 
}
14366
 
#endif
14367
 
#endif
14368
 
 
14369
 
/******************************************************************************/
14370
 
#ifndef WITH_NOHTTP
14371
 
#ifndef PALM_1
14372
 
SOAP_FMAC1
14373
 
int
14374
 
SOAP_FMAC2
14375
 
soap_recv_empty_response(struct soap *soap)
14376
 
{ if (soap_begin_recv(soap) || soap_end_recv(soap))
14377
 
  { if (soap->error != 202)
14378
 
      return soap_closesock(soap);
14379
 
    soap->error = SOAP_OK;
14380
 
  }
14381
 
  return SOAP_OK;
14382
 
}
14383
 
#endif
14384
 
#endif
14385
 
 
14386
 
/******************************************************************************/
14387
 
#ifndef WITH_NOIO
14388
 
#ifndef PALM_1
14389
 
static const char*
14390
 
soap_strerror(struct soap *soap)
14391
 
{ register int err = soap->errnum;
14392
 
  if (err)
14393
 
  {
14394
 
#ifndef WIN32
14395
 
    return strerror(err);
14396
 
#else
14397
 
#ifndef UNDER_CE
14398
 
    DWORD len;
14399
 
    *soap->msgbuf = '\0';
14400
 
    len = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)soap->msgbuf, (DWORD)sizeof(soap->msgbuf), NULL);
14401
 
#else
14402
 
    DWORD i, len;
14403
 
    *soap->msgbuf = '\0';
14404
 
    len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, 0, (LPTSTR)soap->msgbuf, (DWORD)(sizeof(soap->msgbuf)/sizeof(TCHAR)), NULL);
14405
 
    for (i = 0; i <= len; i++)
14406
 
    { if (((TCHAR*)soap->msgbuf)[i] < 0x80)
14407
 
        soap->msgbuf[i] = (char)((TCHAR*)soap->msgbuf)[i];
14408
 
      else
14409
 
        soap->msgbuf[i] = '?';
14410
 
    }
14411
 
#endif
14412
 
    return soap->msgbuf;
14413
 
#endif
14414
 
  }
14415
 
  return "Operation interrupted or timed out";
14416
 
}
14417
 
#endif
14418
 
#endif 
14419
 
 
14420
 
/******************************************************************************/
14421
 
#ifndef PALM_2
14422
 
static int
14423
 
soap_set_error(struct soap *soap, const char *faultcode, const char *faultsubcode, const char *faultstring, const char *faultdetail, int soaperror)
14424
 
{ *soap_faultcode(soap) = faultcode;
14425
 
  if (faultsubcode)
14426
 
    *soap_faultsubcode(soap) = faultsubcode;
14427
 
  *soap_faultstring(soap) = faultstring;
14428
 
  if (faultdetail && *faultdetail)
14429
 
  { register const char **s = soap_faultdetail(soap);
14430
 
    if (s)
14431
 
      *s = faultdetail;
14432
 
  }
14433
 
  return soap->error = soaperror;
14434
 
}
14435
 
#endif
14436
 
 
14437
 
/******************************************************************************/
14438
 
#ifndef PALM_2
14439
 
SOAP_FMAC1
14440
 
int
14441
 
SOAP_FMAC2
14442
 
soap_set_sender_error(struct soap *soap, const char *faultstring, const char *faultdetail, int soaperror)
14443
 
{ return soap_set_error(soap, soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client", NULL, faultstring, faultdetail, soaperror);
14444
 
}
14445
 
#endif
14446
 
 
14447
 
/******************************************************************************/
14448
 
#ifndef PALM_2
14449
 
SOAP_FMAC1
14450
 
int
14451
 
SOAP_FMAC2
14452
 
soap_set_receiver_error(struct soap *soap, const char *faultstring, const char *faultdetail, int soaperror)
14453
 
{ return soap_set_error(soap, soap->version == 2 ? "SOAP-ENV:Receiver" : "SOAP-ENV:Server", NULL, faultstring, faultdetail, soaperror);
14454
 
}
14455
 
#endif
14456
 
 
14457
 
/******************************************************************************/
14458
 
#ifndef PALM_2
14459
 
static int
14460
 
soap_copy_fault(struct soap *soap, const char *faultcode, const char *faultsubcode, const char *faultstring, const char *faultdetail)
14461
 
{ char *r = NULL, *s = NULL, *t = NULL;
14462
 
  if (faultsubcode)
14463
 
    r = soap_strdup(soap, faultsubcode);
14464
 
  if (faultstring)
14465
 
    s = soap_strdup(soap, faultstring);
14466
 
  if (faultdetail)
14467
 
    t = soap_strdup(soap, faultdetail);
14468
 
  return soap_set_error(soap, faultcode, r, s, t, SOAP_FAULT);
14469
 
}
14470
 
#endif
14471
 
 
14472
 
/******************************************************************************/
14473
 
#ifndef PALM_2
14474
 
SOAP_FMAC1
14475
 
int
14476
 
SOAP_FMAC2
14477
 
soap_sender_fault(struct soap *soap, const char *faultstring, const char *faultdetail)
14478
 
{ return soap_sender_fault_subcode(soap, NULL, faultstring, faultdetail);
14479
 
}
14480
 
#endif
14481
 
 
14482
 
/******************************************************************************/
14483
 
#ifndef PALM_2
14484
 
SOAP_FMAC1
14485
 
int
14486
 
SOAP_FMAC2
14487
 
soap_sender_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail)
14488
 
{ return soap_copy_fault(soap, soap->version == 2 ? "SOAP-ENV:Sender" : "SOAP-ENV:Client", faultsubcode, faultstring, faultdetail);
14489
 
}
14490
 
#endif
14491
 
 
14492
 
/******************************************************************************/
14493
 
#ifndef PALM_2
14494
 
SOAP_FMAC1
14495
 
int
14496
 
SOAP_FMAC2
14497
 
soap_receiver_fault(struct soap *soap, const char *faultstring, const char *faultdetail)
14498
 
{ return soap_receiver_fault_subcode(soap, NULL, faultstring, faultdetail);
14499
 
}
14500
 
#endif
14501
 
 
14502
 
/******************************************************************************/
14503
 
#ifndef PALM_2
14504
 
SOAP_FMAC1
14505
 
int
14506
 
SOAP_FMAC2
14507
 
soap_receiver_fault_subcode(struct soap *soap, const char *faultsubcode, const char *faultstring, const char *faultdetail)
14508
 
{ return soap_copy_fault(soap, soap->version == 2 ? "SOAP-ENV:Receiver" : "SOAP-ENV:Server", faultsubcode, faultstring, faultdetail);
14509
 
}
14510
 
#endif
14511
 
 
14512
 
/******************************************************************************/
14513
 
#ifndef PALM_2
14514
 
#ifndef WITH_NOSTDLIB
14515
 
SOAP_FMAC1
14516
 
void
14517
 
SOAP_FMAC2
14518
 
soap_print_fault(struct soap *soap, FILE *fd)
14519
 
{ if (soap_check_state(soap))
14520
 
    fprintf(fd, "Error: soap struct not initialized\n");
14521
 
  else if (soap->error)
14522
 
  { const char *c, *v = NULL, *s, **d;
14523
 
    d = soap_faultcode(soap);
14524
 
    if (!*d)
14525
 
      soap_set_fault(soap);
14526
 
    c = *d;
14527
 
    if (soap->version == 2)
14528
 
      v = *soap_faultsubcode(soap);
14529
 
    s = *soap_faultstring(soap);
14530
 
    d = soap_faultdetail(soap);
14531
 
    fprintf(fd, "%s%d fault: %s [%s]\n\"%s\"\nDetail: %s\n", soap->version ? "SOAP 1." : "Error ", soap->version ? (int)soap->version : soap->error, c, v ? v : "no subcode", s ? s : "[no reason]", d && *d ? *d : "[no detail]");
14532
 
  }
14533
 
}
14534
 
#endif
14535
 
#endif
14536
 
 
14537
 
/******************************************************************************/
14538
 
#ifndef WITH_LEAN
14539
 
#ifndef WITH_NOSTDLIB
14540
 
SOAP_FMAC1
14541
 
char*
14542
 
SOAP_FMAC2
14543
 
soap_sprint_fault(struct soap *soap, char *buf, size_t len)
14544
 
{ if (soap_check_state(soap))
14545
 
    strncpy(buf, "Error: soap struct not initialized", len);
14546
 
  else if (soap->error)
14547
 
  { const char *c, *v = NULL, *s, **d;
14548
 
    d = soap_faultcode(soap);
14549
 
    if (!*d)
14550
 
      soap_set_fault(soap);
14551
 
    c = *d;
14552
 
    if (soap->version == 2)
14553
 
      v = *soap_faultsubcode(soap);
14554
 
    s = *soap_faultstring(soap);
14555
 
    d = soap_faultdetail(soap);
14556
 
#ifdef WIN32
14557
 
    _snprintf
14558
 
#else
14559
 
    snprintf
14560
 
#endif
14561
 
      (buf, len, "%s%d fault: %s [%s]\n\"%s\"\nDetail: %s\n", soap->version ? "SOAP 1." : "Error ", soap->version ? (int)soap->version : soap->error, c, v ? v : "no subcode", s ? s : "[no reason]", d && *d ? *d : "[no detail]");
14562
 
  }
14563
 
  return buf;
14564
 
}
14565
 
#endif
14566
 
#endif
14567
 
 
14568
 
/******************************************************************************/
14569
 
#ifndef PALM_1
14570
 
#ifndef WITH_NOSTDLIB
14571
 
SOAP_FMAC1
14572
 
void
14573
 
SOAP_FMAC2
14574
 
soap_print_fault_location(struct soap *soap, FILE *fd)
14575
 
14576
 
#ifndef WITH_LEAN
14577
 
  int i, j, c1, c2;
14578
 
  if (soap->error && soap->bufidx <= soap->buflen && soap->buflen > 0 && soap->buflen <= SOAP_BUFLEN)
14579
 
  { i = (int)soap->bufidx - 1;
14580
 
    if (i <= 0)
14581
 
      i = 0;
14582
 
    c1 = soap->buf[i];
14583
 
    soap->buf[i] = '\0';
14584
 
    if ((int)soap->buflen >= i + 1024)
14585
 
      j = i + 1023;
14586
 
    else
14587
 
      j = (int)soap->buflen - 1;
14588
 
    c2 = soap->buf[j];
14589
 
    soap->buf[j] = '\0';
14590
 
    fprintf(fd, "%s%c\n<!-- ** HERE ** -->\n", soap->buf, c1);
14591
 
    if (soap->bufidx < soap->buflen)
14592
 
      fprintf(fd, "%s\n", soap->buf + soap->bufidx);
14593
 
    soap->buf[i] = c1;
14594
 
    soap->buf[j] = c2;
14595
 
  }
14596
 
#endif
14597
 
}
14598
 
#endif
14599
 
#endif
14600
 
 
14601
 
/******************************************************************************/
14602
 
#ifndef PALM_1
14603
 
SOAP_FMAC1
14604
 
int
14605
 
SOAP_FMAC2
14606
 
soap_register_plugin_arg(struct soap *soap, int (*fcreate)(struct soap*, struct soap_plugin*, void*), void *arg)
14607
 
{ register struct soap_plugin *p;
14608
 
  register int r;
14609
 
  if (!(p = (struct soap_plugin*)SOAP_MALLOC(soap, sizeof(struct soap_plugin))))
14610
 
    return soap->error = SOAP_EOM;
14611
 
  p->id = NULL;
14612
 
  p->data = NULL;
14613
 
  p->fcopy = NULL;
14614
 
  p->fdelete = NULL;
14615
 
  r = fcreate(soap, p, arg);
14616
 
  if (!r && p->fdelete)
14617
 
  { p->next = soap->plugins;
14618
 
    soap->plugins = p;
14619
 
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Registered '%s' plugin\n", p->id));
14620
 
    return SOAP_OK;
14621
 
  }
14622
 
  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not register plugin '%s': plugin returned error %d (or fdelete callback not set)\n", p->id?p->id:"?", r));
14623
 
  SOAP_FREE(soap, p);
14624
 
  return r;
14625
 
}
14626
 
#endif
14627
 
 
14628
 
/******************************************************************************/
14629
 
#ifndef PALM_1
14630
 
static void *
14631
 
fplugin(struct soap *soap, const char *id)
14632
 
{ register struct soap_plugin *p;
14633
 
  for (p = soap->plugins; p; p = p->next)
14634
 
    if (p->id == id || !strcmp(p->id, id))
14635
 
      return p->data;
14636
 
  return NULL;
14637
 
}
14638
 
#endif
14639
 
 
14640
 
/******************************************************************************/
14641
 
#ifndef PALM_2
14642
 
SOAP_FMAC1
14643
 
void *
14644
 
SOAP_FMAC2
14645
 
soap_lookup_plugin(struct soap *soap, const char *id)
14646
 
{ return soap->fplugin(soap, id);
14647
 
}
14648
 
#endif
14649
 
 
14650
 
/******************************************************************************/
14651
 
#ifdef __cplusplus
14652
 
}
14653
 
#endif
14654
 
 
14655
 
/******************************************************************************\
14656
 
 *
14657
 
 *      C++ soap struct methods
14658
 
 *
14659
 
\******************************************************************************/
14660
 
 
14661
 
#ifdef __cplusplus
14662
 
#ifndef WITH_LEAN
14663
 
soap::soap()
14664
 
{ soap_init(this);
14665
 
}
14666
 
#endif
14667
 
#endif
14668
 
 
14669
 
/******************************************************************************/
14670
 
#ifdef __cplusplus
14671
 
#ifndef WITH_LEAN
14672
 
soap::soap(soap_mode m)
14673
 
{ soap_init1(this, m);
14674
 
}
14675
 
#endif
14676
 
#endif
14677
 
 
14678
 
/******************************************************************************/
14679
 
#ifdef __cplusplus
14680
 
#ifndef WITH_LEAN
14681
 
soap::soap(soap_mode im, soap_mode om)
14682
 
{ soap_init2(this, im, om);
14683
 
}
14684
 
#endif
14685
 
#endif
14686
 
 
14687
 
/******************************************************************************/
14688
 
#ifdef __cplusplus
14689
 
#ifndef WITH_LEAN
14690
 
soap::soap(struct soap& soap)
14691
 
{ soap_copy_context(this, &soap);
14692
 
}
14693
 
#endif
14694
 
#endif
14695
 
 
14696
 
/******************************************************************************/
14697
 
#ifdef __cplusplus
14698
 
#ifndef WITH_LEAN
14699
 
soap::~soap()
14700
 
{ soap_destroy(this);
14701
 
  soap_end(this);
14702
 
  soap_done(this);
14703
 
}
14704
 
#endif
14705
 
#endif
14706
 
 
14707
 
/******************************************************************************/