getpart.c revision 9bd90e6e25f1e55f50201c87a1b5837de7e5b64a
19bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/*************************************************************************** 29bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * _ _ ____ _ 39bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Project ___| | | | _ \| | 49bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * / __| | | | |_) | | 59bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * | (__| |_| | _ <| |___ 69bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * \___|\___/|_| \_\_____| 79bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 89bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Copyright (C) 1998 - 2010, 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 ***************************************************************************/ 229bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#define CURL_NO_OLDIES 249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include "setup.h" 269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include "getpart.h" 289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#define ENABLE_CURLX_PRINTF 309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* make the curlx header define all printf() functions to use the curlx_* 319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels versions instead */ 329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include "curlx.h" /* from the private lib dir */ 339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* just to please base64.h we create a fake struct */ 359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsstruct SessionHandle { 369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int fake; 379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels}; 389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include "curl_base64.h" 409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include "curl_memory.h" 419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* include memdebug.h last */ 439bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#include "memdebug.h" 449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 459bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#define EAT_SPACE(p) while(*(p) && ISSPACE(*(p))) (p)++ 469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#define EAT_WORD(p) while(*(p) && !ISSPACE(*(p)) && ('>' != *(p))) (p)++ 489bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 499bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#ifdef DEBUG_GETPART 509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#define show(x) printf x 519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#else 529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#define show(x) 539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#endif 549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#if defined(_MSC_VER) && defined(_DLL) 569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels# pragma warning(disable:4232) /* MSVC extension, dllimport identity */ 579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels#endif 589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 599bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelscurl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc; 609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelscurl_free_callback Curl_cfree = (curl_free_callback)free; 619bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelscurl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc; 629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelscurl_strdup_callback Curl_cstrdup = (curl_strdup_callback)strdup; 639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelscurl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc; 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{ 1559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels size_t need_alloc, src_len; 1569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels union { 1579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels unsigned char *as_uchar; 1589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char *as_char; 1599bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } buf64; 1609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1619bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels src_len = strlen(src_buf); 1629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(!src_len) 1639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return GPE_OK; 1649bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1659bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels buf64.as_char = NULL; 1669bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(src_b64) { 1689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* base64 decode the given buffer */ 1699bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels src_len = Curl_base64_decode(src_buf, &buf64.as_uchar); 1709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels src_buf = buf64.as_char; 1719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(!src_len || !src_buf) { 1729bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* 1739bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ** currently there is no way to tell apart an OOM condition in 1749bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ** Curl_base64_decode() from zero length decoded data. For now, 1759bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ** let's just assume it is an OOM condition, currently we have 1769bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ** no input for this function that decodes to zero length data. 1779bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels */ 1789bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(buf64.as_char) 1799bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels free(buf64.as_char); 1809bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return GPE_OUT_OF_MEMORY; 1819bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 1829bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 1839bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1849bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels need_alloc = src_len + *dst_len + 1; 1859bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1869bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* enlarge destination buffer if required */ 1879bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(need_alloc > *dst_alloc) { 1889bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels size_t newsize = need_alloc * 2; 1899bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char *newptr = realloc(*dst_buf, newsize); 1909bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(!newptr) { 1919bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(buf64.as_char) 1929bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels free(buf64.as_char); 1939bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return GPE_OUT_OF_MEMORY; 1949bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 1959bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *dst_alloc = newsize; 1969bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *dst_buf = newptr; 1979bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 1989bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 1999bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* memcpy to support binary blobs */ 2009bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels memcpy(*dst_buf + *dst_len, src_buf, src_len); 2019bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *dst_len += src_len; 2029bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *(*dst_buf + *dst_len) = '\0'; 2039bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2049bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(buf64.as_char) 2059bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels free(buf64.as_char); 2069bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2079bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return GPE_OK; 2089bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 2099bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels/* 2119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * getpart() 2129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 2139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * This returns whole contents of specified XML-like section and subsection 2149bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * from the given file. This is mostly used to retrieve a specific part from 2159bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * a test definition file for consumption by test suite servers. 2169bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 2179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Data is returned in a dynamically allocated buffer, a pointer to this data 2189bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * and the size of the data is stored at the addresses that caller specifies. 2199bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 2209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * If the returned data is a string the returned size will be the length of 2219bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * the string excluding null termination. Otherwise it will just be the size 2229bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * of the returned binary data. 2239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 2249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * Calling function is responsible to free returned buffer. 2259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * 2269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * This function may return: 2279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * GPE_NO_BUFFER_SPACE 2289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * GPE_OUT_OF_MEMORY 2299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels * GPE_OK 2309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels */ 2319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckelsint getpart(char **outbuf, size_t *outlen, 2339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels const char *main, const char *sub, FILE *stream) 2349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels{ 2359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels# define MAX_TAG_LEN 79 2369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char couter[MAX_TAG_LEN+1]; /* current outermost section */ 2379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char cmain[MAX_TAG_LEN+1]; /* current main section */ 2389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char csub[MAX_TAG_LEN+1]; /* current sub section */ 2399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char ptag[MAX_TAG_LEN+1]; /* potential tag */ 2409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char patt[MAX_TAG_LEN+1]; /* potential attributes */ 2419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char *buffer = NULL; 2429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char *ptr; 2439bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels char *end; 2449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels union { 2459bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ssize_t sig; 2469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels size_t uns; 2479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } len; 2489bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels size_t bufsize = 0; 2499bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels size_t outalloc = 256; 2509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int in_wanted_part = 0; 2519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int base64 = 0; 2529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels int error; 2539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels enum { 2559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels STATE_OUTSIDE = 0, 2569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels STATE_OUTER = 1, 2579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels STATE_INMAIN = 2, 2589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels STATE_INSUB = 3, 2599bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels STATE_ILLEGAL = 4 2609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } state = STATE_OUTSIDE; 2619bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *outlen = 0; 2639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *outbuf = malloc(outalloc); 2649bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(!*outbuf) 2659bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return GPE_OUT_OF_MEMORY; 2669bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *(*outbuf) = '\0'; 2679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels couter[0] = cmain[0] = csub[0] = ptag[0] = patt[0] = '\0'; 2699bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels while((error = readline(&buffer, &bufsize, stream)) == GPE_OK) { 2719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2729bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ptr = buffer; 2739bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels EAT_SPACE(ptr); 2749bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2759bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if('<' != *ptr) { 2769bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(in_wanted_part) { 2779bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels show(("=> %s", buffer)); 2789bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels error = appenddata(outbuf, outlen, &outalloc, buffer, base64); 2799bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(error) 2809bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels break; 2819bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 2829bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels continue; 2839bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 2849bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2859bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ptr++; 2869bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2879bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if('/' == *ptr) { 2889bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* 2899bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ** closing section tag 2909bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels */ 2919bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 2929bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ptr++; 2939bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels end = ptr; 2949bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels EAT_WORD(end); 2959bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if((len.sig = end - ptr) > MAX_TAG_LEN) { 2969bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels error = GPE_NO_BUFFER_SPACE; 2979bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels break; 2989bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 2999bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels memcpy(ptag, ptr, len.uns); 3009bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ptag[len.uns] = '\0'; 3019bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3029bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if((STATE_INSUB == state) && !strcmp(csub, ptag)) { 3039bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* end of current sub section */ 3049bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels state = STATE_INMAIN; 3059bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels csub[0] = '\0'; 3069bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(in_wanted_part) { 3079bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* end of wanted part */ 3089bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels in_wanted_part = 0; 3099bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels break; 3109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels else if((STATE_INMAIN == state) && !strcmp(cmain, ptag)) { 3139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* end of current main section */ 3149bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels state = STATE_OUTER; 3159bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels cmain[0] = '\0'; 3169bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(in_wanted_part) { 3179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* end of wanted part */ 3189bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels in_wanted_part = 0; 3199bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels break; 3209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3219bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3229bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels else if((STATE_OUTER == state) && !strcmp(couter, ptag)) { 3239bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* end of outermost file section */ 3249bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels state = STATE_OUTSIDE; 3259bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels couter[0] = '\0'; 3269bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(in_wanted_part) { 3279bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* end of wanted part */ 3289bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels in_wanted_part = 0; 3299bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels break; 3309bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3319bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3329bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3339bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3349bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels else if(!in_wanted_part) { 3359bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* 3369bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ** opening section tag 3379bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels */ 3389bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3399bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* get potential tag */ 3409bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels end = ptr; 3419bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels EAT_WORD(end); 3429bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if((len.sig = end - ptr) > MAX_TAG_LEN) { 3439bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels error = GPE_NO_BUFFER_SPACE; 3449bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels break; 3459bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3469bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels memcpy(ptag, ptr, len.uns); 3479bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ptag[len.uns] = '\0'; 3489bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3499bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* ignore comments, doctypes and xml declarations */ 3509bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(('!' == ptag[0]) || ('?' == ptag[0])) { 3519bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels show(("* ignoring (%s)", buffer)); 3529bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels continue; 3539bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3549bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3559bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* get all potential attributes */ 3569bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels ptr = end; 3579bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels EAT_SPACE(ptr); 3589bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels end = ptr; 3599bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels while(*end && ('>' != *end)) 3609bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels end++; 3619bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if((len.sig = end - ptr) > MAX_TAG_LEN) { 3629bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels error = GPE_NO_BUFFER_SPACE; 3639bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels break; 3649bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3659bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels memcpy(patt, ptr, len.uns); 3669bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels patt[len.uns] = '\0'; 3679bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3689bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(STATE_OUTSIDE == state) { 3699bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* outermost element (<testcase>) */ 3709bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels strcpy(couter, ptag); 3719bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels state = STATE_OUTER; 3729bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels continue; 3739bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3749bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels else if(STATE_OUTER == state) { 3759bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* start of a main section */ 3769bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels strcpy(cmain, ptag); 3779bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels state = STATE_INMAIN; 3789bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels continue; 3799bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3809bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels else if(STATE_INMAIN == state) { 3819bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* start of a sub section */ 3829bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels strcpy(csub, ptag); 3839bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels state = STATE_INSUB; 3849bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(!strcmp(cmain, main) && !strcmp(csub, sub)) { 3859bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* start of wanted part */ 3869bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels in_wanted_part = 1; 3879bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(strstr(patt, "base64=")) 3889bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* bit rough test, but "mostly" functional, */ 3899bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* treat wanted part data as base64 encoded */ 3909bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels base64 = 1; 3919bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3929bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels continue; 3939bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3949bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3959bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3969bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 3979bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(in_wanted_part) { 3989bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels show(("=> %s", buffer)); 3999bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels error = appenddata(outbuf, outlen, &outalloc, buffer, base64); 4009bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(error) 4019bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels break; 4029bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 4039bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 4049bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } /* while */ 4059bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 4069bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(buffer) 4079bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels free(buffer); 4089bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 4099bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(error != GPE_OK) { 4109bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(error == GPE_END_OF_FILE) 4119bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels error = GPE_OK; 4129bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels else { 4139bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels if(*outbuf) 4149bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels free(*outbuf); 4159bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *outbuf = NULL; 4169bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels *outlen = 0; 4179bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 4189bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 4199bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 4209bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels return error; 4219bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels} 4229bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels 423