1054
|
1 /*
|
|
2 Yahoo Pager Client Library
|
|
3
|
|
4 This code is based on code by Douglas Winslow. The original info from
|
|
5 his code is listed below. This code has taken his code and has been
|
|
6 altered to my naming and coding conventions and has been made more
|
|
7 usable as a library of routines.
|
|
8
|
|
9 -- Nathan Neulinger <nneul@umr.edu>
|
|
10 */
|
|
11
|
|
12 /*
|
|
13 Yahoo Pager Client Emulator Pro - yppro.c
|
|
14 A basic reference implementation
|
|
15 Douglas Winslow <douglas@min.net>
|
|
16 Tue Sep 1 02:28:21 EDT 1998
|
|
17 Version 2, Revision 2
|
|
18 Known to compile on Linux 2.0, FreeBSD 2.2, and BSDi 3.0.
|
|
19 hi to aap bdc drw jfn jrc mm mcd [cejn]b #cz and rootshell
|
|
20
|
|
21 Finally!
|
|
22 Yahoo finally patched their server-side, and things will be getting
|
|
23 back to "normal". I will continue to maintain this code as long as
|
|
24 there is interest for it. Since Yahoo will be discontinuing YPNS1.1
|
|
25 login support shortly, I've upgraded this client to do YPNS1.2. You
|
|
26 *must* have a password to pass authentication to the pager server.
|
|
27 This authentication is done by a weird HTTP cookie method.
|
|
28
|
|
29 This code is distributed under the GNU General Public License (GPL)
|
|
30 */
|
|
31
|
|
32 #include "config.h"
|
|
33 #include <stdio.h>
|
|
34 #include <netdb.h>
|
|
35 #include <fcntl.h>
|
|
36 #include <errno.h>
|
|
37 #include <sys/socket.h>
|
|
38 #include <netinet/in.h>
|
|
39 #if defined(WITH_GTK)
|
|
40 #include <gtk/gtk.h>
|
|
41 #endif
|
|
42 #include <unistd.h>
|
|
43 #if defined(HAVE_STRINGS_H)
|
|
44 #include <strings.h>
|
|
45 #endif
|
|
46 #if defined(HAVE_STRING_H)
|
|
47 #include <string.h>
|
|
48 #endif
|
|
49 #include <ctype.h>
|
|
50 #include "libyahoo.h"
|
|
51 #ifdef HAVE_DMALLOC
|
|
52 #include "dmalloc.h"
|
|
53 #else
|
|
54 #include <stdlib.h>
|
|
55 #endif
|
|
56
|
|
57 #include "memtok.h"
|
|
58
|
|
59 /* allow libyahoo to be used without gtkyahoo's debug support */
|
|
60 #ifdef ENABLE_LIBYAHOO_DEBUG
|
|
61 #include "libyahoo-debug.h"
|
|
62 #else
|
|
63 static void yahoo_dbg_Print(char *tmp, ...)
|
|
64 {
|
|
65 }
|
|
66
|
|
67 #define yahoo_dbg_NullCheck(x) ((x)?(x):("[NULL]"))
|
|
68 #endif
|
|
69
|
|
70 /* remap functions to gtk versions */
|
|
71 #if defined(WITH_GTK)
|
|
72 #define malloc g_malloc
|
|
73 #define free g_free
|
|
74 #define calloc(x,y) g_malloc0((x)*(y))
|
|
75 #endif
|
|
76
|
|
77 #if (!defined(TRUE) || !defined(FALSE))
|
|
78 # define TRUE 1
|
|
79 # define FALSE 0
|
|
80 #endif
|
|
81
|
|
82 /* Define a quick shortcut function to free a pointer and set it to null */
|
|
83 #define FREE(x) if (x) { free(x); x=NULL; }
|
|
84
|
|
85 #if defined(WITH_SOCKS4)
|
|
86 void SOCKSinit(char *argv0);
|
|
87 #endif
|
|
88
|
|
89 /* pager server host */
|
|
90 #define YAHOO_PAGER_HOST "cs.yahoo.com"
|
|
91 #define YAHOO_PAGER_PORT 5050
|
|
92 /* pager server host for http connections */
|
|
93 #define YAHOO_PAGER_HTTP_HOST "http.pager.yahoo.com"
|
|
94 #define YAHOO_PAGER_HTTP_PORT 80
|
|
95 /* authentication/login host */
|
|
96 #define YAHOO_AUTH_HOST "msg.edit.yahoo.com"
|
|
97 #define YAHOO_AUTH_PORT 80
|
|
98 /* buddy/identity/config host */
|
|
99 #define YAHOO_DATA_HOST YAHOO_AUTH_HOST
|
|
100 #define YAHOO_DATA_PORT 80
|
|
101 /* Address book host */
|
|
102 #define YAHOO_ADDRESS_HOST "uk.address.yahoo.com"
|
|
103 #define YAHOO_ADDRESS_PORT 80
|
|
104
|
|
105 /* User agent to use for HTTP connections */
|
|
106 /* It needs to have Mozilla/4 in it, otherwise it fails */
|
|
107 #ifndef VERSION
|
|
108 #define VERSION "1.0"
|
|
109 #endif
|
|
110 #define YAHOO_USER_AGENT "Mozilla/4.6 (libyahoo/" VERSION ")"
|
|
111
|
|
112 #define YAHOO_PROTOCOL_HEADER "YPNS2.0"
|
|
113
|
|
114 /*
|
|
115 * Routines and data private to this library, should not be directly
|
|
116 * accessed outside of these routines.
|
|
117 */
|
|
118
|
|
119 /* Service code labels for debugging output */
|
|
120 static struct yahoo_idlabel yahoo_service_codes[] = {
|
|
121 {YAHOO_SERVICE_LOGON, "Pager Logon"},
|
|
122 {YAHOO_SERVICE_LOGOFF, "Pager Logoff"},
|
|
123 {YAHOO_SERVICE_ISAWAY, "Is Away"},
|
|
124 {YAHOO_SERVICE_ISBACK, "Is Back"},
|
|
125 {YAHOO_SERVICE_IDLE, "Idle"},
|
|
126 {YAHOO_SERVICE_MESSAGE, "Message"},
|
|
127 {YAHOO_SERVICE_IDACT, "Activate Identity"},
|
|
128 {YAHOO_SERVICE_IDDEACT, "Deactivate Identity"},
|
|
129 {YAHOO_SERVICE_MAILSTAT, "Mail Status"},
|
|
130 {YAHOO_SERVICE_USERSTAT, "User Status"},
|
|
131 {YAHOO_SERVICE_NEWMAIL, "New Mail"},
|
|
132 {YAHOO_SERVICE_CHATINVITE, "Chat Invitation"},
|
|
133 {YAHOO_SERVICE_CALENDAR, "Calendar Reminder"},
|
|
134 {YAHOO_SERVICE_NEWPERSONALMAIL, "New Personals Mail"},
|
|
135 {YAHOO_SERVICE_NEWCONTACT, "New Friend"},
|
|
136 {YAHOO_SERVICE_GROUPRENAME, "Group Renamed"},
|
|
137 {YAHOO_SERVICE_ADDIDENT, "Add Identity"},
|
|
138 {YAHOO_SERVICE_ADDIGNORE, "Add Ignore"},
|
|
139 {YAHOO_SERVICE_PING, "Ping"},
|
|
140 {YAHOO_SERVICE_SYSMESSAGE, "System Message"},
|
|
141 {YAHOO_SERVICE_CONFINVITE, "Conference Invitation"},
|
|
142 {YAHOO_SERVICE_CONFLOGON, "Conference Logon"},
|
|
143 {YAHOO_SERVICE_CONFDECLINE, "Conference Decline"},
|
|
144 {YAHOO_SERVICE_CONFLOGOFF, "Conference Logoff"},
|
|
145 {YAHOO_SERVICE_CONFMSG, "Conference Message"},
|
|
146 {YAHOO_SERVICE_CONFADDINVITE, "Conference Additional Invitation"},
|
|
147 {YAHOO_SERVICE_CHATLOGON, "Chat Logon"},
|
|
148 {YAHOO_SERVICE_CHATLOGOFF, "Chat Logoff"},
|
|
149 {YAHOO_SERVICE_CHATMSG, "Chat Message"},
|
|
150 {YAHOO_SERVICE_GAMELOGON, "Game Logon"},
|
|
151 {YAHOO_SERVICE_GAMELOGOFF, "Game Logoff"},
|
|
152 {YAHOO_SERVICE_FILETRANSFER, "File Transfer"},
|
|
153 {YAHOO_SERVICE_PASSTHROUGH2, "Passthrough 2"},
|
|
154 {0, NULL}
|
|
155 };
|
|
156
|
|
157 /* Status codes */
|
|
158 static struct yahoo_idlabel yahoo_status_codes[] = {
|
|
159 {YAHOO_STATUS_AVAILABLE, "I'm Available"},
|
|
160 {YAHOO_STATUS_BRB, "Be Right Back"},
|
|
161 {YAHOO_STATUS_BUSY, "Busy"},
|
|
162 {YAHOO_STATUS_NOTATHOME, "Not at Home"},
|
|
163 {YAHOO_STATUS_NOTATDESK, "Not at my Desk"},
|
|
164 {YAHOO_STATUS_NOTINOFFICE, "Not in the Office"},
|
|
165 {YAHOO_STATUS_ONPHONE, "On the Phone"},
|
|
166 {YAHOO_STATUS_ONVACATION, "On Vacation"},
|
|
167 {YAHOO_STATUS_OUTTOLUNCH, "Out to Lunch"},
|
|
168 {YAHOO_STATUS_STEPPEDOUT, "Stepped Out"},
|
|
169 {YAHOO_STATUS_INVISIBLE, "Invisible"},
|
|
170 {YAHOO_STATUS_IDLE, "Idle"},
|
|
171 {YAHOO_STATUS_CUSTOM, "Custom Message"},
|
|
172 {0, NULL}
|
|
173 };
|
|
174
|
|
175 /* Status codes */
|
|
176 static struct yahoo_idlabel yahoo_status_append[] = {
|
|
177 {YAHOO_STATUS_AVAILABLE, "is now available"},
|
|
178 {YAHOO_STATUS_BRB, "will be right back"},
|
|
179 {YAHOO_STATUS_BUSY, "is now busy"},
|
|
180 {YAHOO_STATUS_NOTATHOME, "is not at home"},
|
|
181 {YAHOO_STATUS_NOTATDESK, "is not at their desk"},
|
|
182 {YAHOO_STATUS_NOTINOFFICE, "is not in the office"},
|
|
183 {YAHOO_STATUS_ONPHONE, "is on the phone"},
|
|
184 {YAHOO_STATUS_ONVACATION, "is on vacation"},
|
|
185 {YAHOO_STATUS_OUTTOLUNCH, "is out to lunch"},
|
|
186 {YAHOO_STATUS_STEPPEDOUT, "has stepped out"},
|
|
187 {YAHOO_STATUS_INVISIBLE, "is now invisible"},
|
|
188 {YAHOO_STATUS_IDLE, "is now idle"},
|
|
189 {YAHOO_STATUS_CUSTOM, ""},
|
|
190 {0, NULL}
|
|
191 };
|
|
192
|
|
193 /* Take a 4-byte character string in little-endian format and return
|
|
194 a unsigned integer */
|
|
195 unsigned int yahoo_makeint(unsigned char *data)
|
|
196 {
|
|
197 if (data)
|
|
198 {
|
|
199 return ((data[3] << 24) + (data[2] << 16) + (data[1] << 8) +
|
|
200 (data[0]));
|
|
201 }
|
|
202 return 0;
|
|
203 }
|
|
204
|
|
205 /* Take an integer and store it into a 4 character little-endian string */
|
|
206 static void yahoo_storeint(unsigned char *data, unsigned int val)
|
|
207 {
|
|
208 unsigned int tmp = val;
|
|
209 int i;
|
|
210
|
|
211 if (data)
|
|
212 {
|
|
213 for (i = 0; i < 4; i++)
|
|
214 {
|
|
215 data[i] = tmp % 256;
|
|
216 tmp >>= 8;
|
|
217 }
|
|
218 }
|
|
219 }
|
|
220
|
|
221 /*
|
|
222 converts a comma seperated list to an array of strings
|
|
223 used primarily in conference code
|
|
224
|
|
225 allocates a string in here -- caller needs to free it
|
|
226 */
|
|
227 char **yahoo_list2array(char *buff)
|
|
228 {
|
|
229 char **tmp_array = NULL;
|
|
230 char *array_elem = NULL;
|
|
231 char *tmp = NULL;
|
|
232
|
|
233 char *buffer = 0;
|
|
234 char *ptr_buffer = 0;
|
|
235
|
|
236 int sublen = 0;
|
|
237 int cnt = 0;
|
|
238 int nxtelem = 0;
|
|
239 unsigned int i = 0;
|
|
240 unsigned int len = 0;
|
|
241
|
|
242 if (0 == buff)
|
|
243 return 0;
|
|
244
|
|
245 buffer = strdup(buff); /* play with a copy */
|
|
246 ptr_buffer = buffer;
|
|
247
|
|
248 /* count the number of users (commas + 1) */
|
|
249 for (i = 0; i < strlen(buffer); i++)
|
|
250 {
|
|
251 if (buffer[i] == ',')
|
|
252 {
|
|
253 /*
|
|
254 if not looking at end of list
|
|
255 ( ignore extra pesky comma at end of list)
|
|
256 */
|
|
257 if (i != (strlen(buffer) - 1))
|
|
258 cnt++;
|
|
259 }
|
|
260 }
|
|
261
|
|
262 /* add one more name than comma .. */
|
|
263 cnt++;
|
|
264
|
|
265 /* allocate the array to hold the list of buddys */
|
|
266 /* null terminated array of pointers */
|
|
267 tmp_array = (char **) malloc(sizeof(char *) * (cnt + 1));
|
|
268
|
|
269 memset(tmp_array, 0, (sizeof(char *) * (cnt + 1)));
|
|
270
|
|
271 /* Parse through the list and get all the entries */
|
|
272 while ((ptr_buffer[sublen] != ',') && (ptr_buffer[sublen] != '\0'))
|
|
273 sublen++;
|
|
274 tmp = (char *) malloc(sizeof(char) * (sublen + 1));
|
|
275
|
|
276 memcpy(tmp, ptr_buffer, sublen);
|
|
277 tmp[sublen] = '\0';
|
|
278
|
|
279 if (ptr_buffer[sublen] != '\0')
|
|
280 ptr_buffer = &(ptr_buffer[sublen + 1]);
|
|
281 else
|
|
282 ptr_buffer = &(ptr_buffer[sublen]); /* stay at the null char */
|
|
283 sublen = 0;
|
|
284
|
|
285 while (tmp && (strcmp(tmp, "") != 0))
|
|
286 {
|
|
287 len = strlen(tmp);
|
|
288 array_elem = (char *) malloc(sizeof(char) * (len + 1));
|
|
289
|
|
290 strncpy(array_elem, tmp, (len + 1));
|
|
291 array_elem[len] = '\0';
|
|
292
|
|
293 tmp_array[nxtelem++] = array_elem;
|
|
294 array_elem = NULL;
|
|
295
|
|
296 FREE(tmp);
|
|
297
|
|
298 while ((ptr_buffer[sublen] != ',') && (ptr_buffer[sublen] != '\0'))
|
|
299 sublen++;
|
|
300 tmp = (char *) malloc(sizeof(char) * (sublen + 1));
|
|
301
|
|
302 memcpy(tmp, ptr_buffer, sublen);
|
|
303 tmp[sublen] = '\0';
|
|
304
|
|
305 if (ptr_buffer[sublen] != '\0')
|
|
306 ptr_buffer = &(ptr_buffer[sublen + 1]);
|
|
307 else
|
|
308 ptr_buffer = &(ptr_buffer[sublen]); /* stay at the null char */
|
|
309
|
|
310 sublen = 0;
|
|
311 }
|
|
312 tmp_array[nxtelem] = NULL;
|
|
313
|
|
314 FREE(tmp);
|
|
315 FREE(buffer);
|
|
316 return (tmp_array);
|
|
317
|
|
318 } /* yahoo_list2array() */
|
|
319
|
|
320 /*
|
|
321 Free's the memory associated with an array generated bu yahoo_list2array
|
|
322 */
|
|
323 void yahoo_arraykill(char **array)
|
|
324 {
|
|
325 int nxtelem = 0;
|
|
326
|
|
327 if (NULL == array)
|
|
328 return;
|
|
329
|
|
330 while (array[nxtelem] != NULL)
|
|
331 {
|
|
332 free(array[nxtelem++]);
|
|
333 }
|
|
334
|
|
335 free(array);
|
|
336 } /* yahoo_arraykill() */
|
|
337
|
|
338 /*
|
|
339 converts an array of strings to a comma seperated list
|
|
340 used primarily in conference code
|
|
341
|
|
342 allocates a string in here.. needs to be freed by caller program
|
|
343 */
|
|
344 char *yahoo_array2list(char **array)
|
|
345 {
|
|
346 char *list = NULL;
|
|
347 int nxtelem = 0;
|
|
348 int arraylength = 0;
|
|
349
|
|
350 if (NULL == array)
|
|
351 return NULL;
|
|
352
|
|
353 while (array[nxtelem] != NULL)
|
|
354 {
|
|
355 arraylength += strlen(array[nxtelem++]);
|
|
356 arraylength++; /* comma */
|
|
357 }
|
|
358
|
|
359 nxtelem = 0; /* reset array counter */
|
|
360
|
|
361 /* allocate at least one - for NULL list - and to
|
|
362 allow my strcat to write past the end for the
|
|
363 last comma which gets converted to NULL */
|
|
364 list = (char *) malloc(sizeof(char) * (arraylength + 1));
|
|
365
|
|
366 memset(list, 0, (arraylength + 1));
|
|
367
|
|
368 while (array[nxtelem] != NULL)
|
|
369 {
|
|
370 strcat(list, array[nxtelem++]);
|
|
371 strcat(list, ",");
|
|
372 }
|
|
373 /*
|
|
374 overwrite last ',' with a NULL
|
|
375 makes the string end with two null characters, but this way
|
|
376 handles empty lists gracefully
|
|
377 */
|
|
378 list[arraylength - 1] = '\0';
|
|
379
|
|
380 return (list);
|
|
381 } /* yahoo_array2list() */
|
|
382
|
|
383 /* Free a buddy list */
|
|
384 static void yahoo_free_buddies(struct yahoo_context *ctx)
|
|
385 {
|
|
386 int i;
|
|
387
|
|
388 if (!ctx->buddies)
|
|
389 {
|
|
390 return;
|
|
391 }
|
|
392
|
|
393 i = 0;
|
|
394 while (ctx->buddies[i])
|
|
395 {
|
|
396 FREE(ctx->buddies[i]->group);
|
|
397 FREE(ctx->buddies[i]->id);
|
|
398 i++;
|
|
399 }
|
|
400
|
|
401 FREE(ctx->buddies);
|
|
402 }
|
|
403
|
|
404 /* Free a identities list */
|
|
405 static void yahoo_free_identities(struct yahoo_context *ctx)
|
|
406 {
|
|
407 int i;
|
|
408
|
|
409 if (!ctx->identities)
|
|
410 {
|
|
411 return;
|
|
412 }
|
|
413
|
|
414 i = 0;
|
|
415 while (ctx->identities[i])
|
|
416 {
|
|
417 FREE(ctx->identities[i]);
|
|
418 i++;
|
|
419 }
|
|
420
|
|
421 FREE(ctx->identities);
|
|
422 yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_free_identities: done\n");
|
|
423 }
|
|
424
|
|
425 #if 0 /* not used at the moment */
|
|
426 static void yahoo_hexdump(char *label, unsigned char *data, int datalen)
|
|
427 {
|
|
428 int i, j;
|
|
429 int val, skipped_last;
|
|
430 char current[100];
|
|
431 char last[100];
|
|
432 char tmp[15];
|
|
433 char outline[100];
|
|
434 static int last_datalen = 0;
|
|
435 static unsigned char *last_data = NULL;
|
|
436
|
|
437 if (last_data)
|
|
438 {
|
|
439 if (last_datalen == datalen && !memcmp(data, last_data, datalen))
|
|
440 {
|
|
441 printf("\n%s: <same as last dump>\n", label);
|
|
442 return;
|
|
443 }
|
|
444 FREE(last_data);
|
|
445 }
|
|
446
|
|
447 /* Copy the packet so we can don't duplicate it next time. */
|
|
448 last_datalen = datalen;
|
|
449 last_data = (unsigned char *) malloc(datalen);
|
|
450 memcpy(last_data, data, datalen);
|
|
451
|
|
452 /* Handle printing the full entry out */
|
|
453 printf("\n");
|
|
454 printf("%s:\n", label);
|
|
455
|
|
456 skipped_last = 0;
|
|
457 last[0] = 0;
|
|
458 for (j = 0; j * 16 < datalen; j++)
|
|
459 {
|
|
460 current[0] = 0;
|
|
461
|
|
462 /* Print out in hex */
|
|
463 for (i = j * 16; i < (j * 16 + 16); i++)
|
|
464 {
|
|
465 if (i < datalen)
|
|
466 {
|
|
467 val = data[i];
|
|
468 sprintf(tmp, "%.2X ", val);
|
|
469 }
|
|
470 else
|
|
471 {
|
|
472 sprintf(tmp, " ");
|
|
473 }
|
|
474 strcat(current, tmp);
|
|
475 }
|
|
476
|
|
477 /* Print out in ascii */
|
|
478 strcat(current, " ");
|
|
479 for (i = j * 16; i < (j * 16) + 16; i++)
|
|
480 {
|
|
481 if (i < datalen)
|
|
482 {
|
|
483 if (isprint(data[i]))
|
|
484 {
|
|
485 sprintf(tmp, "%c", data[i]);
|
|
486 }
|
|
487 else
|
|
488 {
|
|
489 sprintf(tmp, ".");
|
|
490 }
|
|
491 }
|
|
492 else
|
|
493 {
|
|
494 sprintf(tmp, " ");
|
|
495 }
|
|
496 strcat(current, tmp);
|
|
497 }
|
|
498
|
|
499 outline[0] = 0;
|
|
500 if (!strcmp(current, last))
|
|
501 {
|
|
502 if (!skipped_last)
|
|
503 {
|
|
504 strcpy(outline, " ....:\n");
|
|
505 }
|
|
506 skipped_last = 1;
|
|
507 }
|
|
508 else
|
|
509 {
|
|
510 sprintf(outline, " %.4d: %s\n", j * 16, current);
|
|
511 skipped_last = 0;
|
|
512 }
|
|
513 printf("%s", outline);
|
|
514 strcpy(last, current);
|
|
515 }
|
|
516
|
|
517 if (skipped_last)
|
|
518 {
|
|
519 printf("%s", outline);
|
|
520 }
|
|
521 printf("\n");
|
|
522 }
|
|
523 #endif
|
|
524
|
|
525 static int yahoo_socket_connect(struct yahoo_context *ctx, char *host,
|
|
526 int port)
|
|
527 {
|
|
528 struct sockaddr_in serv_addr;
|
|
529 struct hostent *server;
|
|
530 int servfd;
|
|
531 int res;
|
|
532
|
|
533 yahoo_dbg_Print("libyahoo",
|
|
534 "[libyahoo] yahoo_socket_connect - starting [%s:%d]\n", host, port);
|
|
535
|
|
536 if (!ctx || !host || !port)
|
|
537 {
|
|
538 yahoo_dbg_Print("libyahoo",
|
|
539 "[libyahoo] yahoo_socket_connect - nulls\n");
|
|
540 return 0;
|
|
541 }
|
|
542
|
|
543 server = gethostbyname(host);
|
|
544 if (!server)
|
|
545 {
|
|
546 printf("[libyahoo] failed to look up server (%s:%d)\n", host, port);
|
|
547 return (0);
|
|
548 }
|
|
549
|
|
550 servfd = socket(AF_INET, SOCK_STREAM, 0);
|
|
551
|
|
552 bzero(&serv_addr, sizeof(serv_addr));
|
|
553 serv_addr.sin_family = AF_INET;
|
|
554 bcopy(server->h_addr, &serv_addr.sin_addr.s_addr, server->h_length);
|
|
555 serv_addr.sin_port = htons(port);
|
|
556
|
|
557 res = -1;
|
|
558 if (ctx->connect_mode == YAHOO_CONNECT_SOCKS4)
|
|
559 {
|
|
560 #if defined(WITH_SOCKS4)
|
|
561 res =
|
|
562 Rconnect(servfd, (struct sockaddr *) &serv_addr,
|
|
563 sizeof(serv_addr));
|
|
564 #endif
|
|
565 }
|
|
566 else if (ctx->connect_mode == YAHOO_CONNECT_SOCKS5)
|
|
567 {
|
|
568 #if defined(WITH_SOCKS5)
|
|
569 #endif
|
|
570 }
|
|
571 else if (ctx->connect_mode == YAHOO_CONNECT_NORMAL ||
|
|
572 ctx->connect_mode == YAHOO_CONNECT_HTTP ||
|
|
573 ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY)
|
|
574 {
|
|
575 res =
|
|
576 connect(servfd, (struct sockaddr *) &serv_addr,
|
|
577 sizeof(serv_addr));
|
|
578 }
|
|
579 else
|
|
580 {
|
|
581 printf("[libyahoo] unhandled connect mode (%d).\n",
|
|
582 ctx->connect_mode);
|
|
583 return (0);
|
|
584 }
|
|
585
|
|
586 if (res < 0)
|
|
587 {
|
|
588 close(servfd);
|
|
589 servfd = 0;
|
|
590 printf("[libyahoo] failed to connect to server (%s:%d)\n", host,
|
|
591 port);
|
|
592 return (0);
|
|
593 }
|
|
594
|
|
595 yahoo_dbg_Print("libyahoo",
|
|
596 "[libyahoo] yahoo_socket_connect - finished\n");
|
|
597 return servfd;
|
|
598 }
|
|
599
|
|
600 /* really ugly brute force approach - someone find a GPL'd/free
|
|
601 equivalent and replace this p.o.s. */
|
|
602 static char *yahoo_urlencode(char *data)
|
|
603 {
|
|
604 static char *tmp = NULL;
|
|
605 char buf[4];
|
|
606 int i, len;
|
|
607
|
|
608 len = 3 * strlen(data) + 1;
|
|
609
|
|
610 FREE(tmp);
|
|
611
|
|
612 if (!data)
|
|
613 {
|
|
614 return NULL;
|
|
615 }
|
|
616
|
|
617 /* change this at some point to re-use the buffer, no sense
|
|
618 allocating repeatedly */
|
|
619 tmp = (char *) malloc(len);
|
|
620 tmp[0] = 0;
|
|
621
|
|
622 for (i = 0; i < strlen(data); i++)
|
|
623 {
|
|
624 if (isdigit((int) (data[i])) ||
|
|
625 isalpha((int) data[i]) || data[i] == '_')
|
|
626 {
|
|
627 buf[0] = data[i];
|
|
628 buf[1] = 0;
|
|
629 strcat(tmp, buf);
|
|
630 }
|
|
631 else
|
|
632 {
|
|
633 sprintf(buf, "%%%.2X", data[i]);
|
|
634 strcat(tmp, buf);
|
|
635 }
|
|
636 }
|
|
637
|
|
638 return tmp;
|
|
639 }
|
|
640
|
|
641 static void yahoo_addtobuffer(struct yahoo_context *ctx, char *data,
|
|
642 int datalen)
|
|
643 {
|
|
644 //yahoo_hexdump("yahoo_addtobuffer", data, datalen);
|
|
645
|
|
646 /* Check buffer, increase size if necessary */
|
|
647 if (!ctx->io_buf
|
|
648 || ((ctx->io_buf_maxlen - ctx->io_buf_curlen) < (datalen + 100)))
|
|
649 {
|
|
650 char *new_io_buf;
|
|
651
|
|
652 if (datalen < 10240)
|
|
653 {
|
|
654 ctx->io_buf_maxlen += 10240;
|
|
655 }
|
|
656 else
|
|
657 {
|
|
658 ctx->io_buf_maxlen += datalen;
|
|
659 }
|
|
660 new_io_buf = (char *) malloc(ctx->io_buf_maxlen);
|
|
661
|
|
662 if (ctx->io_buf)
|
|
663 {
|
|
664 memcpy(new_io_buf, ctx->io_buf, ctx->io_buf_curlen);
|
|
665 FREE(ctx->io_buf);
|
|
666 }
|
|
667
|
|
668 ctx->io_buf = new_io_buf;
|
|
669 }
|
|
670
|
|
671 memcpy(ctx->io_buf + ctx->io_buf_curlen, data, datalen);
|
|
672 ctx->io_buf_curlen += datalen;
|
|
673 }
|
|
674
|
|
675 static int yahoo_tcp_readline(char *ptr, int maxlen, int fd)
|
|
676 {
|
|
677 int n, rc;
|
|
678 char c;
|
|
679
|
|
680 for (n = 1; n < maxlen; n++)
|
|
681 {
|
|
682 again:
|
|
683
|
|
684 if ((rc = read(fd, &c, 1)) == 1)
|
|
685 {
|
|
686 *ptr++ = c;
|
|
687 if (c == '\n')
|
|
688 break;
|
|
689 }
|
|
690 else if (rc == 0)
|
|
691 {
|
|
692 if (n == 1)
|
|
693 return (0); /* EOF, no data */
|
|
694 else
|
|
695 break; /* EOF, w/ data */
|
|
696 }
|
|
697 else
|
|
698 {
|
|
699 if (errno == EINTR)
|
|
700 goto again;
|
|
701 printf
|
|
702 ("Yahoo: Error reading from socket in yahoo_tcp_readline.\n");
|
|
703 exit(1);
|
|
704 }
|
|
705 }
|
|
706
|
|
707 *ptr = 0;
|
|
708 return (n);
|
|
709 }
|
|
710
|
|
711 /*
|
|
712 * Published library interfaces
|
|
713 */
|
|
714
|
|
715 /* Initialize interface to yahoo library, sortof like a class object
|
|
716 creation routine. */
|
|
717 struct yahoo_context *yahoo_init(char *user, char *password,
|
|
718 struct yahoo_options *options)
|
|
719 {
|
|
720 struct yahoo_context *tmp;
|
|
721
|
|
722 if (!user || !password)
|
|
723 {
|
|
724 return NULL;
|
|
725 }
|
|
726
|
|
727 /* Allocate a new context */
|
|
728 tmp = (struct yahoo_context *) calloc(1, sizeof(*tmp));
|
|
729
|
|
730 /* Fill in any available info */
|
|
731 tmp->user = strdup(user);
|
|
732 tmp->password = strdup(password);
|
|
733 if (options->proxy_host)
|
|
734 {
|
|
735 tmp->proxy_host = strdup(options->proxy_host);
|
|
736 }
|
|
737 tmp->proxy_port = options->proxy_port;
|
|
738 tmp->connect_mode = options->connect_mode;
|
|
739
|
|
740 #if defined(WITH_SOCKS4)
|
|
741 if (connect_mode == YAHOO_CONNECT_SOCKS4)
|
|
742 {
|
|
743 static int did_socks_init = 0;
|
|
744
|
|
745 if (did_socks_init == 0)
|
|
746 {
|
|
747 SOCKSinit("libyahoo");
|
|
748 did_socks_init = 1;
|
|
749 }
|
|
750 }
|
|
751 #endif
|
|
752
|
|
753 /* Fetch the cookies */
|
|
754 if (!yahoo_fetchcookies(tmp))
|
|
755 {
|
|
756 yahoo_free_context(tmp);
|
|
757 return NULL;
|
|
758 }
|
|
759
|
|
760 return tmp;
|
|
761 }
|
|
762
|
|
763 /* Free a yahoo context */
|
|
764 void yahoo_free_context(struct yahoo_context *ctx)
|
|
765 {
|
|
766 FREE(ctx->user);
|
|
767 FREE(ctx->password);
|
|
768 FREE(ctx->proxy_host);
|
|
769 FREE(ctx->io_buf);
|
|
770 FREE(ctx->cookie);
|
|
771 FREE(ctx->login_cookie);
|
|
772 FREE(ctx->login_id);
|
|
773
|
|
774 yahoo_free_buddies(ctx);
|
|
775 yahoo_free_identities(ctx);
|
|
776
|
|
777 FREE(ctx);
|
|
778 }
|
|
779
|
|
780 /* Turn a status code into it's corresponding string */
|
|
781 char *yahoo_get_status_string(int statuscode)
|
|
782 {
|
|
783 int i;
|
|
784
|
|
785 for (i = 0; yahoo_status_codes[i].label; i++)
|
|
786 {
|
|
787 if (yahoo_status_codes[i].id == statuscode)
|
|
788 {
|
|
789 return yahoo_status_codes[i].label;
|
|
790 }
|
|
791 }
|
|
792 return NULL;
|
|
793 }
|
|
794
|
|
795 /* Turn a status code into it's corresponding string */
|
|
796 char *yahoo_get_status_append(int statuscode)
|
|
797 {
|
|
798 int i;
|
|
799
|
|
800 for (i = 0; yahoo_status_append[i].label; i++)
|
|
801 {
|
|
802 if (yahoo_status_append[i].id == statuscode)
|
|
803 {
|
|
804 return yahoo_status_append[i].label;
|
|
805 }
|
|
806 }
|
|
807 return NULL;
|
|
808 }
|
|
809
|
|
810 /* Turn a service code into it's corresponding string */
|
|
811 char *yahoo_get_service_string(int servicecode)
|
|
812 {
|
|
813 int i;
|
|
814 char *name = "Unknown Service";
|
|
815 static char tmp[50];
|
|
816
|
|
817 for (i = 0; yahoo_service_codes[i].label; i++)
|
|
818 {
|
|
819 if (yahoo_service_codes[i].id == servicecode)
|
|
820 {
|
|
821 name = yahoo_service_codes[i].label;
|
|
822 break;
|
|
823 }
|
|
824 }
|
|
825
|
|
826 snprintf(tmp, 50, "(%d) %s", servicecode, name);
|
|
827 return tmp;
|
|
828 }
|
|
829
|
|
830 /* Return a malloc()'d copy of the users cookie */
|
|
831 int yahoo_fetchcookies(struct yahoo_context *ctx)
|
|
832 {
|
|
833 char buffer[5000];
|
|
834 int servfd;
|
|
835 int i;
|
|
836 int res;
|
|
837 char *tmpstr;
|
|
838
|
|
839 if (!ctx)
|
|
840 {
|
|
841 return 0;
|
|
842 }
|
|
843
|
|
844 yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_fetchcookies: starting\n");
|
|
845
|
|
846 /* Check for cached cookie */
|
|
847 if (ctx->cookie)
|
|
848 {
|
|
849 FREE(ctx->cookie);
|
|
850 }
|
|
851 if (ctx->login_cookie)
|
|
852 {
|
|
853 FREE(ctx->login_cookie);
|
|
854 }
|
|
855
|
|
856 if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY)
|
|
857 {
|
|
858 servfd = yahoo_socket_connect(ctx, ctx->proxy_host, ctx->proxy_port);
|
|
859 }
|
|
860 else
|
|
861 {
|
|
862 servfd = yahoo_socket_connect(ctx, YAHOO_AUTH_HOST, YAHOO_AUTH_PORT);
|
|
863 }
|
|
864 if (!servfd)
|
|
865 {
|
|
866 printf("[libyahoo] failed to connect to pager auth server.\n");
|
|
867 return (0);
|
|
868 }
|
|
869
|
|
870 strcpy(buffer, "GET ");
|
|
871 if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY)
|
|
872 {
|
|
873 strcat(buffer, "http://" YAHOO_AUTH_HOST);
|
|
874 }
|
|
875 strcat(buffer, "/config/ncclogin?login=");
|
|
876 if (ctx->login_id)
|
|
877 {
|
|
878 strcat(buffer, yahoo_urlencode(ctx->login_id));
|
|
879 }
|
|
880 else
|
|
881 {
|
|
882 strcat(buffer, yahoo_urlencode(ctx->user));
|
|
883 }
|
|
884 strcat(buffer, "&passwd=");
|
|
885 strcat(buffer, yahoo_urlencode(ctx->password));
|
|
886 strcat(buffer, "&n=1 HTTP/1.0\r\n");
|
|
887 strcat(buffer, "User-Agent: " YAHOO_USER_AGENT "\r\n");
|
|
888 strcat(buffer, "Host: " YAHOO_AUTH_HOST "\r\n");
|
|
889 strcat(buffer, "\r\n");
|
|
890
|
|
891 write(servfd, buffer, strlen(buffer));
|
|
892
|
|
893 yahoo_dbg_Print("libyahoo",
|
|
894 "[libyahoo] yahoo_fetchcookies: writing buffer '%s'\n", buffer);
|
|
895
|
|
896 ctx->cookie = NULL;
|
|
897 while ((res = yahoo_tcp_readline(buffer, 5000, servfd)) > 0)
|
|
898 {
|
|
899 /* strip out any non-alphas */
|
|
900 for (i = 0; i < strlen(buffer); i++)
|
|
901 {
|
|
902 if (!isprint((int) buffer[i]))
|
|
903 {
|
|
904 buffer[i] = 0;
|
|
905 }
|
|
906 }
|
|
907
|
|
908 yahoo_dbg_Print("libyahoo",
|
|
909 "[libyahoo] yahoo_fetchcookies: read buffer '%s'\n", buffer);
|
|
910
|
|
911 if (!strcasecmp(buffer, "ERROR: Invalid NCC Login"))
|
|
912 {
|
|
913 yahoo_dbg_Print("libyahoo",
|
|
914 "[libyahoo] yahoo_fetchcookies: password was invalid\n");
|
|
915 return (0);
|
|
916 }
|
|
917
|
|
918 if (!strncasecmp(buffer, "Set-Cookie: Y=", 14))
|
|
919 {
|
|
920 FREE(ctx->cookie);
|
|
921 ctx->cookie = strdup(buffer + 12);
|
|
922
|
|
923 tmpstr = strchr(ctx->cookie, ';');
|
|
924 if (tmpstr)
|
|
925 {
|
|
926 *tmpstr = '\0';
|
|
927 }
|
|
928 }
|
|
929 }
|
|
930 yahoo_dbg_Print("libyahoo",
|
|
931 "[libyahoo] yahoo_fetchcookies: closing server connection\n");
|
|
932 close(servfd);
|
|
933 servfd = 0;
|
|
934 yahoo_dbg_Print("libyahoo",
|
|
935 "[libyahoo] yahoo_fetchcookies: closed server connection\n");
|
|
936
|
|
937 if (ctx->cookie)
|
|
938 {
|
|
939 tmpstr = strstr(ctx->cookie, "n=");
|
|
940 if (tmpstr)
|
|
941 {
|
|
942 ctx->login_cookie = strdup(tmpstr + 2);
|
|
943 }
|
|
944
|
|
945 tmpstr = strchr(ctx->login_cookie, '&');
|
|
946 if (tmpstr)
|
|
947 {
|
|
948 *tmpstr = '\0';
|
|
949 }
|
|
950 }
|
|
951
|
|
952 if (ctx->cookie)
|
|
953 yahoo_dbg_Print("libyahoo",
|
|
954 "[libyahoo] yahoo_fetchcookies: cookie (%s)\n", ctx->cookie);
|
|
955 if (ctx->login_cookie)
|
|
956 yahoo_dbg_Print("libyahoo",
|
|
957 "[libyahoo] yahoo_fetchcookies: login cookie (%s)\n",
|
|
958 ctx->login_cookie);
|
|
959
|
|
960 yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_fetchcookies: done\n");
|
|
961
|
|
962 return 1;
|
|
963 }
|
|
964
|
|
965 /* Add a buddy to your buddy list */
|
|
966 int yahoo_add_buddy(struct yahoo_context *ctx, char *addid,
|
|
967 char *active_id, char *group, char *msg)
|
|
968 {
|
|
969 char buffer[5000];
|
|
970 int servfd;
|
|
971
|
|
972 if (!ctx)
|
|
973 {
|
|
974 return 0;
|
|
975 }
|
|
976
|
|
977 if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY)
|
|
978 {
|
|
979 yahoo_dbg_Print("libyahoo",
|
|
980 "[libyahoo] yahoo_add_buddy - connecting via proxy\n");
|
|
981 servfd = yahoo_socket_connect(ctx, ctx->proxy_host, ctx->proxy_port);
|
|
982 }
|
|
983 else
|
|
984 {
|
|
985 yahoo_dbg_Print("libyahoo",
|
|
986 "[libyahoo] yahoo_add_buddy - connecting\n");
|
|
987 servfd = yahoo_socket_connect(ctx, YAHOO_DATA_HOST, YAHOO_DATA_PORT);
|
|
988 }
|
|
989 if (!servfd)
|
|
990 {
|
|
991 yahoo_dbg_Print("libyahoo",
|
|
992 "[libyahoo] yahoo_add_buddy: failed to connect\n");
|
|
993 return (0);
|
|
994 }
|
|
995
|
|
996 strcpy(buffer, "GET ");
|
|
997 if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY)
|
|
998 {
|
|
999 strcat(buffer, "http://" YAHOO_DATA_HOST);
|
|
1000 }
|
|
1001 strcat(buffer, "/config/set_buddygrp?.bg=");
|
|
1002 strcat(buffer, yahoo_urlencode(group));
|
|
1003 strcat(buffer, "&.src=bl&.cmd=a&.bdl=");
|
|
1004 strcat(buffer, yahoo_urlencode(addid));
|
|
1005 strcat(buffer, "&.id=");
|
|
1006 strcat(buffer, yahoo_urlencode(active_id));
|
|
1007 strcat(buffer, "&.l=");
|
|
1008 strcat(buffer, yahoo_urlencode(ctx->user));
|
|
1009 strcat(buffer, "&.amsg=");
|
|
1010 strcat(buffer, yahoo_urlencode(msg));
|
|
1011 strcat(buffer, " HTTP/1.0\r\n");
|
|
1012
|
|
1013 strcat(buffer, "User-Agent: " YAHOO_USER_AGENT "\r\n");
|
|
1014 strcat(buffer, "Host: " YAHOO_DATA_HOST "\r\n");
|
|
1015 strcat(buffer, "Cookie: ");
|
|
1016 strcat(buffer, ctx->cookie);
|
|
1017 strcat(buffer, "\r\n");
|
|
1018 strcat(buffer, "\r\n");
|
|
1019
|
|
1020 write(servfd, buffer, strlen(buffer));
|
|
1021 while (yahoo_tcp_readline(buffer, 5000, servfd) > 0)
|
|
1022 {
|
|
1023 /* just dump the output, I don't care about errors at the moment */
|
|
1024 }
|
|
1025 close(servfd);
|
|
1026 servfd = 0;
|
|
1027
|
|
1028 /* indicate success for now with 0 */
|
|
1029 yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_add_buddy: finished\n");
|
|
1030 return 0;
|
|
1031 }
|
|
1032
|
|
1033 /* Remove a buddy from your buddy list */
|
|
1034 int yahoo_remove_buddy(struct yahoo_context *ctx, char *addid,
|
|
1035 char *active_id, char *group, char *msg)
|
|
1036 {
|
|
1037 char buffer[5000];
|
|
1038 int servfd;
|
|
1039
|
|
1040 if (!ctx)
|
|
1041 {
|
|
1042 return 0;
|
|
1043 }
|
|
1044
|
|
1045 if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY)
|
|
1046 {
|
|
1047 yahoo_dbg_Print("libyahoo",
|
|
1048 "[libyahoo] yahoo_add_buddy - connecting via proxy\n");
|
|
1049 servfd = yahoo_socket_connect(ctx, ctx->proxy_host, ctx->proxy_port);
|
|
1050 }
|
|
1051 else
|
|
1052 {
|
|
1053 yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_add_buddy - connecting\n");
|
|
1054 servfd = yahoo_socket_connect(ctx, YAHOO_DATA_HOST, YAHOO_DATA_PORT);
|
|
1055 }
|
|
1056 if (!servfd)
|
|
1057 {
|
|
1058 yahoo_dbg_Print("libyahoo",
|
|
1059 "[libyahoo] yahoo_add_buddy: failed to connect\n");
|
|
1060 return (0);
|
|
1061 }
|
|
1062
|
|
1063 strcpy(buffer, "GET ");
|
|
1064 if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY)
|
|
1065 {
|
|
1066 strcat(buffer, "http://" YAHOO_DATA_HOST);
|
|
1067 }
|
|
1068 strcat(buffer, "/config/set_buddygrp?.bg=");
|
|
1069 strcat(buffer, yahoo_urlencode(group));
|
|
1070 strcat(buffer, "&.src=bl&.cmd=d&.bdl=");
|
|
1071 strcat(buffer, yahoo_urlencode(addid));
|
|
1072 strcat(buffer, "&.id=");
|
|
1073 strcat(buffer, yahoo_urlencode(active_id));
|
|
1074 strcat(buffer, "&.l=");
|
|
1075 strcat(buffer, yahoo_urlencode(ctx->user));
|
|
1076 strcat(buffer, "&.amsg=");
|
|
1077 strcat(buffer, yahoo_urlencode(msg));
|
|
1078 strcat(buffer, " HTTP/1.0\r\n");
|
|
1079
|
|
1080 strcat(buffer, "User-Agent: " YAHOO_USER_AGENT "\r\n");
|
|
1081 strcat(buffer, "Host: " YAHOO_DATA_HOST "\r\n");
|
|
1082 strcat(buffer, "Cookie: ");
|
|
1083 strcat(buffer, ctx->cookie);
|
|
1084 strcat(buffer, "\r\n");
|
|
1085 strcat(buffer, "\r\n");
|
|
1086
|
|
1087 write(servfd, buffer, strlen(buffer));
|
|
1088 while (yahoo_tcp_readline(buffer, 5000, servfd) > 0)
|
|
1089 {
|
|
1090 /* just dump the output, I don't care about errors at the moment */
|
|
1091 }
|
|
1092 close(servfd);
|
|
1093 servfd = 0;
|
|
1094
|
|
1095 /* indicate success for now with 0 */
|
|
1096 return 0;
|
|
1097 }
|
|
1098
|
|
1099 /* Retrieve the configuration from the server */
|
|
1100 int yahoo_get_config(struct yahoo_context *ctx)
|
|
1101 {
|
|
1102 char buffer[5000];
|
|
1103 int i, j;
|
|
1104 int servfd;
|
|
1105 int commas;
|
|
1106 int in_section;
|
|
1107 struct yahoo_buddy **buddylist = NULL;
|
|
1108 int buddycnt = 0;
|
|
1109 int nextbuddy = 0;
|
|
1110
|
|
1111 /* Check for cached cookie */
|
|
1112 if (!ctx || !ctx->cookie)
|
|
1113 {
|
|
1114 return 0;
|
|
1115 }
|
|
1116
|
|
1117 yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_get_config: starting\n");
|
|
1118
|
|
1119 if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY)
|
|
1120 {
|
|
1121 servfd = yahoo_socket_connect(ctx, ctx->proxy_host, ctx->proxy_port);
|
|
1122 }
|
|
1123 else
|
|
1124 {
|
|
1125 servfd = yahoo_socket_connect(ctx, YAHOO_DATA_HOST, YAHOO_DATA_PORT);
|
|
1126 }
|
|
1127 if (!servfd)
|
|
1128 {
|
|
1129 yahoo_dbg_Print("libyahoo",
|
|
1130 "[libyahoo] yahoo_get_config: failed to connect\n");
|
|
1131 return (0);
|
|
1132 }
|
|
1133
|
|
1134 strcpy(buffer, "GET ");
|
|
1135 if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY)
|
|
1136 {
|
|
1137 strcat(buffer, "http://" YAHOO_DATA_HOST);
|
|
1138 }
|
|
1139 strcat(buffer, "/config/get_buddylist?.src=bl HTTP/1.0\r\n");
|
|
1140 strcat(buffer, "Cookie: ");
|
|
1141 strcat(buffer, ctx->cookie);
|
|
1142 strcat(buffer, "\r\n");
|
|
1143 strcat(buffer, "\r\n");
|
|
1144
|
|
1145 write(servfd, buffer, strlen(buffer));
|
|
1146 yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_get_config: sending '%s'\n",
|
|
1147 buffer);
|
|
1148
|
|
1149 in_section = 0;
|
|
1150 while (yahoo_tcp_readline(buffer, 5000, servfd) > 0)
|
|
1151 {
|
|
1152 /* strip out any non-alphas */
|
|
1153 for (i = 0; i < strlen(buffer); i++)
|
|
1154 {
|
|
1155 if (!isprint((int) buffer[i]))
|
|
1156 {
|
|
1157 for (j = i; j < strlen(buffer); j++)
|
|
1158 {
|
|
1159 buffer[j] = buffer[j + 1];
|
|
1160 }
|
|
1161 }
|
|
1162 }
|
|
1163
|
|
1164 yahoo_dbg_Print("libyahoo",
|
|
1165 "[libyahoo] yahoo_get_config: read '%s'\n", buffer);
|
|
1166
|
|
1167 if (!strcasecmp(buffer, "BEGIN IDENTITIES"))
|
|
1168 {
|
|
1169 in_section = 1;
|
|
1170 }
|
|
1171 else if (!strcasecmp(buffer, "END IDENTITIES"))
|
|
1172 {
|
|
1173 in_section = 0;
|
|
1174 }
|
|
1175 else if (!strcasecmp(buffer, "BEGIN BUDDYLIST"))
|
|
1176 {
|
|
1177 in_section = 2;
|
|
1178 }
|
|
1179 else if (!strcasecmp(buffer, "END BUDDYLIST"))
|
|
1180 {
|
|
1181 in_section = 0;
|
|
1182 }
|
|
1183 else if (in_section == 1)
|
|
1184 {
|
|
1185 char *tmp;
|
|
1186
|
|
1187 /* count the commas */
|
|
1188 commas = 0;
|
|
1189 for (i = 0; i < strlen(buffer); i++)
|
|
1190 {
|
|
1191 if (buffer[i] == ',')
|
|
1192 {
|
|
1193 commas++;
|
|
1194 }
|
|
1195 }
|
|
1196
|
|
1197 /* make sure we've gotten rid of any previous identities array */
|
|
1198 yahoo_free_identities(ctx);
|
|
1199
|
|
1200 /* allocate the array to hold the list of identities */
|
|
1201 ctx->identities = (char **) calloc(commas + 2, sizeof(char *));
|
|
1202
|
|
1203 /* Parse through the list and get all the entries */
|
|
1204 i = 0;
|
|
1205 tmp = strtok(buffer, ",");
|
|
1206 while (tmp)
|
|
1207 {
|
|
1208 yahoo_dbg_Print("libyahoo",
|
|
1209 "[libyahoo] yahoo_get_config: retrieved "
|
|
1210 "identity '%s'\n", tmp);
|
|
1211 ctx->identities[i++] = strdup(tmp);
|
|
1212 tmp = strtok(NULL, ",");
|
|
1213 }
|
|
1214 ctx->identities[i] = 0;
|
|
1215 }
|
|
1216 else if (in_section == 2)
|
|
1217 {
|
|
1218 char *group;
|
|
1219 char *tmp;
|
|
1220 struct yahoo_buddy **tmp_buddylist;
|
|
1221 struct yahoo_buddy *tmpbuddy;
|
|
1222 int tmp_buddycnt;
|
|
1223
|
|
1224 /* count the buddies on this line */
|
|
1225 tmp_buddycnt = buddycnt;
|
|
1226 for (i = 0; i < strlen(buffer); i++)
|
|
1227 {
|
|
1228 if (buffer[i] == ',')
|
|
1229 {
|
|
1230 buddycnt++;
|
|
1231 }
|
|
1232 }
|
|
1233 buddycnt++; /* always one more than comma count */
|
|
1234
|
|
1235 /* allocate the array to hold the list of buddy */
|
|
1236 tmp_buddylist = (struct yahoo_buddy **)
|
|
1237 malloc(sizeof(struct yahoo_buddy *) * (buddycnt + 1));
|
|
1238
|
|
1239 /* Free and copy the old one if necessary */
|
|
1240 if (buddylist)
|
|
1241 {
|
|
1242 memcpy(tmp_buddylist, buddylist,
|
|
1243
|
|
1244 (tmp_buddycnt + 1) * sizeof(struct yahoo_buddy *));
|
|
1245
|
|
1246 FREE(buddylist);
|
|
1247 }
|
|
1248 buddylist = tmp_buddylist;
|
|
1249
|
|
1250 /* Parse through the list and get all the entries */
|
|
1251 tmp = strtok(buffer, ",:");
|
|
1252 group = NULL;
|
|
1253 while (tmp)
|
|
1254 {
|
|
1255 if (tmp == buffer) /* group name */
|
|
1256 {
|
|
1257 group = tmp;
|
|
1258 }
|
|
1259 else
|
|
1260 {
|
|
1261 tmpbuddy = (struct yahoo_buddy *)
|
|
1262
|
|
1263 malloc(sizeof(struct yahoo_buddy));
|
|
1264
|
|
1265 tmpbuddy->id = strdup(tmp);
|
|
1266 tmpbuddy->group = strdup(group);
|
|
1267 yahoo_dbg_Print("libyahoo",
|
|
1268 "[libyahoo] yahoo_get_config: retrieved buddy '%s:%s'\n",
|
|
1269 group, tmp);
|
|
1270 buddylist[nextbuddy++] = tmpbuddy;
|
|
1271 }
|
|
1272 tmp = strtok(NULL, ",");
|
|
1273 }
|
|
1274 buddylist[nextbuddy] = 0;
|
|
1275 }
|
|
1276 else if (!strncasecmp(buffer, "Mail=", strlen("Mail=")))
|
|
1277 {
|
|
1278 ctx->mail = atoi(buffer + strlen("Mail="));
|
|
1279 yahoo_dbg_Print("libyahoo",
|
|
1280 "[libyahoo] yahoo_get_config: retrieved mail flag '%d'\n",
|
|
1281 ctx->mail);
|
|
1282 }
|
|
1283 else if (!strncasecmp(buffer, "Login=", strlen("Login=")))
|
|
1284 {
|
|
1285 FREE(ctx->login_id);
|
|
1286 ctx->login_id = strdup(buffer + strlen("Login="));
|
|
1287 yahoo_dbg_Print("libyahoo",
|
|
1288 "[libyahoo] yahoo_get_config: retrieved login id '%s'\n",
|
|
1289 ctx->login_id);
|
|
1290 }
|
|
1291 }
|
|
1292 close(servfd);
|
|
1293 servfd = 0;
|
|
1294
|
|
1295 yahoo_free_buddies(ctx);
|
|
1296 ctx->buddies = buddylist;
|
|
1297
|
|
1298 /* fill in a bogus login_in, just in case */
|
|
1299 if (!ctx->login_id)
|
|
1300 {
|
|
1301 ctx->login_id = strdup(ctx->user);
|
|
1302 }
|
|
1303
|
|
1304 /* refetch the cookie if the login_id is different so that
|
|
1305 it will have the correct info in it */
|
|
1306 if (strcmp(ctx->login_id, ctx->user))
|
|
1307 {
|
|
1308 yahoo_dbg_Print("libyahoo",
|
|
1309 "[libyahoo] yahoo_get_config - refetching cookies\n");
|
|
1310 yahoo_fetchcookies(ctx);
|
|
1311 }
|
|
1312
|
|
1313 yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_get_config - finished\n");
|
|
1314
|
|
1315 return 1;
|
|
1316 }
|
|
1317
|
|
1318 /* Log in, optionally activating other secondary identities */
|
|
1319 int yahoo_cmd_logon(struct yahoo_context *ctx, unsigned int initial_status)
|
|
1320 {
|
|
1321 char login_string[5000]; /* need to change to malloc ASAP */
|
|
1322 char *tmpid;
|
|
1323 char **identities = ctx->identities;
|
|
1324 int i;
|
|
1325
|
|
1326 if (!ctx || !ctx->login_cookie)
|
|
1327 {
|
|
1328 yahoo_dbg_Print("libyahoo",
|
|
1329 "[libyahoo] yahoo_cmd_logon: logon called without "
|
|
1330 "context and/or cookie.\n");
|
|
1331 exit(1);
|
|
1332 }
|
|
1333
|
|
1334 strcpy(login_string, ctx->login_cookie);
|
|
1335 /* testing with new logon code */
|
|
1336 // strcpy(login_string, "$1$_2S43d5f$XXXXXXXXWtRKNclLWyy8C.");
|
|
1337
|
|
1338 login_string[strlen(login_string) + 1] = 0;
|
|
1339 login_string[strlen(login_string)] = 1; /* control-A */
|
|
1340
|
|
1341 strcat(login_string, ctx->user);
|
|
1342
|
|
1343 /* Send all identities */
|
|
1344 if (identities)
|
|
1345 {
|
|
1346 i = 0;
|
|
1347 tmpid = identities[i];
|
|
1348 while (tmpid)
|
|
1349 {
|
|
1350 if (strcasecmp(tmpid, ctx->user))
|
|
1351 {
|
|
1352 strcat(login_string, ",");
|
|
1353 strcat(login_string, tmpid);
|
|
1354 }
|
|
1355 tmpid = identities[i++];
|
|
1356 }
|
|
1357 }
|
|
1358
|
|
1359 yahoo_sendcmd(ctx, YAHOO_SERVICE_LOGON, ctx->user, login_string,
|
|
1360 initial_status);
|
|
1361
|
|
1362 /* something that the windows one sends, not sure what it is */
|
|
1363 #if 0
|
|
1364 login_string[0] = 0;
|
|
1365 strcat(login_string, "C=0\002");
|
|
1366 strcat(login_string, "F=0,P=0,H=0,S=0,W=0,O=0\002");
|
|
1367 strcat(login_string, "M=0,P=0,C=0,S=0");
|
|
1368 yahoo_sendcmd(ctx, YAHOO_SERVICE_PASSTHROUGH2, ctx->user, login_string,
|
|
1369 0);
|
|
1370 #endif
|
|
1371
|
|
1372 return 0;
|
|
1373 }
|
|
1374
|
|
1375 int yahoo_connect(struct yahoo_context *ctx)
|
|
1376 {
|
|
1377 int res;
|
|
1378
|
|
1379 res = 0;
|
|
1380 ctx->sockfd = 0;
|
|
1381
|
|
1382 yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_connect - starting\n");
|
|
1383
|
|
1384 switch (ctx->connect_mode)
|
|
1385 {
|
|
1386 case YAHOO_CONNECT_SOCKS4:
|
|
1387 case YAHOO_CONNECT_SOCKS5:
|
|
1388 case YAHOO_CONNECT_NORMAL:
|
|
1389 yahoo_dbg_Print("libyahoo",
|
|
1390 "[libyahoo] yahoo_connect - establishing socket connection\n");
|
|
1391 ctx->sockfd =
|
|
1392 yahoo_socket_connect(ctx, YAHOO_PAGER_HOST, YAHOO_PAGER_PORT);
|
|
1393 if (!ctx->sockfd)
|
|
1394 {
|
|
1395 printf("[libyahoo] couldn't connect to pager host\n");
|
|
1396 return (0);
|
|
1397 }
|
|
1398 break;
|
|
1399
|
|
1400 case YAHOO_CONNECT_HTTP:
|
|
1401 case YAHOO_CONNECT_HTTPPROXY:
|
|
1402 yahoo_dbg_Print("libyahoo",
|
|
1403 "[libyahoo] yahoo_connect - no connect for HTTP\n");
|
|
1404 /* no pager connection will be established for this */
|
|
1405 break;
|
|
1406
|
|
1407 default:
|
|
1408 printf("[libyahoo] unhandled connect mode (%d)\n",
|
|
1409 ctx->connect_mode);
|
|
1410 }
|
|
1411
|
|
1412 yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_connect - finished\n");
|
|
1413 return (1);
|
|
1414 }
|
|
1415
|
|
1416 /* Send a packet to the server via http connection method */
|
|
1417 /* at moment only handles regular http connection, once I have that
|
|
1418 working, this code needs to also do http proxy connections as well */
|
|
1419 int yahoo_sendcmd_http(struct yahoo_context *ctx, struct yahoo_rawpacket *pkt)
|
|
1420 {
|
|
1421 int sockfd;
|
|
1422 char buffer[5000];
|
|
1423 char tmpbuf[1000];
|
|
1424 int size;
|
|
1425 int res;
|
|
1426
|
|
1427 if (!ctx || !pkt)
|
|
1428 {
|
|
1429 return (0);
|
|
1430 }
|
|
1431
|
|
1432 size = YAHOO_PACKET_HEADER_SIZE + strlen(pkt->content) + 1;
|
|
1433
|
|
1434 if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY)
|
|
1435 {
|
|
1436 sockfd = yahoo_socket_connect(ctx, ctx->proxy_host, ctx->proxy_port);
|
|
1437 }
|
|
1438 else
|
|
1439 {
|
|
1440 sockfd = yahoo_socket_connect(ctx, YAHOO_PAGER_HTTP_HOST,
|
|
1441 YAHOO_PAGER_HTTP_PORT);
|
|
1442 }
|
|
1443 if (!sockfd)
|
|
1444 {
|
|
1445 printf("[libyahoo] failed to connect to pager http server.\n");
|
|
1446 return (0);
|
|
1447 }
|
|
1448
|
|
1449 strcpy(buffer, "POST ");
|
|
1450 if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY)
|
|
1451 {
|
|
1452 strcat(buffer, "http://" YAHOO_PAGER_HTTP_HOST);
|
|
1453 }
|
|
1454 strcat(buffer, "/notify HTTP/1.0\r\n");
|
|
1455
|
|
1456 strcat(buffer, "User-Agent: " YAHOO_USER_AGENT "\r\n");
|
|
1457 strcat(buffer, "Host: " YAHOO_PAGER_HTTP_HOST "\r\n");
|
|
1458 snprintf(tmpbuf, 1000, "Content-Length: %d\r\n", size);
|
|
1459 strcat(buffer, tmpbuf);
|
|
1460
|
|
1461 strcat(buffer, "Pragma: No-Cache\r\n");
|
|
1462
|
|
1463 strcat(buffer, "Cookie: ");
|
|
1464 strcat(buffer, ctx->cookie);
|
|
1465 strcat(buffer, "\r\n");
|
|
1466 strcat(buffer, "\r\n");
|
|
1467
|
|
1468 write(sockfd, buffer, strlen(buffer));
|
|
1469 write(sockfd, pkt, size);
|
|
1470 write(sockfd, "\r\n", 2);
|
|
1471
|
|
1472 /* now we need to read the results */
|
|
1473 /* I'm taking the cheat approach and just dumping them onto the
|
|
1474 buffer, headers and all, the _skip_to_YHOO_ code will handle it
|
|
1475 for now */
|
|
1476
|
|
1477 while ((res = read(sockfd, buffer, 5000)) > 0)
|
|
1478 {
|
|
1479 if (res == -1)
|
|
1480 {
|
|
1481 printf("[libyahoo] Error reading data from server.\n");
|
|
1482 exit(1);
|
|
1483 }
|
|
1484 yahoo_addtobuffer(ctx, buffer, res);
|
|
1485 }
|
|
1486 close(sockfd);
|
|
1487 sockfd = 0;
|
|
1488
|
|
1489 return (0);
|
|
1490 }
|
|
1491
|
|
1492 /* Send a packet to the server, called by all routines that want to issue
|
|
1493 a command. */
|
|
1494 int yahoo_sendcmd(struct yahoo_context *ctx, int service, char *active_nick,
|
|
1495 char *content, unsigned int msgtype)
|
|
1496 {
|
|
1497 int size;
|
|
1498 struct yahoo_rawpacket *pkt;
|
|
1499 int maxcontentsize;
|
|
1500
|
|
1501 /* why the )&*@#$( did they hardwire the packet size that gets sent
|
|
1502 when the size of the packet is included in what is sent, bizarre */
|
|
1503 size = 4 * 256 + YAHOO_PACKET_HEADER_SIZE;
|
|
1504 pkt = (struct yahoo_rawpacket *) calloc(1, size);
|
|
1505
|
|
1506 /* figure out max content length, including trailing null */
|
|
1507 maxcontentsize = size - sizeof(struct yahoo_rawpacket);
|
|
1508
|
|
1509 /* Build the packet */
|
|
1510 strcpy(pkt->version, YAHOO_PROTOCOL_HEADER);
|
|
1511 yahoo_storeint(pkt->len, size);
|
|
1512 yahoo_storeint(pkt->service, service);
|
|
1513
|
|
1514 /* not sure if this is valid with YPNS1.4 or if it needs 2.0 */
|
|
1515 yahoo_storeint(pkt->msgtype, msgtype);
|
|
1516
|
|
1517 /* Not sure, but might as well send for regular connections as well. */
|
|
1518 yahoo_storeint(pkt->magic_id, ctx->magic_id);
|
|
1519 strcpy(pkt->nick1, ctx->login_id);
|
|
1520 strcpy(pkt->nick2, active_nick);
|
|
1521 strncpy(pkt->content, content, maxcontentsize);
|
|
1522
|
|
1523 // yahoo_hexdump("send_cmd", (char *) pkt, size);
|
|
1524
|
|
1525 switch (ctx->connect_mode)
|
|
1526 {
|
|
1527 case YAHOO_CONNECT_SOCKS4:
|
|
1528 case YAHOO_CONNECT_SOCKS5:
|
|
1529 case YAHOO_CONNECT_NORMAL:
|
|
1530 write(ctx->sockfd, pkt, size);
|
|
1531 break;
|
|
1532 case YAHOO_CONNECT_HTTP:
|
|
1533 case YAHOO_CONNECT_HTTPPROXY:
|
|
1534 yahoo_sendcmd_http(ctx, pkt);
|
|
1535 break;
|
|
1536 }
|
|
1537
|
|
1538 FREE(pkt);
|
|
1539 return (0);
|
|
1540 }
|
|
1541
|
|
1542 int yahoo_cmd_ping(struct yahoo_context *ctx)
|
|
1543 {
|
|
1544 yahoo_sendcmd(ctx, YAHOO_SERVICE_PING, ctx->user, "", 0);
|
|
1545 return (0);
|
|
1546 }
|
|
1547
|
|
1548 int yahoo_cmd_idle(struct yahoo_context *ctx)
|
|
1549 {
|
|
1550 yahoo_sendcmd(ctx, YAHOO_SERVICE_IDLE, ctx->user, "", 0);
|
|
1551 return (0);
|
|
1552 }
|
|
1553
|
|
1554 int yahoo_cmd_sendfile(struct yahoo_context *ctx, char *active_user,
|
|
1555 char *touser, char *msg, char *filename)
|
|
1556 {
|
|
1557 yahoo_dbg_Print("libyahoo", "yahoo_cmd_sendfile not implemented yet!");
|
|
1558 return (0);
|
|
1559 }
|
|
1560
|
|
1561 int yahoo_cmd_msg(struct yahoo_context *ctx, char *active_user,
|
|
1562 char *touser, char *msg)
|
|
1563 {
|
|
1564 char *content;
|
|
1565
|
|
1566 content = (char *) malloc(strlen(touser) + strlen(msg) + 5);
|
|
1567
|
|
1568 if (strlen(touser))
|
|
1569 {
|
|
1570 sprintf(content, "%s,%s", touser, msg);
|
|
1571 yahoo_sendcmd(ctx, YAHOO_SERVICE_MESSAGE, active_user, content, 0);
|
|
1572 }
|
|
1573
|
|
1574 FREE(content);
|
|
1575 return (0);
|
|
1576 }
|
|
1577
|
|
1578 int yahoo_cmd_msg_offline(struct yahoo_context *ctx, char *active_user,
|
|
1579 char *touser, char *msg)
|
|
1580 {
|
|
1581 char *content;
|
|
1582
|
|
1583 content = (char *) malloc(strlen(touser) + strlen(msg) + 5);
|
|
1584
|
|
1585 if (strlen(touser))
|
|
1586 {
|
|
1587 sprintf(content, "%s,%s", touser, msg);
|
|
1588 yahoo_sendcmd(ctx, YAHOO_SERVICE_MESSAGE, active_user, content,
|
|
1589 YAHOO_MSGTYPE_KNOWN_USER);
|
|
1590 }
|
|
1591
|
|
1592 FREE(content);
|
|
1593 return (0);
|
|
1594 }
|
|
1595
|
|
1596 /* appended the " " so that won't trigger yahoo bug - hack for the moment */
|
|
1597 int yahoo_cmd_set_away_mode(struct yahoo_context *ctx, int status, char *msg)
|
|
1598 {
|
|
1599 char statusstring[500];
|
|
1600
|
|
1601 yahoo_dbg_Print("libyahoo",
|
|
1602 "[libyahoo] yahoo_cmd_set_away_mode: set status (%d), msg(%s)\n",
|
|
1603 status, yahoo_dbg_NullCheck(msg));
|
|
1604
|
|
1605 if (status == YAHOO_STATUS_CUSTOM)
|
|
1606 {
|
|
1607 if (msg && msg[0] != 0)
|
|
1608 {
|
|
1609 snprintf(statusstring, 500, "%d%c%s", status, 1, msg);
|
|
1610 }
|
|
1611 else
|
|
1612 {
|
|
1613 snprintf(statusstring, 500, "%d%c---", status, 1);
|
|
1614 }
|
|
1615 }
|
|
1616 else
|
|
1617 {
|
|
1618 snprintf(statusstring, 500, "%d", status);
|
|
1619 }
|
|
1620 yahoo_sendcmd(ctx, YAHOO_SERVICE_ISAWAY, ctx->user, statusstring, 0);
|
|
1621
|
|
1622 return 0;
|
|
1623 }
|
|
1624
|
|
1625 int yahoo_cmd_set_back_mode(struct yahoo_context *ctx, int status, char *msg)
|
|
1626 {
|
|
1627 char statusstring[500];
|
|
1628
|
|
1629 yahoo_dbg_Print("libyahoo",
|
|
1630 "[libyahoo] yahoo_cmd_set_back_mode: set status (%d), msg(%s)\n",
|
|
1631 status, yahoo_dbg_NullCheck(msg));
|
|
1632
|
|
1633 snprintf(statusstring, 500, "%d%c%s ", status, 1, msg ? msg : "");
|
|
1634 yahoo_sendcmd(ctx, YAHOO_SERVICE_ISBACK, ctx->user, statusstring, 0);
|
|
1635
|
|
1636 return 0;
|
|
1637 }
|
|
1638
|
|
1639 int yahoo_cmd_activate_id(struct yahoo_context *ctx, char *newid)
|
|
1640 {
|
|
1641 if (strlen(newid))
|
|
1642 {
|
|
1643 yahoo_sendcmd(ctx, YAHOO_SERVICE_IDACT, newid, newid, 0);
|
|
1644 }
|
|
1645 return (0);
|
|
1646 }
|
|
1647
|
|
1648 int yahoo_cmd_user_status(struct yahoo_context *ctx)
|
|
1649 {
|
|
1650 yahoo_sendcmd(ctx, YAHOO_SERVICE_USERSTAT, ctx->user, "", 0);
|
|
1651 return (0);
|
|
1652 }
|
|
1653
|
|
1654 int yahoo_cmd_logoff(struct yahoo_context *ctx)
|
|
1655 {
|
|
1656 yahoo_sendcmd(ctx, YAHOO_SERVICE_LOGOFF, ctx->user, ctx->user, 0);
|
|
1657 return (0);
|
|
1658 }
|
|
1659
|
|
1660 /*
|
|
1661
|
|
1662 yahoo_cmd_start_conf()
|
|
1663
|
|
1664 Starts a conference. (You create the conference)
|
|
1665
|
|
1666 Arguments:
|
|
1667 char *conf_id == The conference id -- usually of the form name-number,
|
|
1668 though it doesn't seem to matter much. ex: jaylubo-123
|
|
1669 You create this id to start the conference, but pass it
|
|
1670 along after that.
|
|
1671 char **userlist == Users to invite. Null terminated array of strings.
|
|
1672 car *msg == Invitiation message.
|
|
1673 int type == 0 - normal, 1 - voice (not supported yet)
|
|
1674
|
|
1675 Packet format:
|
|
1676 id^invited-users^msg^0or1
|
|
1677 */
|
|
1678 int yahoo_cmd_start_conf(struct yahoo_context *ctx, char *conf_id,
|
|
1679 char **userlist, char *msg, int type)
|
|
1680 {
|
|
1681 char ctrlb = 2;
|
|
1682 char *content;
|
|
1683 char *new_userlist = yahoo_array2list(userlist);
|
|
1684 int cont_len = 0;
|
|
1685
|
|
1686 #ifdef ENABLE_LIBYAHOO_DEBUG
|
|
1687 char *unraw_msg = NULL;
|
|
1688 #endif /* def ENABLE_LIBYAHOO_DEBUG */
|
|
1689
|
|
1690 int size = strlen(conf_id) + strlen(msg) + 8 + strlen(new_userlist);
|
|
1691
|
|
1692 content = (char *) malloc(size);
|
|
1693 memset(content, 0, size);
|
|
1694
|
|
1695 cont_len = snprintf(content,
|
|
1696 size - 1,
|
|
1697 "%s%c%s%c%s%c%d",
|
|
1698 conf_id, ctrlb, new_userlist, ctrlb, msg, ctrlb, type);
|
|
1699
|
|
1700 #ifdef ENABLE_LIBYAHOO_DEBUG
|
|
1701 unraw_msg = yahoo_unraw_buffer(content, cont_len);
|
|
1702 yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_cmd_start_conf: %s\n",
|
|
1703 unraw_msg);
|
|
1704 free(unraw_msg);
|
|
1705 #endif /* def ENABLE_LIBYAHOO_DEBUG */
|
|
1706 yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFINVITE, ctx->user, content, 0);
|
|
1707
|
|
1708 FREE(new_userlist);
|
|
1709 FREE(content);
|
|
1710 return (0);
|
|
1711 }
|
|
1712
|
|
1713 /*
|
|
1714 yahoo_cmd_conf_logon()
|
|
1715
|
|
1716 Reply to a conference invitation, logs you into conference.
|
|
1717
|
|
1718 Arguments:
|
|
1719 char *conf_id == The conference id -- usually of the form name-number,
|
|
1720 though it doesn't seem to matter much. ex: jaylubo-123
|
|
1721 This comes from the invitiation.
|
|
1722 char *host == The person that sent you the invitation.
|
|
1723 char **userlist == Everyone else invited. This comes from the invitiation.
|
|
1724 Null terminated array of strings.
|
|
1725
|
|
1726 Packet format:
|
|
1727 id^all-invited-users-and-host
|
|
1728
|
|
1729 */
|
|
1730 int yahoo_cmd_conf_logon(struct yahoo_context *ctx, char *conf_id,
|
|
1731 char *host, char **userlist)
|
|
1732 {
|
|
1733 char ctrlb = 2;
|
|
1734 char *content;
|
|
1735 char *new_userlist = yahoo_array2list(userlist);
|
|
1736 int cont_len = 0;
|
|
1737
|
|
1738 #ifdef ENABLE_LIBYAHOO_DEBUG
|
|
1739 char *unraw_msg = NULL;
|
|
1740 #endif /* def ENABLE_LIBYAHOO_DEBUG */
|
|
1741
|
|
1742 int size = strlen(conf_id) + strlen(host) + 8 + strlen(new_userlist);
|
|
1743
|
|
1744 content = (char *) malloc(size);
|
|
1745 memset(content, 0, size);
|
|
1746
|
|
1747 cont_len =
|
|
1748 sprintf(content, "%s%c%s,%s", conf_id, ctrlb, host, new_userlist);
|
|
1749
|
|
1750 #ifdef ENABLE_LIBYAHOO_DEBUG
|
|
1751 unraw_msg = yahoo_unraw_buffer(content, cont_len);
|
|
1752 yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_cmd_conf_logon: %s\n",
|
|
1753 unraw_msg);
|
|
1754 free(unraw_msg);
|
|
1755 #endif /* def ENABLE_LIBYAHOO_DEBUG */
|
|
1756 yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFLOGON, ctx->user, content, 0);
|
|
1757
|
|
1758 FREE(new_userlist);
|
|
1759 FREE(content);
|
|
1760 return (0);
|
|
1761 }
|
|
1762
|
|
1763 /*
|
|
1764
|
|
1765 yahoo_cmd_decline_conf()
|
|
1766
|
|
1767 Reply to a conference invitation, decline offer.
|
|
1768
|
|
1769 Arguments:
|
|
1770 char *conf_id == The conference id -- usually of the form name-number,
|
|
1771 though it doesn't seem to matter much. ex: jaylubo-123
|
|
1772 This comes from the invitiation.
|
|
1773 char *host == The person that sent you the invitation.
|
|
1774 char **userlist == Everyone else invited. This comes from the invitiation.
|
|
1775 Null terminated array of strings.
|
|
1776 (Null if replying to a conference additional invite )
|
|
1777 char *msg == Reason for declining.
|
|
1778
|
|
1779 Packet format:
|
|
1780 id^all-invited-users-and-host^msg
|
|
1781
|
|
1782 */
|
|
1783 int yahoo_cmd_decline_conf(struct yahoo_context *ctx, char *conf_id,
|
|
1784 char *host, char **userlist, char *msg)
|
|
1785 {
|
|
1786 char ctrlb = 2;
|
|
1787 char *content;
|
|
1788 char *new_userlist = yahoo_array2list(userlist);
|
|
1789
|
|
1790 int size =
|
|
1791
|
|
1792 strlen(conf_id) + strlen(host) + strlen(msg) + 8 +
|
|
1793 strlen(new_userlist);
|
|
1794
|
|
1795 content = (char *) malloc(size);
|
|
1796 memset(content, 0, size);
|
|
1797
|
|
1798 sprintf(content, "%s%c%s,%s%c%s", conf_id, ctrlb, host, new_userlist,
|
|
1799 ctrlb, msg);
|
|
1800
|
|
1801 yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_cmd_decline_conf: %s\n",
|
|
1802 content);
|
|
1803 yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFDECLINE, ctx->user, content, 0);
|
|
1804
|
|
1805 FREE(new_userlist);
|
|
1806 FREE(content);
|
|
1807 return (0);
|
|
1808 }
|
|
1809
|
|
1810 /*
|
|
1811
|
|
1812 yahoo_cmd_conf_logoff()
|
|
1813
|
|
1814 Logoff of a conference.
|
|
1815
|
|
1816 Arguments:
|
|
1817 char *conf_id == The conference id -- usually of the form name-number,
|
|
1818 though it doesn't seem to matter much. ex: jaylubo-123
|
|
1819 This comes from the invitiation.
|
|
1820 char **userlist == Everyone in conference.
|
|
1821 Null terminated array of strings.
|
|
1822
|
|
1823 Packet format:
|
|
1824 id^all-invited-users
|
|
1825
|
|
1826 */
|
|
1827
|
|
1828 int yahoo_cmd_conf_logoff(struct yahoo_context *ctx, char *conf_id,
|
|
1829 char **userlist)
|
|
1830 {
|
|
1831 char ctrlb = 2;
|
|
1832 char *content;
|
|
1833 int cont_len = 0;
|
|
1834
|
|
1835 #ifdef ENABLE_LIBYAHOO_DEBUG
|
|
1836 char *unraw_msg = NULL;
|
|
1837 #endif /* def ENABLE_LIBYAHOO_DEBUG */
|
|
1838 char *new_userlist = yahoo_array2list(userlist);
|
|
1839
|
|
1840 int size = strlen(conf_id) + strlen(new_userlist) + 8;
|
|
1841
|
|
1842 content = (char *) malloc(size);
|
|
1843 memset(content, 0, size);
|
|
1844
|
|
1845 cont_len =
|
|
1846 snprintf(content, size, "%s%c%s", conf_id, ctrlb, new_userlist);
|
|
1847 #ifdef ENABLE_LIBYAHOO_DEBUG
|
|
1848 unraw_msg = yahoo_unraw_buffer(content, cont_len);
|
|
1849 yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_cmd_conf_logoff: %s\n",
|
|
1850 unraw_msg);
|
|
1851 free(unraw_msg);
|
|
1852 #endif /* def ENABLE_LIBYAHOO_DEBUG */
|
|
1853 yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFLOGOFF, ctx->user, content, 0);
|
|
1854
|
|
1855 FREE(new_userlist);
|
|
1856 FREE(content);
|
|
1857 return (0);
|
|
1858 }
|
|
1859
|
|
1860 /*
|
|
1861
|
|
1862 yahoo_cmd_conf_invite()
|
|
1863
|
|
1864 Invite another user to an already running conference.
|
|
1865
|
|
1866 Arguments:
|
|
1867 char *conf_id == The conference id -- usually of the form name-number,
|
|
1868 though it doesn't seem to matter much. ex: jaylubo-123
|
|
1869 This comes from the invitiation.
|
|
1870 char *invited_user == The person being invited to conference.
|
|
1871 char **userlist == Everyone else in conference.
|
|
1872 Null terminated array of strings.
|
|
1873 char *msg == Invitation message.
|
|
1874
|
|
1875 Packet format:
|
|
1876 id^invited-user^who-else-in-conf^who-else-in-conf^msg^0
|
|
1877
|
|
1878 */
|
|
1879
|
|
1880 int yahoo_cmd_conf_invite(struct yahoo_context *ctx, char *conf_id,
|
|
1881 char **userlist, char *invited_user, char *msg)
|
|
1882 {
|
|
1883 char ctrlb = 2;
|
|
1884 char *content;
|
|
1885 char *new_userlist = yahoo_array2list(userlist);
|
|
1886
|
|
1887 int size = strlen(conf_id) + strlen(invited_user)
|
|
1888 + (2 * strlen(new_userlist)) + strlen(msg) + 7;
|
|
1889
|
|
1890 content = (char *) malloc(size);
|
|
1891 memset(content, 0, size);
|
|
1892
|
|
1893 sprintf(content, "%s%c%s%c%s%c%s%c%s%c0", conf_id, ctrlb,
|
|
1894 invited_user, ctrlb, new_userlist, ctrlb,
|
|
1895 new_userlist, ctrlb, msg, ctrlb);
|
|
1896 yahoo_dbg_Print("libyahoo", "[libyahoo] yahoo_cmd_conf_invite: %s\n",
|
|
1897 content);
|
|
1898 yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFADDINVITE, ctx->user, content, 0);
|
|
1899
|
|
1900 FREE(new_userlist);
|
|
1901 FREE(content);
|
|
1902 return (0);
|
|
1903 }
|
|
1904
|
|
1905 /*
|
|
1906
|
|
1907 yahoo_cmd_conf_msg()
|
|
1908
|
|
1909 Send a message to everyone in conference.
|
|
1910
|
|
1911 Arguments:
|
|
1912 char *conf_id == The conference id -- usually of the form name-number,
|
|
1913 though it doesn't seem to matter much. ex: jaylubo-123
|
|
1914 This comes from the invitiation.
|
|
1915 char **userlist == Everyone in conference.
|
|
1916 Null terminated array of strings.
|
|
1917 char *msg == Message to send.
|
|
1918
|
|
1919 Packet format:
|
|
1920 id^all-invited-users^msg
|
|
1921
|
|
1922 */
|
|
1923 int yahoo_cmd_conf_msg(struct yahoo_context *ctx, char *conf_id,
|
|
1924 char **userlist, char *msg)
|
|
1925 {
|
|
1926 char ctrlb = 2;
|
|
1927 char *content;
|
|
1928 int cont_len = 0;
|
|
1929
|
|
1930 #ifdef ENABLE_LIBYAHOO_DEBUG
|
|
1931 char *unraw_msg = NULL;
|
|
1932 #endif /* def ENABLE_LIBYAHOO_DEBUG */
|
|
1933 char *new_userlist = yahoo_array2list(userlist);
|
|
1934
|
|
1935 int size = strlen(conf_id) + strlen(new_userlist) + strlen(msg) + 8;
|
|
1936
|
|
1937 content = (char *) malloc(size);
|
|
1938 memset(content, 0, size);
|
|
1939
|
|
1940 cont_len =
|
|
1941 snprintf(content, size, "%s%c%s%c%s", conf_id, ctrlb, new_userlist,
|
|
1942 ctrlb, msg);
|
|
1943 #ifdef ENABLE_LIBYAHOO_DEBUG
|
|
1944 unraw_msg = yahoo_unraw_buffer(content, cont_len);
|
|
1945 yahoo_dbg_Print("libyahoo", "yahoo_cmd_conf_msg: %s\n", unraw_msg);
|
|
1946 free(unraw_msg);
|
|
1947 #endif /* def ENABLE_LIBYAHOO_DEBUG */
|
|
1948 yahoo_sendcmd(ctx, YAHOO_SERVICE_CONFMSG, ctx->user, content, 0);
|
|
1949
|
|
1950 FREE(new_userlist);
|
|
1951 FREE(content);
|
|
1952 return (0);
|
|
1953 }
|
|
1954
|
|
1955 /*
|
|
1956 * Free the rawpacket structure - primarily a placeholder
|
|
1957 * since all static elements at the moment
|
|
1958 */
|
|
1959 void yahoo_free_rawpacket(struct yahoo_rawpacket *pkt)
|
|
1960 {
|
|
1961 FREE(pkt);
|
|
1962 }
|
|
1963
|
|
1964 /*
|
|
1965 * Free entire packet structure including string elements
|
|
1966 */
|
|
1967 void yahoo_free_packet(struct yahoo_packet *pkt)
|
|
1968 {
|
|
1969 int i;
|
|
1970
|
|
1971 if (pkt)
|
|
1972 {
|
|
1973 FREE(pkt->real_id);
|
|
1974 FREE(pkt->active_id);
|
|
1975 FREE(pkt->conf_id);
|
|
1976 FREE(pkt->conf_host);
|
|
1977 FREE(pkt->conf_user);
|
|
1978 FREE(pkt->conf_msg);
|
|
1979 FREE(pkt->cal_url);
|
|
1980 FREE(pkt->cal_timestamp);
|
|
1981 FREE(pkt->cal_title);
|
|
1982 FREE(pkt->cal_description);
|
|
1983 FREE(pkt->chat_invite_content);
|
|
1984 FREE(pkt->msg_id);
|
|
1985 FREE(pkt->msg_timestamp);
|
|
1986 FREE(pkt->msg);
|
|
1987 FREE(pkt->file_from);
|
|
1988 FREE(pkt->file_flag);
|
|
1989 FREE(pkt->file_url);
|
|
1990 FREE(pkt->file_description);
|
|
1991 FREE(pkt->group_old);
|
|
1992 FREE(pkt->group_new);
|
|
1993 if (pkt->idstatus)
|
|
1994 {
|
|
1995 for (i = 0; i < pkt->idstatus_count; i++)
|
|
1996 {
|
|
1997 yahoo_free_idstatus(pkt->idstatus[i]);
|
|
1998 }
|
|
1999 free(pkt->idstatus);
|
|
2000 }
|
|
2001 free(pkt);
|
|
2002 }
|
|
2003 }
|
|
2004
|
|
2005 void yahoo_free_idstatus(struct yahoo_idstatus *idstatus)
|
|
2006 {
|
|
2007 if (!idstatus)
|
|
2008 {
|
|
2009 return;
|
|
2010 }
|
|
2011
|
|
2012 FREE(idstatus->id);
|
|
2013 FREE(idstatus->connection_id);
|
|
2014 FREE(idstatus->status_msg);
|
|
2015 FREE(idstatus);
|
|
2016 }
|
|
2017
|
|
2018 struct yahoo_packet *yahoo_parsepacket(struct yahoo_context *ctx,
|
|
2019 struct yahoo_rawpacket *inpkt)
|
|
2020 {
|
|
2021 struct yahoo_packet *pkt;
|
|
2022
|
|
2023 /* If no valid inpkt passed, return */
|
|
2024 if (!inpkt)
|
|
2025 {
|
|
2026 return NULL;
|
|
2027 }
|
|
2028
|
|
2029 /* Allocate the packet structure, zeroed out */
|
|
2030 pkt = (struct yahoo_packet *) calloc(sizeof(*pkt), 1);
|
|
2031
|
|
2032 /* Pull out the standard data */
|
|
2033 pkt->service = yahoo_makeint(inpkt->service);
|
|
2034 pkt->connection_id = yahoo_makeint(inpkt->connection_id);
|
|
2035 pkt->real_id = strdup(inpkt->nick1);
|
|
2036 pkt->active_id = strdup(inpkt->nick2);
|
|
2037
|
|
2038 pkt->magic_id = yahoo_makeint(inpkt->magic_id);
|
|
2039 pkt->unknown1 = yahoo_makeint(inpkt->unknown1);
|
|
2040 pkt->msgtype = yahoo_makeint(inpkt->msgtype);
|
|
2041
|
|
2042 /* doing this seems like a cleaner approach, but am not sure if it is
|
|
2043 a valid one */
|
|
2044 if (pkt->magic_id != 0)
|
|
2045 {
|
|
2046 ctx->magic_id = pkt->magic_id;
|
|
2047 }
|
|
2048 if (pkt->connection_id != 0)
|
|
2049 {
|
|
2050 ctx->connection_id = pkt->connection_id;
|
|
2051 }
|
|
2052
|
|
2053 /* Call a particular parse routine to pull out the content */
|
|
2054 switch (pkt->service)
|
|
2055 {
|
|
2056 case YAHOO_SERVICE_LOGON:
|
|
2057 case YAHOO_SERVICE_LOGOFF:
|
|
2058 case YAHOO_SERVICE_ISAWAY:
|
|
2059 case YAHOO_SERVICE_ISBACK:
|
|
2060 case YAHOO_SERVICE_USERSTAT:
|
|
2061 case YAHOO_SERVICE_CHATLOGON:
|
|
2062 case YAHOO_SERVICE_CHATLOGOFF:
|
|
2063 case YAHOO_SERVICE_GAMELOGON:
|
|
2064 case YAHOO_SERVICE_GAMELOGOFF:
|
|
2065 yahoo_parsepacket_status(ctx, pkt, inpkt);
|
|
2066 break;
|
|
2067 case YAHOO_SERVICE_IDACT:
|
|
2068 case YAHOO_SERVICE_IDDEACT:
|
|
2069 /* nothing needs done, only has main fields */
|
|
2070 break;
|
|
2071 case YAHOO_SERVICE_MESSAGE:
|
|
2072 case YAHOO_SERVICE_SYSMESSAGE:
|
|
2073 case YAHOO_SERVICE_CHATMSG:
|
|
2074 yahoo_parsepacket_message(ctx, pkt, inpkt);
|
|
2075 break;
|
|
2076 case YAHOO_SERVICE_NEWMAIL:
|
|
2077 case YAHOO_SERVICE_NEWPERSONALMAIL:
|
|
2078 yahoo_parsepacket_newmail(ctx, pkt, inpkt);
|
|
2079 break;
|
|
2080 case YAHOO_SERVICE_CALENDAR:
|
|
2081 yahoo_parsepacket_calendar(ctx, pkt, inpkt);
|
|
2082 break;
|
|
2083 case YAHOO_SERVICE_CHATINVITE:
|
|
2084 yahoo_parsepacket_chatinvite(ctx, pkt, inpkt);
|
|
2085 break;
|
|
2086 case YAHOO_SERVICE_NEWCONTACT:
|
|
2087 yahoo_parsepacket_newcontact(ctx, pkt, inpkt);
|
|
2088 break;
|
|
2089 case YAHOO_SERVICE_GROUPRENAME:
|
|
2090 yahoo_parsepacket_grouprename(ctx, pkt, inpkt);
|
|
2091 break;
|
|
2092 case YAHOO_SERVICE_CONFINVITE:
|
|
2093 yahoo_parsepacket_conference_invite(ctx, pkt, inpkt);
|
|
2094 break;
|
|
2095 case YAHOO_SERVICE_CONFLOGON:
|
|
2096 case YAHOO_SERVICE_CONFLOGOFF:
|
|
2097 yahoo_parsepacket_conference_user(ctx, pkt, inpkt);
|
|
2098 break;
|
|
2099 case YAHOO_SERVICE_CONFDECLINE:
|
|
2100 yahoo_parsepacket_conference_decline(ctx, pkt, inpkt);
|
|
2101 break;
|
|
2102 case YAHOO_SERVICE_CONFADDINVITE:
|
|
2103 yahoo_parsepacket_conference_addinvite(ctx, pkt, inpkt);
|
|
2104 break;
|
|
2105 case YAHOO_SERVICE_CONFMSG:
|
|
2106 yahoo_parsepacket_conference_msg(ctx, pkt, inpkt);
|
|
2107 break;
|
|
2108 case YAHOO_SERVICE_PING:
|
|
2109 yahoo_parsepacket_ping(ctx, pkt, inpkt);
|
|
2110 break;
|
|
2111 case YAHOO_SERVICE_FILETRANSFER:
|
|
2112 yahoo_parsepacket_filetransfer(ctx, pkt, inpkt);
|
|
2113 break;
|
|
2114 default:
|
|
2115 yahoo_dbg_Print("libyahoo",
|
|
2116 "yahoo_parsepacket: can't parse packet type (%d)\n",
|
|
2117 pkt->service);
|
|
2118 break;
|
|
2119 }
|
|
2120
|
|
2121 return pkt;
|
|
2122 }
|
|
2123
|
|
2124 int yahoo_parsepacket_ping(struct yahoo_context *ctx,
|
|
2125 struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt)
|
|
2126 {
|
|
2127 char *content;
|
|
2128
|
|
2129 /* Make working copy of content */
|
|
2130 content = inpkt->content;
|
|
2131
|
|
2132 pkt->msg = NULL;
|
|
2133 if (content)
|
|
2134 {
|
|
2135 pkt->msg = strdup(content);
|
|
2136 }
|
|
2137
|
|
2138 return 0;
|
|
2139 }
|
|
2140
|
|
2141 int yahoo_parsepacket_newmail(struct yahoo_context *ctx,
|
|
2142 struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt)
|
|
2143 {
|
|
2144 char *content;
|
|
2145 int len;
|
|
2146
|
|
2147 /* Make working copy of content */
|
|
2148 content = inpkt->content;
|
|
2149 len = strlen(content);
|
|
2150
|
|
2151 if (pkt->service == YAHOO_SERVICE_NEWMAIL)
|
|
2152 {
|
|
2153 pkt->mail_status = 0;
|
|
2154 if (len > 0)
|
|
2155 {
|
|
2156 pkt->mail_status = atoi(content);
|
|
2157 }
|
|
2158 }
|
|
2159 else if (pkt->service == YAHOO_SERVICE_NEWPERSONALMAIL)
|
|
2160 {
|
|
2161 pkt->mail_status = 0;
|
|
2162 if (len > 0)
|
|
2163 {
|
|
2164 pkt->mail_status = atoi(content);
|
|
2165 }
|
|
2166 }
|
|
2167
|
|
2168 return 0;
|
|
2169 }
|
|
2170
|
|
2171 int yahoo_parsepacket_grouprename(struct yahoo_context *ctx,
|
|
2172 struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt)
|
|
2173 {
|
|
2174 char *content;
|
|
2175 char *tmp, delim[5];
|
|
2176
|
|
2177 /* Make working copy of content */
|
|
2178 content = strdup(inpkt->content);
|
|
2179
|
|
2180 /* init elements to all null */
|
|
2181 pkt->group_old = NULL;
|
|
2182 pkt->group_new = NULL;
|
|
2183
|
|
2184 tmp = NULL;
|
|
2185 delim[0] = 1; /* control-a */
|
|
2186 delim[1] = 0;
|
|
2187
|
|
2188 if (content)
|
|
2189 {
|
|
2190 tmp = strtok(content, delim);
|
|
2191 }
|
|
2192
|
|
2193 if (tmp) /* got the conference id */
|
|
2194 {
|
|
2195 pkt->group_old = strdup(tmp);
|
|
2196 tmp = strtok(NULL, delim);
|
|
2197 }
|
|
2198
|
|
2199 if (tmp) /* conference host */
|
|
2200 {
|
|
2201 pkt->group_new = strdup(tmp);
|
|
2202 tmp = strtok(NULL, delim);
|
|
2203 }
|
|
2204
|
|
2205 FREE(content);
|
|
2206 return (0);
|
|
2207 }
|
|
2208
|
|
2209 /*
|
|
2210
|
|
2211 yahoo_parsepacket_conference_invite()
|
|
2212
|
|
2213 Packet format:
|
|
2214 id^host^invited-users^msg^0or1
|
|
2215
|
|
2216 Parses Arguments:
|
|
2217 char *conf_id == The conference id -- usually of the form name-number,
|
|
2218 though it doesn't seem to matter much. ex: jaylubo-123
|
|
2219 char *conf_host == The person inviting you to conference.
|
|
2220 char **userlist == Everyone else invited to conference.
|
|
2221 Null terminated array of strings.
|
|
2222 char *msg == Invitation message.
|
|
2223 int conf_type == Type of conference ( 0 = text, 1 = voice )
|
|
2224
|
|
2225 */
|
|
2226 int yahoo_parsepacket_conference_invite(struct yahoo_context *ctx,
|
|
2227 struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt)
|
|
2228 {
|
|
2229 char *content;
|
|
2230 char *tmp = 0;
|
|
2231 size_t found = 0, len = yahoo_makeint(inpkt->len);
|
|
2232
|
|
2233 /* Make working copy of content */
|
|
2234 content = memdup(inpkt->content, len);
|
|
2235
|
|
2236 /* init elements to all null */
|
|
2237 pkt->conf_id = NULL;
|
|
2238 pkt->conf_host = NULL;
|
|
2239 pkt->conf_user = pkt->active_id;
|
|
2240 pkt->conf_userlist = NULL;
|
|
2241 pkt->conf_inviter = NULL;
|
|
2242 pkt->conf_msg = NULL;
|
|
2243
|
|
2244 if (content)
|
|
2245 {
|
|
2246 tmp = memtok(content, len, "\002", 2, &found);
|
|
2247 }
|
|
2248
|
|
2249 if (tmp) /* got the conference id */
|
|
2250 {
|
|
2251 pkt->conf_id = memdupasstr(tmp, found);
|
|
2252 tmp = memtok(0, 0, "\002", 2, &found);
|
|
2253 }
|
|
2254
|
|
2255 if (tmp) /* conference host */
|
|
2256 {
|
|
2257 pkt->conf_host = memdupasstr(tmp, found);
|
|
2258 tmp = memtok(0, 0, "\002", 2, &found);
|
|
2259 }
|
|
2260
|
|
2261 if (tmp) /* who else is invited */
|
|
2262 {
|
|
2263 char *userlist = memdupasstr(tmp, found);
|
|
2264
|
|
2265 pkt->conf_userlist = yahoo_list2array(userlist);
|
|
2266 FREE(userlist);
|
|
2267 tmp = memtok(0, 0, "\002", 2, &found);
|
|
2268 }
|
|
2269
|
|
2270 if (tmp) /* msg */
|
|
2271 {
|
|
2272 pkt->conf_msg = memdupasstr(tmp, found);
|
|
2273 tmp = memtok(0, 0, "\002", 2, &found);
|
|
2274 }
|
|
2275
|
|
2276 if (tmp) /* 0 == text chat 1 == voice chat */
|
|
2277 {
|
|
2278 char *conftype = memdupasstr(tmp, found);
|
|
2279
|
|
2280 if (0 != conftype)
|
|
2281 pkt->conf_type = atoi(conftype);
|
|
2282 FREE(conftype);
|
|
2283 tmp = memtok(0, 0, "\002", 2, &found);
|
|
2284 }
|
|
2285
|
|
2286 FREE(content);
|
|
2287 return 0;
|
|
2288 }
|
|
2289
|
|
2290 /*
|
|
2291
|
|
2292 yahoo_parsepacket_conference_decline()
|
|
2293
|
|
2294 Packet format:
|
|
2295 id^user-who-declined^msg
|
|
2296
|
|
2297 Parses Arguments:
|
|
2298 char *conf_id == The conference id -- usually of the form name-number,
|
|
2299 though it doesn't seem to matter much. ex: jaylubo-123
|
|
2300 char *conf_user == User who declined.
|
|
2301 char *msg == Reason for declining.
|
|
2302
|
|
2303 */
|
|
2304 int yahoo_parsepacket_conference_decline(struct yahoo_context *ctx,
|
|
2305 struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt)
|
|
2306 {
|
|
2307 char *content;
|
|
2308 char *tmp, delim[2];
|
|
2309
|
|
2310 /* Make working copy of content */
|
|
2311 content = strdup(inpkt->content);
|
|
2312
|
|
2313 /* init elements to all null */
|
|
2314 pkt->conf_id = NULL;
|
|
2315 pkt->conf_host = NULL;
|
|
2316 pkt->conf_user = NULL;
|
|
2317 pkt->conf_userlist = NULL;
|
|
2318 pkt->conf_inviter = NULL;
|
|
2319 pkt->conf_msg = NULL;
|
|
2320
|
|
2321 tmp = NULL;
|
|
2322 delim[0] = 2; /* control-b */
|
|
2323 delim[1] = 0;
|
|
2324
|
|
2325 if (content)
|
|
2326 {
|
|
2327 tmp = strtok(content, delim);
|
|
2328 }
|
|
2329
|
|
2330 if (tmp) /* got the conference id */
|
|
2331 {
|
|
2332 pkt->conf_id = strdup(tmp);
|
|
2333 tmp = strtok(NULL, delim);
|
|
2334 }
|
|
2335 if (tmp) /* got the user who declined */
|
|
2336 {
|
|
2337 pkt->conf_user = strdup(tmp);
|
|
2338 tmp = strtok(NULL, delim);
|
|
2339 }
|
|
2340 if (tmp) /* msg */
|
|
2341 {
|
|
2342 pkt->conf_msg = strdup(tmp);
|
|
2343 tmp = strtok(NULL, delim);
|
|
2344 }
|
|
2345
|
|
2346 FREE(content);
|
|
2347 return 0;
|
|
2348
|
|
2349 }
|
|
2350
|
|
2351 /*
|
|
2352
|
|
2353 yahoo_parsepacket_conference_addinvite()
|
|
2354
|
|
2355 Packet format:
|
|
2356 Msgtype == 1
|
|
2357 id^inviter^who-else-invited^who-else-in-conf^msg^0or1
|
|
2358 Msgtype == 11
|
|
2359 id^inviter^invited-user
|
|
2360
|
|
2361 Parses Arguments:
|
|
2362 char *conf_id == The conference id -- usually of the form name-number,
|
|
2363 though it doesn't seem to matter much. ex: jaylubo-123
|
|
2364 char *conf_inviter == The person inviting you to conference.
|
|
2365 char **userlist == Everyone else in conference.
|
|
2366 Null terminated array of strings.
|
|
2367 char *msg == Invitation message.
|
|
2368 int conf_type == Type of conference ( 0 = text, 1 = voice )
|
|
2369
|
|
2370 char *conf_user == User invited to conference (msgtype == 11)
|
|
2371 */
|
|
2372 int yahoo_parsepacket_conference_addinvite(struct yahoo_context *ctx,
|
|
2373 struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt)
|
|
2374 {
|
|
2375 char *content = 0, *tmp = 0;
|
|
2376 size_t found = 0, len = yahoo_makeint(inpkt->len);
|
|
2377
|
|
2378 /* Make working copy of content */
|
|
2379 content = memdup(inpkt->content, len);
|
|
2380
|
|
2381 /* init elements to all null */
|
|
2382 pkt->conf_id = NULL;
|
|
2383 pkt->conf_host = NULL;
|
|
2384 pkt->conf_user = NULL;
|
|
2385 pkt->conf_userlist = NULL;
|
|
2386 pkt->conf_inviter = NULL;
|
|
2387 pkt->conf_msg = NULL;
|
|
2388
|
|
2389 if (pkt->msgtype == 1)
|
|
2390 {
|
|
2391 if (content)
|
|
2392 {
|
|
2393 tmp = memtok(content, len, "\002", 2, &found);
|
|
2394 }
|
|
2395
|
|
2396 if (tmp) /* got the conference id */
|
|
2397 {
|
|
2398 pkt->conf_id = memdupasstr(tmp, found);
|
|
2399 tmp = memtok(0, 0, "\002", 2, &found);
|
|
2400 }
|
|
2401 if (tmp) /* got the inviter */
|
|
2402 {
|
|
2403 pkt->conf_inviter = memdupasstr(tmp, found);
|
|
2404 tmp = memtok(0, 0, "\002", 2, &found);
|
|
2405 }
|
|
2406 if (tmp) /* got who-else-invited */
|
|
2407 {
|
|
2408 /* don't use this field, its the same as the next one
|
|
2409 so I'm going to use the second field */
|
|
2410 /* pkt->conf_userlist = yahoo_list2array(tmp); */
|
|
2411 tmp = memtok(0, 0, "\002", 2, &found);
|
|
2412 }
|
|
2413 if (tmp) /* got the people in conference
|
|
2414 not counting the inviter */
|
|
2415 {
|
|
2416 char *userlist = memdupasstr(tmp, found);
|
|
2417
|
|
2418 pkt->conf_userlist = yahoo_list2array(userlist);
|
|
2419 FREE(userlist);
|
|
2420 tmp = memtok(0, 0, "\002", 2, &found);
|
|
2421 }
|
|
2422 if (tmp) /* got the message */
|
|
2423 {
|
|
2424 pkt->conf_msg = memdupasstr(tmp, found);
|
|
2425 tmp = memtok(0, 0, "\002", 2, &found);
|
|
2426 }
|
|
2427 if (tmp) /* 0 at the end */
|
|
2428 {
|
|
2429 char *conftype = memdupasstr(tmp, found);
|
|
2430
|
|
2431 if (0 != conftype)
|
|
2432 pkt->conf_type = atoi(conftype);
|
|
2433 FREE(conftype);
|
|
2434 /* tmp = memtok (0, 0, "\002", 2, &found); */
|
|
2435 }
|
|
2436 }
|
|
2437 else
|
|
2438 /* msgid == 11 (someone else is being invited) */
|
|
2439 {
|
|
2440 if (content)
|
|
2441 {
|
|
2442 tmp = memtok(content, len, "\002", 2, &found);
|
|
2443 }
|
|
2444
|
|
2445 if (tmp) /* got the conference id */
|
|
2446 {
|
|
2447 pkt->conf_id = memdupasstr(tmp, found);
|
|
2448 tmp = memtok(0, 0, "\002", 2, &found);
|
|
2449 }
|
|
2450
|
|
2451 if (tmp) /* got the inviter */
|
|
2452 {
|
|
2453 pkt->conf_inviter = memdupasstr(tmp, found);
|
|
2454 tmp = memtok(0, 0, "\002", 2, &found);
|
|
2455 }
|
|
2456
|
|
2457 if (tmp) /* got the invited-user */
|
|
2458 {
|
|
2459 pkt->conf_user = memdupasstr(tmp, found);
|
|
2460 /* tmp = memtok (0, 0, "\002", 2, &found); */
|
|
2461 }
|
|
2462 }
|
|
2463
|
|
2464 FREE(content);
|
|
2465 return 0;
|
|
2466 }
|
|
2467
|
|
2468 /*
|
|
2469
|
|
2470 yahoo_parsepacket_conference_msg()
|
|
2471
|
|
2472 Packet format:
|
|
2473 id^who-from^msg
|
|
2474
|
|
2475 Parses Arguments:
|
|
2476 char *conf_id == The conference id -- usually of the form name-number,
|
|
2477 though it doesn't seem to matter much. ex: jaylubo-123
|
|
2478 char *conf_user == User who sent message.
|
|
2479 char *msg == Message.
|
|
2480
|
|
2481 */
|
|
2482 int yahoo_parsepacket_conference_msg(struct yahoo_context *ctx,
|
|
2483 struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt)
|
|
2484 {
|
|
2485 char *content;
|
|
2486 char *tmp, delim[5];
|
|
2487
|
|
2488 /* Make working copy of content */
|
|
2489 content = strdup(inpkt->content);
|
|
2490
|
|
2491 /* init elements to all null */
|
|
2492 pkt->conf_id = NULL;
|
|
2493 pkt->conf_host = NULL;
|
|
2494 pkt->conf_user = NULL;
|
|
2495 pkt->conf_userlist = NULL;
|
|
2496 pkt->conf_inviter = NULL;
|
|
2497 pkt->conf_msg = NULL;
|
|
2498
|
|
2499 tmp = NULL;
|
|
2500 delim[0] = 2; /* control-b */
|
|
2501 delim[1] = 0;
|
|
2502
|
|
2503 /* parse error messages first */
|
|
2504 if (pkt->msgtype == YAHOO_MSGTYPE_ERROR)
|
|
2505 {
|
|
2506 FREE(content);
|
|
2507 return 0;
|
|
2508 }
|
|
2509
|
|
2510 if (content)
|
|
2511 {
|
|
2512 tmp = strtok(content, delim);
|
|
2513 }
|
|
2514
|
|
2515 if (tmp) /* got the conference id */
|
|
2516 {
|
|
2517 pkt->conf_id = strdup(tmp);
|
|
2518 tmp = strtok(NULL, delim);
|
|
2519 }
|
|
2520
|
|
2521 if (tmp) /* conference user */
|
|
2522 {
|
|
2523 pkt->conf_user = strdup(tmp);
|
|
2524 tmp = strtok(NULL, delim);
|
|
2525 }
|
|
2526
|
|
2527 if (tmp) /* msg */
|
|
2528 {
|
|
2529 pkt->conf_msg = strdup(tmp);
|
|
2530 tmp = strtok(NULL, delim);
|
|
2531 }
|
|
2532
|
|
2533 FREE(content);
|
|
2534 return 0;
|
|
2535 }
|
|
2536
|
|
2537 /*
|
|
2538
|
|
2539 yahoo_parsepacket_conference_user()
|
|
2540 (User logged on/off to conference)
|
|
2541 Packet format:
|
|
2542 id^user_who_logged_on/off
|
|
2543
|
|
2544 Parses Arguments:
|
|
2545 char *conf_id == The conference id -- usually of the form name-number,
|
|
2546 though it doesn't seem to matter much. ex: jaylubo-123
|
|
2547 char *conf_user == User who logged on to conference.
|
|
2548
|
|
2549 */
|
|
2550 int yahoo_parsepacket_conference_user(struct yahoo_context *ctx,
|
|
2551 struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt)
|
|
2552 {
|
|
2553 char *content;
|
|
2554 char *tmp, delim[5];
|
|
2555
|
|
2556 /* Make working copy of content */
|
|
2557 content = strdup(inpkt->content);
|
|
2558
|
|
2559 /* init elements to all null */
|
|
2560 pkt->conf_id = NULL;
|
|
2561 pkt->conf_host = NULL;
|
|
2562 pkt->conf_user = NULL;
|
|
2563 pkt->conf_userlist = NULL;
|
|
2564 pkt->conf_inviter = NULL;
|
|
2565 pkt->conf_msg = NULL;
|
|
2566
|
|
2567 tmp = NULL;
|
|
2568 delim[0] = 2; /* control-b */
|
|
2569 delim[1] = 0;
|
|
2570
|
|
2571 if (content)
|
|
2572 {
|
|
2573 tmp = strtok(content, delim);
|
|
2574 }
|
|
2575
|
|
2576 if (tmp) /* got the conference id */
|
|
2577 {
|
|
2578 pkt->conf_id = strdup(tmp);
|
|
2579 tmp = strtok(NULL, delim);
|
|
2580 }
|
|
2581
|
|
2582 if (tmp) /* conference user */
|
|
2583 {
|
|
2584 pkt->conf_user = strdup(tmp);
|
|
2585 tmp = strtok(NULL, delim);
|
|
2586 }
|
|
2587
|
|
2588 FREE(content);
|
|
2589 return 0;
|
|
2590 }
|
|
2591
|
|
2592 int yahoo_parsepacket_filetransfer(struct yahoo_context *ctx,
|
|
2593 struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt)
|
|
2594 {
|
|
2595 char *content;
|
|
2596 char *tmp[5];
|
|
2597 int i, j, section;
|
|
2598
|
|
2599 /* Make working copy of content */
|
|
2600 content = strdup(inpkt->content);
|
|
2601
|
|
2602 /* init elements to all null */
|
|
2603 pkt->file_from = NULL;
|
|
2604 pkt->file_flag = NULL;
|
|
2605 pkt->file_url = NULL;
|
|
2606 pkt->file_expires = 0;
|
|
2607 pkt->file_description = NULL;
|
|
2608
|
|
2609 /* overkill allocation, but simple since only temporary use */
|
|
2610 tmp[0] = strdup(content);
|
|
2611 tmp[1] = strdup(content);
|
|
2612 tmp[2] = strdup(content);
|
|
2613 tmp[3] = strdup(content);
|
|
2614 tmp[4] = strdup(content);
|
|
2615
|
|
2616 /* raw data format: from,flag,url,timestamp,description */
|
|
2617
|
|
2618 i = 0;
|
|
2619 j = 0;
|
|
2620 section = 0;
|
|
2621 tmp[0][0] = 0;
|
|
2622 tmp[1][0] = 0;
|
|
2623 tmp[2][0] = 0;
|
|
2624 tmp[3][0] = 0;
|
|
2625 tmp[4][0] = 0;
|
|
2626
|
|
2627 while (i < strlen(content))
|
|
2628 {
|
|
2629 char ch = content[i];
|
|
2630
|
|
2631 if (ch == ',' && section < 4)
|
|
2632 {
|
|
2633 j = 0;
|
|
2634 section++;
|
|
2635 }
|
|
2636 else
|
|
2637 {
|
|
2638 tmp[section][j++] = ch;
|
|
2639 tmp[section][j] = 0;
|
|
2640 }
|
|
2641 i++;
|
|
2642 }
|
|
2643
|
|
2644 /* do stuff with extracted parts */
|
|
2645 pkt->file_from = strdup(tmp[0]);
|
|
2646 pkt->file_flag = strdup(tmp[1]);
|
|
2647 pkt->file_url = strdup(tmp[2]);
|
|
2648 pkt->file_expires = atoi(tmp[3]);
|
|
2649 pkt->file_description = strdup(tmp[4]);
|
|
2650
|
|
2651 /* free working variables */
|
|
2652 FREE(tmp[0]);
|
|
2653 FREE(tmp[1]);
|
|
2654 FREE(tmp[2]);
|
|
2655 FREE(tmp[3]);
|
|
2656 FREE(tmp[4]);
|
|
2657 FREE(content);
|
|
2658 return 0;
|
|
2659 }
|
|
2660
|
|
2661 int yahoo_parsepacket_calendar(struct yahoo_context *ctx,
|
|
2662 struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt)
|
|
2663 {
|
|
2664 char *content;
|
|
2665 char *tmp, delim[5];
|
|
2666
|
|
2667 /* Make working copy of content */
|
|
2668 content = strdup(inpkt->content);
|
|
2669
|
|
2670 /* init elements to all null */
|
|
2671 pkt->cal_url = NULL;
|
|
2672 pkt->cal_timestamp = NULL;
|
|
2673 pkt->cal_type = 0;
|
|
2674 pkt->cal_title = NULL;
|
|
2675 pkt->cal_description = NULL;
|
|
2676
|
|
2677 tmp = NULL;
|
|
2678 delim[0] = 2; /* control-b */
|
|
2679 delim[1] = 0;
|
|
2680
|
|
2681 if (content)
|
|
2682 {
|
|
2683 tmp = strtok(content, delim);
|
|
2684 }
|
|
2685
|
|
2686 if (tmp) /* got the url */
|
|
2687 {
|
|
2688 pkt->cal_url = strdup(tmp);
|
|
2689 tmp = strtok(NULL, delim);
|
|
2690
|
|
2691 /*
|
|
2692 v= is not the type code
|
|
2693 i= doesn't look like it either
|
|
2694 tmp2 = strstr(pkt->cal_url, "v=");
|
|
2695 if ( tmp2 )
|
|
2696 {
|
|
2697 pkt->cal_type = atoi(tmp2);
|
|
2698 }
|
|
2699 */
|
|
2700
|
|
2701 }
|
|
2702
|
|
2703 if (tmp) /* unknown (type code?) */
|
|
2704 {
|
|
2705 /* appears this isn't it either, I don't see where it is */
|
|
2706 /* pkt->cal_type = atoi(tmp); */
|
|
2707 tmp = strtok(NULL, "\r\n");
|
|
2708 }
|
|
2709
|
|
2710 if (tmp) /* timestamp */
|
|
2711 {
|
|
2712 pkt->cal_timestamp = strdup(tmp);
|
|
2713 tmp = strtok(NULL, "\r\n");
|
|
2714 }
|
|
2715
|
|
2716 if (tmp) /* title */
|
|
2717 {
|
|
2718 pkt->cal_title = strdup(tmp);
|
|
2719 tmp = strtok(NULL, delim); /* use delim since it won't occur again */
|
|
2720 }
|
|
2721
|
|
2722 if (tmp)
|
|
2723 {
|
|
2724 pkt->cal_description = strdup(tmp);
|
|
2725 }
|
|
2726
|
|
2727 FREE(content);
|
|
2728 return 0;
|
|
2729 }
|
|
2730
|
|
2731 int yahoo_parsepacket_chatinvite(struct yahoo_context *ctx,
|
|
2732 struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt)
|
|
2733 {
|
|
2734 char *content;
|
|
2735 int len;
|
|
2736
|
|
2737 /* Make working copy of content */
|
|
2738 content = strdup(inpkt->content);
|
|
2739 len = strlen(content);
|
|
2740
|
|
2741 /* do special parsing for invite later on */
|
|
2742 pkt->chat_invite_content = strdup(content);
|
|
2743
|
|
2744 return 0;
|
|
2745 }
|
|
2746
|
|
2747 int yahoo_parsepacket_newcontact(struct yahoo_context *ctx,
|
|
2748 struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt)
|
|
2749 {
|
|
2750 char *content;
|
|
2751 int len;
|
|
2752
|
|
2753 /* Make working copy of content */
|
|
2754 content = strdup(inpkt->content);
|
|
2755 len = strlen(content);
|
|
2756
|
|
2757 /* cheat for now, say if first digit is number */
|
|
2758 if (len > 0)
|
|
2759 {
|
|
2760 if (isdigit((int) content[0]))
|
|
2761 {
|
|
2762 return yahoo_parsepacket_status(ctx, pkt, inpkt);
|
|
2763 }
|
|
2764 else
|
|
2765 {
|
|
2766 return yahoo_parsepacket_message(ctx, pkt, inpkt);
|
|
2767 }
|
|
2768 }
|
|
2769
|
|
2770 return 0;
|
|
2771 }
|
|
2772
|
|
2773 int yahoo_parsepacket_status(struct yahoo_context *ctx,
|
|
2774 struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt)
|
|
2775 {
|
|
2776 char *content;
|
|
2777 char *tmpc;
|
|
2778 char *tmp1;
|
|
2779 int i;
|
|
2780 int len;
|
|
2781 int index;
|
|
2782 int realcount;
|
|
2783
|
|
2784 /* Make working copy of content */
|
|
2785 content = strdup(inpkt->content);
|
|
2786 len = strlen(content);
|
|
2787
|
|
2788 /* Pull off the flag from the initial part of the content */
|
|
2789 /* this flag indicates the number of buddy that're online */
|
|
2790 pkt->flag = 0;
|
|
2791 tmpc = content;
|
|
2792 while (tmpc[0] && isdigit((int) tmpc[0]))
|
|
2793 {
|
|
2794 pkt->flag = pkt->flag * 10 + (content[0] - '0');
|
|
2795 tmpc++;
|
|
2796 }
|
|
2797 if (tmpc[0] && tmpc[0] == ',')
|
|
2798 {
|
|
2799 tmpc++;
|
|
2800 }
|
|
2801
|
|
2802 /*
|
|
2803 We're receiving either this:
|
|
2804 2,buddy1(0,728EE9FB,0,1,0,0),buddy2(0,7AC00000,0,1,0,0)
|
|
2805 or this:
|
|
2806 buddy1(0,728EE9FB,0,1,0,0)
|
|
2807 hence:
|
|
2808 */
|
|
2809
|
|
2810 if (pkt->flag == 0)
|
|
2811 {
|
|
2812 pkt->idstatus_count = 1;
|
|
2813 }
|
|
2814 else
|
|
2815 {
|
|
2816 pkt->idstatus_count = pkt->flag;
|
|
2817 }
|
|
2818
|
|
2819 /* print an error if I get the was not AWAY */
|
|
2820 if (strstr(tmpc, "was not AWAY"))
|
|
2821 {
|
|
2822 pkt->idstatus_count = 0;
|
|
2823 yahoo_dbg_Print("libyahoo", "yahoo_parsepacket_status: "
|
|
2824 "got a 'was not AWAY' message\n");
|
|
2825 }
|
|
2826
|
|
2827 if (pkt->idstatus_count == 0)
|
|
2828 {
|
|
2829 /* No entries, so no array needed */
|
|
2830 pkt->idstatus = NULL;
|
|
2831 }
|
|
2832 else
|
|
2833 {
|
|
2834 /* Allocate the array */
|
|
2835 pkt->idstatus = (struct yahoo_idstatus **)
|
|
2836 calloc(sizeof(struct yahoo_idstatus), pkt->idstatus_count);
|
|
2837
|
|
2838 for (i = 0; i < pkt->idstatus_count; i++)
|
|
2839 {
|
|
2840 pkt->idstatus[i] = (struct yahoo_idstatus *)
|
|
2841
|
|
2842 calloc(1, sizeof(struct yahoo_idstatus));
|
|
2843 }
|
|
2844 }
|
|
2845
|
|
2846 index = 0;
|
|
2847 tmp1 = NULL;
|
|
2848 realcount = 0;
|
|
2849 while (tmpc && tmpc[0] && pkt->idstatus)
|
|
2850 {
|
|
2851 struct yahoo_idstatus *tmpid;
|
|
2852
|
|
2853 /* Get pointer to allocated structure to hold status data */
|
|
2854 tmpid = pkt->idstatus[index++];
|
|
2855 if (!tmpid)
|
|
2856 {
|
|
2857 /* shortcut, we know there can't be any more status entries
|
|
2858 at this point */
|
|
2859 /* yahoo_dbg_Print("status", "null tmpid"); */
|
|
2860 break;
|
|
2861 }
|
|
2862
|
|
2863 /* YPNS2.0 nick(status,msg,connection_id,UNK,in_pager,in_chat,in_game) */
|
|
2864 /* tnneul(99,test,message^A,6AD68325,0,1,0,0) */
|
|
2865 /* 0 1 2 3 4 5 6 */
|
|
2866
|
|
2867 /* YPNS1.0 nick(status,connection_id,UNK,in_pager,in_chat,in_game) */
|
|
2868 /* nneul(0,7081F531,0,1,0,0) */
|
|
2869 /* 0 2 3 4 5 6 */
|
|
2870
|
|
2871 /* rewrite this whole section in a less ugly fashion */
|
|
2872 /* first pull off the id */
|
|
2873
|
|
2874 /* YUCK - YPNS2.0 has variable format status records, if type is 99,
|
|
2875 it has 7 fields, second is msg */
|
|
2876
|
|
2877 #if 0
|
|
2878 yahoo_dbg_Print("status", "whole string = '%s'\n",
|
|
2879 yahoo_dbg_NullCheck(tmpc));
|
|
2880 #endif
|
|
2881
|
|
2882 if (tmp1)
|
|
2883 {
|
|
2884 tmp1 = strtok(NULL, "(");
|
|
2885 }
|
|
2886 else
|
|
2887 {
|
|
2888 tmp1 = strtok(tmpc, "(");
|
|
2889 }
|
|
2890 if (tmp1 && tmp1[0] == ',')
|
|
2891 {
|
|
2892 tmp1++;
|
|
2893 }
|
|
2894
|
|
2895 if (tmp1)
|
|
2896 {
|
|
2897 tmpid->id = strdup(tmp1);
|
|
2898 realcount++;
|
|
2899
|
|
2900 for (i = 0; i <= 6 && tmp1; i++)
|
|
2901 {
|
|
2902 #if 0
|
|
2903 yahoo_dbg_Print("status", "i==%d\n", i);
|
|
2904 #endif
|
|
2905
|
|
2906 if (i == 6) /* end of status area */
|
|
2907 {
|
|
2908 tmp1 = strtok(NULL, "),");
|
|
2909 }
|
|
2910 else if (i == 1)
|
|
2911 {
|
|
2912 char delim[3];
|
|
2913
|
|
2914 if (tmpid->status == YAHOO_STATUS_CUSTOM)
|
|
2915 {
|
|
2916 delim[0] = 1;
|
|
2917 delim[1] = ',';
|
|
2918 delim[1] = 0;
|
|
2919 tmp1 = strtok(NULL, delim);
|
|
2920 }
|
|
2921 else
|
|
2922 {
|
|
2923 i = 2;
|
|
2924 tmp1 = strtok(NULL, ",");
|
|
2925 }
|
|
2926 }
|
|
2927 else
|
|
2928 {
|
|
2929
|
|
2930 tmp1 = strtok(NULL, ",");
|
|
2931 }
|
|
2932
|
|
2933 /* then pull off the particular element of the list */
|
|
2934 if (tmp1)
|
|
2935 {
|
|
2936 switch (i)
|
|
2937 {
|
|
2938 case 0: /* status */
|
|
2939 tmpid->status = atoi(tmp1);
|
|
2940 break;
|
|
2941 case 1: /* msg */
|
|
2942 if (tmpid->status == YAHOO_STATUS_CUSTOM)
|
|
2943 {
|
|
2944 tmpid->status_msg = strdup(tmp1);
|
|
2945 }
|
|
2946 break;
|
|
2947 case 2: /* session id */
|
|
2948 tmpid->connection_id = strdup(tmp1);
|
|
2949 break;
|
|
2950 case 3: /* dunno what this is */
|
|
2951 break;
|
|
2952 case 4:
|
|
2953 tmpid->in_pager = atoi(tmp1);
|
|
2954 break;
|
|
2955 case 5:
|
|
2956 tmpid->in_chat = atoi(tmp1);
|
|
2957 break;
|
|
2958 case 6:
|
|
2959 tmpid->in_game = atoi(tmp1);
|
|
2960 break;
|
|
2961 }
|
|
2962 }
|
|
2963 }
|
|
2964 }
|
|
2965 }
|
|
2966
|
|
2967 for (i = realcount; i <= pkt->idstatus_count; i++)
|
|
2968 {
|
|
2969 if (pkt->idstatus && pkt->idstatus[i])
|
|
2970 {
|
|
2971 FREE(pkt->idstatus[i]);
|
|
2972 }
|
|
2973 }
|
|
2974 pkt->idstatus_count = realcount;
|
|
2975
|
|
2976 /* Free working copy of content */
|
|
2977 FREE(content);
|
|
2978
|
|
2979 /* Return ok for success */
|
|
2980 return (0);
|
|
2981 }
|
|
2982
|
|
2983 int yahoo_parsepacket_message(struct yahoo_context *ctx,
|
|
2984 struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt)
|
|
2985 {
|
|
2986 char *content;
|
|
2987 char *tmp_id;
|
|
2988 int i, j, section;
|
|
2989
|
|
2990 if (pkt->msgtype == YAHOO_MSGTYPE_OFFLINE)
|
|
2991 {
|
|
2992 return yahoo_parsepacket_message_offline(ctx, pkt, inpkt);
|
|
2993 }
|
|
2994
|
|
2995 /* Make working copy of content */
|
|
2996 content = strdup(inpkt->content);
|
|
2997 tmp_id = strdup(content);
|
|
2998
|
|
2999 /* initialize */
|
|
3000 pkt->msg_status = 0;
|
|
3001
|
|
3002 /* possible message content formats: */
|
|
3003 /* userid(#) *//* msgtype == YAHOO_MSGTYPE_STATUS */
|
|
3004 /* userid,,msg */
|
|
3005
|
|
3006 /* this needed butchered */
|
|
3007 /* YAHOO_MSGTYPE_OFFLINE */
|
|
3008 /* 6,6,tnneul,nneul,Tue Mar 7 12:14:50 2000,test offline msg^A */
|
|
3009
|
|
3010 i = 0;
|
|
3011 j = 0;
|
|
3012 section = 0;
|
|
3013 tmp_id[0] = 0;
|
|
3014 while (i < strlen(content))
|
|
3015 {
|
|
3016 char ch = content[i];
|
|
3017
|
|
3018 if (section == 0) /* parsing userid */
|
|
3019 {
|
|
3020 if (ch == ',')
|
|
3021 {
|
|
3022 j = 0;
|
|
3023 section = 1;
|
|
3024 }
|
|
3025 else if (ch == '(')
|
|
3026 {
|
|
3027 j = 0;
|
|
3028 section = 2;
|
|
3029 }
|
|
3030 else
|
|
3031 {
|
|
3032 tmp_id[j++] = ch;
|
|
3033 tmp_id[j] = 0;
|
|
3034 }
|
|
3035 }
|
|
3036 else if (section == 1) /* parsing flag */
|
|
3037 {
|
|
3038 if (ch == ',')
|
|
3039 {
|
|
3040 j = 0;
|
|
3041 section = 3;
|
|
3042 }
|
|
3043 }
|
|
3044 else if (section == 2) /* parsing status */
|
|
3045 {
|
|
3046 if (ch == ')')
|
|
3047 {
|
|
3048 j = 0;
|
|
3049 section = 3;
|
|
3050 }
|
|
3051 else
|
|
3052 {
|
|
3053 if (isdigit((int) ch))
|
|
3054 {
|
|
3055 pkt->msg_status *= 10;
|
|
3056 pkt->msg_status += ch - '0';
|
|
3057 }
|
|
3058 }
|
|
3059 }
|
|
3060 else
|
|
3061 {
|
|
3062 pkt->msg = strdup(&content[i]);
|
|
3063 break;
|
|
3064 }
|
|
3065
|
|
3066 i++;
|
|
3067 }
|
|
3068
|
|
3069 /* do stuff with extracted parts */
|
|
3070 pkt->msg_id = strdup(tmp_id);
|
|
3071
|
|
3072 /* handle empty message case */
|
|
3073 /* don't pass a message if it's just a status update */
|
|
3074 if (!pkt->msg && pkt->msgtype != YAHOO_MSGTYPE_STATUS)
|
|
3075 {
|
|
3076 pkt->msg = strdup("");
|
|
3077 }
|
|
3078
|
|
3079 /* free working variables */
|
|
3080 FREE(tmp_id);
|
|
3081 FREE(content);
|
|
3082
|
|
3083 /* Return ok for success */
|
|
3084 return (0);
|
|
3085 }
|
|
3086
|
|
3087 /* This parses a special format offline message, and is only currently
|
|
3088 called from yahoo_parsepacket_message. */
|
|
3089 int yahoo_parsepacket_message_offline(struct yahoo_context *ctx,
|
|
3090 struct yahoo_packet *pkt, struct yahoo_rawpacket *inpkt)
|
|
3091 {
|
|
3092 char *content;
|
|
3093 char *to_id;
|
|
3094 char *from_id;
|
|
3095 char *timestamp;
|
|
3096 int i, j, section;
|
|
3097
|
|
3098 /* Make working copy of content */
|
|
3099 content = strdup(inpkt->content);
|
|
3100 to_id = strdup(content);
|
|
3101 from_id = strdup(content);
|
|
3102 timestamp = strdup(content);
|
|
3103
|
|
3104 /* initialize */
|
|
3105 pkt->msg_status = 0;
|
|
3106
|
|
3107 /* 6,6,tnneul,nneul,Tue Mar 7 12:14:50 2000,test offline msg^A */
|
|
3108 /* sec0,sec1,sec2=to,sec3=from,sec4=tstamp,sec5=msg */
|
|
3109
|
|
3110 i = 0;
|
|
3111 j = 0;
|
|
3112 section = 0;
|
|
3113 to_id[0] = 0;
|
|
3114 from_id[0] = 0;
|
|
3115 timestamp[0] = 0;
|
|
3116
|
|
3117 while (i < strlen(content))
|
|
3118 {
|
|
3119 char ch = content[i];
|
|
3120
|
|
3121 if (section == 0) /* parsing first unknown number */
|
|
3122 {
|
|
3123 if (ch == ',')
|
|
3124 {
|
|
3125 j = 0;
|
|
3126 section = 1;
|
|
3127 }
|
|
3128 }
|
|
3129 else if (section == 1) /* parsing second unknown number */
|
|
3130 {
|
|
3131 if (ch == ',')
|
|
3132 {
|
|
3133 j = 0;
|
|
3134 section = 2;
|
|
3135 }
|
|
3136 }
|
|
3137 else if (section == 2) /* parsing to-id */
|
|
3138 {
|
|
3139 if (ch == ',')
|
|
3140 {
|
|
3141 j = 0;
|
|
3142 section = 3;
|
|
3143 }
|
|
3144 else
|
|
3145 {
|
|
3146 to_id[j++] = ch;
|
|
3147 to_id[j] = 0;
|
|
3148 }
|
|
3149 }
|
|
3150 else if (section == 3) /* parsing from-id */
|
|
3151 {
|
|
3152 if (ch == ',')
|
|
3153 {
|
|
3154 j = 0;
|
|
3155 section = 4;
|
|
3156 }
|
|
3157 else
|
|
3158 {
|
|
3159 from_id[j++] = ch;
|
|
3160 from_id[j] = 0;
|
|
3161 }
|
|
3162 }
|
|
3163 else if (section == 4) /* parsing timestamp */
|
|
3164 {
|
|
3165 if (ch == ',')
|
|
3166 {
|
|
3167 j = 0;
|
|
3168 section = 5;
|
|
3169 }
|
|
3170 else
|
|
3171 {
|
|
3172 timestamp[j++] = ch;
|
|
3173 timestamp[j] = 0;
|
|
3174 }
|
|
3175 }
|
|
3176 else
|
|
3177 {
|
|
3178 pkt->msg = strdup(&content[i]);
|
|
3179 break;
|
|
3180 }
|
|
3181
|
|
3182 i++;
|
|
3183 }
|
|
3184
|
|
3185 /* do stuff with extracted parts */
|
|
3186 pkt->msg_id = strdup(from_id);
|
|
3187 pkt->msg_timestamp = strdup(timestamp);
|
|
3188 if (pkt->active_id)
|
|
3189 {
|
|
3190 FREE(pkt->active_id);
|
|
3191 pkt->active_id = strdup(to_id);
|
|
3192 }
|
|
3193
|
|
3194 /* free working variables */
|
|
3195 FREE(timestamp);
|
|
3196 FREE(from_id);
|
|
3197 FREE(to_id) FREE(content);
|
|
3198
|
|
3199 /* Return ok for success */
|
|
3200 return (0);
|
|
3201 }
|
|
3202
|
|
3203 int yahoo_getdata(struct yahoo_context *ctx)
|
|
3204 {
|
|
3205 char buf[1000];
|
|
3206 int res;
|
|
3207
|
|
3208 /* This is a http mode connection, so just send a ping to get any
|
|
3209 new data from the server. */
|
|
3210 if (ctx->connect_mode == YAHOO_CONNECT_HTTP ||
|
|
3211 ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY)
|
|
3212 {
|
|
3213 yahoo_sendcmd(ctx, YAHOO_SERVICE_PING, ctx->user, "", 0);
|
|
3214 return (1);
|
|
3215 }
|
|
3216
|
|
3217 /* this assumes that data is ready */
|
|
3218 /* Read from the connection to the server and get any new data */
|
|
3219 res = read(ctx->sockfd, buf, 1000);
|
|
3220 if (res == -1)
|
|
3221 {
|
|
3222 yahoo_dbg_Print("io",
|
|
3223 "yahoo_getdata: error reading data from server\n");
|
|
3224 return (0);
|
|
3225 }
|
|
3226 if (res > 0)
|
|
3227 {
|
|
3228 yahoo_addtobuffer(ctx, buf, res);
|
|
3229 yahoo_dbg_Print("io", "[libyahoo] yahoo_getdata: read (%d) bytes\n",
|
|
3230 res);
|
|
3231 return 1;
|
|
3232 }
|
|
3233 else if (res == 0)
|
|
3234 {
|
|
3235 yahoo_dbg_Print("io",
|
|
3236 "[libyahoo] yahoo_getdata: got zero length read\n", res);
|
|
3237 return 0;
|
|
3238 }
|
|
3239
|
|
3240 return (1);
|
|
3241 }
|
|
3242
|
|
3243 struct yahoo_rawpacket *yahoo_getpacket(struct yahoo_context *ctx)
|
|
3244 {
|
|
3245 struct yahoo_rawpacket *pkt;
|
|
3246 struct yahoo_rawpacket *retpkt;
|
|
3247 int *buflen = &ctx->io_buf_curlen;
|
|
3248 char *buffer = ctx->io_buf;
|
|
3249 unsigned int contentlen;
|
|
3250
|
|
3251 /* If buffer doesn't start with YHOO, skip bytes until it
|
|
3252 does. This is to protect against possible packet alignment
|
|
3253 errors if I size something wrong at any time. */
|
|
3254
|
|
3255 while ((*buflen >= 4) && (memcmp(buffer, "YHOO", 4)))
|
|
3256 {
|
|
3257 /* making quiet for now so I don't have to work too hard on the HTTP support */
|
|
3258 #if 0
|
|
3259 printf("\nskipped buffer byte (%d)\n", buffer[0]);
|
|
3260 #endif
|
|
3261 memmove(buffer, buffer + 1, *buflen - 1);
|
|
3262 *buflen = *buflen - 1;
|
|
3263 }
|
|
3264
|
|
3265 /* Don't do anything if the buffer doesn't have at least a full
|
|
3266 header */
|
|
3267 if (*buflen < YAHOO_PACKET_HEADER_SIZE)
|
|
3268 {
|
|
3269 // printf("returning null cause buffer is too small\n");
|
|
3270 return NULL;
|
|
3271 }
|
|
3272
|
|
3273 /* print out the beginning of the buffer */
|
|
3274 #if 0
|
|
3275 printf("Buffer (buflen = %d):\n", *buflen);
|
|
3276 for (i = 0; i < *buflen; i++)
|
|
3277 {
|
|
3278 if ((i) % 10 == 0)
|
|
3279 {
|
|
3280 printf("\n%.4d: ", i);
|
|
3281 }
|
|
3282 if (isprint(buffer[i]))
|
|
3283 {
|
|
3284 printf("%-3d %c ", buffer[i], buffer[i]);
|
|
3285 }
|
|
3286 else
|
|
3287 {
|
|
3288 printf("%-3d ", buffer[i]);
|
|
3289 }
|
|
3290 }
|
|
3291 printf("\n");
|
|
3292 #endif
|
|
3293 /* Make pkt point to buffer for ease of use */
|
|
3294 pkt = (struct yahoo_rawpacket *) buffer;
|
|
3295
|
|
3296 /* Determine the content size specified by the header */
|
|
3297 contentlen = yahoo_makeint(pkt->len) - YAHOO_PACKET_HEADER_SIZE;
|
|
3298 // printf("contentlen = %d\n", contentlen);
|
|
3299
|
|
3300 /* Don't continue if buffer doesn't have full content in it */
|
|
3301 if (*buflen < (YAHOO_PACKET_HEADER_SIZE + contentlen))
|
|
3302 {
|
|
3303 // printf("buffer not big enough for contentlen\n");
|
|
3304 return NULL;
|
|
3305 }
|
|
3306
|
|
3307 /* Copy this packet */
|
|
3308 retpkt =
|
|
3309 (struct yahoo_rawpacket *) malloc(YAHOO_PACKET_HEADER_SIZE +
|
|
3310 contentlen);
|
|
3311 memcpy(retpkt, buffer, YAHOO_PACKET_HEADER_SIZE + contentlen);
|
|
3312
|
|
3313 /* Shift the buffer */
|
|
3314 memmove(buffer, buffer + YAHOO_PACKET_HEADER_SIZE + contentlen,
|
|
3315 *buflen - YAHOO_PACKET_HEADER_SIZE - contentlen);
|
|
3316
|
|
3317 /* Adjust the buffer length */
|
|
3318 *buflen -= (YAHOO_PACKET_HEADER_SIZE + contentlen);
|
|
3319
|
|
3320 /* Return the packet */
|
|
3321 return retpkt;
|
|
3322 }
|
|
3323
|
|
3324 int yahoo_isbuddy(struct yahoo_context *ctx, const char *id)
|
|
3325 {
|
|
3326 int i;
|
|
3327 char *buddy = NULL;
|
|
3328
|
|
3329 if (!id || !ctx || !ctx->buddies)
|
|
3330 {
|
|
3331 return FALSE;
|
|
3332 }
|
|
3333
|
|
3334 for (i = 0; ctx->buddies[i]; i++)
|
|
3335 {
|
|
3336 buddy = (ctx->buddies[i])->id;
|
|
3337 if (!strcasecmp(id, buddy))
|
|
3338 {
|
|
3339 return TRUE;
|
|
3340 }
|
|
3341 }
|
|
3342
|
|
3343 return FALSE;
|
|
3344 }
|
|
3345
|
|
3346 static void yahoo_free_address (struct yahoo_address *add)
|
|
3347 {
|
|
3348 yahoo_dbg_Print("addressbook",
|
|
3349 "[libyahoo] yahoo_free_address: record at address 0x%08p for user %s (%s %s) being free'd\n",
|
|
3350 add, add->id, add->firstname, add->lastname);
|
|
3351
|
|
3352 FREE (add->firstname);
|
|
3353 FREE (add->lastname);
|
|
3354 FREE (add->emailnickname);
|
|
3355 FREE (add->email);
|
|
3356 FREE (add->workphone);
|
|
3357 FREE (add->homephone);
|
|
3358 }
|
|
3359
|
|
3360 void yahoo_freeaddressbook(struct yahoo_context *ctx)
|
|
3361 {
|
|
3362 unsigned int count = ctx->address_count;
|
|
3363 struct yahoo_address *add_p = ctx->addresses;
|
|
3364
|
|
3365 if (NULL == ctx || NULL == ctx->addresses)
|
|
3366 return;
|
|
3367
|
|
3368 while (count-- > 0)
|
|
3369 {
|
|
3370 yahoo_free_address (add_p++);
|
|
3371 }
|
|
3372
|
|
3373 ctx->address_count = 0;
|
|
3374 FREE (ctx->addresses);
|
|
3375 }
|
|
3376
|
|
3377 static void yahoo_data_to_addressbook (char *block, struct yahoo_context *ctx)
|
|
3378 {
|
|
3379 char *token = NULL;
|
|
3380 int record = 0;
|
|
3381 struct yahoo_address *add = NULL;
|
|
3382
|
|
3383 if (NULL == block || NULL == ctx)
|
|
3384 return;
|
|
3385
|
|
3386 yahoo_freeaddressbook (ctx);
|
|
3387
|
|
3388 add = ctx->addresses = calloc (ctx->address_count, sizeof (struct yahoo_address));
|
|
3389
|
|
3390 /*
|
|
3391 Okay!
|
|
3392 At this point we have a char * (block) that has \012 delimited records
|
|
3393 Each record (as a string when retreived with strtok) follows the format:
|
|
3394 <ID>:<FIRSTNAME>\011<LASTNAME>\011<EMAILNICKNAME>\011<EMAIL>\011<HOMEPHONE>\011<WORKPHONE>\011[01]\011<ENTRYID>\000
|
|
3395 */
|
|
3396
|
|
3397 token = strtok (block, "\012");
|
|
3398 while (NULL != token)
|
|
3399 {
|
|
3400 /*
|
|
3401 Here we must use memtok because we'll get some repeated tokens!!!!!
|
|
3402 */
|
|
3403 char *field = NULL;
|
|
3404 size_t token_len = 0, found = 0;
|
|
3405
|
|
3406 ++record;
|
|
3407 token_len = strlen (token);
|
|
3408
|
|
3409 field = memtok(token, token_len, ":", 1, &found);
|
|
3410
|
|
3411 if (NULL != field)
|
|
3412 {
|
|
3413 add->id = memdupasstr(field, found);
|
|
3414 field = memtok(0, 0, "\011", 1, &found);
|
|
3415 }
|
|
3416
|
|
3417 if (NULL != field)
|
|
3418 {
|
|
3419 add->firstname = memdupasstr(field, found);
|
|
3420 field = memtok(0, 0, "\011", 1, &found);
|
|
3421 }
|
|
3422
|
|
3423 if (NULL != field)
|
|
3424 {
|
|
3425 add->lastname = memdupasstr(field, found);
|
|
3426 field = memtok(0, 0, "\011", 1, &found);
|
|
3427 }
|
|
3428
|
|
3429 if (NULL != field)
|
|
3430 {
|
|
3431 add->emailnickname = memdupasstr(field, found);
|
|
3432 field = memtok(0, 0, "\011", 1, &found);
|
|
3433 }
|
|
3434
|
|
3435 if (NULL != field)
|
|
3436 {
|
|
3437 add->email = memdupasstr(field, found);
|
|
3438 field = memtok(0, 0, "\011", 1, &found);
|
|
3439 }
|
|
3440
|
|
3441 if (NULL != field)
|
|
3442 {
|
|
3443 add->homephone = memdupasstr(field, found);
|
|
3444 field = memtok(0, 0, "\011", 1, &found);
|
|
3445 }
|
|
3446
|
|
3447 if (NULL != field)
|
|
3448 {
|
|
3449 add->workphone = memdupasstr(field, found);
|
|
3450 field = memtok(0, 0, "\011", 1, &found);
|
|
3451 }
|
|
3452
|
|
3453 if (NULL != field)
|
|
3454 {
|
|
3455 add->primary_phone = (*field == '0' ? home : work);
|
|
3456 field = memtok(0, 0, "", 1, &found);
|
|
3457 }
|
|
3458
|
|
3459 if (NULL != field)
|
|
3460 {
|
|
3461 char *entryid = memdupasstr(field, found);
|
|
3462 if (NULL != entryid)
|
|
3463 {
|
|
3464 add->entryid = atoi (entryid);
|
|
3465 FREE (entryid);
|
|
3466 }
|
|
3467 }
|
|
3468
|
|
3469 yahoo_dbg_Print("addressbook",
|
|
3470 "[libyahoo] yahoo_fetchaddressbook: record #%d is for user %s (%s %s)\n",
|
|
3471 record, add->id, add->firstname, add->lastname);
|
|
3472
|
|
3473 ++add;
|
|
3474
|
|
3475 token = strtok (NULL, "\012");
|
|
3476 }
|
|
3477 }
|
|
3478
|
|
3479 /* retreive the details of the friends in your address book that have a Yahoo! id listed */
|
|
3480 int yahoo_fetchaddressbook(struct yahoo_context *ctx)
|
|
3481 {
|
|
3482 char buffer[5000];
|
|
3483 int servfd;
|
|
3484 int res;
|
|
3485 int copied = 0, size = 5000;
|
|
3486 char *address = NULL, *copy = NULL;
|
|
3487
|
|
3488 if (!ctx)
|
|
3489 {
|
|
3490 return 0;
|
|
3491 }
|
|
3492
|
|
3493 yahoo_dbg_Print("addressbook",
|
|
3494 "[libyahoo] yahoo_fetchaddressbook: starting\n");
|
|
3495
|
|
3496 /* Check for cached addresses */
|
|
3497 if (ctx->addresses)
|
|
3498 {
|
|
3499 yahoo_freeaddressbook(ctx);
|
|
3500 }
|
|
3501
|
|
3502 if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY)
|
|
3503 {
|
|
3504 servfd = yahoo_socket_connect(ctx, ctx->proxy_host, ctx->proxy_port);
|
|
3505 }
|
|
3506 else
|
|
3507 {
|
|
3508 servfd = yahoo_socket_connect(ctx, YAHOO_ADDRESS_HOST, YAHOO_ADDRESS_PORT);
|
|
3509 }
|
|
3510
|
|
3511 if (!servfd)
|
|
3512 {
|
|
3513 printf("[libyahoo] failed to connect to address book server.\n");
|
|
3514 return (0);
|
|
3515 }
|
|
3516
|
|
3517 strcpy(buffer, "GET ");
|
|
3518 if (ctx->connect_mode == YAHOO_CONNECT_HTTPPROXY)
|
|
3519 {
|
|
3520 strcat(buffer, YAHOO_ADDRESS_HOST);
|
|
3521 }
|
|
3522 strcat(buffer, "/yab/uk/yab?v=PG&A=s");
|
|
3523 strcat(buffer, " HTTP/1.0\r\n");
|
|
3524 strcat(buffer, "User-Agent: " YAHOO_USER_AGENT "\r\n");
|
|
3525 strcat(buffer, "Host: " YAHOO_AUTH_HOST "\r\n");
|
|
3526 strcat(buffer, "Cookie: ");
|
|
3527 strcat(buffer, ctx->cookie);
|
|
3528 strcat(buffer, "\r\n");
|
|
3529 strcat(buffer, "\r\n");
|
|
3530
|
|
3531 write(servfd, buffer, strlen(buffer));
|
|
3532
|
|
3533 yahoo_dbg_Print("addressbook",
|
|
3534 "[libyahoo] yahoo_fetchaddressbook: writing buffer '%s'\n", buffer);
|
|
3535
|
|
3536 while ((res = yahoo_tcp_readline(buffer, 5000, servfd)) > 0)
|
|
3537 {
|
|
3538 if ('\012' == buffer[0])
|
|
3539 continue;
|
|
3540
|
|
3541 if (0 == strncmp (buffer, "1\011", 2))
|
|
3542 {
|
|
3543 yahoo_dbg_Print("addressbook",
|
|
3544 "[libyahoo] yahoo_fetchaddressbook: found first line\n");
|
|
3545 if (3 == res)
|
|
3546 {
|
|
3547 yahoo_dbg_Print("addressbook",
|
|
3548 "[libyahoo] yahoo_fetchaddressbook: however there's been a problem\n");
|
|
3549 break;
|
|
3550 }
|
|
3551
|
|
3552 address = &buffer[2];
|
|
3553 }
|
|
3554 else if (NULL != address)
|
|
3555 {
|
|
3556 address = &buffer[0];
|
|
3557 }
|
|
3558
|
|
3559 if (NULL != address)
|
|
3560 {
|
|
3561 if (NULL == copy)
|
|
3562 {
|
|
3563 copy = malloc (size);
|
|
3564 memset (copy, 0, size);
|
|
3565 }
|
|
3566
|
|
3567 if ((copied + res) > size)
|
|
3568 {
|
|
3569 char *newcopy = NULL;
|
|
3570
|
|
3571 yahoo_dbg_Print("addressbook",
|
|
3572 "[libyahoo] yahoo_fetchaddressbook: resizing buffer from %d bytes to %d bytes\n", size, size * 2);
|
|
3573 size *= 2;
|
|
3574 newcopy = malloc (size);
|
|
3575 memset (newcopy, 0, size);
|
|
3576 memcpy (newcopy, copy, copied);
|
|
3577 free (copy);
|
|
3578 copy = newcopy;
|
|
3579 }
|
|
3580
|
|
3581 copied += res;
|
|
3582 strcat (copy, address);
|
|
3583 ++ctx->address_count;
|
|
3584 }
|
|
3585 }
|
|
3586
|
|
3587 yahoo_data_to_addressbook (copy, ctx);
|
|
3588 FREE (copy);
|
|
3589
|
|
3590 yahoo_dbg_Print("addressbook",
|
|
3591 "[libyahoo] yahoo_fetchaddressbook: closing server connection\n");
|
|
3592 close(servfd);
|
|
3593 servfd = 0;
|
|
3594 yahoo_dbg_Print("addressbook",
|
|
3595 "[libyahoo] yahoo_fetchaddressbook: closed server connection\n");
|
|
3596
|
|
3597 yahoo_dbg_Print("addressbook", "[libyahoo] yahoo_fetchaddressbook: done (%d addresses retreived)\n", ctx->address_count);
|
|
3598
|
|
3599 return ctx->address_count;
|
|
3600 }
|