| 2211 purple_notify_error(gc, NULL, _("Could not add buddy to server list"), buf); |
2211 purple_notify_error(gc, NULL, _("Could not add buddy to server list"), buf); |
| 2212 g_free(buf); |
2212 g_free(buf); |
| 2213 g_free(decoded_group); |
2213 g_free(decoded_group); |
| 2214 } |
2214 } |
| 2215 |
2215 |
| |
2216 static void yahoo_write_p2p_packet(gpointer data, gint source) |
| |
2217 { |
| |
2218 struct yahoo_p2p_data *user_data; |
| |
2219 struct yahoo_packet *pkt_to_send; |
| |
2220 size_t pkt_len; |
| |
2221 guchar *raw_packet; |
| |
2222 PurpleAccount *account; |
| |
2223 int val_13_to_send = 0; |
| |
2224 |
| |
2225 if(!(user_data = data)) |
| |
2226 return ; |
| |
2227 |
| |
2228 account = purple_connection_get_account(user_data->gc); |
| |
2229 |
| |
2230 /*key_13 appears to be a sort of a counter,yahoo server sends with val_13=0, we send packet to host with val_13=1, receive back with val_13=5, we send with val_13=6, receive back with val_13=7, we send with val_13=7, then break the connection. So we keep the value for 7 and increment for not 7*/ |
| |
2231 |
| |
2232 if(user_data->val_13 != 7) |
| |
2233 val_13_to_send = user_data->val_13 + 1; |
| |
2234 else |
| |
2235 val_13_to_send = user_data->val_13; /* haven't ever received values other than 0, 5, 6, 7*/ |
| |
2236 |
| |
2237 /*Build the yahoo packet*/ |
| |
2238 pkt_to_send = yahoo_packet_new(YAHOO_SERVICE_P2PFILEXFER, YAHOO_STATUS_AVAILABLE, user_data->session_id); |
| |
2239 yahoo_packet_hash(pkt_to_send, "ssisi", |
| |
2240 4, purple_normalize(account, purple_account_get_username(account)), |
| |
2241 5, user_data->host_username, |
| |
2242 241, 0, /*Protocol identifier*/ |
| |
2243 49, "PEERTOPEER", |
| |
2244 13, val_13_to_send); |
| |
2245 |
| |
2246 /*build the packet and send it to the host*/ |
| |
2247 pkt_len = yahoo_packet_build(pkt_to_send, 0, 0, 0, &raw_packet); |
| |
2248 if(write(source, raw_packet, pkt_len) != pkt_len) |
| |
2249 purple_debug_warning("yahoo","p2p: couldn't write to the source\n"); |
| |
2250 yahoo_packet_free(pkt_to_send); |
| |
2251 g_free(raw_packet); |
| |
2252 |
| |
2253 /*if written packet has val_13 equal to 7, we dont send any other packet but dont close the connection, connection seems to exist long after the p2p processes are over*/ |
| |
2254 if(val_13_to_send == 7) { |
| |
2255 /*cant figure out when to close the connection, not closing connection right now, misbehaves if host logs out, to be fixed soon*/ |
| |
2256 /*free user_data, do we need it now*/ |
| |
2257 g_free(user_data->host_ip); |
| |
2258 g_free(user_data->host_username); |
| |
2259 g_free(user_data); |
| |
2260 } |
| |
2261 } |
| |
2262 |
| |
2263 static void yahoo_p2p_packet_process(gpointer data, gint source, struct yahoo_packet *pkt) |
| |
2264 { |
| |
2265 struct yahoo_p2p_data *user_data; |
| |
2266 char *who = NULL; |
| |
2267 GSList *l = pkt->hash; |
| |
2268 |
| |
2269 if(!(user_data = data)) |
| |
2270 return ; |
| |
2271 |
| |
2272 /* lets see whats in the packet */ |
| |
2273 while (l) { |
| |
2274 struct yahoo_pair *pair = l->data; |
| |
2275 |
| |
2276 switch (pair->key) { |
| |
2277 case 4: |
| |
2278 who = pair->value; |
| |
2279 if(strncmp(who, user_data->host_username, strlen(user_data->host_username)) != 0) { |
| |
2280 /* from whom are we receiving the packets ?? */ |
| |
2281 purple_debug_warning("yahoo","p2p: received data from wrong user"); |
| |
2282 return; |
| |
2283 } |
| |
2284 break; |
| |
2285 case 13: |
| |
2286 user_data->val_13 = strtol(pair->value, NULL, 10); /*Value should be 5-7*/ |
| |
2287 break; |
| |
2288 /*case 5, 49 look laters, no use right now*/ |
| |
2289 } |
| |
2290 l = l->next; |
| |
2291 } |
| |
2292 |
| |
2293 yahoo_write_p2p_packet(data, source); /*udpated the value of key 13, now write data*/ |
| |
2294 } |
| |
2295 |
| |
2296 static void yahoo_read_p2p_pkt_cb(gpointer data, gint source, PurpleInputCondition cond) |
| |
2297 { |
| |
2298 guchar buf[1024]; /*is it safe to assume a fixed array length of 1024 ??*/ |
| |
2299 int len; |
| |
2300 int pos = 0; |
| |
2301 int pktlen; |
| |
2302 struct yahoo_packet *pkt; |
| |
2303 guchar *start = NULL; |
| |
2304 |
| |
2305 if((len = read(source, buf, sizeof(buf))) <= 0 ) |
| |
2306 purple_debug_warning("yahoo","p2p: Error in connection to p2p host\n"); |
| |
2307 |
| |
2308 if(len < YAHOO_PACKET_HDRLEN) |
| |
2309 return; |
| |
2310 if(strncmp((char *)buf, "YMSG", MIN(4, len)) != 0) { |
| |
2311 /* Not a YMSG packet */ |
| |
2312 purple_debug_warning("yahoo","p2p: Got something other than YMSG packet\n"); |
| |
2313 |
| |
2314 start = memchr(buf + 1, 'Y', len - 1); |
| |
2315 if(start) { |
| |
2316 g_memmove(buf, start, len - (start - buf)); |
| |
2317 len -= start - buf; |
| |
2318 } else { |
| |
2319 g_free(buf); |
| |
2320 return; |
| |
2321 } |
| |
2322 } |
| |
2323 |
| |
2324 pos += 4; /* YMSG */ |
| |
2325 pos += 2; |
| |
2326 pos += 2; |
| |
2327 |
| |
2328 pktlen = yahoo_get16(buf + pos); pos += 2; |
| |
2329 purple_debug(PURPLE_DEBUG_MISC, "yahoo", "p2p: %d bytes to read\n", len); |
| |
2330 |
| |
2331 pkt = yahoo_packet_new(0, 0, 0); |
| |
2332 |
| |
2333 pkt->service = yahoo_get16(buf + pos); pos += 2; |
| |
2334 if(pkt->service != YAHOO_SERVICE_P2PFILEXFER) { |
| |
2335 /* Shouldn't we be getting p2p filexfer packets only*/ |
| |
2336 /* Should we break connection if this happens ??*/ |
| |
2337 return; |
| |
2338 } |
| |
2339 purple_debug_info("yahoo", "p2p: received packet recognized as a p2p, Status: %d\n", pkt->status); |
| |
2340 |
| |
2341 pkt->status = yahoo_get32(buf + pos); pos += 4; |
| |
2342 pkt->id = yahoo_get32(buf + pos); pos += 4; |
| |
2343 |
| |
2344 yahoo_packet_read(pkt, buf + pos, pktlen); |
| |
2345 |
| |
2346 yahoo_p2p_packet_process(data, source, pkt); |
| |
2347 yahoo_packet_free(pkt); |
| |
2348 } |
| |
2349 |
| |
2350 static void yahoo_p2p_init_cb(gpointer data, gint source, const gchar *error_message) |
| |
2351 { |
| |
2352 if(error_message != NULL) { |
| |
2353 purple_debug_warning("yahoo","p2p: %s\n",error_message); |
| |
2354 return; |
| |
2355 } |
| |
2356 |
| |
2357 /*Add an Input Read event to the file descriptor*/ |
| |
2358 purple_input_add(source, PURPLE_INPUT_READ, yahoo_read_p2p_pkt_cb, data); |
| |
2359 |
| |
2360 yahoo_write_p2p_packet(data, source); /*create and send packet*/ |
| |
2361 } |
| |
2362 |
| 2216 static void yahoo_process_p2p(PurpleConnection *gc, struct yahoo_packet *pkt) |
2363 static void yahoo_process_p2p(PurpleConnection *gc, struct yahoo_packet *pkt) |
| 2217 { |
2364 { |
| 2218 GSList *l = pkt->hash; |
2365 GSList *l = pkt->hash; |
| 2219 char *who = NULL; |
2366 char *who = NULL; |
| 2220 char *base64 = NULL; |
2367 char *base64 = NULL; |
| 2221 guchar *decoded; |
2368 guchar *decoded; |
| 2222 gsize len; |
2369 gsize len; |
| |
2370 gint val_13 = 0; |
| |
2371 PurpleAccount *account; |
| |
2372 struct yahoo_p2p_data *user_data = g_new0(struct yahoo_p2p_data, 1); |
| 2223 |
2373 |
| 2224 while (l) { |
2374 while (l) { |
| 2225 struct yahoo_pair *pair = l->data; |
2375 struct yahoo_pair *pair = l->data; |
| 2226 |
2376 |
| 2227 switch (pair->key) { |
2377 switch (pair->key) { |
| 2228 case 5: |
2378 case 5: |
| 2229 /* our identity */ |
2379 /* our identity */ |
| 2230 break; |
2380 break; |
| 2231 case 4: |
2381 case 4: |
| 2232 who = pair->value; |
2382 who = (char *)g_malloc(strlen(pair->value)); |
| |
2383 strcpy(who, pair->value); |
| |
2384 user_data->host_username = who; |
| 2233 break; |
2385 break; |
| 2234 case 1: |
2386 case 1: |
| 2235 /* who again, the master identity this time? */ |
2387 /* who again, the master identity this time? */ |
| 2236 break; |
2388 break; |
| 2237 case 12: |
2389 case 12: |
| 2238 base64 = pair->value; |
2390 base64 = pair->value; |
| 2239 /* so, this is an ip address. in base64. decoded it's in ascii. |
2391 /* so, this is an ip address. in base64. decoded it's in ascii. |
| 2240 after strtol, it's in reversed byte order. Who thought this up?*/ |
2392 after strtol, it's in reversed byte order. Who thought this up?*/ |
| 2241 break; |
2393 break; |
| |
2394 case 13: |
| |
2395 val_13 = strtol(pair->value, NULL, 10); /*Value always 0*/ |
| |
2396 user_data->val_13 = val_13; |
| |
2397 break; |
| |
2398 |
| 2242 /* |
2399 /* |
| 2243 TODO: figure these out |
2400 TODO: figure these out |
| 2244 yahoo: Key: 61 Value: 0 |
2401 yahoo: Key: 61 Value: 0 |
| 2245 yahoo: Key: 2 Value: |
2402 yahoo: Key: 2 Value: |
| 2246 yahoo: Key: 13 Value: 0 |
2403 yahoo: Key: 13 Value: 0 packet count ?? |
| 2247 yahoo: Key: 49 Value: PEERTOPEER |
2404 yahoo: Key: 49 Value: PEERTOPEER |
| 2248 yahoo: Key: 140 Value: 1 |
2405 yahoo: Key: 140 Value: 1 |
| 2249 yahoo: Key: 11 Value: -1786225828 |
2406 yahoo: Key: 11 Value: -1786225828 |
| 2250 */ |
2407 */ |
| 2251 |
2408 |