// A handler for the /ajax/send_message endpoint. static void ajax_send_message(struct mg_connection *conn, const struct mg_request_info *request_info) { struct message *message; struct session *session; char text[sizeof(message->text) - 1]; int is_jsonp; mg_printf(conn, "%s", ajax_reply_start); is_jsonp = handle_jsonp(conn, request_info); get_qsvar(request_info, "text", text, sizeof(text)); if (text[0] != '\0') { // We have a message to store. Write-lock the ringbuffer, // grab the next message and copy data into it. pthread_rwlock_wrlock(&rwlock); message = new_message(); // TODO(lsm): JSON-encode all text strings session = get_session(conn); assert(session != NULL); my_strlcpy(message->text, text, sizeof(text)); my_strlcpy(message->user, session->user, sizeof(message->user)); pthread_rwlock_unlock(&rwlock); } mg_printf(conn, "%s", text[0] == '\0' ? "false" : "true"); if (is_jsonp) { mg_printf(conn, "%s", ")"); } }
/* ----------------------------------------------------------------------------- Function: FS_FindFirstFile() -Searches a directory for a file. Parameters: path -[in] Pointer to a NUL-terminated string that specifies a valid directory or path and file name. musthave -[in] File or directory must have these attributes. canthave- [in] File or directory can not have these attributes. Returns: On success string of file name or directory, otherwise NULL. Notes: ----------------------------------------------------------------------------- */ PUBLIC char *FS_FindFirst( const char *path, W32 musthave, W32 canthave ) { struct dirent *d; char *p; p; if( fdir ) { Com_Printf( "FS_FindFirst without close\n" ); return NULL; } FS_FilePath( (char *)path, findbase ); my_strlcpy( (char *)findpattern, FS_SkipPath( (char *)path ), sizeof( findpattern ) ); if( ! *findbase ) { if( (fdir = opendir( "." )) == NULL ) { return NULL; } } else { if( (fdir = opendir( findbase )) == NULL ) { return NULL; } } while( (d = readdir( fdir )) != NULL ) { if( ! *findpattern || glob_match( findpattern, d->d_name ) ) { if( ! *findbase ) { my_strlcpy( findpath, d->d_name, sizeof( findpath ) ); } else { my_snprintf( findpath, sizeof( findpath ), "%s/%s", findbase, d->d_name ); } if( CompareAttributes( findpath, musthave, canthave ) ) { return findpath; } } } return NULL; }
/****************************************************************************** purpose: returns a new string consisting of s+t ******************************************************************************/ char *strdup_together(const char *s, const char *t) { char *both; size_t siz; if (s == NULL) { if (t == NULL) return NULL; return strdup(t); } if (t == NULL) return strdup(s); if (0) diagnostics(1, "'%s' + '%s'", s, t); siz = strlen(s) + strlen(t) + 1; both = (char *) malloc(siz); if (both == NULL) diagnostics(ERROR, "Could not allocate memory for both strings."); my_strlcpy(both, s, siz); my_strlcat(both, t, siz); return both; }
/* ----------------------------------------------------------------------------- Function: FS_FindNext -Continues a file search from a previous call to the FS_FindFirst function. Parameters: musthave -[in] File or directory must have these attributes. canthave- [in] File or directory can not have these attributes. Returns: On success string of file name or directory, otherwise NULL. Notes: ----------------------------------------------------------------------------- */ PUBLIC char *FS_FindNext( W32 musthave, W32 canthave ) { struct dirent *d; if( fdir == NULL ) { return NULL; } while( (d = readdir( fdir ) ) != NULL) { if( ! *findpattern || glob_match( findpattern, d->d_name ) ) { if( ! *findbase ) { my_strlcpy( findpath, d->d_name, sizeof( findpath ) ); } else { my_snprintf( findpath, sizeof( findpath ), "%s/%s", findbase, d->d_name ); } if( CompareAttributes( findpath, musthave, canthave ) ) { return findpath; } } } return NULL; }
char * my_strndup(const char *ptr, size_t len) { char *p; if ((p = malloc(len + 1)) != NULL) my_strlcpy(p, ptr, len + 1); return (p); }
/* ----------------------------------------------------------------------------- Function: Parameters: Returns: Notes: ----------------------------------------------------------------------------- */ PUBLIC void Client_PrepRefresh( const char *r_mapname ) { char mapname[ 32 ]; if( ! r_mapname || ! *r_mapname ) { return; } if( g_version->value == SPEAROFDESTINY ) { spritelocation = SODSPRITESDIRNAME; } else { spritelocation = WL6SPRITESDIRNAME; } my_strlcpy( mapname, r_mapname, sizeof( mapname ) ); // skip "maps/" // !@# fix crash bug if you type something short... if ( strlen( mapname ) > 4 && !strcmp( mapname + strlen( mapname ) - 4, ".map" ) ) { mapname[ strlen( mapname ) - 4 ] = '\0'; // cut off ".map" } // register models, pics, and skins R_BeginRegistration( mapname ); if( r_world == NULL ) { return; } Com_Printf( "Map: %s\n", r_world->mapName ); Level_ScanInfoPlane( r_world ); // Spawn items/guards Com_Printf( "Spawning Entities\n" ); PL_Spawn( r_world->pSpawn, r_world ); // Spawn Player Com_Printf( "Caching Textures and Sounds\n" ); Level_PrecacheTextures_Sound( r_world ); // clear any lines of console text Con_ClearNotify(); if( r_world->musicName ) { Sound_StartBGTrack( r_world->musicName, r_world->musicName ); } Player.playstate = ex_playing; }
// Allocate new session object Server::session *Server::new_session(const std::string &user) { Server::session *session = new Server::session; my_strlcpy(session->user, user.c_str(), sizeof(session->user)); snprintf(session->random, sizeof(session->random), "%d", rand()); generate_session_id(session->session_id, session->random, session->user); session->expire = time(0) + SESSION_TTL; session->admin = std::string(user) == m_user; sessions[session->session_id] = session; return session; }
/* ----------------------------------------------------------------------------- Function: Parameters: Returns: Notes: ----------------------------------------------------------------------------- */ PRIVATE void R_ScreenShot_f( void ) { W8 *buffer; char picname[ 80 ]; char checkname[ MAX_OSPATH ]; int i; FILE *f; // create the scrnshots directory if it doesn't exist my_snprintf( checkname, sizeof( checkname ), "%s/scrnshot", FS_Gamedir() ); FS_CreateDirectory( checkname ); // // find a file name to save it to // my_strlcpy( picname, "scrn00.tga", sizeof( picname ) ); for( i = 0 ; i <= 99 ; ++i ) { picname[ 4 ] = i / 10 + '0'; picname[ 5 ] = i % 10 + '0'; my_snprintf( checkname, sizeof( checkname ), "%s/scrnshot/%s", FS_Gamedir(), picname ); f = fopen( checkname, "rb" ); if( ! f ) { break; // file doesn't exist } fclose( f ); } if( i == 100 ) { Com_Printf( "R_ScreenShot_f: Couldn't create a file\n" ); return; } buffer = MM_MALLOC( viddef.width * viddef.height * 3 ); pfglReadPixels( 0, 0, viddef.width, viddef.height, GL_RGB, GL_UNSIGNED_BYTE, buffer ); WriteTGA( checkname, 24, viddef.width, viddef.height, buffer, 1, 1 ); MM_FREE( buffer ); Com_Printf( "Wrote %s\n", picname ); }
/* ----------------------------------------------------------------------------- Function: Sound_StartBGTrack -Play background music track. Parameters: introTrack -[in] File name of intro track. loopTrack -[in] File name of loop track. Returns: Nothing Notes: ----------------------------------------------------------------------------- */ PUBLIC void Sound_StartBGTrack( const char *introTrack, const char *loopTrack ) { if( ! sound_initialized ) { return; } Sound_StopBGTrack(); my_strlcpy( bgTrack.introName, introTrack, sizeof( bgTrack.introName ) ); my_strlcpy( bgTrack.loopName, loopTrack, sizeof( bgTrack.loopName) ); Sound_StartStreaming(); if( ! Sound_OpenBGTrack( bgTrack.introName, &bgTrack ) ) { Sound_StopBGTrack(); return; } Sound_StreamBGTrack(); }
// A handler for the /authorize endpoint. // Login page form sends user name and password to this endpoint. struct session* authorize_ex(struct mg_connection *conn, const struct mg_request_info *request_info) { char user[MAX_USER_LEN], password[MAX_USER_LEN]; struct session *session; if (session = if_authorized(conn, request_info)) return session; // Fetch user name and password. get_qsvar(request_info, "user", user, sizeof(user)); get_qsvar(request_info, "password", password, sizeof(password)); if (check_password(user, password) && (session = new_session()) != NULL) { my_strlcpy(session->user, user, sizeof(session->user)); snprintf(session->random, sizeof(session->random), "%d", rand()); generate_session_id(session->session_id, session->random, session->user); return session; } return 0; }
texture_t *TM_AllocateTexture( const char *name ) { texture_t *tex; int i; assert( strlen( name ) < sizeof( tex->name ) ); // find a free texture_t space for( i = 0, tex = ttextures; i < numttextures; ++i, ++tex ) { if( ! tex->texnum ) { break; } } if( i == numttextures ) { if( numttextures == MAX_TEXTURES ) { Com_DPrintf( "MAX_TEXTURES reached\n" ); return r_notexture; } numttextures++; } tex = &ttextures[ i ]; memset( tex, 0, sizeof( *tex ) ); my_strlcpy( tex->name, name, MAX_GAMEPATH ); tex->registration_sequence = texture_registration_sequence; // don't let R_Bind skip the next bind call currentTextures[ currenttmu ] = -1; pfglGenTextures( 1, &tex->texnum ); pfglBindTexture( GL_TEXTURE_2D, tex->texnum ); return tex; }
// A handler for the /authorize endpoint. // Login page form sends user name and password to this endpoint. int authorize(struct mg_connection *conn, const struct mg_request_info *request_info) { char user[MAX_USER_LEN], password[MAX_USER_LEN]; struct session *session; // Fetch user name and password. get_qsvar(request_info, "user", user, sizeof(user)); get_qsvar(request_info, "password", password, sizeof(password)); if (check_password(user, password) && (session = new_session()) != NULL) { // Authentication success: // 1. create new session // 2. set session ID token in the cookie // 3. remove original_url from the cookie - not needed anymore // 4. redirect client back to the original URL // // The most secure way is to stay HTTPS all the time. However, just to // show the technique, we redirect to HTTP after the successful // authentication. The danger of doing this is that session cookie can // be stolen and an attacker may impersonate the user. // Secure application must use HTTPS all the time. my_strlcpy(session->user, user, sizeof(session->user)); snprintf(session->random, sizeof(session->random), "%d", rand()); generate_session_id(session->session_id, session->random, session->user); mg_printf(conn, "HTTP/1.1 302 Found\r\n" "Set-Cookie: session=%s; max-age=3600; http-only\r\n" // Session ID "Set-Cookie: user=%s\r\n"// Set user, needed by Javascript code "Set-Cookie: original_url=/; max-age=0\r\n"// Delete original_url "Location: /\r\n\r\n", session->session_id, session->user); return 1; } else { // Authentication failure, redirect to login. redirect_to_login(conn, request_info); return 0; } }
/* ----------------------------------------------------------------------------- Function: Parameters: Returns: Notes: ----------------------------------------------------------------------------- */ PUBLIC void R_Init() { char renderer_buffer[ 1000 ]; char vendor_buffer[ 1000 ]; int err; int a, b; Com_Printf( "\n------ Display Initialization ------\n" ); Com_Printf( "Initializing OpenGL Subsystem\n" ); R_Register(); // set our "safe" modes gl_state.prev_mode = 0; // get various GL strings gl_config.vendor_string = (char *)pfglGetString( GL_VENDOR ); Com_Printf( "GL_VENDOR: %s\n", gl_config.vendor_string ); gl_config.renderer_string = (char *)pfglGetString( GL_RENDERER ); Com_Printf( "GL_RENDERER: %s\n", gl_config.renderer_string ); gl_config.version_string = (char *)pfglGetString( GL_VERSION ); Com_Printf( "GL_VERSION: %s\n", gl_config.version_string ); gl_config.extensions_string = (char *)pfglGetString( GL_EXTENSIONS ); Com_Printf( "GL_EXTENSIONS: %s\n", gl_config.extensions_string ); my_strlcpy( renderer_buffer, gl_config.renderer_string, sizeof( renderer_buffer ) ); (void)my_strlwr( renderer_buffer ); my_strlcpy( vendor_buffer, gl_config.vendor_string, sizeof( vendor_buffer ) ); (void)my_strlwr( vendor_buffer ); sscanf( gl_config.version_string, "%d.%d", &a, &b ); if( a >= 1 && b >= 2 ) { gl_config.Version_1_2 = true; } pfglGetIntegerv( GL_MAX_TEXTURE_SIZE, &glMaxTexSize ); Com_Printf( "GL_MAX_TEXTURE_SIZE: %d\n", glMaxTexSize); if ( strstr( gl_config.extensions_string, "GL_EXT_discard_framebuffer" ) != 0 ) { gl_config.framebuffer_discard = true; } else { gl_config.framebuffer_discard = false; } InitImmediateModeGL(); GL_SetDefaultState(); TM_Init(); Font_Init(); err = pfglGetError(); if( err != GL_NO_ERROR ) { Com_Printf( "glGetError() = 0x%x\n", err ); } }
static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* context, bool succeeded) { //printf("Wrote minidump to: %s\n", descriptor.path()); if (succeeded) { sys_write(STDOUT_FILENO, "Wrote minidump to: ", 19); } else { sys_write(STDOUT_FILENO, "Failed to write minidump to: ", 29); } sys_write(STDOUT_FILENO, descriptor.path(), my_strlen(descriptor.path())); sys_write(STDOUT_FILENO, "\n", 1); if (!succeeded) { return succeeded; } my_strlcpy(dumpStoragePath, descriptor.path(), sizeof(dumpStoragePath)); my_strlcat(dumpStoragePath, ".txt", sizeof(dumpStoragePath)); int extra = sys_open(dumpStoragePath, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); if (extra == -1) { sys_write(STDOUT_FILENO, "Failed to open metadata file!\n", 30); return succeeded; } sys_write(extra, "-------- CONFIG BEGIN --------", 30); sys_write(extra, "\nMap=", 5); sys_write(extra, crashMap, my_strlen(crashMap)); sys_write(extra, "\nGamePath=", 10); sys_write(extra, crashGamePath, my_strlen(crashGamePath)); sys_write(extra, "\nCommandLine=", 13); sys_write(extra, crashCommandLine, my_strlen(crashCommandLine)); sys_write(extra, "\nSourceModPath=", 15); sys_write(extra, crashSourceModPath, my_strlen(crashSourceModPath)); sys_write(extra, "\nGameDirectory=", 15); sys_write(extra, crashGameDirectory, my_strlen(crashGameDirectory)); sys_write(extra, "\nExtensionVersion=", 18); sys_write(extra, SM_VERSION, my_strlen(SM_VERSION)); sys_write(extra, "\nExtensionBuild=", 16); sys_write(extra, SM_BUILD_UNIQUEID, my_strlen(SM_BUILD_UNIQUEID)); sys_write(extra, steamInf, my_strlen(steamInf)); sys_write(extra, "\n-------- CONFIG END --------\n", 30); if (GetSpew) { GetSpew(spewBuffer, sizeof(spewBuffer)); if (my_strlen(spewBuffer) > 0) { sys_write(extra, "-------- CONSOLE HISTORY BEGIN --------\n", 40); sys_write(extra, spewBuffer, my_strlen(spewBuffer)); sys_write(extra, "-------- CONSOLE HISTORY END --------\n", 38); } } #if 0 char pis[64]; char pds[32]; for (unsigned i = 0; i < plugin_count; ++i) { PluginInfo *p = &plugins[i]; if (p->serial == 0) continue; my_uitos(pds, i, my_uint_len(i)); pds[my_uint_len(i)] = '\0'; my_strlcpy(pis, "plugin[", sizeof(pis)); my_strlcat(pis, pds, sizeof(pis)); my_strlcat(pis, "].", sizeof(pis)); sys_write(extra, pis, my_strlen(pis)); sys_write(extra, "filename=", 9); sys_write(extra, p->filename, my_strlen(p->filename)); sys_write(extra, "\n", 1); sys_write(extra, pis, my_strlen(pis)); sys_write(extra, "name=", 5); sys_write(extra, p->name, my_strlen(p->name)); sys_write(extra, "\n", 1); sys_write(extra, pis, my_strlen(pis)); sys_write(extra, "author=", 7); sys_write(extra, p->author, my_strlen(p->author)); sys_write(extra, "\n", 1); sys_write(extra, pis, my_strlen(pis)); sys_write(extra, "description=", 12); sys_write(extra, p->description, my_strlen(p->description)); sys_write(extra, "\n", 1); sys_write(extra, pis, my_strlen(pis)); sys_write(extra, "version=", 8); sys_write(extra, p->version, my_strlen(p->version)); sys_write(extra, "\n", 1); sys_write(extra, pis, my_strlen(pis)); sys_write(extra, "url=", 4); sys_write(extra, p->url, my_strlen(p->url)); sys_write(extra, "\n", 1); } #endif sys_close(extra); return succeeded; }
/* ----------------------------------------------------------------------------- Function: Parameters: Returns: Notes: ----------------------------------------------------------------------------- */ PUBLIC void Client_PrepRefresh( const char *r_mapname ) { // char mapname[ 32 ]; char mapname[ 64 ]; //gsh, decided to allow longer map names if( ! r_mapname || ! *r_mapname ) { return; } if( g_version->value == SPEAROFDESTINY && currentMap.episode >= 6 && currentMap.episode < 10)//added the episode check... gsh) { spritelocation = SODSPRITESDIRNAME; } else { spritelocation = WL6SPRITESDIRNAME; } my_strlcpy( mapname, r_mapname, sizeof( mapname ) ); // skip "maps/" // !@# fix crash bug if you type something short... if ( strlen( mapname ) > 4 && !strcmp( mapname + strlen( mapname ) - 4, ".map" ) ) { mapname[ strlen( mapname ) - 4 ] = '\0'; // cut off ".map" } // register models, pics, and skins R_BeginRegistration( mapname ); if( r_world == NULL ) { return; } Com_Printf( "Map: %s\n", r_world->mapName ); Level_ScanInfoPlane( r_world ); // Spawn items/guards Com_Printf( "Spawning Entities\n" ); PL_Spawn( r_world->pSpawn, r_world ); // Spawn Player Com_Printf( "Caching Textures and Sounds\n" ); Level_PrecacheTextures_Sound( r_world ); // clear any lines of console text Con_ClearNotify(); //gsh //this is a hack... to save space on the download... we've removed the music //so instead we're going to replace the SOD music with wolf3d music here //however, we don't have to worry about that now that we package the SOD music //with the binary /* if (currentMap.episode >= 6) //if it's the SOD levels { char *source; switch (currentMap.episode * 10 + currentMap.map) { case 60: source = "ZEROHOUR.ogg"; break; case 61: source = "CORNER.ogg"; break; case 62: source = "DUNGEON.ogg"; break; case 63: source = "ENDLEVEL.ogg"; break; case 64: source = "FUNKYOU.ogg"; break; case 65: source = "HEADACHE.ogg"; break; case 66: source = "HITLWLTZ.ogg"; break; case 67: source = "INTROCW3.ogg"; break; case 68: source = "NAZI_NOR.ogg"; break; case 69: source = "NAZI_OMI.ogg"; break; case 70: source = "NAZI_RAP.ogg"; break; case 71: source = "PACMAN.ogg"; break; case 72: source = "POW.ogg"; break; case 73: source = "PREGNANT.ogg"; break; case 74: source = "ROSTER.ogg"; break; case 75: source = "SALUTE.ogg"; break; case 76: source = "SEARCHN.ogg"; break; case 77: source = "SUSPENSE.ogg"; break; case 78: source = "TWELFTH.ogg"; break; case 79: source = "URAHERO.ogg"; break; case 80: source = "ULTIMATE.ogg"; break; default: source = "CORNER.ogg"; } strcpy(levelData.musicName + 6, source); //the '6' is to get us past the "music/" part of musicName levelData.musicName[6 + strlen(source)] = '\0'; }*/ Com_Printf("Starting Music Track: %s\n", levelData.musicName); Sound_StartBGTrack( levelData.musicName, levelData.musicName ); Player.playstate = ex_playing; }
/* ----------------------------------------------------------------------------- Function: Cmd_Alias_f -Creates a new command that executes a command string (possibly ; seperated). Parameters: Nothing. Returns: Nothing. Notes: ----------------------------------------------------------------------------- */ PRIVATE void Cmd_Alias_f( void ) { cmdalias_t *a; char cmd[ 1024 ]; int i, c; char *s; W32 hashid; if( Cmd_Argc() == 1 ) { Com_Printf( "Current alias commands:\n" ); for( a = cmd_alias ; a ; a = a->next ) { Com_Printf( "%s : %s\n", a->name, a->value ); } return; } s = Cmd_Argv( 1 ); if( strlen( s ) >= MAX_ALIAS_NAME ) { Com_Printf( "Alias name is too long\n" ); return; } hashid = my_strhash( s ); // if the alias already exists, reuse it for( a = cmd_alias ; a ; a = a->next ) { if( hashid == a->id ) { Z_Free( a->value ); break; } } if( ! a ) { a = Z_Malloc( sizeof( cmdalias_t ) ); a->next = cmd_alias; cmd_alias = a; } my_strlcpy( a->name, s, sizeof( a->name ) ); a->id = hashid; // copy the rest of the command line cmd[ 0 ] = '\0'; // start out with a NUL-terminated string c = Cmd_Argc(); for( i = 2; i < c; ++i ) { my_strlcat( cmd, Cmd_Argv( i ), sizeof( cmd ) ); if( i != (c - 1) ) { my_strlcat( cmd, " ", sizeof( cmd ) ); } } my_strlcat( cmd, "\n", sizeof( cmd ) ); a->value = my_CopyString( cmd ); }
/* ----------------------------------------------------------------------------- Function: Cmd_MacroExpandString Parameters: Returns: Notes: ----------------------------------------------------------------------------- */ PRIVATE char *Cmd_MacroExpandString( char *text ) { int i, j, count, len; _boolean inquote; char *scan; static char expanded[ MAX_STRING_CHARS ]; char temporary[MAX_STRING_CHARS]; char *token, *start; inquote = false; scan = text; len = strlen( scan ); if( len >= MAX_STRING_CHARS ) { Com_Printf( "Line exceeded %i chars, discarded.\n", MAX_STRING_CHARS ); return NULL; } count = 0; for( i = 0 ; i < len ; ++i ) { if (scan[i] == '"') inquote ^= 1; if (inquote) continue; // don't expand inside quotes if (scan[i] != '$') continue; // scan out the complete macro start = scan+i+1; token = COM_Parse( &start ); if (!start) continue; token = Cvar_VariableString (token); j = strlen(token); len += j; if (len >= MAX_STRING_CHARS) { Com_Printf ("Expanded line exceeded %i chars, discarded.\n", MAX_STRING_CHARS); return NULL; } strncpy( temporary, scan, i ); my_strlcpy( temporary+i, token, sizeof( temporary ) - i ); my_strlcpy( temporary+i+j, start, sizeof( temporary ) - i - j ); my_strlcpy( expanded, temporary, sizeof( expanded ) ); scan = expanded; i--; if( ++count == 100 ) { Com_Printf( "Macro expansion loop, discarded.\n" ); return NULL; } } if( inquote ) { Com_Printf( "Line has unmatched quote, discarded.\n" ); return NULL; } return scan; }
/* ----------------------------------------------------------------------------- Function: Cmd_TokenizeString -Parses the given string into command line tokens. Parameters: text -[in] string to tokenize. macroExpand -[in] Expand macro, true for yes, otherwise false. Returns: Nothing Notes: $Cvars will be expanded unless they are in a quoted token ----------------------------------------------------------------------------- */ PUBLIC void Cmd_TokenizeString( char *text, _boolean macroExpand ) { int i; char *com_token; // clear the args from the last string for( i = 0 ; i < cmd_argc ; ++i ) { Z_Free( cmd_argv[ i ] ); } cmd_argc = 0; cmd_args[ 0 ] = 0; // macro expand the text if( macroExpand ) { text = Cmd_MacroExpandString( text ); } if( ! text ) { return; } while( 1 ) { // skip whitespace up to a /n while( *text && *text <= ' ' && *text != '\n' ) { text++; } if( *text == '\n' ) { // a newline seperates commands in the buffer text++; break; } if( ! *text ) { return; } // set cmd_args to everything after the first arg if( cmd_argc == 1 ) { int l; my_strlcpy( cmd_args, text, sizeof( cmd_args ) - 1 ); // strip off any trailing whitespace l = strlen( cmd_args ) - 1; for( ; l >= 0 ; --l ) { if (cmd_args[l] <= ' ') { cmd_args[l] = 0; } else { break; } } } com_token = COM_Parse( &text ); if( ! text ) { return; } if( cmd_argc < MAX_STRING_TOKENS ) { cmd_argv[ cmd_argc ] = Z_Malloc( strlen( com_token ) + 1 ); my_strlcpy( cmd_argv[ cmd_argc ], com_token, strlen( com_token ) + 1 ); cmd_argc++; } } }