2000-01-03 06:51:43 +00:00
|
|
|
/*
|
|
|
|
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.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
#include "master.h"
|
|
|
|
|
|
|
|
int com_argc;
|
|
|
|
char **com_argv;
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
COM_CheckParm
|
|
|
|
|
|
|
|
Returns the position (1 to argc-1) in the program's argument list
|
|
|
|
where the given parameter apears, or 0 if not present
|
|
|
|
================
|
|
|
|
*/
|
|
|
|
int COM_CheckParm (char *parm)
|
|
|
|
{
|
|
|
|
int i;
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
for (i=1 ; i<com_argc ; i++)
|
|
|
|
{
|
|
|
|
if (!com_argv[i])
|
|
|
|
continue; // NEXTSTEP sometimes clears appkit vars.
|
|
|
|
if (!strcmp (parm,com_argv[i]))
|
|
|
|
return i;
|
|
|
|
}
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *AdrToString (netadr_t a)
|
|
|
|
{
|
|
|
|
static char s[64];
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
sprintf (s, "%i.%i.%i.%i:%i",
|
|
|
|
a.sin_addr.S_un.S_un_b.s_b1,
|
|
|
|
a.sin_addr.S_un.S_un_b.s_b2,
|
|
|
|
a.sin_addr.S_un.S_un_b.s_b3,
|
|
|
|
a.sin_addr.S_un.S_un_b.s_b4,
|
|
|
|
ntohs(a.sin_port));
|
|
|
|
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
netadr_t StringToAdr (char *s)
|
|
|
|
{
|
|
|
|
netadr_t a;
|
|
|
|
int b1, b2, b3, b4, p;
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
b1 = b2 = b3 = b4 = p = 0;
|
|
|
|
sscanf (s, "%i.%i.%i.%i:%i", &b1, &b2, &b3, &b4, &p);
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
a.sin_addr.S_un.S_un_b.s_b1 = b1;
|
|
|
|
a.sin_addr.S_un.S_un_b.s_b2 = b2;
|
|
|
|
a.sin_addr.S_un.S_un_b.s_b3 = b3;
|
|
|
|
a.sin_addr.S_un.S_un_b.s_b4 = b4;
|
|
|
|
a.sin_port = ntohs(p);
|
|
|
|
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
qboolean CompareAdr (netadr_t a, netadr_t b)
|
|
|
|
{
|
2000-03-19 15:59:51 +00:00
|
|
|
if (a.sin_addr.s_addr == b.sin_addr.s_addr
|
1999-12-25 05:22:39 +00:00
|
|
|
&& a.sin_port == b.sin_port)
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void mprintf (char *msg, ...)
|
|
|
|
{
|
|
|
|
va_list argptr;
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
va_start (argptr, msg);
|
|
|
|
vprintf (msg, argptr);
|
|
|
|
vfprintf (logfile, msg, argptr);
|
|
|
|
va_end (argptr);
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int msg_readcount;
|
|
|
|
char *MSG_ReadString (void)
|
|
|
|
{
|
|
|
|
char *start;
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
start = packet_data + msg_readcount;
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
for ( ; msg_readcount < packet_length ; msg_readcount++)
|
|
|
|
if (packet_data[msg_readcount] == '\n'
|
|
|
|
|| packet_data[msg_readcount] == 0)
|
|
|
|
break;
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
packet_data[msg_readcount] = 0;
|
|
|
|
msg_readcount++;
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
return start;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
=====================================================================
|
|
|
|
|
|
|
|
COMMAND LINES
|
|
|
|
|
|
|
|
=====================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define MAX_ARGS 32
|
|
|
|
#define MAX_ARG_LENGTH 1024
|
|
|
|
int cmd_argc;
|
|
|
|
char cmd_argv[MAX_ARGS][MAX_ARG_LENGTH];
|
|
|
|
|
|
|
|
char com_token[1024];
|
|
|
|
/*
|
|
|
|
==============
|
|
|
|
COM_Parse
|
|
|
|
|
|
|
|
Parse a token out of a string
|
|
|
|
==============
|
|
|
|
*/
|
|
|
|
char *COM_Parse (char *data)
|
|
|
|
{
|
|
|
|
int c;
|
|
|
|
int len;
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
len = 0;
|
|
|
|
com_token[0] = 0;
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
if (!data)
|
|
|
|
return NULL;
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
// skip whitespace
|
|
|
|
skipwhite:
|
|
|
|
while ( (c = *data) <= ' ')
|
|
|
|
{
|
|
|
|
if (c == 0)
|
|
|
|
return NULL; // end of file;
|
|
|
|
data++;
|
|
|
|
}
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
// skip // comments
|
|
|
|
if (c=='/' && data[1] == '/')
|
|
|
|
{
|
|
|
|
while (*data && *data != '\n')
|
|
|
|
data++;
|
|
|
|
goto skipwhite;
|
|
|
|
}
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
|
|
|
|
// handle quoted strings specially
|
|
|
|
if (c == '\"')
|
|
|
|
{
|
|
|
|
data++;
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
c = *data++;
|
|
|
|
if (c=='\"' || !c)
|
|
|
|
{
|
|
|
|
com_token[len] = 0;
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
com_token[len] = c;
|
|
|
|
len++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// parse a regular word
|
|
|
|
do
|
|
|
|
{
|
|
|
|
com_token[len] = c;
|
|
|
|
data++;
|
|
|
|
len++;
|
|
|
|
c = *data;
|
|
|
|
} while (c>32);
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
com_token[len] = 0;
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Cmd_Argc
|
|
|
|
============
|
|
|
|
*/
|
|
|
|
int Cmd_Argc (void)
|
|
|
|
{
|
|
|
|
return cmd_argc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Cmd_Argv
|
|
|
|
============
|
|
|
|
*/
|
|
|
|
char *Cmd_Argv (int arg)
|
|
|
|
{
|
|
|
|
if ( (unsigned)arg >= cmd_argc )
|
|
|
|
return "";
|
2000-03-19 15:59:51 +00:00
|
|
|
return cmd_argv[arg];
|
1999-12-25 05:22:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
Cmd_TokenizeString
|
|
|
|
|
|
|
|
Parses the given string into command line tokens.
|
|
|
|
============
|
|
|
|
*/
|
|
|
|
void Cmd_TokenizeString (char *text)
|
2000-03-19 15:59:51 +00:00
|
|
|
{
|
1999-12-25 05:22:39 +00:00
|
|
|
cmd_argc = 0;
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
// skip whitespace up to a /n
|
|
|
|
while (*text && *text <= ' ')
|
|
|
|
{
|
|
|
|
text++;
|
|
|
|
}
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
if (!*text)
|
|
|
|
return;
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
text = COM_Parse (text);
|
|
|
|
if (!text)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (cmd_argc < MAX_ARGS)
|
|
|
|
{
|
|
|
|
strcpy (cmd_argv[cmd_argc], com_token);
|
|
|
|
cmd_argc++;
|
|
|
|
}
|
|
|
|
}
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
=====================================================================
|
|
|
|
|
|
|
|
INFO STRINGS
|
|
|
|
|
|
|
|
=====================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
===============
|
|
|
|
Info_ValueForKey
|
|
|
|
|
|
|
|
Searches the string (userinfo or masterinfo) for the given
|
|
|
|
key and returns the associated value, or an empty string.
|
|
|
|
===============
|
|
|
|
*/
|
|
|
|
char *Info_ValueForKey (char *s, char *key)
|
|
|
|
{
|
|
|
|
char pkey[512];
|
|
|
|
static char value[512];
|
|
|
|
char *o;
|
2000-03-19 15:59:51 +00:00
|
|
|
|
1999-12-25 05:22:39 +00:00
|
|
|
if (*s == '\\')
|
|
|
|
s++;
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
o = pkey;
|
|
|
|
while (*s != '\\')
|
|
|
|
{
|
|
|
|
if (!*s)
|
|
|
|
return "";
|
|
|
|
*o++ = *s++;
|
|
|
|
}
|
|
|
|
*o = 0;
|
|
|
|
s++;
|
|
|
|
|
|
|
|
o = value;
|
|
|
|
while (*s != '\\' && *s)
|
|
|
|
{
|
|
|
|
if (!*s)
|
|
|
|
return "";
|
|
|
|
*o++ = *s++;
|
|
|
|
}
|
|
|
|
*o = 0;
|
|
|
|
|
|
|
|
if (!strcmp (key, pkey) )
|
|
|
|
return value;
|
|
|
|
|
|
|
|
if (!*s)
|
|
|
|
return "";
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Info_RemoveKey (char *s, char *key)
|
|
|
|
{
|
|
|
|
char *start;
|
|
|
|
char pkey[512];
|
|
|
|
char value[512];
|
|
|
|
char *o;
|
|
|
|
|
|
|
|
if (strstr (key, "\\"))
|
|
|
|
{
|
|
|
|
printf ("Can't use a key with a \\\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
start = s;
|
|
|
|
if (*s == '\\')
|
|
|
|
s++;
|
|
|
|
o = pkey;
|
|
|
|
while (*s != '\\')
|
|
|
|
{
|
|
|
|
if (!*s)
|
|
|
|
return;
|
|
|
|
*o++ = *s++;
|
|
|
|
}
|
|
|
|
*o = 0;
|
|
|
|
s++;
|
|
|
|
|
|
|
|
o = value;
|
|
|
|
while (*s != '\\' && *s)
|
|
|
|
{
|
|
|
|
if (!*s)
|
|
|
|
return;
|
|
|
|
*o++ = *s++;
|
|
|
|
}
|
|
|
|
*o = 0;
|
|
|
|
|
|
|
|
if (!strcmp (key, pkey) )
|
|
|
|
{
|
|
|
|
strcpy (start, s); // remove this part
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!*s)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void Info_RemovePrefixedKeys (char *start, char prefix)
|
|
|
|
{
|
|
|
|
char *s;
|
|
|
|
char pkey[512];
|
|
|
|
char value[512];
|
|
|
|
char *o;
|
|
|
|
|
|
|
|
s = start;
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
if (*s == '\\')
|
|
|
|
s++;
|
|
|
|
o = pkey;
|
|
|
|
while (*s != '\\')
|
|
|
|
{
|
|
|
|
if (!*s)
|
|
|
|
return;
|
|
|
|
*o++ = *s++;
|
|
|
|
}
|
|
|
|
*o = 0;
|
|
|
|
s++;
|
|
|
|
|
|
|
|
o = value;
|
|
|
|
while (*s != '\\' && *s)
|
|
|
|
{
|
|
|
|
if (!*s)
|
|
|
|
return;
|
|
|
|
*o++ = *s++;
|
|
|
|
}
|
|
|
|
*o = 0;
|
|
|
|
|
|
|
|
if (pkey[0] == prefix)
|
|
|
|
{
|
|
|
|
Info_RemoveKey (start, pkey);
|
|
|
|
s = start;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!*s)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void Info_SetValueForKey (char *s, char *key, char *value)
|
|
|
|
{
|
|
|
|
char new[512];
|
|
|
|
|
|
|
|
if (strstr (key, "\\") || strstr (value, "\\") )
|
|
|
|
{
|
|
|
|
printf ("Can't use keys or values with a \\\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (strstr (key, "\"") || strstr (value, "\"") )
|
|
|
|
{
|
|
|
|
printf ("Can't use keys or values with a \\\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Info_RemoveKey (s, key);
|
|
|
|
if (!value || !strlen(value))
|
|
|
|
return;
|
|
|
|
|
|
|
|
sprintf (new, "\\%s\\%s", key, value);
|
|
|
|
|
|
|
|
if (strlen(new) + strlen(s) > MAX_INFO_STRING)
|
|
|
|
{
|
|
|
|
printf ("Info string length exceeded\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
strcat (s, new);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Info_Print (char *s)
|
|
|
|
{
|
|
|
|
char key[512];
|
|
|
|
char value[512];
|
|
|
|
char *o;
|
|
|
|
int l;
|
|
|
|
|
|
|
|
if (*s == '\\')
|
|
|
|
s++;
|
|
|
|
while (*s)
|
|
|
|
{
|
|
|
|
o = key;
|
|
|
|
while (*s && *s != '\\')
|
|
|
|
*o++ = *s++;
|
|
|
|
|
|
|
|
l = o - key;
|
|
|
|
if (l < 20)
|
|
|
|
{
|
|
|
|
memset (o, ' ', 20-l);
|
|
|
|
key[20] = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
*o = 0;
|
|
|
|
printf ("%s", key);
|
|
|
|
|
|
|
|
if (!*s)
|
|
|
|
{
|
|
|
|
printf ("MISSING VALUE\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
o = value;
|
|
|
|
s++;
|
|
|
|
while (*s && *s != '\\')
|
|
|
|
*o++ = *s++;
|
|
|
|
*o = 0;
|
|
|
|
|
|
|
|
if (*s)
|
|
|
|
s++;
|
|
|
|
printf ("%s\n", value);
|
|
|
|
}
|
|
|
|
}
|