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:
Spoike 2005-12-22 02:29:11 +00:00
parent a32c1af46d
commit 054663b990
8 changed files with 161 additions and 98 deletions

View file

@ -1,5 +1,10 @@
#include "quakedef.h" #include "quakedef.h"
#ifdef WEBCLIENT #ifdef WEBCLIENT
//#define DOWNLOADMENU
#endif
#ifdef DOWNLOADMENU
#define ROOTDOWNLOADABLESSOURCE "http://fteqw.sourceforge.net/downloadables.txt" #define ROOTDOWNLOADABLESSOURCE "http://fteqw.sourceforge.net/downloadables.txt"
#define INSTALLEDFILES "installed.lst" //the file that resides in the quakedir (saying what's installed). #define INSTALLEDFILES "installed.lst" //the file that resides in the quakedir (saying what's installed).
@ -13,8 +18,6 @@
int dlcount=1; int dlcount=1;
extern char *com_basedir;
//note: these are allocated for the life of the exe //note: these are allocated for the life of the exe
char *downloadablelist[256] = { char *downloadablelist[256] = {
ROOTDOWNLOADABLESSOURCE ROOTDOWNLOADABLESSOURCE
@ -51,7 +54,7 @@ typedef struct {
package_t *availablepackages; package_t *availablepackages;
int numpackages; 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]; char line[1024];
package_t *p; package_t *p;
@ -62,13 +65,14 @@ static package_t *BuildPackageList(FILE *f, int flags, char *prefix)
do do
{ {
fgets(line, sizeof(line)-1, f); if (!VFS_GETS(f, line, sizeof(line)-1))
break;
while((sl=strchr(line, '\n'))) while((sl=strchr(line, '\n')))
*sl = '\0'; *sl = '\0';
while((sl=strchr(line, '\r'))) while((sl=strchr(line, '\r')))
*sl = '\0'; *sl = '\0';
Cmd_TokenizeString (line, false, false); Cmd_TokenizeString (line, false, false);
} while (!feof(f) && !Cmd_Argc()); } while (!Cmd_Argc());
if (strcmp(Cmd_Argv(0), "version")) if (strcmp(Cmd_Argv(0), "version"))
return NULL; //it's not the right format. 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. 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; break;
while((sl=strchr(line, '\n'))) while((sl=strchr(line, '\n')))
*sl = '\0'; *sl = '\0';
@ -155,23 +159,27 @@ static package_t *BuildPackageList(FILE *f, int flags, char *prefix)
static void WriteInstalledPackages(void) static void WriteInstalledPackages(void)
{ {
char *s;
package_t *p; package_t *p;
char *fname = va("%s/%s", com_basedir, INSTALLEDFILES); vfsfile_t *f = FS_OpenVFS(INSTALLEDFILES, "wb", FS_BASE);
FILE *f = fopen(fname, "wb");
if (!f) if (!f)
{ {
Con_Printf("menu_download: Can't update installed list\n"); Con_Printf("menu_download: Can't update installed list\n");
return; return;
} }
fprintf(f, "version 1\n"); s = "version 1\n";
VFS_WRITE(f, s, strlen(s));
for (p = availablepackages; p ; p=p->next) for (p = availablepackages; p ; p=p->next)
{ {
if (p->flags & DPF_HAVEAVERSION) 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) 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) static void dlnotification(char *localfile, qboolean sucess)
{ {
int i; int i;
FILE *f; vfsfile_t *f;
COM_RefreshFSCache_f(); COM_RefreshFSCache_f();
COM_FOpenFile(localfile, &f); f = FS_OpenVFS (localfile, "rb", FS_BASE);
if (f) if (f)
{ {
i = atoi(localfile+7); i = atoi(localfile+7);
ConcatPackageLists(BuildPackageList(f, 0, downloadablelistnameprefix[i])); ConcatPackageLists(BuildPackageList(f, 0, downloadablelistnameprefix[i]));
fclose(f); VFS_CLOSE(f);
} }
} }
@ -489,14 +497,20 @@ void Menu_DownloadStuff_f (void)
{ {
static qboolean loadedinstalled; static qboolean loadedinstalled;
char *fname = va("%s/%s", com_basedir, INSTALLEDFILES); vfsfile_t *f = loadedinstalled?NULL:FS_OpenVFS(INSTALLEDFILES, "rb", FS_BASE);
FILE *f = loadedinstalled?NULL:fopen(fname, "rb");
loadedinstalled = true; loadedinstalled = true;
if (f) if (f)
{ {
ConcatPackageLists(BuildPackageList(f, DPF_DELETEONUNINSTALL|DPF_HAVEAVERSION|DPF_WANTTOINSTALL, "")); 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 #endif

View file

@ -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 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 FISH //sw rendering only
#define ZLIB //zip/pk3 support #define ZLIB //zip/pk3 support
// #define WEBSERVER //http/ftp servers #define WEBSERVER //http/ftp servers
// #define WEBCLIENT //http/ftp clients. #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 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 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. #define CL_MASTER //query master servers and stuff for a dynamic server listing.

View file

@ -307,6 +307,7 @@ typedef struct vfsfile_s {
unsigned long (*Tell) (struct vfsfile_s *file); unsigned long (*Tell) (struct vfsfile_s *file);
unsigned long (*GetLen) (struct vfsfile_s *file); //could give some lag unsigned long (*GetLen) (struct vfsfile_s *file); //could give some lag
void (*Close) (struct vfsfile_s *file); void (*Close) (struct vfsfile_s *file);
void (*Flush) (struct vfsfile_s *file);
} vfsfile_t; } vfsfile_t;
#define VFS_CLOSE(vf) (vf->Close(vf)) #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_SEEK(vf,pos) (vf->Seek(vf,pos))
#define VFS_READ(vf,buffer,buflen) (vf->ReadBytes(vf,buffer,buflen)) #define VFS_READ(vf,buffer,buflen) (vf->ReadBytes(vf,buffer,buflen))
#define VFS_WRITE(vf,buffer,buflen) (vf->WriteBytes(vf,buffer,buflen)) #define VFS_WRITE(vf,buffer,buflen) (vf->WriteBytes(vf,buffer,buflen))
#define VFS_FLUSH(vf) #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 //:( #define VFS_GETS(vf,buffer,buflen) (Sys_Error("VFS_GETS not implemented"),false) //:(
void FS_Remove(char *fname, int relativeto); void FS_Remove(char *fname, int relativeto);
vfsfile_t *FS_OpenVFS(char *filename, char *mode, int relativeto); vfsfile_t *FS_OpenVFS(char *filename, char *mode, int relativeto);

View file

@ -234,7 +234,7 @@ iwboolean FTP_ClientConnThink (FTPclientconn_t *con) //true to kill con
} }
while((len = recv(con->datasock, readdata, sizeof(readdata), 0)) >0 ) 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; con->transfered += len;
} }
if (len == 0) if (len == 0)
@ -248,14 +248,14 @@ iwboolean FTP_ClientConnThink (FTPclientconn_t *con) //true to kill con
int pos, sent; int pos, sent;
int ammount, wanted = sizeof(readdata); int ammount, wanted = sizeof(readdata);
pos = IWebFTell(con->f); pos = VFS_TELL(con->f);
ammount = IWebFRead(readdata, 1, wanted, con->f); ammount = VFS_READ(con->f, readdata, wanted);
sent = send(con->datasock, readdata, ammount, 0); sent = send(con->datasock, readdata, ammount, 0);
if (sent == -1) 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 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 if (!ammount) //file is over
{ {
@ -380,7 +380,7 @@ iwboolean FTP_ClientConnThink (FTPclientconn_t *con) //true to kill con
con->stage = 6; con->stage = 6;
if (con->type == ftp_getting) if (con->type == ftp_getting)
{ {
con->f = IWebFOpenWrite(con->localfile, false); con->f = FS_OpenVFS(con->localfile, "wb", FS_GAME);
if (con->f) if (con->f)
{ {
sprintf(tempbuff, "RETR %s\r\n", con->file); 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) else if (con->type == ftp_putting)
{ {
con->f = IWebFOpenRead(con->localfile); con->f = FS_OpenVFS (con->localfile, "rb", FS_GAME);
if (con->f) if (con->f)
{ {
sprintf(tempbuff, "STOR %s\r\n", con->file); sprintf(tempbuff, "STOR %s\r\n", con->file);
@ -438,7 +438,7 @@ usepasv:
{ {
COM_StripExtension(con->localfile, msg); COM_StripExtension(con->localfile, msg);
strcat(msg, ".tmp"); strcat(msg, ".tmp");
con->f = IWebFOpenWrite(msg, false); con->f = FS_OpenVFS (msg, "wb", FS_GAME);
if (!con->f) if (!con->f)
{ {
msg = va("ABOR\r\nQUIT\r\n"); //bummer. we couldn't open this file to output to. 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; con->transfered+=len;
data[len] = 0; 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; con->f = NULL;
closesocket(con->datasock); closesocket(con->datasock);
con->datasock = INVALID_SOCKET; con->datasock = INVALID_SOCKET;
@ -535,7 +535,7 @@ usepasv:
{ {
if (con->type == ftp_getting) if (con->type == ftp_getting)
{ {
con->f = IWebFOpenWrite(con->localfile, false); con->f = FS_OpenVFS(con->localfile, "wb", FS_GAME);
if (con->f) if (con->f)
{ {
con->stage = 8; con->stage = 8;
@ -557,13 +557,13 @@ usepasv:
} }
else if (con->type == ftp_putting) else if (con->type == ftp_putting)
{ {
con->f = IWebFOpenRead(con->localfile); con->f = FS_OpenVFS(con->localfile, "rb", FS_GAME);
if (con->f) if (con->f)
{ {
msg = va("STOR %s\r\n", con->file); msg = va("STOR %s\r\n", con->file);
con->stage = 6; con->stage = 6;
con->transfered = 0; con->transfered = 0;
con->transfersize = con->f->length; con->transfersize = VFS_GETLEN(con->f);
} }
else else
{ {
@ -642,7 +642,7 @@ void FTP_ClientThink (void)
cls.downloadmethod = DL_NONE; cls.downloadmethod = DL_NONE;
} }
if (con->f) if (con->f)
IWebFClose(con->f); VFS_CLOSE(con->f);
if (con->controlsock != INVALID_SOCKET) if (con->controlsock != INVALID_SOCKET)
closesocket(con->controlsock); closesocket(con->controlsock);
if (con->datasock != INVALID_SOCKET) if (con->datasock != INVALID_SOCKET)

View file

@ -35,7 +35,7 @@ typedef struct FTPclient_s{
int datasock; //FTP only allows one transfer per connection. int datasock; //FTP only allows one transfer per connection.
int dataislisten; int dataislisten;
int datadir; //0 no data, 1 reading, 2 writing int datadir; //0 no data, 1 reading, 2 writing
IWEBFILE *file; vfsfile_t *file;
unsigned long blocking; unsigned long blocking;
@ -238,18 +238,18 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
int pos, sent; int pos, sent;
int ammount, wanted = sizeof(resource); int ammount, wanted = sizeof(resource);
pos = IWebFTell(cl->file); pos = VFS_TELL(cl->file);
ammount = IWebFRead(resource, 1, wanted, cl->file); ammount = VFS_READ(cl->file, resource, wanted);
sent = send(cl->datasock, resource, ammount, 0); sent = send(cl->datasock, resource, ammount, 0);
if (sent == -1) if (sent == -1)
{ {
IWebFSeek(cl->file, pos, SEEK_SET); VFS_SEEK(cl->file, pos);
if (qerrno != EWOULDBLOCK) if (qerrno != EWOULDBLOCK)
{ {
closesocket(cl->datasock); closesocket(cl->datasock);
cl->datasock = INVALID_SOCKET; cl->datasock = INVALID_SOCKET;
IWebFClose(cl->file); VFS_CLOSE(cl->file);
cl->file = NULL; cl->file = NULL;
QueueMessage (cl, "226 Transfer complete .\r\n"); QueueMessage (cl, "226 Transfer complete .\r\n");
@ -259,7 +259,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
else else
{ {
if (sent != ammount) if (sent != ammount)
IWebFSeek(cl->file, pos + sent, SEEK_SET); VFS_SEEK(cl->file, pos + sent);
if (ammount != wanted && sent == ammount) //file is over if (ammount != wanted && sent == ammount) //file is over
{ {
@ -268,7 +268,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
send(cl->datasock, resource, 0, 0); send(cl->datasock, resource, 0, 0);
closesocket(cl->datasock); closesocket(cl->datasock);
cl->datasock = INVALID_SOCKET; cl->datasock = INVALID_SOCKET;
IWebFClose(cl->file); VFS_CLOSE(cl->file);
cl->file = NULL; cl->file = NULL;
QueueMessage (cl, "226 Transfer complete .\r\n"); QueueMessage (cl, "226 Transfer complete .\r\n");
@ -281,7 +281,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
int len; int len;
while((len = recv(cl->datasock, resource, sizeof(resource), 0)) >0 ) 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) if (len == -1)
{ {
@ -290,7 +290,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
closesocket(cl->datasock); closesocket(cl->datasock);
cl->datasock = INVALID_SOCKET; cl->datasock = INVALID_SOCKET;
if (cl->file) if (cl->file)
IWebFClose(cl->file); VFS_CLOSE(cl->file);
cl->file = NULL; cl->file = NULL;
QueueMessage (cl, "226 Transfer complete .\r\n"); QueueMessage (cl, "226 Transfer complete .\r\n");
@ -300,7 +300,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
if (len == 0) if (len == 0)
{ {
QueueMessage (cl, "226 Transfer complete .\r\n"); QueueMessage (cl, "226 Transfer complete .\r\n");
IWebFClose(cl->file); VFS_CLOSE(cl->file);
cl->file = NULL; cl->file = NULL;
cl->datadir = 0; cl->datadir = 0;
} }
@ -586,14 +586,14 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
if (*resource == '/') if (*resource == '/')
{ {
if (SV_AllowDownload(resource+1)) if (SV_AllowDownload(resource+1))
cl->file = IWebFOpenRead(resource+1); cl->file = FS_OpenVFS(resource+1, "rb", FS_GAME);
else else
cl->file = IWebGenerateFile(resource+1, NULL, 0); cl->file = IWebGenerateFile(resource+1, NULL, 0);
} }
else else
{ {
if (SV_AllowDownload(resource)) if (SV_AllowDownload(resource))
cl->file = IWebFOpenRead(resource); cl->file = FS_OpenVFS(resource, "rb", FS_GAME);
else else
cl->file = IWebGenerateFile(resource, NULL, 0); cl->file = IWebGenerateFile(resource, NULL, 0);
} }
@ -653,14 +653,14 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
else else
sprintf(resource, "%s%s", cl->path, mode); sprintf(resource, "%s%s", cl->path, mode);
cl->file = IWebFOpenRead(resource); cl->file = FS_OpenVFS(resource, "rb", FS_GAMEONLY);
if (cl->file) if (cl->file)
{ {
IWebFClose(cl->file); VFS_CLOSE(cl->file);
QueueMessage (cl, "550 File already exists.\r\n"); QueueMessage (cl, "550 File already exists.\r\n");
continue; continue;
} }
cl->file = IWebFOpenWrite(resource, false); cl->file = FS_OpenVFS(resource, "wb", FS_GAME);
if (!cl->file) if (!cl->file)
{ {
@ -726,7 +726,7 @@ unsigned int WINAPI BlockingClient(FTPclient_t *cl)
} }
if (cl->file) if (cl->file)
IWebFClose(cl->file); VFS_CLOSE(cl->file);
closesocket(cl->controlsock); closesocket(cl->controlsock);
if (cl->datasock) if (cl->datasock)
closesocket(cl->datasock); closesocket(cl->datasock);
@ -762,7 +762,7 @@ unsigned long _true = true;
if (FTP_ServerThinkForConnection(cl)) if (FTP_ServerThinkForConnection(cl))
{ {
if (cl->file) if (cl->file)
IWebFClose(cl->file); VFS_CLOSE(cl->file);
closesocket(cl->controlsock); closesocket(cl->controlsock);
if (cl->datasock) if (cl->datasock)
closesocket(cl->datasock); closesocket(cl->datasock);

View file

@ -47,7 +47,7 @@ typedef struct http_con_s {
int contentlength; 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. 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; struct http_con_s *next;
@ -201,7 +201,7 @@ static qboolean HTTP_CL_Run(http_con_t *con)
con->bufferused -= ammount; con->bufferused -= ammount;
con->file = IWebFOpenWrite(con->filename, false); con->file = FS_OpenVFS(con->filename, "wb", FS_GAME);
if (!con->file) if (!con->file)
{ {
Con_Printf("HTTP: Couldn't open file %s\n", con->filename); 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) if (!con->file)
{ {
IWebFWrite(con->buffer+ammount, con->bufferused, 1, con->file); VFS_WRITE(con->file, con->buffer+ammount, con->bufferused);
con->bufferused = 0; con->bufferused = 0;
} }
else else
@ -281,7 +281,7 @@ static qboolean HTTP_CL_Run(http_con_t *con)
con->totalreceived+=con->chunked; con->totalreceived+=con->chunked;
if (con->file && con->chunked) //we've got a chunk in the buffer if (con->file && con->chunked) //we've got a chunk in the buffer
{ //write it { //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. //and move the unparsed chunk to the front.
con->bufferused -= con->chunked; con->bufferused -= con->chunked;
memmove(con->buffer, con->buffer+con->chunked, con->bufferused); 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; con->totalreceived+=ammount;
if (con->file) //we've got a chunk in the buffer if (con->file) //we've got a chunk in the buffer
{ //write it { //write it
IWebFWrite(con->buffer, con->bufferused, 1, con->file); VFS_WRITE(con->file, con->buffer, con->bufferused);
con->bufferused = 0; 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("Recieved file isn't the correct length - must be corrupt - %s\n", con->filename);
Con_Printf("Retrieved %s\n", con->filename); Con_Printf("Retrieved %s\n", con->filename);
if (con->file) if (con->file)
IWebFClose(con->file); VFS_CLOSE(con->file);
else else
{ {
snprintf(Location, sizeof(Location)-1, "%s/%s", com_gamedir, con->filename); snprintf(Location, sizeof(Location)-1, "%s/%s", com_gamedir, con->filename);

View file

@ -152,7 +152,7 @@ void HTTP_RunExisting (void)
if (cl->outbuffer) if (cl->outbuffer)
IWebFree(cl->outbuffer); IWebFree(cl->outbuffer);
if (cl->file) if (cl->file)
IWebFClose(cl->file); VFS_CLOSE(cl->file);
IWebFree(cl); IWebFree(cl);
httpconnectioncount--; httpconnectioncount--;
cl = prev; 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. 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); cl->file = IWebGenerateFile(resource+1, content, contentlen);
else else
cl->file = IWebFOpenRead(resource); cl->file = FS_OpenVFS(resource, "rb", FS_GAME);
if (!cl->file) if (!cl->file)
{ {
if (HTTPmarkup >= 3) if (HTTPmarkup >= 3)
@ -349,9 +349,9 @@ cont:
else else
{ {
if (HTTPmarkup>=3) 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) 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) else if (HTTPmarkup)
sprintf(resource, "HTTP/0.9 200 OK\r\n\r\n"); sprintf(resource, "HTTP/0.9 200 OK\r\n\r\n");
else else
@ -361,7 +361,7 @@ cont:
if (*mode == 'H' || *mode == 'h') if (*mode == 'H' || *mode == 'h')
{ {
IWebFClose(cl->file); VFS_CLOSE(cl->file);
cl->file = NULL; cl->file = NULL;
} }
@ -413,11 +413,11 @@ notimplemented:
{ {
ExpandOutBuffer(cl, 1500, true); ExpandOutBuffer(cl, 1500, true);
wanted = cl->outbuffersize - cl->outbufferused; 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) if (!ammount)
{ {
IWebFClose(cl->file); VFS_CLOSE(cl->file);
cl->file = NULL; cl->file = NULL;
} }
else else
@ -457,7 +457,7 @@ notimplemented:
{ {
if (qerrno != EWOULDBLOCK) //they closed on us. Assume end. if (qerrno != EWOULDBLOCK) //they closed on us. Assume end.
{ {
IWebFClose(cl->file); VFS_CLOSE(cl->file);
cl->file = NULL; cl->file = NULL;
cl->close = true; cl->close = true;
continue; continue;

View file

@ -326,13 +326,82 @@ IWebFile_t IWebFiles[] = {
typedef struct { typedef struct {
vfsfile_t funcs; 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) 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 (*lastrecordedmvd && !strcmp(name, "lastdemo.mvd"))
if (strcmp(name, "lastdemo.mvd")) //no infinate loops please... if (strcmp(name, "lastdemo.mvd")) //no infinate loops please...
return IWebFOpenRead(lastrecordedmvd); return FS_OpenVFS(lastrecordedmvd, "rb", FS_GAME);
parms = strchr(name, '?'); parms = strchr(name, '?');
if (!parms) if (!parms)
@ -363,7 +432,6 @@ vfsfile_t *IWebGenerateFile(char *name, char *content, int contentlength)
{ {
if (!Q_strncasecmp(name, IWebFiles[fnum].name, len+1)) if (!Q_strncasecmp(name, IWebFiles[fnum].name, len+1))
{ {
IWEBFILE *ret;
if (IWebFiles[fnum].buffer) if (IWebFiles[fnum].buffer)
{ {
if (IWebFiles[fnum].lastgenerationtime+10 < Sys_DoubleTime() || contentlength||*parms) //10 sec lifetime 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].GenerationFunction(parms, content, contentlength);
IWebFiles[fnum].buffer = IWeb_GenerationBuffer; IWebFiles[fnum].buffer = IWeb_GenerationBuffer;
if (!contentlength) //so it can't be sent once and freed instantly.
{
IWeb_GenerationBuffer->references++; //so it can't be sent once and freed instantly.
IWebFiles[fnum].lastgenerationtime = Sys_DoubleTime(); IWebFiles[fnum].lastgenerationtime = Sys_DoubleTime();
} }
else IWebFiles[fnum].buffer->references++;
IWebFiles[fnum].lastgenerationtime = -10;
}
ret = VFSMEM_FromZMalloc
ret = IWebMalloc(sizeof(vfsfile_t));
if (!ret)
{
BZ_Free(IWeb_GenerationBuffer);
return NULL;
}
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;
IWeb_GenerationBuffer = NULL; IWeb_GenerationBuffer = NULL;
return ret; return VFSGen_Create(IWebFiles[fnum].buffer);
} }
} }
return NULL; return NULL;