#include "setup.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "getpart.h"
#define _MPRINTF_REPLACE
#include <curl/mprintf.h>
struct SessionHandle {
int fake;
};
#include "base64.h"
#include "memdebug.h"
#define EAT_SPACE(ptr) while( ptr && *ptr && ISSPACE(*ptr) ) ptr++
#define EAT_WORD(ptr) while( ptr && *ptr && !ISSPACE(*ptr) && \
('>' != *ptr)) ptr++
#ifdef DEBUG
#define show(x) printf x
#else
#define show(x)
#endif
curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc;
curl_free_callback Curl_cfree = (curl_free_callback)free;
curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)strdup;
curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
static
char *appendstring(char *string,
char *buffer,
size_t *stringlen,
size_t *stralloc,
char base64)
{
size_t len = strlen(buffer);
size_t needed_len = len + *stringlen + 1;
char *buf64=NULL;
if(base64) {
len = Curl_base64_decode(buffer, (unsigned char**)&buf64);
buffer = buf64;
needed_len = len + *stringlen + 1;
}
if(needed_len >= *stralloc) {
char *newptr;
size_t newsize = needed_len*2;
newptr = realloc(string, newsize);
if(newptr) {
string = newptr;
*stralloc = newsize;
}
else {
if(buf64)
free(buf64);
return NULL;
}
}
memcpy(&string[*stringlen], buffer, len);
*stringlen += len;
string[*stringlen]=0;
if(buf64)
free(buf64);
return string;
}
const char *spitout(FILE *stream,
const char *main,
const char *sub, size_t *size)
{
char buffer[8192];
char cmain[128]="";
char csub[128]="";
char *ptr;
char *end;
char display = 0;
char *string;
size_t stringlen=0;
size_t stralloc=256;
char base64 = 0;
enum {
STATE_OUTSIDE,
STATE_OUTER,
STATE_INMAIN,
STATE_INSUB,
STATE_ILLEGAL
} state = STATE_OUTSIDE;
string = (char *)malloc(stralloc);
if(!string)
return NULL;
string[0] = 0;
while(fgets(buffer, sizeof(buffer), stream)) {
ptr = buffer;
EAT_SPACE(ptr);
if('<' != *ptr) {
if(display) {
show(("=> %s", buffer));
string = appendstring(string, buffer, &stringlen, &stralloc, base64);
show(("* %s\n", buffer));
}
continue;
}
ptr++;
EAT_SPACE(ptr);
if('/' == *ptr) {
ptr++;
EAT_SPACE(ptr);
end = ptr;
EAT_WORD(end);
*end = 0;
if((state == STATE_INSUB) &&
!strcmp(csub, ptr)) {
state--;
csub[0]=0;
display=0;
}
else if((state == STATE_INMAIN) &&
!strcmp(cmain, ptr)) {
state--;
cmain[0]=0;
display=0;
}
else if(state == STATE_OUTER) {
state--;
}
}
else if(!display) {
end = ptr;
EAT_WORD(end);
*end = 0;
switch(state) {
case STATE_OUTSIDE:
strcpy(cmain, ptr);
state = STATE_OUTER;
break;
case STATE_OUTER:
strcpy(cmain, ptr);
state = STATE_INMAIN;
break;
case STATE_INMAIN:
strcpy(csub, ptr);
state = STATE_INSUB;
break;
default:
break;
}
if(!end[1] != '>') {
if(strstr(&end[1], "base64=")) {
base64 = 1;
}
}
}
if(display) {
string = appendstring(string, buffer, &stringlen, &stralloc, base64);
show(("* %s\n", buffer));
}
if((STATE_INSUB == state) &&
!strcmp(cmain, main) &&
!strcmp(csub, sub)) {
show(("* (%d bytes) %s\n", stringlen, buffer));
display = 1;
}
else if ((*cmain == '?') || (*cmain == '!') || (*csub == '!')) {
show(("%d ignoring (%s/%s)\n", state, cmain, csub));
state--;
}
else {
show(("%d (%s/%s): %s\n", state, cmain, csub, buffer));
display = 0;
}
}
*size = stringlen;
return string;
}