19bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/*************************************************************************** 29bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * _ _ ____ _ 39bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Project ___| | | | _ \| | 49bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * / __| | | | |_) | | 59bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * | (__| |_| | _ <| |___ 69bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * \___|\___/|_| \_\_____| 79bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 8e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al. 99bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * This software is licensed as described in the file COPYING, which 119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * you should have received as part of this distribution. The terms 129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * are also available at http://curl.haxx.se/docs/copyright.html. 139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 149bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * You may opt to use, copy, modify, merge, publish, distribute and/or sell 159bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * copies of the Software, and permit persons to whom the Software is 169bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * furnished to do so, under the terms of the COPYING file. 179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 189bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 199bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * KIND, either express or implied. 209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 219bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ***************************************************************************/ 22e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "server_setup.h" 239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include "getpart.h" 259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#define ENABLE_CURLX_PRINTF 279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* make the curlx header define all printf() functions to use the curlx_* 289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels versions instead */ 299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include "curlx.h" /* from the private lib dir */ 309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 31e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* just to please curl_base64.h we create a fake struct */ 329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstruct SessionHandle { 339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int fake; 349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels}; 359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include "curl_base64.h" 379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include "curl_memory.h" 389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* include memdebug.h last */ 409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include "memdebug.h" 419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#define EAT_SPACE(p) while(*(p) && ISSPACE(*(p))) (p)++ 439bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#define EAT_WORD(p) while(*(p) && !ISSPACE(*(p)) && ('>' != *(p))) (p)++ 459bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#ifdef DEBUG_GETPART 479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#define show(x) printf x 489bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#else 49e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#define show(x) Curl_nop_stmt 509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#endif 519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#if defined(_MSC_VER) && defined(_DLL) 539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels# pragma warning(disable:4232) /* MSVC extension, dllimport identity */ 549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#endif 559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelscurl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc; 579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelscurl_free_callback Curl_cfree = (curl_free_callback)free; 589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelscurl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc; 599bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelscurl_strdup_callback Curl_cstrdup = (curl_strdup_callback)strdup; 609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelscurl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc; 61e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#if defined(WIN32) && defined(UNICODE) 62e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETcurl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup; 63e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif 649bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 659bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#if defined(_MSC_VER) && defined(_DLL) 669bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels# pragma warning(default:4232) /* MSVC extension, dllimport identity */ 679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#endif 689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 699bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* 709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * readline() 719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 729bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Reads a complete line from a file into a dynamically allocated buffer. 739bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 749bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Calling function may call this multiple times with same 'buffer' 759bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * and 'bufsize' pointers to avoid multiple buffer allocations. Buffer 769bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * will be reallocated and 'bufsize' increased until whole line fits in 779bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * buffer before returning it. 789bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 799bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Calling function is responsible to free allocated buffer. 809bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 819bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * This function may return: 829bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * GPE_OUT_OF_MEMORY 839bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * GPE_END_OF_FILE 849bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * GPE_OK 859bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels */ 869bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 879bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic int readline(char **buffer, size_t *bufsize, FILE *stream) 889bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 899bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels size_t offset = 0; 909bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels size_t length; 919bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char *newptr; 929bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 939bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(!*buffer) { 949bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *buffer = malloc(128); 959bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(!*buffer) 969bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return GPE_OUT_OF_MEMORY; 979bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *bufsize = 128; 989bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 999bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1009bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels for(;;) { 1019bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int bytestoread = curlx_uztosi(*bufsize - offset); 1029bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1039bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(!fgets(*buffer + offset, bytestoread, stream)) 1049bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return (offset != 0) ? GPE_OK : GPE_END_OF_FILE ; 1059bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1069bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels length = offset + strlen(*buffer + offset); 1079bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(*(*buffer + length - 1) == '\n') 1089bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels break; 1099bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels offset = length; 1109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(length < *bufsize - 1) 1119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels continue; 1129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels newptr = realloc(*buffer, *bufsize * 2); 1149bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(!newptr) 1159bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return GPE_OUT_OF_MEMORY; 1169bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *buffer = newptr; 1179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *bufsize *= 2; 1189bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 1199bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return GPE_OK; 1219bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 1229bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* 1249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * appenddata() 1259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 1269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * This appends data from a given source buffer to the end of the used part of 1279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * a destination buffer. Arguments relative to the destination buffer are, the 1289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * address of a pointer to the destination buffer 'dst_buf', the length of data 1299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * in destination buffer excluding potential null string termination 'dst_len', 1309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * the allocated size of destination buffer 'dst_alloc'. All three destination 1319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * buffer arguments may be modified by this function. Arguments relative to the 1329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * source buffer are, a pointer to the source buffer 'src_buf' and indication 1339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * whether the source buffer is base64 encoded or not 'src_b64'. 1349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 1359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * If the source buffer is indicated to be base64 encoded, this appends the 1369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * decoded data, binary or whatever, to the destination. The source buffer 1379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * may not hold binary data, only a null terminated string is valid content. 1389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 1399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Destination buffer will be enlarged and relocated as needed. 1409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 1419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Calling function is responsible to provide preallocated destination 1429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * buffer and also to deallocate it when no longer needed. 1439bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 1449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * This function may return: 1459bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * GPE_OUT_OF_MEMORY 1469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * GPE_OK 1479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels */ 1489bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1499bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstatic int appenddata(char **dst_buf, /* dest buffer */ 1509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels size_t *dst_len, /* dest buffer data length */ 1519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels size_t *dst_alloc, /* dest buffer allocated size */ 1529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char *src_buf, /* source buffer */ 1539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int src_b64) /* != 0 if source is base64 encoded */ 1549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 155e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET size_t need_alloc = 0; 156e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET size_t src_len = strlen(src_buf); 1579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(!src_len) 1599bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return GPE_OK; 1609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 161e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET need_alloc = src_len + *dst_len + 1; 1629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(src_b64) { 164e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(src_buf[src_len - 1] == '\r') 165e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET src_len--; 1669bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 167e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(src_buf[src_len - 1] == '\n') 168e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET src_len--; 169e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 1709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* enlarge destination buffer if required */ 1729bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(need_alloc > *dst_alloc) { 1739bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels size_t newsize = need_alloc * 2; 1749bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char *newptr = realloc(*dst_buf, newsize); 1759bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(!newptr) { 1769bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return GPE_OUT_OF_MEMORY; 1779bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 1789bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *dst_alloc = newsize; 1799bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *dst_buf = newptr; 1809bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 1819bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1829bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* memcpy to support binary blobs */ 1839bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels memcpy(*dst_buf + *dst_len, src_buf, src_len); 1849bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *dst_len += src_len; 1859bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *(*dst_buf + *dst_len) = '\0'; 1869bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 187e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return GPE_OK; 188e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 189e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 190e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int decodedata(char **buf, /* dest buffer */ 191e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET size_t *len) /* dest buffer data length */ 192e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 193e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET int error = 0; 194e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned char *buf64 = NULL; 195e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET size_t src_len = 0; 196e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 197e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!*len) 198e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return GPE_OK; 199e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 200e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* base64 decode the given buffer */ 201e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET error = (int) Curl_base64_decode(*buf, &buf64, &src_len); 202e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(error) 203e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return GPE_OUT_OF_MEMORY; 204e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 205e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!src_len) { 206e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* 207e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ** currently there is no way to tell apart an OOM condition in 208e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ** Curl_base64_decode() from zero length decoded data. For now, 209e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ** let's just assume it is an OOM condition, currently we have 210e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ** no input for this function that decodes to zero length data. 211e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */ 212e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET free(buf64); 213e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 214e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return GPE_OUT_OF_MEMORY; 215e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 216e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 217e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* memcpy to support binary blobs */ 218e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET memcpy(*buf, buf64, src_len); 219e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *len = src_len; 220e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *(*buf + src_len) = '\0'; 221e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 222e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET free(buf64); 2239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return GPE_OK; 2259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 2269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* 2289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * getpart() 2299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 2309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * This returns whole contents of specified XML-like section and subsection 2319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * from the given file. This is mostly used to retrieve a specific part from 2329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * a test definition file for consumption by test suite servers. 2339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 2349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Data is returned in a dynamically allocated buffer, a pointer to this data 2359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * and the size of the data is stored at the addresses that caller specifies. 2369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 2379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * If the returned data is a string the returned size will be the length of 2389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * the string excluding null termination. Otherwise it will just be the size 2399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * of the returned binary data. 2409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 2419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Calling function is responsible to free returned buffer. 2429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 2439bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * This function may return: 2449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * GPE_NO_BUFFER_SPACE 2459bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * GPE_OUT_OF_MEMORY 2469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * GPE_OK 2479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels */ 2489bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2499bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsint getpart(char **outbuf, size_t *outlen, 2509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels const char *main, const char *sub, FILE *stream) 2519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 2529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels# define MAX_TAG_LEN 79 2539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char couter[MAX_TAG_LEN+1]; /* current outermost section */ 2549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char cmain[MAX_TAG_LEN+1]; /* current main section */ 2559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char csub[MAX_TAG_LEN+1]; /* current sub section */ 2569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char ptag[MAX_TAG_LEN+1]; /* potential tag */ 2579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char patt[MAX_TAG_LEN+1]; /* potential attributes */ 2589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char *buffer = NULL; 2599bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char *ptr; 2609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char *end; 2619bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels union { 2629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ssize_t sig; 2639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels size_t uns; 2649bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } len; 2659bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels size_t bufsize = 0; 2669bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels size_t outalloc = 256; 2679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int in_wanted_part = 0; 2689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int base64 = 0; 2699bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int error; 2709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels enum { 2729bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels STATE_OUTSIDE = 0, 2739bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels STATE_OUTER = 1, 2749bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels STATE_INMAIN = 2, 2759bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels STATE_INSUB = 3, 2769bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels STATE_ILLEGAL = 4 2779bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } state = STATE_OUTSIDE; 2789bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2799bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *outlen = 0; 2809bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *outbuf = malloc(outalloc); 2819bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(!*outbuf) 2829bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return GPE_OUT_OF_MEMORY; 2839bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *(*outbuf) = '\0'; 2849bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2859bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels couter[0] = cmain[0] = csub[0] = ptag[0] = patt[0] = '\0'; 2869bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2879bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels while((error = readline(&buffer, &bufsize, stream)) == GPE_OK) { 2889bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2899bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ptr = buffer; 2909bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels EAT_SPACE(ptr); 2919bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2929bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if('<' != *ptr) { 2939bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(in_wanted_part) { 2949bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels show(("=> %s", buffer)); 2959bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels error = appenddata(outbuf, outlen, &outalloc, buffer, base64); 2969bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(error) 2979bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels break; 2989bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 2999bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels continue; 3009bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3019bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3029bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ptr++; 3039bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3049bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if('/' == *ptr) { 3059bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* 3069bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ** closing section tag 3079bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels */ 3089bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3099bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ptr++; 3109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels end = ptr; 3119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels EAT_WORD(end); 3129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if((len.sig = end - ptr) > MAX_TAG_LEN) { 3139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels error = GPE_NO_BUFFER_SPACE; 3149bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels break; 3159bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3169bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels memcpy(ptag, ptr, len.uns); 3179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ptag[len.uns] = '\0'; 3189bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3199bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if((STATE_INSUB == state) && !strcmp(csub, ptag)) { 3209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* end of current sub section */ 3219bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels state = STATE_INMAIN; 3229bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels csub[0] = '\0'; 3239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(in_wanted_part) { 3249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* end of wanted part */ 3259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels in_wanted_part = 0; 326e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 327e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* Do we need to base64 decode the data? */ 328e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(base64) { 329e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET error = decodedata(outbuf, outlen); 330e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(error) 331e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return error; 332e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 3339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels break; 3349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels else if((STATE_INMAIN == state) && !strcmp(cmain, ptag)) { 3379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* end of current main section */ 3389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels state = STATE_OUTER; 3399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels cmain[0] = '\0'; 3409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(in_wanted_part) { 3419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* end of wanted part */ 3429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels in_wanted_part = 0; 343e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 344e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* Do we need to base64 decode the data? */ 345e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(base64) { 346e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET error = decodedata(outbuf, outlen); 347e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(error) 348e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return error; 349e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 3509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels break; 3519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels else if((STATE_OUTER == state) && !strcmp(couter, ptag)) { 3549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* end of outermost file section */ 3559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels state = STATE_OUTSIDE; 3569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels couter[0] = '\0'; 3579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(in_wanted_part) { 3589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* end of wanted part */ 3599bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels in_wanted_part = 0; 3609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels break; 3619bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3649bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3659bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels else if(!in_wanted_part) { 3669bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* 3679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ** opening section tag 3689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels */ 3699bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* get potential tag */ 3719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels end = ptr; 3729bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels EAT_WORD(end); 3739bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if((len.sig = end - ptr) > MAX_TAG_LEN) { 3749bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels error = GPE_NO_BUFFER_SPACE; 3759bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels break; 3769bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3779bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels memcpy(ptag, ptr, len.uns); 3789bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ptag[len.uns] = '\0'; 3799bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3809bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* ignore comments, doctypes and xml declarations */ 3819bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(('!' == ptag[0]) || ('?' == ptag[0])) { 3829bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels show(("* ignoring (%s)", buffer)); 3839bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels continue; 3849bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3859bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3869bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* get all potential attributes */ 3879bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ptr = end; 3889bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels EAT_SPACE(ptr); 3899bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels end = ptr; 3909bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels while(*end && ('>' != *end)) 3919bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels end++; 3929bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if((len.sig = end - ptr) > MAX_TAG_LEN) { 3939bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels error = GPE_NO_BUFFER_SPACE; 3949bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels break; 3959bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3969bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels memcpy(patt, ptr, len.uns); 3979bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels patt[len.uns] = '\0'; 3989bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3999bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(STATE_OUTSIDE == state) { 4009bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* outermost element (<testcase>) */ 4019bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels strcpy(couter, ptag); 4029bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels state = STATE_OUTER; 4039bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels continue; 4049bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 4059bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels else if(STATE_OUTER == state) { 4069bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* start of a main section */ 4079bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels strcpy(cmain, ptag); 4089bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels state = STATE_INMAIN; 4099bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels continue; 4109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 4119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels else if(STATE_INMAIN == state) { 4129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* start of a sub section */ 4139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels strcpy(csub, ptag); 4149bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels state = STATE_INSUB; 4159bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(!strcmp(cmain, main) && !strcmp(csub, sub)) { 4169bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* start of wanted part */ 4179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels in_wanted_part = 1; 4189bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(strstr(patt, "base64=")) 4199bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* bit rough test, but "mostly" functional, */ 4209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* treat wanted part data as base64 encoded */ 4219bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels base64 = 1; 4229bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 4239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels continue; 4249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 4259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 4269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 4279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 4289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(in_wanted_part) { 4299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels show(("=> %s", buffer)); 4309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels error = appenddata(outbuf, outlen, &outalloc, buffer, base64); 4319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(error) 4329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels break; 4339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 4349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 4359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } /* while */ 4369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 437e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET free(buffer); 4389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 4399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(error != GPE_OK) { 4409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(error == GPE_END_OF_FILE) 4419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels error = GPE_OK; 4429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels else { 443e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET free(*outbuf); 4449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *outbuf = NULL; 4459bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *outlen = 0; 4469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 4479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 4489bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 4499bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return error; 4509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 4519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 452