Mercurial > pidgin
annotate src/protocols/yahoo/yahoo.c @ 4891:cfa045006bec
[gaim-migrate @ 5221]
this saves the blist.xml file to an alternate name, and then moves it, that
way we don't lose your precious buddies if gaim crashes.
Of course, if gaim were to crash, it wouldn't be gaim's fault, it would be
the fault of some external force. This is because gaim is perfect, and
Sean is perfect. Yeah.
This should be done for .gaimrc too, but i'm too tired to do that right now.
committer: Tailor Script <tailor@pidgin.im>
| author | Nathan Walp <nwalp@pidgin.im> |
|---|---|
| date | Tue, 25 Mar 2003 06:35:45 +0000 |
| parents | 0ed37c803503 |
| children | d9b6b5ae34e4 |
| rev | line source |
|---|---|
| 2681 | 1 /* |
| 2 * gaim | |
| 3 * | |
| 4 * Some code copyright (C) 1998-1999, Mark Spencer <markster@marko.net> | |
| 5 * libfaim code copyright 1998, 1999 Adam Fritzler <afritz@auk.cx> | |
| 6 * | |
| 7 * This program is free software; you can redistribute it and/or modify | |
| 8 * it under the terms of the GNU General Public License as published by | |
| 9 * the Free Software Foundation; either version 2 of the License, or | |
| 10 * (at your option) any later version. | |
| 11 * | |
| 12 * This program is distributed in the hope that it will be useful, | |
| 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 15 * GNU General Public License for more details. | |
| 16 * | |
| 17 * You should have received a copy of the GNU General Public License | |
| 18 * along with this program; if not, write to the Free Software | |
| 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 20 * | |
| 21 */ | |
| 22 | |
| 23 #ifdef HAVE_CONFIG_H | |
| 24 #include "config.h" | |
| 25 #endif | |
| 26 | |
| 3630 | 27 #ifndef _WIN32 |
| 2681 | 28 #include <netdb.h> |
| 29 #include <unistd.h> | |
| 30 #include <netinet/in.h> | |
| 31 #include <arpa/inet.h> | |
| 3630 | 32 #include <sys/socket.h> |
| 33 #else | |
| 34 #include <winsock.h> | |
| 35 #endif | |
| 36 | |
| 37 #include <errno.h> | |
| 2681 | 38 #include <string.h> |
| 39 #include <stdlib.h> | |
| 40 #include <stdio.h> | |
| 41 #include <time.h> | |
| 42 #include <sys/stat.h> | |
| 43 #include <ctype.h> | |
| 4608 | 44 #include "gaim.h" |
| 2681 | 45 #include "multi.h" |
| 46 #include "prpl.h" | |
| 47 #include "proxy.h" | |
| 3147 | 48 #include "md5.h" |
| 2681 | 49 |
| 3630 | 50 #ifdef _WIN32 |
| 51 #include "win32dep.h" | |
| 52 #endif | |
| 53 | |
|
2795
536bb833fdeb
[gaim-migrate @ 2808]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2786
diff
changeset
|
54 extern char *yahoo_crypt(char *, char *); |
|
536bb833fdeb
[gaim-migrate @ 2808]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2786
diff
changeset
|
55 |
| 3630 | 56 /* for win32 compatability */ |
| 57 G_MODULE_IMPORT GSList *connections; | |
| 58 | |
| 2993 | 59 #define YAHOO_DEBUG |
| 2681 | 60 |
| 61 #define USEROPT_MAIL 0 | |
| 62 | |
| 63 #define USEROPT_PAGERHOST 3 | |
| 3147 | 64 #define YAHOO_PAGER_HOST "scs.yahoo.com" |
| 2681 | 65 #define USEROPT_PAGERPORT 4 |
| 66 #define YAHOO_PAGER_PORT 5050 | |
| 67 | |
| 3467 | 68 #define YAHOO_PROTO_VER 0x0900 |
| 69 | |
|
2686
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
70 enum yahoo_service { /* these are easier to see in hex */ |
| 2681 | 71 YAHOO_SERVICE_LOGON = 1, |
| 72 YAHOO_SERVICE_LOGOFF, | |
| 73 YAHOO_SERVICE_ISAWAY, | |
| 74 YAHOO_SERVICE_ISBACK, | |
|
2686
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
75 YAHOO_SERVICE_IDLE, /* 5 (placemarker) */ |
| 2681 | 76 YAHOO_SERVICE_MESSAGE, |
| 77 YAHOO_SERVICE_IDACT, | |
| 78 YAHOO_SERVICE_IDDEACT, | |
| 79 YAHOO_SERVICE_MAILSTAT, | |
|
2686
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
80 YAHOO_SERVICE_USERSTAT, /* 0xa */ |
| 2681 | 81 YAHOO_SERVICE_NEWMAIL, |
| 82 YAHOO_SERVICE_CHATINVITE, | |
| 83 YAHOO_SERVICE_CALENDAR, | |
| 84 YAHOO_SERVICE_NEWPERSONALMAIL, | |
| 85 YAHOO_SERVICE_NEWCONTACT, | |
|
2686
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
86 YAHOO_SERVICE_ADDIDENT, /* 0x10 */ |
| 2681 | 87 YAHOO_SERVICE_ADDIGNORE, |
| 88 YAHOO_SERVICE_PING, | |
| 89 YAHOO_SERVICE_GROUPRENAME, | |
|
2686
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
90 YAHOO_SERVICE_SYSMESSAGE = 0x14, |
|
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
91 YAHOO_SERVICE_PASSTHROUGH2 = 0x16, |
|
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
92 YAHOO_SERVICE_CONFINVITE = 0x18, |
| 2681 | 93 YAHOO_SERVICE_CONFLOGON, |
| 94 YAHOO_SERVICE_CONFDECLINE, | |
| 95 YAHOO_SERVICE_CONFLOGOFF, | |
| 96 YAHOO_SERVICE_CONFADDINVITE, | |
| 97 YAHOO_SERVICE_CONFMSG, | |
| 98 YAHOO_SERVICE_CHATLOGON, | |
| 99 YAHOO_SERVICE_CHATLOGOFF, | |
|
2686
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
100 YAHOO_SERVICE_CHATMSG = 0x20, |
|
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
101 YAHOO_SERVICE_GAMELOGON = 0x28, |
|
2786
318f846120e2
[gaim-migrate @ 2799]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2772
diff
changeset
|
102 YAHOO_SERVICE_GAMELOGOFF, |
|
318f846120e2
[gaim-migrate @ 2799]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2772
diff
changeset
|
103 YAHOO_SERVICE_GAMEMSG = 0x2a, |
|
2686
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
104 YAHOO_SERVICE_FILETRANSFER = 0x46, |
| 3019 | 105 YAHOO_SERVICE_NOTIFY = 0x4B, |
| 3147 | 106 YAHOO_SERVICE_AUTHRESP = 0x54, |
|
2686
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
107 YAHOO_SERVICE_LIST = 0x55, |
| 3147 | 108 YAHOO_SERVICE_AUTH = 0x57, |
|
2686
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
109 YAHOO_SERVICE_ADDBUDDY = 0x83, |
|
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
110 YAHOO_SERVICE_REMBUDDY = 0x84 |
| 2681 | 111 }; |
| 112 | |
| 113 enum yahoo_status { | |
|
2686
7b21c5446baf
[gaim-migrate @ 2699]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2683
diff
changeset
|
114 YAHOO_STATUS_AVAILABLE = 0, |
| 2681 | 115 YAHOO_STATUS_BRB, |
| 116 YAHOO_STATUS_BUSY, | |
| 117 YAHOO_STATUS_NOTATHOME, | |
| 118 YAHOO_STATUS_NOTATDESK, | |
| 119 YAHOO_STATUS_NOTINOFFICE, | |
| 120 YAHOO_STATUS_ONPHONE, | |
| 121 YAHOO_STATUS_ONVACATION, | |
| 122 YAHOO_STATUS_OUTTOLUNCH, | |
| 123 YAHOO_STATUS_STEPPEDOUT, | |
| 124 YAHOO_STATUS_INVISIBLE = 12, | |
| 125 YAHOO_STATUS_CUSTOM = 99, | |
| 126 YAHOO_STATUS_IDLE = 999, | |
| 2993 | 127 YAHOO_STATUS_OFFLINE = 0x5a55aa56, /* don't ask */ |
| 128 YAHOO_STATUS_TYPING = 0x16 | |
| 2681 | 129 }; |
| 3019 | 130 #define YAHOO_STATUS_GAME 0x2 /* Games don't fit into the regular status model */ |
| 2681 | 131 |
| 132 struct yahoo_data { | |
| 133 int fd; | |
| 134 guchar *rxqueue; | |
| 135 int rxlen; | |
| 136 GHashTable *hash; | |
| 3019 | 137 GHashTable *games; |
| 2681 | 138 int current_status; |
| 139 gboolean logged_in; | |
| 140 }; | |
| 141 | |
| 142 struct yahoo_pair { | |
| 143 int key; | |
| 144 char *value; | |
| 145 }; | |
| 146 | |
| 147 struct yahoo_packet { | |
| 148 guint16 service; | |
| 149 guint32 status; | |
| 150 guint32 id; | |
| 151 GSList *hash; | |
| 152 }; | |
| 153 | |
| 154 #define YAHOO_PACKET_HDRLEN (4 + 2 + 2 + 2 + 2 + 4 + 4) | |
| 155 | |
| 156 static struct yahoo_packet *yahoo_packet_new(enum yahoo_service service, enum yahoo_status status, int id) | |
| 157 { | |
| 158 struct yahoo_packet *pkt = g_new0(struct yahoo_packet, 1); | |
| 159 | |
| 160 pkt->service = service; | |
| 161 pkt->status = status; | |
| 162 pkt->id = id; | |
| 163 | |
| 164 return pkt; | |
| 165 } | |
| 166 | |
| 3466 | 167 static void yahoo_packet_hash(struct yahoo_packet *pkt, int key, const char *value) |
| 2681 | 168 { |
| 169 struct yahoo_pair *pair = g_new0(struct yahoo_pair, 1); | |
| 170 pair->key = key; | |
| 171 pair->value = g_strdup(value); | |
| 172 pkt->hash = g_slist_append(pkt->hash, pair); | |
| 173 } | |
| 174 | |
| 175 static int yahoo_packet_length(struct yahoo_packet *pkt) | |
| 176 { | |
| 177 GSList *l; | |
| 178 | |
| 179 int len = 0; | |
| 180 | |
| 181 l = pkt->hash; | |
| 182 while (l) { | |
| 183 struct yahoo_pair *pair = l->data; | |
| 184 int tmp = pair->key; | |
| 185 do { | |
| 186 tmp /= 10; | |
| 187 len++; | |
| 188 } while (tmp); | |
| 189 len += 2; | |
| 190 len += strlen(pair->value); | |
| 191 len += 2; | |
| 192 l = l->next; | |
| 193 } | |
| 194 | |
| 195 return len; | |
| 196 } | |
| 197 | |
| 198 /* sometimes i wish prpls could #include things from other prpls. then i could just | |
| 199 * use the routines from libfaim and not have to admit to knowing how they work. */ | |
| 200 #define yahoo_put16(buf, data) ( \ | |
| 201 (*(buf) = (u_char)((data)>>8)&0xff), \ | |
| 202 (*((buf)+1) = (u_char)(data)&0xff), \ | |
| 203 2) | |
| 204 #define yahoo_get16(buf) ((((*(buf))<<8)&0xff00) + ((*((buf)+1)) & 0xff)) | |
| 205 #define yahoo_put32(buf, data) ( \ | |
| 206 (*((buf)) = (u_char)((data)>>24)&0xff), \ | |
| 207 (*((buf)+1) = (u_char)((data)>>16)&0xff), \ | |
| 208 (*((buf)+2) = (u_char)((data)>>8)&0xff), \ | |
| 209 (*((buf)+3) = (u_char)(data)&0xff), \ | |
| 210 4) | |
| 211 #define yahoo_get32(buf) ((((*(buf))<<24)&0xff000000) + \ | |
| 212 (((*((buf)+1))<<16)&0x00ff0000) + \ | |
| 213 (((*((buf)+2))<< 8)&0x0000ff00) + \ | |
| 214 (((*((buf)+3) )&0x000000ff))) | |
| 215 | |
| 216 static void yahoo_packet_read(struct yahoo_packet *pkt, guchar *data, int len) | |
| 217 { | |
| 218 int pos = 0; | |
| 219 | |
| 220 while (pos + 1 < len) { | |
|
2724
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
221 char key[64], *value = NULL; |
|
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
222 int accept; |
| 2681 | 223 int x; |
| 224 | |
| 225 struct yahoo_pair *pair = g_new0(struct yahoo_pair, 1); | |
| 226 | |
| 227 x = 0; | |
| 228 while (pos + 1 < len) { | |
| 229 if (data[pos] == 0xc0 && data[pos + 1] == 0x80) | |
| 230 break; | |
| 231 key[x++] = data[pos++]; | |
| 232 } | |
| 233 key[x] = 0; | |
| 234 pos += 2; | |
| 235 pair->key = strtol(key, NULL, 10); | |
|
2724
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
236 accept = x; /* if x is 0 there was no key, so don't accept it */ |
| 2681 | 237 |
|
3996
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
238 if (len - pos + 1 <= 0) { |
|
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
239 /* Truncated. Garbage or something. */ |
|
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
240 accept = 0; |
|
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
241 } |
|
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
242 |
|
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
243 if (accept) { |
|
2724
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
244 value = g_malloc(len - pos + 1); |
|
3996
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
245 x = 0; |
|
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
246 while (pos + 1 < len) { |
|
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
247 if (data[pos] == 0xc0 && data[pos + 1] == 0x80) |
|
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
248 break; |
|
2724
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
249 value[x++] = data[pos++]; |
|
3996
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
250 } |
|
2724
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
251 value[x] = 0; |
|
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
252 pair->value = g_strdup(value); |
|
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
253 g_free(value); |
|
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
254 pkt->hash = g_slist_append(pkt->hash, pair); |
|
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
255 debug_printf("Key: %d \tValue: %s\n", pair->key, pair->value); |
|
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
256 } else { |
|
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
257 g_free(pair); |
|
7f3f4aa114ad
[gaim-migrate @ 2737]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2723
diff
changeset
|
258 } |
|
3996
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
259 pos += 2; |
|
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
260 |
|
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
261 /* Skip over garbage we've noticed in the mail notifications */ |
|
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
262 if (data[0] == '9' && data[pos] == 0x01) |
|
3fdfe7872118
[gaim-migrate @ 4191]
Christian Hammond <chipx86@chipx86.com>
parents:
3768
diff
changeset
|
263 pos++; |
| 2681 | 264 } |
| 265 } | |
| 266 | |
| 267 static void yahoo_packet_write(struct yahoo_packet *pkt, guchar *data) | |
| 268 { | |
| 269 GSList *l = pkt->hash; | |
| 270 int pos = 0; | |
| 271 | |
| 272 while (l) { | |
| 273 struct yahoo_pair *pair = l->data; | |
| 274 guchar buf[100]; | |
| 275 | |
| 276 g_snprintf(buf, sizeof(buf), "%d", pair->key); | |
| 277 strcpy(data + pos, buf); | |
| 278 pos += strlen(buf); | |
| 279 data[pos++] = 0xc0; | |
| 280 data[pos++] = 0x80; | |
| 281 | |
| 282 strcpy(data + pos, pair->value); | |
| 283 pos += strlen(pair->value); | |
| 284 data[pos++] = 0xc0; | |
| 285 data[pos++] = 0x80; | |
| 286 | |
| 287 l = l->next; | |
| 288 } | |
| 289 } | |
| 290 | |
| 291 static void yahoo_packet_dump(guchar *data, int len) | |
| 292 { | |
| 293 #ifdef YAHOO_DEBUG | |
| 294 int i; | |
| 295 for (i = 0; i + 1 < len; i += 2) { | |
| 296 if ((i % 16 == 0) && i) | |
| 297 debug_printf("\n"); | |
| 298 debug_printf("%02x", data[i]); | |
| 299 debug_printf("%02x ", data[i+1]); | |
| 300 } | |
| 301 if (i < len) | |
| 302 debug_printf("%02x", data[i]); | |
| 303 debug_printf("\n"); | |
| 304 for (i = 0; i < len; i++) { | |
| 305 if ((i % 16 == 0) && i) | |
| 306 debug_printf("\n"); | |
| 307 if (isprint(data[i])) | |
| 308 debug_printf("%c ", data[i]); | |
| 309 else | |
| 310 debug_printf(". "); | |
| 311 } | |
| 312 debug_printf("\n"); | |
| 313 #endif | |
| 314 } | |
| 315 | |
| 316 static int yahoo_send_packet(struct yahoo_data *yd, struct yahoo_packet *pkt) | |
| 317 { | |
| 318 int pktlen = yahoo_packet_length(pkt); | |
| 319 int len = YAHOO_PACKET_HDRLEN + pktlen; | |
| 320 int ret; | |
| 321 | |
| 322 guchar *data; | |
| 323 int pos = 0; | |
| 324 | |
| 325 if (yd->fd < 0) | |
| 326 return -1; | |
| 327 | |
| 328 data = g_malloc0(len + 1); | |
| 329 | |
| 330 memcpy(data + pos, "YMSG", 4); pos += 4; | |
| 3467 | 331 pos += yahoo_put16(data + pos, YAHOO_PROTO_VER); |
| 2681 | 332 pos += yahoo_put16(data + pos, 0x0000); |
| 333 pos += yahoo_put16(data + pos, pktlen); | |
| 334 pos += yahoo_put16(data + pos, pkt->service); | |
| 335 pos += yahoo_put32(data + pos, pkt->status); | |
| 336 pos += yahoo_put32(data + pos, pkt->id); | |
| 337 | |
| 338 yahoo_packet_write(pkt, data + pos); | |
| 339 | |
| 340 yahoo_packet_dump(data, len); | |
| 341 ret = write(yd->fd, data, len); | |
| 342 g_free(data); | |
| 343 | |
| 344 return ret; | |
| 345 } | |
| 346 | |
| 347 static void yahoo_packet_free(struct yahoo_packet *pkt) | |
| 348 { | |
| 349 while (pkt->hash) { | |
| 350 struct yahoo_pair *pair = pkt->hash->data; | |
| 351 g_free(pair->value); | |
| 352 g_free(pair); | |
| 353 pkt->hash = g_slist_remove(pkt->hash, pair); | |
| 354 } | |
| 355 g_free(pkt); | |
| 356 } | |
| 357 | |
|
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
358 static void yahoo_process_status(struct gaim_connection *gc, struct yahoo_packet *pkt) |
| 2681 | 359 { |
| 360 struct yahoo_data *yd = gc->proto_data; | |
| 361 GSList *l = pkt->hash; | |
| 362 char *name = NULL; | |
| 363 int state = 0; | |
| 3019 | 364 int gamestate = 0; |
| 2681 | 365 char *msg = NULL; |
| 3019 | 366 |
| 2681 | 367 while (l) { |
| 368 struct yahoo_pair *pair = l->data; | |
| 369 | |
| 370 switch (pair->key) { | |
| 371 case 0: /* we won't actually do anything with this */ | |
| 372 break; | |
| 373 case 1: /* we don't get the full buddy list here. */ | |
|
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
374 if (!yd->logged_in) { |
|
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
375 account_online(gc); |
|
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
376 serv_finish_login(gc); |
|
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
377 g_snprintf(gc->displayname, sizeof(gc->displayname), "%s", pair->value); |
|
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
378 yd->logged_in = TRUE; |
| 2681 | 379 |
| 3147 | 380 /* this requests the list. i have a feeling that this is very evil |
| 381 * | |
| 382 * scs.yahoo.com sends you the list before this packet without it being | |
| 383 * requested | |
| 384 * | |
| 385 * do_import(gc, NULL); | |
| 386 * newpkt = yahoo_packet_new(YAHOO_SERVICE_LIST, YAHOO_STATUS_OFFLINE, 0); | |
| 387 * yahoo_send_packet(yd, newpkt); | |
| 388 * yahoo_packet_free(newpkt); | |
| 389 */ | |
| 390 | |
| 391 } | |
| 2681 | 392 break; |
| 393 case 8: /* how many online buddies we have */ | |
| 394 break; | |
| 395 case 7: /* the current buddy */ | |
| 396 name = pair->value; | |
| 397 break; | |
| 398 case 10: /* state */ | |
| 399 state = strtol(pair->value, NULL, 10); | |
| 400 break; | |
| 401 case 19: /* custom message */ | |
| 402 msg = pair->value; | |
| 403 break; | |
| 404 case 11: /* i didn't know what this was in the old protocol either */ | |
| 405 break; | |
| 406 case 17: /* in chat? */ | |
| 407 break; | |
|
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
408 case 13: /* in pager? */ |
|
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
409 if (pkt->service == YAHOO_SERVICE_LOGOFF || |
|
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
410 strtol(pair->value, NULL, 10) == 0) { |
| 4732 | 411 serv_got_update(gc, name, 0, 0, 0, 0, 0); |
|
2807
f01e6a425136
[gaim-migrate @ 2820]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2805
diff
changeset
|
412 break; |
|
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
413 } |
| 3019 | 414 if (g_hash_table_lookup(yd->games, name)) |
| 415 gamestate = YAHOO_STATUS_GAME; | |
|
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
416 if (state == YAHOO_STATUS_CUSTOM) { |
|
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
417 gpointer val = g_hash_table_lookup(yd->hash, name); |
|
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
418 if (val) { |
|
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
419 g_free(val); |
|
2873
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
420 g_hash_table_insert(yd->hash, name, |
|
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
421 msg ? g_strdup(msg) : g_malloc0(1)); |
|
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
422 } else |
|
2873
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
423 g_hash_table_insert(yd->hash, g_strdup(name), |
|
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
424 msg ? g_strdup(msg) : g_malloc0(1)); |
|
2771
450f4f9d2f23
[gaim-migrate @ 2784]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2741
diff
changeset
|
425 } |
| 4777 | 426 if (state == YAHOO_STATUS_AVAILABLE) |
| 427 serv_got_update(gc, name, 1, 0, 0, 0, gamestate); | |
| 428 else | |
| 429 serv_got_update(gc, name, 1, 0, 0, 0, (state << 2) | UC_UNAVAILABLE | gamestate); | |
|
2771
450f4f9d2f23
[gaim-migrate @ 2784]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2741
diff
changeset
|
430 break; |
|
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
431 case 60: /* no clue */ |
|
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
432 break; |
| 2979 | 433 case 16: /* Custom error message */ |
| 3427 | 434 do_error_dialog(pair->value, NULL, GAIM_ERROR); |
| 2951 | 435 break; |
| 2681 | 436 default: |
|
2805
9b3c7d2a6e9a
[gaim-migrate @ 2818]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2795
diff
changeset
|
437 debug_printf("unknown status key %d\n", pair->key); |
| 2681 | 438 break; |
| 439 } | |
| 440 | |
| 441 l = l->next; | |
| 442 } | |
| 443 } | |
| 444 | |
| 445 static void yahoo_process_list(struct gaim_connection *gc, struct yahoo_packet *pkt) | |
| 446 { | |
| 447 GSList *l = pkt->hash; | |
| 448 gboolean export = FALSE; | |
| 4775 | 449 struct buddy *b; |
| 450 struct group *g; | |
| 2681 | 451 |
| 452 while (l) { | |
| 453 char **lines; | |
| 454 char **split; | |
| 455 char **buddies; | |
| 456 char **tmp, **bud; | |
| 457 | |
| 458 struct yahoo_pair *pair = l->data; | |
| 459 l = l->next; | |
| 460 | |
| 461 if (pair->key != 87) | |
| 462 continue; | |
| 463 | |
| 464 lines = g_strsplit(pair->value, "\n", -1); | |
| 465 for (tmp = lines; *tmp; tmp++) { | |
| 466 split = g_strsplit(*tmp, ":", 2); | |
|
2697
7759f914a009
[gaim-migrate @ 2710]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2688
diff
changeset
|
467 if (!split) |
|
7759f914a009
[gaim-migrate @ 2710]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2688
diff
changeset
|
468 continue; |
|
2702
94b4271b9567
[gaim-migrate @ 2715]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2697
diff
changeset
|
469 if (!split[0] || !split[1]) { |
|
2697
7759f914a009
[gaim-migrate @ 2710]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2688
diff
changeset
|
470 g_strfreev(split); |
|
7759f914a009
[gaim-migrate @ 2710]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2688
diff
changeset
|
471 continue; |
|
7759f914a009
[gaim-migrate @ 2710]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2688
diff
changeset
|
472 } |
| 2681 | 473 buddies = g_strsplit(split[1], ",", -1); |
|
2697
7759f914a009
[gaim-migrate @ 2710]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2688
diff
changeset
|
474 for (bud = buddies; bud && *bud; bud++) |
| 4775 | 475 if (!(b = gaim_find_buddy(gc->account, *bud))) { |
| 476 if (!(g = gaim_find_group(split[0]))) { | |
| 477 g = gaim_group_new(split[0]); | |
| 478 gaim_blist_add_group(g, NULL); | |
| 479 } | |
| 480 b = gaim_buddy_new(gc->account, *bud, NULL); | |
| 481 gaim_blist_add_buddy(b, g, NULL); | |
| 2681 | 482 export = TRUE; |
| 483 } | |
| 484 g_strfreev(buddies); | |
| 485 g_strfreev(split); | |
| 486 } | |
| 487 g_strfreev(lines); | |
| 488 } | |
| 489 | |
| 490 if (export) | |
| 4349 | 491 gaim_blist_save(); |
| 2681 | 492 } |
| 493 | |
| 3019 | 494 static void yahoo_process_notify(struct gaim_connection *gc, struct yahoo_packet *pkt) |
| 2993 | 495 { |
| 496 char *msg = NULL; | |
| 497 char *from = NULL; | |
| 3019 | 498 char *stat = NULL; |
| 499 char *game = NULL; | |
| 2993 | 500 GSList *l = pkt->hash; |
| 3019 | 501 struct yahoo_data *yd = (struct yahoo_data*) gc->proto_data; |
| 2993 | 502 while (l) { |
| 503 struct yahoo_pair *pair = l->data; | |
| 504 if (pair->key == 4) | |
| 505 from = pair->value; | |
| 506 if (pair->key == 49) | |
| 507 msg = pair->value; | |
| 3001 | 508 if (pair->key == 13) |
| 3019 | 509 stat = pair->value; |
| 510 if (pair->key == 14) | |
| 511 game = pair->value; | |
| 2993 | 512 l = l->next; |
| 513 } | |
| 3640 | 514 |
| 515 if (!msg) | |
| 516 return; | |
| 3019 | 517 |
| 4793 | 518 if (!g_ascii_strncasecmp(msg, "TYPING", strlen("TYPING"))) { |
| 3019 | 519 if (*stat == '1') |
| 3768 | 520 serv_got_typing(gc, from, 0, TYPING); |
| 3019 | 521 else |
| 522 serv_got_typing_stopped(gc, from); | |
| 4793 | 523 } else if (!g_ascii_strncasecmp(msg, "GAME", strlen("GAME"))) { |
| 4687 | 524 struct buddy *bud = gaim_find_buddy(gc->account, from); |
| 3019 | 525 void *free1=NULL, *free2=NULL; |
|
4201
511c2b63caa4
[gaim-migrate @ 4432]
Christian Hammond <chipx86@chipx86.com>
parents:
4115
diff
changeset
|
526 if (!bud) |
|
511c2b63caa4
[gaim-migrate @ 4432]
Christian Hammond <chipx86@chipx86.com>
parents:
4115
diff
changeset
|
527 debug_printf("%s is playing a game, and doesn't want you to know.\n", from); |
| 3019 | 528 if (*stat == '1') { |
| 529 if (g_hash_table_lookup_extended (yd->games, from, free1, free2)) { | |
| 530 g_free(free1); | |
| 531 g_free(free2); | |
| 532 } | |
| 533 g_hash_table_insert (yd->games, g_strdup(from), g_strdup(game)); | |
| 3020 | 534 if (bud) |
| 4732 | 535 serv_got_update(gc, from, 1, 0, 0, 0, bud->uc | YAHOO_STATUS_GAME); |
| 3019 | 536 } else { |
| 537 if (g_hash_table_lookup_extended (yd->games, from, free1, free2)) { | |
| 538 g_free(free1); | |
| 539 g_free(free2); | |
| 540 g_hash_table_remove (yd->games, from); | |
| 541 } | |
| 3020 | 542 if (bud) |
| 4732 | 543 serv_got_update(gc, from, 1, 0, 0, 0, bud->uc & ~YAHOO_STATUS_GAME); |
| 3019 | 544 } |
| 545 } | |
| 2993 | 546 } |
| 547 | |
| 2681 | 548 static void yahoo_process_message(struct gaim_connection *gc, struct yahoo_packet *pkt) |
| 549 { | |
| 550 char *msg = NULL; | |
| 551 char *from = NULL; | |
| 552 time_t tm = time(NULL); | |
| 553 GSList *l = pkt->hash; | |
| 3021 | 554 |
| 2681 | 555 while (l) { |
| 556 struct yahoo_pair *pair = l->data; | |
| 557 if (pair->key == 4) | |
| 558 from = pair->value; | |
| 559 if (pair->key == 14) | |
| 560 msg = pair->value; | |
| 561 if (pair->key == 15) | |
| 562 tm = strtol(pair->value, NULL, 10); | |
| 563 l = l->next; | |
| 564 } | |
| 565 | |
| 3021 | 566 if (pkt->status <= 1 || pkt->status == 5) { |
|
2715
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
567 char *m; |
|
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
568 int i, j; |
| 2681 | 569 strip_linefeed(msg); |
|
2715
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
570 m = msg; |
|
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
571 for (i = 0, j = 0; m[i]; i++) { |
|
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
572 if (m[i] == 033) { |
|
2813
bda5b89ba2f9
[gaim-migrate @ 2826]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2807
diff
changeset
|
573 while (m[i] && (m[i] != 'm')) |
|
2715
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
574 i++; |
|
2813
bda5b89ba2f9
[gaim-migrate @ 2826]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2807
diff
changeset
|
575 if (!m[i]) |
|
bda5b89ba2f9
[gaim-migrate @ 2826]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2807
diff
changeset
|
576 i--; |
|
2715
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
577 continue; |
|
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
578 } |
|
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
579 msg[j++] = m[i]; |
|
e901fd3ebbad
[gaim-migrate @ 2728]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2708
diff
changeset
|
580 } |
|
2813
bda5b89ba2f9
[gaim-migrate @ 2826]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2807
diff
changeset
|
581 msg[j] = 0; |
| 3642 | 582 serv_got_im(gc, from, g_strdup(msg), 0, tm, -1); |
| 2681 | 583 } else if (pkt->status == 2) { |
| 3427 | 584 do_error_dialog(_("Your Yahoo! message did not get sent."), NULL, GAIM_ERROR); |
| 2681 | 585 } |
| 586 } | |
| 587 | |
| 588 | |
| 589 static void yahoo_process_contact(struct gaim_connection *gc, struct yahoo_packet *pkt) | |
| 590 { | |
|
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
591 struct yahoo_data *yd = gc->proto_data; |
| 2681 | 592 char *id = NULL; |
| 593 char *who = NULL; | |
| 594 char *msg = NULL; | |
|
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
595 char *name = NULL; |
|
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
596 int state = YAHOO_STATUS_AVAILABLE; |
|
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
597 int online = FALSE; |
|
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
598 |
| 2681 | 599 GSList *l = pkt->hash; |
| 600 | |
| 601 while (l) { | |
| 602 struct yahoo_pair *pair = l->data; | |
| 603 if (pair->key == 1) | |
| 604 id = pair->value; | |
| 605 else if (pair->key == 3) | |
| 606 who = pair->value; | |
| 607 else if (pair->key == 14) | |
| 608 msg = pair->value; | |
|
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
609 else if (pair->key == 7) |
|
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
610 name = pair->value; |
|
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
611 else if (pair->key == 10) |
|
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
612 state = strtol(pair->value, NULL, 10); |
|
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
613 else if (pair->key == 13) |
|
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
614 online = strtol(pair->value, NULL, 10); |
| 2681 | 615 l = l->next; |
| 616 } | |
| 617 | |
|
2682
db2b0b733732
[gaim-migrate @ 2695]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2681
diff
changeset
|
618 if (id) |
|
db2b0b733732
[gaim-migrate @ 2695]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2681
diff
changeset
|
619 show_got_added(gc, id, who, NULL, msg); |
|
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
620 if (name) { |
|
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
621 if (state == YAHOO_STATUS_AVAILABLE) |
| 4732 | 622 serv_got_update(gc, name, 1, 0, 0, 0, 0); |
|
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
623 else if (state == YAHOO_STATUS_IDLE) |
| 4732 | 624 serv_got_update(gc, name, 1, 0, 0, time(NULL) - 600, (state << 2)); |
|
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
625 else |
| 4732 | 626 serv_got_update(gc, name, 1, 0, 0, 0, (state << 2) | UC_UNAVAILABLE); |
|
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
627 if (state == YAHOO_STATUS_CUSTOM) { |
|
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
628 gpointer val = g_hash_table_lookup(yd->hash, name); |
|
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
629 if (val) { |
|
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
630 g_free(val); |
|
2873
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
631 g_hash_table_insert(yd->hash, name, |
|
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
632 msg ? g_strdup(msg) : g_malloc0(1)); |
|
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
633 } else |
|
2873
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
634 g_hash_table_insert(yd->hash, g_strdup(name), |
|
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
635 msg ? g_strdup(msg) : g_malloc0(1)); |
|
2683
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
636 } |
|
4836eae8dd8c
[gaim-migrate @ 2696]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2682
diff
changeset
|
637 } |
| 2681 | 638 } |
| 639 | |
| 640 static void yahoo_process_mail(struct gaim_connection *gc, struct yahoo_packet *pkt) | |
| 641 { | |
| 642 char *who = NULL; | |
| 643 char *email = NULL; | |
| 644 char *subj = NULL; | |
| 645 int count = 0; | |
| 646 GSList *l = pkt->hash; | |
| 647 | |
| 648 while (l) { | |
| 649 struct yahoo_pair *pair = l->data; | |
| 650 if (pair->key == 9) | |
| 651 count = strtol(pair->value, NULL, 10); | |
| 652 else if (pair->key == 43) | |
| 653 who = pair->value; | |
| 654 else if (pair->key == 42) | |
| 655 email = pair->value; | |
| 656 else if (pair->key == 18) | |
| 657 subj = pair->value; | |
| 658 l = l->next; | |
| 659 } | |
| 660 | |
| 4001 | 661 if (who && subj && email && *email) { |
|
2850
cbe6a1e63a72
[gaim-migrate @ 2863]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2813
diff
changeset
|
662 char *from = g_strdup_printf("%s (%s)", who, email); |
|
cbe6a1e63a72
[gaim-migrate @ 2863]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2813
diff
changeset
|
663 connection_has_mail(gc, -1, from, subj, "http://mail.yahoo.com/"); |
|
cbe6a1e63a72
[gaim-migrate @ 2863]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2813
diff
changeset
|
664 g_free(from); |
| 4001 | 665 } else if (count > 0) |
|
2850
cbe6a1e63a72
[gaim-migrate @ 2863]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2813
diff
changeset
|
666 connection_has_mail(gc, count, NULL, NULL, "http://mail.yahoo.com/"); |
| 2681 | 667 } |
| 3147 | 668 /* This is the y64 alphabet... it's like base64, but has a . and a _ */ |
| 669 char base64digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._"; | |
| 670 | |
| 671 /* This is taken from Sylpheed by Hiroyuki Yamamoto. We have our own tobase64 function | |
| 672 * in util.c, but it has a bug I don't feel like finding right now ;) */ | |
| 673 void to_y64(unsigned char *out, const unsigned char *in, int inlen) | |
| 674 /* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */ | |
| 675 { | |
| 676 for (; inlen >= 3; inlen -= 3) | |
| 677 { | |
| 678 *out++ = base64digits[in[0] >> 2]; | |
| 679 *out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)]; | |
| 680 *out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; | |
| 681 *out++ = base64digits[in[2] & 0x3f]; | |
| 682 in += 3; | |
| 683 } | |
| 684 if (inlen > 0) | |
| 685 { | |
| 686 unsigned char fragment; | |
| 687 | |
| 688 *out++ = base64digits[in[0] >> 2]; | |
| 689 fragment = (in[0] << 4) & 0x30; | |
| 690 if (inlen > 1) | |
| 691 fragment |= in[1] >> 4; | |
| 692 *out++ = base64digits[fragment]; | |
| 693 *out++ = (inlen < 2) ? '-' : base64digits[(in[1] << 2) & 0x3c]; | |
| 694 *out++ = '-'; | |
| 695 } | |
| 696 *out = '\0'; | |
| 697 } | |
| 698 | |
| 699 static void yahoo_process_auth(struct gaim_connection *gc, struct yahoo_packet *pkt) | |
| 700 { | |
| 701 char *seed = NULL; | |
| 702 char *sn = NULL; | |
| 703 GSList *l = pkt->hash; | |
| 704 struct yahoo_data *yd = gc->proto_data; | |
| 705 | |
| 706 while (l) { | |
| 707 struct yahoo_pair *pair = l->data; | |
| 708 if (pair->key == 94) | |
| 709 seed = pair->value; | |
| 710 if (pair->key == 1) | |
| 711 sn = pair->value; | |
| 712 l = l->next; | |
| 713 } | |
| 714 | |
| 715 if (seed) { | |
| 716 struct yahoo_packet *pack; | |
| 717 | |
| 718 /* So, Yahoo has stopped supporting its older clients in India, and undoubtedly | |
| 719 * will soon do so in the rest of the world. | |
| 720 * | |
| 721 * The new clients use this authentication method. I warn you in advance, it's | |
| 722 * bizzare, convoluted, inordinately complicated. It's also no more secure than | |
| 723 * crypt() was. The only purpose this scheme could serve is to prevent third | |
| 724 * part clients from connecting to their servers. | |
| 725 * | |
| 726 * Sorry, Yahoo. | |
| 727 */ | |
| 728 | |
| 729 md5_byte_t result[16]; | |
| 730 md5_state_t ctx; | |
| 731 char *crypt_result; | |
| 732 char *password_hash = g_malloc(25); | |
| 733 char *crypt_hash = g_malloc(25); | |
| 734 char *hash_string_p = g_malloc(50 + strlen(sn)); | |
| 735 char *hash_string_c = g_malloc(50 + strlen(sn)); | |
| 736 | |
| 737 char checksum; | |
| 738 | |
| 3157 | 739 int sv; |
| 3147 | 740 |
| 741 char *result6 = g_malloc(25); | |
| 742 char *result96 = g_malloc(25); | |
| 743 | |
| 744 sv = seed[15]; | |
| 3157 | 745 sv = sv % 8; |
| 3147 | 746 |
| 747 md5_init(&ctx); | |
| 748 md5_append(&ctx, gc->password, strlen(gc->password)); | |
| 749 md5_finish(&ctx, result); | |
| 750 to_y64(password_hash, result, 16); | |
| 751 | |
| 752 md5_init(&ctx); | |
| 753 crypt_result = yahoo_crypt(gc->password, "$1$_2S43d5f$"); | |
| 754 md5_append(&ctx, crypt_result, strlen(crypt_result)); | |
| 755 md5_finish(&ctx, result); | |
| 756 to_y64(crypt_hash, result, 16); | |
| 3157 | 757 |
| 758 switch (sv) { | |
| 3147 | 759 case 1: |
| 760 case 6: | |
| 3157 | 761 checksum = seed[seed[9] % 16]; |
| 3147 | 762 g_snprintf(hash_string_p, strlen(sn) + 50, |
| 3157 | 763 "%c%s%s%s", checksum, gc->username, seed, password_hash); |
| 764 g_snprintf(hash_string_c, strlen(sn) + 50, | |
| 3147 | 765 "%c%s%s%s", checksum, gc->username, seed, crypt_hash); |
| 766 break; | |
| 767 case 2: | |
| 768 case 7: | |
| 3157 | 769 checksum = seed[seed[15] % 16]; |
| 3147 | 770 g_snprintf(hash_string_p, strlen(sn) + 50, |
| 3157 | 771 "%c%s%s%s", checksum, seed, password_hash, gc->username); |
| 772 g_snprintf(hash_string_c, strlen(sn) + 50, | |
| 773 "%c%s%s%s", checksum, seed, crypt_hash, gc->username); | |
| 774 break; | |
| 3147 | 775 case 3: |
| 3157 | 776 checksum = seed[seed[1] % 16]; |
| 3147 | 777 g_snprintf(hash_string_p, strlen(sn) + 50, |
| 3157 | 778 "%c%s%s%s", checksum, gc->username, password_hash, seed); |
| 779 g_snprintf(hash_string_c, strlen(sn) + 50, | |
| 780 "%c%s%s%s", checksum, gc->username, crypt_hash, seed); | |
| 781 break; | |
| 782 case 4: | |
| 783 checksum = seed[seed[3] % 16]; | |
| 784 g_snprintf(hash_string_p, strlen(sn) + 50, | |
| 785 "%c%s%s%s", checksum, password_hash, seed, gc->username); | |
| 3147 | 786 g_snprintf(hash_string_c, strlen(sn) + 50, |
| 3157 | 787 "%c%s%s%s", checksum, crypt_hash, seed, gc->username); |
| 788 break; | |
| 3147 | 789 case 0: |
| 790 case 5: | |
| 3157 | 791 checksum = seed[seed[7] % 16]; |
| 3147 | 792 g_snprintf(hash_string_p, strlen(sn) + 50, |
| 3157 | 793 "%c%s%s%s", checksum, password_hash, gc->username, seed); |
| 794 g_snprintf(hash_string_c, strlen(sn) + 50, | |
| 3147 | 795 "%c%s%s%s", checksum, crypt_hash, gc->username, seed); |
| 3157 | 796 break; |
| 3147 | 797 } |
| 3157 | 798 |
| 3147 | 799 md5_init(&ctx); |
| 3157 | 800 md5_append(&ctx, hash_string_p, strlen(hash_string_p)); |
| 3147 | 801 md5_finish(&ctx, result); |
| 802 to_y64(result6, result, 16); | |
| 803 | |
| 804 md5_init(&ctx); | |
| 805 md5_append(&ctx, hash_string_c, strlen(hash_string_c)); | |
| 806 md5_finish(&ctx, result); | |
| 807 to_y64(result96, result, 16); | |
| 808 | |
| 809 pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, YAHOO_STATUS_AVAILABLE, 0); | |
| 810 yahoo_packet_hash(pack, 0, gc->username); | |
| 811 yahoo_packet_hash(pack, 6, result6); | |
| 812 yahoo_packet_hash(pack, 96, result96); | |
| 813 yahoo_packet_hash(pack, 1, gc->username); | |
| 814 | |
| 815 yahoo_send_packet(yd, pack); | |
| 816 | |
| 3523 | 817 g_free(result6); |
| 818 g_free(result96); | |
| 3147 | 819 g_free(password_hash); |
| 820 g_free(crypt_hash); | |
| 821 g_free(hash_string_p); | |
| 822 g_free(hash_string_c); | |
| 823 | |
| 824 yahoo_packet_free(pack); | |
| 825 } | |
| 826 } | |
| 2681 | 827 |
| 828 static void yahoo_packet_process(struct gaim_connection *gc, struct yahoo_packet *pkt) | |
| 829 { | |
| 830 switch (pkt->service) | |
| 831 { | |
| 832 case YAHOO_SERVICE_LOGON: | |
|
2771
450f4f9d2f23
[gaim-migrate @ 2784]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2741
diff
changeset
|
833 case YAHOO_SERVICE_LOGOFF: |
| 2681 | 834 case YAHOO_SERVICE_ISAWAY: |
|
2737
f61c1f3a6afa
[gaim-migrate @ 2750]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2724
diff
changeset
|
835 case YAHOO_SERVICE_ISBACK: |
| 3019 | 836 case YAHOO_SERVICE_GAMELOGON: |
| 837 case YAHOO_SERVICE_GAMELOGOFF: | |
| 2681 | 838 yahoo_process_status(gc, pkt); |
| 839 break; | |
| 3019 | 840 case YAHOO_SERVICE_NOTIFY: |
| 841 yahoo_process_notify(gc, pkt); | |
| 2993 | 842 break; |
| 2681 | 843 case YAHOO_SERVICE_MESSAGE: |
|
2786
318f846120e2
[gaim-migrate @ 2799]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2772
diff
changeset
|
844 case YAHOO_SERVICE_GAMEMSG: |
| 2681 | 845 yahoo_process_message(gc, pkt); |
| 846 break; | |
| 847 case YAHOO_SERVICE_NEWMAIL: | |
| 848 yahoo_process_mail(gc, pkt); | |
| 849 break; | |
| 850 case YAHOO_SERVICE_NEWCONTACT: | |
| 851 yahoo_process_contact(gc, pkt); | |
| 852 break; | |
| 853 case YAHOO_SERVICE_LIST: | |
| 854 yahoo_process_list(gc, pkt); | |
| 855 break; | |
| 3147 | 856 case YAHOO_SERVICE_AUTH: |
| 857 yahoo_process_auth(gc, pkt); | |
| 858 break; | |
| 2681 | 859 default: |
|
2741
38cb5fa48bec
[gaim-migrate @ 2754]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2737
diff
changeset
|
860 debug_printf("unhandled service 0x%02x\n", pkt->service); |
| 2681 | 861 break; |
| 862 } | |
| 863 } | |
| 864 | |
| 865 static void yahoo_pending(gpointer data, gint source, GaimInputCondition cond) | |
| 866 { | |
| 867 struct gaim_connection *gc = data; | |
| 868 struct yahoo_data *yd = gc->proto_data; | |
| 869 char buf[1024]; | |
| 870 int len; | |
| 871 | |
| 872 len = read(yd->fd, buf, sizeof(buf)); | |
| 873 | |
| 874 if (len <= 0) { | |
| 3074 | 875 hide_login_progress_error(gc, "Unable to read"); |
| 2681 | 876 signoff(gc); |
| 877 return; | |
| 878 } | |
| 879 | |
| 880 yd->rxqueue = g_realloc(yd->rxqueue, len + yd->rxlen); | |
| 881 memcpy(yd->rxqueue + yd->rxlen, buf, len); | |
| 882 yd->rxlen += len; | |
| 883 | |
| 884 while (1) { | |
| 885 struct yahoo_packet *pkt; | |
| 886 int pos = 0; | |
| 887 int pktlen; | |
| 888 | |
| 889 if (yd->rxlen < YAHOO_PACKET_HDRLEN) | |
| 890 return; | |
| 891 | |
| 892 pos += 4; /* YMSG */ | |
| 893 pos += 2; | |
| 894 pos += 2; | |
| 895 | |
| 896 pktlen = yahoo_get16(yd->rxqueue + pos); pos += 2; | |
| 897 debug_printf("%d bytes to read, rxlen is %d\n", pktlen, yd->rxlen); | |
| 898 | |
| 899 if (yd->rxlen < (YAHOO_PACKET_HDRLEN + pktlen)) | |
| 900 return; | |
| 901 | |
| 902 yahoo_packet_dump(yd->rxqueue, YAHOO_PACKET_HDRLEN + pktlen); | |
| 903 | |
| 904 pkt = yahoo_packet_new(0, 0, 0); | |
| 905 | |
| 906 pkt->service = yahoo_get16(yd->rxqueue + pos); pos += 2; | |
| 3021 | 907 pkt->status = yahoo_get32(yd->rxqueue + pos); pos += 4; |
|
2741
38cb5fa48bec
[gaim-migrate @ 2754]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2737
diff
changeset
|
908 debug_printf("Yahoo Service: 0x%02x Status: %d\n", pkt->service, pkt->status); |
| 2681 | 909 pkt->id = yahoo_get32(yd->rxqueue + pos); pos += 4; |
| 910 | |
| 911 yahoo_packet_read(pkt, yd->rxqueue + pos, pktlen); | |
| 912 | |
| 913 yd->rxlen -= YAHOO_PACKET_HDRLEN + pktlen; | |
| 914 if (yd->rxlen) { | |
| 915 char *tmp = g_memdup(yd->rxqueue + YAHOO_PACKET_HDRLEN + pktlen, yd->rxlen); | |
| 916 g_free(yd->rxqueue); | |
| 917 yd->rxqueue = tmp; | |
| 918 } else { | |
| 919 g_free(yd->rxqueue); | |
| 920 yd->rxqueue = NULL; | |
| 921 } | |
| 922 | |
| 923 yahoo_packet_process(gc, pkt); | |
| 924 | |
| 925 yahoo_packet_free(pkt); | |
| 926 } | |
| 927 } | |
| 928 | |
| 929 static void yahoo_got_connected(gpointer data, gint source, GaimInputCondition cond) | |
| 930 { | |
| 931 struct gaim_connection *gc = data; | |
| 932 struct yahoo_data *yd; | |
| 933 struct yahoo_packet *pkt; | |
| 934 | |
| 935 if (!g_slist_find(connections, gc)) { | |
| 936 close(source); | |
| 937 return; | |
| 938 } | |
| 939 | |
| 940 if (source < 0) { | |
| 941 hide_login_progress(gc, "Unable to connect"); | |
| 942 signoff(gc); | |
| 943 return; | |
| 944 } | |
| 945 | |
| 946 yd = gc->proto_data; | |
| 947 yd->fd = source; | |
| 948 | |
| 3147 | 949 pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YAHOO_STATUS_AVAILABLE, 0); |
| 2681 | 950 |
| 951 yahoo_packet_hash(pkt, 1, gc->username); | |
| 952 yahoo_send_packet(yd, pkt); | |
| 953 | |
| 954 yahoo_packet_free(pkt); | |
| 955 | |
| 956 gc->inpa = gaim_input_add(yd->fd, GAIM_INPUT_READ, yahoo_pending, gc); | |
| 957 } | |
| 958 | |
| 4491 | 959 static void yahoo_login(struct gaim_account *account) { |
| 960 struct gaim_connection *gc = new_gaim_conn(account); | |
| 2681 | 961 struct yahoo_data *yd = gc->proto_data = g_new0(struct yahoo_data, 1); |
| 962 | |
| 4834 | 963 set_login_progress(gc, 1, _("Connecting")); |
| 2681 | 964 |
| 965 yd->fd = -1; | |
| 966 yd->hash = g_hash_table_new(g_str_hash, g_str_equal); | |
| 3019 | 967 yd->games = g_hash_table_new(g_str_hash, g_str_equal); |
| 2681 | 968 |
| 3193 | 969 |
| 4793 | 970 if (!g_ascii_strncasecmp(account->proto_opt[USEROPT_PAGERHOST], "cs.yahoo.com", strlen("cs.yahoo.com"))) { |
| 3193 | 971 /* Figured out the new auth method -- cs.yahoo.com likes to disconnect on buddy remove and add now */ |
| 2951 | 972 debug_printf("Setting new Yahoo! server.\n"); |
| 4491 | 973 g_snprintf(account->proto_opt[USEROPT_PAGERHOST], strlen("scs.yahoo.com") + 1, "scs.yahoo.com"); |
| 2951 | 974 save_prefs(); |
| 975 } | |
| 4491 | 976 |
| 977 | |
| 4634 | 978 if (proxy_connect(account, account->proto_opt[USEROPT_PAGERHOST][0] ? |
| 4491 | 979 account->proto_opt[USEROPT_PAGERHOST] : YAHOO_PAGER_HOST, |
| 980 account->proto_opt[USEROPT_PAGERPORT][0] ? | |
| 981 atoi(account->proto_opt[USEROPT_PAGERPORT]) : YAHOO_PAGER_PORT, | |
| 982 yahoo_got_connected, gc) != 0) { | |
| 2681 | 983 hide_login_progress(gc, "Connection problem"); |
| 984 signoff(gc); | |
| 985 return; | |
| 986 } | |
| 987 | |
| 988 } | |
| 989 | |
| 990 static gboolean yahoo_destroy_hash(gpointer key, gpointer val, gpointer data) | |
| 991 { | |
| 992 g_free(key); | |
| 993 g_free(val); | |
| 994 return TRUE; | |
| 995 } | |
| 996 | |
| 997 static void yahoo_close(struct gaim_connection *gc) { | |
| 998 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
| 999 g_hash_table_foreach_remove(yd->hash, yahoo_destroy_hash, NULL); | |
| 1000 g_hash_table_destroy(yd->hash); | |
| 3019 | 1001 g_hash_table_foreach_remove(yd->games, yahoo_destroy_hash, NULL); |
| 1002 g_hash_table_destroy(yd->games); | |
| 2681 | 1003 if (yd->fd >= 0) |
| 1004 close(yd->fd); | |
|
3720
34c95669952f
[gaim-migrate @ 3853]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3642
diff
changeset
|
1005 |
| 2681 | 1006 if (yd->rxqueue) |
| 1007 g_free(yd->rxqueue); | |
|
2687
2d544f48146d
[gaim-migrate @ 2700]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2686
diff
changeset
|
1008 yd->rxlen = 0; |
| 2681 | 1009 if (gc->inpa) |
| 1010 gaim_input_remove(gc->inpa); | |
| 1011 g_free(yd); | |
| 1012 } | |
| 1013 | |
| 4687 | 1014 static const char *yahoo_list_icon(struct gaim_account *a, struct buddy *b) |
| 2681 | 1015 { |
| 4687 | 1016 return "yahoo"; |
| 2681 | 1017 } |
| 4687 | 1018 /* |
| 1019 if ((uc >> 2) == YAHOO_STATUS_IDLE) | |
| 1020 return status_idle_xpm; | |
| 1021 else if (uc & UC_UNAVAILABLE) | |
| 1022 return status_away_xpm; | |
| 1023 else if (uc & YAHOO_STATUS_GAME) | |
| 1024 return status_game_xpm; | |
| 1025 return status_here_xpm; | |
| 1026 }*/ | |
| 2681 | 1027 |
| 1028 static char *yahoo_get_status_string(enum yahoo_status a) | |
| 1029 { | |
| 1030 switch (a) { | |
| 1031 case YAHOO_STATUS_BRB: | |
| 4596 | 1032 return _("Be Right Back"); |
| 2681 | 1033 case YAHOO_STATUS_BUSY: |
| 4596 | 1034 return _("Busy"); |
| 2681 | 1035 case YAHOO_STATUS_NOTATHOME: |
| 4596 | 1036 return _("Not At Home"); |
| 2681 | 1037 case YAHOO_STATUS_NOTATDESK: |
| 4596 | 1038 return _("Not At Desk"); |
| 2681 | 1039 case YAHOO_STATUS_NOTINOFFICE: |
| 4596 | 1040 return _("Not In Office"); |
| 2681 | 1041 case YAHOO_STATUS_ONPHONE: |
| 4606 | 1042 return _("On The Phone"); |
| 2681 | 1043 case YAHOO_STATUS_ONVACATION: |
| 4596 | 1044 return _("On Vacation"); |
| 2681 | 1045 case YAHOO_STATUS_OUTTOLUNCH: |
| 4596 | 1046 return _("Out To Lunch"); |
| 2681 | 1047 case YAHOO_STATUS_STEPPEDOUT: |
| 4596 | 1048 return _("Stepped Out"); |
|
2873
26be84883f91
[gaim-migrate @ 2886]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2856
diff
changeset
|
1049 case YAHOO_STATUS_INVISIBLE: |
| 4596 | 1050 return _("Invisible"); |
| 4730 | 1051 case YAHOO_STATUS_IDLE: |
| 1052 return _("Idle"); | |
|
2879
5fc5123b7098
[gaim-migrate @ 2892]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2878
diff
changeset
|
1053 default: |
| 4596 | 1054 return _("Online"); |
| 2681 | 1055 } |
| 1056 } | |
| 1057 | |
| 3019 | 1058 static void yahoo_game(struct gaim_connection *gc, char *name) { |
| 1059 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
| 1060 char *game = g_hash_table_lookup(yd->games, name); | |
| 1061 char *t; | |
| 1062 char url[256]; | |
| 1063 | |
| 1064 if (!game) | |
| 1065 return; | |
| 1066 t = game = g_strdup(strstr(game, "ante?room=")); | |
| 1067 while (*t != '\t') | |
| 1068 t++; | |
| 1069 *t = 0; | |
| 1070 g_snprintf(url, sizeof url, "http://games.yahoo.com/games/%s", game); | |
| 1071 open_url(NULL, url); | |
| 1072 g_free(game); | |
| 1073 } | |
| 4722 | 1074 |
| 4732 | 1075 static char *yahoo_status_text(struct buddy *b) |
| 4722 | 1076 { |
| 1077 struct yahoo_data *yd = (struct yahoo_data*)b->account->gc->proto_data; | |
| 4730 | 1078 if (b->uc & UC_UNAVAILABLE) { |
| 4732 | 1079 if ((b->uc >> 2) != YAHOO_STATUS_CUSTOM) |
| 1080 return g_strdup(yahoo_get_status_string(b->uc >> 2)); | |
| 4777 | 1081 else { |
| 1082 char *stripped = strip_html(g_hash_table_lookup(yd->hash, b->name)); | |
| 1083 if(stripped) { | |
| 1084 char *ret = g_markup_escape_text(stripped, strlen(stripped)); | |
| 1085 g_free(stripped); | |
| 1086 return ret; | |
| 1087 } | |
| 1088 } | |
| 4722 | 1089 } |
| 4729 | 1090 return NULL; |
| 4722 | 1091 } |
| 1092 | |
| 4724 | 1093 static char *yahoo_tooltip_text(struct buddy *b) |
| 1094 { | |
| 1095 struct yahoo_data *yd = (struct yahoo_data*)b->account->gc->proto_data; | |
| 4730 | 1096 if (b->uc & UC_UNAVAILABLE) { |
| 4745 | 1097 char *status; |
| 1098 char *ret; | |
| 4731 | 1099 if ((b->uc >> 2) != YAHOO_STATUS_CUSTOM) |
| 4745 | 1100 status = g_strdup(yahoo_get_status_string(b->uc >> 2)); |
| 4724 | 1101 else |
| 4745 | 1102 status = strip_html(g_hash_table_lookup(yd->hash, b->name)); |
| 1103 if(status) { | |
| 4777 | 1104 char *escaped = g_markup_escape_text(status, strlen(status)); |
| 1105 ret = g_strdup_printf(_("<b>Status:</b> %s"), escaped); | |
| 4745 | 1106 g_free(status); |
| 4777 | 1107 g_free(escaped); |
| 4745 | 1108 return ret; |
| 1109 } | |
| 4724 | 1110 } |
| 4729 | 1111 return NULL; |
| 1112 } | |
| 1113 | |
| 2681 | 1114 static GList *yahoo_buddy_menu(struct gaim_connection *gc, char *who) |
| 1115 { | |
| 1116 GList *m = NULL; | |
| 1117 struct proto_buddy_menu *pbm; | |
| 1118 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
| 4687 | 1119 struct buddy *b = gaim_find_buddy(gc->account, who); /* this should never be null. if it is, |
| 2681 | 1120 segfault and get the bug report. */ |
| 3019 | 1121 static char buf2[1024]; |
| 4722 | 1122 |
| 3019 | 1123 if (b->uc | YAHOO_STATUS_GAME) { |
| 1124 char *game = g_hash_table_lookup(yd->games, b->name); | |
| 1125 char *room; | |
| 1126 if (!game) | |
| 1127 return m; | |
| 1128 if (game) { | |
| 1129 char *t; | |
| 1130 pbm = g_new0(struct proto_buddy_menu, 1); | |
| 1131 if (!(room = strstr(game, "&follow="))) /* skip ahead to the url */ | |
| 1132 return NULL; | |
| 1133 while (*room && *room != '\t') /* skip to the tab */ | |
| 1134 room++; | |
| 1135 t = room++; /* room as now at the name */ | |
| 1136 while (*t != '\n') | |
| 1137 t++; /* replace the \n with a space */ | |
| 1138 *t = ' '; | |
| 1139 g_snprintf(buf2, sizeof buf2, "%s", room); | |
| 1140 pbm->label = buf2; | |
| 1141 pbm->callback = yahoo_game; | |
| 1142 pbm->gc = gc; | |
| 1143 m = g_list_append(m, pbm); | |
| 1144 } | |
| 1145 } | |
| 4722 | 1146 |
| 2681 | 1147 return m; |
| 1148 } | |
| 1149 | |
| 1150 static void yahoo_act_id(gpointer data, char *entry) | |
| 1151 { | |
| 1152 struct gaim_connection *gc = data; | |
| 1153 struct yahoo_data *yd = gc->proto_data; | |
| 1154 | |
| 1155 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_IDACT, YAHOO_STATUS_AVAILABLE, 0); | |
| 1156 yahoo_packet_hash(pkt, 3, entry); | |
| 1157 yahoo_send_packet(yd, pkt); | |
| 1158 yahoo_packet_free(pkt); | |
| 1159 | |
| 1160 g_snprintf(gc->displayname, sizeof(gc->displayname), "%s", entry); | |
| 1161 } | |
| 1162 | |
| 4333 | 1163 static void yahoo_show_act_id(struct gaim_connection *gc) |
| 2681 | 1164 { |
| 4333 | 1165 do_prompt_dialog("Activate which ID:", gc->displayname, gc, yahoo_act_id, NULL); |
| 2681 | 1166 } |
| 1167 | |
| 4333 | 1168 static GList *yahoo_actions(struct gaim_connection *gc) { |
| 2681 | 1169 GList *m = NULL; |
| 4333 | 1170 struct proto_actions_menu *pam; |
| 2681 | 1171 |
| 4333 | 1172 pam = g_new0(struct proto_actions_menu, 1); |
| 1173 pam->label = _("Activate ID"); | |
| 1174 pam->callback = yahoo_show_act_id; | |
| 1175 pam->gc = gc; | |
| 1176 m = g_list_append(m, pam); | |
| 2681 | 1177 |
| 1178 return m; | |
| 1179 } | |
| 1180 | |
| 3033 | 1181 static int yahoo_send_im(struct gaim_connection *gc, char *who, char *what, int len, int flags) |
| 2681 | 1182 { |
| 1183 struct yahoo_data *yd = gc->proto_data; | |
| 1184 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, 0); | |
| 3642 | 1185 char *msg = g_strdup(what); |
| 2681 | 1186 |
| 1187 yahoo_packet_hash(pkt, 1, gc->displayname); | |
| 1188 yahoo_packet_hash(pkt, 5, who); | |
| 3493 | 1189 yahoo_packet_hash(pkt, 14, msg); |
| 2681 | 1190 |
| 1191 yahoo_send_packet(yd, pkt); | |
| 1192 | |
| 1193 yahoo_packet_free(pkt); | |
| 3493 | 1194 |
| 2681 | 1195 return 1; |
| 1196 } | |
| 1197 | |
| 3001 | 1198 int yahoo_send_typing(struct gaim_connection *gc, char *who, int typ) |
| 2993 | 1199 { |
| 1200 struct yahoo_data *yd = gc->proto_data; | |
| 3019 | 1201 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_TYPING, 0); |
| 2993 | 1202 yahoo_packet_hash(pkt, 49, "TYPING"); |
| 1203 yahoo_packet_hash(pkt, 1, gc->displayname); | |
| 1204 yahoo_packet_hash(pkt, 14, " "); | |
| 3596 | 1205 yahoo_packet_hash(pkt, 13, typ == TYPING ? "1" : "0"); |
| 2993 | 1206 yahoo_packet_hash(pkt, 5, who); |
| 1207 yahoo_packet_hash(pkt, 1002, "1"); | |
| 1208 | |
| 1209 yahoo_send_packet(yd, pkt); | |
| 1210 | |
| 1211 yahoo_packet_free(pkt); | |
| 1212 | |
| 3001 | 1213 return 0; |
| 2993 | 1214 } |
| 1215 | |
| 2681 | 1216 static void yahoo_set_away(struct gaim_connection *gc, char *state, char *msg) |
| 1217 { | |
| 1218 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
| 1219 struct yahoo_packet *pkt; | |
|
2772
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
1220 int service; |
| 2681 | 1221 char s[4]; |
| 1222 | |
|
4111
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4044
diff
changeset
|
1223 if (gc->away) { |
|
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4044
diff
changeset
|
1224 g_free(gc->away); |
|
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4044
diff
changeset
|
1225 gc->away = NULL; |
|
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4044
diff
changeset
|
1226 } |
| 2681 | 1227 |
| 1228 if (msg) { | |
| 1229 yd->current_status = YAHOO_STATUS_CUSTOM; | |
|
4111
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4044
diff
changeset
|
1230 gc->away = g_strdup(msg); |
| 2681 | 1231 } else if (state) { |
|
4111
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4044
diff
changeset
|
1232 gc->away = g_strdup(""); |
| 4596 | 1233 if (!strcmp(state, _("Available"))) { |
| 2681 | 1234 yd->current_status = YAHOO_STATUS_AVAILABLE; |
|
4111
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4044
diff
changeset
|
1235 g_free(gc->away); |
| 2681 | 1236 gc->away = NULL; |
| 4596 | 1237 } else if (!strcmp(state, _("Be Right Back"))) { |
| 2681 | 1238 yd->current_status = YAHOO_STATUS_BRB; |
| 4596 | 1239 } else if (!strcmp(state, _("Busy"))) { |
| 2681 | 1240 yd->current_status = YAHOO_STATUS_BUSY; |
| 4596 | 1241 } else if (!strcmp(state, _("Not At Home"))) { |
| 2681 | 1242 yd->current_status = YAHOO_STATUS_NOTATHOME; |
| 4596 | 1243 } else if (!strcmp(state, _("Not At Desk"))) { |
| 2681 | 1244 yd->current_status = YAHOO_STATUS_NOTATDESK; |
| 4596 | 1245 } else if (!strcmp(state, _("Not In Office"))) { |
| 2681 | 1246 yd->current_status = YAHOO_STATUS_NOTINOFFICE; |
| 4606 | 1247 } else if (!strcmp(state, _("On The Phone"))) { |
| 2681 | 1248 yd->current_status = YAHOO_STATUS_ONPHONE; |
| 4596 | 1249 } else if (!strcmp(state, _("On Vacation"))) { |
| 2681 | 1250 yd->current_status = YAHOO_STATUS_ONVACATION; |
| 4596 | 1251 } else if (!strcmp(state, _("Out To Lunch"))) { |
| 2681 | 1252 yd->current_status = YAHOO_STATUS_OUTTOLUNCH; |
| 4596 | 1253 } else if (!strcmp(state, _("Stepped Out"))) { |
| 2681 | 1254 yd->current_status = YAHOO_STATUS_STEPPEDOUT; |
| 4596 | 1255 } else if (!strcmp(state, _("Invisible"))) { |
| 2681 | 1256 yd->current_status = YAHOO_STATUS_INVISIBLE; |
| 1257 } else if (!strcmp(state, GAIM_AWAY_CUSTOM)) { | |
| 1258 if (gc->is_idle) { | |
| 1259 yd->current_status = YAHOO_STATUS_IDLE; | |
| 1260 } else { | |
| 1261 yd->current_status = YAHOO_STATUS_AVAILABLE; | |
| 1262 } | |
|
4111
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4044
diff
changeset
|
1263 g_free(gc->away); |
| 2681 | 1264 gc->away = NULL; |
| 1265 } | |
| 1266 } else if (gc->is_idle) { | |
| 1267 yd->current_status = YAHOO_STATUS_IDLE; | |
| 1268 } else { | |
| 1269 yd->current_status = YAHOO_STATUS_AVAILABLE; | |
| 1270 } | |
| 1271 | |
|
2772
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
1272 if (yd->current_status == YAHOO_STATUS_AVAILABLE) |
|
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
1273 service = YAHOO_SERVICE_ISBACK; |
|
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
1274 else |
|
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
1275 service = YAHOO_SERVICE_ISAWAY; |
|
f9227268db25
[gaim-migrate @ 2785]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2771
diff
changeset
|
1276 pkt = yahoo_packet_new(service, yd->current_status, 0); |
| 2681 | 1277 g_snprintf(s, sizeof(s), "%d", yd->current_status); |
| 1278 yahoo_packet_hash(pkt, 10, s); | |
| 1279 if (yd->current_status == YAHOO_STATUS_CUSTOM) | |
| 1280 yahoo_packet_hash(pkt, 19, msg); | |
| 1281 | |
| 1282 yahoo_send_packet(yd, pkt); | |
| 1283 yahoo_packet_free(pkt); | |
| 1284 } | |
| 1285 | |
| 1286 static void yahoo_set_idle(struct gaim_connection *gc, int idle) | |
| 1287 { | |
| 1288 struct yahoo_data *yd = gc->proto_data; | |
| 1289 struct yahoo_packet *pkt = NULL; | |
| 1290 | |
| 1291 if (idle && yd->current_status == YAHOO_STATUS_AVAILABLE) { | |
| 1292 pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, YAHOO_STATUS_IDLE, 0); | |
| 1293 yd->current_status = YAHOO_STATUS_IDLE; | |
| 1294 } else if (!idle && yd->current_status == YAHOO_STATUS_IDLE) { | |
| 1295 pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, YAHOO_STATUS_AVAILABLE, 0); | |
| 1296 yd->current_status = YAHOO_STATUS_AVAILABLE; | |
| 1297 } | |
| 1298 | |
| 1299 if (pkt) { | |
| 1300 char buf[4]; | |
| 1301 g_snprintf(buf, sizeof(buf), "%d", yd->current_status); | |
| 1302 yahoo_packet_hash(pkt, 10, buf); | |
| 1303 yahoo_send_packet(yd, pkt); | |
| 1304 yahoo_packet_free(pkt); | |
| 1305 } | |
| 1306 } | |
| 1307 | |
| 1308 static GList *yahoo_away_states(struct gaim_connection *gc) | |
| 1309 { | |
| 1310 GList *m = NULL; | |
| 1311 | |
| 4596 | 1312 m = g_list_append(m, _("Available")); |
| 1313 m = g_list_append(m, _("Be Right Back")); | |
| 1314 m = g_list_append(m, _("Busy")); | |
| 1315 m = g_list_append(m, _("Not At Home")); | |
| 1316 m = g_list_append(m, _("Not At Desk")); | |
| 1317 m = g_list_append(m, _("Not In Office")); | |
| 4606 | 1318 m = g_list_append(m, _("On The Phone")); |
| 4596 | 1319 m = g_list_append(m, _("On Vacation")); |
| 1320 m = g_list_append(m, _("Out To Lunch")); | |
| 1321 m = g_list_append(m, _("Stepped Out")); | |
| 1322 m = g_list_append(m, _("Invisible")); | |
| 2681 | 1323 m = g_list_append(m, GAIM_AWAY_CUSTOM); |
| 1324 | |
| 1325 return m; | |
| 1326 } | |
| 1327 | |
| 1328 static void yahoo_keepalive(struct gaim_connection *gc) | |
| 1329 { | |
| 1330 struct yahoo_data *yd = gc->proto_data; | |
| 1331 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YAHOO_STATUS_AVAILABLE, 0); | |
| 1332 yahoo_send_packet(yd, pkt); | |
| 1333 yahoo_packet_free(pkt); | |
| 1334 } | |
| 1335 | |
| 3466 | 1336 static void yahoo_add_buddy(struct gaim_connection *gc, const char *who) |
| 2681 | 1337 { |
| 1338 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
| 1339 struct yahoo_packet *pkt; | |
| 1340 struct group *g; | |
| 1341 char *group = NULL; | |
| 1342 | |
| 1343 if (!yd->logged_in) | |
| 1344 return; | |
| 1345 | |
| 4687 | 1346 g = gaim_find_buddys_group(gaim_find_buddy(gc->account, who)); |
| 2681 | 1347 if (g) |
| 1348 group = g->name; | |
| 1349 else | |
| 1350 group = "Buddies"; | |
| 1351 | |
| 1352 pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, 0); | |
| 1353 yahoo_packet_hash(pkt, 1, gc->displayname); | |
| 1354 yahoo_packet_hash(pkt, 7, who); | |
| 1355 yahoo_packet_hash(pkt, 65, group); | |
| 1356 yahoo_send_packet(yd, pkt); | |
| 1357 yahoo_packet_free(pkt); | |
| 1358 } | |
| 1359 | |
| 1360 static void yahoo_remove_buddy(struct gaim_connection *gc, char *who, char *group) | |
| 1361 { | |
| 1362 struct yahoo_data *yd = (struct yahoo_data *)gc->proto_data; | |
| 1363 | |
| 1364 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, 0); | |
| 1365 yahoo_packet_hash(pkt, 1, gc->displayname); | |
| 1366 yahoo_packet_hash(pkt, 7, who); | |
| 1367 yahoo_packet_hash(pkt, 65, group); | |
| 1368 yahoo_send_packet(yd, pkt); | |
| 1369 yahoo_packet_free(pkt); | |
| 1370 } | |
| 1371 | |
| 1372 static struct prpl *my_protocol = NULL; | |
| 1373 | |
| 3630 | 1374 G_MODULE_EXPORT void yahoo_init(struct prpl *ret) { |
| 3572 | 1375 struct proto_user_opt *puo; |
| 2681 | 1376 ret->protocol = PROTO_YAHOO; |
| 1377 ret->options = OPT_PROTO_MAIL_CHECK; | |
| 3572 | 1378 ret->name = g_strdup("Yahoo"); |
| 2681 | 1379 ret->login = yahoo_login; |
| 1380 ret->close = yahoo_close; | |
| 1381 ret->buddy_menu = yahoo_buddy_menu; | |
| 1382 ret->list_icon = yahoo_list_icon; | |
| 4722 | 1383 ret->status_text = yahoo_status_text; |
| 4724 | 1384 ret->tooltip_text = yahoo_tooltip_text; |
| 2681 | 1385 ret->actions = yahoo_actions; |
| 1386 ret->send_im = yahoo_send_im; | |
| 1387 ret->away_states = yahoo_away_states; | |
| 1388 ret->set_away = yahoo_set_away; | |
| 1389 ret->set_idle = yahoo_set_idle; | |
| 1390 ret->keepalive = yahoo_keepalive; | |
| 1391 ret->add_buddy = yahoo_add_buddy; | |
| 1392 ret->remove_buddy = yahoo_remove_buddy; | |
| 2993 | 1393 ret->send_typing = yahoo_send_typing; |
| 2681 | 1394 |
| 3572 | 1395 puo = g_new0(struct proto_user_opt, 1); |
| 4115 | 1396 puo->label = g_strdup(_("Pager Host:")); |
| 3572 | 1397 puo->def = g_strdup(YAHOO_PAGER_HOST); |
| 1398 puo->pos = USEROPT_PAGERHOST; | |
| 1399 ret->user_opts = g_list_append(ret->user_opts, puo); | |
| 1400 | |
| 1401 puo = g_new0(struct proto_user_opt, 1); | |
| 4115 | 1402 puo->label = g_strdup(_("Pager Port:")); |
| 3572 | 1403 puo->def = g_strdup("5050"); |
| 1404 puo->pos = USEROPT_PAGERPORT; | |
| 1405 ret->user_opts = g_list_append(ret->user_opts, puo); | |
| 1406 | |
| 2681 | 1407 my_protocol = ret; |
| 1408 } | |
| 1409 | |
| 1410 #ifndef STATIC | |
| 1411 | |
| 3630 | 1412 G_MODULE_EXPORT void gaim_prpl_init(struct prpl *prpl) |
| 2681 | 1413 { |
| 3572 | 1414 yahoo_init(prpl); |
| 1415 prpl->plug->desc.api_version = PLUGIN_API_VERSION; | |
| 2681 | 1416 } |
| 1417 | |
| 1418 #endif |
