/* =========== FS_FOpenDemoFileWrite =========== */ qboolean FS_FOpenDemoFileWrite( const char *filename, fileHandleData_t *fh ) { char ospath[MAX_OSPATH]; if ( !FS_Initialized() ) { Com_Error( ERR_FATAL, "Filesystem call made without initialization" ); } FS_BuildOSPathForThread( fs_homepath->string, filename, "", ospath, 0 ); ospath[strlen(ospath)-1] = '\0'; fh->zipFile = qfalse; if ( fs_debug->boolean ) { Com_Printf( "FS_SV_FOpenDemoFileWrite: %s\n", ospath ); } if( FS_CreatePath( ospath ) ) { return qfalse; } fh->handleFiles.file.o = fopen( ospath, "wb" ); Q_strncpyz( fh->name, filename, sizeof( fh->name ) ); fh->handleSync = qfalse; if (!fh->handleFiles.file.o) { return qfalse; } fh->writebuffer = Z_Malloc(FS_DEMOWRITEBUF_SIZE); fh->bufferSize = FS_DEMOWRITEBUF_SIZE; return qtrue; }
void Log_AutoLogging_SaveMatch(void) { int error, num; FILE *f; char *dir, *tempname, savedname[2 * MAX_OSPATH], *fullsavedname, *exts[] = {"log", NULL}; if (!temp_log_ready) return; temp_log_ready = false; dir = Log_LogDirectory(); tempname = va("%s/%s", MT_TempDirectory(), TEMP_LOG_NAME); fullsavedname = va("%s/%s", dir, auto_matchname); if ((num = Util_Extend_Filename(fullsavedname, exts)) == -1) { Com_Printf("Error: no available filenames\n"); return; } snprintf (savedname, sizeof(savedname), "%s_%03i.log", auto_matchname, num); fullsavedname = va("%s/%s", dir, savedname); if (!(f = fopen(tempname, "rb"))) return; fclose(f); if ((error = rename(tempname, fullsavedname))) { FS_CreatePath(fullsavedname); error = rename(tempname, fullsavedname); } if (!error) Com_Printf("Match console log saved to %s\n", savedname); }
/* * Returns file size or -1 on error. */ int FS_FOpenFileAppend(fsHandle_t *handle) { char path[MAX_OSPATH]; FS_CreatePath(handle->name); Com_sprintf(path, sizeof(path), "%s/%s", fs_gamedir, handle->name); handle->file = fopen(path, "ab"); if (handle->file) { if (fs_debug->value) { Com_Printf("FS_FOpenFileAppend: '%s'.\n", path); } return FS_FileLength(handle->file); } if (fs_debug->value) { Com_Printf("FS_FOpenFileAppend: couldn't open '%s'.\n", path); } return -1; }
/* * Use ~/.quake2/dir as fs_gamedir. */ void FS_AddHomeAsGameDirectory(char *dir) { char *home; char gdir[MAX_OSPATH]; size_t len; home = Sys_GetHomeDir(); if (home == NULL) { return; } len = snprintf(gdir, sizeof(gdir), "%s%s/", home, dir); FS_CreatePath(gdir); if ((len > 0) && (len < sizeof(gdir)) && (gdir[len - 1] == '/')) { gdir[len - 1] = 0; } Q_strlcpy(fs_gamedir, gdir, sizeof(fs_gamedir)); FS_AddGameDirectory(gdir); }
/* =========== FS_FOpenFileAppend =========== */ fileHandle_t FS_FOpenFileAppend( const char *filename ) { char *ospath; fileHandle_t f; if ( !fs_searchpaths ) { Com_Error( ERR_FATAL, "Filesystem call made without initialization\n" ); } f = FS_HandleForFile(); fsh[f].zipFile = qfalse; Q_strncpyz( fsh[f].name, filename, sizeof( fsh[f].name ) ); // don't let sound stutter S_ClearSoundBuffer(); #ifdef _XBOX ospath = FS_BuildOSPath( filename ); #else ospath = FS_BuildOSPath( fs_basepath->string, fs_gamedir, filename ); #endif if ( fs_debug->integer ) { Com_Printf( "FS_FOpenFileAppend: %s\n", ospath ); } FS_CreatePath( ospath ); fsh[f].handleFiles.file.o = fopen( ospath, "ab" ); fsh[f].handleSync = qfalse; if (!fsh[f].handleFiles.file.o) { f = 0; } return f; }
/* * Always returns 0 or -1 on error. */ int FS_FOpenFileWrite(fsHandle_t *handle) { char path[MAX_OSPATH]; FS_CreatePath(handle->name); Com_sprintf(path, sizeof(path), "%s/%s", fs_gamedir, handle->name); if ((handle->file = fopen(path, "wb")) != NULL) { if (fs_debug->value) { Com_Printf("FS_FOpenFileWrite: '%s'.\n", path); } return 0; } if (fs_debug->value) { Com_Printf("FS_FOpenFileWrite: couldn't open '%s'.\n", path); } return -1; }
void Host_LockSession(void) { if(locksession_run) return; locksession_run = true; if(locksession.integer != 0 && !COM_CheckParm("-readonly")) { char vabuf[1024]; char *p = va(vabuf, sizeof(vabuf), "%slock%s", *fs_userdir ? fs_userdir : fs_basedir, sessionid.string); FS_CreatePath(p); locksession_fh = FS_SysOpen(p, "wl", false); // TODO maybe write the pid into the lockfile, while we are at it? may help server management tools if(!locksession_fh) { if(locksession.integer == 2) { Con_Printf("WARNING: session lock %s could not be acquired. Please run with -sessionid and an unique session name. Continuing anyway.\n", p); } else { Sys_Error("session lock %s could not be acquired. Please run with -sessionid and an unique session name.\n", p); } } } }
/* =========== FS_FOpenDemoFileWrite =========== */ fileHandle_t FS_FOpenDemoFileWrite( const char *filename ) { char *ospath; fileHandle_t f; if ( !fs_searchpaths ) { Com_Error( ERR_FATAL, "Filesystem call made without initialization" ); } ospath = FS_BuildOSPath( fs_homepath->string, filename, "" ); ospath[strlen(ospath)-1] = '\0'; f = FS_HandleForDemoFile(); demofsh[f].zipFile = qfalse; if ( fs_debug->boolean ) { Com_Printf( "FS_SV_FOpenDemoFileWrite: %s\n", ospath ); } if( FS_CreatePath( ospath ) ) { return 0; } demofsh[f].handleFiles.file.o = fopen( ospath, "wb" ); Q_strncpyz( demofsh[f].name, filename, sizeof( demofsh[f].name ) ); demofsh[f].handleSync = qfalse; if (!demofsh[f].handleFiles.file.o) { f = 0; } return f; }
/* ================== SV_GameMap_f Saves the state of the map just being exited and goes to a new map. If the initial character of the map string is '*', the next map is in a new unit, so the current savegame directory is cleared of map files. Example: *inter.cin+jail Clears the archived maps, plays the inter.cin cinematic, then goes to map jail.bsp. ================== */ void SV_GameMap_f (void) { char *map; int i; client_t *cl; qboolean *savedInuse; if (Cmd_Argc() != 2) { Com_Printf ("USAGE: gamemap <map>\n"); return; } Com_DPrintf("SV_GameMap(%s)\n", Cmd_Argv(1)); FS_CreatePath (va("%s/save/current/", FS_Gamedir())); // check for clearing the current savegame map = Cmd_Argv(1); if (map[0] == '*') { // wipe all the *.sav files SV_WipeSavegame ("current"); } else { // save the map just exited if (sv.state == ss_game) { // clear all the client inuse flags before saving so that // when the level is re-entered, the clients will spawn // at spawn points instead of occupying body shells savedInuse = malloc(maxclients->value * sizeof(qboolean)); for (i=0,cl=svs.clients ; i<maxclients->value; i++,cl++) { savedInuse[i] = cl->edict->inuse; cl->edict->inuse = false; } SV_WriteLevelFile (); // we must restore these for clients to transfer over correctly for (i=0,cl=svs.clients ; i<maxclients->value; i++,cl++) cl->edict->inuse = savedInuse[i]; free (savedInuse); } } // start up the next map SV_Map (false, Cmd_Argv(1), false ); // archive server state strncpy (svs.mapcmd, Cmd_Argv(1), sizeof(svs.mapcmd)-1); // copy off the level to the autosave slot if (!dedicated->value) { SV_WriteServerFile (true); SV_CopySaveGame ("current", "save0"); } }
/* ======================================================================================================================================= DL_BeginDownload Inspired from http://www.w3.org/Library/Examples/LoadToFile.c, setup the download, return once we have a connection. ======================================================================================================================================= */ int DL_BeginDownload(char *localName, const char *remoteName) { char referer[MAX_STRING_CHARS + 5 /*"ET://"*/]; if (dl_request) { Com_Printf(S_COLOR_RED "DL_BeginDownload: Error - called with a download request already active\n"); return 0; } if (!localName[0] || !remoteName[0]) { Com_Printf(S_COLOR_RED "DL_BeginDownload: Error - empty download URL or empty local file name\n"); return 0; } if (FS_CreatePath(localName)) { Com_Printf(S_COLOR_RED "DL_BeginDownload: Error - unable to create directory(%s).\n", localName); return 0; } dl_file = fopen(localName, "wb + "); if (!dl_file) { Com_Printf(S_COLOR_RED "DL_BeginDownload: Error - unable to open '%s' for writing\n", localName); return 0; } DL_InitDownload(); // ET://ip:port strcpy(referer, "ET://"); Q_strncpyz(referer + 5, Cvar_VariableString("cl_currentServerIP"), MAX_STRING_CHARS); dl_request = curl_easy_init(); curl_easy_setopt(dl_request, CURLOPT_USERAGENT, va("%s %s", APP_NAME "/" APP_VERSION, curl_version())); curl_easy_setopt(dl_request, CURLOPT_REFERER, referer); curl_easy_setopt(dl_request, CURLOPT_URL, remoteName); curl_easy_setopt(dl_request, CURLOPT_WRITEFUNCTION, DL_cb_FWriteFile); curl_easy_setopt(dl_request, CURLOPT_WRITEDATA, (void *)dl_file); curl_easy_setopt(dl_request, CURLOPT_PROGRESSFUNCTION, DL_cb_Progress); curl_easy_setopt(dl_request, CURLOPT_NOPROGRESS, 0); curl_easy_setopt(dl_request, CURLOPT_FAILONERROR, 1); curl_easy_setopt(dl_request, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(dl_request, CURLOPT_MAXREDIRS, 5); #ifdef FEATURE_OPENSSL #if 0 curl_easy_setopt(dl_request, CURLOPT_CAINFO, "./cert.crt"); #else curl_easy_setopt(dl_request, CURLOPT_SSL_VERIFYHOST, 0); curl_easy_setopt(dl_request, CURLOPT_SSL_VERIFYPEER, 0); #endif #endif if (curl_multi_add_handle(dl_multi, dl_request) != CURLM_OK) { Com_Printf(S_COLOR_RED "DL_BeginDownload: Error - invalid handle.\n"); } Cvar_Set("cl_downloadName", remoteName); return 1; }
void FS_InitFilesystem(void) { /* Register FS commands. */ Cmd_AddCommand("path", FS_Path_f); Cmd_AddCommand("link", FS_Link_f); Cmd_AddCommand("dir", FS_Dir_f); /* basedir <path> Allows the game to run from outside the data tree. */ fs_basedir = Cvar_Get("basedir", #ifdef SYSTEMWIDE SYSTEMDIR, #else ".", #endif CVAR_NOSET); /* cddir <path> Logically concatenates the cddir after the basedir to allow the game to run from outside the data tree. */ fs_cddir = Cvar_Get("cddir", "", CVAR_NOSET); if (fs_cddir->string[0] != '\0') { FS_AddGameDirectory(va("%s/" BASEDIRNAME, fs_cddir->string)); } /* Debug flag. */ fs_debug = Cvar_Get("fs_debug", "0", 0); /* Game directory. */ fs_gamedirvar = Cvar_Get("game", "", CVAR_LATCH | CVAR_SERVERINFO); /* Current directory. */ fs_homepath = Cvar_Get("homepath", Sys_GetCurrentDirectory(), CVAR_NOSET); /* Add baseq2 to search path. */ FS_AddGameDirectory(va("%s/" BASEDIRNAME, fs_basedir->string)); FS_AddBinaryDirAsGameDirectory(BASEDIRNAME); FS_AddHomeAsGameDirectory(BASEDIRNAME); /* Any set gamedirs will be freed up to here. */ fs_baseSearchPaths = fs_searchPaths; Q_strlcpy(fs_currentGame, BASEDIRNAME, sizeof(fs_currentGame)); /* Check for game override. */ if (fs_gamedirvar->string[0] != '\0') { FS_SetGamedir(fs_gamedirvar->string); } /* Create directory if it does not exist. */ FS_CreatePath(fs_gamedir); Com_Printf("Using '%s' for writing.\n", fs_gamedir); }
/* ================ SV_CopySaveGame ================ */ void SV_CopySaveGame (char *src, char *dst) { char name[MAX_OSPATH], name2[MAX_OSPATH]; int l, len; char *found; Com_DPrintf("SV_CopySaveGame(%s, %s)\n", src, dst); SV_WipeSavegame (dst); // copy the savegame over Com_sprintf (name, sizeof(name), "%s/save/%s/server.ssv", FS_Gamedir(), src); Com_sprintf (name2, sizeof(name2), "%s/save/%s/server.ssv", FS_Gamedir(), dst); FS_CreatePath (name2); CopyFile (name, name2); Com_sprintf (name, sizeof(name), "%s/save/%s/game.ssv", FS_Gamedir(), src); Com_sprintf (name2, sizeof(name2), "%s/save/%s/game.ssv", FS_Gamedir(), dst); CopyFile (name, name2); // Knightmare- copy screenshot if (strcmp(dst, "kmq2save0")) // no screenshot for start of level autosaves { Com_sprintf (name, sizeof(name), "%s/save/%s/shot.jpg", FS_Gamedir(), src); Com_sprintf (name2, sizeof(name2), "%s/save/%s/shot.jpg", FS_Gamedir(), dst); CopyFile (name, name2); } Com_sprintf (name, sizeof(name), "%s/save/%s/", FS_Gamedir(), src); len = strlen(name); Com_sprintf (name, sizeof(name), "%s/save/%s/*.sav", FS_Gamedir(), src); found = Sys_FindFirst(name, 0, 0 ); while (found) { // strncpy (name+len, found+len); Q_strncpyz (name+len, found+len, sizeof(name)-len); Com_sprintf (name2, sizeof(name2), "%s/save/%s/%s", FS_Gamedir(), dst, found+len); CopyFile (name, name2); // change sav to sv2 l = strlen(name); // strncpy (name+l-3, "sv2"); Q_strncpyz (name+l-3, "sv2", sizeof(name)-l+3); l = strlen(name2); // strncpy (name2+l-3, "sv2"); Q_strncpyz (name2+l-3, "sv2", sizeof(name2)-l+3); CopyFile (name, name2); found = Sys_FindNext( 0, 0 ); } Sys_FindClose (); }
/* ============== Sys_ErrorDialog Display an error message ============== */ void Sys_ErrorDialog( const char *error ) { char buffer[ 1024 ]; unsigned int size; int f; const char *homepath = Cvar_VariableString( "fs_homepath" ); const char *gamedir = Cvar_VariableString( "fs_game" ); const char *fileName = "crashlog.txt"; char *ospath = FS_BuildOSPath( homepath, gamedir, fileName ); Sys_Print( va( "%s\n", error ) ); #ifndef DEDICATED // We may have grabbed input devices. Need to release. if ( SDL_WasInit( SDL_INIT_VIDEO ) ) { SDL_WM_GrabInput( SDL_GRAB_OFF ); } Sys_Dialog( DT_ERROR, va( "%s. See \"%s\" for details.", error, ospath ), "Error" ); #endif // Make sure the write path for the crashlog exists... if ( FS_CreatePath( ospath ) ) { Com_Printf( "ERROR: couldn't create path '%s' for crash log.\n", ospath ); return; } // We might be crashing because we maxed out the Quake MAX_FILE_HANDLES, // which will come through here, so we don't want to recurse forever by // calling FS_FOpenFileWrite()...use the Unix system APIs instead. f = open( ospath, O_CREAT | O_TRUNC | O_WRONLY, 0640 ); if ( f == -1 ) { Com_Printf( "ERROR: couldn't open %s\n", fileName ); return; } // We're crashing, so we don't care much if write() or close() fails. while ( ( size = CON_LogRead( buffer, sizeof( buffer ) ) ) > 0 ) { if ( write( f, buffer, size ) != size ) { Com_Printf( "ERROR: couldn't fully write to %s\n", fileName ); break; } } close( f ); }
void screenshotJPEG(char *filename, qbyte *screendata, int screenwidth, int screenheight) //input is rgb NOT rgba { qbyte *buffer; vfsfile_t *outfile; jpeg_error_mgr_wrapper jerr; struct jpeg_compress_struct cinfo; JSAMPROW row_pointer[1]; if (!(outfile = FS_OpenVFS(filename, "wb", FS_GAMEONLY))) { FS_CreatePath (filename, FS_GAME); if (!(outfile = FS_OpenVFS(filename, "wb", FS_GAMEONLY))) { Con_Printf("Error opening %s\n", filename); return; } } cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = jpeg_error_exit; if (setjmp(jerr.setjmp_buffer)) { jpeg_destroy_compress(&cinfo); VFS_CLOSE(outfile); FS_Remove(filename, FS_GAME); Con_Printf("Failed to create jpeg\n"); return; } jpeg_create_compress(&cinfo); buffer = screendata; jpeg_mem_dest(&cinfo, outfile); cinfo.image_width = screenwidth; cinfo.image_height = screenheight; cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults(&cinfo); jpeg_set_quality (&cinfo, 75/*bound(0, (int) gl_image_jpeg_quality_level.value, 100)*/, true); jpeg_start_compress(&cinfo, true); while (cinfo.next_scanline < cinfo.image_height) { *row_pointer = &buffer[(cinfo.image_height - cinfo.next_scanline - 1) * cinfo.image_width * 3]; jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); VFS_CLOSE(outfile); jpeg_destroy_compress(&cinfo); }
void Log_AutoLogging_StartMatch(char *logname) { char extendedname[MAX_OSPATH * 2], *fullname; FILE *templog; void *buf; temp_log_ready = false; if (!match_auto_logconsole.value) return; if (Log_IsLogging()) { if (autologging) { autologging = false; Log_Stop(); } else { Com_Printf("Auto console logging skipped (already logging)\n"); return; } } strlcpy(auto_matchname, logname, sizeof(auto_matchname)); strlcpy (extendedname, TEMP_LOG_NAME, sizeof(extendedname)); COM_ForceExtensionEx (extendedname, ".log", sizeof (extendedname)); fullname = va("%s/%s", MT_TempDirectory(), extendedname); if (!(templog = fopen (fullname, log_readable.value ? "w" : "wb"))) { FS_CreatePath(fullname); if (!(templog = fopen (fullname, log_readable.value ? "w" : "wb"))) { Com_Printf("Error: Couldn't open %s\n", fullname); return; } } buf = Q_calloc(1, LOGFILEBUFFER); if (!buf) { Com_Printf("Not enough memory to allocate log buffer\n"); return; } memlogfile = FSMMAP_OpenVFS(buf, LOGFILEBUFFER); Com_Printf ("Auto console logging commenced\n"); logfile = templog; autologging = true; auto_starttime = cls.realtime; }
void SV_CopySaveGame(char *src, char *dst) { char name[MAX_OSPATH], name2[MAX_OSPATH]; size_t l, len; char *found; Com_DPrintf("SV_CopySaveGame(%s, %s)\n", src, dst); SV_WipeSavegame(dst); /* copy the savegame over */ Com_sprintf(name, sizeof(name), "%s/save/%s/server.ssv", FS_Gamedir(), src); Com_sprintf(name2, sizeof(name2), "%s/save/%s/server.ssv", FS_Gamedir(), dst); FS_CreatePath(name2); CopyFile(name, name2); Com_sprintf(name, sizeof(name), "%s/save/%s/game.ssv", FS_Gamedir(), src); Com_sprintf(name2, sizeof(name2), "%s/save/%s/game.ssv", FS_Gamedir(), dst); CopyFile(name, name2); Com_sprintf(name, sizeof(name), "%s/save/%s/", FS_Gamedir(), src); len = strlen(name); Com_sprintf(name, sizeof(name), "%s/save/%s/*.sav", FS_Gamedir(), src); found = Sys_FindFirst(name, 0, 0); while (found) { strcpy(name + len, found + len); Com_sprintf(name2, sizeof(name2), "%s/save/%s/%s", FS_Gamedir(), dst, found + len); CopyFile(name, name2); /* change sav to sv2 */ l = strlen(name); strcpy(name + l - 3, "sv2"); l = strlen(name2); strcpy(name2 + l - 3, "sv2"); CopyFile(name, name2); found = Sys_FindNext(0, 0); } Sys_FindClose(); }
void Log_AutoLogging_SaveMatch(qbool allow_upload) { int error, num; FILE *f; char *dir, *tempname, savedname[2 * MAX_OSPATH], *fullsavedname, *exts[] = {"log", NULL}; if (!temp_log_ready) return; if (temp_log_upload_pending) { Com_Printf("Error: Can't save the log. Log upload is still pending.\n"); return; } temp_log_ready = false; dir = Log_LogDirectory(); tempname = va("%s/%s", MT_TempDirectory(), TEMP_LOG_NAME); fullsavedname = va("%s/%s", dir, auto_matchname); if ((num = Util_Extend_Filename(fullsavedname, exts)) == -1) { Com_Printf("Error: no available filenames\n"); return; } snprintf (savedname, sizeof(savedname), "%s_%03i.log", auto_matchname, num); fullsavedname = va("%s/%s", dir, savedname); if (!(f = fopen(tempname, "rb"))) return; fclose(f); if ((error = rename(tempname, fullsavedname))) { FS_CreatePath(fullsavedname); error = rename(tempname, fullsavedname); } if (!error) { Com_Printf("Match console log saved to %s\n", savedname); if (allow_upload && Log_IsUploadAllowed()) { // note: we allow the client to be a spectator, so that spectators // can submit logs for matches they spec in case players don't do it Log_AutoLogging_Upload(fullsavedname); } } }
bool MakeDir(std::string destdir, std::string basegame) { std::string destpath(destdir); if ( basegame != "" ) { destpath += '/'; destpath += basegame; } if ( *destpath.rbegin() != '/' ) destpath += '/'; // XXX FS_CreatePath requires a trailing slash. // Maybe the assumption is that a file listing might be included? FS_CreatePath(destpath.c_str()); return true; }
static int copy_file(const char *src, const char *dst, const char *name) { char path[MAX_OSPATH]; byte buf[0x10000]; FILE *ifp, *ofp; size_t len, res; int ret = -1; len = Q_snprintf(path, MAX_OSPATH, "%s/save/%s/%s", fs_gamedir, src, name); if (len >= MAX_OSPATH) goto fail0; ifp = fopen(path, "rb"); if (!ifp) goto fail0; len = Q_snprintf(path, MAX_OSPATH, "%s/save/%s/%s", fs_gamedir, dst, name); if (len >= MAX_OSPATH) goto fail1; if (FS_CreatePath(path)) goto fail1; ofp = fopen(path, "wb"); if (!ofp) goto fail1; do { len = fread(buf, 1, sizeof(buf), ifp); res = fwrite(buf, 1, len, ofp); } while (len == sizeof(buf) && res == len); if (ferror(ifp)) goto fail2; if (ferror(ofp)) goto fail2; ret = 0; fail2: fclose(ofp); fail1: fclose(ifp); fail0: return ret; }
/* =============== inspired from http://www.w3.org/Library/Examples/LoadToFile.c setup the download, return once we have a connection =============== */ int DL_BeginDownload( const char *localName, const char *remoteName, int debug ) { char referer[ MAX_STRING_CHARS + URI_SCHEME_LENGTH ]; if ( dl_request ) { Com_Printf( "ERROR: DL_BeginDownload called with a download request already active\n" ); return 0; } if ( !localName || !remoteName ) { Com_DPrintf( "Empty download URL or empty local file name\n" ); return 0; } FS_CreatePath( localName ); dl_file = fopen( localName, "wb+" ); if ( !dl_file ) { Com_Printf( "ERROR: DL_BeginDownload unable to open '%s' for writing\n", localName ); return 0; } DL_InitDownload(); strcpy( referer, URI_SCHEME ); Q_strncpyz( referer + URI_SCHEME_LENGTH, Cvar_VariableString( "cl_currentServerIP" ), MAX_STRING_CHARS ); dl_request = curl_easy_init(); curl_easy_setopt( dl_request, CURLOPT_USERAGENT, va( "%s %s", PRODUCT_NAME "/" PRODUCT_VERSION, curl_version() ) ); curl_easy_setopt( dl_request, CURLOPT_REFERER, referer ); curl_easy_setopt( dl_request, CURLOPT_URL, remoteName ); curl_easy_setopt( dl_request, CURLOPT_WRITEFUNCTION, DL_cb_FWriteFile ); curl_easy_setopt( dl_request, CURLOPT_WRITEDATA, ( void * ) dl_file ); curl_easy_setopt( dl_request, CURLOPT_PROGRESSFUNCTION, DL_cb_Progress ); curl_easy_setopt( dl_request, CURLOPT_NOPROGRESS, 0 ); curl_easy_setopt( dl_request, CURLOPT_FAILONERROR, 1 ); curl_multi_add_handle( dl_multi, dl_request ); Cvar_Set( "cl_downloadName", remoteName ); return 1; }
void DumpHUD(const char *name) { // Dumps all variables from CFG_GROUP_HUD into a file extern cvar_t scr_newHud; FILE *f; int max_width = 0, i = 0, j; char *outfile, *spaces; cvar_t *var; cvar_t *sorted[MAX_DUMPED_CVARS]; outfile = va("%s/ezquake/configs/%s", com_basedir, name); if (!(f = fopen (outfile, "w"))) { FS_CreatePath(outfile); if (!(f = fopen (outfile, "w"))) { Com_Printf ("Couldn't write %s.\n", name); return; } } fprintf(f, "//\n"); fprintf(f, "// Head Up Display Configuration Dump\n"); fprintf(f, "//\n\n"); for(var = cvar_vars; var; var = var->next) if(var->group && !strcmp(var->group->name, CVAR_GROUP_HUD)) { max_width = max(max_width, strlen(var->name)); sorted[i++] = var; } max_width++; qsort(sorted, i, sizeof(cvar_t *), Cvar_CvarCompare); spaces = CreateSpaces(max_width - strlen(scr_newHud.name)); fprintf(f, "%s%s\"%d\"\n", scr_newHud.name, spaces, scr_newHud.integer); for(j = 0; j < i; j++) { spaces = CreateSpaces(max_width - strlen(sorted[j]->name)); fprintf(f, "%s%s\"%s\"\n", sorted[j]->name, spaces, sorted[j]->string); } fprintf(f, "hud_recalculate\n"); fclose(f); }
//FIXME: this is bad, loads entire file for just 8 bytes! qboolean GetWalInfo (const char *name, int *width, int *height) { miptex_t mt; qboolean closeFile; FILE *h; FS_FOpenFile (name, &h, HANDLE_OPEN, &closeFile); if (!h) return false; /*if (fread (&mt, sizeof(mt), 1, h) != 1) { ri.FS_FCloseFile (h); return false; }*/ FS_Read (&mt, sizeof(mt), h); if (closeFile) FS_FCloseFile (h); *width = LittleLong(mt.width); *height = LittleLong(mt.height); #if defined(_DEBUG) && !defined(EMSCRIPTEN) int i; char grey = 8; FS_CreatePath (va("wals/%s", name)); h = fopen (va("wals/%s", name), "wb"); fwrite (&mt, 1, sizeof(mt), h); for (i = 0; i < mt.width * mt.height; i++) fwrite (&grey, 1, 1, h); for (i = 0; i < (mt.width * mt.height) / 2; i++) fwrite (&grey, 1, 1, h); for (i = 0; i < (mt.width * mt.height) / 4; i++) fwrite (&grey, 1, 1, h); for (i = 0; i < (mt.width * mt.height) / 8; i++) fwrite (&grey, 1, 1, h); fclose (h); #endif return true; }
/* ================= Sys_WritePIDFile Return qtrue if there is an existing stale PID file ================= */ static qboolean Sys_WritePIDFile( const char *gamedir ) { char *pidFile = Sys_PIDFileName( gamedir ); FILE *f; qboolean stale = qfalse; if( pidFile == NULL ) return qfalse; // First, check if the pid file is already there if( ( f = fopen( pidFile, "r" ) ) != NULL ) { char pidBuffer[ 64 ] = { 0 }; int pid; pid = fread( pidBuffer, sizeof( char ), sizeof( pidBuffer ) - 1, f ); fclose( f ); if(pid > 0) { pid = atoi( pidBuffer ); if( !Sys_PIDIsRunning( pid ) ) stale = qtrue; } else stale = qtrue; } if( FS_CreatePath( pidFile ) ) { return 0; } if( ( f = fopen( pidFile, "w" ) ) != NULL ) { fprintf( f, "%d", Sys_PID( ) ); fclose( f ); } else Com_Printf( S_COLOR_YELLOW "Couldn't write %s.\n", pidFile ); return stale; }
void SV_Snap (int uid) { client_t *cl; char pcxname[80], checkname[MAX_OSPATH]; int i; FILE *f; for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++) { if (cl->state < cs_connected) continue; if (cl->userid == uid) break; } if (i >= MAX_CLIENTS) { Com_Printf ("userid not found\n"); return; } FS_CreatePath (va("%s/snap/", com_gamedir)); snprintf (pcxname, sizeof (pcxname), "%d-00.pcx", uid); for (i = 0; i <= 99; i++) { pcxname[strlen(pcxname) - 6] = i / 10 + '0'; pcxname[strlen(pcxname) - 5] = i % 10 + '0'; snprintf (checkname, sizeof(checkname), "%s/snap/%s", com_gamedir, pcxname); if (!(f = fopen (checkname, "rb"))) break; // file doesn't exist fclose (f); } if (i == 100) { Com_Printf ("Snap: Couldn't create a file, clean some out.\n"); return; } strlcpy (cl->uploadfn, checkname, sizeof (cl->uploadfn)); memcpy(&cl->snap_from, &net_from, sizeof(net_from)); cl->remote_snap = (sv_redirected != RD_NONE); ClientReliableWrite_Begin (cl, svc_stufftext, 24); ClientReliableWrite_String (cl, "cmd snap\n"); Com_Printf ("Requesting snap from user %d...\n", uid); }
void CL_ParseDownload (qboolean dataIsCompressed) { int size, percent; char name[MAX_OSPATH]; // read the data size = MSG_ReadShort (&net_message); percent = MSG_ReadByte (&net_message); if (size < 0) { if (size == -1) Com_Printf ("Server does not have this file.\n", LOG_CLIENT); else Com_Printf ("Bad download data from server.\n", LOG_CLIENT); //r1: nuke the temp filename cls.downloadtempname[0] = 0; cls.downloadname[0] = 0; cls.failed_download = true; if (cls.download) { // if here, we tried to resume a file but the server said no fclose (cls.download); cls.download = NULL; } cls.downloadpending = false; CL_RequestNextDownload (); return; } // open the file if not opened yet if (!cls.download) { if (!cls.downloadtempname[0]) { Com_Printf ("Received download packet without request. Ignored.\n", LOG_CLIENT); net_message.readcount += size; return; } CL_DownloadFileName(name, sizeof(name), cls.downloadtempname); FS_CreatePath (name); cls.download = fopen (name, "wb"); if (!cls.download) { net_message.readcount += size; Com_Printf ("Failed to open %s\n", LOG_CLIENT, cls.downloadtempname); cls.downloadpending = false; CL_RequestNextDownload (); return; } } //r1: downloading something, drop to console to show status bar SCR_EndLoadingPlaque(); //r1: if we're stuck with udp, may as well make best use of the bandwidth... if (dataIsCompressed) { #ifndef NO_ZLIB uint16 uncompressedLen; byte uncompressed[0xFFFF]; uncompressedLen = (uint16)MSG_ReadShort (&net_message); if (!uncompressedLen) Com_Error (ERR_DROP, "uncompressedLen == 0"); ZLibDecompress (net_message_buffer + net_message.readcount, size, uncompressed, uncompressedLen, -15); fwrite (uncompressed, 1, uncompressedLen, cls.download); Com_DPrintf ("svc_zdownload(%s): %d -> %d\n", cls.downloadname, size, uncompressedLen); #else Com_Error (ERR_DROP, "Received a unrequested compressed download"); #endif } else { fwrite (net_message_buffer + net_message.readcount, 1, size, cls.download); } net_message.readcount += size; if (percent != 100) { cls.downloadpercent = percent; MSG_WriteByte (clc_stringcmd); MSG_Print ("nextdl"); MSG_EndWriting (&cls.netchan.message); send_packet_now = true; } else { CL_FinishDownload (); // get another file if needed CL_RequestNextDownload (); } }
/* =============== CL_StartHTTPDownload Actually starts a download by adding it to the curl multi handle. =============== */ static void CL_StartHTTPDownload (dlqueue_t *entry, dlhandle_t *dl) { size_t len; char tempFile[MAX_OSPATH]; char escapedFilePath[MAX_QPATH*4]; //yet another hack to accomodate filelists, how i wish i could push :( //NULL file handle indicates filelist. len = strlen (entry->quakePath); if (len > 9 && !strcmp (entry->quakePath + len - 9, ".filelist")) { dl->file = NULL; CL_EscapeHTTPPath (entry->quakePath, escapedFilePath); } else { CL_HTTP_Reset_KBps_counter (); // Knightmare- for KB/s counter Com_sprintf (dl->filePath, sizeof(dl->filePath), "%s/%s", FS_Gamedir(), entry->quakePath); Com_sprintf (tempFile, sizeof(tempFile), "%s/%s", cl.gamedir, entry->quakePath); CL_EscapeHTTPPath (dl->filePath, escapedFilePath); // strncat (dl->filePath, ".tmp"); Q_strncatz (dl->filePath, ".tmp", sizeof(dl->filePath)); FS_CreatePath (dl->filePath); //don't bother with http resume... too annoying if server doesn't support it. dl->file = fopen (dl->filePath, "wb"); if (!dl->file) { Com_Printf ("CL_StartHTTPDownload: Couldn't open %s for writing.\n", dl->filePath); entry->state = DLQ_STATE_DONE; //CL_RemoveHTTPDownload (entry->quakePath); return; } } dl->tempBuffer = NULL; dl->speed = 0; dl->fileSize = 0; dl->position = 0; dl->queueEntry = entry; if (!dl->curl) dl->curl = curl_easy_init (); Com_sprintf (dl->URL, sizeof(dl->URL), "%s%s", cls.downloadServer, escapedFilePath); curl_easy_setopt (dl->curl, CURLOPT_ENCODING, ""); //curl_easy_setopt (dl->curl, CURLOPT_DEBUGFUNCTION, CL_CURL_Debug); //curl_easy_setopt (dl->curl, CURLOPT_VERBOSE, 1); curl_easy_setopt (dl->curl, CURLOPT_NOPROGRESS, 0); if (dl->file) { curl_easy_setopt (dl->curl, CURLOPT_WRITEDATA, dl->file); curl_easy_setopt (dl->curl, CURLOPT_WRITEFUNCTION, NULL); } else { curl_easy_setopt (dl->curl, CURLOPT_WRITEDATA, dl); curl_easy_setopt (dl->curl, CURLOPT_WRITEFUNCTION, CL_HTTP_Recv); } curl_easy_setopt (dl->curl, CURLOPT_PROXY, cl_http_proxy->string); curl_easy_setopt (dl->curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt (dl->curl, CURLOPT_MAXREDIRS, 5); curl_easy_setopt (dl->curl, CURLOPT_WRITEHEADER, dl); curl_easy_setopt (dl->curl, CURLOPT_HEADERFUNCTION, CL_HTTP_Header); curl_easy_setopt (dl->curl, CURLOPT_PROGRESSFUNCTION, CL_HTTP_Progress); curl_easy_setopt (dl->curl, CURLOPT_PROGRESSDATA, dl); curl_easy_setopt (dl->curl, CURLOPT_USERAGENT, Cvar_VariableString ("version")); curl_easy_setopt (dl->curl, CURLOPT_REFERER, cls.downloadReferer); curl_easy_setopt (dl->curl, CURLOPT_URL, dl->URL); if (curl_multi_add_handle (multi, dl->curl) != CURLM_OK) { Com_Printf ("curl_multi_add_handle: error\n"); dl->queueEntry->state = DLQ_STATE_DONE; return; } handleCount++; //Com_Printf ("started dl: hc = %d\n", LOG_GENERAL, handleCount); Com_DPrintf ("CL_StartHTTPDownload: Fetching %s...\n", dl->URL); dl->queueEntry->state = DLQ_STATE_RUNNING; }
/* =============== inspired from http://www.w3.org/Library/Examples/LoadToFile.c setup the download, return once we have a connection =============== */ int DL_BeginDownload( const char *localName, const char *remoteName, int debug ) { char *access = NULL; char *url = NULL; char *login = NULL; char *path = NULL; char *ptr = NULL; if ( dl_running ) { Com_Printf(_( "ERROR: DL_BeginDownload called with a download request already active\n" )); return 0; } terminate_status = HT_UNDEF; #ifdef HTDEBUG if ( debug ) { WWWTRACE = SHOW_ALL_TRACE; } #endif if ( !localName || !remoteName ) { Com_DPrintf( "Empty download URL or empty local file name\n" ); return 0; } DL_InitDownload(); /* need access for ftp behaviour and HTTP Basic Auth */ access = HTParse( remoteName, "", PARSE_ACCESS ); /* Set the timeout for how long we are going to wait for a response This needs to be set and reset to 0 after dl each time idcvs/2003-January/000449.html http://lists.w3.org/Archives/Public/www-lib/2003AprJun/0033.html In case of ftp download, we leave no timeout during connect phase cause of libwww bugs show_bug.cgi?id=605 */ if ( !Q_stricmp( access, "ftp" ) ) { dl_is_ftp = 1; HTHost_setEventTimeout( -1 ); } else { dl_is_ftp = 0; HTHost_setEventTimeout( 30000 ); } dl_request = HTRequest_new(); /* HTTP Basic Auth */ if ( !Q_stricmp( access, "http" ) ) { HTBasic *basic; login = HTParse( remoteName, "", PARSE_HOST ); path = HTParse( remoteName, "", PARSE_PATH + PARSE_PUNCTUATION ); ptr = strchr( login, '@' ); if ( ptr ) { /* Uid and/or passwd specified */ char *passwd; *ptr = '\0'; passwd = strchr( login, ':' ); if ( passwd ) { /* Passwd specified */ *passwd++ = '\0'; HTUnEscape( passwd ); } HTUnEscape( login ); /* proactively set the auth */ basic = HTBasic_new(); StrAllocCopy( basic->uid, login ); StrAllocCopy( basic->pw, passwd ); basic_credentials( dl_request, basic ); HTBasic_delete( basic ); /* correct the HTTP */ url = HT_MALLOC( 7 + strlen( ptr + 1 ) + strlen( path ) + 1 ); sprintf( url, "http://%s%s", ptr + 1, path ); Com_DPrintf( "HTTP Basic Auth – %s %s %s\n", login, passwd, url ); HT_FREE( login ); HT_FREE( path ); } else { StrAllocCopy( url, remoteName ); } } else { StrAllocCopy( url, remoteName ); } HT_FREE( access ); FS_CreatePath( localName ); /* Start the load */ if ( HTLoadToFile( url, dl_request, localName ) != YES ) { Com_DPrintf( "HTLoadToFile failed\n" ); HT_FREE( url ); HTProfile_delete(); return 0; } HT_FREE( url ); /* remove possible login/pass part for the ui */ access = HTParse( remoteName, "", PARSE_ACCESS ); login = HTParse( remoteName, "", PARSE_HOST ); path = HTParse( remoteName, "", PARSE_PATH + PARSE_PUNCTUATION ); ptr = strchr( login, '@' ); if ( ptr ) { /* Uid and/or passwd specified */ Cvar_Set( "cl_downloadName", va( "%s://*:*%s%s", access, ptr, path ) ); } else { Cvar_Set( "cl_downloadName", remoteName ); } HT_FREE( path ); HT_FREE( login ); HT_FREE( access ); if ( dl_is_ftp ) { HTHost_setEventTimeout( 30000 ); } /* Go into the event loop... */ HTEventList_init( dl_request ); dl_running = 1; return 1; }
/* ===================== CL_ParseDownload A download message has been received from the server ===================== */ void CL_ParseDownload(void) { int size, percent; char name[MAX_OSPATH]; int r; // read the data size = MSG_ReadShort(&net_message); percent = MSG_ReadByte(&net_message); if (size == -1) { Com_Printf("Server does not have this file.\n"); if (cls.download) { // if here, we tried to resume a file but the server said no fclose(cls.download); cls.download = NULL; } CL_RequestNextDownload(); return; } // open the file if not opened yet if (!cls.download) { CL_DownloadFileName(name, sizeof(name), cls.downloadtempname); FS_CreatePath(name); cls.download = fopen(name, "wb"); if (!cls.download) { net_message.readcount += size; Com_Printf("Failed to open %s\n", cls.downloadtempname); CL_RequestNextDownload(); return; } } fwrite(net_message.data + net_message.readcount, 1, size, cls.download); net_message.readcount += size; if (percent != 100) { // request next block // change display routines by zoid #if 0 Com_Printf ("."); if (10*(percent/10) != cls.downloadpercent) { cls.downloadpercent = 10*(percent/10); Com_Printf ("%i%%", cls.downloadpercent); } #endif cls.downloadpercent = percent; MSG_WriteByte(&cls.netchan.message, clc_stringcmd); SZ_Print(&cls.netchan.message, "nextdl"); } else { char oldn[MAX_OSPATH]; char newn[MAX_OSPATH]; // Com_Printf ("100%%\n"); fclose(cls.download); // rename the temp file to it's final name CL_DownloadFileName(oldn, sizeof(oldn), cls.downloadtempname); CL_DownloadFileName(newn, sizeof(newn), cls.downloadname); r = rename(oldn, newn); if (r) Com_Printf("failed to rename.\n"); cls.download = NULL; cls.downloadpercent = 0; // get another file if needed CL_RequestNextDownload(); } }
void SV_SaveGame_f (void) { char fname[MAX_OSPATH], comment[SAVEGAME_COMMENT_LENGTH+1]; FILE *f; int i; if (Cmd_Argc() != 2) { Com_Printf ("Usage: %s <savefname> : save a game\n", Cmd_Argv(0)); return; } else if (strstr(Cmd_Argv(1), "..")) { Com_Printf ("Relative pathfnames are not allowed.\n"); return; } else if (sv.state != ss_active) { Com_Printf ("Not playing a local game.\n"); return; } else if (cl.intermission) { Com_Printf ("Can't save in intermission.\n"); return; } else if (deathmatch.value != 0 || coop.value != 0 || maxclients.value != 1) { Com_Printf ("Can't save multiplayer games.\n"); return; } for (i = 1; i < MAX_CLIENTS; i++) { if (svs.clients[i].state == cs_spawned) { Com_Printf ("Can't save multiplayer games.\n"); return; } } if (svs.clients[0].state != cs_spawned) { Com_Printf ("Can't save, client #0 not spawned.\n"); return; } else if (svs.clients[0].edict->v.health <= 0) { Com_Printf ("Can't save game with a dead player\n"); // in fact, we can, but does it make sense? return; } snprintf (fname, sizeof(fname), "%s/save/%s", com_gamedir, Cmd_Argv(1)); COM_DefaultExtension (fname, ".sav"); Com_Printf ("Saving game to %s...\n", fname); if (!(f = fopen (fname, "w"))) { FS_CreatePath (fname); if (!(f = fopen (fname, "w"))) { Com_Printf ("ERROR: couldn't open.\n"); return; } } fprintf (f, "%i\n", SAVEGAME_VERSION); SV_SavegameComment (comment); fprintf (f, "%s\n", comment); for (i = 0 ; i < NUM_SPAWN_PARMS; i++) fprintf (f, "%f\n", svs.clients->spawn_parms[i]); fprintf (f, "%d\n", current_skill); fprintf (f, "%s\n", sv.mapname); fprintf (f, "%f\n", sv.time); // write the light styles for (i = 0; i < MAX_LIGHTSTYLES; i++) { if (sv.lightstyles[i]) fprintf (f, "%s\n", sv.lightstyles[i]); else fprintf (f,"m\n"); } ED_WriteGlobals (f); for (i = 0; i < sv.num_edicts; i++) { ED_Write (f, EDICT_NUM(i)); fflush (f); } fclose (f); Com_Printf ("done.\n"); }
void DumpConfig(char *name) { FILE *f; char *outfile, *newlines = "\n"; if (cfg_use_home.integer) // homedir outfile = va("%s/%s/%s", com_homedir, (strcmp(com_gamedirfile, "qw") == 0 || !cfg_use_gamedir.integer) ? "" : com_gamedirfile, name); else // basedir outfile = va("%s/%s/configs/%s", com_basedir, (strcmp(com_gamedirfile, "qw") == 0 || !cfg_use_gamedir.integer) ? "ezquake" : com_gamedirfile, name); if (!(f = fopen (outfile, "w"))) { FS_CreatePath(outfile); if (!(f = fopen (outfile, "w"))) { Com_Printf ("Couldn't write %s.\n", name); return; } } Com_Printf("Saving configuration to %s\n", outfile); Config_PrintPreamble(f); if (cfg_save_cvars.value) { Config_PrintHeading(f, "V A R I A B L E S"); DumpVariables(f); fprintf(f, "%s", newlines); } if (cfg_save_cmds.value) { Config_PrintHeading(f, "S E L E C T E D S O U R C E S"); WriteSourcesConfiguration(f); fprintf(f, "%s", newlines); } if (cfg_save_aliases.value) { Config_PrintHeading(f, "A L I A S E S"); DumpAliases(f); fprintf(f, "%s", newlines); } if (cfg_save_cmds.value) { Config_PrintHeading(f, "Q W 2 6 2 H U D"); DumpHUD262(f); fprintf(f, "%s", newlines); Config_PrintHeading(f, "T E A M P L A Y C O M M A N D S"); DumpTeamplay(f); fprintf(f, "%s", newlines); Config_PrintHeading(f, "M I S C E L L A N E O U S C O M M A N D S"); DumpMisc(f); fprintf(f, "%s", newlines); Config_PrintHeading(f, "P L U S C O M M A N D S"); DumpPlusCommands(f); fprintf(f, "%s", newlines); } if (cfg_save_binds.value) { Config_PrintHeading(f, "K E Y B I N D I N G S"); DumpBindings(f); } fclose(f); }