Mercurial > pidgin
comparison libpurple/protocols/qq/qq_trans.c @ 24095:25f62d21b3f8
disapproval of revision '8cebefbc6cd5d84acb69c74e69e8821f11dd225d'
author | Daniel Atallah <daniel.atallah@gmail.com> |
---|---|
date | Mon, 15 Sep 2008 03:04:07 +0000 |
parents | 147ada94a1d8 |
children | 225e0e9e1055 |
comparison
equal
deleted
inserted
replaced
24088:147ada94a1d8 | 24095:25f62d21b3f8 |
---|---|
35 #include "qq_process.h" | 35 #include "qq_process.h" |
36 #include "qq_trans.h" | 36 #include "qq_trans.h" |
37 | 37 |
38 #define QQ_RESEND_MAX 3 /* max resend per packet */ | 38 #define QQ_RESEND_MAX 3 /* max resend per packet */ |
39 | 39 |
40 enum { | 40 qq_transaction *qq_trans_find_rcved(qq_data *qd, guint16 cmd, guint16 seq) |
41 QQ_TRANS_IS_SERVER = 0x01, /* Is server command or client command */ | 41 { |
42 QQ_TRANS_IS_IMPORT = 0x02, /* Only notice if not get reply; or resend, disconn if reties get 0*/ | |
43 QQ_TRANS_BEFORE_LOGIN = 0x04, /* server command before login*/ | |
44 }; | |
45 | |
46 struct _qq_transaction { | |
47 guint8 flag; | |
48 guint16 seq; | |
49 guint16 cmd; | |
50 | |
51 guint8 room_cmd; | |
52 guint32 room_id; | |
53 | |
54 guint8 *data; | |
55 gint data_len; | |
56 | |
57 gint fd; | |
58 gint send_retries; | |
59 gint rcved_times; | |
60 gint scan_times; | |
61 | |
62 gint update_class; | |
63 guint32 ship32; | |
64 }; | |
65 | |
66 qq_transaction *qq_trans_find_rcved(PurpleConnection *gc, guint16 cmd, guint16 seq) | |
67 { | |
68 qq_data *qd = (qq_data *)gc->proto_data; | |
69 GList *curr; | 42 GList *curr; |
70 GList *next; | 43 GList *next; |
71 qq_transaction *trans; | 44 qq_transaction *trans; |
72 | 45 |
73 if (qd->transactions == NULL) { | 46 if (qd->transactions == NULL) { |
75 } | 48 } |
76 | 49 |
77 next = qd->transactions; | 50 next = qd->transactions; |
78 while( (curr = next) ) { | 51 while( (curr = next) ) { |
79 next = curr->next; | 52 next = curr->next; |
80 | 53 |
81 trans = (qq_transaction *) (curr->data); | 54 trans = (qq_transaction *) (curr->data); |
82 if(trans->cmd == cmd && trans->seq == seq) { | 55 if(trans->cmd == cmd && trans->seq == seq) { |
83 if (trans->rcved_times == 0) { | 56 if (trans->rcved_times == 0) { |
84 trans->scan_times = 0; | 57 trans->scan_times = 0; |
85 } | 58 } |
86 trans->rcved_times++; | 59 trans->rcved_times++; |
87 /* server may not get our confirm reply before, send reply again*/ | |
88 /* only rcved buffer stored in transaction | |
89 if (qq_trans_is_server(trans) && qq_trans_is_dup(trans)) { | 60 if (qq_trans_is_server(trans) && qq_trans_is_dup(trans)) { |
61 /* server may not get our confirm reply before, send reply again*/ | |
90 if (trans->data != NULL && trans->data_len > 0) { | 62 if (trans->data != NULL && trans->data_len > 0) { |
91 qq_send_cmd_encrypted(gc, trans->cmd, trans->seq, trans->data, trans->data_len, FALSE); | 63 qq_send_data(qd, trans->cmd, trans->seq, FALSE, trans->data, trans->data_len); |
92 } | 64 } |
93 } | 65 } |
94 */ | |
95 return trans; | 66 return trans; |
96 } | 67 } |
97 } | 68 } |
98 | 69 |
99 return NULL; | 70 return NULL; |
100 } | 71 } |
101 | 72 |
102 gboolean qq_trans_is_server(qq_transaction *trans) | 73 gboolean qq_trans_is_server(qq_transaction *trans) |
103 { | 74 { |
104 g_return_val_if_fail(trans != NULL, FALSE); | 75 g_return_val_if_fail(trans != NULL, FALSE); |
105 | 76 |
106 if (trans->flag & QQ_TRANS_IS_SERVER) | 77 if (trans->flag & QQ_TRANS_IS_SERVER) |
107 return TRUE; | 78 return TRUE; |
108 else | 79 else |
109 return FALSE; | 80 return FALSE; |
110 } | 81 } |
111 | 82 |
112 gboolean qq_trans_is_dup(qq_transaction *trans) | 83 gboolean qq_trans_is_dup(qq_transaction *trans) |
113 { | 84 { |
114 g_return_val_if_fail(trans != NULL, TRUE); | 85 g_return_val_if_fail(trans != NULL, TRUE); |
115 | 86 |
116 if (trans->rcved_times > 1) | 87 if (trans->rcved_times > 1) |
117 return TRUE; | 88 return TRUE; |
118 else | 89 else |
119 return FALSE; | 90 return FALSE; |
120 } | 91 } |
129 { | 100 { |
130 g_return_val_if_fail(trans != NULL, 0); | 101 g_return_val_if_fail(trans != NULL, 0); |
131 return trans->room_id; | 102 return trans->room_id; |
132 } | 103 } |
133 | 104 |
134 gint qq_trans_get_class(qq_transaction *trans) | |
135 { | |
136 g_return_val_if_fail(trans != NULL, QQ_CMD_CLASS_NONE); | |
137 return trans->update_class; | |
138 } | |
139 | |
140 gint qq_trans_get_ship(qq_transaction *trans) | |
141 { | |
142 g_return_val_if_fail(trans != NULL, 0); | |
143 return trans->ship32; | |
144 } | |
145 | |
146 static qq_transaction *trans_create(PurpleConnection *gc, gint fd, | |
147 guint16 cmd, guint16 seq, guint8 *data, gint data_len, gint update_class, guint32 ship32) | |
148 { | |
149 qq_data *qd; | |
150 qq_transaction *trans; | |
151 | |
152 g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, NULL); | |
153 qd = (qq_data *) gc->proto_data; | |
154 | |
155 trans = g_new0(qq_transaction, 1); | |
156 | |
157 memset(trans, 0, sizeof(qq_transaction)); | |
158 trans->fd = fd; | |
159 trans->cmd = cmd; | |
160 trans->seq = seq; | |
161 | |
162 trans->data = NULL; | |
163 trans->data_len = 0; | |
164 if (data != NULL && data_len > 0) { | |
165 /* don't use g_strdup, may have 0x00 */ | |
166 trans->data = g_memdup(data, data_len); | |
167 trans->data_len = data_len; | |
168 } | |
169 | |
170 trans->update_class = update_class; | |
171 return trans; | |
172 } | |
173 | |
174 /* Remove a packet with seq from send trans */ | 105 /* Remove a packet with seq from send trans */ |
175 static void trans_remove(PurpleConnection *gc, qq_transaction *trans) | 106 static void trans_remove(qq_data *qd, qq_transaction *trans) |
176 { | 107 { |
177 qq_data *qd = (qq_data *)gc->proto_data; | |
178 g_return_if_fail(qd != NULL && trans != NULL); | 108 g_return_if_fail(qd != NULL && trans != NULL); |
179 | 109 |
180 #if 0 | 110 purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS", |
181 purple_debug_info("QQ_TRANS", | |
182 "Remove [%s%05d] retry %d rcved %d scan %d %s\n", | 111 "Remove [%s%05d] retry %d rcved %d scan %d %s\n", |
183 (trans->flag & QQ_TRANS_IS_SERVER) ? "SRV-" : "", | 112 (trans->flag & QQ_TRANS_IS_SERVER) ? "SRV-" : "", |
184 trans->seq, | 113 trans->seq, |
185 trans->send_retries, trans->rcved_times, trans->scan_times, | 114 trans->send_retries, trans->rcved_times, trans->scan_times, |
186 qq_get_cmd_desc(trans->cmd)); | 115 qq_get_cmd_desc(trans->cmd)); |
187 #endif | 116 |
188 if (trans->data) g_free(trans->data); | 117 if (trans->data) g_free(trans->data); |
189 qd->transactions = g_list_remove(qd->transactions, trans); | 118 qd->transactions = g_list_remove(qd->transactions, trans); |
190 g_free(trans); | 119 g_free(trans); |
191 } | 120 } |
192 | 121 |
193 void qq_trans_add_client_cmd(PurpleConnection *gc, | 122 void qq_trans_add_client_cmd(qq_data *qd, guint16 cmd, guint16 seq, guint8 *data, gint data_len) |
194 guint16 cmd, guint16 seq, guint8 *data, gint data_len, gint update_class, guint32 ship32) | 123 { |
195 { | 124 qq_transaction *trans = g_new0(qq_transaction, 1); |
196 qq_data *qd = (qq_data *)gc->proto_data; | 125 |
197 qq_transaction *trans = trans_create(gc, qd->fd, cmd, seq, data, data_len, update_class, ship32); | 126 g_return_if_fail(trans != NULL); |
198 | 127 |
128 trans->flag = 0; | |
199 if (cmd == QQ_CMD_TOKEN || cmd == QQ_CMD_LOGIN || cmd == QQ_CMD_KEEP_ALIVE) { | 129 if (cmd == QQ_CMD_TOKEN || cmd == QQ_CMD_LOGIN || cmd == QQ_CMD_KEEP_ALIVE) { |
200 trans->flag |= QQ_TRANS_IS_IMPORT; | 130 trans->flag |= QQ_TRANS_CLI_IMPORT; |
201 } | 131 } |
132 trans->fd = qd->fd; | |
133 trans->cmd = cmd; | |
134 trans->seq = seq; | |
135 trans->room_cmd = 0; | |
136 trans->room_id = 0; | |
202 trans->send_retries = QQ_RESEND_MAX; | 137 trans->send_retries = QQ_RESEND_MAX; |
203 #if 0 | 138 trans->rcved_times = 0; |
204 purple_debug_info("QQ_TRANS", "Add client cmd, seq %d, data %p, len %d\n", | 139 trans->scan_times = 0; |
140 | |
141 trans->data = NULL; | |
142 trans->data_len = 0; | |
143 if (data != NULL && data_len > 0) { | |
144 trans->data = g_memdup(data, data_len); /* don't use g_strdup, may have 0x00 */ | |
145 trans->data_len = data_len; | |
146 } | |
147 purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS", | |
148 "Add client cmd, seq = %d, data = %p, len = %d\n", | |
205 trans->seq, trans->data, trans->data_len); | 149 trans->seq, trans->data, trans->data_len); |
206 #endif | |
207 qd->transactions = g_list_append(qd->transactions, trans); | 150 qd->transactions = g_list_append(qd->transactions, trans); |
208 } | 151 } |
209 | 152 |
210 void qq_trans_add_room_cmd(PurpleConnection *gc, | 153 void qq_trans_add_room_cmd(qq_data *qd, guint16 seq, guint8 room_cmd, guint32 room_id, |
211 guint16 seq, guint8 room_cmd, guint32 room_id, guint8 *data, gint data_len, | 154 guint8 *data, gint data_len) |
212 gint update_class, guint32 ship32) | 155 { |
213 { | 156 qq_transaction *trans = g_new0(qq_transaction, 1); |
214 qq_data *qd = (qq_data *)gc->proto_data; | 157 |
215 qq_transaction *trans = trans_create(gc, qd->fd, QQ_CMD_ROOM, seq, data, data_len, | 158 g_return_if_fail(trans != NULL); |
216 update_class, ship32); | 159 |
217 | 160 trans->flag = 0; |
161 trans->fd = qd->fd; | |
162 trans->seq = seq; | |
163 trans->cmd = QQ_CMD_ROOM; | |
218 trans->room_cmd = room_cmd; | 164 trans->room_cmd = room_cmd; |
219 trans->room_id = room_id; | 165 trans->room_id = room_id; |
220 trans->send_retries = QQ_RESEND_MAX; | 166 trans->send_retries = QQ_RESEND_MAX; |
221 #if 0 | 167 trans->rcved_times = 0; |
222 purple_debug_info("QQ_TRANS", "Add room cmd, seq %d, data %p, len %d\n", | 168 trans->scan_times = 0; |
169 | |
170 trans->data = NULL; | |
171 trans->data_len = 0; | |
172 if (data != NULL && data_len > 0) { | |
173 trans->data = g_memdup(data, data_len); /* don't use g_strdup, may have 0x00 */ | |
174 trans->data_len = data_len; | |
175 } | |
176 purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS", | |
177 "Add room cmd, seq = %d, data = %p, len = %d\n", | |
223 trans->seq, trans->data, trans->data_len); | 178 trans->seq, trans->data, trans->data_len); |
224 #endif | |
225 qd->transactions = g_list_append(qd->transactions, trans); | 179 qd->transactions = g_list_append(qd->transactions, trans); |
226 } | 180 } |
227 | 181 |
228 void qq_trans_add_server_cmd(PurpleConnection *gc, | 182 void qq_trans_add_server_cmd(qq_data *qd, guint16 cmd, guint16 seq, guint8 *data, gint data_len) |
229 guint16 cmd, guint16 seq, guint8 *data, gint data_len) | 183 { |
230 { | 184 qq_transaction *trans = g_new0(qq_transaction, 1); |
231 qq_data *qd = (qq_data *)gc->proto_data; | 185 |
232 qq_transaction *trans = trans_create(gc, qd->fd, cmd, seq, data, data_len, QQ_CMD_CLASS_NONE, 0); | 186 g_return_if_fail(trans != NULL); |
233 | 187 |
234 trans->flag = QQ_TRANS_IS_SERVER; | 188 trans->flag = QQ_TRANS_IS_SERVER; |
235 if ( !qd->is_login ) { | 189 if ( !qd->logged_in ) { |
236 trans->flag |= QQ_TRANS_BEFORE_LOGIN; | 190 trans->flag |= QQ_TRANS_BEFORE_LOGIN; |
237 } | 191 } |
192 trans->fd = qd->fd; | |
193 trans->cmd = cmd; | |
194 trans->seq = seq; | |
195 trans->room_cmd = 0; | |
196 trans->room_id = 0; | |
238 trans->send_retries = 0; | 197 trans->send_retries = 0; |
239 trans->rcved_times = 1; | 198 trans->rcved_times = 1; |
240 #if 0 | 199 trans->scan_times = 0; |
241 purple_debug_info("QQ_TRANS", "Add server cmd, seq %d, data %p, len %d\n", | 200 trans->data = NULL; |
201 trans->data_len = 0; | |
202 if (data != NULL && data_len > 0) { | |
203 trans->data = g_memdup(data, data_len); /* don't use g_strdup, may have 0x00 */ | |
204 trans->data_len = data_len; | |
205 } | |
206 purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS", | |
207 "Add server cmd, seq = %d, data = %p, len = %d\n", | |
242 trans->seq, trans->data, trans->data_len); | 208 trans->seq, trans->data, trans->data_len); |
243 #endif | |
244 qd->transactions = g_list_append(qd->transactions, trans); | 209 qd->transactions = g_list_append(qd->transactions, trans); |
245 } | 210 } |
246 | 211 |
247 void qq_trans_process_before_login(PurpleConnection *gc) | 212 void qq_trans_process_before_login(qq_data *qd) |
248 { | 213 { |
249 qq_data *qd = (qq_data *)gc->proto_data; | |
250 GList *curr; | 214 GList *curr; |
251 GList *next; | 215 GList *next; |
252 qq_transaction *trans; | 216 qq_transaction *trans; |
253 | 217 |
254 g_return_if_fail(qd != NULL); | 218 g_return_if_fail(qd != NULL); |
255 | 219 |
256 next = qd->transactions; | 220 next = qd->transactions; |
257 while( (curr = next) ) { | 221 while( (curr = next) ) { |
258 next = curr->next; | 222 next = curr->next; |
259 trans = (qq_transaction *) (curr->data); | 223 trans = (qq_transaction *) (curr->data); |
260 #if 0 | 224 /* purple_debug(PURPLE_DEBUG_ERROR, "QQ_TRANS", "Scan [%d]\n", trans->seq); */ |
261 purple_debug_info("QQ_TRANS", "Scan [%d]\n", trans->seq); | 225 |
262 #endif | |
263 if ( !(trans->flag & QQ_TRANS_IS_SERVER) ) { | 226 if ( !(trans->flag & QQ_TRANS_IS_SERVER) ) { |
264 continue; | 227 continue; |
265 } | 228 } |
266 if ( !(trans->flag & QQ_TRANS_BEFORE_LOGIN) ) { | 229 if ( !(trans->flag & QQ_TRANS_BEFORE_LOGIN) ) { |
267 continue; | 230 continue; |
268 } | 231 } |
269 /* set QQ_TRANS_BEFORE_LOGIN off */ | 232 // set QQ_TRANS_BEFORE_LOGIN off |
270 trans->flag &= ~QQ_TRANS_BEFORE_LOGIN; | 233 trans->flag &= ~QQ_TRANS_BEFORE_LOGIN; |
271 | 234 |
272 purple_debug_info("QQ_TRANS", | 235 purple_debug(PURPLE_DEBUG_ERROR, "QQ_TRANS", |
273 "Process server cmd before login, seq %d, data %p, len %d, send_retries %d\n", | 236 "Process server cmd before login, seq %d, data %p, len %d, send_retries %d\n", |
274 trans->seq, trans->data, trans->data_len, trans->send_retries); | 237 trans->seq, trans->data, trans->data_len, trans->send_retries); |
275 | 238 |
276 qq_proc_cmd_reply(gc, trans->seq, trans->cmd, trans->data, trans->data_len, trans->update_class, trans->ship32); | 239 qq_proc_cmd_reply(qd->gc, trans->seq, trans->cmd, trans->data, trans->data_len); |
277 } | 240 } |
278 | 241 |
279 /* purple_debug_info("QQ_TRANS", "Scan finished\n"); */ | 242 /* purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS", "Scan finished\n"); */ |
280 return; | 243 return; |
281 } | 244 } |
282 | 245 |
283 gboolean qq_trans_scan(PurpleConnection *gc) | 246 gboolean qq_trans_scan(qq_data *qd) |
284 { | 247 { |
285 qq_data *qd = (qq_data *)gc->proto_data; | |
286 GList *curr; | 248 GList *curr; |
287 GList *next; | 249 GList *next; |
288 qq_transaction *trans; | 250 qq_transaction *trans; |
289 | 251 |
290 g_return_val_if_fail(qd != NULL, FALSE); | 252 g_return_val_if_fail(qd != NULL, FALSE); |
291 | 253 |
292 next = qd->transactions; | 254 next = qd->transactions; |
293 while( (curr = next) ) { | 255 while( (curr = next) ) { |
294 next = curr->next; | 256 next = curr->next; |
295 trans = (qq_transaction *) (curr->data); | 257 trans = (qq_transaction *) (curr->data); |
296 /* purple_debug_info("QQ_TRANS", "Scan [%d]\n", trans->seq); */ | 258 /* purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS", "Scan [%d]\n", trans->seq); */ |
297 | 259 |
298 if (trans->flag & QQ_TRANS_BEFORE_LOGIN) { | 260 if (trans->flag & QQ_TRANS_BEFORE_LOGIN) { |
299 /* keep server cmd before login*/ | 261 /* keep server cmd before login*/ |
300 continue; | 262 continue; |
301 } | 263 } |
302 | 264 |
306 continue; | 268 continue; |
307 } | 269 } |
308 | 270 |
309 if (trans->rcved_times > 0) { | 271 if (trans->rcved_times > 0) { |
310 /* Has been received */ | 272 /* Has been received */ |
311 trans_remove(gc, trans); | 273 trans_remove(qd, trans); |
312 continue; | 274 continue; |
313 } | 275 } |
314 | 276 |
315 if (trans->flag & QQ_TRANS_IS_SERVER) { | 277 if (trans->flag & QQ_TRANS_IS_SERVER) { |
316 continue; | 278 continue; |
317 } | 279 } |
318 | 280 |
319 /* Never get reply */ | 281 /* Never get reply */ |
320 trans->send_retries--; | 282 trans->send_retries--; |
321 if (trans->send_retries <= 0) { | 283 if (trans->send_retries <= 0) { |
322 purple_debug_warning("QQ_TRANS", | 284 purple_debug(PURPLE_DEBUG_WARNING, "QQ_TRANS", |
323 "[%d] %s is lost.\n", | 285 "[%d] %s is lost.\n", |
324 trans->seq, qq_get_cmd_desc(trans->cmd)); | 286 trans->seq, qq_get_cmd_desc(trans->cmd)); |
325 if (trans->flag & QQ_TRANS_IS_IMPORT) { | 287 if (trans->flag & QQ_TRANS_CLI_IMPORT) { |
326 return TRUE; | 288 return TRUE; |
327 } | 289 } |
328 | 290 |
329 purple_debug_error("QQ_TRANS", | 291 purple_debug(PURPLE_DEBUG_ERROR, "QQ_TRANS", |
330 "Lost [%d] %s, data %p, len %d, retries %d\n", | 292 "Lost [%d] %s, data %p, len %d, retries %d\n", |
331 trans->seq, qq_get_cmd_desc(trans->cmd), | 293 trans->seq, qq_get_cmd_desc(trans->cmd), |
332 trans->data, trans->data_len, trans->send_retries); | 294 trans->data, trans->data_len, trans->send_retries); |
333 trans_remove(gc, trans); | 295 trans_remove(qd, trans); |
334 continue; | 296 continue; |
335 } | 297 } |
336 | 298 |
337 purple_debug_error("QQ_TRANS", | 299 purple_debug(PURPLE_DEBUG_ERROR, "QQ_TRANS", |
338 "Resend [%d] %s data %p, len %d, send_retries %d\n", | 300 "Resend [%d] %s data %p, len %d, send_retries %d\n", |
339 trans->seq, qq_get_cmd_desc(trans->cmd), | 301 trans->seq, qq_get_cmd_desc(trans->cmd), |
340 trans->data, trans->data_len, trans->send_retries); | 302 trans->data, trans->data_len, trans->send_retries); |
341 qq_send_cmd_encrypted(gc, trans->cmd, trans->seq, trans->data, trans->data_len, FALSE); | 303 qq_send_data(qd, trans->cmd, trans->seq, FALSE, trans->data, trans->data_len); |
342 } | 304 } |
343 | 305 |
344 /* purple_debug_info("QQ_TRANS", "Scan finished\n"); */ | 306 /* purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS", "Scan finished\n"); */ |
345 return FALSE; | 307 return FALSE; |
346 } | 308 } |
347 | 309 |
348 /* clean up send trans and free all contents */ | 310 /* clean up send trans and free all contents */ |
349 void qq_trans_remove_all(PurpleConnection *gc) | 311 void qq_trans_remove_all(qq_data *qd) |
350 { | 312 { |
351 qq_data *qd = (qq_data *)gc->proto_data; | 313 GList *curr; |
314 GList *next; | |
352 qq_transaction *trans; | 315 qq_transaction *trans; |
353 gint count = 0; | 316 gint count = 0; |
354 | 317 |
355 while(qd->transactions != NULL) { | 318 curr = qd->transactions; |
356 trans = (qq_transaction *) (qd->transactions->data); | 319 while(curr) { |
357 qd->transactions = g_list_remove(qd->transactions, trans); | 320 next = curr->next; |
358 | 321 |
359 if (trans->data) g_free(trans->data); | 322 trans = (qq_transaction *) (curr->data); |
360 g_free(trans); | 323 /* |
324 purple_debug(PURPLE_DEBUG_ERROR, "QQ_TRANS", | |
325 "Remove to transaction, seq = %d, buf = %p, len = %d\n", | |
326 trans->seq, trans->buf, trans->len); | |
327 */ | |
328 trans_remove(qd, trans); | |
361 | 329 |
362 count++; | 330 count++; |
363 } | 331 curr = next; |
364 if (count > 0) { | 332 } |
365 purple_debug_info("QQ_TRANS", "Free all %d packets\n", count); | 333 g_list_free(qd->transactions); |
366 } | 334 |
367 } | 335 purple_debug(PURPLE_DEBUG_INFO, "QQ_TRANS", "Free all %d packets\n", count); |
336 } |