Mercurial > pidgin
annotate src/protocols/msn/msn.c @ 2273:0b5c3338fa3d
[gaim-migrate @ 2283]
One of the girls on the floor of my sister's dorm lost both her parents when their plane was hijacked and crashed into the World Trade Center. my girlfriend's boss's sister-in-law's brother died when the building collapsed. my parents flew to atlanta on monday; they're safe but currently stranded there. they had planned on flying to Raleigh, NC today but now are just hoping to be able to fly home soon. how did this happen?
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Wed, 12 Sep 2001 21:29:32 +0000 |
parents | 2f03cfd21fc2 |
children | f5bf315e6104 |
rev | line source |
---|---|
2086 | 1 #include "config.h" |
2 | |
3 #include <stdlib.h> | |
4 #include <string.h> | |
2167
edf8c5a70e5b
[gaim-migrate @ 2177]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2162
diff
changeset
|
5 #include <errno.h> |
2086 | 6 #include <stdio.h> |
7 #include <unistd.h> | |
8 #include <ctype.h> | |
9 #include "gaim.h" | |
10 #include "prpl.h" | |
11 #include "proxy.h" | |
12 #include "md5.h" | |
13 | |
14 #include "pixmaps/msn_online.xpm" | |
15 #include "pixmaps/msn_away.xpm" | |
16 | |
17 #define MSN_BUF_LEN 8192 | |
18 #define MIME_HEADER "MIME-Version: 1.0\r\n" \ | |
19 "Content-Type: text/plain; charset=UTF-8\r\n" \ | |
2273
0b5c3338fa3d
[gaim-migrate @ 2283]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2265
diff
changeset
|
20 "User-Agent: Gaim/" VERSION "\r\n" \ |
2086 | 21 "X-MMS-IM-Format: FN=MS%20Sans%20Serif; EF=; CO=0; PF=0\r\n\r\n" |
22 | |
23 #define MSN_ONLINE 1 | |
24 #define MSN_BUSY 2 | |
25 #define MSN_IDLE 3 | |
26 #define MSN_BRB 4 | |
27 #define MSN_AWAY 5 | |
28 #define MSN_PHONE 6 | |
29 #define MSN_LUNCH 7 | |
30 #define MSN_OFFLINE 8 | |
31 #define MSN_HIDDEN 9 | |
32 | |
33 #define USEROPT_HOTMAIL 0 | |
34 | |
35 struct msn_data { | |
36 int fd; | |
37 int trId; | |
38 int inpa; | |
39 GSList *switches; | |
40 GSList *fl; | |
41 gboolean imported; | |
42 }; | |
43 | |
44 struct msn_switchboard { | |
45 struct gaim_connection *gc; | |
46 struct conversation *chat; | |
47 int fd; | |
48 int inpa; | |
49 char *sessid; | |
50 char *auth; | |
51 int trId; | |
52 int total; | |
53 char *user; | |
54 char *txqueue; | |
55 }; | |
56 | |
57 struct msn_buddy { | |
58 char *user; | |
59 char *friend; | |
60 }; | |
61 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
62 static void msn_login_callback(gpointer, gint, GaimInputCondition); |
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
63 static void msn_login_xfr_connect(gpointer, gint, GaimInputCondition); |
2086 | 64 |
65 #define GET_NEXT(tmp) while (*(tmp) && !isspace(*(tmp))) \ | |
66 (tmp)++; \ | |
67 *(tmp)++ = 0; \ | |
68 while (*(tmp) && isspace(*(tmp))) \ | |
69 (tmp)++; | |
70 | |
71 static char *msn_name() | |
72 { | |
73 return "MSN"; | |
74 } | |
75 | |
76 static char *msn_normalize(const char *s) | |
77 { | |
78 static char buf[BUF_LEN]; | |
79 | |
80 g_return_val_if_fail(s != NULL, NULL); | |
81 | |
82 g_snprintf(buf, sizeof(buf), "%s%s", s, strchr(s, '@') ? "" : "@hotmail.com"); | |
83 | |
84 return buf; | |
85 } | |
86 | |
87 static int msn_write(int fd, void *data, int len) | |
88 { | |
89 debug_printf("C: %s", data); | |
90 return write(fd, data, len); | |
91 } | |
92 | |
93 static char *url_decode(const char *msg) | |
94 { | |
95 static char buf[MSN_BUF_LEN]; | |
96 int i, j = 0; | |
97 | |
98 bzero(buf, sizeof(buf)); | |
99 for (i = 0; i < strlen(msg); i++) { | |
100 char hex[3]; | |
101 if (msg[i] != '%') { | |
102 buf[j++] = msg[i]; | |
103 continue; | |
104 } | |
2093
83d8a9b7e89b
[gaim-migrate @ 2103]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
105 strncpy(hex, msg + ++i, 2); hex[2] = 0; |
83d8a9b7e89b
[gaim-migrate @ 2103]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
106 /* i is pointing to the start of the number */ |
83d8a9b7e89b
[gaim-migrate @ 2103]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
107 i++; /* now it's at the end and at the start of the for loop |
83d8a9b7e89b
[gaim-migrate @ 2103]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
108 will be at the next character */ |
83d8a9b7e89b
[gaim-migrate @ 2103]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
109 buf[j++] = strtol(hex, NULL, 16); |
2086 | 110 } |
111 buf[j] = 0; | |
112 | |
113 return buf; | |
114 } | |
115 | |
2219
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
116 static char *url_encode(const char *msg) |
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
117 { |
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
118 static char buf[MSN_BUF_LEN]; |
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
119 int i, j = 0; |
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
120 |
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
121 bzero(buf, sizeof(buf)); |
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
122 for (i = 0; i < strlen(msg); i++) { |
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
123 if (isalnum(msg[i])) |
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
124 buf[j++] = msg[i]; |
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
125 else { |
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
126 sprintf(buf + j, "%%%02x", (unsigned char)msg[i]); |
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
127 j += 3; |
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
128 } |
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
129 } |
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
130 buf[j] = 0; |
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
131 |
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
132 return buf; |
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
133 } |
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
134 |
2086 | 135 static char *handle_errcode(char *buf, gboolean show) |
136 { | |
137 int errcode; | |
138 static char msg[MSN_BUF_LEN]; | |
139 | |
140 buf[4] = 0; | |
141 errcode = atoi(buf); | |
142 | |
143 switch (errcode) { | |
144 case 200: | |
145 g_snprintf(msg, sizeof(msg), "Syntax Error (probably a Gaim bug)"); | |
146 break; | |
147 case 201: | |
148 g_snprintf(msg, sizeof(msg), "Invalid Parameter (probably a Gaim bug)"); | |
149 break; | |
150 case 205: | |
151 g_snprintf(msg, sizeof(msg), "Invalid User"); | |
152 break; | |
153 case 206: | |
154 g_snprintf(msg, sizeof(msg), "Fully Qualified Domain Name missing"); | |
155 break; | |
156 case 207: | |
157 g_snprintf(msg, sizeof(msg), "Already Login"); | |
158 break; | |
159 case 208: | |
160 g_snprintf(msg, sizeof(msg), "Invalid Username"); | |
161 break; | |
162 case 209: | |
163 g_snprintf(msg, sizeof(msg), "Invalid Friendly Name"); | |
164 break; | |
165 case 210: | |
166 g_snprintf(msg, sizeof(msg), "List Full"); | |
167 break; | |
168 case 215: | |
169 g_snprintf(msg, sizeof(msg), "Already there"); | |
170 break; | |
171 case 216: | |
172 g_snprintf(msg, sizeof(msg), "Not on list"); | |
173 break; | |
174 case 218: | |
175 g_snprintf(msg, sizeof(msg), "Already in the mode"); | |
176 break; | |
177 case 219: | |
178 g_snprintf(msg, sizeof(msg), "Already in opposite list"); | |
179 break; | |
180 case 280: | |
181 g_snprintf(msg, sizeof(msg), "Switchboard failed"); | |
182 break; | |
183 case 281: | |
184 g_snprintf(msg, sizeof(msg), "Notify Transfer failed"); | |
185 break; | |
186 | |
187 case 300: | |
188 g_snprintf(msg, sizeof(msg), "Required fields missing"); | |
189 break; | |
190 case 302: | |
191 g_snprintf(msg, sizeof(msg), "Not logged in"); | |
192 break; | |
193 | |
194 case 500: | |
195 g_snprintf(msg, sizeof(msg), "Internal server error"); | |
196 break; | |
197 case 501: | |
198 g_snprintf(msg, sizeof(msg), "Database server error"); | |
199 break; | |
200 case 510: | |
201 g_snprintf(msg, sizeof(msg), "File operation error"); | |
202 break; | |
203 case 520: | |
204 g_snprintf(msg, sizeof(msg), "Memory allocation error"); | |
205 break; | |
206 | |
207 case 600: | |
208 g_snprintf(msg, sizeof(msg), "Server busy"); | |
209 break; | |
210 case 601: | |
211 g_snprintf(msg, sizeof(msg), "Server unavailable"); | |
212 break; | |
213 case 602: | |
214 g_snprintf(msg, sizeof(msg), "Peer Notification server down"); | |
215 break; | |
216 case 603: | |
217 g_snprintf(msg, sizeof(msg), "Database connect error"); | |
218 break; | |
219 case 604: | |
220 g_snprintf(msg, sizeof(msg), "Server is going down (abandon ship)"); | |
221 break; | |
222 | |
223 case 707: | |
224 g_snprintf(msg, sizeof(msg), "Error creating connection"); | |
225 break; | |
226 case 711: | |
227 g_snprintf(msg, sizeof(msg), "Unable to write"); | |
228 break; | |
229 case 712: | |
230 g_snprintf(msg, sizeof(msg), "Session overload"); | |
231 break; | |
232 case 713: | |
233 g_snprintf(msg, sizeof(msg), "User is too active"); | |
234 break; | |
235 case 714: | |
236 g_snprintf(msg, sizeof(msg), "Too many sessions"); | |
237 break; | |
238 case 715: | |
239 g_snprintf(msg, sizeof(msg), "Not expected"); | |
240 break; | |
241 case 717: | |
242 g_snprintf(msg, sizeof(msg), "Bad friend file"); | |
243 break; | |
244 | |
245 case 911: | |
246 g_snprintf(msg, sizeof(msg), "Authentication failed"); | |
247 break; | |
248 case 913: | |
249 g_snprintf(msg, sizeof(msg), "Not allowed when offline"); | |
250 break; | |
251 case 920: | |
252 g_snprintf(msg, sizeof(msg), "Not accepting new users"); | |
253 break; | |
254 | |
255 default: | |
256 g_snprintf(msg, sizeof(msg), "Unknown Error Code"); | |
257 break; | |
258 } | |
259 | |
260 if (show) | |
261 do_error_dialog(msg, "MSN Error"); | |
262 | |
263 return msg; | |
264 } | |
265 | |
266 static void handle_hotmail(struct gaim_connection *gc, char *data) | |
267 { | |
2153
0befa2d2e540
[gaim-migrate @ 2163]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2152
diff
changeset
|
268 if (strstr(data, "Content-Type: text/x-msmsgsinitialemailnotification;")) { |
0befa2d2e540
[gaim-migrate @ 2163]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2152
diff
changeset
|
269 char *x = strstr(data, "Inbox-Unread:"); |
0befa2d2e540
[gaim-migrate @ 2163]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2152
diff
changeset
|
270 if (!x) return; |
0befa2d2e540
[gaim-migrate @ 2163]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2152
diff
changeset
|
271 x += strlen("Inbox-Unread: "); |
0befa2d2e540
[gaim-migrate @ 2163]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2152
diff
changeset
|
272 connection_has_mail(gc, atoi(x), NULL, NULL); |
0befa2d2e540
[gaim-migrate @ 2163]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2152
diff
changeset
|
273 } else if (strstr(data, "Content-Type: text/x-msmsgsemailnotification;")) { |
0befa2d2e540
[gaim-migrate @ 2163]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2152
diff
changeset
|
274 char *from = strstr(data, "From:"); |
0befa2d2e540
[gaim-migrate @ 2163]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2152
diff
changeset
|
275 char *subject = strstr(data, "Subject:"); |
0befa2d2e540
[gaim-migrate @ 2163]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2152
diff
changeset
|
276 char *x; |
0befa2d2e540
[gaim-migrate @ 2163]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2152
diff
changeset
|
277 if (!from || !subject) { |
0befa2d2e540
[gaim-migrate @ 2163]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2152
diff
changeset
|
278 connection_has_mail(gc, 1, NULL, NULL); |
0befa2d2e540
[gaim-migrate @ 2163]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2152
diff
changeset
|
279 return; |
0befa2d2e540
[gaim-migrate @ 2163]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2152
diff
changeset
|
280 } |
0befa2d2e540
[gaim-migrate @ 2163]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2152
diff
changeset
|
281 from += strlen("From: "); |
0befa2d2e540
[gaim-migrate @ 2163]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2152
diff
changeset
|
282 x = strstr(from, "\r\n"); *x = 0; |
0befa2d2e540
[gaim-migrate @ 2163]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2152
diff
changeset
|
283 subject += strlen("Subject: "); |
0befa2d2e540
[gaim-migrate @ 2163]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2152
diff
changeset
|
284 x = strstr(subject, "\r\n"); *x = 0; |
0befa2d2e540
[gaim-migrate @ 2163]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2152
diff
changeset
|
285 connection_has_mail(gc, -1, from, subject); |
2086 | 286 } |
287 } | |
288 | |
289 static struct msn_switchboard *msn_find_switch(struct gaim_connection *gc, char *id) | |
290 { | |
291 struct msn_data *md = gc->proto_data; | |
292 GSList *m = md->switches; | |
293 | |
294 while (m) { | |
295 struct msn_switchboard *ms = m->data; | |
296 m = m->next; | |
297 if ((ms->total == 1) && !g_strcasecmp(ms->user, id)) | |
298 return ms; | |
299 } | |
300 | |
301 return NULL; | |
302 } | |
303 | |
304 static struct msn_switchboard *msn_find_switch_by_id(struct gaim_connection *gc, int id) | |
305 { | |
306 struct msn_data *md = gc->proto_data; | |
307 GSList *m = md->switches; | |
308 | |
309 while (m) { | |
310 struct msn_switchboard *ms = m->data; | |
311 m = m->next; | |
312 if (ms->chat && (ms->chat->id == id)) | |
313 return ms; | |
314 } | |
315 | |
316 return NULL; | |
317 } | |
318 | |
319 static struct msn_switchboard *msn_find_writable_switch(struct gaim_connection *gc) | |
320 { | |
321 struct msn_data *md = gc->proto_data; | |
322 GSList *m = md->switches; | |
323 | |
324 while (m) { | |
325 struct msn_switchboard *ms = m->data; | |
326 m = m->next; | |
327 if (ms->txqueue) | |
328 return ms; | |
329 } | |
330 | |
331 return NULL; | |
332 } | |
333 | |
334 static void msn_kill_switch(struct msn_switchboard *ms) | |
335 { | |
336 struct gaim_connection *gc = ms->gc; | |
337 struct msn_data *md = gc->proto_data; | |
338 | |
339 if (ms->inpa) | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
340 gaim_input_remove(ms->inpa); |
2086 | 341 close(ms->fd); |
342 if (ms->sessid) | |
343 g_free(ms->sessid); | |
344 g_free(ms->auth); | |
345 if (ms->user) | |
346 g_free(ms->user); | |
347 if (ms->txqueue) | |
348 g_free(ms->txqueue); | |
349 if (ms->chat) | |
350 serv_got_chat_left(gc, ms->chat->id); | |
351 | |
352 md->switches = g_slist_remove(md->switches, ms); | |
353 | |
354 g_free(ms); | |
355 } | |
356 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
357 static void msn_switchboard_callback(gpointer data, gint source, GaimInputCondition cond) |
2086 | 358 { |
359 struct msn_switchboard *ms = data; | |
360 struct gaim_connection *gc = ms->gc; | |
361 char buf[MSN_BUF_LEN]; | |
362 static int id = 0; | |
363 int i = 0; | |
364 | |
365 bzero(buf, sizeof(buf)); | |
366 while ((read(ms->fd, buf + i, 1) > 0) && (buf[i++] != '\n')) | |
367 if (i == sizeof(buf)) | |
368 i--; /* yes i know this loses data but we shouldn't get messages this long | |
369 and it's better than possibly writing past our buffer */ | |
370 if (i == 0 || buf[i - 1] != '\n') { | |
371 msn_kill_switch(ms); | |
372 return; | |
373 } | |
374 debug_printf("S: %s", buf); | |
375 g_strchomp(buf); | |
376 | |
377 if (!g_strncasecmp(buf, "ACK", 3)) { | |
378 } else if (!g_strncasecmp(buf, "ANS", 3)) { | |
379 if (ms->chat) | |
380 add_chat_buddy(ms->chat, gc->username); | |
381 } else if (!g_strncasecmp(buf, "BYE", 3)) { | |
382 if (ms->chat) { | |
383 char *user, *tmp = buf; | |
384 GET_NEXT(tmp); | |
385 user = tmp; | |
386 remove_chat_buddy(ms->chat, user); | |
387 } else | |
388 msn_kill_switch(ms); | |
389 } else if (!g_strncasecmp(buf, "CAL", 3)) { | |
390 } else if (!g_strncasecmp(buf, "IRO", 3)) { | |
391 char *tot, *user, *tmp = buf; | |
392 | |
393 GET_NEXT(tmp); | |
394 GET_NEXT(tmp); | |
395 GET_NEXT(tmp); | |
396 tot = tmp; | |
397 GET_NEXT(tmp); | |
398 ms->total = atoi(tot); | |
399 user = tmp; | |
400 GET_NEXT(tmp); | |
401 | |
402 if (ms->total > 1) { | |
403 if (!ms->chat) | |
404 ms->chat = serv_got_joined_chat(gc, ++id, "MSN Chat"); | |
405 add_chat_buddy(ms->chat, user); | |
406 } | |
407 } else if (!g_strncasecmp(buf, "JOI", 3)) { | |
408 char *user, *tmp = buf; | |
409 GET_NEXT(tmp); | |
410 user = tmp; | |
411 GET_NEXT(tmp); | |
412 | |
413 if (ms->total == 1) { | |
414 ms->chat = serv_got_joined_chat(gc, ++id, "MSN Chat"); | |
415 add_chat_buddy(ms->chat, ms->user); | |
416 add_chat_buddy(ms->chat, gc->username); | |
417 g_free(ms->user); | |
418 ms->user = NULL; | |
419 } | |
420 if (ms->chat) | |
421 add_chat_buddy(ms->chat, user); | |
422 ms->total++; | |
423 if (ms->txqueue) { | |
424 char *utf8 = str_to_utf8(ms->txqueue); | |
425 g_snprintf(buf, sizeof(buf), "MSG %d N %d\r\n%s%s", ++ms->trId, | |
426 strlen(MIME_HEADER) + strlen(utf8), | |
427 MIME_HEADER, utf8); | |
428 g_free(utf8); | |
429 g_free(ms->txqueue); | |
430 ms->txqueue = NULL; | |
431 if (msn_write(ms->fd, buf, strlen(buf)) < 0) | |
432 msn_kill_switch(ms); | |
433 debug_printf("\n"); | |
434 } | |
435 } else if (!g_strncasecmp(buf, "MSG", 3)) { | |
436 char *user, *tmp = buf; | |
437 int length; | |
2273
0b5c3338fa3d
[gaim-migrate @ 2283]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2265
diff
changeset
|
438 char *msg, *content, *agent, *utf; |
2086 | 439 int len, r; |
2273
0b5c3338fa3d
[gaim-migrate @ 2283]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2265
diff
changeset
|
440 int flags = 0; |
2086 | 441 |
442 GET_NEXT(tmp); | |
443 user = tmp; | |
444 | |
445 GET_NEXT(tmp); | |
446 | |
447 GET_NEXT(tmp); | |
448 length = atoi(tmp); | |
449 | |
450 msg = g_new0(char, MAX(length + 1, MSN_BUF_LEN)); | |
451 | |
452 for (len = 0; len < length; len += r) { | |
453 if ((r = read(ms->fd, msg+len, length-len)) <= 0) { | |
454 g_free(msg); | |
455 hide_login_progress(gc, "Unable to read message"); | |
456 signoff(gc); | |
457 return; | |
458 } | |
459 } | |
460 | |
2273
0b5c3338fa3d
[gaim-migrate @ 2283]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2265
diff
changeset
|
461 agent = strstr(msg, "User-Agent: "); |
0b5c3338fa3d
[gaim-migrate @ 2283]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2265
diff
changeset
|
462 if (agent) { |
0b5c3338fa3d
[gaim-migrate @ 2283]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2265
diff
changeset
|
463 if (!g_strncasecmp(agent, "User-Agent: Gaim", strlen("User-Agent: Gaim"))) |
0b5c3338fa3d
[gaim-migrate @ 2283]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2265
diff
changeset
|
464 flags |= IM_FLAG_GAIMUSER; |
0b5c3338fa3d
[gaim-migrate @ 2283]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2265
diff
changeset
|
465 } |
2086 | 466 content = strstr(msg, "Content-Type: "); |
467 if (!content) { | |
468 g_free(msg); | |
469 return; | |
470 } | |
471 if (!g_strncasecmp(content, "Content-Type: text/plain", | |
472 strlen("Content-Type: text/plain"))) { | |
473 char *final, *skiphead; | |
474 skiphead = strstr(msg, "\r\n\r\n"); | |
475 if (!skiphead || !skiphead[4]) { | |
476 g_free(msg); | |
477 return; | |
478 } | |
479 skiphead += 4; | |
480 utf = utf8_to_str(skiphead); | |
481 len = MAX(strlen(utf) + 1, BUF_LEN); | |
482 final = g_malloc(len); | |
483 g_snprintf(final, len, "%s", utf); | |
484 g_free(utf); | |
485 | |
486 if (ms->chat) | |
2273
0b5c3338fa3d
[gaim-migrate @ 2283]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2265
diff
changeset
|
487 serv_got_chat_in(gc, ms->chat->id, user, flags, final, time(NULL)); |
2086 | 488 else |
2273
0b5c3338fa3d
[gaim-migrate @ 2283]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2265
diff
changeset
|
489 serv_got_im(gc, user, final, flags, time(NULL)); |
2086 | 490 |
491 g_free(final); | |
492 } | |
493 g_free(msg); | |
494 } else if (!g_strncasecmp(buf, "NAK", 3)) { | |
495 do_error_dialog("A message may not have been received.", "MSN Error"); | |
496 } else if (!g_strncasecmp(buf, "NLN", 3)) { | |
497 } else if (!g_strncasecmp(buf, "OUT", 3)) { | |
498 if (ms->chat) | |
499 serv_got_chat_left(gc, ms->chat->id); | |
500 msn_kill_switch(ms); | |
501 } else if (!g_strncasecmp(buf, "USR", 3)) { | |
502 /* good, we got USR, now we need to find out who we want to talk to */ | |
503 struct msn_switchboard *ms = msn_find_writable_switch(gc); | |
504 | |
505 if (!ms) | |
506 return; | |
507 | |
508 g_snprintf(buf, sizeof(buf), "CAL %d %s\n", ++ms->trId, ms->user); | |
509 if (msn_write(ms->fd, buf, strlen(buf)) < 0) | |
510 msn_kill_switch(ms); | |
511 } else if (isdigit(*buf)) { | |
512 handle_errcode(buf, TRUE); | |
513 } else { | |
514 debug_printf("Unhandled message!\n"); | |
515 } | |
516 } | |
517 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
518 static void msn_rng_connect(gpointer data, gint source, GaimInputCondition cond) |
2086 | 519 { |
520 struct msn_switchboard *ms = data; | |
521 struct gaim_connection *gc = ms->gc; | |
522 struct msn_data *md; | |
523 char buf[MSN_BUF_LEN]; | |
524 | |
525 if (source == -1 || !g_slist_find(connections, gc)) { | |
2210
3a6fd1e8f00a
[gaim-migrate @ 2220]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
526 close(source); |
2086 | 527 g_free(ms->sessid); |
528 g_free(ms->auth); | |
529 g_free(ms); | |
530 return; | |
531 } | |
532 | |
533 md = gc->proto_data; | |
534 | |
535 if (ms->fd != source) | |
536 ms->fd = source; | |
537 | |
538 g_snprintf(buf, sizeof(buf), "ANS %d %s %s %s\n", ++ms->trId, gc->username, ms->auth, ms->sessid); | |
539 if (msn_write(ms->fd, buf, strlen(buf)) < 0) { | |
540 close(ms->fd); | |
541 g_free(ms->sessid); | |
542 g_free(ms->auth); | |
543 g_free(ms); | |
544 return; | |
545 } | |
546 | |
547 md->switches = g_slist_append(md->switches, ms); | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
548 ms->inpa = gaim_input_add(ms->fd, GAIM_INPUT_READ, msn_switchboard_callback, ms); |
2086 | 549 } |
550 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
551 static void msn_ss_xfr_connect(gpointer data, gint source, GaimInputCondition cond) |
2086 | 552 { |
553 struct msn_switchboard *ms = data; | |
554 struct gaim_connection *gc = ms->gc; | |
555 char buf[MSN_BUF_LEN]; | |
556 | |
557 if (source == -1 || !g_slist_find(connections, gc)) { | |
2210
3a6fd1e8f00a
[gaim-migrate @ 2220]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
558 close(source); |
2265
2f03cfd21fc2
[gaim-migrate @ 2275]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2231
diff
changeset
|
559 if (g_slist_find(connections, gc)) { |
2f03cfd21fc2
[gaim-migrate @ 2275]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2231
diff
changeset
|
560 msn_kill_switch(ms); |
2f03cfd21fc2
[gaim-migrate @ 2275]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2231
diff
changeset
|
561 do_error_dialog(_("MSN Error"), _("Gaim was unable to send a message")); |
2f03cfd21fc2
[gaim-migrate @ 2275]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2231
diff
changeset
|
562 } |
2086 | 563 return; |
564 } | |
565 | |
566 if (ms->fd != source) | |
567 ms->fd = source; | |
568 | |
569 g_snprintf(buf, sizeof(buf), "USR %d %s %s\n", ++ms->trId, gc->username, ms->auth); | |
570 if (msn_write(ms->fd, buf, strlen(buf)) < 0) { | |
571 g_free(ms->auth); | |
572 g_free(ms); | |
573 return; | |
574 } | |
575 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
576 ms->inpa = gaim_input_add(ms->fd, GAIM_INPUT_READ, msn_switchboard_callback, ms); |
2086 | 577 } |
578 | |
579 struct msn_add_permit { | |
580 struct gaim_connection *gc; | |
581 char *user; | |
582 char *friend; | |
583 }; | |
584 | |
585 static void msn_accept_add(gpointer w, struct msn_add_permit *map) | |
586 { | |
587 struct msn_data *md = map->gc->proto_data; | |
588 char buf[MSN_BUF_LEN]; | |
589 | |
590 g_snprintf(buf, sizeof(buf), "ADD %d AL %s %s\n", ++md->trId, map->user, map->friend); | |
591 if (msn_write(md->fd, buf, strlen(buf)) < 0) { | |
592 hide_login_progress(map->gc, "Write error"); | |
593 signoff(map->gc); | |
594 return; | |
595 } | |
596 } | |
597 | |
598 static void msn_cancel_add(gpointer w, struct msn_add_permit *map) | |
599 { | |
600 g_free(map->user); | |
601 g_free(map->friend); | |
602 g_free(map); | |
603 } | |
604 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
605 static void msn_callback(gpointer data, gint source, GaimInputCondition cond) |
2086 | 606 { |
607 struct gaim_connection *gc = data; | |
608 struct msn_data *md = gc->proto_data; | |
609 char buf[MSN_BUF_LEN]; | |
610 int i = 0; | |
611 | |
612 bzero(buf, sizeof(buf)); | |
613 while ((read(md->fd, buf + i, 1) > 0) && (buf[i++] != '\n')) | |
614 if (i == sizeof(buf)) | |
615 i--; /* yes i know this loses data but we shouldn't get messages this long | |
616 and it's better than possibly writing past our buffer */ | |
617 if (i == 0 || buf[i - 1] != '\n') { | |
618 hide_login_progress(gc, "Error reading from server"); | |
619 signoff(gc); | |
620 return; | |
621 } | |
622 debug_printf("S: %s", buf); | |
623 g_strchomp(buf); | |
624 | |
625 if (!g_strncasecmp(buf, "ADD", 3)) { | |
626 char *list, *user, *friend, *tmp = buf; | |
627 struct msn_add_permit *ap = g_new0(struct msn_add_permit, 1); | |
628 char msg[MSN_BUF_LEN]; | |
629 | |
630 GET_NEXT(tmp); | |
631 GET_NEXT(tmp); | |
632 list = tmp; | |
633 | |
634 GET_NEXT(tmp); | |
635 GET_NEXT(tmp); | |
636 user = tmp; | |
637 | |
638 GET_NEXT(tmp); | |
639 friend = tmp; | |
640 | |
641 if (g_strcasecmp(list, "RL")) | |
642 return; | |
643 | |
644 ap->user = g_strdup(user); | |
645 ap->friend = g_strdup(friend); | |
646 ap->gc = gc; | |
647 | |
648 g_snprintf(msg, sizeof(msg), "The user %s (%s) wants to add you to their buddy list.", | |
649 ap->user, url_decode(ap->friend)); | |
650 | |
651 do_ask_dialog(msg, ap, msn_accept_add, msn_cancel_add); | |
652 } else if (!g_strncasecmp(buf, "BLP", 3)) { | |
653 } else if (!g_strncasecmp(buf, "BPR", 3)) { | |
654 } else if (!g_strncasecmp(buf, "CHG", 3)) { | |
655 } else if (!g_strncasecmp(buf, "CHL", 3)) { | |
656 char *hash = buf; | |
657 char buf2[MSN_BUF_LEN]; | |
658 md5_state_t st; | |
659 md5_byte_t di[16]; | |
660 int i; | |
661 | |
662 GET_NEXT(hash); | |
663 GET_NEXT(hash); | |
664 | |
665 md5_init(&st); | |
666 md5_append(&st, (const md5_byte_t *)hash, strlen(hash)); | |
667 md5_append(&st, (const md5_byte_t *)"Q1P7W2E4J9R8U3S5", strlen("Q1P7W2E4J9R8U3S5")); | |
668 md5_finish(&st, di); | |
669 | |
670 g_snprintf(buf, sizeof(buf), "QRY %d msmsgs@msnmsgr.com 32\r\n", ++md->trId); | |
671 for (i = 0; i < 16; i++) { | |
672 g_snprintf(buf2, sizeof(buf2), "%02x", di[i]); | |
673 strcat(buf, buf2); | |
674 } | |
675 | |
676 if (msn_write(md->fd, buf, strlen(buf)) < 0) { | |
677 hide_login_progress(gc, "Unable to write to server"); | |
678 signoff(gc); | |
679 } | |
680 | |
681 debug_printf("\n"); | |
682 } else if (!g_strncasecmp(buf, "FLN", 3)) { | |
683 char *usr = buf; | |
684 | |
685 GET_NEXT(usr); | |
686 serv_got_update(gc, usr, 0, 0, 0, 0, 0, 0); | |
687 } else if (!g_strncasecmp(buf, "GTC", 3)) { | |
688 } else if (!g_strncasecmp(buf, "INF", 3)) { | |
689 } else if (!g_strncasecmp(buf, "ILN", 3)) { | |
690 char *state, *user, *tmp = buf; | |
691 int status = UC_NORMAL; | |
692 | |
693 GET_NEXT(tmp); | |
694 | |
695 GET_NEXT(tmp); | |
696 state = tmp; | |
697 | |
698 GET_NEXT(tmp); | |
699 user = tmp; | |
700 | |
701 GET_NEXT(tmp); | |
702 | |
703 if (!g_strcasecmp(state, "BSY")) { | |
704 status |= (MSN_BUSY << 5); | |
705 } else if (!g_strcasecmp(state, "IDL")) { | |
706 status |= (MSN_IDLE << 5); | |
707 } else if (!g_strcasecmp(state, "BRB")) { | |
708 status |= (MSN_BRB << 5); | |
709 } else if (!g_strcasecmp(state, "AWY")) { | |
710 status = UC_UNAVAILABLE; | |
711 } else if (!g_strcasecmp(state, "PHN")) { | |
712 status |= (MSN_PHONE << 5); | |
713 } else if (!g_strcasecmp(state, "LUN")) { | |
714 status |= (MSN_LUNCH << 5); | |
715 } | |
716 | |
717 serv_got_update(gc, user, 1, 0, 0, 0, status, 0); | |
718 } else if (!g_strncasecmp(buf, "LST", 3)) { | |
719 char *which, *who, *friend, *tmp = buf; | |
720 | |
721 GET_NEXT(tmp); | |
722 GET_NEXT(tmp); | |
723 which = tmp; | |
724 | |
725 GET_NEXT(tmp); | |
726 GET_NEXT(tmp); | |
727 GET_NEXT(tmp); | |
728 GET_NEXT(tmp); | |
729 who = tmp; | |
730 | |
731 GET_NEXT(tmp); | |
732 friend = url_decode(tmp); | |
733 | |
734 if (!g_strcasecmp(which, "FL")) { | |
735 struct msn_buddy *b = g_new0(struct msn_buddy, 1); | |
736 b->user = g_strdup(who); | |
737 b->friend = g_strdup(friend); | |
738 md->fl = g_slist_append(md->fl, b); | |
739 } else if (!md->imported) { | |
740 if (bud_list_cache_exists(gc)) | |
741 do_import(NULL, gc); | |
742 md->imported = TRUE; | |
743 while (md->fl) { | |
744 struct msn_buddy *mb = md->fl->data; | |
745 struct buddy *b; | |
746 md->fl = g_slist_remove(md->fl, mb); | |
747 if (!(b = find_buddy(gc, mb->user))) | |
748 add_buddy(gc, "Buddies", mb->user, mb->friend); | |
749 else if (!g_strcasecmp(b->name, b->show)) { | |
750 g_snprintf(b->show, sizeof(b->show), "%s", mb->friend); | |
751 handle_buddy_rename(b, b->name); | |
752 } | |
753 g_free(mb->user); | |
754 g_free(mb->friend); | |
755 g_free(mb); | |
756 } | |
757 } | |
758 } else if (!g_strncasecmp(buf, "MSG", 3)) { | |
759 char *user, *tmp = buf; | |
760 int length; | |
761 char *msg, *skiphead, *utf, *final; | |
2169
b7807144bf44
[gaim-migrate @ 2179]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
762 int len, r; |
2086 | 763 |
764 GET_NEXT(tmp); | |
765 user = tmp; | |
766 | |
767 GET_NEXT(tmp); | |
768 | |
769 GET_NEXT(tmp); | |
770 length = atoi(tmp); | |
771 | |
772 msg = g_new0(char, MAX(length + 1, MSN_BUF_LEN)); | |
773 | |
2169
b7807144bf44
[gaim-migrate @ 2179]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
774 for (len = 0; len < length; len += r) { |
b7807144bf44
[gaim-migrate @ 2179]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
775 if ((r = read(md->fd, msg+len, length-len)) <= 0) { |
b7807144bf44
[gaim-migrate @ 2179]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
776 g_free(msg); |
b7807144bf44
[gaim-migrate @ 2179]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
777 hide_login_progress(gc, "Unable to read message"); |
b7807144bf44
[gaim-migrate @ 2179]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
778 signoff(gc); |
b7807144bf44
[gaim-migrate @ 2179]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
779 return; |
b7807144bf44
[gaim-migrate @ 2179]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
780 } |
2086 | 781 } |
782 | |
783 if (!g_strcasecmp(user, "hotmail")) { | |
784 handle_hotmail(gc, msg); | |
785 g_free(msg); | |
786 return; | |
787 } | |
788 | |
789 skiphead = strstr(msg, "\r\n\r\n"); | |
790 if (!skiphead || !skiphead[4]) { | |
791 g_free(msg); | |
792 return; | |
793 } | |
794 skiphead += 4; | |
795 utf = utf8_to_str(skiphead); | |
796 len = MAX(strlen(utf) + 1, BUF_LEN); | |
797 final = g_malloc(len); | |
798 g_snprintf(final, len, "%s", utf); | |
799 g_free(utf); | |
800 | |
801 serv_got_im(gc, user, final, 0, time(NULL)); | |
802 | |
803 g_free(final); | |
804 g_free(msg); | |
805 } else if (!g_strncasecmp(buf, "NLN", 3)) { | |
806 char *state, *user, *tmp = buf; | |
807 int status = UC_NORMAL; | |
808 | |
809 GET_NEXT(tmp); | |
810 state = tmp; | |
811 | |
812 GET_NEXT(tmp); | |
813 user = tmp; | |
814 | |
815 GET_NEXT(tmp); | |
816 | |
817 if (!g_strcasecmp(state, "BSY")) { | |
818 status |= (MSN_BUSY << 5); | |
819 } else if (!g_strcasecmp(state, "IDL")) { | |
820 status |= (MSN_IDLE << 5); | |
821 } else if (!g_strcasecmp(state, "BRB")) { | |
822 status |= (MSN_BRB << 5); | |
823 } else if (!g_strcasecmp(state, "AWY")) { | |
824 status = UC_UNAVAILABLE; | |
825 } else if (!g_strcasecmp(state, "PHN")) { | |
826 status |= (MSN_PHONE << 5); | |
827 } else if (!g_strcasecmp(state, "LUN")) { | |
828 status |= (MSN_LUNCH << 5); | |
829 } | |
830 | |
831 serv_got_update(gc, user, 1, 0, 0, 0, status, 0); | |
832 } else if (!g_strncasecmp(buf, "OUT", 3)) { | |
833 } else if (!g_strncasecmp(buf, "PRP", 3)) { | |
834 } else if (!g_strncasecmp(buf, "QRY", 3)) { | |
2213
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
835 } else if (!g_strncasecmp(buf, "REA", 3)) { |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
836 char *friend, *tmp = buf; |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
837 |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
838 GET_NEXT(tmp); |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
839 GET_NEXT(tmp); |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
840 GET_NEXT(tmp); |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
841 GET_NEXT(tmp); |
2219
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
842 friend = url_decode(tmp); |
2213
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
843 |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
844 g_snprintf(gc->displayname, sizeof(gc->displayname), "%s", friend); |
2086 | 845 } else if (!g_strncasecmp(buf, "REM", 3)) { |
846 } else if (!g_strncasecmp(buf, "RNG", 3)) { | |
847 struct msn_switchboard *ms; | |
848 char *sessid, *ssaddr, *auth, *user; | |
849 int port, i = 0; | |
850 char *tmp = buf; | |
851 | |
852 GET_NEXT(tmp); | |
853 sessid = tmp; | |
854 | |
855 GET_NEXT(tmp); | |
856 ssaddr = tmp; | |
857 | |
858 GET_NEXT(tmp); | |
859 | |
860 GET_NEXT(tmp); | |
861 auth = tmp; | |
862 | |
863 GET_NEXT(tmp); | |
864 user = tmp; | |
865 GET_NEXT(tmp); | |
866 | |
867 while (ssaddr[i] && ssaddr[i] != ':') i++; | |
868 if (ssaddr[i] == ':') { | |
869 char *x = &ssaddr[i + 1]; | |
870 ssaddr[i] = 0; | |
871 port = atoi(x); | |
872 } else | |
873 port = 1863; | |
874 | |
875 ms = g_new0(struct msn_switchboard, 1); | |
876 ms->user = g_strdup(user); | |
877 ms->sessid = g_strdup(sessid); | |
878 ms->auth = g_strdup(auth); | |
879 ms->gc = gc; | |
880 ms->fd = proxy_connect(ssaddr, port, msn_rng_connect, ms); | |
881 } else if (!g_strncasecmp(buf, "SYN", 3)) { | |
882 } else if (!g_strncasecmp(buf, "USR", 3)) { | |
883 } else if (!g_strncasecmp(buf, "XFR", 3)) { | |
884 char *host = strstr(buf, "SB"); | |
885 int port; | |
886 int i = 0; | |
887 gboolean switchboard = TRUE; | |
888 char *tmp; | |
889 | |
890 if (!host) { | |
891 host = strstr(buf, "NS"); | |
892 if (!host) { | |
893 hide_login_progress(gc, "Got invalid XFR\n"); | |
894 signoff(gc); | |
895 return; | |
896 } | |
897 switchboard = FALSE; | |
898 } | |
899 | |
900 GET_NEXT(host); | |
901 while (host[i] && host[i] != ':') i++; | |
902 if (host[i] == ':') { | |
903 tmp = &host[i + 1]; | |
904 host[i] = 0; | |
905 while (isdigit(*tmp)) tmp++; | |
906 *tmp++ = 0; | |
907 port = atoi(&host[i + 1]); | |
908 } else { | |
909 port = 1863; | |
910 tmp = host; | |
911 GET_NEXT(tmp); | |
912 } | |
913 | |
914 if (switchboard) { | |
915 struct msn_switchboard *ms = msn_find_writable_switch(gc); | |
916 if (!ms) | |
917 return; | |
918 | |
919 GET_NEXT(tmp); | |
920 | |
921 ms->auth = g_strdup(tmp); | |
922 ms->fd = proxy_connect(host, port, msn_ss_xfr_connect, ms); | |
923 } else { | |
924 close(md->fd); | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
925 gaim_input_remove(md->inpa); |
2086 | 926 md->inpa = 0; |
927 md->fd = proxy_connect(host, port, msn_login_xfr_connect, gc); | |
928 } | |
929 } else if (isdigit(*buf)) { | |
930 handle_errcode(buf, TRUE); | |
931 } else { | |
932 debug_printf("Unhandled message!\n"); | |
933 } | |
934 } | |
935 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
936 static void msn_login_xfr_connect(gpointer data, gint source, GaimInputCondition cond) |
2086 | 937 { |
938 struct gaim_connection *gc = data; | |
939 struct msn_data *md; | |
940 char buf[MSN_BUF_LEN]; | |
941 | |
2210
3a6fd1e8f00a
[gaim-migrate @ 2220]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
942 if (!g_slist_find(connections, gc)) { |
3a6fd1e8f00a
[gaim-migrate @ 2220]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
943 close(source); |
2086 | 944 return; |
2210
3a6fd1e8f00a
[gaim-migrate @ 2220]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
945 } |
2086 | 946 |
947 md = gc->proto_data; | |
948 | |
949 if (md->fd != source) | |
950 md->fd = source; | |
951 | |
952 if (md->fd == -1) { | |
953 hide_login_progress(gc, "Unable to connect to Notification Server"); | |
954 signoff(gc); | |
955 return; | |
956 } | |
957 | |
2226
2a09a177ed5f
[gaim-migrate @ 2236]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2219
diff
changeset
|
958 g_snprintf(buf, sizeof(buf), "VER %d MSNP5\n", ++md->trId); |
2086 | 959 if (msn_write(md->fd, buf, strlen(buf)) < 0) { |
960 hide_login_progress(gc, "Unable to talk to Notification Server"); | |
961 signoff(gc); | |
962 return; | |
963 } | |
964 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
965 md->inpa = gaim_input_add(md->fd, GAIM_INPUT_READ, msn_login_callback, gc); |
2086 | 966 } |
967 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
968 static void msn_login_callback(gpointer data, gint source, GaimInputCondition cond) |
2086 | 969 { |
970 struct gaim_connection *gc = data; | |
971 struct msn_data *md = gc->proto_data; | |
972 char buf[MSN_BUF_LEN]; | |
973 int i = 0; | |
974 | |
975 bzero(buf, sizeof(buf)); | |
976 while ((read(md->fd, buf + i, 1) > 0) && (buf[i++] != '\n')) | |
977 if (i == sizeof(buf)) | |
978 i--; /* yes i know this loses data but we shouldn't get messages this long | |
979 and it's better than possibly writing past our buffer */ | |
980 if (i == 0 || buf[i - 1] != '\n') { | |
981 hide_login_progress(gc, "Error reading from server"); | |
982 signoff(gc); | |
983 return; | |
984 } | |
985 debug_printf("S: %s", buf); | |
986 g_strchomp(buf); | |
987 | |
988 if (!g_strncasecmp(buf, "VER", 3)) { | |
2226
2a09a177ed5f
[gaim-migrate @ 2236]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2219
diff
changeset
|
989 /* we got VER, check to see that MSNP5 is in the list, then send INF */ |
2a09a177ed5f
[gaim-migrate @ 2236]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2219
diff
changeset
|
990 if (!strstr(buf, "MSNP5")) { |
2086 | 991 hide_login_progress(gc, "Protocol not supported"); |
992 signoff(gc); | |
993 return; | |
994 } | |
995 | |
996 g_snprintf(buf, sizeof(buf), "INF %d\n", ++md->trId); | |
997 if (msn_write(md->fd, buf, strlen(buf)) < 0) { | |
998 hide_login_progress(gc, "Unable to request INF\n"); | |
999 signoff(gc); | |
1000 return; | |
1001 } | |
1002 } else if (!g_strncasecmp(buf, "INF", 3)) { | |
1003 /* check to make sure we can use md5 */ | |
1004 if (!strstr(buf, "MD5")) { | |
1005 hide_login_progress(gc, "Unable to login using MD5"); | |
1006 signoff(gc); | |
1007 return; | |
1008 } | |
1009 | |
1010 g_snprintf(buf, sizeof(buf), "USR %d MD5 I %s\n", ++md->trId, gc->username); | |
1011 if (msn_write(md->fd, buf, strlen(buf)) < 0) { | |
1012 hide_login_progress(gc, "Unable to send USR\n"); | |
1013 signoff(gc); | |
1014 return; | |
1015 } | |
1016 | |
1017 set_login_progress(gc, 3, "Requesting to send password"); | |
1018 } else if (!g_strncasecmp(buf, "USR", 3)) { | |
2210
3a6fd1e8f00a
[gaim-migrate @ 2220]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1019 char *resp, *friend, *tmp = buf; |
3a6fd1e8f00a
[gaim-migrate @ 2220]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1020 |
3a6fd1e8f00a
[gaim-migrate @ 2220]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1021 GET_NEXT(tmp); |
3a6fd1e8f00a
[gaim-migrate @ 2220]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1022 GET_NEXT(tmp); |
3a6fd1e8f00a
[gaim-migrate @ 2220]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1023 resp = tmp; |
3a6fd1e8f00a
[gaim-migrate @ 2220]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1024 GET_NEXT(tmp); |
3a6fd1e8f00a
[gaim-migrate @ 2220]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1025 GET_NEXT(tmp); |
3a6fd1e8f00a
[gaim-migrate @ 2220]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1026 friend = tmp; |
2213
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1027 GET_NEXT(tmp); |
2219
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
1028 friend = url_decode(friend); |
2210
3a6fd1e8f00a
[gaim-migrate @ 2220]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1029 |
2086 | 1030 /* so here, we're either getting the challenge or the OK */ |
2213
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1031 if (!g_strcasecmp(resp, "OK")) { |
2210
3a6fd1e8f00a
[gaim-migrate @ 2220]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1032 g_snprintf(gc->displayname, sizeof(gc->displayname), "%s", friend); |
3a6fd1e8f00a
[gaim-migrate @ 2220]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1033 |
2086 | 1034 g_snprintf(buf, sizeof(buf), "SYN %d 0\n", ++md->trId); |
1035 if (msn_write(md->fd, buf, strlen(buf)) < 0) { | |
1036 hide_login_progress(gc, "Unable to write"); | |
1037 signoff(gc); | |
1038 return; | |
1039 } | |
1040 | |
1041 g_snprintf(buf, sizeof(buf), "CHG %d NLN\n", ++md->trId); | |
1042 if (msn_write(md->fd, buf, strlen(buf)) < 0) { | |
1043 hide_login_progress(gc, "Unable to write"); | |
1044 signoff(gc); | |
1045 return; | |
1046 } | |
1047 | |
1048 g_snprintf(buf, sizeof(buf), "BLP %d AL\n", ++md->trId); | |
1049 if (msn_write(md->fd, buf, strlen(buf)) < 0) { | |
1050 hide_login_progress(gc, "Unable to write"); | |
1051 signoff(gc); | |
1052 return; | |
1053 } | |
1054 | |
1055 account_online(gc); | |
1056 serv_finish_login(gc); | |
1057 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1058 gaim_input_remove(md->inpa); |
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1059 md->inpa = gaim_input_add(md->fd, GAIM_INPUT_READ, msn_callback, gc); |
2213
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1060 } else if (!g_strcasecmp(resp, "MD5")) { |
2086 | 1061 char buf2[MSN_BUF_LEN]; |
1062 md5_state_t st; | |
1063 md5_byte_t di[16]; | |
1064 int i; | |
1065 | |
2213
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1066 g_snprintf(buf2, sizeof(buf2), "%s%s", friend, gc->password); |
2086 | 1067 |
1068 md5_init(&st); | |
1069 md5_append(&st, (const md5_byte_t *)buf2, strlen(buf2)); | |
1070 md5_finish(&st, di); | |
1071 | |
1072 g_snprintf(buf, sizeof(buf), "USR %d MD5 S ", ++md->trId); | |
1073 for (i = 0; i < 16; i++) { | |
1074 g_snprintf(buf2, sizeof(buf2), "%02x", di[i]); | |
1075 strcat(buf, buf2); | |
1076 } | |
1077 strcat(buf, "\n"); | |
1078 | |
1079 if (msn_write(md->fd, buf, strlen(buf)) < 0) { | |
1080 hide_login_progress(gc, "Unable to send password"); | |
1081 signoff(gc); | |
1082 return; | |
1083 } | |
1084 | |
1085 set_login_progress(gc, 4, "Password sent"); | |
1086 } | |
1087 } else if (!g_strncasecmp(buf, "XFR", 3)) { | |
1088 char *host = strstr(buf, "NS"); | |
1089 int port; | |
1090 int i = 0; | |
1091 | |
1092 if (!host) { | |
1093 hide_login_progress(gc, "Got invalid XFR\n"); | |
1094 signoff(gc); | |
1095 return; | |
1096 } | |
1097 | |
1098 GET_NEXT(host); | |
1099 while (host[i] && host[i] != ':') i++; | |
1100 if (host[i] == ':') { | |
1101 char *x = &host[i + 1]; | |
1102 host[i] = 0; | |
1103 port = atoi(x); | |
1104 } else | |
1105 port = 1863; | |
1106 | |
1107 close(md->fd); | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1108 gaim_input_remove(md->inpa); |
2086 | 1109 md->inpa = 0; |
1110 md->fd = 0; | |
1111 md->fd = proxy_connect(host, port, msn_login_xfr_connect, gc); | |
1112 } else { | |
1113 if (isdigit(*buf)) | |
1114 hide_login_progress(gc, handle_errcode(buf, FALSE)); | |
1115 else | |
1116 hide_login_progress(gc, "Unable to parse message"); | |
1117 signoff(gc); | |
1118 return; | |
1119 } | |
1120 } | |
1121 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1122 static void msn_login_connect(gpointer data, gint source, GaimInputCondition cond) |
2086 | 1123 { |
1124 struct gaim_connection *gc = data; | |
1125 struct msn_data *md; | |
1126 char buf[1024]; | |
1127 | |
2210
3a6fd1e8f00a
[gaim-migrate @ 2220]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1128 if (!g_slist_find(connections, gc)) { |
3a6fd1e8f00a
[gaim-migrate @ 2220]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1129 close(source); |
2086 | 1130 return; |
2210
3a6fd1e8f00a
[gaim-migrate @ 2220]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1131 } |
2086 | 1132 |
1133 md = gc->proto_data; | |
1134 | |
1135 if (md->fd != source) | |
1136 md->fd = source; | |
1137 | |
1138 if (md->fd == -1) { | |
1139 hide_login_progress(gc, "Unable to connect"); | |
1140 signoff(gc); | |
1141 return; | |
1142 } | |
1143 | |
2226
2a09a177ed5f
[gaim-migrate @ 2236]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2219
diff
changeset
|
1144 g_snprintf(buf, sizeof(buf), "VER %d MSNP5\n", ++md->trId); |
2086 | 1145 if (msn_write(md->fd, buf, strlen(buf)) < 0) { |
1146 hide_login_progress(gc, "Unable to write to server"); | |
1147 signoff(gc); | |
1148 return; | |
1149 } | |
1150 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1151 md->inpa = gaim_input_add(md->fd, GAIM_INPUT_READ, msn_login_callback, gc); |
2086 | 1152 set_login_progress(gc, 2, "Synching with server"); |
1153 } | |
1154 | |
1155 static void msn_login(struct aim_user *user) | |
1156 { | |
1157 struct gaim_connection *gc = new_gaim_conn(user); | |
1158 struct msn_data *md = gc->proto_data = g_new0(struct msn_data, 1); | |
1159 | |
1160 set_login_progress(gc, 1, "Connecting"); | |
1161 | |
1162 g_snprintf(gc->username, sizeof(gc->username), "%s", msn_normalize(gc->username)); | |
1163 | |
1164 md->fd = proxy_connect("messenger.hotmail.com", 1863, msn_login_connect, gc); | |
1165 } | |
1166 | |
1167 static void msn_close(struct gaim_connection *gc) | |
1168 { | |
1169 struct msn_data *md = gc->proto_data; | |
1170 close(md->fd); | |
1171 if (md->inpa) | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1172 gaim_input_remove(md->inpa); |
2086 | 1173 while (md->switches) |
1174 msn_kill_switch(md->switches->data); | |
1175 while (md->fl) { | |
1176 struct msn_buddy *tmp = md->fl->data; | |
1177 md->fl = g_slist_remove(md->fl, tmp); | |
1178 g_free(tmp->user); | |
1179 g_free(tmp->friend); | |
1180 g_free(tmp); | |
1181 } | |
1182 g_free(md); | |
1183 } | |
1184 | |
2231
8c4ff1a368bd
[gaim-migrate @ 2241]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2230
diff
changeset
|
1185 static int msn_send_im(struct gaim_connection *gc, char *who, char *message, int flags) |
2086 | 1186 { |
1187 struct msn_data *md = gc->proto_data; | |
1188 struct msn_switchboard *ms = msn_find_switch(gc, who); | |
1189 char buf[MSN_BUF_LEN]; | |
1190 | |
1191 if (ms) { | |
1192 char *utf8 = str_to_utf8(message); | |
1193 g_snprintf(buf, sizeof(buf), "MSG %d N %d\r\n%s%s", ++ms->trId, | |
1194 strlen(MIME_HEADER) + strlen(utf8), | |
1195 MIME_HEADER, utf8); | |
1196 g_free(utf8); | |
1197 if (msn_write(ms->fd, buf, strlen(buf)) < 0) | |
1198 msn_kill_switch(ms); | |
1199 debug_printf("\n"); | |
1200 } else if (strcmp(who, gc->username)) { | |
1201 g_snprintf(buf, MSN_BUF_LEN, "XFR %d SB\n", ++md->trId); | |
1202 if (msn_write(md->fd, buf, strlen(buf)) < 0) { | |
1203 hide_login_progress(gc, "Write error"); | |
1204 signoff(gc); | |
2123
56c4382f2909
[gaim-migrate @ 2133]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2093
diff
changeset
|
1205 return 0; |
2086 | 1206 } |
1207 | |
1208 ms = g_new0(struct msn_switchboard, 1); | |
1209 md->switches = g_slist_append(md->switches, ms); | |
1210 ms->user = g_strdup(who); | |
1211 ms->txqueue = g_strdup(message); | |
1212 ms->gc = gc; | |
1213 ms->fd = -1; | |
1214 } else | |
1215 /* in msn you can't send messages to yourself, so we'll fake like we received it ;) */ | |
2273
0b5c3338fa3d
[gaim-migrate @ 2283]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2265
diff
changeset
|
1216 serv_got_im(gc, who, message, flags | IM_FLAG_GAIMUSER, time(NULL)); |
2123
56c4382f2909
[gaim-migrate @ 2133]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2093
diff
changeset
|
1217 return 0; |
2086 | 1218 } |
1219 | |
2167
edf8c5a70e5b
[gaim-migrate @ 2177]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2162
diff
changeset
|
1220 static int msn_chat_send(struct gaim_connection *gc, int id, char *message) |
2086 | 1221 { |
1222 struct msn_switchboard *ms = msn_find_switch_by_id(gc, id); | |
1223 char buf[MSN_BUF_LEN]; | |
1224 | |
1225 if (!ms) | |
2167
edf8c5a70e5b
[gaim-migrate @ 2177]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2162
diff
changeset
|
1226 return -EINVAL; |
2086 | 1227 |
1228 g_snprintf(buf, sizeof(buf), "MSG %d N %d\r\n%s%s", ++ms->trId, | |
1229 strlen(MIME_HEADER) + strlen(message), | |
1230 MIME_HEADER, message); | |
1231 if (msn_write(ms->fd, buf, strlen(buf)) < 0) | |
1232 msn_kill_switch(ms); | |
1233 debug_printf("\n"); | |
1234 serv_got_chat_in(gc, id, gc->username, 0, message, time(NULL)); | |
2167
edf8c5a70e5b
[gaim-migrate @ 2177]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2162
diff
changeset
|
1235 return 0; |
2086 | 1236 } |
1237 | |
1238 static void msn_chat_invite(struct gaim_connection *gc, int id, char *msg, char *who) | |
1239 { | |
1240 struct msn_switchboard *ms = msn_find_switch_by_id(gc, id); | |
1241 char buf[MSN_BUF_LEN]; | |
1242 | |
1243 if (!ms) | |
1244 return; | |
1245 | |
1246 g_snprintf(buf, sizeof(buf), "CAL %d %s\n", ++ms->trId, who); | |
1247 if (msn_write(ms->fd, buf, strlen(buf)) < 0) | |
1248 msn_kill_switch(ms); | |
1249 } | |
1250 | |
1251 static void msn_chat_leave(struct gaim_connection *gc, int id) | |
1252 { | |
1253 struct msn_switchboard *ms = msn_find_switch_by_id(gc, id); | |
1254 char buf[MSN_BUF_LEN]; | |
1255 | |
1256 if (!ms) | |
1257 return; | |
1258 | |
1259 g_snprintf(buf, sizeof(buf), "OUT\n"); | |
1260 if (msn_write(ms->fd, buf, strlen(buf)) < 0) | |
1261 msn_kill_switch(ms); | |
1262 } | |
1263 | |
1264 static GList *msn_away_states() | |
1265 { | |
1266 GList *m = NULL; | |
1267 | |
1268 m = g_list_append(m, "Available"); | |
1269 m = g_list_append(m, "Away From Computer"); | |
1270 m = g_list_append(m, "Be Right Back"); | |
1271 m = g_list_append(m, "Busy"); | |
1272 m = g_list_append(m, "On The Phone"); | |
1273 m = g_list_append(m, "Out To Lunch"); | |
2152
f631cfc8e824
[gaim-migrate @ 2162]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1274 m = g_list_append(m, "Hidden"); |
2086 | 1275 |
1276 return m; | |
1277 } | |
1278 | |
1279 static void msn_set_away(struct gaim_connection *gc, char *state, char *msg) | |
1280 { | |
1281 struct msn_data *md = gc->proto_data; | |
1282 char buf[MSN_BUF_LEN]; | |
1283 char *away; | |
1284 | |
1285 gc->away = NULL; | |
1286 | |
1287 if (msg) { | |
1288 gc->away = ""; | |
1289 away = "AWY"; | |
1290 } else if (state) { | |
1291 gc->away = ""; | |
1292 | |
1293 if (!strcmp(state, "Away From Computer")) | |
1294 away = "AWY"; | |
1295 else if (!strcmp(state, "Be Right Back")) | |
1296 away = "BRB"; | |
1297 else if (!strcmp(state, "Busy")) | |
1298 away = "BSY"; | |
1299 else if (!strcmp(state, "On The Phone")) | |
1300 away = "PHN"; | |
1301 else if (!strcmp(state, "Out To Lunch")) | |
1302 away = "LUN"; | |
2152
f631cfc8e824
[gaim-migrate @ 2162]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1303 else if (!strcmp(state, "Hidden")) |
f631cfc8e824
[gaim-migrate @ 2162]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1304 away = "HDN"; |
2086 | 1305 else { |
1306 gc->away = NULL; | |
1307 away = "NLN"; | |
1308 } | |
1309 } else if (gc->is_idle) | |
1310 away = "IDL"; | |
1311 else | |
1312 away = "NLN"; | |
1313 | |
1314 g_snprintf(buf, sizeof(buf), "CHG %d %s\n", ++md->trId, away); | |
1315 if (msn_write(md->fd, buf, strlen(buf)) < 0) { | |
1316 hide_login_progress(gc, "Write error"); | |
1317 signoff(gc); | |
1318 return; | |
1319 } | |
1320 } | |
1321 | |
1322 static void msn_set_idle(struct gaim_connection *gc, int idle) | |
1323 { | |
1324 struct msn_data *md = gc->proto_data; | |
1325 char buf[MSN_BUF_LEN]; | |
1326 | |
1327 if (gc->away) | |
1328 return; | |
1329 if (idle) | |
1330 g_snprintf(buf, sizeof(buf), "CHG %d IDL\n", ++md->trId); | |
1331 else | |
1332 g_snprintf(buf, sizeof(buf), "CHG %d NLN\n", ++md->trId); | |
1333 if (msn_write(md->fd, buf, strlen(buf)) < 0) { | |
1334 hide_login_progress(gc, "Write error"); | |
1335 signoff(gc); | |
1336 return; | |
1337 } | |
1338 } | |
1339 | |
1340 static char **msn_list_icon(int uc) | |
1341 { | |
1342 if (uc == UC_NORMAL) | |
1343 return msn_online_xpm; | |
1344 | |
1345 return msn_away_xpm; | |
1346 } | |
1347 | |
1348 static char *msn_get_away_text(int s) | |
1349 { | |
1350 switch (s) { | |
1351 case MSN_BUSY : | |
1352 return "Busy"; | |
1353 case MSN_BRB : | |
1354 return "Be right back"; | |
1355 case MSN_AWAY : | |
1356 return "Away from the computer"; | |
1357 case MSN_PHONE : | |
1358 return "On the phone"; | |
1359 case MSN_LUNCH : | |
1360 return "Out to lunch"; | |
1361 case MSN_IDLE : | |
1362 return "Idle"; | |
1363 default: | |
1364 return "Available"; | |
1365 } | |
1366 } | |
1367 | |
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2169
diff
changeset
|
1368 static GList *msn_buddy_menu(struct gaim_connection *gc, char *who) |
2086 | 1369 { |
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2169
diff
changeset
|
1370 GList *m = NULL; |
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2169
diff
changeset
|
1371 struct proto_buddy_menu *pbm; |
2086 | 1372 struct buddy *b = find_buddy(gc, who); |
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2169
diff
changeset
|
1373 static char buf[MSN_BUF_LEN]; |
2086 | 1374 |
1375 if (!b || !(b->uc >> 5)) | |
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2169
diff
changeset
|
1376 return m; |
2086 | 1377 |
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2169
diff
changeset
|
1378 pbm = g_new0(struct proto_buddy_menu, 1); |
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2169
diff
changeset
|
1379 g_snprintf(buf, sizeof(buf), "Status: %s", msn_get_away_text(b->uc >> 5)); |
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2169
diff
changeset
|
1380 pbm->label = buf; |
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2169
diff
changeset
|
1381 pbm->callback = NULL; |
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2169
diff
changeset
|
1382 pbm->gc = gc; |
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2169
diff
changeset
|
1383 m = g_list_append(m, pbm); |
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2169
diff
changeset
|
1384 |
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2169
diff
changeset
|
1385 return m; |
2086 | 1386 } |
1387 | |
1388 static void msn_add_buddy(struct gaim_connection *gc, char *who) | |
1389 { | |
1390 struct msn_data *md = gc->proto_data; | |
1391 char buf[MSN_BUF_LEN]; | |
1392 GSList *l = md->fl; | |
1393 | |
1394 while (l) { | |
1395 struct msn_buddy *b = l->data; | |
1396 if (!g_strcasecmp(who, b->user)) | |
1397 break; | |
1398 l = l->next; | |
1399 } | |
1400 if (l) | |
1401 return; | |
1402 | |
1403 g_snprintf(buf, sizeof(buf), "ADD %d FL %s %s\n", ++md->trId, who, who); | |
1404 if (msn_write(md->fd, buf, strlen(buf)) < 0) { | |
1405 hide_login_progress(gc, "Write error"); | |
1406 signoff(gc); | |
1407 return; | |
1408 } | |
1409 } | |
1410 | |
1411 static void msn_rem_buddy(struct gaim_connection *gc, char *who) | |
1412 { | |
1413 struct msn_data *md = gc->proto_data; | |
1414 char buf[MSN_BUF_LEN]; | |
1415 | |
1416 g_snprintf(buf, sizeof(buf), "REM %d FL %s\n", ++md->trId, who); | |
1417 if (msn_write(md->fd, buf, strlen(buf)) < 0) { | |
1418 hide_login_progress(gc, "Write error"); | |
1419 signoff(gc); | |
1420 return; | |
1421 } | |
1422 } | |
1423 | |
2213
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1424 static void msn_act_id(gpointer data, char *entry) |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1425 { |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1426 struct gaim_connection *gc = data; |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1427 struct msn_data *md = gc->proto_data; |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1428 char buf[MSN_BUF_LEN]; |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1429 |
2219
20a4d5da0b95
[gaim-migrate @ 2229]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2213
diff
changeset
|
1430 g_snprintf(buf, sizeof(buf), "REA %d %s %s\n", ++md->trId, gc->username, url_encode(entry)); |
2213
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1431 if (msn_write(md->fd, buf, strlen(buf)) < 0) { |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1432 hide_login_progress(gc, "Write error"); |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1433 signoff(gc); |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1434 return; |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1435 } |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1436 } |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1437 |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1438 static void msn_do_action(struct gaim_connection *gc, char *act) |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1439 { |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1440 if (!strcmp(act, "Set Friendly Name")) { |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1441 do_prompt_dialog("Set Friendly Name:", gc, msn_act_id, NULL); |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1442 } |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1443 } |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1444 |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1445 static GList *msn_actions() |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1446 { |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1447 GList *m = NULL; |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1448 |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1449 m = g_list_append(m, "Set Friendly Name"); |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1450 |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1451 return m; |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1452 } |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1453 |
2086 | 1454 static struct prpl *my_protocol = NULL; |
1455 | |
1456 void msn_init(struct prpl *ret) | |
1457 { | |
1458 ret->protocol = PROTO_MSN; | |
2153
0befa2d2e540
[gaim-migrate @ 2163]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2152
diff
changeset
|
1459 ret->options = OPT_PROTO_MAIL_CHECK; |
2086 | 1460 ret->name = msn_name; |
1461 ret->list_icon = msn_list_icon; | |
1462 ret->buddy_menu = msn_buddy_menu; | |
1463 ret->login = msn_login; | |
1464 ret->close = msn_close; | |
1465 ret->send_im = msn_send_im; | |
1466 ret->away_states = msn_away_states; | |
1467 ret->set_away = msn_set_away; | |
1468 ret->set_idle = msn_set_idle; | |
1469 ret->add_buddy = msn_add_buddy; | |
1470 ret->remove_buddy = msn_rem_buddy; | |
1471 ret->chat_send = msn_chat_send; | |
1472 ret->chat_invite = msn_chat_invite; | |
1473 ret->chat_leave = msn_chat_leave; | |
1474 ret->normalize = msn_normalize; | |
2213
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1475 ret->do_action = msn_do_action; |
a226ebf4be47
[gaim-migrate @ 2223]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2210
diff
changeset
|
1476 ret->actions = msn_actions; |
2086 | 1477 |
1478 my_protocol = ret; | |
1479 } | |
1480 | |
1481 #ifndef STATIC | |
1482 | |
1483 char *gaim_plugin_init(GModule *handle) | |
1484 { | |
1485 load_protocol(msn_init, sizeof(struct prpl)); | |
1486 return NULL; | |
1487 } | |
1488 | |
1489 void gaim_plugin_remove() | |
1490 { | |
1491 struct prpl *p = find_prpl(PROTO_MSN); | |
1492 if (p == my_protocol) | |
1493 unload_protocol(p); | |
1494 } | |
1495 | |
1496 char *name() | |
1497 { | |
1498 return "MSN"; | |
1499 } | |
1500 | |
1501 char *description() | |
1502 { | |
2162
a464da684307
[gaim-migrate @ 2172]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2153
diff
changeset
|
1503 return PRPL_DESC("MSN"); |
2086 | 1504 } |
1505 | |
1506 #endif |