20#include "lt-comment.h"
24#define Strerror() strErr()
26#define Realloc srealloc
28#define fopen stdsfopen
34#define LT_ERROR(err, format) fprintf(stderr, format)
35#define LT_ERROR1(err, format, arg) fprintf(stderr, format, arg)
36#define LT_ERROR2(err, format, arg1, arg2) fprintf(stderr, format, arg1, arg2)
37#define LT_ERROR3(err, format, arg1, arg2, arg3) fprintf(stderr, format, arg1, arg2, arg3)
38#define WARN(err, format) fprintf(stderr, format)
39#define WARN1(err, format, arg) fprintf(stderr, format, arg)
41#define Strerror() strerror(errno)
44#define CWDBS MAXPATHLEN+1
49#define GETWD(buf) getcwd(buf,CWDBS)
65#ifdef SOCKETS_IMPLEMENTED
74#include <sys/socket.h>
75#include <netinet/in.h>
92static FILE16 *http_open(
const char *url,
93 const char *
host,
int port,
const char *path,
95static FILE16 *file_open(
const char *url,
96 const char *
host,
int port,
const char *path,
99static void parse_url(
const char *url,
100 char **scheme,
char **
host,
int *port,
char **path);
106 FILE16 *(*open)(
const char *,
const char *, int,
const char *,
const char *);
108 {(
char *)
"http", http_open},
109 {(
char *)
"file", file_open},
111#define NSCHEME (sizeof(schemes) / sizeof(schemes[0]))
115char *default_base_url(
void)
122 WARN(
LEFILE,
"Warning: can't get current directory for default base url\n");
123 return strdup8(
"file:/");
178char *url_merge(
const char *url,
const char *
base,
182 char *scheme=0, *
host=0, *path=0;
190 parse_url(url, &scheme, &
host, &port, &path);
191 if(scheme && (
host || *path ==
'/'))
211 LT_ERROR1(
LEFILE,
"Error: bad base URL <%s>\n",
base);
248 for(
j=i+1; p[
j] && p[
j] !=
'/';
j++)
253 if(
j - i == 2 && p[i+1] ==
'.')
265 if(p[
j] ==
'/' && p[
j+1] ==
'.' && p[
j+2] ==
'.' &&
266 (p[
j+3] ==
'/' || p[
j+3] ==
'\0') &&
267 (
j - i != 3 || p[i+1] !=
'.' || p[i+2] !=
'.'))
269 strcpy(&p[i+1], p[
j+3] ? &p[
j+4] : &p[
j+3]);
282 if(scheme && !
host && *path !=
'/')
287 "Warning: relative URL <%s> contains scheme, contrary to RFC 1808\n",
293 "Error: relative URL <%s> has scheme different from base <%s>\n",
367FILE16 *url_open(
const char *url,
const char *
base,
const char *type,
379 if(!(
m_url = url_merge(url,
base, &scheme, &
host, &port, &path)))
395 for(i=0; i<NSCHEME; i++)
396 if(
strcmp(scheme, schemes[i].scheme) == 0)
398 f = schemes[i].open(
m_url,
host, port, path, type);
420 "Can't attach gzip processor to URL \"%s\"\n",
444 LT_ERROR1(
LEFILE,
"Error: scheme \"%s\" not implemented\n", scheme);
457static FILE16 *http_open(
const char *url,
458 const char *
host,
int port,
const char *path,
461#ifndef SOCKETS_IMPLEMENTED
463 "http: URLs are not yet implemented on this platform\n");
476 static char buf[1024];
484 LT_ERROR(
LEFILE,
"Error: can't init HTTP interface\n");
489 LT_ERROR(
LEFILE,
"Error: wrong version of WINSOCK\n");
499 LT_ERROR1(
LEFILE,
"Error: can't open http URL \"%s\" for writing\n",
506 LT_ERROR1(
LEFILE,
"Error: no host part in http URL \"%s\"\n", url);
515 LT_ERROR1(
LEFILE,
"Error: system call socket failed: %d\n",
520 LT_ERROR1(
LEFILE,
"Error: system call socket failed: %s\n",
532 "Error: can't find address for host in http URL \"%s\"\n",
547 LT_ERROR1(
LEFILE,
"Error: system call connect failed: %s\n",
572 sprintf(
buf,
"GET %s HTTP/1.0\012\015Connection: close\012\015\012\015",
575 LT_ERROR1(
LEFILE,
"Error: system call socket failed: %d\n",
581 fprintf(
fout,
"GET %s HTTP/1.0\012\015Connection: close\012\015\012\015",
591 LT_ERROR1(
LEWRTF,
"Error: write to socket failed: %s\n",Strerror());
601 for(i=0; i<
sizeof(
buf)-1; i++)
603 if(
recv(s, &
buf[i], 1, 0) != 1)
605 "Error: recv error from server for URL \"%s\"\n",
610 count=
sscanf(
buf,
"HTTP/%d.%d %d %80[^\012]",
613 count=
fscanf(
fin,
"HTTP/%d.%d %d %80[^\012]",
620 "Error: bad header from server for URL \"%s\"\n%d %s\n",
621 url, count, Strerror());
631 LT_ERROR3(
LEFILE,
"Error: can't retrieve \"%s\": %d %s\n",
643 while(
recv(s,
buf, 1, 0) == 1 && (c =
buf[0], 1) || (c =
EOF, 0))
658 LT_ERROR1(
LEFILE,
"Error: EOF in headers retrieving \"%s\"\n", url);
668 f16 = MakeFILE16FromFILE(
fin, type);
671 SetCloseUnderlying(
f16, 1);
678static FILE16 *file_open(
const char *url,
679 const char *
host,
int port,
const char *path,
687 WARN1(
LEFILE,
"Warning: ignoring host part in file URL \"%s\"\n", url);
693 if(path[0] ==
'/' && path[1] && path[2] ==
':')
696 file = strdup8(path);
712 file = strdup8(path);
723 file = strdup8(path);
740 f16 = MakeFILE16FromFILE(f, type);
741 SetCloseUnderlying(
f16, 1);
746static void parse_url(
const char *url,
747 char **scheme,
char **
host,
int *port,
char **path)
752 *scheme = *
host = *path = 0;
757 for(p = (
char *)url; *p; p++)
758 if(*p ==
':' || *p ==
'/')
761 if(p > url && *p ==
':')
763 *scheme = Malloc(p - url + 1);
764 strncpy(*scheme, url, p - url);
765 (*scheme)[p - url] =
'\0';
771 if(url[0] ==
'/' && url[1] ==
'/')
775 for(p = (
char *)url; *p; p++)
781 for(
q = p-1;
q >= url;
q--)
785 if(
q < p-1 && *
q ==
':')
790 *
host = Malloc(
q - url + 1);
792 (*host)[
q - url] =
'\0';
799 *path = strdup8(url);
801 *path = strdup8(
"/");
805 for(p=*path; *p; p++)
810 WARN1(
LEFILE,
"Warning: illegal backslashes in URL path \"%s\""
811 "replaced by slashes\n", url);