comparison plugins/irc.c @ 1266:aac04affc65d

[gaim-migrate @ 1276] first round of cleanups. mostly just ran through indent. changed to have non-blocking connect, that's fun. changed the recv to read and increased reliability. committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Thu, 14 Dec 2000 12:26:56 +0000
parents 245d040422ce
children 677e2c9e8baf
comparison
equal deleted inserted replaced
1265:245d040422ce 1266:aac04affc65d
27 #include <gtk/gtk.h> 27 #include <gtk/gtk.h>
28 #include <unistd.h> 28 #include <unistd.h>
29 #include <errno.h> 29 #include <errno.h>
30 #include <netinet/in.h> 30 #include <netinet/in.h>
31 #include <arpa/inet.h> 31 #include <arpa/inet.h>
32 #include <fcntl.h>
32 #include <string.h> 33 #include <string.h>
33 #include <stdlib.h> 34 #include <stdlib.h>
34 #include <stdio.h> 35 #include <stdio.h>
35 #include <time.h> 36 #include <time.h>
36 #include <sys/socket.h> 37 #include <sys/socket.h>
47 #define IRC_BUF_LEN 4096 48 #define IRC_BUF_LEN 4096
48 49
49 50
50 static int chat_id = 0; 51 static int chat_id = 0;
51 52
52 struct irc_channel { 53 struct irc_channel {
53 int id; 54 int id;
54 gchar *name; 55 gchar *name;
55 }; 56 };
56 57
57 struct irc_data { 58 struct irc_data {
58 int fd; 59 int fd;
60 int inpa; /* used for non-block logins */
59 61
60 int timer; 62 int timer;
61 63
62 int totalblocks; 64 int totalblocks;
63 int recblocks; 65 int recblocks;
64 66
65 GSList *templist; 67 GSList *templist;
66 GList *channels; 68 GList *channels;
67 }; 69 };
68 70
69 static char *irc_name() { 71 static char *irc_name()
72 {
70 return "IRC"; 73 return "IRC";
71 } 74 }
72 75
73 char *name() { 76 char *name()
77 {
74 return "IRC"; 78 return "IRC";
75 } 79 }
76 80
77 char *description() { 81 char *description()
82 {
78 return "Allows gaim to use the IRC protocol"; 83 return "Allows gaim to use the IRC protocol";
79 } 84 }
80 85
81 void irc_join_chat( struct gaim_connection *gc, int id, char *name) { 86 static void irc_join_chat(struct gaim_connection *gc, int id, char *name)
87 {
82 struct irc_data *idata = (struct irc_data *)gc->proto_data; 88 struct irc_data *idata = (struct irc_data *)gc->proto_data;
83 gchar *buf = (gchar *)g_malloc(IRC_BUF_LEN+1); 89 gchar *buf = (gchar *) g_malloc(IRC_BUF_LEN + 1);
84 90
85 g_snprintf(buf, IRC_BUF_LEN, "JOIN %s\n", name); 91 g_snprintf(buf, IRC_BUF_LEN, "JOIN %s\n", name);
86 write(idata->fd, buf, strlen(buf)); 92 write(idata->fd, buf, strlen(buf));
87 93
88 g_free(buf); 94 g_free(buf);
89 } 95 }
90 96
91 void irc_update_user (struct gaim_connection *gc, char *name, int status) { 97 static void irc_update_user(struct gaim_connection *gc, char *name, int status)
98 {
92 struct irc_data *idata = (struct irc_data *)gc->proto_data; 99 struct irc_data *idata = (struct irc_data *)gc->proto_data;
93 struct irc_channel *u; 100 struct irc_channel *u;
94 GSList *temp = idata->templist; 101 GSList *temp = idata->templist;
95 102
96 /* Loop through our list */ 103 /* Loop through our list */
97 104
98 while (temp) { 105 while (temp) {
99 u = (struct irc_channel *)temp->data; 106 u = (struct irc_channel *)temp->data;
100 if (g_strcasecmp(u->name, name) == 0) { 107 if (g_strcasecmp(u->name, name) == 0) {
101 u->id = status; 108 u->id = status;
102 return; 109 return;
103 } 110 }
104 111
105 temp = g_slist_next(temp); 112 temp = g_slist_next(temp);
106 } 113 }
107 return; 114 return;
108 } 115 }
109 116
110 void irc_request_buddy_update ( struct gaim_connection *gc ) { 117 static void irc_request_buddy_update(struct gaim_connection *gc)
118 {
111 struct irc_data *idata = (struct irc_data *)gc->proto_data; 119 struct irc_data *idata = (struct irc_data *)gc->proto_data;
112 GSList *grp = gc->groups; 120 GSList *grp = gc->groups;
113 GSList *person; 121 GSList *person;
114 struct group *g; 122 struct group *g;
115 struct buddy *b; 123 struct buddy *b;
116 struct irc_channel *u; 124 struct irc_channel *u;
117 gchar buf[IRC_BUF_LEN+1]; 125 gchar buf[IRC_BUF_LEN + 1];
118 126
119 if (idata->templist != NULL) 127 if (idata->templist != NULL)
120 return; 128 return;
121 129
122 idata->recblocks = 0; 130 idata->recblocks = 0;
125 /* First, let's check to see if we have anyone on our buddylist */ 133 /* First, let's check to see if we have anyone on our buddylist */
126 if (!grp) { 134 if (!grp) {
127 return; 135 return;
128 } 136 }
129 137
130 /* Send the first part of our request */ 138 /* Send the first part of our request */
131 write(idata->fd, "ISON", 4); 139 write(idata->fd, "ISON", 4);
132 140
133 /* Step through our list of groups */ 141 /* Step through our list of groups */
134 while (grp) { 142 while (grp) {
135 143
136 g = (struct group *)grp->data; 144 g = (struct group *)grp->data;
137 person = g->members; 145 person = g->members;
138 146
139 while (person) { 147 while (person) {
140 b = (struct buddy *)person->data; 148 b = (struct buddy *)person->data;
141 149
142 /* We will store our buddy info here. I know, this is cheap 150 /* We will store our buddy info here. I know, this is cheap
143 * but hey, its the exact same data structure. Why should we 151 * but hey, its the exact same data structure. Why should we
144 * bother with making another one */ 152 * bother with making another one */
145 153
146 u = g_new0(struct irc_channel, 1); 154 u = g_new0(struct irc_channel, 1);
147 u->id = 0; /* Assume by default that they're offline */ 155 u->id = 0; /* Assume by default that they're offline */
148 u->name = strdup(b->name); 156 u->name = strdup(b->name);
149 157
150 write(idata->fd, " ", 1); 158 write(idata->fd, " ", 1);
151 write(idata->fd, u->name, strlen(u->name)); 159 write(idata->fd, u->name, strlen(u->name));
152 idata->templist = g_slist_append(idata->templist, u); 160 idata->templist = g_slist_append(idata->templist, u);
153 161
154 person = person->next; 162 person = person->next;
155 } 163 }
156 164
157 grp = g_slist_next(grp); 165 grp = g_slist_next(grp);
158 } 166 }
159 write(idata->fd, "\n", 1); 167 write(idata->fd, "\n", 1);
160 } 168 }
161 169
162 170
163 void irc_send_im( struct gaim_connection *gc, char *who, char *message, int away) { 171 static void irc_send_im(struct gaim_connection *gc, char *who, char *message, int away)
172 {
164 173
165 struct irc_data *idata = (struct irc_data *)gc->proto_data; 174 struct irc_data *idata = (struct irc_data *)gc->proto_data;
166 gchar *buf = (gchar *)g_malloc(IRC_BUF_LEN + 1); 175 gchar *buf = (gchar *) g_malloc(IRC_BUF_LEN + 1);
167 176
168 /* Before we actually send this, we should check to see if they're trying 177 /* Before we actually send this, we should check to see if they're trying
169 * To issue a /me command and handle it properly. */ 178 * To issue a /me command and handle it properly. */
170 179
171 if ( (g_strncasecmp(message, "/me ", 4) == 0) && (strlen(message)>4)) { 180 if ((g_strncasecmp(message, "/me ", 4) == 0) && (strlen(message) > 4)) {
172 /* We have /me!! We have /me!! :-) */ 181 /* We have /me!! We have /me!! :-) */
173 182
174 gchar *temp = (gchar *)g_malloc(IRC_BUF_LEN+1); 183 gchar *temp = (gchar *) g_malloc(IRC_BUF_LEN + 1);
175 strcpy(temp, message+4); 184 strcpy(temp, message + 4);
176 g_snprintf(buf, IRC_BUF_LEN, "PRIVMSG %s :%cACTION %s%c\n", who, '\001', temp, '\001'); 185 g_snprintf(buf, IRC_BUF_LEN, "PRIVMSG %s :%cACTION %s%c\n", who, '\001', temp, '\001');
177 g_free(temp); 186 g_free(temp);
178 } 187 } else {
179 else
180 {
181 g_snprintf(buf, IRC_BUF_LEN, "PRIVMSG %s :%s\n", who, message); 188 g_snprintf(buf, IRC_BUF_LEN, "PRIVMSG %s :%s\n", who, message);
182 } 189 }
183 190
184 write(idata->fd, buf, strlen(buf)); 191 write(idata->fd, buf, strlen(buf));
185 192
186 g_free(buf); 193 g_free(buf);
187 } 194 }
188 195
189 int find_id_by_name(struct gaim_connection *gc, char *name) { 196 static int find_id_by_name(struct gaim_connection *gc, char *name)
190 gchar *temp = (gchar *)g_malloc(IRC_BUF_LEN + 1); 197 {
198 gchar *temp = (gchar *) g_malloc(IRC_BUF_LEN + 1);
191 GList *templist; 199 GList *templist;
192 struct irc_channel *channel; 200 struct irc_channel *channel;
193 201
194 templist = ((struct irc_data *)gc->proto_data)->channels; 202 templist = ((struct irc_data *)gc->proto_data)->channels;
195 203
201 if (g_strcasecmp(temp, name) == 0) { 209 if (g_strcasecmp(temp, name) == 0) {
202 g_free(temp); 210 g_free(temp);
203 return channel->id; 211 return channel->id;
204 } 212 }
205 213
206 templist = templist -> next; 214 templist = templist->next;
207 } 215 }
208 216
209 g_free(temp); 217 g_free(temp);
210 218
211 /* Return -1 if we have no ID */ 219 /* Return -1 if we have no ID */
212 return -1; 220 return -1;
213 } 221 }
214 222
215 struct irc_channel * find_channel_by_name(struct gaim_connection *gc, char *name) { 223 static struct irc_channel *find_channel_by_name(struct gaim_connection *gc, char *name)
216 gchar *temp = (gchar *)g_malloc(IRC_BUF_LEN + 1); 224 {
225 gchar *temp = (gchar *) g_malloc(IRC_BUF_LEN + 1);
217 GList *templist; 226 GList *templist;
218 struct irc_channel *channel; 227 struct irc_channel *channel;
219 228
220 templist = ((struct irc_data *)gc->proto_data)->channels; 229 templist = ((struct irc_data *)gc->proto_data)->channels;
221 230
227 if (g_strcasecmp(temp, name) == 0) { 236 if (g_strcasecmp(temp, name) == 0) {
228 g_free(temp); 237 g_free(temp);
229 return channel; 238 return channel;
230 } 239 }
231 240
232 templist = templist -> next; 241 templist = templist->next;
233 } 242 }
234 243
235 g_free(temp); 244 g_free(temp);
236 245
237 /* If we found nothing, return nothing :-) */ 246 /* If we found nothing, return nothing :-) */
238 return NULL; 247 return NULL;
239 } 248 }
240 249
241 struct irc_channel * find_channel_by_id (struct gaim_connection *gc, int id) { 250 static struct irc_channel *find_channel_by_id(struct gaim_connection *gc, int id)
251 {
242 struct irc_data *idata = (struct irc_data *)gc->proto_data; 252 struct irc_data *idata = (struct irc_data *)gc->proto_data;
243 struct irc_channel *channel; 253 struct irc_channel *channel;
244 254
245 GList *temp; 255 GList *temp;
246 256
247 temp = idata->channels; 257 temp = idata->channels;
248 258
249 while (temp) { 259 while (temp) {
251 261
252 if (channel->id == id) { 262 if (channel->id == id) {
253 /* We've found our man */ 263 /* We've found our man */
254 return channel; 264 return channel;
255 } 265 }
256 266
257 temp = temp->next; 267 temp = temp->next;
258 } 268 }
259 269
260 270
261 /* If we didnt find one, return NULL */ 271 /* If we didnt find one, return NULL */
262 return NULL; 272 return NULL;
263 } 273 }
264 274
265 void irc_chat_send( struct gaim_connection *gc, int id, char *message) { 275 static void irc_chat_send(struct gaim_connection *gc, int id, char *message)
276 {
266 277
267 struct irc_data *idata = (struct irc_data *)gc->proto_data; 278 struct irc_data *idata = (struct irc_data *)gc->proto_data;
268 struct irc_channel *channel = NULL; 279 struct irc_channel *channel = NULL;
269 gchar *buf = (gchar *)g_malloc(IRC_BUF_LEN + 1); 280 gchar *buf = (gchar *) g_malloc(IRC_BUF_LEN + 1);
270 281
271 /* First lets get our current channel */ 282 /* First lets get our current channel */
272 channel = find_channel_by_id(gc, id); 283 channel = find_channel_by_id(gc, id);
273 284
274 285
275 if (!channel) { 286 if (!channel) {
276 /* If for some reason we've lost our channel, let's bolt */ 287 /* If for some reason we've lost our channel, let's bolt */
277 g_free(buf); 288 g_free(buf);
278 return; 289 return;
279 } 290 }
280 291
281 292
282 /* Before we actually send this, we should check to see if they're trying 293 /* Before we actually send this, we should check to see if they're trying
283 * To issue a /me command and handle it properly. */ 294 * To issue a /me command and handle it properly. */
284 295
285 if ( (g_strncasecmp(message, "/me ", 4) == 0) && (strlen(message)>4)) { 296 if ((g_strncasecmp(message, "/me ", 4) == 0) && (strlen(message) > 4)) {
286 /* We have /me!! We have /me!! :-) */ 297 /* We have /me!! We have /me!! :-) */
287 298
288 gchar *temp = (gchar *)g_malloc(IRC_BUF_LEN+1); 299 gchar *temp = (gchar *) g_malloc(IRC_BUF_LEN + 1);
289 strcpy(temp, message+4); 300 strcpy(temp, message + 4);
290 g_snprintf(buf, IRC_BUF_LEN, "PRIVMSG #%s :%cACTION %s%c\n", channel->name, '\001', temp, '\001'); 301 g_snprintf(buf, IRC_BUF_LEN, "PRIVMSG #%s :%cACTION %s%c\n", channel->name, '\001', temp,
302 '\001');
291 g_free(temp); 303 g_free(temp);
292 } 304 } else {
293 else
294 {
295 g_snprintf(buf, IRC_BUF_LEN, "PRIVMSG #%s :%s\n", channel->name, message); 305 g_snprintf(buf, IRC_BUF_LEN, "PRIVMSG #%s :%s\n", channel->name, message);
296 } 306 }
297 307
298 write(idata->fd, buf, strlen(buf)); 308 write(idata->fd, buf, strlen(buf));
299 309
300 /* Since AIM expects us to receive the message we send, we gotta fake it */ 310 /* Since AIM expects us to receive the message we send, we gotta fake it */
301 serv_got_chat_in(gc, id, gc->username, 0, message); 311 serv_got_chat_in(gc, id, gc->username, 0, message);
302 312
303 g_free(buf); 313 g_free(buf);
304 } 314 }
305 315
306 struct conversation * find_conversation_by_id( struct gaim_connection * gc, int id) { 316 static struct conversation *find_conversation_by_id(struct gaim_connection *gc, int id)
317 {
307 struct irc_data *idata = (struct irc_data *)gc->proto_data; 318 struct irc_data *idata = (struct irc_data *)gc->proto_data;
308 GSList *bc = gc->buddy_chats; 319 GSList *bc = gc->buddy_chats;
309 struct conversation *b = NULL; 320 struct conversation *b = NULL;
310 321
311 while (bc) { 322 while (bc) {
322 } 333 }
323 334
324 return b; 335 return b;
325 } 336 }
326 337
327 struct conversation * find_conversation_by_name( struct gaim_connection * gc, char *name) { 338 static struct conversation *find_conversation_by_name(struct gaim_connection *gc, char *name)
339 {
328 struct irc_data *idata = (struct irc_data *)gc->proto_data; 340 struct irc_data *idata = (struct irc_data *)gc->proto_data;
329 GSList *bc = gc->buddy_chats; 341 GSList *bc = gc->buddy_chats;
330 struct conversation *b = NULL; 342 struct conversation *b = NULL;
331 343
332 while (bc) { 344 while (bc) {
346 return b; 358 return b;
347 } 359 }
348 360
349 361
350 362
351 void irc_callback ( struct gaim_connection * gc ) { 363 static void irc_callback(gpointer data, gint source, GdkInputCondition condition)
352 364 {
365 struct gaim_connection *gc = data;
353 int i = 0; 366 int i = 0;
354 char c;
355 gchar buf[4096]; 367 gchar buf[4096];
356 gchar **buf2; 368 gchar **buf2;
357 int status;
358 struct irc_data *idata; 369 struct irc_data *idata;
359 370
360 idata = (struct irc_data *)gc->proto_data; 371 idata = (struct irc_data *)gc->proto_data;
361 372
362 do { 373 do {
363 status = recv(idata->fd, &c, 1, 0); 374 if (read(idata->fd, buf + i, 1) < 0) {
364 375 hide_login_progress(gc, "Read error");
365 if (!status) 376 signoff(gc);
366 {
367 return; 377 return;
368 } 378 }
369 buf[i] = c; 379 } while (buf[i++] != '\n');
370 i++; 380
371 } while (c != '\n'); 381 buf[--i] = '\0';
372
373 buf[i] = '\0';
374
375 /* And remove that damned trailing \n */
376 g_strchomp(buf);
377
378 /* For now, lets display everything to the console too. Im such
379 * a bitch */
380 printf("IRC:'%'s\n", buf);
381
382
383 382
384 /* Check for errors */ 383 /* Check for errors */
385 384
386 if (((strstr(buf, "ERROR :") && (!strstr(buf, "PRIVMSG ")) && 385 if (((strstr(buf, "ERROR :") && (!strstr(buf, "PRIVMSG ")) &&
387 (!strstr(buf, "NOTICE ")) && (strlen(buf) > 7)))) { 386 (!strstr(buf, "NOTICE ")) && (strlen(buf) > 7)))) {
388 387
389 gchar *u_errormsg; 388 gchar *u_errormsg;
390 389
391 /* Let's get our error message */ 390 /* Let's get our error message */
392 u_errormsg = strdup(buf + 7); 391 u_errormsg = strdup(buf + 7);
397 do_error_dialog(u_errormsg, "Gaim: IRC Error"); 396 do_error_dialog(u_errormsg, "Gaim: IRC Error");
398 397
399 /* And our necessary garbage collection */ 398 /* And our necessary garbage collection */
400 free(u_errormsg); 399 free(u_errormsg);
401 } 400 }
402 401
403 /* Parse the list of names that we receive when we first sign on to 402 /* Parse the list of names that we receive when we first sign on to
404 * a channel */ 403 * a channel */
405 404
406 if (((strstr(buf, " 353 ")) && (!strstr(buf, "PRIVMSG")) && 405 if (((strstr(buf, " 353 ")) && (!strstr(buf, "PRIVMSG")) && (!strstr(buf, "NOTICE")))) {
407 (!strstr(buf, "NOTICE")))) {
408 gchar u_host[255]; 406 gchar u_host[255];
409 gchar u_command[32]; 407 gchar u_command[32];
410 gchar u_channel[128]; 408 gchar u_channel[128];
411 gchar u_names[IRC_BUF_LEN + 1]; 409 gchar u_names[IRC_BUF_LEN + 1];
412 struct conversation *convo = NULL; 410 struct conversation *convo = NULL;
414 412
415 for (j = 0, i = 0; buf[i] != ' '; j++, i++) { 413 for (j = 0, i = 0; buf[i] != ' '; j++, i++) {
416 u_host[j] = buf[i]; 414 u_host[j] = buf[i];
417 } 415 }
418 416
419 u_host[j] = '\0'; i++; 417 u_host[j] = '\0';
418 i++;
420 419
421 for (j = 0; buf[i] != ' '; j++, i++) { 420 for (j = 0; buf[i] != ' '; j++, i++) {
422 u_command[j] = buf[i]; 421 u_command[j] = buf[i];
423 } 422 }
424 423
425 u_command[j] = '\0'; i++; 424 u_command[j] = '\0';
425 i++;
426 426
427 for (j = 0; buf[i] != '#'; j++, i++) { 427 for (j = 0; buf[i] != '#'; j++, i++) {
428 } 428 }
429 i++; 429 i++;
430 430
431 for (j = 0; buf[i] != ':'; j++, i++) { 431 for (j = 0; buf[i] != ':'; j++, i++) {
432 u_channel[j] = buf[i]; 432 u_channel[j] = buf[i];
433 } 433 }
434 434
435 u_channel[j-1] = '\0'; i++; 435 u_channel[j - 1] = '\0';
436 i++;
436 437
437 while ((buf[i] == ' ') || (buf[i] == ':')) { 438 while ((buf[i] == ' ') || (buf[i] == ':')) {
438 i++; 439 i++;
439 } 440 }
440 441
441 strcpy(u_names, buf + i); 442 strcpy(u_names, buf + i);
442 443
443 buf2 = g_strsplit(u_names, " ", 0); 444 buf2 = g_strsplit(u_names, " ", 0);
444 445
445 /* Let's get our conversation window */ 446 /* Let's get our conversation window */
446 convo = find_conversation_by_name(gc, u_channel); 447 convo = find_conversation_by_name(gc, u_channel);
447 448
448 if (!convo) { 449 if (!convo) {
449 return; 450 return;
450 } 451 }
451 452
452 /* Now that we've parsed the hell out of this big 453 /* Now that we've parsed the hell out of this big
453 * mess, let's try to split up the names properly */ 454 * mess, let's try to split up the names properly */
454 455
455 for (i = 0; buf2[i] != NULL; i++) { 456 for (i = 0; buf2[i] != NULL; i++) {
456 /* We shouldnt play with ourselves */ 457 /* We shouldnt play with ourselves */
462 add_chat_buddy(convo, buf2[i]); 463 add_chat_buddy(convo, buf2[i]);
463 } 464 }
464 } 465 }
465 466
466 /* And free our pointers */ 467 /* And free our pointers */
467 g_strfreev (buf2); 468 g_strfreev(buf2);
468 469
469 return; 470 return;
470 471
471 } 472 }
472 473
473 /* Receive a list of users that are currently online */ 474 /* Receive a list of users that are currently online */
474 475
475 if (((strstr(buf, " 303 ")) && (!strstr(buf, "PRIVMSG")) && 476 if (((strstr(buf, " 303 ")) && (!strstr(buf, "PRIVMSG")) && (!strstr(buf, "NOTICE")))) {
476 (!strstr(buf, "NOTICE")))) {
477 gchar u_host[255]; 477 gchar u_host[255];
478 gchar u_command[32]; 478 gchar u_command[32];
479 gchar u_names[IRC_BUF_LEN + 1]; 479 gchar u_names[IRC_BUF_LEN + 1];
480 int j; 480 int j;
481 481
482 for (j = 0, i = 0; buf[i] != ' '; j++, i++) { 482 for (j = 0, i = 0; buf[i] != ' '; j++, i++) {
483 u_host[j] = buf[i]; 483 u_host[j] = buf[i];
484 } 484 }
485 485
486 u_host[j] = '\0'; i++; 486 u_host[j] = '\0';
487 i++;
487 488
488 for (j = 0; buf[i] != ' '; j++, i++) { 489 for (j = 0; buf[i] != ' '; j++, i++) {
489 u_command[j] = buf[i]; 490 u_command[j] = buf[i];
490 } 491 }
491 492
492 u_command[j] = '\0'; i++; 493 u_command[j] = '\0';
494 i++;
493 495
494 for (j = 0; buf[i] != ':'; j++, i++) { 496 for (j = 0; buf[i] != ':'; j++, i++) {
495 /* My Nick */ 497 /* My Nick */
496 } 498 }
497 i++; 499 i++;
498 500
499 strcpy(u_names, buf + i); 501 strcpy(u_names, buf + i);
500 502
501 buf2 = g_strsplit(u_names, " ", 0); 503 buf2 = g_strsplit(u_names, " ", 0);
502 504
503 /* Now that we've parsed the hell out of this big 505 /* Now that we've parsed the hell out of this big
504 * mess, let's try to split up the names properly */ 506 * mess, let's try to split up the names properly */
505 507
506 for (i = 0; buf2[i] != NULL; i++) { 508 for (i = 0; buf2[i] != NULL; i++) {
507 /* If we have a name here then our buddy is online. We should 509 /* If we have a name here then our buddy is online. We should
508 * update our temporary gslist accordingly. When we achieve our maximum 510 * update our temporary gslist accordingly. When we achieve our maximum
509 * list of names then we should force an update */ 511 * list of names then we should force an update */
510 512
511 irc_update_user(gc, buf2[i], 1); 513 irc_update_user(gc, buf2[i], 1);
512 } 514 }
513 515
514 /* Increase our received blocks counter */ 516 /* Increase our received blocks counter */
515 idata->recblocks++; 517 idata->recblocks++;
516 518
517 /* If we have our total number of blocks */ 519 /* If we have our total number of blocks */
518 if (idata->recblocks == idata->totalblocks) { 520 if (idata->recblocks == idata->totalblocks) {
519 GSList *temp; 521 GSList *temp;
520 struct irc_channel *u; 522 struct irc_channel *u;
521 523
522 /* Let's grab our list of people and bring them all on or off line */ 524 /* Let's grab our list of people and bring them all on or off line */
523 temp = idata->templist; 525 temp = idata->templist;
524 526
525 /* Loop */ 527 /* Loop */
526 while (temp) { 528 while (temp) {
527 529
528 u = temp->data; 530 u = temp->data;
529 531
530 /* Tell Gaim to bring the person on or off line */ 532 /* Tell Gaim to bring the person on or off line */
531 serv_got_update(gc, u->name, u->id, 0, 0, 0, 0, 0); 533 serv_got_update(gc, u->name, u->id, 0, 0, 0, 0, 0);
532 534
533 /* Grab the next entry */ 535 /* Grab the next entry */
534 temp = g_slist_next(temp); 536 temp = g_slist_next(temp);
535 } 537 }
536 538
537 /* And now, let's delete all of our entries */ 539 /* And now, let's delete all of our entries */
538 temp = idata->templist; 540 temp = idata->templist;
539 while (temp) { 541 while (temp) {
540 u = temp->data; 542 u = temp->data;
541 g_free(u->name); 543 g_free(u->name);
542 temp = g_slist_remove(temp, u); 544 temp = g_slist_remove(temp, u);
543 } 545 }
544 546
545 /* Reset our list */ 547 /* Reset our list */
546 idata->totalblocks = 0; 548 idata->totalblocks = 0;
547 idata->recblocks = 0; 549 idata->recblocks = 0;
548 550
549 idata->templist = NULL; 551 idata->templist = NULL;
550 552
551 return; 553 return;
552 } 554 }
553 555
554 /* And free our pointers */ 556 /* And free our pointers */
555 g_strfreev (buf2); 557 g_strfreev(buf2);
556 558
557 return; 559 return;
558 560
559 } 561 }
560 562
561 563
562 if ( (strstr(buf, " JOIN ")) && (buf[0] == ':') && (!strstr(buf, " NOTICE "))) { 564 if ((strstr(buf, " JOIN ")) && (buf[0] == ':') && (!strstr(buf, " NOTICE "))) {
563 565
564 gchar u_channel[128]; 566 gchar u_channel[128];
565 gchar u_nick[128]; 567 gchar u_nick[128];
566 568
567 struct irc_channel *channel; 569 struct irc_channel *channel;
568 int id; 570 int id;
569 int j; 571 int j;
570 572
571 for (j = 0, i = 1; buf[i] != '!'; j++, i++) { 573 for (j = 0, i = 1; buf[i] != '!'; j++, i++) {
572 u_nick[j] = buf[i]; 574 u_nick[j] = buf[i];
573 } 575 }
574 576
575 u_nick[j] = '\0'; i++; 577 u_nick[j] = '\0';
578 i++;
576 579
577 for (j = 0; buf[i] != '#'; j++, i++) { 580 for (j = 0; buf[i] != '#'; j++, i++) {
578 } 581 }
579 582
580 i++; 583 i++;
581 584
582 strcpy(u_channel, buf+i); 585 strcpy(u_channel, buf + i);
583 586
584 /* Looks like we're going to join the channel for real 587 /* Looks like we're going to join the channel for real
585 * now. Let's create a valid channel structure and add 588 * now. Let's create a valid channel structure and add
586 * it to our list. Let's make sure that 589 * it to our list. Let's make sure that
587 * we are not already in a channel first */ 590 * we are not already in a channel first */
590 593
591 if (!channel) { 594 if (!channel) {
592 chat_id++; 595 chat_id++;
593 596
594 channel = g_new0(struct irc_channel, 1); 597 channel = g_new0(struct irc_channel, 1);
595 598
596 channel->id = chat_id; 599 channel->id = chat_id;
597 channel->name = strdup(u_channel); 600 channel->name = strdup(u_channel);
598 601
599 idata->channels = g_list_append(idata->channels, channel); 602 idata->channels = g_list_append(idata->channels, channel);
600 603
601 serv_got_joined_chat(gc, chat_id, u_channel); 604 serv_got_joined_chat(gc, chat_id, u_channel);
602 } else { 605 } else {
603 struct conversation *convo = NULL; 606 struct conversation *convo = NULL;
604 607
605 /* Someone else joined. Find their conversation 608 /* Someone else joined. Find their conversation
606 * window */ 609 * window */
607 convo = find_conversation_by_id(gc, channel->id); 610 convo = find_conversation_by_id(gc, channel->id);
608 611
609 /* And add their name to it */ 612 /* And add their name to it */
610 add_chat_buddy(convo, u_nick); 613 add_chat_buddy(convo, u_nick);
611 614
612 } 615 }
613 616
614 return; 617 return;
615 } 618 }
616 619
617 if ( (strstr(buf, " PART ")) && (buf[0] == ':') && (!strstr(buf, " NOTICE "))) { 620 if ((strstr(buf, " PART ")) && (buf[0] == ':') && (!strstr(buf, " NOTICE "))) {
618 621
619 gchar u_channel[128]; 622 gchar u_channel[128];
620 gchar u_nick[128]; 623 gchar u_nick[128];
621 624
622 struct irc_channel *channel; 625 struct irc_channel *channel;
628 u_nick[j] = buf[i]; 631 u_nick[j] = buf[i];
629 } 632 }
630 u_nick[j] = '\0'; 633 u_nick[j] = '\0';
631 634
632 i++; 635 i++;
633 636
634 for (j = 0; buf[i] != '#'; j++, i++) { 637 for (j = 0; buf[i] != '#'; j++, i++) {
635 } 638 }
636 639
637 i++; 640 i++;
638 641
639 strcpy(u_channel, buf+i); 642 strcpy(u_channel, buf + i);
640 643
641 644
642 /* Now, lets check to see if it was US that was leaving. 645 /* Now, lets check to see if it was US that was leaving.
643 * If so, do the correct thing by closing up all of our 646 * If so, do the correct thing by closing up all of our
644 * old channel stuff. Otherwise, 647 * old channel stuff. Otherwise,
649 if (!channel) { 652 if (!channel) {
650 return; 653 return;
651 } 654 }
652 655
653 if (g_strcasecmp(u_nick, gc->username) == 0) { 656 if (g_strcasecmp(u_nick, gc->username) == 0) {
654 657
655 /* Looks like we're going to leave the channel for 658 /* Looks like we're going to leave the channel for
656 * real now. Let's create a valid channel structure 659 * real now. Let's create a valid channel structure
657 * and add it to our list */ 660 * and add it to our list */
658 661
659 serv_got_chat_left(gc, channel->id); 662 serv_got_chat_left(gc, channel->id);
660 663
661 idata->channels = g_list_remove(idata->channels, channel); 664 idata->channels = g_list_remove(idata->channels, channel);
662 } else { 665 } else {
663 struct conversation *convo = NULL; 666 struct conversation *convo = NULL;
664 667
665 /* Find their conversation window */ 668 /* Find their conversation window */
666 convo = find_conversation_by_id(gc, channel->id); 669 convo = find_conversation_by_id(gc, channel->id);
667 670
668 if (!convo) { 671 if (!convo) {
669 /* Some how the window doesn't exist. 672 /* Some how the window doesn't exist.
670 * Let's get out of here */ 673 * Let's get out of here */
671 return ; 674 return;
672 } 675 }
673 676
674 /* And remove their name */ 677 /* And remove their name */
675 remove_chat_buddy(convo, u_nick); 678 remove_chat_buddy(convo, u_nick);
676 679
677 } 680 }
678 681
679 /* Go Home! */ 682 /* Go Home! */
680 return; 683 return;
681 } 684 }
682 685
683 if ( (strstr(buf, " NOTICE ")) && (buf[0] == ':')) { 686 if ((strstr(buf, " NOTICE ")) && (buf[0] == ':')) {
684 gchar u_nick[128]; 687 gchar u_nick[128];
685 gchar u_host[255]; 688 gchar u_host[255];
686 gchar u_command[32]; 689 gchar u_command[32];
687 gchar u_channel[128]; 690 gchar u_channel[128];
688 gchar u_message[IRC_BUF_LEN]; 691 gchar u_message[IRC_BUF_LEN];
691 694
692 for (j = 0, i = 1; buf[i] != '!'; j++, i++) { 695 for (j = 0, i = 1; buf[i] != '!'; j++, i++) {
693 u_nick[j] = buf[i]; 696 u_nick[j] = buf[i];
694 } 697 }
695 698
696 u_nick[j] = '\0'; i++; 699 u_nick[j] = '\0';
700 i++;
697 701
698 for (j = 0; buf[i] != ' '; j++, i++) { 702 for (j = 0; buf[i] != ' '; j++, i++) {
699 u_host[j] = buf[i]; 703 u_host[j] = buf[i];
700 } 704 }
701 705
702 u_host[j] = '\0'; i++; 706 u_host[j] = '\0';
707 i++;
703 708
704 for (j = 0; buf[i] != ' '; j++, i++) { 709 for (j = 0; buf[i] != ' '; j++, i++) {
705 u_command[j] = buf[i]; 710 u_command[j] = buf[i];
706 } 711 }
707 712
708 u_command[j] = '\0'; i++; 713 u_command[j] = '\0';
714 i++;
709 715
710 for (j = 0; buf[i] != ':'; j++, i++) { 716 for (j = 0; buf[i] != ':'; j++, i++) {
711 u_channel[j] = buf[i]; 717 u_channel[j] = buf[i];
712 } 718 }
713 719
714 u_channel[j-1] = '\0'; i++; 720 u_channel[j - 1] = '\0';
721 i++;
715 722
716 723
717 /* Now that everything is parsed, the rest of this baby must be our message */ 724 /* Now that everything is parsed, the rest of this baby must be our message */
718 strncpy(u_message, buf + i, IRC_BUF_LEN); 725 strncpy(u_message, buf + i, IRC_BUF_LEN);
719 726
723 /* Someone's triyng to ping us. Let's respond */ 730 /* Someone's triyng to ping us. Let's respond */
724 gchar u_arg[24]; 731 gchar u_arg[24];
725 gchar u_buf[200]; 732 gchar u_buf[200];
726 733
727 strcpy(u_arg, u_message + 6); 734 strcpy(u_arg, u_message + 6);
728 u_arg[strlen(u_arg)-1] = '\0'; 735 u_arg[strlen(u_arg) - 1] = '\0';
729 736
730 /* FIXME: We should keep track of pings we send. We should store 737 /* FIXME: We should keep track of pings we send. We should store
731 * the serial # and the time so that we can accurately report which 738 * the serial # and the time so that we can accurately report which
732 * pings are turning, etc */ 739 * pings are turning, etc */
733 740
734 g_snprintf(u_buf, sizeof(u_buf), "Ping Reply From %s", u_nick); 741 g_snprintf(u_buf, sizeof(u_buf), "Ping Reply From %s", u_nick);
735 742
736 do_error_dialog(u_buf, "Gaim IRC - Ping Reply"); 743 do_error_dialog(u_buf, "Gaim IRC - Ping Reply");
737 744
738 return; 745 return;
739 } 746 }
740 } 747 }
741 748
742 } 749 }
743 750
744 751
745 if ( (strstr(buf, " PRIVMSG ")) && (buf[0] == ':')) { 752 if ((strstr(buf, " PRIVMSG ")) && (buf[0] == ':')) {
746 gchar u_nick[128]; 753 gchar u_nick[128];
747 gchar u_host[255]; 754 gchar u_host[255];
748 gchar u_command[32]; 755 gchar u_command[32];
749 gchar u_channel[128]; 756 gchar u_channel[128];
750 gchar u_message[IRC_BUF_LEN]; 757 gchar u_message[IRC_BUF_LEN];
753 760
754 for (j = 0, i = 1; buf[i] != '!'; j++, i++) { 761 for (j = 0, i = 1; buf[i] != '!'; j++, i++) {
755 u_nick[j] = buf[i]; 762 u_nick[j] = buf[i];
756 } 763 }
757 764
758 u_nick[j] = '\0'; i++; 765 u_nick[j] = '\0';
766 i++;
759 767
760 for (j = 0; buf[i] != ' '; j++, i++) { 768 for (j = 0; buf[i] != ' '; j++, i++) {
761 u_host[j] = buf[i]; 769 u_host[j] = buf[i];
762 } 770 }
763 771
764 u_host[j] = '\0'; i++; 772 u_host[j] = '\0';
773 i++;
765 774
766 for (j = 0; buf[i] != ' '; j++, i++) { 775 for (j = 0; buf[i] != ' '; j++, i++) {
767 u_command[j] = buf[i]; 776 u_command[j] = buf[i];
768 } 777 }
769 778
770 u_command[j] = '\0'; i++; 779 u_command[j] = '\0';
780 i++;
771 781
772 for (j = 0; buf[i] != ':'; j++, i++) { 782 for (j = 0; buf[i] != ':'; j++, i++) {
773 u_channel[j] = buf[i]; 783 u_channel[j] = buf[i];
774 } 784 }
775 785
776 u_channel[j-1] = '\0'; i++; 786 u_channel[j - 1] = '\0';
787 i++;
777 788
778 789
779 /* Now that everything is parsed, the rest of this baby must be our message */ 790 /* Now that everything is parsed, the rest of this baby must be our message */
780 strncpy(u_message, buf + i, IRC_BUF_LEN); 791 strncpy(u_message, buf + i, IRC_BUF_LEN);
781 792
782 /* Now, lets check the message to see if there's anything special in it */ 793 /* Now, lets check the message to see if there's anything special in it */
783 if (u_message[0] == '\001') { 794 if (u_message[0] == '\001') {
784 if (g_strncasecmp(u_message, "\001VERSION", 8) == 0) { 795 if (g_strncasecmp(u_message, "\001VERSION", 8) == 0) {
785 /* Looks like we have a version request. Let 796 /* Looks like we have a version request. Let
786 * us handle it thusly */ 797 * us handle it thusly */
787 798
788 g_snprintf(buf, IRC_BUF_LEN, "NOTICE %s :%cVERSION GAIM %s:The Pimpin Penguin AIM Clone:www.marko.net/gaim%c\n", u_nick, '\001', VERSION, '\001'); 799 g_snprintf(buf, IRC_BUF_LEN,
800 "NOTICE %s :%cVERSION GAIM %s:The Pimpin Penguin AIM Clone:www.marko.net/gaim%c\n",
801 u_nick, '\001', VERSION, '\001');
789 802
790 write(idata->fd, buf, strlen(buf)); 803 write(idata->fd, buf, strlen(buf));
791 804
792 /* And get the heck out of dodge */ 805 /* And get the heck out of dodge */
793 return; 806 return;
794 } 807 }
795 808
796 if ((g_strncasecmp(u_message, "\001PING ", 6) == 0) && (strlen(u_message) > 6)) { 809 if ((g_strncasecmp(u_message, "\001PING ", 6) == 0) && (strlen(u_message) > 6)) {
797 /* Someone's triyng to ping us. Let's respond */ 810 /* Someone's triyng to ping us. Let's respond */
798 gchar u_arg[24]; 811 gchar u_arg[24];
799 812
800 strcpy(u_arg, u_message + 6); 813 strcpy(u_arg, u_message + 6);
801 u_arg[strlen(u_arg)-1] = '\0'; 814 u_arg[strlen(u_arg) - 1] = '\0';
802 815
803 g_snprintf(buf, IRC_BUF_LEN, "NOTICE %s :%cPING %s%c\n", u_nick, '\001', u_arg, '\001'); 816 g_snprintf(buf, IRC_BUF_LEN, "NOTICE %s :%cPING %s%c\n", u_nick, '\001',
817 u_arg, '\001');
804 818
805 write(idata->fd, buf, strlen(buf)); 819 write(idata->fd, buf, strlen(buf));
806 820
807 /* And get the heck out of dodge */ 821 /* And get the heck out of dodge */
808 return; 822 return;
828 842
829 id = find_id_by_name(gc, u_channel); 843 id = find_id_by_name(gc, u_channel);
830 if (id != -1) { 844 if (id != -1) {
831 serv_got_chat_in(gc, id, u_nick, 0, u_message); 845 serv_got_chat_in(gc, id, u_nick, 0, u_message);
832 } 846 }
833 } 847 } else {
834 else {
835 /* Nope. Let's treat it as a private message */ 848 /* Nope. Let's treat it as a private message */
836 serv_got_im(gc, u_nick, u_message, 0); 849 serv_got_im(gc, u_nick, u_message, 0);
837 } 850 }
838 851
839 return; 852 return;
841 854
842 /* Let's parse PING requests so that we wont get booted for inactivity */ 855 /* Let's parse PING requests so that we wont get booted for inactivity */
843 856
844 if (strncmp(buf, "PING :", 6) == 0) { 857 if (strncmp(buf, "PING :", 6) == 0) {
845 buf2 = g_strsplit(buf, ":", 1); 858 buf2 = g_strsplit(buf, ":", 1);
846 859
847 /* Let's build a new response */ 860 /* Let's build a new response */
848 g_snprintf(buf, IRC_BUF_LEN, "PONG :%s\n", buf2[1]); 861 g_snprintf(buf, IRC_BUF_LEN, "PONG :%s\n", buf2[1]);
849 write(idata->fd, buf, strlen(buf)); 862 write(idata->fd, buf, strlen(buf));
850 863
851 /* And clean up after ourselves */ 864 /* And clean up after ourselves */
854 return; 867 return;
855 } 868 }
856 869
857 } 870 }
858 871
859 void irc_handler(gpointer data, gint source, GdkInputCondition condition) { 872 static void irc_close(struct gaim_connection *gc)
860 irc_callback(data); 873 {
861 }
862
863 void irc_close(struct gaim_connection *gc) {
864 struct irc_data *idata = (struct irc_data *)gc->proto_data; 874 struct irc_data *idata = (struct irc_data *)gc->proto_data;
865 GList *chats = idata->channels; 875 GList *chats = idata->channels;
866 struct irc_channel *cc; 876 struct irc_channel *cc;
867 877
868 gchar *buf = (gchar *)g_malloc(IRC_BUF_LEN); 878 gchar *buf = (gchar *) g_malloc(IRC_BUF_LEN);
869 879
870 gtk_timeout_remove(idata->timer);
871
872 g_snprintf(buf, IRC_BUF_LEN, "QUIT :Download GAIM [www.marko.net/gaim]\n"); 880 g_snprintf(buf, IRC_BUF_LEN, "QUIT :Download GAIM [www.marko.net/gaim]\n");
873 write(idata->fd, buf, strlen(buf)); 881 write(idata->fd, buf, strlen(buf));
874 882
875 g_free(buf); 883 g_free(buf);
884
885 if (idata->timer)
886 gtk_timeout_remove(idata->timer);
876 887
877 while (chats) { 888 while (chats) {
878 cc = (struct irc_channel *)chats->data; 889 cc = (struct irc_channel *)chats->data;
879 g_free(cc->name); 890 g_free(cc->name);
880 chats = g_list_remove(chats, cc); 891 chats = g_list_remove(chats, cc);
881 g_free(cc); 892 g_free(cc);
882 } 893 }
883 894
884 if (gc->inpa) 895 if (gc->inpa)
885 gdk_input_remove(gc->inpa); 896 gdk_input_remove(gc->inpa);
886 897
898 if (idata->inpa)
899 gdk_input_remove(idata->inpa);
900
887 close(idata->fd); 901 close(idata->fd);
888 g_free(gc->proto_data); 902 g_free(gc->proto_data);
889 } 903 }
890 904
891 void irc_chat_leave(struct gaim_connection *gc, int id) { 905 static void irc_chat_leave(struct gaim_connection *gc, int id)
906 {
892 struct irc_data *idata = (struct irc_data *)gc->proto_data; 907 struct irc_data *idata = (struct irc_data *)gc->proto_data;
893 struct irc_channel *channel; 908 struct irc_channel *channel;
894 gchar *buf = (gchar *)g_malloc(IRC_BUF_LEN+1); 909 gchar *buf = (gchar *) g_malloc(IRC_BUF_LEN + 1);
895 910
896 channel = find_channel_by_id(gc, id); 911 channel = find_channel_by_id(gc, id);
897 912
898 if (!channel) { 913 if (!channel) {
899 return; 914 return;
900 } 915 }
901 916
902 g_snprintf(buf, IRC_BUF_LEN, "PART #%s\n", channel->name); 917 g_snprintf(buf, IRC_BUF_LEN, "PART #%s\n", channel->name);
903 write(idata->fd, buf, strlen(buf)); 918 write(idata->fd, buf, strlen(buf));
904 919
905 g_free(buf); 920 g_free(buf);
906 } 921 }
907 922
908 void irc_login(struct aim_user *user) { 923 static void irc_login_callback(gpointer data, gint source, GdkInputCondition condition)
924 {
925 struct gaim_connection *gc = data;
926 struct irc_data *idata = gc->proto_data;
927 char buf[4096];
928 int len, error = ETIMEDOUT;
929
930 len = sizeof(error);
931 if (getsockopt(idata->fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
932 error = errno;
933 if (error) {
934 hide_login_progress(gc, "Couldn't connect");
935 signoff(gc);
936 return;
937 }
938
939 fcntl(idata->fd, F_SETFL, 0);
940
941 g_snprintf(buf, 4096, "NICK %s\n USER %s localhost %s :GAIM (www.marko.net/gaim)\n",
942 gc->username, g_get_user_name(), gc->user->proto_opt[0]);
943
944 if (write(idata->fd, buf, strlen(buf)) < 0) {
945 hide_login_progress(gc, "Write error");
946 signoff(gc);
947 return;
948 }
949
950 gdk_input_remove(idata->inpa);
951 idata->inpa = 0;
952
953 /* Now lets sign ourselves on */
954 account_online(gc);
955 serv_finish_login(gc);
956
957 if (bud_list_cache_exists(gc))
958 do_import(NULL, gc);
959
960 idata->timer = gtk_timeout_add(20000, (GtkFunction)irc_request_buddy_update, gc);
961
962 irc_request_buddy_update(gc);
963 }
964
965 static void irc_login(struct aim_user *user)
966 {
909 int fd; 967 int fd;
910 struct hostent *host; 968 struct hostent *host;
911 struct sockaddr_in site; 969 struct sockaddr_in site;
912 char buf[4096]; 970 char buf[4096];
913 971
914 struct gaim_connection *gc = new_gaim_conn(user); 972 struct gaim_connection *gc = new_gaim_conn(user);
915 struct irc_data *idata = gc->proto_data = g_new0(struct irc_data, 1); 973 struct irc_data *idata = gc->proto_data = g_new0(struct irc_data, 1);
916 char c; 974 char c;
917 int i; 975 int i;
918 int status; 976 int status;
919 977
920 set_login_progress(gc, 1, buf);
921
922 while (gtk_events_pending())
923 gtk_main_iteration();
924 if (!g_slist_find(connections, gc))
925 return;
926
927 host = gethostbyname(user->proto_opt[0]); 978 host = gethostbyname(user->proto_opt[0]);
928 if (!host) { 979 if (!host) {
929 hide_login_progress(gc, "Unable to resolve hostname"); 980 hide_login_progress(gc, "Unable to resolve hostname");
930 signoff(gc); 981 signoff(gc);
931 return; 982 return;
940 hide_login_progress(gc, "Unable to create socket"); 991 hide_login_progress(gc, "Unable to create socket");
941 signoff(gc); 992 signoff(gc);
942 return; 993 return;
943 } 994 }
944 995
996 fcntl(fd, F_SETFL, O_NONBLOCK);
945 if (connect(fd, (struct sockaddr *)&site, sizeof(site)) < 0) { 997 if (connect(fd, (struct sockaddr *)&site, sizeof(site)) < 0) {
946 hide_login_progress(gc, "Unable to connect."); 998 if ((errno == EINPROGRESS) || (errno == EINTR)) {
947 signoff(gc); 999 idata->inpa = gdk_input_add(idata->fd, GDK_INPUT_WRITE, irc_login_callback, gc);
948 return; 1000 } else {
1001 hide_login_progress(gc, "Unable to connect.");
1002 signoff(gc);
1003 return;
1004 }
949 } 1005 }
950 1006
951 idata->fd = fd; 1007 idata->fd = fd;
952 1008
953 g_snprintf(buf, sizeof(buf), "Signon: %s", gc->username); 1009 g_snprintf(buf, sizeof(buf), "Signon: %s", gc->username);
954 set_login_progress(gc, 2, buf); 1010 set_login_progress(gc, 2, buf);
955 1011
956 /* This is where we will attempt to sign on */ 1012 /* This is where we will attempt to sign on */
957 1013
958 g_snprintf(buf, 4096, "NICK %s\n USER %s localhost %s :GAIM (www.marko.net/gaim)\n", gc->username, getenv("USER"), user->proto_opt[0]); 1014 if (!idata->inpa)
959 1015 irc_login_callback(gc, idata->fd, GDK_INPUT_READ);
960 printf("Sending: %s\n", buf); 1016
961 write(idata->fd, buf, strlen(buf)); 1017 gc->inpa = gdk_input_add(idata->fd, GDK_INPUT_READ, irc_callback, gc);
962 1018 }
963 /* Now lets sign ourselves on */ 1019
964 account_online(gc); 1020 static void irc_print_option(GtkEntry * entry, struct aim_user *user)
965 serv_finish_login(gc); 1021 {
966
967 if (bud_list_cache_exists(gc))
968 do_import(NULL, gc);
969
970
971 gc->inpa = gdk_input_add(idata->fd, GDK_INPUT_READ, irc_handler, gc);
972
973 /* We want to update our buddlist every 20 seconds */
974 idata->timer = gtk_timeout_add(20000, (GtkFunction)irc_request_buddy_update, gc);
975
976 /* But first, let's go ahead and check our list */
977 irc_request_buddy_update(gc);
978 }
979
980 static void irc_print_option(GtkEntry *entry, struct aim_user *user) {
981 if (gtk_object_get_user_data(GTK_OBJECT(entry))) { 1022 if (gtk_object_get_user_data(GTK_OBJECT(entry))) {
982 g_snprintf(user->proto_opt[1], sizeof(user->proto_opt[1]), "%s", 1023 g_snprintf(user->proto_opt[1], sizeof(user->proto_opt[1]), "%s",
983 gtk_entry_get_text(entry)); 1024 gtk_entry_get_text(entry));
984 } else { 1025 } else {
985 g_snprintf(user->proto_opt[0], sizeof(user->proto_opt[0]), "%s", 1026 g_snprintf(user->proto_opt[0], sizeof(user->proto_opt[0]), "%s",
986 gtk_entry_get_text(entry)); 1027 gtk_entry_get_text(entry));
987 } 1028 }
988 } 1029 }
989 1030
990 static void irc_user_opts(GtkWidget *book, struct aim_user *user) { 1031 static void irc_user_opts(GtkWidget * book, struct aim_user *user)
1032 {
991 /* so here, we create the new notebook page */ 1033 /* so here, we create the new notebook page */
992 GtkWidget *vbox; 1034 GtkWidget *vbox;
993 GtkWidget *hbox; 1035 GtkWidget *hbox;
994 GtkWidget *label; 1036 GtkWidget *label;
995 GtkWidget *entry; 1037 GtkWidget *entry;
996 1038
997 vbox = gtk_vbox_new(FALSE, 0); 1039 vbox = gtk_vbox_new(FALSE, 0);
998 gtk_notebook_append_page(GTK_NOTEBOOK(book), vbox, 1040 gtk_notebook_append_page(GTK_NOTEBOOK(book), vbox, gtk_label_new("IRC Options"));
999 gtk_label_new("IRC Options"));
1000 gtk_widget_show(vbox); 1041 gtk_widget_show(vbox);
1001 1042
1002 hbox = gtk_hbox_new(FALSE, 0); 1043 hbox = gtk_hbox_new(FALSE, 0);
1003 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5); 1044 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
1004 gtk_widget_show(hbox); 1045 gtk_widget_show(hbox);
1007 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); 1048 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
1008 gtk_widget_show(label); 1049 gtk_widget_show(label);
1009 1050
1010 entry = gtk_entry_new(); 1051 entry = gtk_entry_new();
1011 gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 5); 1052 gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 5);
1012 gtk_signal_connect(GTK_OBJECT(entry), "changed", 1053 gtk_signal_connect(GTK_OBJECT(entry), "changed", GTK_SIGNAL_FUNC(irc_print_option), user);
1013 GTK_SIGNAL_FUNC(irc_print_option), user);
1014 if (user->proto_opt[0][0]) { 1054 if (user->proto_opt[0][0]) {
1015 debug_printf("setting text %s\n", user->proto_opt[0]); 1055 debug_printf("setting text %s\n", user->proto_opt[0]);
1016 gtk_entry_set_text(GTK_ENTRY(entry), user->proto_opt[0]); 1056 gtk_entry_set_text(GTK_ENTRY(entry), user->proto_opt[0]);
1017 } 1057 }
1018 gtk_widget_show(entry); 1058 gtk_widget_show(entry);
1030 if (user->proto_opt[1][0]) { 1070 if (user->proto_opt[1][0]) {
1031 debug_printf("setting text %s\n", user->proto_opt[1]); 1071 debug_printf("setting text %s\n", user->proto_opt[1]);
1032 gtk_entry_set_text(GTK_ENTRY(entry), user->proto_opt[1]); 1072 gtk_entry_set_text(GTK_ENTRY(entry), user->proto_opt[1]);
1033 } 1073 }
1034 gtk_object_set_user_data(GTK_OBJECT(entry), user); 1074 gtk_object_set_user_data(GTK_OBJECT(entry), user);
1035 gtk_signal_connect(GTK_OBJECT(entry), "changed", 1075 gtk_signal_connect(GTK_OBJECT(entry), "changed", GTK_SIGNAL_FUNC(irc_print_option), user);
1036 GTK_SIGNAL_FUNC(irc_print_option), user);
1037 gtk_widget_show(entry); 1076 gtk_widget_show(entry);
1038 } 1077 }
1039 1078
1040 static char **irc_list_icon(int uc) { 1079 static char **irc_list_icon(int uc)
1080 {
1041 return free_icon_xpm; 1081 return free_icon_xpm;
1042 } 1082 }
1043 1083
1044 /* Send out a ping request to the specified user */ 1084 /* Send out a ping request to the specified user */
1045 void irc_send_ping(GtkObject *w, char *who) { 1085 static void irc_send_ping(GtkObject * w, char *who)
1086 {
1046 struct gaim_connection *gc = (struct gaim_connection *)gtk_object_get_user_data(w); 1087 struct gaim_connection *gc = (struct gaim_connection *)gtk_object_get_user_data(w);
1047 struct irc_data *idata = (struct irc_data *)gc->proto_data; 1088 struct irc_data *idata = (struct irc_data *)gc->proto_data;
1048 char buf[BUF_LEN]; 1089 char buf[BUF_LEN];
1049 unsigned int serial = 2391271; 1090 unsigned int serial = 2391271;
1050 1091
1051 g_snprintf(buf, BUF_LEN, "PRIVMSG %s :%cPING %d%c\n", who, '\001', serial, '\001'); 1092 g_snprintf(buf, BUF_LEN, "PRIVMSG %s :%cPING %d%c\n", who, '\001', serial, '\001');
1052 1093
1053 write(idata->fd, buf, strlen(buf)); 1094 write(idata->fd, buf, strlen(buf));
1054 } 1095 }
1055 1096
1056 1097
1057 static void irc_action_menu(GtkWidget *menu, struct gaim_connection *gc, char *who) { 1098 static void irc_action_menu(GtkWidget * menu, struct gaim_connection *gc, char *who)
1099 {
1058 GtkWidget *button; 1100 GtkWidget *button;
1059 1101
1060 button = gtk_menu_item_new_with_label("Ping"); 1102 button = gtk_menu_item_new_with_label("Ping");
1061 gtk_signal_connect(GTK_OBJECT(button), "activate", 1103 gtk_signal_connect(GTK_OBJECT(button), "activate", GTK_SIGNAL_FUNC(irc_send_ping), who);
1062 GTK_SIGNAL_FUNC(irc_send_ping), who);
1063 gtk_object_set_user_data(GTK_OBJECT(button), gc); 1104 gtk_object_set_user_data(GTK_OBJECT(button), gc);
1064 gtk_menu_append(GTK_MENU(menu), button); 1105 gtk_menu_append(GTK_MENU(menu), button);
1065 gtk_widget_show(button); 1106 gtk_widget_show(button);
1066 } 1107 }
1067 1108
1068 1109
1069 static struct prpl *my_protocol = NULL; 1110 static struct prpl *my_protocol = NULL;
1070 1111
1071 void irc_init(struct prpl *ret) { 1112 static void irc_init(struct prpl *ret)
1113 {
1072 ret->protocol = PROTO_IRC; 1114 ret->protocol = PROTO_IRC;
1073 ret->name = irc_name; 1115 ret->name = irc_name;
1074 ret->list_icon = irc_list_icon; 1116 ret->list_icon = irc_list_icon;
1075 ret->action_menu = irc_action_menu; 1117 ret->action_menu = irc_action_menu;
1076 ret->user_opts = irc_user_opts; 1118 ret->user_opts = irc_user_opts;
1077 ret->login = irc_login; 1119 ret->login = irc_login;
1078 ret->close = irc_close; 1120 ret->close = irc_close;
1079 ret->send_im = irc_send_im; 1121 ret->send_im = irc_send_im;
1080 ret->set_info = NULL;
1081 ret->get_info = NULL;
1082 ret->set_away = NULL;
1083 ret->get_away_msg = NULL;
1084 ret->set_dir = NULL;
1085 ret->get_dir = NULL;
1086 ret->dir_search = NULL;
1087 ret->set_idle = NULL;
1088 ret->change_passwd = NULL;
1089 ret->add_buddy = NULL;
1090 ret->add_buddies = NULL;
1091 ret->remove_buddy = NULL;
1092 ret->add_permit = NULL;
1093 ret->add_deny = NULL;
1094 ret->warn = NULL;
1095 ret->accept_chat = NULL;
1096 ret->join_chat = irc_join_chat; 1122 ret->join_chat = irc_join_chat;
1097 ret->chat_invite = NULL;
1098 ret->chat_leave = irc_chat_leave; 1123 ret->chat_leave = irc_chat_leave;
1099 ret->chat_whisper = NULL;
1100 ret->chat_send = irc_chat_send; 1124 ret->chat_send = irc_chat_send;
1101 ret->keepalive = NULL;
1102 1125
1103 my_protocol = ret; 1126 my_protocol = ret;
1104 } 1127 }
1105 1128
1106 char *gaim_plugin_init(GModule *handle) { 1129 char *gaim_plugin_init(GModule * handle)
1130 {
1107 load_protocol(irc_init); 1131 load_protocol(irc_init);
1108 return NULL; 1132 return NULL;
1109 } 1133 }
1110 1134
1111 void gaim_plugin_remove() { 1135 void gaim_plugin_remove()
1136 {
1112 struct prpl *p = find_prpl(PROTO_IRC); 1137 struct prpl *p = find_prpl(PROTO_IRC);
1113 if (p == my_protocol) 1138 if (p == my_protocol)
1114 unload_protocol(p); 1139 unload_protocol(p);
1115 } 1140 }