#ifdef HAVE_LIBWWW
#include "hslibwww.h"
#include <stdio.h>
#include <string.h>
static const char darcs_version[] = PACKAGE_VERSION;
#include <WWWLib.h>
#include <WWWInit.h>
enum RESULT_CODES
{
RESULT_OK = 0,
RESULT_REQUEST_NEW_FAIL,
RESULT_NET_ADD_AFTER_FAIL,
RESULT_REQUEST_ADD_CACHE_CONTROL_FAIL,
RESULT_LOAD_TO_FILE_FAIL,
RESULT_MALLOC_FAIL,
RESULT_LIST_NEW_FAIL,
RESULT_LIST_APPEND_OBJECT_FAIL,
RESULT_EVENTLIST_NEW_LOOP
};
static const char *error_strings[] =
{
"",
"HTRequest_new() failed",
"HTNet_addAfter() failed",
"HTRequest_addCacheControl() failed",
"HTLoadToFile() failed",
"malloc() failed",
"HTList_new() failed",
"HTList_appendObject() failed",
"HTEventList_newLoop() failed"
};
struct Completed
{
int error;
char *url;
};
static BOOL init_done = NO;
static int error;
static HTList *completed_list = NULL;
static char *last_url = NULL;
static char libwww_error[80];
static const char libwww_error_fmt[] = "libwww error code: %i";
int terminate_handler(HTRequest *request,
HTResponse *response,
void *param,
int status)
{
struct Completed *completed = malloc(sizeof(struct Completed));
if (completed == NULL)
error = RESULT_MALLOC_FAIL;
else
{
if (HTList_appendObject(completed_list, completed) == NO)
{
error = RESULT_LIST_APPEND_OBJECT_FAIL;
free(completed);
}
else
{
error = RESULT_OK;
completed->error = status;
completed->url = HTRequest_context(request);
}
}
HTRequest_delete(request);
HTEventList_stopLoop();
// Return not HT_OK to stop executing after filters.
return HT_ERROR;
}
const char *libwww_request_url(const char *url,
const char *filename,
int cache_time)
{
BOOL result;
if (init_done == NO)
{
HTProfile_newNoCacheClient("darcs", darcs_version);
HTProxy_getEnvVar();
HTAlert_setInteractive(NO);
HTFormat_addCoding("*", NULL, HTIdentityCoding, 1.0);
#ifdef LIBWWW_DEBUG
HTSetTraceMessageMask("sop");
#endif
init_done = YES;
}
if (completed_list == NULL)
{
completed_list = HTList_new();
if (completed_list == NULL)
return error_strings[RESULT_LIST_NEW_FAIL];
}
HTRequest *const request = HTRequest_new();
if (request == NULL)
return error_strings[RESULT_REQUEST_NEW_FAIL];
HTRequest_setContext(request, strdup(url));
result = HTNet_addAfter(terminate_handler, NULL, NULL, HT_ALL, HT_FILTER_LAST);
if (result == NO)
return error_strings[RESULT_NET_ADD_AFTER_FAIL];
if (cache_time == 0)
{
HTRequest_addGnHd(request, HT_G_PRAGMA_NO_CACHE);
result = HTRequest_addCacheControl(request, "no-cache", "");
}
else if (cache_time > 0)
{
char buf[8];
snprintf(buf, sizeof(buf), "%d", cache_time);
buf[sizeof(buf) - 1] = '\0';
result = HTRequest_addCacheControl(request, "max-age", buf);
}
if (result == NO)
return error_strings[RESULT_REQUEST_ADD_CACHE_CONTROL_FAIL];
result = HTLoadToFile(url, request, filename);
if (result == NO)
return error_strings[RESULT_LOAD_TO_FILE_FAIL];
return error_strings[RESULT_OK];
}
const char *libwww_wait_next_url()
{
if (last_url != NULL)
{
free(last_url);
last_url = NULL;
}
error = RESULT_OK;
if (HTList_isEmpty(completed_list) == YES &&
HTNet_isEmpty() == NO &&
HTEventList_newLoop() != HT_OK)
return error_strings[RESULT_EVENTLIST_NEW_LOOP];
if (HTList_isEmpty(completed_list) == NO)
{
struct Completed *completed = HTList_firstObject(completed_list);
if (completed->error == HT_LOADED)
libwww_error[0] = '\0';
else
{
snprintf(libwww_error, sizeof(libwww_error),
libwww_error_fmt, completed->error);
libwww_error[sizeof(libwww_error) - 1] = '\0';
}
last_url = completed->url;
HTList_removeFirstObject(completed_list);
free(completed);
return libwww_error;
}
return error_strings[error];
}
const char *libwww_last_url()
{
return last_url != NULL ? last_url : "";
}
#endif