Mercurial > pidgin
comparison src/protocols/qq/utils.c @ 14015:9516a796ed5f
[gaim-migrate @ 16607]
Added a debugging tool for firing custom packets at the QQ server.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Huetsch <markhuetsch> |
---|---|
date | Tue, 01 Aug 2006 17:39:47 +0000 |
parents | 16102b9c5c4a |
children | 39d6d4128599 |
comparison
equal
deleted
inserted
replaced
14014:9c5790820ac6 | 14015:9516a796ed5f |
---|---|
18 * You should have received a copy of the GNU General Public License | 18 * You should have received a copy of the GNU General Public License |
19 * along with this program; if not, write to the Free Software | 19 * along with this program; if not, write to the Free Software |
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 */ | 21 */ |
22 | 22 |
23 // START OF FILE | |
24 /*****************************************************************************/ | |
25 #include "stdlib.h" // strtol | 23 #include "stdlib.h" // strtol |
26 #include "limits.h" | 24 #include "limits.h" |
27 #include "string.h" // strlen | 25 #include "string.h" // strlen |
28 | 26 |
29 #ifdef _WIN32 | 27 #ifdef _WIN32 |
44 return !strncmp(str, prefix, len); | 42 return !strncmp(str, prefix, len); |
45 } | 43 } |
46 #endif | 44 #endif |
47 | 45 |
48 /*****************************************************************************/ | 46 /*****************************************************************************/ |
49 gchar *get_name_by_index_str(gchar ** array, const gchar * index_str, gint amount) { | 47 gchar *get_name_by_index_str(gchar **array, const gchar *index_str, gint amount) { |
50 gint index; | 48 gint index; |
51 | 49 |
52 index = atoi(index_str); | 50 index = atoi(index_str); |
53 if (index < 0 || index >= amount) | 51 if (index < 0 || index >= amount) |
54 index = 0; | 52 index = 0; |
55 | 53 |
56 return array[index]; | 54 return array[index]; |
57 } // get_name_by_index_str | 55 } // get_name_by_index_str |
58 | 56 |
59 /*****************************************************************************/ | 57 /*****************************************************************************/ |
60 gchar *get_index_str_by_name(gchar ** array, const gchar * name, gint amount) { | 58 gchar *get_index_str_by_name(gchar **array, const gchar *name, gint amount) { |
61 gint index; | 59 gint index; |
62 | 60 |
63 for (index = 0; index <= amount; index++) | 61 for (index = 0; index <= amount; index++) |
64 if (g_ascii_strcasecmp(array[index], name) == 0) | 62 if (g_ascii_strcasecmp(array[index], name) == 0) |
65 break; | 63 break; |
68 index = 0; // meaning no match | 66 index = 0; // meaning no match |
69 return g_strdup_printf("%d", index); | 67 return g_strdup_printf("%d", index); |
70 } // get_index_str_by_name | 68 } // get_index_str_by_name |
71 | 69 |
72 /*****************************************************************************/ | 70 /*****************************************************************************/ |
73 gint qq_string_to_dec_value(const gchar * str) | 71 gint qq_string_to_dec_value(const gchar *str) |
74 { | 72 { |
75 g_return_val_if_fail(str != NULL, 0); | 73 g_return_val_if_fail(str != NULL, 0); |
76 return strtol(str, NULL, 10); | 74 return strtol(str, NULL, 10); |
77 } // _qq_string_to_dec_value | 75 } // _qq_string_to_dec_value |
78 | 76 |
79 /*****************************************************************************/ | 77 /*****************************************************************************/ |
80 // split the given data(len) with delimit, | 78 // split the given data(len) with delimit, |
81 // check the number of field matches the expected_fields (<=0 means all) | 79 // check the number of field matches the expected_fields (<=0 means all) |
82 // return gchar* array (needs to be freed by g_strfreev later), or NULL | 80 // return gchar* array (needs to be freed by g_strfreev later), or NULL |
83 gchar **split_data(guint8 * data, gint len, const gchar * delimit, gint expected_fields) { | 81 gchar **split_data(guint8 *data, gint len, const gchar *delimit, gint expected_fields) { |
84 | 82 |
85 guint8 *input; | 83 guint8 *input; |
86 gchar **segments; | 84 gchar **segments; |
87 gint i, j; | 85 gint i, j; |
88 | 86 |
109 gaim_debug(GAIM_DEBUG_WARNING, "QQ", | 107 gaim_debug(GAIM_DEBUG_WARNING, "QQ", |
110 "Dangerous data, expect %d fields, found %d, return all\n", expected_fields, i); | 108 "Dangerous data, expect %d fields, found %d, return all\n", expected_fields, i); |
111 // free up those not used | 109 // free up those not used |
112 for (j = expected_fields; j < i; j++) { | 110 for (j = expected_fields; j < i; j++) { |
113 gaim_debug(GAIM_DEBUG_WARNING, "QQ", "field[%d] is %s\n", j, segments[j]); | 111 gaim_debug(GAIM_DEBUG_WARNING, "QQ", "field[%d] is %s\n", j, segments[j]); |
114 g_free(segments[j]); // bug found by gfhuang ! i -> j | 112 g_free(segments[j]); |
115 } | 113 } |
116 | 114 |
117 segments[expected_fields] = NULL; | 115 segments[expected_fields] = NULL; |
118 } // if i | 116 } |
119 | 117 |
120 return segments; | 118 return segments; |
121 } // split_data | 119 } |
122 | 120 |
123 /*****************************************************************************/ | 121 /*****************************************************************************/ |
124 // given a four-byte ip data, convert it into a human readable ip string | 122 // given a four-byte ip data, convert it into a human readable ip string |
125 // the return needs to be freed | 123 // the return needs to be freed |
126 gchar *gen_ip_str(guint8 * ip) | 124 gchar *gen_ip_str(guint8 *ip) |
127 { | 125 { |
128 if (ip == NULL || ip[0] == 0) | 126 if (ip == NULL || ip[0] == 0) |
129 return g_strdup_printf(""); | 127 return g_strdup_printf(""); |
130 else | 128 else |
131 return g_strdup_printf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); | 129 return g_strdup_printf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); |
132 } | 130 } |
133 | 131 |
134 // by gfhuang | |
135 guint8 *str_ip_gen(gchar *str) { | 132 guint8 *str_ip_gen(gchar *str) { |
136 guint8 *ip = g_new(guint8, 4); | 133 guint8 *ip = g_new(guint8, 4); |
137 int a, b, c, d; | 134 int a, b, c, d; |
138 sscanf(str, "%d.%d.%d.%d", &a, &b, &c, &d); | 135 sscanf(str, "%d.%d.%d.%d", &a, &b, &c, &d); |
139 ip[0] = a; | 136 ip[0] = a; |
159 return g_strdup_printf(QQ_NAME_FORMAT, uid); | 156 return g_strdup_printf(QQ_NAME_FORMAT, uid); |
160 } // uid_to_gaim_name | 157 } // uid_to_gaim_name |
161 | 158 |
162 /*****************************************************************************/ | 159 /*****************************************************************************/ |
163 // convert GAIM name to original QQ UID | 160 // convert GAIM name to original QQ UID |
164 guint32 gaim_name_to_uid(const gchar * name) | 161 guint32 gaim_name_to_uid(const gchar *name) |
165 { | 162 { |
166 gchar *p; | 163 gchar *p; |
167 | 164 |
168 g_return_val_if_fail(g_str_has_prefix(name, QQ_NAME_PREFIX), 0); | 165 g_return_val_if_fail(g_str_has_prefix(name, QQ_NAME_PREFIX), 0); |
169 | 166 |
173 return (p == NULL) ? 0 : strtol(p + strlen(QQ_NAME_PREFIX), NULL, 10); | 170 return (p == NULL) ? 0 : strtol(p + strlen(QQ_NAME_PREFIX), NULL, 10); |
174 } | 171 } |
175 | 172 |
176 /*****************************************************************************/ | 173 /*****************************************************************************/ |
177 // try to dump the data as GBK | 174 // try to dump the data as GBK |
178 void try_dump_as_gbk(guint8 * data, gint len) | 175 void try_dump_as_gbk(guint8 *data, gint len) |
179 { | 176 { |
180 gint i; | 177 gint i; |
181 guint8 *incoming; | 178 guint8 *incoming; |
182 gchar *msg_utf8; | 179 gchar *msg_utf8; |
183 | 180 |
199 g_free(msg_utf8); | 196 g_free(msg_utf8); |
200 } // msg_utf8 != NULL | 197 } // msg_utf8 != NULL |
201 } // try_dump_gbk | 198 } // try_dump_gbk |
202 | 199 |
203 /*****************************************************************************/ | 200 /*****************************************************************************/ |
204 | 201 // strips whitespace |
205 // dump a chunk of raw data into hex string | 202 static gchar *strstrip(const gchar *buffer) |
206 // the return should be freed later | 203 { |
207 gchar *hex_dump_to_str(const guint8 * buffer, gint bytes) | 204 GString *stripped; |
205 gchar *ret; | |
206 int i; | |
207 | |
208 stripped = g_string_new(""); | |
209 for (i=0; i<strlen(buffer); i++) { | |
210 if ((int) buffer[i] != 32) { | |
211 g_string_append_c(stripped, buffer[i]); | |
212 } | |
213 } | |
214 ret = stripped->str; | |
215 g_string_free(stripped, FALSE); | |
216 | |
217 return ret; | |
218 } | |
219 | |
220 /*****************************************************************************/ | |
221 // Dumps an ASCII hex string to a string of bytes. The return should be freed later. | |
222 // Returns NULL if a string with an odd number of nibbles is passed in or if buffer | |
223 // isn't a valid hex string | |
224 guint8 *hex_str_to_bytes(const gchar *buffer) | |
225 { | |
226 gchar *hex_str, *hex_buffer, *cursor, tmp; | |
227 guint8 *bytes, nibble1, nibble2; | |
228 gint index, len; | |
229 | |
230 hex_buffer = strstrip(buffer); | |
231 | |
232 if (strlen(hex_buffer) % 2 != 0) { | |
233 gaim_debug(GAIM_DEBUG_WARNING, "QQ", | |
234 "Unable to convert an odd number of nibbles to a string of bytes!\n"); | |
235 g_free(hex_buffer); | |
236 return NULL; | |
237 } | |
238 bytes = g_newa(guint8, strlen(hex_buffer) / 2); | |
239 hex_str = g_ascii_strdown(hex_buffer, -1); | |
240 g_free(hex_buffer); | |
241 index = 0; | |
242 for (cursor = hex_str; cursor < hex_str + sizeof(gchar) * (strlen(hex_str)) - 1; cursor++) { | |
243 if (g_ascii_isdigit(*cursor)) {tmp = *cursor; nibble1 = atoi(&tmp); } | |
244 else if (g_ascii_isalpha(*cursor) && (gint) *cursor - 87 < 16) | |
245 nibble1 = (gint) *cursor - 87; | |
246 else { | |
247 gaim_debug(GAIM_DEBUG_WARNING, "QQ", | |
248 "Invalid char found in hex string!\n"); | |
249 g_free(hex_str); | |
250 return NULL; | |
251 } | |
252 nibble1 = nibble1 << 4; | |
253 cursor++; | |
254 if (g_ascii_isdigit(*cursor)) {tmp = *cursor; nibble2 = atoi(&tmp); } | |
255 else if (g_ascii_isalpha(*cursor) && (gint) (*cursor - 87) < 16) | |
256 nibble2 = (gint) *cursor - 87; | |
257 else { | |
258 g_free(hex_str); | |
259 return NULL; | |
260 } | |
261 bytes[index++] = nibble1 + nibble2; | |
262 } | |
263 len = strlen(hex_str) / 2; | |
264 g_free(hex_str); | |
265 return g_memdup(bytes, len); | |
266 } | |
267 | |
268 // Dumps a chunk of raw data into an ASCII hex string. The return should be freed later. | |
269 gchar *hex_dump_to_str(const guint8 *buffer, gint bytes) | |
208 { | 270 { |
209 GString *str; | 271 GString *str; |
210 gchar *ret; | 272 gchar *ret; |
211 gint i, j, ch; | 273 gint i, j, ch; |
212 | 274 |
238 // GString can be freed without freeing it character data | 300 // GString can be freed without freeing it character data |
239 g_string_free(str, FALSE); | 301 g_string_free(str, FALSE); |
240 | 302 |
241 return ret; | 303 return ret; |
242 } | 304 } |
243 | |
244 /*****************************************************************************/ | |
245 // ENF OF FILE |