libcurl internal base64.h header file renamed to curl_base64.h
[platform/upstream/curl.git] / tests / server / getpart.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, 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
24 #include "setup.h"
25
26 #include "getpart.h"
27
28 #define _MPRINTF_REPLACE /* use our functions only */
29 #include <curl/mprintf.h>
30
31 /* just to please base64.h we create a fake struct */
32 struct SessionHandle {
33   int fake;
34 };
35
36 #include "curl_base64.h"
37
38 /* include memdebug.h last */
39 #include "memdebug.h"
40
41 #define EAT_SPACE(ptr) while( ptr && *ptr && ISSPACE(*ptr) ) ptr++
42 #define EAT_WORD(ptr) while( ptr && *ptr && !ISSPACE(*ptr) && \
43                             ('>' != *ptr)) ptr++
44
45 #ifdef DEBUG
46 #define show(x) printf x
47 #else
48 #define show(x)
49 #endif
50
51 curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc;
52 curl_free_callback Curl_cfree = (curl_free_callback)free;
53 curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
54 curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)strdup;
55 curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
56
57 static
58 char *appendstring(char *string, /* original string */
59                    char *buffer, /* to append */
60                    size_t *stringlen, /* length of string */
61                    size_t *stralloc,  /* allocated size */
62                    char base64) /* 1 if base64 encoded */
63 {
64   size_t len = strlen(buffer);
65   size_t needed_len = len + *stringlen + 1;
66   char *buf64=NULL;
67
68   if(base64) {
69     /* decode the given buffer first */
70     len = Curl_base64_decode(buffer, (unsigned char**)&buf64); /* updated len */
71     buffer = buf64;
72     needed_len = len + *stringlen + 1; /* recalculate */
73   }
74
75   if(needed_len >= *stralloc) {
76     char *newptr;
77     size_t newsize = needed_len*2; /* get twice the needed size */
78
79     newptr = realloc(string, newsize);
80     if(newptr) {
81       string = newptr;
82       *stralloc = newsize;
83     }
84     else {
85       if(buf64)
86         free(buf64);
87       return NULL;
88     }
89   }
90   /* memcpy to support binary blobs */
91   memcpy(&string[*stringlen], buffer, len);
92   *stringlen += len;
93   string[*stringlen]=0;
94
95   if(buf64)
96     free(buf64);
97
98   return string;
99 }
100
101 const char *spitout(FILE *stream,
102                     const char *main,
103                     const char *sub, size_t *size)
104 {
105   char buffer[8192]; /* big enough for anything */
106   char cmain[128]=""; /* current main section */
107   char csub[128]="";  /* current sub section */
108   char *ptr;
109   char *end;
110   char display = 0;
111
112   char *string;
113   size_t stringlen=0;
114   size_t stralloc=256;
115   char base64 = 0; /* set to 1 if true */
116
117   enum {
118     STATE_OUTSIDE,
119     STATE_OUTER,
120     STATE_INMAIN,
121     STATE_INSUB,
122     STATE_ILLEGAL
123   } state = STATE_OUTSIDE;
124
125   string = (char *)malloc(stralloc);
126   if(!string)
127     return NULL;
128
129   string[0] = 0; /* zero first byte in case of no data */
130
131   while(fgets(buffer, sizeof(buffer), stream)) {
132
133     ptr = buffer;
134
135     /* pass white spaces */
136     EAT_SPACE(ptr);
137
138     if('<' != *ptr) {
139       if(display) {
140         show(("=> %s", buffer));
141         string = appendstring(string, buffer, &stringlen, &stralloc, base64);
142         show(("* %s\n", buffer));
143       }
144       continue;
145     }
146
147     ptr++;
148     EAT_SPACE(ptr);
149
150     if('/' == *ptr) {
151       /* end of a section */
152       ptr++;
153       EAT_SPACE(ptr);
154
155       end = ptr;
156       EAT_WORD(end);
157       *end = 0;
158
159       if((state == STATE_INSUB) &&
160          !strcmp(csub, ptr)) {
161         /* this is the end of the currently read sub section */
162         state--;
163         csub[0]=0; /* no sub anymore */
164         display=0;
165       }
166       else if((state == STATE_INMAIN) &&
167               !strcmp(cmain, ptr)) {
168         /* this is the end of the currently read main section */
169         state--;
170         cmain[0]=0; /* no main anymore */
171         display=0;
172       }
173       else if(state == STATE_OUTER) {
174         /* this is the end of the outermost file section */
175         state--;
176       }
177     }
178     else if(!display) {
179       /* this is the beginning of a section */
180       end = ptr;
181       EAT_WORD(end);
182
183       *end = 0;
184       switch(state) {
185       case STATE_OUTSIDE:
186         /* Skip over the outermost element (<testcase>), but if it turns out
187            to be a comment, completely ignore it below */
188         strcpy(cmain, ptr);
189         state = STATE_OUTER;
190         break;
191       case STATE_OUTER:
192         strcpy(cmain, ptr);
193         state = STATE_INMAIN;
194         break;
195       case STATE_INMAIN:
196         strcpy(csub, ptr);
197         state = STATE_INSUB;
198         break;
199       default:
200         break;
201       }
202
203       if(!end[1] != '>') {
204         /* There might be attributes here. Check for those we know of and care
205            about. */
206         if(strstr(&end[1], "base64=")) {
207           /* rough and dirty, but "mostly" functional */
208           /* Treat all data as base64 encoded */
209           base64 = 1;
210         }
211       }
212     }
213     if(display) {
214       string = appendstring(string, buffer, &stringlen, &stralloc, base64);
215       show(("* %s\n", buffer));
216     }
217
218     if((STATE_INSUB == state) &&
219        !strcmp(cmain, main) &&
220        !strcmp(csub, sub)) {
221       show(("* (%d bytes) %s\n", stringlen, buffer));
222       display = 1; /* start displaying */
223     }
224     else if ((*cmain == '?') || (*cmain == '!') || (*csub == '!')) {
225         /* Ignore comments, DOCTYPEs and XML declarations */
226         show(("%d ignoring (%s/%s)\n", state, cmain, csub));
227         state--;
228     }
229     else {
230       show(("%d (%s/%s): %s\n", state, cmain, csub, buffer));
231       display = 0; /* no display */
232     }
233   }
234
235   *size = stringlen;
236   return string;
237 }
238