Mercurial > pidgin
annotate src/protocols/qq/utils.c @ 14058:32a71e64ceae
[gaim-migrate @ 16673]
Eliminated a number of warnings. Generally, this consisted of fixing incorrectly declared data types and adding a few casts. I also moved some declarations that occurred in the middle of code. Minor formatting changes.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Huetsch <markhuetsch> |
---|---|
date | Tue, 08 Aug 2006 23:20:08 +0000 |
parents | 44e1bf83dadf |
children |
rev | line source |
---|---|
13870 | 1 /** |
2 * The QQ2003C protocol plugin | |
3 * | |
4 * for gaim | |
5 * | |
6 * Copyright (C) 2004 Puzzlebird | |
7 * | |
8 * This program is free software; you can redistribute it and/or modify | |
9 * it under the terms of the GNU General Public License as published by | |
10 * the Free Software Foundation; either version 2 of the License, or | |
11 * (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 * GNU General Public License for more details. | |
17 * | |
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 | |
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 */ | |
22 | |
14021 | 23 #include "stdlib.h" |
13870 | 24 #include "limits.h" |
14021 | 25 #include "string.h" |
13870 | 26 |
27 #ifdef _WIN32 | |
28 #include "win32dep.h" | |
29 #endif | |
30 | |
14021 | 31 #include "char_conv.h" |
32 #include "debug.h" | |
33 #include "prefs.h" | |
14055
44e1bf83dadf
[gaim-migrate @ 16668]
Richard Laager <rlaager@wiktel.com>
parents:
14054
diff
changeset
|
34 #include "util.h" |
13870 | 35 #include "utils.h" |
36 | |
37 #define QQ_NAME_FORMAT "qq-%d" | |
38 | |
14021 | 39 gchar *get_name_by_index_str(gchar **array, const gchar *index_str, gint amount) |
40 { | |
13870 | 41 gint index; |
42 | |
43 index = atoi(index_str); | |
44 if (index < 0 || index >= amount) | |
45 index = 0; | |
46 | |
47 return array[index]; | |
14021 | 48 } |
13870 | 49 |
14021 | 50 gchar *get_index_str_by_name(gchar **array, const gchar *name, gint amount) |
51 { | |
13870 | 52 gint index; |
53 | |
54 for (index = 0; index <= amount; index++) | |
55 if (g_ascii_strcasecmp(array[index], name) == 0) | |
56 break; | |
57 | |
58 if (index >= amount) | |
14021 | 59 index = 0; /* meaning no match */ |
13870 | 60 return g_strdup_printf("%d", index); |
14021 | 61 } |
13870 | 62 |
14015 | 63 gint qq_string_to_dec_value(const gchar *str) |
13870 | 64 { |
65 g_return_val_if_fail(str != NULL, 0); | |
66 return strtol(str, NULL, 10); | |
14021 | 67 } |
13870 | 68 |
14021 | 69 /* split the given data(len) with delimit, |
70 * check the number of field matches the expected_fields (<=0 means all) | |
71 * return gchar* array (needs to be freed by g_strfreev later), or NULL */ | |
72 gchar **split_data(guint8 *data, gint len, const gchar *delimit, gint expected_fields) | |
73 { | |
13870 | 74 guint8 *input; |
75 gchar **segments; | |
76 gint i, j; | |
77 | |
78 g_return_val_if_fail(data != NULL && len != 0 && delimit != 0, NULL); | |
79 | |
14021 | 80 /* as the last field would be string, but data is not ended with 0x00 |
81 * we have to duplicate the data and append a 0x00 at the end */ | |
13870 | 82 input = g_newa(guint8, len + 1); |
83 g_memmove(input, data, len); | |
84 input[len] = 0x00; | |
85 | |
14017 | 86 segments = g_strsplit((gchar *) input, delimit, 0); |
13870 | 87 if (expected_fields <= 0) |
88 return segments; | |
89 | |
90 for (i = 0; segments[i] != NULL; i++) {; | |
91 } | |
14021 | 92 if (i < expected_fields) { /* not enough fields */ |
13870 | 93 gaim_debug(GAIM_DEBUG_ERROR, "QQ", |
94 "Invalid data, expect %d fields, found only %d, discard\n", expected_fields, i); | |
95 g_strfreev(segments); | |
96 return NULL; | |
14021 | 97 } else if (i > expected_fields) { /* more fields, OK */ |
13870 | 98 gaim_debug(GAIM_DEBUG_WARNING, "QQ", |
99 "Dangerous data, expect %d fields, found %d, return all\n", expected_fields, i); | |
14021 | 100 /* free up those not used */ |
13870 | 101 for (j = expected_fields; j < i; j++) { |
102 gaim_debug(GAIM_DEBUG_WARNING, "QQ", "field[%d] is %s\n", j, segments[j]); | |
14015 | 103 g_free(segments[j]); |
13870 | 104 } |
105 | |
106 segments[expected_fields] = NULL; | |
14015 | 107 } |
13870 | 108 |
109 return segments; | |
14015 | 110 } |
13870 | 111 |
14021 | 112 /* given a four-byte ip data, convert it into a human readable ip string |
113 * the return needs to be freed */ | |
14015 | 114 gchar *gen_ip_str(guint8 *ip) |
13870 | 115 { |
14017 | 116 gchar *ret; |
117 if (ip == NULL || ip[0] == 0) { | |
118 ret = g_new(gchar, 1); | |
119 *ret = '\0'; | |
120 return ret; | |
14021 | 121 } else { |
13989 | 122 return g_strdup_printf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); |
14021 | 123 } |
13989 | 124 } |
13870 | 125 |
126 guint8 *str_ip_gen(gchar *str) { | |
127 guint8 *ip = g_new(guint8, 4); | |
128 int a, b, c, d; | |
129 sscanf(str, "%d.%d.%d.%d", &a, &b, &c, &d); | |
130 ip[0] = a; | |
131 ip[1] = b; | |
132 ip[2] = c; | |
133 ip[3] = d; | |
134 return ip; | |
135 } | |
136 | |
14021 | 137 /* return the QQ icon file name |
138 * the return needs to be freed */ | |
13870 | 139 gchar *get_icon_name(gint set, gint suffix) |
140 { | |
141 return g_strdup_printf("qq_%d-%d", set, suffix); | |
14021 | 142 } |
13870 | 143 |
14021 | 144 /* convert a QQ UID to a unique name of GAIM |
145 * the return needs to be freed */ | |
13870 | 146 gchar *uid_to_gaim_name(guint32 uid) |
147 { | |
148 return g_strdup_printf(QQ_NAME_FORMAT, uid); | |
14021 | 149 } |
13870 | 150 |
14021 | 151 /* convert GAIM name to original QQ UID */ |
14015 | 152 guint32 gaim_name_to_uid(const gchar *name) |
13870 | 153 { |
154 gchar *p; | |
155 | |
14055
44e1bf83dadf
[gaim-migrate @ 16668]
Richard Laager <rlaager@wiktel.com>
parents:
14054
diff
changeset
|
156 g_return_val_if_fail(gaim_str_has_prefix(name, QQ_NAME_PREFIX), 0); |
13870 | 157 |
158 p = g_strrstr(name, QQ_NAME_PREFIX); | |
159 return (p == NULL) ? 0 : strtol(p + strlen(QQ_NAME_PREFIX), NULL, 10); | |
13989 | 160 } |
13870 | 161 |
14021 | 162 /* try to dump the data as GBK */ |
14015 | 163 void try_dump_as_gbk(guint8 *data, gint len) |
13870 | 164 { |
165 gint i; | |
166 guint8 *incoming; | |
167 gchar *msg_utf8; | |
168 | |
169 incoming = g_newa(guint8, len + 1); | |
170 g_memmove(incoming, data, len); | |
171 incoming[len] = 0x00; | |
14021 | 172 /* GBK code: |
173 * Single-byte ASCII: 0x21-0x7E | |
174 * GBK first byte range: 0x81-0xFE | |
175 * GBK second byte range: 0x40-0x7E and 0x80-0xFE */ | |
13870 | 176 for (i = 0; i < len; i++) |
177 if (incoming[i] >= 0x81) | |
178 break; | |
179 | |
14017 | 180 msg_utf8 = i < len ? qq_to_utf8((gchar *) &incoming[i], QQ_CHARSET_DEFAULT) : NULL; |
13870 | 181 |
182 if (msg_utf8 != NULL) { | |
183 gaim_debug(GAIM_DEBUG_WARNING, "QQ", "Try extract GB msg: %s\n", msg_utf8); | |
184 g_free(msg_utf8); | |
14021 | 185 } |
186 } | |
13870 | 187 |
14021 | 188 /* strips whitespace */ |
14015 | 189 static gchar *strstrip(const gchar *buffer) |
190 { | |
191 GString *stripped; | |
192 gchar *ret; | |
193 int i; | |
13989 | 194 |
14049 | 195 g_return_val_if_fail(buffer != NULL, NULL); |
196 | |
14015 | 197 stripped = g_string_new(""); |
198 for (i=0; i<strlen(buffer); i++) { | |
199 if ((int) buffer[i] != 32) { | |
200 g_string_append_c(stripped, buffer[i]); | |
201 } | |
202 } | |
203 ret = stripped->str; | |
204 g_string_free(stripped, FALSE); | |
205 | |
206 return ret; | |
207 } | |
208 | |
14021 | 209 /* Dumps an ASCII hex string to a string of bytes. The return should be freed later. |
210 * Returns NULL if a string with an odd number of nibbles is passed in or if buffer | |
211 * isn't a valid hex string */ | |
14049 | 212 guint8 *hex_str_to_bytes(const gchar *buffer, gint *out_len) |
14015 | 213 { |
214 gchar *hex_str, *hex_buffer, *cursor, tmp; | |
215 guint8 *bytes, nibble1, nibble2; | |
14049 | 216 gint index; |
14015 | 217 |
14049 | 218 g_return_val_if_fail(buffer != NULL, NULL); |
219 | |
14015 | 220 hex_buffer = strstrip(buffer); |
221 | |
222 if (strlen(hex_buffer) % 2 != 0) { | |
223 gaim_debug(GAIM_DEBUG_WARNING, "QQ", | |
224 "Unable to convert an odd number of nibbles to a string of bytes!\n"); | |
225 g_free(hex_buffer); | |
226 return NULL; | |
227 } | |
228 bytes = g_newa(guint8, strlen(hex_buffer) / 2); | |
229 hex_str = g_ascii_strdown(hex_buffer, -1); | |
230 g_free(hex_buffer); | |
231 index = 0; | |
232 for (cursor = hex_str; cursor < hex_str + sizeof(gchar) * (strlen(hex_str)) - 1; cursor++) { | |
14049 | 233 if (g_ascii_isdigit(*cursor)) { |
234 tmp = *cursor; nibble1 = atoi(&tmp); | |
235 } else if (g_ascii_isalpha(*cursor) && (gint) *cursor - 87 < 16) { | |
14015 | 236 nibble1 = (gint) *cursor - 87; |
14049 | 237 } else { |
14015 | 238 gaim_debug(GAIM_DEBUG_WARNING, "QQ", |
239 "Invalid char found in hex string!\n"); | |
240 g_free(hex_str); | |
241 return NULL; | |
242 } | |
243 nibble1 = nibble1 << 4; | |
244 cursor++; | |
14049 | 245 if (g_ascii_isdigit(*cursor)) { |
246 tmp = *cursor; nibble2 = atoi(&tmp); | |
247 } else if (g_ascii_isalpha(*cursor) && (gint) (*cursor - 87) < 16) { | |
14015 | 248 nibble2 = (gint) *cursor - 87; |
14049 | 249 } else { |
250 gaim_debug(GAIM_DEBUG_WARNING, "QQ", | |
251 "Invalid char found in hex string!\n"); | |
14015 | 252 g_free(hex_str); |
253 return NULL; | |
254 } | |
255 bytes[index++] = nibble1 + nibble2; | |
256 } | |
14049 | 257 *out_len = strlen(hex_str) / 2; |
14015 | 258 g_free(hex_str); |
14049 | 259 return g_memdup(bytes, *out_len); |
14015 | 260 } |
261 | |
14021 | 262 /* Dumps a chunk of raw data into an ASCII hex string. The return should be freed later. */ |
14015 | 263 gchar *hex_dump_to_str(const guint8 *buffer, gint bytes) |
13870 | 264 { |
265 GString *str; | |
266 gchar *ret; | |
267 gint i, j, ch; | |
268 | |
269 str = g_string_new(""); | |
270 for (i = 0; i < bytes; i += 16) { | |
14021 | 271 /* length label */ |
13870 | 272 g_string_append_printf(str, "%04d: ", i); |
273 | |
14021 | 274 /* dump hex value */ |
13870 | 275 for (j = 0; j < 16; j++) |
276 if ((i + j) < bytes) | |
277 g_string_append_printf(str, " %02X", buffer[i + j]); | |
278 else | |
279 g_string_append(str, " "); | |
280 g_string_append(str, " "); | |
281 | |
14021 | 282 /* dump ascii value */ |
13870 | 283 for (j = 0; j < 16 && (i + j) < bytes; j++) { |
284 ch = buffer[i + j] & 127; | |
285 if (ch < ' ' || ch == 127) | |
286 g_string_append_c(str, '.'); | |
287 else | |
288 g_string_append_c(str, ch); | |
13989 | 289 } |
13870 | 290 g_string_append_c(str, '\n'); |
13989 | 291 } |
13870 | 292 |
293 ret = str->str; | |
14021 | 294 /* GString can be freed without freeing it character data */ |
13870 | 295 g_string_free(str, FALSE); |
296 | |
297 return ret; | |
13989 | 298 } |