fteqw/engine/server/sv_sys_unix.c
Spoike ce3c561cfe CSQC is standard now, and secure via the same md4 as a map currently has.
Particle system functions renamed a bit, a few other cleanups in that area.
Console handling tweeked. Better rules for subconsoles and plugins. Commands are coloured if it'll be execed, which should help reduce occurences of chat being commands. tab compleation tweeked, partial compleation no longer changes the suggestion.


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@895 fc73d0e0-1445-4013-8a0c-d673dee63da5
2005-03-10 03:55:18 +00:00

463 lines
8 KiB
C

/*
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <sys/types.h>
#include "qwsvdef.h"
#undef malloc
#ifdef NeXT
#include <libc.h>
#endif
#if defined(__linux__) || defined(sun) || defined(__CYGWIN__)
#include <sys/stat.h>
#include <unistd.h>
#include <sys/time.h>
#include <errno.h>
#include <fcntl.h>
#else
#include <sys/dir.h>
#endif
cvar_t sys_nostdout = {"sys_nostdout","0"};
cvar_t sys_extrasleep = {"sys_extrasleep","0"};
qboolean stdin_ready;
/*
===============================================================================
REQUIRED SYS FUNCTIONS
===============================================================================
*/
/*
============
Sys_FileTime
returns -1 if not present
============
*/
int Sys_FileTime (char *path)
{
struct stat buf;
if (stat (path,&buf) == -1)
return -1;
return buf.st_mtime;
}
/*
============
Sys_mkdir
============
*/
void Sys_mkdir (char *path)
{
if (mkdir (path, 0777) != -1)
return;
if (errno != EEXIST)
Sys_Error ("mkdir %s: %s",path, strerror(errno));
}
qboolean Sys_remove (char *path)
{
return system(va("rm \"%s\"", path));
}
#ifdef SHADERS
int Sys_EnumerateFiles (char *gpath, char *match, int (*func)(char *, int, void *), void *parm)
{
#include <dirent.h>
DIR *dir;
struct dirent *ent;
dir = opendir(gpath);
if (!dir)
{
Con_Printf("Failed to open dir");
return true;
}
do
{
ent = readdir(dir); //FIXME: no wild card comparisons.
if (!ent)
break;
if (*ent->d_name != '.')
if (!func(ent->d_name, -2, parm))
{
closedir(dir);
return false;
}
} while(1);
closedir(dir);
return true;
}
#endif
void Sys_DebugLog(char *file, char *fmt, ...)
{
va_list argptr;
char data[1024];
int fd;
va_start(argptr, fmt);
_vsnprintf (data,sizeof(data)-1, fmt, argptr);
va_end(argptr);
if (strlen(data) >= sizeof(data)-1)
Sys_Error("Sys_DebugLog was stomped\n");
fd = open(file, O_WRONLY | O_CREAT | O_APPEND, 0666);
write(fd, data, strlen(data));
close(fd);
}
/*
================
Sys_DoubleTime
================
*/
double Sys_DoubleTime (void)
{
struct timeval tp;
struct timezone tzp;
static int secbase;
gettimeofday(&tp, &tzp);
if (!secbase)
{
secbase = tp.tv_sec;
return tp.tv_usec/1000000.0;
}
return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0;
}
/*
================
Sys_Error
================
*/
void Sys_Error (const char *error, ...)
{
va_list argptr;
char string[1024];
va_start (argptr,error);
_vsnprintf (string,sizeof(string)-1, error,argptr);
va_end (argptr);
printf ("Fatal error: %s\n",string);
*(int*)-3 = 0;
exit (1);
}
/*
================
Sys_Printf
================
*/
void Sys_Printf (char *fmt, ...)
{
va_list argptr;
static char text[2048];
unsigned char *p;
va_start (argptr,fmt);
_vsnprintf (text,sizeof(text)-1, fmt,argptr);
va_end (argptr);
if (strlen(text) > sizeof(text))
Sys_Error("memory overwrite in Sys_Printf");
if (sys_nostdout.value)
return;
for (p = (unsigned char *)text; *p; p++) {
*p &= 0x7f;
if ((*p > 128 || *p < 32) && *p != 10 && *p != 13 && *p != 9)
printf("[%02x]", *p);
else
putc(*p, stdout);
}
fflush(stdout);
}
/*
================
Sys_Quit
================
*/
void Sys_Quit (void)
{
exit (0); // appkit isn't running
}
static int do_stdin = 1;
/*
================
Sys_ConsoleInput
Checks for a complete line of text typed in at the console, then forwards
it to the host command processor
================
*/
char *Sys_ConsoleInput (void)
{
static char text[256];
int len;
if (!stdin_ready || !do_stdin)
return NULL; // the select didn't say it was ready
stdin_ready = false;
len = read (0, text, sizeof(text));
if (len == 0) {
// end of file
do_stdin = 0;
return NULL;
}
if (len < 1)
return NULL;
text[len-1] = 0; // rip off the /n and terminate
return text;
}
/*
=============
Sys_Init
Quake calls this so the system can register variables before host_hunklevel
is marked
=============
*/
void Sys_Init (void)
{
Cvar_Register (&sys_nostdout, "System configuration");
Cvar_Register (&sys_extrasleep, "System configuration");
}
/*
=============
main
=============
*/
int main(int argc, char *argv[])
{
double time, oldtime, newtime;
quakeparms_t parms;
// fd_set fdset;
// extern int net_socket;
int j;
memset (&parms, 0, sizeof(parms));
COM_InitArgv (argc, argv);
TL_InitLanguages();
parms.argc = com_argc;
parms.argv = com_argv;
parms.memsize = 16*1024*1024;
j = COM_CheckParm("-mem");
if (j)
parms.memsize = (int) (Q_atof(com_argv[j+1]) * 1024 * 1024);
if ((parms.membase = malloc (parms.memsize)) == NULL)
Sys_Error("Can't allocate %ld\n", parms.memsize);
parms.basedir = ".";
/*
if (Sys_FileTime ("id1/pak0.pak") != -1)
else
parms.basedir = "/raid/quake/v2";
*/
SV_Init (&parms);
// run one frame immediately for first heartbeat
SV_Frame (0.1);
//
// main loop
//
oldtime = Sys_DoubleTime () - 0.1;
while (1)
{
if (do_stdin)
stdin_ready = NET_Sleep(100, true);
else
{
NET_Sleep(100, false);
stdin_ready = false;
}
// find time passed since last cycle
newtime = Sys_DoubleTime ();
time = newtime - oldtime;
oldtime = newtime;
SV_Frame (time);
// extrasleep is just a way to generate a fucked up connection on purpose
if (sys_extrasleep.value)
usleep (sys_extrasleep.value);
}
return 0;
}
//1 if match
//FIXME: make windows like - *.* becomes *
int wildcmp(char *wild, char *string) {
char *cp, *mp;
while ((*string) && (*wild != '*')) {
if ((*wild != *string) && (*wild != '?')) {
return 0;
}
wild++;
string++;
}
while (*string) {
if (*wild == '*') {
if (!*++wild) {
return 1;
}
mp = wild;
cp = string+1;
} else if ((*wild == *string) || (*wild == '?')) {
wild++;
string++;
} else {
wild = mp;
string = cp++;
}
}
while (*wild == '*') {
wild++;
}
return !*wild;
}
int Sys_EnumerateFiles (char *gpath, char *match, int (*func)(char *, int, void *), void *parm)
{
#include <dirent.h>
DIR *dir, *dir2;
char apath[MAX_OSPATH];
char file[MAX_OSPATH];
char truepath[MAX_OSPATH];
char *s;
struct dirent *ent;
//printf("path = %s\n", gpath);
//printf("match = %s\n", match);
if (!gpath)
gpath = "";
*apath = '\0';
Q_strncpyz(apath, match, sizeof(apath));
for (s = apath+strlen(apath)-1; s >= apath; s--)
{
if (*s == '/')
{
s[1] = '\0';
match += s - apath+1;
break;
}
}
if (s < apath) //didn't find a '/'
*apath = '\0';
sprintf(truepath, "%s/%s", gpath, apath);
//printf("truepath = %s\n", truepath);
//printf("gamepath = %s\n", gpath);
//printf("apppath = %s\n", apath);
//printf("match = %s\n", match);
dir = opendir(truepath);
if (!dir)
{
Con_Printf("Failed to open dir");
return true;
}
do
{
ent = readdir(dir);
if (!ent)
break;
if (*ent->d_name != '.')
if (wildcmp(match, ent->d_name))
{
snprintf(file, sizeof(file)-1, "%s/%s", gpath, ent->d_name);
//would use stat, but it breaks on fat32.
if ((dir2 = opendir(file)))
{
closedir(dir2);
snprintf(file, sizeof(file)-1, "%s%s/", apath, ent->d_name);
//printf("is directory = %s\n", file);
}
else
{
snprintf(file, sizeof(file)-1, "%s%s", apath, ent->d_name);
//printf("file = %s\n", file);
}
if (!func(file, -2, parm))
{
closedir(dir);
return false;
}
}
} while(1);
closedir(dir);
return true;
}
void Sys_UnloadGame (void)
{
}
void *Sys_GetGameAPI (void *parms)
{
return NULL;
}
void Sys_ServerActivity(void)
{
}