Mercurial > pidgin
comparison src/toc.c @ 1106:5bc8fdacd2cb
[gaim-migrate @ 1116]
lots of changes.
buddy.c: just in general tried to get things to work better. moving things in the edit list window and signing off should be handled better in the main buddy list window (watch out for flashes).
gaim.h: removed toc-specific things and moved them to toc.c and rvous.c as needed.
gtkhtml.c: possible fix for AOL 6.0 problems (I wasn't able to reproduce the problem before or after the fix, but i fixed what i think might have been causing the problem).
multi.c: moved LOGIN_STEPS from gaim.h here and actually use it now
oscar.c: moved an oscar-specific struct definition from gaim.h here and also handle problems better
perl.c: fix for stupid problem
rvous.c: first pass at attempt to be able to remove toc.c and rvous.c (though this will never happen; gaim will support toc as long as aol does) without cruft. gaim is now only dependent on toc.c and rvous.c for toc_build_config and parse_toc_buddy_list, which gaim needs to save and read its buddy list.
toc.c: rewrote the signin process so that the read()'s won't block. it's not actually a non-blocking read; it's just that it won't ever get to the read until there's data to be read (thanks to the gdk_input watcher). this means the cancel button should work after it's connected, but it's still not a non-blocking connect.
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Mon, 20 Nov 2000 07:24:18 +0000 |
parents | f168625b63fe |
children | 3f56704a09bd |
comparison
equal
deleted
inserted
replaced
1105:c964df5b2a84 | 1106:5bc8fdacd2cb |
---|---|
45 #include "pixmaps/aol_icon.xpm" | 45 #include "pixmaps/aol_icon.xpm" |
46 #include "pixmaps/away_icon.xpm" | 46 #include "pixmaps/away_icon.xpm" |
47 #include "pixmaps/dt_icon.xpm" | 47 #include "pixmaps/dt_icon.xpm" |
48 #include "pixmaps/free_icon.xpm" | 48 #include "pixmaps/free_icon.xpm" |
49 | 49 |
50 #define REVISION "gaim:$Revision: 1110 $" | 50 #define REVISION "gaim:$Revision: 1116 $" |
51 | |
52 #define TYPE_SIGNON 1 | |
53 #define TYPE_DATA 2 | |
54 #define TYPE_ERROR 3 | |
55 #define TYPE_SIGNOFF 4 | |
56 #define TYPE_KEEPALIVE 5 | |
57 | |
58 #define FLAPON "FLAPON\r\n\r\n" | |
59 #define ROAST "Tic/Toc" | |
60 | |
61 #define TOC_HOST "toc.oscar.aol.com" | |
62 #define TOC_PORT 9898 | |
63 #define AUTH_HOST "login.oscar.aol.com" | |
64 #define AUTH_PORT 5190 | |
65 #define LANGUAGE "english" | |
66 | |
67 #define STATE_OFFLINE 0 | |
68 #define STATE_FLAPON 1 | |
69 #define STATE_SIGNON_REQUEST 2 | |
70 #define STATE_ONLINE 3 | |
71 #define STATE_PAUSE 4 | |
51 | 72 |
52 struct toc_data { | 73 struct toc_data { |
53 int toc_fd; | 74 int toc_fd; |
54 int seqno; | 75 int seqno; |
55 int state; | 76 int state; |
56 }; | 77 }; |
57 | 78 |
58 | 79 struct sflap_hdr { |
59 static unsigned int peer_ver=0; | 80 unsigned char ast; |
60 #ifdef _WIN32 | 81 unsigned char type; |
61 static int win32_r; | 82 unsigned short seqno; |
62 #endif | 83 unsigned short len; |
63 | 84 }; |
64 static int toc_signon(struct gaim_connection *); | 85 |
86 struct signon { | |
87 unsigned int ver; | |
88 unsigned short tag; | |
89 unsigned short namelen; | |
90 char username[80]; | |
91 }; | |
65 | 92 |
66 /* constants to identify proto_opts */ | 93 /* constants to identify proto_opts */ |
67 #define USEROPT_AUTH 0 | 94 #define USEROPT_AUTH 0 |
68 #define USEROPT_AUTHPORT 1 | 95 #define USEROPT_AUTHPORT 1 |
69 #define USEROPT_SOCKSHOST 2 | 96 #define USEROPT_SOCKSHOST 2 |
70 #define USEROPT_SOCKSPORT 3 | 97 #define USEROPT_SOCKSPORT 3 |
71 #define USEROPT_PROXYTYPE 4 | 98 #define USEROPT_PROXYTYPE 4 |
72 | 99 |
100 static void toc_callback(gpointer, gint, GdkInputCondition); | |
101 static unsigned char *roast_password(char *); | |
102 | |
73 /* ok. this function used to take username/password, and return 0 on success. | 103 /* ok. this function used to take username/password, and return 0 on success. |
74 * now, it takes username/password, and returns NULL on error or a new gaim_connection | 104 * now, it takes username/password, and returns NULL on error or a new gaim_connection |
75 * on success. */ | 105 * on success. */ |
76 void toc_login(struct aim_user *user) | 106 static void toc_login(struct aim_user *user) { |
77 { | |
78 char *config; | |
79 struct gaim_connection *gc; | 107 struct gaim_connection *gc; |
80 struct toc_data *tdt; | 108 struct toc_data *tdt; |
81 char buf[80]; | 109 char buf[80]; |
82 char buf2[2048]; | |
83 | 110 |
84 gc = new_gaim_conn(user); | 111 gc = new_gaim_conn(user); |
85 gc->proto_data = tdt = g_new0(struct toc_data, 1); | 112 gc->proto_data = tdt = g_new0(struct toc_data, 1); |
86 | 113 |
87 g_snprintf(buf, sizeof(buf), "Looking up %s", | 114 g_snprintf(buf, sizeof buf, "Lookin up %s", |
88 user->proto_opt[USEROPT_AUTH][0] ? user->proto_opt[USEROPT_AUTH] : TOC_HOST); | 115 user->proto_opt[USEROPT_AUTH][0] ? user->proto_opt[USEROPT_AUTH] : TOC_HOST); |
116 /* this is such a hack */ | |
89 set_login_progress(gc, 1, buf); | 117 set_login_progress(gc, 1, buf); |
90 while (gtk_events_pending()) | 118 while (gtk_events_pending()) |
91 gtk_main_iteration(); | 119 gtk_main_iteration(); |
92 if (!g_slist_find(connections, gc)) | 120 if (!g_slist_find(connections, gc)) |
93 return; | 121 return; |
94 | 122 |
95 tdt->toc_fd = proxy_connect( | 123 tdt->toc_fd = proxy_connect( |
96 user->proto_opt[USEROPT_AUTH][0] ? user->proto_opt[USEROPT_AUTH] : TOC_HOST, | 124 user->proto_opt[USEROPT_AUTH][0] ? user->proto_opt[USEROPT_AUTH] : TOC_HOST, |
97 user->proto_opt[USEROPT_AUTHPORT][0] ? atoi(user->proto_opt[USEROPT_AUTHPORT]) : TOC_PORT, | 125 user->proto_opt[USEROPT_AUTHPORT][0] ? atoi(user->proto_opt[USEROPT_AUTHPORT]):TOC_PORT, |
98 user->proto_opt[USEROPT_SOCKSHOST], atoi(user->proto_opt[USEROPT_SOCKSPORT]), | 126 user->proto_opt[USEROPT_SOCKSHOST], atoi(user->proto_opt[USEROPT_SOCKSPORT]), |
99 atoi(user->proto_opt[USEROPT_PROXYTYPE])); | 127 atoi(user->proto_opt[USEROPT_PROXYTYPE])); |
100 | 128 |
101 if (tdt->toc_fd < 0) { | 129 debug_printf("* Client connects to TOC\n"); |
130 if (tdt->toc_fd < 0) { | |
102 g_snprintf(buf, sizeof(buf), "Connect to %s failed", | 131 g_snprintf(buf, sizeof(buf), "Connect to %s failed", |
103 user->proto_opt[USEROPT_AUTH]); | 132 user->proto_opt[USEROPT_AUTH]); |
104 hide_login_progress(gc, buf); | 133 hide_login_progress(gc, buf); |
105 serv_close(gc); | 134 signoff(gc); |
106 return; | 135 return; |
107 } | 136 } |
137 | |
138 debug_printf("* Client sends \"FLAPON\\r\\n\\r\\n\"\n"); | |
139 if (write(tdt->toc_fd, FLAPON, strlen(FLAPON)) < 0) { | |
140 hide_login_progress(gc, "Disconnected."); | |
141 signoff(gc); | |
142 return; | |
143 } | |
144 tdt->state = STATE_FLAPON; | |
145 | |
146 /* i know a lot of people like to look at gaim to see how TOC works. so i'll comment | |
147 * on what this does. it's really simple. when there's data ready to be read from the | |
148 * toc_fd file descriptor, toc_callback is called, with gc passed as its data arg. */ | |
149 gc->inpa = gdk_input_add(tdt->toc_fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, toc_callback, gc); | |
108 | 150 |
109 g_snprintf(buf, sizeof(buf), "Signon: %s", gc->username); | 151 g_snprintf(buf, sizeof(buf), "Signon: %s", gc->username); |
110 set_login_progress(gc, 3, buf); | 152 set_login_progress(gc, 2, buf); |
111 while (gtk_events_pending()) | 153 } |
112 gtk_main_iteration(); | 154 |
113 if (!g_slist_find(connections, gc)) | 155 static void toc_set_config(struct gaim_connection *gc) { |
114 return; | 156 char buf[MSG_LEN], snd[MSG_LEN]; |
115 | 157 toc_build_config(gc, buf, MSG_LEN, FALSE); |
116 if (toc_signon(gc) < 0) { | 158 g_snprintf(snd, MSG_LEN, "toc_set_config \"%s\"", buf); |
117 hide_login_progress(gc, "Disconnected."); | 159 sflap_send(gc, snd, -1, TYPE_DATA); |
118 serv_close(gc); | 160 } |
119 return; | 161 |
120 } | 162 static void toc_close(struct gaim_connection *gc) { |
121 | 163 toc_set_config(gc); |
122 g_snprintf(buf, sizeof(buf), "Waiting for reply..."); | 164 if (gc->inpa > 0) |
123 set_login_progress(gc, 4, buf); | |
124 while (gtk_events_pending()) | |
125 gtk_main_iteration(); | |
126 if (!g_slist_find(connections, gc)) | |
127 return; | |
128 if (toc_wait_signon(gc) < 0) { | |
129 hide_login_progress(gc, "Authentication Failed"); | |
130 serv_close(gc); | |
131 return; | |
132 } | |
133 | |
134 gc->options = user->options; | |
135 save_prefs(); | |
136 | |
137 g_snprintf(buf, sizeof(buf), "Retrieving config..."); | |
138 set_login_progress(gc, 5, buf); | |
139 while (gtk_events_pending()) | |
140 gtk_main_iteration(); | |
141 if (!g_slist_find(connections, gc)) | |
142 return; | |
143 | |
144 account_online(gc); | |
145 serv_finish_login(gc); | |
146 | |
147 config = toc_wait_config(gc); | |
148 tdt->state = STATE_ONLINE; | |
149 | |
150 if (config != NULL) | |
151 parse_toc_buddy_list(gc, config, 0); | |
152 else | |
153 do_import(0, gc); | |
154 | |
155 g_snprintf(buf2, sizeof(buf2), "toc_init_done"); | |
156 sflap_send(gc, buf2, -1, TYPE_DATA); | |
157 | |
158 g_snprintf(buf2, sizeof(buf2), "toc_set_caps %s %s %s %s %s", | |
159 FILE_SEND_UID, FILE_GET_UID, B_ICON_UID, IMAGE_UID, | |
160 VOICE_UID); | |
161 sflap_send(gc, buf2, -1, TYPE_DATA); | |
162 | |
163 if (gc->keepalive < 0) | |
164 update_keepalive(gc, gc->options & OPT_USR_KEEPALV); | |
165 } | |
166 | |
167 void toc_close(struct gaim_connection *gc) | |
168 { | |
169 if (gc->protocol != PROTO_TOC) return; /* how did this happen? */ | |
170 if (gc->inpa > 0) | |
171 gdk_input_remove(gc->inpa); | 165 gdk_input_remove(gc->inpa); |
172 gc->inpa = -1; | 166 gc->inpa = -1; |
173 close(((struct toc_data *)gc->proto_data)->toc_fd); | 167 close(((struct toc_data *)gc->proto_data)->toc_fd); |
174 } | 168 } |
175 | 169 |
176 unsigned char *roast_password(char *pass) | 170 int sflap_send(struct gaim_connection *gc, char *buf, int olen, int type) { |
177 { | |
178 /* Trivial "encryption" */ | |
179 static char rp[256]; | |
180 static char *roast = ROAST; | |
181 int pos=2; | |
182 int x; | |
183 strcpy(rp, "0x"); | |
184 for (x=0;(x<150) && pass[x]; x++) | |
185 pos+=sprintf(&rp[pos],"%02x", pass[x] ^ roast[x % strlen(roast)]); | |
186 rp[pos]='\0'; | |
187 return rp; | |
188 } | |
189 | |
190 | |
191 char *print_header(void *hdr_v) | |
192 { | |
193 static char s[80]; | |
194 struct sflap_hdr *hdr = (struct sflap_hdr *)hdr_v; | |
195 g_snprintf(s,sizeof(s), "[ ast: %c, type: %d, seqno: %d, len: %d ]", | |
196 hdr->ast, hdr->type, ntohs(hdr->seqno), ntohs(hdr->len)); | |
197 return s; | |
198 } | |
199 | |
200 void print_buffer(char *buf, int len) | |
201 { | |
202 #if 0 | |
203 int x; | |
204 printf("[ "); | |
205 for (x=0;x<len;x++) | |
206 printf("%d ", buf[x]); | |
207 printf("]\n"); | |
208 printf("[ "); | |
209 for (x=0;x<len;x++) | |
210 printf("%c ", buf[x]); | |
211 printf("]\n"); | |
212 #endif | |
213 } | |
214 | |
215 int sflap_send(struct gaim_connection *gc, char *buf, int olen, int type) | |
216 { | |
217 int len; | 171 int len; |
218 int slen=0; | 172 int slen=0; |
219 struct sflap_hdr hdr; | 173 struct sflap_hdr hdr; |
220 char obuf[MSG_LEN]; | 174 char obuf[MSG_LEN]; |
221 struct toc_data *tdt = (struct toc_data *)gc->proto_data; | 175 struct toc_data *tdt = (struct toc_data *)gc->proto_data; |
222 | 176 |
177 if (tdt->state == STATE_PAUSE) | |
178 /* TOC has given us the PAUSE message; sending could cause a disconnect | |
179 * so we just return here like everything went through fine */ | |
180 return 0; | |
181 | |
223 /* One _last_ 2048 check here! This shouldn't ever | 182 /* One _last_ 2048 check here! This shouldn't ever |
224 * get hit though, hopefully. If it gets hit on an IM | 183 * get hit though, hopefully. If it gets hit on an IM |
225 * It'll lose the last " and the message won't go through, | 184 * It'll lose the last " and the message won't go through, |
226 * but this'll stop a segfault. */ | 185 * but this'll stop a segfault. */ |
227 if (strlen(buf) > (MSG_LEN - sizeof(hdr))) { | 186 if (strlen(buf) > (MSG_LEN - sizeof(hdr))) { |
187 debug_printf("message too long, truncating\n"); | |
228 buf[MSG_LEN - sizeof(hdr) - 3] = '"'; | 188 buf[MSG_LEN - sizeof(hdr) - 3] = '"'; |
229 buf[MSG_LEN - sizeof(hdr) - 2] = '\0'; | 189 buf[MSG_LEN - sizeof(hdr) - 2] = '\0'; |
230 } | 190 } |
231 | 191 |
232 debug_printf("%s [Len %d]\n", buf, strlen(buf)); | |
233 | |
234 if (olen < 0) | 192 if (olen < 0) |
235 len = escape_message(buf); | 193 len = escape_message(buf); |
236 else | 194 else |
237 len = olen; | 195 len = olen; |
238 hdr.ast = '*'; | 196 hdr.ast = '*'; |
239 hdr.type = type; | 197 hdr.type = type; |
240 hdr.seqno = htons(tdt->seqno++ & 0xffff); | 198 hdr.seqno = htons(tdt->seqno++ & 0xffff); |
241 hdr.len = htons(len + (type == TYPE_SIGNON ? 0 : 1)); | 199 hdr.len = htons(len + (type == TYPE_SIGNON ? 0 : 1)); |
242 | |
243 sprintf(debug_buff,"Escaped message is '%s'\n",buf); | |
244 debug_print(debug_buff); | |
245 | 200 |
246 memcpy(obuf, &hdr, sizeof(hdr)); | 201 memcpy(obuf, &hdr, sizeof(hdr)); |
247 slen += sizeof(hdr); | 202 slen += sizeof(hdr); |
248 memcpy(&obuf[slen], buf, len); | 203 memcpy(&obuf[slen], buf, len); |
249 slen += len; | 204 slen += len; |
250 if (type != TYPE_SIGNON) { | 205 if (type != TYPE_SIGNON) { |
251 obuf[slen]='\0'; | 206 obuf[slen]='\0'; |
252 slen += 1; | 207 slen += 1; |
253 } | 208 } |
254 print_buffer(obuf, slen); | |
255 | 209 |
256 return write(tdt->toc_fd, obuf, slen); | 210 return write(tdt->toc_fd, obuf, slen); |
257 } | 211 } |
258 | 212 |
259 | 213 static int wait_reply(struct gaim_connection *gc, char *buffer, size_t buflen) { |
260 static int wait_reply(struct gaim_connection *gc, char *buffer, size_t buflen) | |
261 { | |
262 size_t res=-1; | |
263 int read_rv = -1; | |
264 struct sflap_hdr *hdr=(struct sflap_hdr *)buffer; | |
265 struct toc_data *tdt = (struct toc_data *)gc->proto_data; | 214 struct toc_data *tdt = (struct toc_data *)gc->proto_data; |
266 char *c; | 215 struct sflap_hdr *hdr; |
267 | 216 int ret; |
268 if(buflen < sizeof(struct sflap_hdr)) { | 217 |
269 do_error_dialog(_("Unable to read from server: Buffer too small"), | 218 if (read(tdt->toc_fd, buffer, sizeof(struct sflap_hdr)) < 0) { |
270 _("Gaim - Error (internal)")); | 219 debug_printf("error, couldn't read flap header\n"); |
271 return -1; | 220 return -1; |
272 } | 221 } |
273 | 222 |
274 while((read_rv = read(tdt->toc_fd, buffer, 1))) { | 223 hdr = (struct sflap_hdr *)buffer; |
275 if (read_rv < 0 || read_rv > 1) | 224 |
276 return -1; | 225 if (buflen < ntohs(hdr->len)) { |
277 if (buffer[0] == '*') | 226 /* fake like there's a read error */ |
278 break; | 227 debug_printf("buffer too small (have %d, need %d)\n", buflen, ntohs(hdr->len)); |
279 | 228 return -1; |
280 } | 229 } |
281 | 230 |
282 read_rv = read(tdt->toc_fd, buffer+1, sizeof(struct sflap_hdr) - 1); | 231 if (ntohs(hdr->len) > 0) { |
283 | 232 ret = read(tdt->toc_fd, buffer + sizeof(struct sflap_hdr), ntohs(hdr->len)); |
284 if (read_rv < 0) | 233 buffer[sizeof(struct sflap_hdr) + ret] = '\0'; |
285 return read_rv; | 234 return ret; |
286 | 235 } else return 0; |
287 res = read_rv + 1; | 236 } |
288 | 237 |
289 | 238 static unsigned char *roast_password(char *pass) { |
290 sprintf(debug_buff, "Rcv: %s %s\n",print_header(buffer), ""); | 239 /* Trivial "encryption" */ |
291 debug_print(debug_buff); | 240 static char rp[256]; |
292 | 241 static char *roast = ROAST; |
293 | 242 int pos=2; |
294 if(buflen < sizeof(struct sflap_hdr) + ntohs(hdr->len) + 1) { | 243 int x; |
295 do_error_dialog(_("Unable to read from server: Too much information"), | 244 strcpy(rp, "0x"); |
296 _("Gaim - Error (internal)")); | 245 for (x=0;(x<150) && pass[x]; x++) |
297 return -1; | 246 pos+=sprintf(&rp[pos],"%02x", pass[x] ^ roast[x % strlen(roast)]); |
298 } | 247 rp[pos]='\0'; |
299 | 248 return rp; |
300 while (res < (sizeof(struct sflap_hdr) + ntohs(hdr->len))) { | 249 } |
301 read_rv = read(tdt->toc_fd, buffer + res, (ntohs(hdr->len) + sizeof(struct sflap_hdr)) - res); | 250 |
302 if(read_rv < 0) return read_rv; | 251 static void toc_callback(gpointer data, gint source, GdkInputCondition condition) { |
303 res += read_rv; | 252 struct gaim_connection *gc = (struct gaim_connection *)data; |
304 /* my feeling is this will kill us. if there's data pending then we'll come right back | 253 struct toc_data *tdt = (struct toc_data *)gc->proto_data; |
305 * to where we are now. possible workarounds are to remove the input watcher until | 254 struct sflap_hdr *hdr; |
306 * we're done with this part | 255 struct signon so; |
307 while(gtk_events_pending()) | 256 char buf[8 * 1024], *c; |
308 gtk_main_iteration(); | 257 char snd[MSG_LEN]; |
309 */ | 258 |
310 } | 259 if (condition & GDK_INPUT_EXCEPTION) { |
311 | 260 debug_printf("gdk_input exception! check internet connection\n"); |
312 if (res >= sizeof(struct sflap_hdr)) | 261 hide_login_progress(gc, _("Connection Closed")); |
313 buffer[res]='\0'; | 262 signoff(gc); |
314 else | 263 return; |
315 return res - sizeof(struct sflap_hdr); | 264 } |
316 | 265 |
317 switch(hdr->type) { | 266 /* there's data waiting to be read, so read it. */ |
318 case TYPE_SIGNON: | 267 if (wait_reply(gc, buf, 8 * 1024) < 0) { |
319 memcpy(&peer_ver, buffer + sizeof(struct sflap_hdr), 4); | 268 hide_login_progress(gc, _("Connection Closed")); |
320 peer_ver = ntohl(peer_ver); | 269 signoff(gc); |
270 return; | |
271 } | |
272 | |
273 if (tdt->state == STATE_FLAPON) { | |
274 hdr = (struct sflap_hdr *)buf; | |
275 if (hdr->type != TYPE_SIGNON) | |
276 debug_printf("problem, hdr->type != TYPE_SIGNON\n"); | |
277 else | |
278 debug_printf("* TOC sends Client FLAP SIGNON\n"); | |
321 tdt->seqno = ntohs(hdr->seqno); | 279 tdt->seqno = ntohs(hdr->seqno); |
322 tdt->state = STATE_SIGNON_REQUEST; | 280 tdt->state = STATE_SIGNON_REQUEST; |
323 break; | 281 |
324 case TYPE_DATA: | 282 debug_printf("* Client sends TOC FLAP SIGNON\n"); |
325 if (!strncasecmp(buffer + sizeof(struct sflap_hdr), "SIGN_ON:", strlen("SIGN_ON:"))) | 283 g_snprintf(so.username, sizeof(so.username), "%s", gc->username); |
326 tdt->state = STATE_SIGNON_ACK; | 284 so.ver = htonl(1); |
327 else if (!strncasecmp(buffer + sizeof(struct sflap_hdr), "CONFIG:", strlen("CONFIG:"))) { | 285 so.tag = htons(1); |
328 tdt->state = STATE_CONFIG; | 286 so.namelen = htons(strlen(so.username)); |
329 } else if (!strncasecmp(buffer + sizeof(struct sflap_hdr), "ERROR:", strlen("ERROR:"))) { | 287 if (sflap_send(gc, (char *)&so, ntohs(so.namelen) + 8, TYPE_SIGNON) < 0) { |
330 c = strtok(buffer + sizeof(struct sflap_hdr) + strlen("ERROR:"), ":"); | 288 hide_login_progress(gc, _("Disconnected.")); |
331 show_error_dialog(c); | 289 signoff(gc); |
290 return; | |
332 } | 291 } |
333 | 292 |
334 sprintf(debug_buff, "Data: %s\n",buffer + sizeof(struct sflap_hdr)); | 293 debug_printf("* Client sends TOC \"toc_signon\" message\n"); |
335 debug_print(debug_buff); | 294 g_snprintf(snd, sizeof snd, "toc_signon %s %d %s %s %s \"%s\"", |
336 | 295 AUTH_HOST, AUTH_PORT, normalize(gc->username), |
337 break; | 296 roast_password(gc->password), LANGUAGE, REVISION); |
338 default: | 297 if (sflap_send(gc, snd, -1, TYPE_DATA) < 0) { |
339 sprintf(debug_buff, "Unknown/unimplemented packet type %d\n",hdr->type); | 298 hide_login_progress(gc, _("Disconnected.")); |
340 debug_print(debug_buff); | 299 signoff(gc); |
341 } | 300 return; |
342 return res; | 301 } |
343 } | 302 |
344 | 303 set_login_progress(gc, 3, _("Waiting for reply...")); |
345 | |
346 | |
347 void toc_callback( gpointer data, | |
348 gint source, | |
349 GdkInputCondition condition ) | |
350 { | |
351 char *buf; | |
352 char *c; | |
353 char *l; | |
354 struct gaim_connection *gc = (struct gaim_connection *)data; | |
355 | |
356 buf = g_malloc(2 * BUF_LONG); | |
357 if (wait_reply(gc, buf, 2 * BUF_LONG) < 0) { | |
358 hide_login_progress(gc, "Connection Closed"); | |
359 signoff(gc); /* this will free gc for us */ | |
360 g_free(buf); | |
361 return; | 304 return; |
362 } | 305 } |
363 | 306 |
364 | 307 if (tdt->state == STATE_SIGNON_REQUEST) { |
365 c=strtok(buf+sizeof(struct sflap_hdr),":"); /* Ditch the first part */ | 308 debug_printf("* TOC sends client SIGN_ON reply\n"); |
366 if (!strcasecmp(c,"UPDATE_BUDDY")) { | 309 if (strncasecmp(buf + sizeof(struct sflap_hdr), "SIGN_ON", strlen("SIGN_ON"))) { |
367 char *uc; | 310 debug_printf("Didn't get SIGN_ON! buf was: %s\n", buf+sizeof(struct sflap_hdr)); |
311 hide_login_progress(gc, _("Authentication Failed")); | |
312 signoff(gc); | |
313 return; | |
314 } | |
315 /* we're supposed to check that it's really TOC v1 here but we know it is ;) */ | |
316 debug_printf("TOC version: %s\n", buf + sizeof(struct sflap_hdr) + 4); | |
317 | |
318 /* we used to check for the CONFIG here, but we'll wait until we've sent our | |
319 * version of the config and then the toc_init_done message. we'll come back to | |
320 * the callback in a better state if we get CONFIG anyway */ | |
321 | |
322 gc->options = gc->user->options; | |
323 tdt->state = STATE_ONLINE; | |
324 | |
325 account_online(gc); | |
326 serv_finish_login(gc); | |
327 | |
328 do_import(0, gc); | |
329 | |
330 /* Client sends TOC toc_init_done message */ | |
331 debug_printf("* Client sends TOC toc_init_done message\n"); | |
332 g_snprintf(snd, sizeof snd, "toc_init_done"); | |
333 sflap_send(gc, snd, -1, TYPE_DATA); | |
334 | |
335 g_snprintf(snd, sizeof snd, "toc_set_caps %s %s %s %s %s", | |
336 FILE_SEND_UID, FILE_GET_UID, B_ICON_UID, IMAGE_UID, VOICE_UID); | |
337 sflap_send(gc, snd, -1, TYPE_DATA); | |
338 | |
339 if (gc->keepalive < 0) | |
340 update_keepalive(gc, gc->options & OPT_USR_KEEPALV); | |
341 | |
342 return; | |
343 } | |
344 | |
345 debug_printf("From TOC server: %s\n", buf + sizeof(struct sflap_hdr)); | |
346 | |
347 c = strtok(buf + sizeof(struct sflap_hdr), ":"); /* Ditch the first part */ | |
348 | |
349 if (!strcasecmp(c, "SIGN_ON")) { | |
350 /* we should only get here after a PAUSE */ | |
351 if (tdt->state != STATE_PAUSE) | |
352 debug_printf("got SIGN_ON but not PAUSE!\n"); | |
353 else { | |
354 tdt->state = STATE_ONLINE; | |
355 do_error_dialog(_("TOC has come back from its pause. You may now send" | |
356 " messages again."), _("TOC Resume")); | |
357 do_import(0, gc); | |
358 g_snprintf(snd, sizeof snd, "toc_init_done"); | |
359 sflap_send(gc, snd, -1, TYPE_DATA); | |
360 } | |
361 } else if (!strcasecmp(c, "CONFIG")) { | |
362 c = strtok(NULL, ":"); | |
363 parse_toc_buddy_list(gc, c, 0); | |
364 } else if (!strcasecmp(c, "NICK")) { | |
365 c = strtok(NULL, ":"); | |
366 g_snprintf(gc->username, sizeof(gc->username), "%s", c); | |
367 } else if (!strcasecmp(c, "IM_IN")) { | |
368 char *away, *message; | |
369 int a = 0; | |
370 | |
371 c = strtok(NULL, ":"); | |
372 away = strtok(NULL, ":"); | |
373 message = strtok(NULL, ":"); | |
374 a = (away && (*away == 'T')) ? 1 : 0; | |
375 | |
376 serv_got_im(gc, c, message, a); | |
377 } else if (!strcasecmp(c, "UPDATE_BUDDY")) { | |
378 char *l, *uc; | |
368 int logged, evil, idle, type = 0; | 379 int logged, evil, idle, type = 0; |
369 time_t signon; | 380 time_t signon, time_idle; |
370 time_t time_idle; | 381 |
371 | 382 c = strtok(NULL, ":"); /* name */ |
372 c = strtok(NULL,":"); /* c is name */ | 383 l = strtok(NULL, ":"); /* online */ |
373 | |
374 l = strtok(NULL,":"); /* l is T/F logged status */ | |
375 | |
376 sscanf(strtok(NULL, ":"), "%d", &evil); | 384 sscanf(strtok(NULL, ":"), "%d", &evil); |
377 | 385 sscanf(strtok(NULL, ":"), "%d", &signon); |
378 sscanf(strtok(NULL, ":"), "%ld", &signon); | |
379 | |
380 sscanf(strtok(NULL, ":"), "%d", &idle); | 386 sscanf(strtok(NULL, ":"), "%d", &idle); |
381 | 387 uc = strtok(NULL, ":"); |
382 uc = strtok(NULL, ":"); | 388 |
383 | 389 logged = (l && (*l == 'T')) ? 1 : 0; |
384 | 390 |
385 if (!strncasecmp(l,"T",1)) | 391 if (uc[0] == 'A') type |= UC_AOL; |
386 logged = 1; | 392 switch (uc[1]) { |
387 else | |
388 logged = 0; | |
389 | |
390 | |
391 if (uc[0] == 'A') | |
392 type |= UC_AOL; | |
393 | |
394 switch(uc[1]) { | |
395 case 'A': | 393 case 'A': |
396 type |= UC_ADMIN; | 394 type |= UC_ADMIN; |
397 break; | 395 break; |
398 case 'U': | 396 case 'U': |
399 type |= UC_UNCONFIRMED; | 397 type |= UC_UNCONFIRMED; |
402 type |= UC_NORMAL; | 400 type |= UC_NORMAL; |
403 break; | 401 break; |
404 default: | 402 default: |
405 break; | 403 break; |
406 } | 404 } |
407 | 405 if (uc[0] == 'U') type |= UC_UNAVAILABLE; |
408 switch(uc[2]) { | 406 |
409 case 'U': | 407 if (idle) { time(&time_idle); time_idle -= idle * 60; } |
410 type |= UC_UNAVAILABLE; | 408 else time_idle = 0; |
411 break; | 409 |
412 default: | 410 serv_got_update(gc, c, logged, evil, signon, time_idle, type, 0); |
413 break; | |
414 } | |
415 | |
416 if (idle) { | |
417 time(&time_idle); | |
418 time_idle -= idle*60; | |
419 } else | |
420 time_idle = 0; | |
421 | |
422 serv_got_update(gc, c, logged, evil, signon, time_idle, type, 0); | |
423 | |
424 } else if (!strcasecmp(c, "CONFIG")) { | |
425 /* do we want to load the buddy list again here? */ | |
426 c = strtok(NULL,":"); | |
427 parse_toc_buddy_list(gc, c, 0); | |
428 } else if (!strcasecmp(c, "ERROR")) { | 411 } else if (!strcasecmp(c, "ERROR")) { |
429 /* This should be handled by wait_reply | 412 c = strtok(NULL, ":"); |
430 c = strtok(NULL,":"); | |
431 show_error_dialog(c); | 413 show_error_dialog(c); |
432 */ | 414 } else if (!strcasecmp(c, "EVILED")) { |
433 } else if (!strcasecmp(c, "NICK")) { | 415 int lev; |
434 c = strtok(NULL,":"); | |
435 g_snprintf(gc->username, sizeof(gc->username), "%s", c); | |
436 } else if (!strcasecmp(c, "IM_IN")) { | |
437 char *away, *message; | |
438 int a = 0; | |
439 | |
440 c = strtok(NULL,":"); | |
441 away = strtok(NULL,":"); | |
442 | |
443 message = away; | |
444 | |
445 while(*message && (*message != ':')) | |
446 message++; | |
447 | |
448 message++; | |
449 | |
450 if (!strncasecmp(away, "T", 1)) | |
451 a = 1; | |
452 serv_got_im(gc, c, message, a); | |
453 | |
454 } else if (!strcasecmp(c, "GOTO_URL")) { | |
455 char *name; | 416 char *name; |
456 char *url; | 417 |
457 | 418 sscanf(strtok(NULL, ":"), "%d", &lev); |
458 char tmp[256]; | |
459 | |
460 name = strtok(NULL, ":"); | 419 name = strtok(NULL, ":"); |
461 url = strtok(NULL, ":"); | |
462 | |
463 | |
464 g_snprintf(tmp, sizeof(tmp), "http://%s:%d/%s", TOC_HOST, TOC_PORT, url); | |
465 g_show_info(gc->user, tmp); | |
466 } else if (!strcasecmp(c, "EVILED")) { | |
467 int lev; | |
468 char *name = NULL; | |
469 | |
470 sscanf(strtok(NULL, ":"), "%d", &lev); | |
471 name = strtok(NULL, ":"); | |
472 | |
473 sprintf(debug_buff,"%s | %d\n", name, lev); | |
474 debug_print(debug_buff); | |
475 | 420 |
476 serv_got_eviled(gc, name, lev); | 421 serv_got_eviled(gc, name, lev); |
477 | 422 } else if (!strcasecmp(c, "CHAT_JOIN")) { |
478 } else if (!strcasecmp(c, "CHAT_JOIN")) { | 423 char *name; |
479 char *name; | 424 int id; |
480 int id; | |
481 | |
482 | 425 |
483 sscanf(strtok(NULL, ":"), "%d", &id); | 426 sscanf(strtok(NULL, ":"), "%d", &id); |
484 name = strtok(NULL, ":"); | 427 name = strtok(NULL, ":"); |
485 serv_got_joined_chat(gc, id, name); | 428 |
486 | 429 serv_got_joined_chat(gc, id, name); |
487 } else if (!strcasecmp(c, "DIR_STATUS")) { | 430 } else if (!strcasecmp(c, "CHAT_IN")) { |
488 } else if (!strcasecmp(c, "ADMIN_PASSWD_STATUS")) { | 431 int id, w; |
489 do_error_dialog("Password Change Successeful", "Gaim - Password Change"); | 432 char *m, *who, *whisper; |
433 | |
434 sscanf(strtok(NULL, ":"), "%d", &id); | |
435 who = strtok(NULL, ":"); | |
436 whisper = strtok(NULL, ":"); | |
437 m = strtok(NULL, ":"); | |
438 | |
439 w = (whisper && (*whisper == 'T')) ? 1 : 0; | |
440 | |
441 serv_got_chat_in(gc, id, who, w, m); | |
490 } else if (!strcasecmp(c, "CHAT_UPDATE_BUDDY")) { | 442 } else if (!strcasecmp(c, "CHAT_UPDATE_BUDDY")) { |
491 int id; | 443 int id; |
492 char *in; | 444 char *in, *buddy; |
493 char *buddy; | 445 GSList *bcs = gc->buddy_chats; |
494 GSList *bcs = gc->buddy_chats; | |
495 struct conversation *b = NULL; | 446 struct conversation *b = NULL; |
496 | 447 |
497 sscanf(strtok(NULL, ":"), "%d", &id); | 448 sscanf(strtok(NULL, ":"), "%d", &id); |
498 | |
499 in = strtok(NULL, ":"); | 449 in = strtok(NULL, ":"); |
500 | 450 |
501 while(bcs) { | 451 while(bcs) { |
502 b = (struct conversation *)bcs->data; | 452 b = (struct conversation *)bcs->data; |
503 if (id == b->id) | 453 if (id == b->id) |
504 break; | 454 break; |
505 bcs = bcs->next; | 455 bcs = bcs->next; |
506 b = NULL; | 456 b = NULL; |
507 } | 457 } |
508 | 458 |
509 if (!b) { | 459 if (!b) return; |
510 g_free(buf); | 460 |
511 return; | 461 if (in && (*in == 'T')) |
512 } | 462 while ((buddy = strtok(NULL, ":")) != NULL) |
513 | |
514 | |
515 if (!strcasecmp(in, "T")) { | |
516 while((buddy = strtok(NULL, ":")) != NULL) { | |
517 add_chat_buddy(b, buddy); | 463 add_chat_buddy(b, buddy); |
518 } | 464 else |
519 } else { | 465 while ((buddy = strtok(NULL, ":")) != NULL) |
520 while((buddy = strtok(NULL, ":")) != NULL) { | |
521 remove_chat_buddy(b, buddy); | 466 remove_chat_buddy(b, buddy); |
522 } | 467 } else if (!strcasecmp(c, "CHAT_INVITE")) { |
523 } | 468 char *name, *who, *message; |
524 | |
525 } else if (!strcasecmp(c, "CHAT_LEFT")) { | |
526 int id; | 469 int id; |
527 | 470 |
528 | |
529 sscanf(strtok(NULL, ":"), "%d", &id); | |
530 | |
531 serv_got_chat_left(gc, id); | |
532 | |
533 | |
534 } else if (!strcasecmp(c, "CHAT_IN")) { | |
535 | |
536 int id, w; | |
537 char *m; | |
538 char *who, *whisper; | |
539 | |
540 | |
541 sscanf(strtok(NULL, ":"), "%d", &id); | |
542 who = strtok(NULL, ":"); | |
543 whisper = strtok(NULL, ":"); | |
544 m = whisper; | |
545 while(*m && (*m != ':')) m++; | |
546 m++; | |
547 | |
548 if (!strcasecmp(whisper, "T")) | |
549 w = 1; | |
550 else | |
551 w = 0; | |
552 | |
553 serv_got_chat_in(gc, id, who, w, m); | |
554 | |
555 | |
556 } else if (!strcasecmp(c, "CHAT_INVITE")) { | |
557 char *name; | |
558 char *who; | |
559 char *message; | |
560 int id; | |
561 | |
562 | |
563 name = strtok(NULL, ":"); | 471 name = strtok(NULL, ":"); |
564 sscanf(strtok(NULL, ":"), "%d", &id); | 472 sscanf(strtok(NULL, ":"), "%d", &id); |
565 who = strtok(NULL, ":"); | 473 who = strtok(NULL, ":"); |
566 message = strtok(NULL, ":"); | 474 message = strtok(NULL, ":"); |
567 | 475 |
568 serv_got_chat_invite(gc, name, id, who, message); | 476 serv_got_chat_invite(gc, name, id, who, message); |
569 | 477 } else if (!strcasecmp(c, "CHAT_LEFT")) { |
570 | 478 int id; |
571 } else if (!strcasecmp(c, "RVOUS_PROPOSE")) { | 479 |
572 char *user; | 480 sscanf(strtok(NULL, ":"), "%d", &id); |
573 char *uuid; | 481 |
574 char *cookie; | 482 serv_got_chat_left(gc, id); |
575 int seq; | 483 } else if (!strcasecmp(c, "GOTO_URL")) { |
576 char *rip, *pip, *vip; | 484 char *name, *url, tmp[256]; |
577 int port; | 485 |
578 int unk[4]; | 486 name = strtok(NULL, ":"); |
579 char *messages[4]; | 487 url = strtok(NULL, ":"); |
580 int subtype, files, totalsize; | 488 |
581 char *name; | 489 g_snprintf(tmp, sizeof(tmp), "http://%s:%d/%s", TOC_HOST, TOC_PORT, url); |
582 char *tmp; | 490 g_show_info(gc->user, tmp); |
583 int i; | 491 } else if (!strcasecmp(c, "DIR_STATUS")) { |
584 struct file_transfer *ft; | 492 } else if (!strcasecmp(c, "ADMIN_NICK_STATUS")) { |
585 | 493 } else if (!strcasecmp(c, "ADMIN_PASSWD_STATUS")) { |
586 | 494 do_error_dialog(_("Password Change Successeful"), _("Gaim - Password Change")); |
587 user = strtok(NULL, ":"); | 495 } else if (!strcasecmp(c, "PAUSE")) { |
588 uuid = strtok(NULL, ":"); | 496 tdt->state = STATE_PAUSE; |
589 cookie = strtok(NULL, ":"); | 497 do_error_dialog(_("TOC has sent a PAUSE command. When this happens, TOC ignores" |
590 sscanf(strtok(NULL, ":"), "%d", &seq); | 498 " any messages sent to it, and may kick you off if you send a" |
591 rip = strtok(NULL, ":"); | 499 " message. Gaim will prevent anything from going through. This" |
592 pip = strtok(NULL, ":"); | 500 " is only temporary, please be patient."), _("TOC Pause")); |
593 vip = strtok(NULL, ":"); | 501 } else if (!strcasecmp(c, "RVOUS_PROPOSE")) { |
594 sscanf(strtok(NULL, ":"), "%d", &port); | 502 char *user, *uuid, *cookie; |
503 int seq; | |
504 char *rip, *pip, *vip; | |
505 int port; | |
506 | |
507 user = strtok(NULL, ":"); | |
508 uuid = strtok(NULL, ":"); | |
509 cookie = strtok(NULL, ":"); | |
510 sscanf(strtok(NULL, ":"), "%d", &seq); | |
511 rip = strtok(NULL, ":"); | |
512 pip = strtok(NULL, ":"); | |
513 vip = strtok(NULL, ":"); | |
514 sscanf(strtok(NULL, ":"), "%d", &port); | |
595 | 515 |
596 if (!strcmp(uuid, FILE_SEND_UID)) { | 516 if (!strcmp(uuid, FILE_SEND_UID)) { |
597 /* we're getting a file */ | 517 /* they want us to get a file */ |
598 for (i=0; i<4; i++) { | 518 int unk[4], i; |
599 sscanf(strtok(NULL, ":"), "%d", &unk[i]); | 519 char *messages[4], *tmp, *name; |
600 if (unk[i] == 10001) | 520 int subtype, files, totalsize = 0; |
601 break; | 521 struct file_transfer *ft; |
602 messages[i] = frombase64(strtok(NULL, ":")); | 522 |
603 } | 523 for (i = 0; i < 4; i++) { |
604 tmp = frombase64(strtok(NULL, ":")); | 524 sscanf(strtok(NULL, ":"), "%d", unk + i); |
605 subtype = tmp[1]; | 525 if (unk[1] == 10001) break; |
606 files = tmp[3]; /* These are fine */ | 526 messages[i] = frombase64(strtok(NULL, ":")); |
607 | 527 } |
608 totalsize = 0; | 528 tmp = frombase64(strtok(NULL, ":")); |
529 | |
530 subtype = tmp[1]; | |
531 files = tmp[3]; | |
532 | |
609 totalsize |= (tmp[4] << 24) & 0xff000000; | 533 totalsize |= (tmp[4] << 24) & 0xff000000; |
610 totalsize |= (tmp[5] << 16) & 0x00ff0000; | 534 totalsize |= (tmp[5] << 16) & 0x00ff0000; |
611 totalsize |= (tmp[6] << 8) & 0x0000ff00; | 535 totalsize |= (tmp[6] << 8) & 0x0000ff00; |
612 totalsize |= (tmp[7] << 0) & 0x000000ff; | 536 totalsize |= (tmp[7] << 0) & 0x000000ff; |
613 | 537 |
614 name = tmp + 8; | 538 if (!totalsize) { |
615 | 539 g_free(tmp); |
616 ft = g_new0(struct file_transfer, 1); | 540 for (i--; i >= 0; i--) g_free(messages[i]); |
617 | 541 return; |
618 ft->cookie = g_strdup(cookie); | 542 } |
619 ft->ip = g_strdup(pip); | 543 |
620 ft->port = port; | 544 name = tmp + 8; |
621 if (i) | 545 |
622 ft->message = g_strdup(messages[0]); | |
623 else | |
624 ft->message = NULL; | |
625 ft->filename = g_strdup(name); | |
626 ft->user = g_strdup(user); | |
627 ft->size = totalsize; | |
628 sprintf(ft->UID, "%s", FILE_SEND_UID); | |
629 ft->gc = gc; | |
630 | |
631 g_free(tmp); | |
632 | |
633 for (i--; i >= 0; i--) | |
634 g_free(messages[i]); | |
635 | |
636 if (totalsize) /* sanity check */ | |
637 accept_file_dialog(ft); | |
638 } else if (!strcmp(uuid, FILE_GET_UID)) { | |
639 /* we're sending a file */ | |
640 for (i=0; i<4; i++) { | |
641 sscanf(strtok(NULL, ":"), "%d", &unk[i]); | |
642 if (unk[i] == 10001) | |
643 break; | |
644 messages[i] = frombase64(strtok(NULL, ":")); | |
645 } | |
646 tmp = frombase64(strtok(NULL, ":")); | |
647 ft = g_new0(struct file_transfer, 1); | 546 ft = g_new0(struct file_transfer, 1); |
648 | |
649 ft->cookie = g_strdup(cookie); | 547 ft->cookie = g_strdup(cookie); |
650 ft->ip = g_strdup(pip); | 548 ft->ip = g_strdup(pip); |
651 ft->port = port; | 549 ft->port = port; |
652 if (i) | 550 if (i) ft->message = g_strdup(messages[0]); |
653 ft->message = g_strdup(messages[0]); | 551 else ft->message = NULL; |
654 else | 552 ft->filename = g_strdup(name); |
655 ft->message = NULL; | |
656 ft->user = g_strdup(user); | 553 ft->user = g_strdup(user); |
657 sprintf(ft->UID, "%s", FILE_GET_UID); | 554 ft->size = totalsize; |
555 g_snprintf(ft->UID, sizeof(ft->UID), "%s", FILE_SEND_UID); | |
658 ft->gc = gc; | 556 ft->gc = gc; |
659 | 557 |
660 g_free(tmp); | 558 g_free(tmp); |
661 | 559 for (i--; i >= 0; i--) g_free(messages[i]); |
662 for (i--; i >= 0; i--) | 560 |
663 g_free(messages[i]); | 561 accept_file_dialog(ft); |
562 } else if (!strcmp(uuid, FILE_GET_UID)) { | |
563 /* they want us to send a file */ | |
564 int unk[4], i; | |
565 char *messages[4], *tmp; | |
566 struct file_transfer *ft; | |
567 | |
568 for (i = 0; i < 4; i++) { | |
569 sscanf(strtok(NULL, ":"), "%d", unk + i); | |
570 if (unk[i] == 10001) break; | |
571 messages[i] = frombase64(strtok(NULL, ":")); | |
572 } | |
573 tmp = frombase64(strtok(NULL, ":")); | |
574 | |
575 ft = g_new0(struct file_transfer, 1); | |
576 ft->cookie = g_strdup(cookie); | |
577 ft->ip = g_strdup(pip); | |
578 ft->port = port; | |
579 if (i) ft->message = g_strdup(messages[0]); | |
580 else ft->message = NULL; | |
581 ft->user = g_strdup(user); | |
582 g_snprintf(ft->UID, sizeof(ft->UID), "%s", FILE_GET_UID); | |
583 ft->gc = gc; | |
584 | |
585 g_free(tmp); | |
586 for (i--; i >= 0; i--) g_free(messages[i]); | |
664 | 587 |
665 accept_file_dialog(ft); | 588 accept_file_dialog(ft); |
666 } else if (!strcmp(uuid, VOICE_UID)) { | 589 } else if (!strcmp(uuid, VOICE_UID)) { |
667 /* oh goody. voice over ip. fun stuff. */ | 590 /* oh goody. voice over ip. fun stuff. */ |
668 | |
669 /* | |
670 } else if (!strcmp(uuid, B_ICON_UID)) { | 591 } else if (!strcmp(uuid, B_ICON_UID)) { |
592 /* buddy icon... */ | |
671 } else if (!strcmp(uuid, IMAGE_UID)) { | 593 } else if (!strcmp(uuid, IMAGE_UID)) { |
672 */ | 594 /* aka Direct IM */ |
673 | |
674 } else { | 595 } else { |
675 sprintf(debug_buff,"don't know what to do with %s\n", | 596 debug_printf("Don't know what to do with RVOUS UUID %s\n", uuid); |
676 uuid); | 597 /* do we have to do anything here? i think it just times out */ |
677 debug_print(debug_buff); | |
678 tmp = g_malloc(BUF_LEN); | |
679 name = frombase64(cookie); | |
680 snprintf(tmp, BUF_LEN, "toc_rvous_cancel %s %s %s", | |
681 user, name, uuid); | |
682 sflap_send(gc, tmp, strlen(tmp), TYPE_DATA); | |
683 free(name); | |
684 free(tmp); | |
685 } | 598 } |
686 } else { | 599 } else { |
687 sprintf(debug_buff,"don't know what to do with %s\n", c); | 600 debug_printf("don't know what to do with %s\n", c); |
688 debug_print(debug_buff); | 601 } |
689 } | |
690 g_free(buf); | |
691 } | |
692 | |
693 | |
694 int toc_signon(struct gaim_connection *gc) | |
695 { | |
696 char buf[BUF_LONG]; | |
697 int res; | |
698 struct signon so; | |
699 struct toc_data *tdt = (struct toc_data *)gc->proto_data; | |
700 | |
701 sprintf(debug_buff,"State = %d\n", tdt->state); | |
702 debug_print(debug_buff); | |
703 | |
704 if ((res = write(tdt->toc_fd, FLAPON, strlen(FLAPON))) < 0) | |
705 return res; | |
706 /* Wait for signon packet */ | |
707 | |
708 tdt->state = STATE_FLAPON; | |
709 | |
710 if ((res = wait_reply(gc, buf, sizeof(buf)) < 0)) | |
711 return res; | |
712 | |
713 if (tdt->state != STATE_SIGNON_REQUEST) { | |
714 sprintf(debug_buff, "State should be %d, but is %d instead\n", STATE_SIGNON_REQUEST, tdt->state); | |
715 debug_print(debug_buff); | |
716 return -1; | |
717 } | |
718 | |
719 /* Compose a response */ | |
720 | |
721 g_snprintf(so.username, sizeof(so.username), "%s", gc->username); | |
722 so.ver = ntohl(1); | |
723 so.tag = ntohs(1); | |
724 so.namelen = htons(strlen(so.username)); | |
725 | |
726 sflap_send(gc, (char *)&so, ntohs(so.namelen) + 8, TYPE_SIGNON); | |
727 | |
728 g_snprintf(buf, sizeof(buf), | |
729 "toc_signon %s %d %s %s %s \"%s\"", | |
730 AUTH_HOST, AUTH_PORT, normalize(gc->username), roast_password(gc->password), | |
731 LANGUAGE, REVISION); | |
732 | |
733 sprintf(debug_buff,"Send: %s\n", buf); | |
734 debug_print(debug_buff); | |
735 | |
736 return sflap_send(gc, buf, -1, TYPE_DATA); | |
737 } | |
738 | |
739 int toc_wait_signon(struct gaim_connection *gc) | |
740 { | |
741 /* Wait for the SIGNON to be approved */ | |
742 struct toc_data *tdt = (struct toc_data *)gc->proto_data; | |
743 char buf[BUF_LONG]; | |
744 int res; | |
745 res = wait_reply(gc, buf, sizeof(buf)); | |
746 if (res < 0) | |
747 return res; | |
748 if (tdt->state != STATE_SIGNON_ACK) { | |
749 sprintf(debug_buff, "State should be %d, but is %d instead\n",STATE_SIGNON_ACK, tdt->state); | |
750 debug_print(debug_buff); | |
751 return -1; | |
752 } | |
753 return 0; | |
754 } | |
755 | |
756 #ifdef _WIN32 | |
757 gint win32_read() | |
758 { | |
759 int ret; | |
760 struct fd_set fds; | |
761 struct timeval tv; | |
762 | |
763 FD_ZERO(&fds); | |
764 | |
765 tv.tv_sec = 0; | |
766 tv.tv_usec = 200; | |
767 | |
768 FD_SET(toc_fd, &fds); | |
769 | |
770 ret = select(toc_fd + 1, &fds, NULL, NULL, &tv); | |
771 | |
772 if (ret == 0) { | |
773 return TRUE; | |
774 } | |
775 | |
776 toc_callback(NULL, 0, (GdkInputCondition)0); | |
777 return TRUE; | |
778 } | |
779 #endif | |
780 | |
781 | |
782 char *toc_wait_config(struct gaim_connection *gc) | |
783 { | |
784 /* Waits for configuration packet, returning the contents of the packet */ | |
785 struct toc_data *tdt = (struct toc_data *)gc->proto_data; | |
786 static char buf[BUF_LONG]; | |
787 int res; | |
788 res = wait_reply(gc, buf, sizeof(buf)); | |
789 if (res < 0) | |
790 return NULL; | |
791 /* Apparently, the toc_config is optional. *VERY* Optional | |
792 */ | |
793 if (tdt->state != STATE_CONFIG) { | |
794 res = 0; | |
795 } else { | |
796 res = 1; | |
797 } | |
798 /* At this point, it's time to setup automatic handling of incoming packets */ | |
799 tdt->state = STATE_ONLINE; | |
800 #ifdef _WIN32 | |
801 win32_r = gtk_timeout_add(1000, (GtkFunction)win32_read, NULL); | |
802 #else | |
803 gc->inpa = gdk_input_add(tdt->toc_fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, toc_callback, gc); | |
804 #endif | |
805 if (res) | |
806 return buf; | |
807 else | |
808 return NULL; | |
809 } | 602 } |
810 | 603 |
811 void toc_build_config(struct gaim_connection *gc, char *s, int len, gboolean show) | 604 void toc_build_config(struct gaim_connection *gc, char *s, int len, gboolean show) |
812 { | 605 { |
813 GSList *grp = gc->groups; | 606 GSList *grp = gc->groups; |
1020 | 813 |
1021 static void toc_add_buddy(struct gaim_connection *g, char *name) { | 814 static void toc_add_buddy(struct gaim_connection *g, char *name) { |
1022 char buf[1024]; | 815 char buf[1024]; |
1023 g_snprintf(buf, sizeof(buf), "toc_add_buddy %s", normalize(name)); | 816 g_snprintf(buf, sizeof(buf), "toc_add_buddy %s", normalize(name)); |
1024 sflap_send(g, buf, -1, TYPE_DATA); | 817 sflap_send(g, buf, -1, TYPE_DATA); |
818 toc_set_config(g); | |
1025 } | 819 } |
1026 | 820 |
1027 static void toc_add_buddies(struct gaim_connection *g, GList *buddies) { | 821 static void toc_add_buddies(struct gaim_connection *g, GList *buddies) { |
1028 char buf[MSG_LEN]; | 822 char buf[MSG_LEN]; |
1029 int n; | 823 int n; |
1042 | 836 |
1043 static void toc_remove_buddy(struct gaim_connection *g, char *name) { | 837 static void toc_remove_buddy(struct gaim_connection *g, char *name) { |
1044 char buf[1024]; | 838 char buf[1024]; |
1045 g_snprintf(buf, sizeof(buf), "toc_remove_buddy %s", normalize(name)); | 839 g_snprintf(buf, sizeof(buf), "toc_remove_buddy %s", normalize(name)); |
1046 sflap_send(g, buf, -1, TYPE_DATA); | 840 sflap_send(g, buf, -1, TYPE_DATA); |
841 toc_set_config(g); | |
1047 } | 842 } |
1048 | 843 |
1049 static void toc_set_idle(struct gaim_connection *g, int time) { | 844 static void toc_set_idle(struct gaim_connection *g, int time) { |
1050 char buf[256]; | 845 char buf[256]; |
1051 g_snprintf(buf, sizeof(buf), "toc_set_idle %d", time); | 846 g_snprintf(buf, sizeof(buf), "toc_set_idle %d", time); |