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