#define Free(b) if (b) free(b)
#ifdef XUSE_WWW
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xos.h>
int
GetUrl(char *url, char **reply_ret, int *len_ret)
{
char buf[BUFSIZ], *reply, *ptr;
FILE *fp;
int readbytes, size;
sprintf(buf, "www -source \"%s\"", url);
fp = popen(buf, "r");
if (fp == NULL)
return 1;
reply = NULL;
size = 0;
do {
readbytes = fread(buf, sizeof(char), BUFSIZ, fp);
if (readbytes != 0) {
ptr = (char *) realloc(reply, sizeof(char) * size + readbytes);
if (ptr == NULL) {
Free(reply);
return 1;
}
reply = ptr;
memcpy(reply + size, buf, readbytes);
size += readbytes;
}
} while (readbytes == BUFSIZ);
pclose(fp);
*reply_ret = reply;
*len_ret = size;
return 0;
}
#else
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#if !defined(UNIXCPP) || defined(ANSICPP)
#define TRANS(func) _HttpTrans##func
#else
#define TRANS(func) _HttpTransfunc
#endif
#include <X11/Xtrans.h>
#define HTTP_CONNECTION_RETRIES 5
static XtransConnInfo
OpenConnection(char *hostname, int port)
{
int retry;
XtransConnInfo trans_conn = NULL;
int connect_stat;
char address[128];
char protocol[] = "tcp";
sprintf(address,"%s/%s:%d",
protocol ? protocol : "",
hostname ? hostname : "",
port);
for(retry = HTTP_CONNECTION_RETRIES; retry >= 0; retry--) {
if ((trans_conn = _HttpTransOpenCOTSClient(address)) == NULL)
break;
if ((connect_stat = _HttpTransConnect(trans_conn, address)) < 0) {
_HttpTransClose(trans_conn);
trans_conn = NULL;
if (connect_stat == TRANS_TRY_CONNECT_AGAIN) {
sleep(1);
continue;
} else
break;
}
}
return trans_conn;
}
static void
CloseConnection(XtransConnInfo trans_conn)
{
_HttpTransDisconnect(trans_conn);
_HttpTransClose(trans_conn);
}
static void
SendGetRequest(XtransConnInfo trans_conn, char *filename)
{
char *request;
char request_format[] =
"GET %s HTTP/1.0\r\nUser-Agent: xrx\r\nAccept: */*\r\n\r\n";
int request_len = strlen(filename) + sizeof(request_format) + 1;
request = (char *)malloc(request_len);
sprintf(request, request_format, filename);
_HttpTransWrite(trans_conn, request, request_len);
Free(request);
}
static int
ReadGetReply(XtransConnInfo trans_conn, char **reply_ret)
{
char *reply = NULL;
char buf[BUFSIZ];
int len, nbytes;
len = 0;
do {
nbytes = _HttpTransRead(trans_conn, buf, BUFSIZ);
if (nbytes > 0) {
reply = (char *)realloc(reply, len + nbytes);
if (reply == NULL)
break;
memcpy(reply + len, buf, nbytes);
len += nbytes;
}
} while (nbytes != 0);
*reply_ret = reply;
return len;
}
#define HTTP_DEFAULT_PORT 80
static int
ParseHttpUrl(char *url, char **hostname_ret, int *port_ret, char **path_ret)
{
char HTTP[] = "http://";
char *hostname, *path;
int port;
char *ptr, *bos;
int status = 0;
if (strncmp(HTTP, url, sizeof(HTTP) - 1))
return 1;
bos = ptr = url + sizeof(HTTP) - 1;
while (*ptr && *ptr != ':' && *ptr != '/')
ptr++;
if (bos == ptr)
return 1;
hostname = (char *)malloc(ptr - bos + 1);
if (hostname == NULL)
return 1;
memcpy(hostname, bos, ptr - bos);
hostname[ptr - bos] = '\0';
path = NULL;
if (*ptr != ':' || ! ptr[1])
port = HTTP_DEFAULT_PORT;
else {
++ptr;
port = 0;
while (*ptr && *ptr != '/') {
if (isdigit((int) *ptr)) {
port *= 10;
port += *ptr - '0';
} else {
status = 1;
goto error;
}
ptr++;
}
}
path = (char *)malloc(strlen(ptr) + 1);
if (path == NULL) {
status = 1;
goto error;
}
strcpy(path, ptr);
*hostname_ret = hostname;
*port_ret = port;
*path_ret = path;
return 0;
error:
Free(hostname);
Free(path);
return status;
}
int
GetUrl(char *url, char **reply_ret, int *len_ret)
{
char *hostname, *path;
int port;
XtransConnInfo trans;
int status = 0;
if (ParseHttpUrl(url, &hostname, &port, &path) != 0)
return 1;
trans = OpenConnection(hostname, port);
if (trans == NULL) {
status = 1;
goto end;
}
SendGetRequest(trans, path);
*len_ret = ReadGetReply(trans, reply_ret);
CloseConnection(trans);
end:
Free(hostname);
Free(path);
return status;
}
#endif