ftp/http stuff should work again. the download menu is still out of action, however.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1734 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
a32c1af46d
commit
054663b990
8 changed files with 161 additions and 98 deletions
|
@ -1,5 +1,10 @@
|
|||
#include "quakedef.h"
|
||||
|
||||
#ifdef WEBCLIENT
|
||||
//#define DOWNLOADMENU
|
||||
#endif
|
||||
|
||||
#ifdef DOWNLOADMENU
|
||||
|
||||
#define ROOTDOWNLOADABLESSOURCE "http://fteqw.sourceforge.net/downloadables.txt"
|
||||
#define INSTALLEDFILES "installed.lst" //the file that resides in the quakedir (saying what's installed).
|
||||
|
@ -13,8 +18,6 @@
|
|||
|
||||
int dlcount=1;
|
||||
|
||||
extern char *com_basedir;
|
||||
|
||||
//note: these are allocated for the life of the exe
|
||||
char *downloadablelist[256] = {
|
||||
ROOTDOWNLOADABLESSOURCE
|
||||
|
@ -51,7 +54,7 @@ typedef struct {
|
|||
package_t *availablepackages;
|
||||
int numpackages;
|
||||
|
||||
static package_t *BuildPackageList(FILE *f, int flags, char *prefix)
|
||||
static package_t *BuildPackageList(vfsfile_t *f, int flags, char *prefix)
|
||||
{
|
||||
char line[1024];
|
||||
package_t *p;
|
||||
|
@ -62,13 +65,14 @@ static package_t *BuildPackageList(FILE *f, int flags, char *prefix)
|
|||
|
||||
do
|
||||
{
|
||||
fgets(line, sizeof(line)-1, f);
|
||||
if (!VFS_GETS(f, line, sizeof(line)-1))
|
||||
break;
|
||||
while((sl=strchr(line, '\n')))
|
||||
*sl = '\0';
|
||||
while((sl=strchr(line, '\r')))
|
||||
*sl = '\0';
|
||||
Cmd_TokenizeString (line, false, false);
|
||||
} while (!feof(f) && !Cmd_Argc());
|
||||
} while (!Cmd_Argc());
|
||||
|
||||
if (strcmp(Cmd_Argv(0), "version"))
|
||||
return NULL; //it's not the right format.
|
||||
|
@ -80,9 +84,9 @@ static package_t *BuildPackageList(FILE *f, int flags, char *prefix)
|
|||
return NULL; //it's not the right version.
|
||||
}
|
||||
|
||||
while(!feof(f))
|
||||
while(1)
|
||||
{
|
||||
if (!fgets(line, sizeof(line)-1, f))
|
||||
if (!VFS_GETS(f, line, sizeof(line)-1))
|
||||
break;
|
||||
while((sl=strchr(line, '\n')))
|
||||
*sl = '\0';
|
||||
|
@ -155,23 +159,27 @@ static package_t *BuildPackageList(FILE *f, int flags, char *prefix)
|
|||
|
||||
static void WriteInstalledPackages(void)
|
||||
{
|
||||
char *s;
|
||||
package_t *p;
|
||||
char *fname = va("%s/%s", com_basedir, INSTALLEDFILES);
|
||||
FILE *f = fopen(fname, "wb");
|
||||
vfsfile_t *f = FS_OpenVFS(INSTALLEDFILES, "wb", FS_BASE);
|
||||
if (!f)
|
||||
{
|
||||
Con_Printf("menu_download: Can't update installed list\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(f, "version 1\n");
|
||||
s = "version 1\n";
|
||||
VFS_WRITE(f, s, strlen(s));
|
||||
for (p = availablepackages; p ; p=p->next)
|
||||
{
|
||||
if (p->flags & DPF_HAVEAVERSION)
|
||||
fprintf(f, "\"%s\" \"%s\" \"%s\" %i \"%s\"\n", p->fullname, p->src, p->dest, p->version, p->gamedir);
|
||||
{
|
||||
s = ("\"%s\" \"%s\" \"%s\" %i \"%s\"\n", p->fullname, p->src, p->dest, p->version, p->gamedir);
|
||||
VFS_WRITE(f, s, strlen(s));
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
VFS_CLOSE(f);
|
||||
}
|
||||
|
||||
static qboolean ComparePackages(package_t **l, package_t *p)
|
||||
|
@ -236,14 +244,14 @@ static void ConcatPackageLists(package_t *l2)
|
|||
static void dlnotification(char *localfile, qboolean sucess)
|
||||
{
|
||||
int i;
|
||||
FILE *f;
|
||||
vfsfile_t *f;
|
||||
COM_RefreshFSCache_f();
|
||||
COM_FOpenFile(localfile, &f);
|
||||
f = FS_OpenVFS (localfile, "rb", FS_BASE);
|
||||
if (f)
|
||||
{
|
||||
i = atoi(localfile+7);
|
||||
ConcatPackageLists(BuildPackageList(f, 0, downloadablelistnameprefix[i]));
|
||||
fclose(f);
|
||||
VFS_CLOSE(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -489,14 +497,20 @@ void Menu_DownloadStuff_f (void)
|
|||
|
||||
{
|
||||
static qboolean loadedinstalled;
|
||||
char *fname = va("%s/%s", com_basedir, INSTALLEDFILES);
|
||||
FILE *f = loadedinstalled?NULL:fopen(fname, "rb");
|
||||
vfsfile_t *f = loadedinstalled?NULL:FS_OpenVFS(INSTALLEDFILES, "rb", FS_BASE);
|
||||
loadedinstalled = true;
|
||||
if (f)
|
||||
{
|
||||
ConcatPackageLists(BuildPackageList(f, DPF_DELETEONUNINSTALL|DPF_HAVEAVERSION|DPF_WANTTOINSTALL, ""));
|
||||
fclose(f);
|
||||
VFS_CLOSE(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif defined(WEBCLIENT)
|
||||
void Menu_DownloadStuff_f (void)
|
||||
{
|
||||
Con_Printf("Not yet reimplemented\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -114,8 +114,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define NQPROT //server and client are capable of using quake1/netquake protocols. (qw is still prefered. uses the command 'nqconnect')
|
||||
#define FISH //sw rendering only
|
||||
#define ZLIB //zip/pk3 support
|
||||
// #define WEBSERVER //http/ftp servers
|
||||
// #define WEBCLIENT //http/ftp clients.
|
||||
#define WEBSERVER //http/ftp servers
|
||||
#define WEBCLIENT //http/ftp clients.
|
||||
#define RUNTIMELIGHTING //calculate lit/lux files the first time the map is loaded and doesn't have a loadable lit.
|
||||
// #define QTERM //qterm... adds a console command that allows running programs from within quake - bit like xterm.
|
||||
#define CL_MASTER //query master servers and stuff for a dynamic server listing.
|
||||
|
|
|
@ -307,6 +307,7 @@ typedef struct vfsfile_s {
|
|||
unsigned long (*Tell) (struct vfsfile_s *file);
|
||||
unsigned long (*GetLen) (struct vfsfile_s *file); //could give some lag
|
||||
void (*Close) (struct vfsfile_s *file);
|
||||
void (*Flush) (struct vfsfile_s *file);
|
||||
} vfsfile_t;
|
||||
|
||||
#define VFS_CLOSE(vf) (vf->Close(vf))
|
||||
|
@ -315,8 +316,8 @@ typedef struct vfsfile_s {
|
|||
#define VFS_SEEK(vf,pos) (vf->Seek(vf,pos))
|
||||
#define VFS_READ(vf,buffer,buflen) (vf->ReadBytes(vf,buffer,buflen))
|
||||
#define VFS_WRITE(vf,buffer,buflen) (vf->WriteBytes(vf,buffer,buflen))
|
||||
#define VFS_FLUSH(vf)
|
||||
#define VFS_GETS(vf,buffer,buflen) Sys_Error("VFS_GETS not implemented"),false //:(
|
||||
#define VFS_FLUSH(vf) do{if(vf->Flush)vf->Flush(vf);}while(0)
|
||||
#define VFS_GETS(vf,buffer,buflen) (Sys_Error("VFS_GETS not implemented"),false) //:(
|
||||
|
||||
void FS_Remove(char *fname, int relativeto);
|
||||
vfsfile_t *FS_OpenVFS(char *filename, char *mode, int relativeto);
|
||||
|
|
|
@ -234,7 +234,7 @@ iwboolean FTP_ClientConnThink (FTPclientconn_t *con) //true to kill con
|
|||
}
|
||||
while((len = recv(con->datasock, readdata, sizeof(readdata), 0)) >0 )
|
||||
{
|
||||
IWebFWrite(readdata, len, 1, con->f);
|
||||
VFS_WRITE(con->f, readdata, len);
|
||||
con->transfered += len;
|
||||
}
|
||||
if (len == 0)
|
||||
|
@ -248,14 +248,14 @@ iwboolean FTP_ClientConnThink (FTPclientconn_t *con) //true to kill con
|
|||
int pos, sent;
|
||||
int ammount, wanted = sizeof(readdata);
|
||||
|
||||
pos = IWebFTell(con->f);
|
||||
ammount = IWebFRead(readdata, 1, wanted, con->f);
|
||||
pos = VFS_TELL(con->f);
|
||||
ammount = VFS_READ(con->f, readdata, wanted);
|
||||
sent = send(con->datasock, readdata, ammount, 0);
|
||||
if (sent == -1)
|
||||
IWebFSeek(con->f, pos, SEEK_SET); //go back. Too much data
|
||||
VFS_SEEK(con->f, pos); //go back. Too much data
|
||||
else
|
||||
{
|
||||
IWebFSeek(con->f, pos + sent, SEEK_SET); //written this much
|
||||
VFS_SEEK(con->f, pos + sent); //written this much
|
||||
|
||||
if (!ammount) //file is over
|
||||
{
|
||||
|
@ -380,7 +380,7 @@ iwboolean FTP_ClientConnThink (FTPclientconn_t *con) //true to kill con
|
|||
con->stage = 6;
|
||||
if (con->type == ftp_getting)
|
||||
{
|
||||
con->f = IWebFOpenWrite(con->localfile, false);
|
||||
con->f = FS_OpenVFS(con->localfile, "wb", FS_GAME);
|
||||
if (con->f)
|
||||
{
|
||||
sprintf(tempbuff, "RETR %s\r\n", con->file);
|
||||
|
@ -396,7 +396,7 @@ iwboolean FTP_ClientConnThink (FTPclientconn_t *con) //true to kill con
|
|||
}
|
||||
else if (con->type == ftp_putting)
|
||||
{
|
||||
con->f = IWebFOpenRead(con->localfile);
|
||||
con->f = FS_OpenVFS (con->localfile, "rb", FS_GAME);
|
||||
if (con->f)
|
||||
{
|
||||
sprintf(tempbuff, "STOR %s\r\n", con->file);
|
||||
|
@ -438,7 +438,7 @@ usepasv:
|
|||
{
|
||||
COM_StripExtension(con->localfile, msg);
|
||||
strcat(msg, ".tmp");
|
||||
con->f = IWebFOpenWrite(msg, false);
|
||||
con->f = FS_OpenVFS (msg, "wb", FS_GAME);
|
||||
if (!con->f)
|
||||
{
|
||||
msg = va("ABOR\r\nQUIT\r\n"); //bummer. we couldn't open this file to output to.
|
||||
|
@ -472,10 +472,10 @@ usepasv:
|
|||
}
|
||||
con->transfered+=len;
|
||||
data[len] = 0;
|
||||
IWebFWrite(data, len, 1, con->f);
|
||||
VFS_WRITE(con->f, data, len);
|
||||
}
|
||||
}
|
||||
IWebFClose(con->f);
|
||||
VFS_CLOSE(con->f);
|
||||
con->f = NULL;
|
||||
closesocket(con->datasock);
|
||||
con->datasock = INVALID_SOCKET;
|
||||
|
@ -535,7 +535,7 @@ usepasv:
|
|||
{
|
||||
if (con->type == ftp_getting)
|
||||
{
|
||||
con->f = IWebFOpenWrite(con->localfile, false);
|
||||
con->f = FS_OpenVFS(con->localfile, "wb", FS_GAME);
|
||||
if (con->f)
|
||||
{
|
||||
con->stage = 8;
|
||||
|
@ -557,13 +557,13 @@ usepasv:
|
|||
}
|
||||
else if (con->type == ftp_putting)
|
||||
{
|
||||
con->f = IWebFOpenRead(con->localfile);
|
||||
con->f = FS_OpenVFS(con->localfile, "rb", FS_GAME);
|
||||
if (con->f)
|
||||
{
|
||||
msg = va("STOR %s\r\n", con->file);
|
||||
con->stage = 6;
|
||||
con->transfered = 0;
|
||||
con->transfersize = con->f->length;
|
||||
con->transfersize = VFS_GETLEN(con->f);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -642,7 +642,7 @@ void FTP_ClientThink (void)
|
|||
cls.downloadmethod = DL_NONE;
|
||||
}
|
||||
if (con->f)
|
||||
IWebFClose(con->f);
|
||||
VFS_CLOSE(con->f);
|
||||
if (con->controlsock != INVALID_SOCKET)
|
||||
closesocket(con->controlsock);
|
||||
if (con->datasock != INVALID_SOCKET)
|
||||
|
|
|
@ -35,7 +35,7 @@ typedef struct FTPclient_s{
|
|||
int datasock; //FTP only allows one transfer per connection.
|
||||
int dataislisten;
|
||||
int datadir; //0 no data, 1 reading, 2 writing
|
||||
IWEBFILE *file;
|
||||
vfsfile_t *file;
|
||||
|
||||
unsigned long blocking;
|
||||
|
||||
|
@ -238,18 +238,18 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
|
|||
int pos, sent;
|
||||
int ammount, wanted = sizeof(resource);
|
||||
|
||||
pos = IWebFTell(cl->file);
|
||||
ammount = IWebFRead(resource, 1, wanted, cl->file);
|
||||
pos = VFS_TELL(cl->file);
|
||||
ammount = VFS_READ(cl->file, resource, wanted);
|
||||
sent = send(cl->datasock, resource, ammount, 0);
|
||||
|
||||
if (sent == -1)
|
||||
{
|
||||
IWebFSeek(cl->file, pos, SEEK_SET);
|
||||
VFS_SEEK(cl->file, pos);
|
||||
if (qerrno != EWOULDBLOCK)
|
||||
{
|
||||
closesocket(cl->datasock);
|
||||
cl->datasock = INVALID_SOCKET;
|
||||
IWebFClose(cl->file);
|
||||
VFS_CLOSE(cl->file);
|
||||
cl->file = NULL;
|
||||
|
||||
QueueMessage (cl, "226 Transfer complete .\r\n");
|
||||
|
@ -259,7 +259,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
|
|||
else
|
||||
{
|
||||
if (sent != ammount)
|
||||
IWebFSeek(cl->file, pos + sent, SEEK_SET);
|
||||
VFS_SEEK(cl->file, pos + sent);
|
||||
|
||||
if (ammount != wanted && sent == ammount) //file is over
|
||||
{
|
||||
|
@ -268,7 +268,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
|
|||
send(cl->datasock, resource, 0, 0);
|
||||
closesocket(cl->datasock);
|
||||
cl->datasock = INVALID_SOCKET;
|
||||
IWebFClose(cl->file);
|
||||
VFS_CLOSE(cl->file);
|
||||
cl->file = NULL;
|
||||
|
||||
QueueMessage (cl, "226 Transfer complete .\r\n");
|
||||
|
@ -281,7 +281,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
|
|||
int len;
|
||||
while((len = recv(cl->datasock, resource, sizeof(resource), 0)) >0 )
|
||||
{
|
||||
IWebFWrite(resource, len, 1, cl->file);
|
||||
VFS_WRITE(cl->file, resource, len);
|
||||
}
|
||||
if (len == -1)
|
||||
{
|
||||
|
@ -290,7 +290,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
|
|||
closesocket(cl->datasock);
|
||||
cl->datasock = INVALID_SOCKET;
|
||||
if (cl->file)
|
||||
IWebFClose(cl->file);
|
||||
VFS_CLOSE(cl->file);
|
||||
cl->file = NULL;
|
||||
|
||||
QueueMessage (cl, "226 Transfer complete .\r\n");
|
||||
|
@ -300,7 +300,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
|
|||
if (len == 0)
|
||||
{
|
||||
QueueMessage (cl, "226 Transfer complete .\r\n");
|
||||
IWebFClose(cl->file);
|
||||
VFS_CLOSE(cl->file);
|
||||
cl->file = NULL;
|
||||
cl->datadir = 0;
|
||||
}
|
||||
|
@ -586,14 +586,14 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
|
|||
if (*resource == '/')
|
||||
{
|
||||
if (SV_AllowDownload(resource+1))
|
||||
cl->file = IWebFOpenRead(resource+1);
|
||||
cl->file = FS_OpenVFS(resource+1, "rb", FS_GAME);
|
||||
else
|
||||
cl->file = IWebGenerateFile(resource+1, NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SV_AllowDownload(resource))
|
||||
cl->file = IWebFOpenRead(resource);
|
||||
cl->file = FS_OpenVFS(resource, "rb", FS_GAME);
|
||||
else
|
||||
cl->file = IWebGenerateFile(resource, NULL, 0);
|
||||
}
|
||||
|
@ -653,14 +653,14 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
|
|||
else
|
||||
sprintf(resource, "%s%s", cl->path, mode);
|
||||
|
||||
cl->file = IWebFOpenRead(resource);
|
||||
cl->file = FS_OpenVFS(resource, "rb", FS_GAMEONLY);
|
||||
if (cl->file)
|
||||
{
|
||||
IWebFClose(cl->file);
|
||||
VFS_CLOSE(cl->file);
|
||||
QueueMessage (cl, "550 File already exists.\r\n");
|
||||
continue;
|
||||
}
|
||||
cl->file = IWebFOpenWrite(resource, false);
|
||||
cl->file = FS_OpenVFS(resource, "wb", FS_GAME);
|
||||
|
||||
if (!cl->file)
|
||||
{
|
||||
|
@ -726,7 +726,7 @@ unsigned int WINAPI BlockingClient(FTPclient_t *cl)
|
|||
}
|
||||
|
||||
if (cl->file)
|
||||
IWebFClose(cl->file);
|
||||
VFS_CLOSE(cl->file);
|
||||
closesocket(cl->controlsock);
|
||||
if (cl->datasock)
|
||||
closesocket(cl->datasock);
|
||||
|
@ -762,7 +762,7 @@ unsigned long _true = true;
|
|||
if (FTP_ServerThinkForConnection(cl))
|
||||
{
|
||||
if (cl->file)
|
||||
IWebFClose(cl->file);
|
||||
VFS_CLOSE(cl->file);
|
||||
closesocket(cl->controlsock);
|
||||
if (cl->datasock)
|
||||
closesocket(cl->datasock);
|
||||
|
|
|
@ -47,7 +47,7 @@ typedef struct http_con_s {
|
|||
|
||||
int contentlength;
|
||||
|
||||
IWEBFILE *file;
|
||||
vfsfile_t *file;
|
||||
|
||||
void (*NotifyFunction)(char *localfile, qboolean sucess); //called when failed or succeeded, and only if it got a connection in the first place.
|
||||
struct http_con_s *next;
|
||||
|
@ -201,7 +201,7 @@ static qboolean HTTP_CL_Run(http_con_t *con)
|
|||
|
||||
con->bufferused -= ammount;
|
||||
|
||||
con->file = IWebFOpenWrite(con->filename, false);
|
||||
con->file = FS_OpenVFS(con->filename, "wb", FS_GAME);
|
||||
if (!con->file)
|
||||
{
|
||||
Con_Printf("HTTP: Couldn't open file %s\n", con->filename);
|
||||
|
@ -210,7 +210,7 @@ static qboolean HTTP_CL_Run(http_con_t *con)
|
|||
|
||||
if (!con->file)
|
||||
{
|
||||
IWebFWrite(con->buffer+ammount, con->bufferused, 1, con->file);
|
||||
VFS_WRITE(con->file, con->buffer+ammount, con->bufferused);
|
||||
con->bufferused = 0;
|
||||
}
|
||||
else
|
||||
|
@ -281,7 +281,7 @@ static qboolean HTTP_CL_Run(http_con_t *con)
|
|||
con->totalreceived+=con->chunked;
|
||||
if (con->file && con->chunked) //we've got a chunk in the buffer
|
||||
{ //write it
|
||||
IWebFWrite(con->buffer, con->chunked, 1, con->file);
|
||||
VFS_WRITE(con->file, con->buffer, con->chunked);
|
||||
//and move the unparsed chunk to the front.
|
||||
con->bufferused -= con->chunked;
|
||||
memmove(con->buffer, con->buffer+con->chunked, con->bufferused);
|
||||
|
@ -293,7 +293,7 @@ static qboolean HTTP_CL_Run(http_con_t *con)
|
|||
con->totalreceived+=ammount;
|
||||
if (con->file) //we've got a chunk in the buffer
|
||||
{ //write it
|
||||
IWebFWrite(con->buffer, con->bufferused, 1, con->file);
|
||||
VFS_WRITE(con->file, con->buffer, con->bufferused);
|
||||
con->bufferused = 0;
|
||||
}
|
||||
}
|
||||
|
@ -306,7 +306,7 @@ static qboolean HTTP_CL_Run(http_con_t *con)
|
|||
Con_Printf("Recieved file isn't the correct length - must be corrupt - %s\n", con->filename);
|
||||
Con_Printf("Retrieved %s\n", con->filename);
|
||||
if (con->file)
|
||||
IWebFClose(con->file);
|
||||
VFS_CLOSE(con->file);
|
||||
else
|
||||
{
|
||||
snprintf(Location, sizeof(Location)-1, "%s/%s", com_gamedir, con->filename);
|
||||
|
|
|
@ -152,7 +152,7 @@ void HTTP_RunExisting (void)
|
|||
if (cl->outbuffer)
|
||||
IWebFree(cl->outbuffer);
|
||||
if (cl->file)
|
||||
IWebFClose(cl->file);
|
||||
VFS_CLOSE(cl->file);
|
||||
IWebFree(cl);
|
||||
httpconnectioncount--;
|
||||
cl = prev;
|
||||
|
@ -328,7 +328,7 @@ cont:
|
|||
if (!strnicmp(mode, "P", 1)) //when stuff is posted, data is provided. Give an error message if we couldn't do anything with that data.
|
||||
cl->file = IWebGenerateFile(resource+1, content, contentlen);
|
||||
else
|
||||
cl->file = IWebFOpenRead(resource);
|
||||
cl->file = FS_OpenVFS(resource, "rb", FS_GAME);
|
||||
if (!cl->file)
|
||||
{
|
||||
if (HTTPmarkup >= 3)
|
||||
|
@ -349,9 +349,9 @@ cont:
|
|||
else
|
||||
{
|
||||
if (HTTPmarkup>=3)
|
||||
sprintf(resource, "HTTP/1.1 200 OK\r\n" "Content-Type: %s\r\n" "Content-Length: %i\r\n" "Server: "FULLENGINENAME"/0\r\n" "\r\n", strstr(resource, ".htm")?"text/html":"text/plain", cl->file->length);
|
||||
sprintf(resource, "HTTP/1.1 200 OK\r\n" "Content-Type: %s\r\n" "Content-Length: %i\r\n" "Server: "FULLENGINENAME"/0\r\n" "\r\n", strstr(resource, ".htm")?"text/html":"text/plain", VFS_GETLEN(cl->file));
|
||||
else if (HTTPmarkup==2)
|
||||
sprintf(resource, "HTTP/1.0 200 OK\r\n" "Content-Type: %s\r\n" "Content-Length: %i\r\n" "Server: "FULLENGINENAME"/0\r\n" "\r\n", strstr(resource, ".htm")?"text/html":"text/plain", cl->file->length);
|
||||
sprintf(resource, "HTTP/1.0 200 OK\r\n" "Content-Type: %s\r\n" "Content-Length: %i\r\n" "Server: "FULLENGINENAME"/0\r\n" "\r\n", strstr(resource, ".htm")?"text/html":"text/plain", VFS_GETLEN(cl->file));
|
||||
else if (HTTPmarkup)
|
||||
sprintf(resource, "HTTP/0.9 200 OK\r\n\r\n");
|
||||
else
|
||||
|
@ -361,7 +361,7 @@ cont:
|
|||
if (*mode == 'H' || *mode == 'h')
|
||||
{
|
||||
|
||||
IWebFClose(cl->file);
|
||||
VFS_CLOSE(cl->file);
|
||||
cl->file = NULL;
|
||||
}
|
||||
|
||||
|
@ -413,11 +413,11 @@ notimplemented:
|
|||
{
|
||||
ExpandOutBuffer(cl, 1500, true);
|
||||
wanted = cl->outbuffersize - cl->outbufferused;
|
||||
ammount = IWebFRead(cl->outbuffer+cl->outbufferused, 1, wanted, cl->file);
|
||||
ammount = VFS_READ(cl->file, cl->outbuffer+cl->outbufferused, wanted);
|
||||
|
||||
if (!ammount)
|
||||
{
|
||||
IWebFClose(cl->file);
|
||||
VFS_CLOSE(cl->file);
|
||||
cl->file = NULL;
|
||||
}
|
||||
else
|
||||
|
@ -457,7 +457,7 @@ notimplemented:
|
|||
{
|
||||
if (qerrno != EWOULDBLOCK) //they closed on us. Assume end.
|
||||
{
|
||||
IWebFClose(cl->file);
|
||||
VFS_CLOSE(cl->file);
|
||||
cl->file = NULL;
|
||||
cl->close = true;
|
||||
continue;
|
||||
|
|
|
@ -326,13 +326,82 @@ IWebFile_t IWebFiles[] = {
|
|||
|
||||
typedef struct {
|
||||
vfsfile_t funcs;
|
||||
char *buffer;
|
||||
int length;
|
||||
int pos;
|
||||
} vfsmemory_t;
|
||||
|
||||
vfsfile_t *VFSMEM_FromZMalloc(char *buffer, int length)
|
||||
IWeb_FileGen_t *buffer;
|
||||
int pos;
|
||||
} vfsgen_t;
|
||||
|
||||
int VFSGen_ReadBytes(vfsfile_t *f, char *buffer, int bytes)
|
||||
{
|
||||
vfsgen_t *g = (vfsgen_t*)f;
|
||||
if (bytes + g->pos >= g->buffer->len)
|
||||
{
|
||||
bytes = g->buffer->len - g->pos;
|
||||
if (bytes <= 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(buffer, g->buffer->data+g->pos, bytes);
|
||||
g->pos += bytes;
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
int VFSGen_WriteBytes(vfsfile_t *f, char *buffer, int bytes)
|
||||
{
|
||||
Sys_Error("VFSGen_WriteBytes: Readonly\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
qboolean VFSGen_Seek(vfsfile_t *f, unsigned long newpos)
|
||||
{
|
||||
vfsgen_t *g = (vfsgen_t*)f;
|
||||
if (newpos < 0 || newpos >= g->buffer->len)
|
||||
return false;
|
||||
|
||||
g->pos = newpos;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int VFSGen_Tell(vfsfile_t *f)
|
||||
{
|
||||
vfsgen_t *g = (vfsgen_t*)f;
|
||||
return g->pos;
|
||||
}
|
||||
|
||||
int VFSGen_GetLen(vfsfile_t *f)
|
||||
{
|
||||
vfsgen_t *g = (vfsgen_t*)f;
|
||||
return g->buffer->len;
|
||||
}
|
||||
|
||||
void VFSGen_Close(vfsfile_t *f)
|
||||
{
|
||||
vfsgen_t *g = (vfsgen_t*)f;
|
||||
g->buffer->references--;
|
||||
if (!g->buffer->references)
|
||||
{
|
||||
Z_Free(g->buffer->data);
|
||||
Z_Free(g->buffer);
|
||||
}
|
||||
Z_Free(g);
|
||||
}
|
||||
|
||||
|
||||
vfsfile_t *VFSGen_Create(IWeb_FileGen_t *gen)
|
||||
{
|
||||
vfsgen_t *ret;
|
||||
ret = Z_Malloc(sizeof(vfsgen_t));
|
||||
|
||||
ret->funcs.ReadBytes = VFSGen_ReadBytes;
|
||||
ret->funcs.WriteBytes = VFSGen_WriteBytes;
|
||||
ret->funcs.Seek = VFSGen_Seek;
|
||||
ret->funcs.Tell = VFSGen_Tell;
|
||||
ret->funcs.GetLen = VFSGen_GetLen;
|
||||
ret->funcs.Close = VFSGen_Close;
|
||||
|
||||
return (vfsfile_t*)ret;
|
||||
}
|
||||
|
||||
vfsfile_t *IWebGenerateFile(char *name, char *content, int contentlength)
|
||||
|
@ -346,7 +415,7 @@ vfsfile_t *IWebGenerateFile(char *name, char *content, int contentlength)
|
|||
|
||||
if (*lastrecordedmvd && !strcmp(name, "lastdemo.mvd"))
|
||||
if (strcmp(name, "lastdemo.mvd")) //no infinate loops please...
|
||||
return IWebFOpenRead(lastrecordedmvd);
|
||||
return FS_OpenVFS(lastrecordedmvd, "rb", FS_GAME);
|
||||
|
||||
parms = strchr(name, '?');
|
||||
if (!parms)
|
||||
|
@ -363,7 +432,6 @@ vfsfile_t *IWebGenerateFile(char *name, char *content, int contentlength)
|
|||
{
|
||||
if (!Q_strncasecmp(name, IWebFiles[fnum].name, len+1))
|
||||
{
|
||||
IWEBFILE *ret;
|
||||
if (IWebFiles[fnum].buffer)
|
||||
{
|
||||
if (IWebFiles[fnum].lastgenerationtime+10 < Sys_DoubleTime() || contentlength||*parms) //10 sec lifetime
|
||||
|
@ -383,33 +451,13 @@ vfsfile_t *IWebGenerateFile(char *name, char *content, int contentlength)
|
|||
IWebFiles[fnum].GenerationFunction(parms, content, contentlength);
|
||||
IWebFiles[fnum].buffer = IWeb_GenerationBuffer;
|
||||
|
||||
if (!contentlength)
|
||||
{
|
||||
IWeb_GenerationBuffer->references++; //so it can't be sent once and freed instantly.
|
||||
IWebFiles[fnum].lastgenerationtime = Sys_DoubleTime();
|
||||
}
|
||||
else
|
||||
IWebFiles[fnum].lastgenerationtime = -10;
|
||||
}
|
||||
|
||||
ret = VFSMEM_FromZMalloc
|
||||
ret = IWebMalloc(sizeof(vfsfile_t));
|
||||
if (!ret)
|
||||
{
|
||||
BZ_Free(IWeb_GenerationBuffer);
|
||||
return NULL;
|
||||
//so it can't be sent once and freed instantly.
|
||||
IWebFiles[fnum].lastgenerationtime = Sys_DoubleTime();
|
||||
}
|
||||
ret->f = NULL;
|
||||
ret->bufferdata = IWebFiles[fnum].buffer;
|
||||
ret->length = ret->bufferdata->len;
|
||||
ret->bufferdata->references++;
|
||||
ret->pos = 0;
|
||||
ret->start = 0;
|
||||
ret->end = ret->start+ret->length;
|
||||
|
||||
IWebFiles[fnum].buffer->references++;
|
||||
IWeb_GenerationBuffer = NULL;
|
||||
|
||||
return ret;
|
||||
return VFSGen_Create(IWebFiles[fnum].buffer);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
|
Loading…
Reference in a new issue