1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19 
20 //
21 // infostrings.c
22 //
23 
24 #include "shared.h"
25 
26 /*
27 =============================================================================
28 
29 	INFO STRINGS
30 
31 =============================================================================
32 */
33 
34 /*
35 ================
36 Info_Print
37 ================
38 */
Info_Print(char * s)39 void Info_Print (char *s)
40 {
41 	char	key[512];
42 	char	value[512];
43 	char	*o;
44 	int		l;
45 
46 	if (*s == '\\')
47 		s++;
48 
49 	while (*s) {
50 		o = key;
51 		while (*s && *s != '\\')
52 			*o++ = *s++;
53 
54 		l = o - key;
55 		if (l < 20) {
56 			memset (o, ' ', 20-l);
57 			key[20] = 0;
58 		}
59 		else
60 			*o = 0;
61 		Com_Printf (0, "%s", key);
62 
63 		if (!*s) {
64 			Com_Printf (0, "MISSING VALUE\n");
65 			return;
66 		}
67 
68 		o = value;
69 		s++;
70 		while (*s && *s != '\\')
71 			*o++ = *s++;
72 		*o = 0;
73 
74 		if (*s)
75 			s++;
76 		Com_Printf (0, "%s\n", value);
77 	}
78 }
79 
80 
81 /*
82 ===============
83 Info_ValueForKey
84 
85 Searches the string for the given key and returns the associated value, or an empty string.
86 
87 Uses two buffers to lessen the chance of stomping.
88 ===============
89 */
Info_ValueForKey(char * s,char * key)90 char *Info_ValueForKey (char *s, char *key)
91 {
92 	char		pkey[512];
93 	static char value[2][512];
94 	static int	valueIndex;
95 	char		*o;
96 
97 	valueIndex ^= 1;
98 	if (*s == '\\')
99 		s++;
100 
101 	for ( ; ; ) {
102 		o = pkey;
103 		while (*s != '\\') {
104 			if (!*s)
105 				return "";
106 			*o++ = *s++;
107 		}
108 		*o = 0;
109 		s++;
110 
111 		o = value[valueIndex];
112 
113 		while (*s != '\\' && *s) {
114 			if (!*s)
115 				return "";
116 			*o++ = *s++;
117 		}
118 		*o = 0;
119 
120 		if (!strcmp (key, pkey))
121 			return value[valueIndex];
122 
123 		if (!*s)
124 			return "";
125 		s++;
126 	}
127 }
128 
129 
130 /*
131 ==================
132 Info_RemoveKey
133 ==================
134 */
Info_RemoveKey(char * s,char * key)135 void Info_RemoveKey (char *s, char *key)
136 {
137 	char	*start;
138 	char	pkey[512];
139 	char	value[512];
140 	char	*o;
141 
142 	if (strstr (key, "\\"))
143 		return;
144 
145 	for ( ; ; ) {
146 		start = s;
147 		if (*s == '\\')
148 			s++;
149 		o = pkey;
150 		while (*s != '\\') {
151 			if (!*s)
152 				return;
153 			*o++ = *s++;
154 		}
155 		*o = 0;
156 		s++;
157 
158 		o = value;
159 		while (*s != '\\' && *s) {
160 			if (!*s)
161 				return;
162 			*o++ = *s++;
163 		}
164 		*o = 0;
165 
166 		if (!strcmp (key, pkey)) {
167 			strcpy (start, s);	// Remove this part
168 			return;
169 		}
170 
171 		if (!*s)
172 			return;
173 	}
174 
175 }
176 
177 
178 /*
179 ==================
180 Info_Validate
181 
182 Some characters are illegal in info strings because they
183 can mess up the server's parsing
184 ==================
185 */
Info_Validate(char * s)186 qBool Info_Validate (char *s)
187 {
188 	if (strstr (s, "\""))
189 		return qFalse;
190 	if (strstr (s, ";"))
191 		return qFalse;
192 
193 	return qTrue;
194 }
195 
196 
197 /*
198 ==================
199 Info_SetValueForKey
200 ==================
201 */
Info_SetValueForKey(char * s,char * key,char * value)202 void Info_SetValueForKey (char *s, char *key, char *value)
203 {
204 	char	newPair[MAX_INFO_STRING], *v;
205 	int		c;
206 
207 	// Sanity check
208 	if (strstr (key, "\\")) {
209 		Com_Printf (PRNT_WARNING, "Can't use keys with a \\\n");
210 		return;
211 	}
212 	if (strstr (value, "\\")) {
213 		Com_Printf (PRNT_WARNING, "Can't use values with a \\\n");
214 		return;
215 	}
216 	if (strstr (key, ";")) {
217 		Com_Printf (PRNT_WARNING, "Can't use keys or values with a semicolon\n");
218 		return;
219 	}
220 	if (strstr (key, "\"")) {
221 		Com_Printf (PRNT_WARNING, "Can't use keys with a \"\n");
222 		return;
223 	}
224 	if (strstr (value, "\"")) {
225 		Com_Printf (PRNT_WARNING, "Can't use values with a \"\n");
226 		return;
227 	}
228 	if (strlen (key) > MAX_INFO_KEY-1 || strlen (value) > MAX_INFO_KEY-1) {
229 		Com_Printf (PRNT_WARNING, "Keys and values must be < %i characters.\n", MAX_INFO_KEY);
230 		return;
231 	}
232 
233 	// Remove the key so it can be re-added cleanly
234 	Info_RemoveKey (s, key);
235 	if (!value || !strlen (value))
236 		return;
237 
238 	// Generate the key and make sure it will fit
239 	Q_snprintfz (newPair, sizeof (newPair), "\\%s\\%s", key, value);
240 	if (strlen (newPair) + strlen (s) > MAX_INFO_STRING-1) {
241 		Com_Printf (PRNT_WARNING, "Info string length exceeded\n");
242 		return;
243 	}
244 
245 	// Only copy ascii values
246 	s += strlen (s);
247 	for (v=newPair ; *v ; ) {
248 		c = *v++;
249 		c &= 127;	// Strip high bits
250 		if (c >= 32 && c < 127)
251 			*s++ = c;
252 	}
253 	*s = 0;
254 }
255