getpart.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 1998 - 2008, Daniel Stenberg, <[email protected]>, et al.
  9. *
  10. * This software is licensed as described in the file COPYING, which
  11. * you should have received as part of this distribution. The terms
  12. * are also available at http://curl.haxx.se/docs/copyright.html.
  13. *
  14. * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  15. * copies of the Software, and permit persons to whom the Software is
  16. * furnished to do so, under the terms of the COPYING file.
  17. *
  18. * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  19. * KIND, either express or implied.
  20. *
  21. * $Id$
  22. ***************************************************************************/
  23. #include "setup.h"
  24. #include "getpart.h"
  25. #define _MPRINTF_REPLACE /* use our functions only */
  26. #include <curl/mprintf.h>
  27. /* just to please base64.h we create a fake struct */
  28. struct SessionHandle {
  29. int fake;
  30. };
  31. #include "curl_base64.h"
  32. /* include memdebug.h last */
  33. #include "memdebug.h"
  34. #define EAT_SPACE(ptr) while( ptr && *ptr && ISSPACE(*ptr) ) ptr++
  35. #define EAT_WORD(ptr) while( ptr && *ptr && !ISSPACE(*ptr) && \
  36. ('>' != *ptr)) ptr++
  37. #ifdef DEBUG
  38. #define show(x) printf x
  39. #else
  40. #define show(x)
  41. #endif
  42. curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc;
  43. curl_free_callback Curl_cfree = (curl_free_callback)free;
  44. curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
  45. curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)strdup;
  46. curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
  47. static
  48. char *appendstring(char *string, /* original string */
  49. char *buffer, /* to append */
  50. size_t *stringlen, /* length of string */
  51. size_t *stralloc, /* allocated size */
  52. char base64) /* 1 if base64 encoded */
  53. {
  54. size_t len = strlen(buffer);
  55. size_t needed_len = len + *stringlen + 1;
  56. char *buf64=NULL;
  57. if(base64) {
  58. /* decode the given buffer first */
  59. len = Curl_base64_decode(buffer, (unsigned char**)&buf64); /* updated len */
  60. buffer = buf64;
  61. needed_len = len + *stringlen + 1; /* recalculate */
  62. }
  63. if(needed_len >= *stralloc) {
  64. char *newptr;
  65. size_t newsize = needed_len*2; /* get twice the needed size */
  66. newptr = realloc(string, newsize);
  67. if(newptr) {
  68. string = newptr;
  69. *stralloc = newsize;
  70. }
  71. else {
  72. if(buf64)
  73. free(buf64);
  74. return NULL;
  75. }
  76. }
  77. /* memcpy to support binary blobs */
  78. memcpy(&string[*stringlen], buffer, len);
  79. *stringlen += len;
  80. string[*stringlen]=0;
  81. if(buf64)
  82. free(buf64);
  83. return string;
  84. }
  85. const char *spitout(FILE *stream,
  86. const char *main,
  87. const char *sub, size_t *size)
  88. {
  89. char buffer[8192]; /* big enough for anything */
  90. char cmain[128]=""; /* current main section */
  91. char csub[128]=""; /* current sub section */
  92. char *ptr;
  93. char *end;
  94. char display = 0;
  95. char *string;
  96. size_t stringlen=0;
  97. size_t stralloc=256;
  98. char base64 = 0; /* set to 1 if true */
  99. enum {
  100. STATE_OUTSIDE,
  101. STATE_OUTER,
  102. STATE_INMAIN,
  103. STATE_INSUB,
  104. STATE_ILLEGAL
  105. } state = STATE_OUTSIDE;
  106. string = (char *)malloc(stralloc);
  107. if(!string)
  108. return NULL;
  109. string[0] = 0; /* zero first byte in case of no data */
  110. while(fgets(buffer, sizeof(buffer), stream)) {
  111. ptr = buffer;
  112. /* pass white spaces */
  113. EAT_SPACE(ptr);
  114. if('<' != *ptr) {
  115. if(display) {
  116. show(("=> %s", buffer));
  117. string = appendstring(string, buffer, &stringlen, &stralloc, base64);
  118. show(("* %s\n", buffer));
  119. }
  120. continue;
  121. }
  122. ptr++;
  123. EAT_SPACE(ptr);
  124. if('/' == *ptr) {
  125. /* end of a section */
  126. ptr++;
  127. EAT_SPACE(ptr);
  128. end = ptr;
  129. EAT_WORD(end);
  130. *end = 0;
  131. if((state == STATE_INSUB) &&
  132. !strcmp(csub, ptr)) {
  133. /* this is the end of the currently read sub section */
  134. state--;
  135. csub[0]=0; /* no sub anymore */
  136. display=0;
  137. }
  138. else if((state == STATE_INMAIN) &&
  139. !strcmp(cmain, ptr)) {
  140. /* this is the end of the currently read main section */
  141. state--;
  142. cmain[0]=0; /* no main anymore */
  143. display=0;
  144. }
  145. else if(state == STATE_OUTER) {
  146. /* this is the end of the outermost file section */
  147. state--;
  148. }
  149. }
  150. else if(!display) {
  151. /* this is the beginning of a section */
  152. end = ptr;
  153. EAT_WORD(end);
  154. *end = 0;
  155. switch(state) {
  156. case STATE_OUTSIDE:
  157. /* Skip over the outermost element (<testcase>), but if it turns out
  158. to be a comment, completely ignore it below */
  159. strcpy(cmain, ptr);
  160. state = STATE_OUTER;
  161. break;
  162. case STATE_OUTER:
  163. strcpy(cmain, ptr);
  164. state = STATE_INMAIN;
  165. break;
  166. case STATE_INMAIN:
  167. strcpy(csub, ptr);
  168. state = STATE_INSUB;
  169. break;
  170. default:
  171. break;
  172. }
  173. if(!end[1] != '>') {
  174. /* There might be attributes here. Check for those we know of and care
  175. about. */
  176. if(strstr(&end[1], "base64=")) {
  177. /* rough and dirty, but "mostly" functional */
  178. /* Treat all data as base64 encoded */
  179. base64 = 1;
  180. }
  181. }
  182. }
  183. if(display) {
  184. string = appendstring(string, buffer, &stringlen, &stralloc, base64);
  185. show(("* %s\n", buffer));
  186. }
  187. if((STATE_INSUB == state) &&
  188. !strcmp(cmain, main) &&
  189. !strcmp(csub, sub)) {
  190. show(("* (%d bytes) %s\n", stringlen, buffer));
  191. display = 1; /* start displaying */
  192. }
  193. else if ((*cmain == '?') || (*cmain == '!') || (*csub == '!')) {
  194. /* Ignore comments, DOCTYPEs and XML declarations */
  195. show(("%d ignoring (%s/%s)\n", state, cmain, csub));
  196. state--;
  197. }
  198. else {
  199. show(("%d (%s/%s): %s\n", state, cmain, csub, buffer));
  200. display = 0; /* no display */
  201. }
  202. }
  203. *size = stringlen;
  204. return string;
  205. }