diff --git a/engine/server/sv_sys_unix.c b/engine/server/sv_sys_unix.c new file mode 100644 index 000000000..2d3283109 --- /dev/null +++ b/engine/server/sv_sys_unix.c @@ -0,0 +1,457 @@ +/* +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 +#include "qwsvdef.h" + +#undef malloc + +#ifdef NeXT +#include +#endif + +#if defined(__linux__) || defined(sun) || defined(__CYGWIN__) +#include +#include +#include +#include +#include +#else +#include +#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 + 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) + { + stdin_ready = NET_Sleep(100, true); + + // 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 + 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) +{ +} +