Mercurial > pidgin
annotate src/protocols/irc/irc.c @ 2273:0b5c3338fa3d
[gaim-migrate @ 2283]
One of the girls on the floor of my sister's dorm lost both her parents when their plane was hijacked and crashed into the World Trade Center. my girlfriend's boss's sister-in-law's brother died when the building collapsed. my parents flew to atlanta on monday; they're safe but currently stranded there. they had planned on flying to Raleigh, NC today but now are just hoping to be able to fly home soon. how did this happen?
committer: Tailor Script <tailor@pidgin.im>
| author | Eric Warmenhoven <eric@warmenhoven.org> |
|---|---|
| date | Wed, 12 Sep 2001 21:29:32 +0000 |
| parents | 8c4ff1a368bd |
| children | 38e156136896 |
| rev | line source |
|---|---|
| 2086 | 1 /* |
| 2 * gaim - IRC Protocol Plugin | |
| 3 * | |
| 4 * Copyright (C) 2000-2001, Rob Flynn <rob@tgflinux.com> | |
| 5 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> | |
| 6 * | |
| 7 * This program is free software; you can redistribute it and/or modify | |
| 8 * it under the terms of the GNU General Public License as published by | |
| 9 * the Free Software Foundation; either version 2 of the License, or | |
| 10 * (at your option) any later version. | |
| 11 * | |
| 12 * This program is distributed in the hope that it will be useful, | |
| 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 15 * GNU General Public License for more details. | |
| 16 * | |
| 17 * You should have received a copy of the GNU General Public License | |
| 18 * along with this program; if not, write to the Free Software | |
| 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 20 * | |
| 21 */ | |
| 22 | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
23 #include <config.h> |
| 2086 | 24 |
| 25 | |
| 26 #include <netdb.h> | |
| 27 #include <unistd.h> | |
| 28 #include <errno.h> | |
| 29 #include <netinet/in.h> | |
| 30 #include <arpa/inet.h> | |
| 31 #include <fcntl.h> | |
| 32 #include <string.h> | |
| 33 #include <stdlib.h> | |
| 34 #include <stdio.h> | |
| 35 #include <time.h> | |
| 36 #include <sys/socket.h> | |
| 37 #include <sys/stat.h> | |
| 38 #include <ctype.h> | |
| 39 #include "multi.h" | |
| 40 #include "prpl.h" | |
| 41 #include "gaim.h" | |
| 42 #include "proxy.h" | |
| 43 | |
| 44 #include "pixmaps/free_icon.xpm" | |
| 45 | |
| 46 #define IRC_BUF_LEN 4096 | |
| 47 | |
| 48 | |
| 49 #define USEROPT_SERV 0 | |
| 50 #define USEROPT_PORT 1 | |
| 51 | |
| 52 static int chat_id = 0; | |
| 53 | |
| 54 struct irc_channel { | |
| 55 int id; | |
| 56 gchar *name; | |
| 57 }; | |
| 58 | |
| 59 struct irc_data { | |
| 60 int fd; | |
| 61 int inpa; /* used for non-block logins */ | |
| 62 | |
| 63 int timer; | |
| 64 | |
| 65 int totalblocks; | |
| 66 int recblocks; | |
| 67 | |
| 68 GSList *templist; | |
| 69 GList *channels; | |
| 70 }; | |
| 71 | |
| 72 static char *irc_name() | |
| 73 { | |
| 74 return "IRC"; | |
| 75 } | |
| 76 | |
| 77 static void irc_get_info(struct gaim_connection *gc, char *who); | |
| 78 | |
|
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
79 static GList *irc_chat_info(struct gaim_connection *gc) |
|
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
80 { |
|
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
81 GList *m = NULL; |
|
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
82 struct proto_chat_entry *pce; |
|
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
83 |
|
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
84 pce = g_new0(struct proto_chat_entry, 1); |
|
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
85 pce->label = _("Room:"); |
|
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
86 m = g_list_append(m, pce); |
|
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
87 |
|
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
88 return m; |
|
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
89 } |
|
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
90 |
|
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
91 static void irc_join_chat(struct gaim_connection *gc, GList *data) |
| 2086 | 92 { |
| 93 struct irc_data *idata = (struct irc_data *)gc->proto_data; | |
|
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
94 gchar *buf, *name; |
|
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
95 |
|
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
96 if (!data) |
|
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
97 return; |
|
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
98 name = data->data; |
|
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
99 |
|
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
100 buf = (gchar *) g_malloc(IRC_BUF_LEN + 1); |
| 2086 | 101 |
| 102 g_snprintf(buf, IRC_BUF_LEN, "JOIN %s\n", name); | |
| 103 write(idata->fd, buf, strlen(buf)); | |
| 104 write(idata->fd, buf, strlen(buf)); | |
| 105 | |
| 106 g_free(buf); | |
| 107 } | |
| 108 | |
| 109 static void irc_update_user(struct gaim_connection *gc, char *name, int status) | |
| 110 { | |
| 111 struct irc_data *idata = (struct irc_data *)gc->proto_data; | |
| 112 struct irc_channel *u; | |
| 113 GSList *temp = idata->templist; | |
| 114 | |
| 115 /* Loop through our list */ | |
| 116 | |
| 117 while (temp) { | |
| 118 u = (struct irc_channel *)temp->data; | |
| 119 if (g_strcasecmp(u->name, name) == 0) { | |
| 120 u->id = status; | |
| 121 return; | |
| 122 } | |
| 123 | |
| 124 temp = g_slist_next(temp); | |
| 125 } | |
| 126 return; | |
| 127 } | |
| 128 | |
|
2137
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
129 static gboolean irc_request_buddy_update(gpointer data) |
| 2086 | 130 { |
|
2137
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
131 struct gaim_connection *gc = data; |
| 2086 | 132 struct irc_data *idata = (struct irc_data *)gc->proto_data; |
| 133 GSList *grp = gc->groups; | |
| 134 GSList *person; | |
| 135 struct group *g; | |
| 136 struct buddy *b; | |
| 137 struct irc_channel *u; | |
| 138 | |
| 139 if (idata->templist != NULL) | |
|
2137
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
140 return TRUE; |
| 2086 | 141 |
| 142 idata->recblocks = 0; | |
| 143 idata->totalblocks = 1; | |
| 144 | |
| 145 /* First, let's check to see if we have anyone on our buddylist */ | |
| 146 if (!grp) { | |
|
2131
acc11216ec5d
[gaim-migrate @ 2141]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
147 return TRUE; |
| 2086 | 148 } |
| 149 | |
| 150 /* Send the first part of our request */ | |
| 151 write(idata->fd, "ISON", 4); | |
| 152 | |
| 153 /* Step through our list of groups */ | |
| 154 while (grp) { | |
| 155 | |
| 156 g = (struct group *)grp->data; | |
| 157 person = g->members; | |
| 158 | |
| 159 while (person) { | |
| 160 b = (struct buddy *)person->data; | |
| 161 | |
| 162 /* We will store our buddy info here. I know, this is cheap | |
| 163 * but hey, its the exact same data structure. Why should we | |
| 164 * bother with making another one */ | |
| 165 | |
| 166 u = g_new0(struct irc_channel, 1); | |
| 167 u->id = 0; /* Assume by default that they're offline */ | |
| 168 u->name = strdup(b->name); | |
| 169 | |
| 170 write(idata->fd, " ", 1); | |
| 171 write(idata->fd, u->name, strlen(u->name)); | |
| 172 idata->templist = g_slist_append(idata->templist, u); | |
| 173 | |
| 174 person = person->next; | |
| 175 } | |
| 176 | |
| 177 grp = g_slist_next(grp); | |
| 178 } | |
| 179 write(idata->fd, "\n", 1); | |
|
2131
acc11216ec5d
[gaim-migrate @ 2141]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
180 return TRUE; |
| 2086 | 181 } |
| 182 | |
| 183 | |
|
2231
8c4ff1a368bd
[gaim-migrate @ 2241]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2206
diff
changeset
|
184 static int irc_send_im(struct gaim_connection *gc, char *who, char *message, int flags) |
| 2086 | 185 { |
| 186 | |
| 187 struct irc_data *idata = (struct irc_data *)gc->proto_data; | |
| 188 gchar *buf = (gchar *) g_malloc(IRC_BUF_LEN + 1); | |
| 189 | |
| 190 if (who[0] == '@' || who[0] == '+') { | |
| 191 | |
| 192 /* If the user trys to msg an op or a voice from the channel, the convo will try | |
| 193 * to send it to @nick or +nick... needless to say, this is undesirable. | |
| 194 */ | |
| 195 who++; | |
| 196 } | |
| 197 | |
| 198 /* Before we actually send this, we should check to see if they're trying | |
| 199 * To issue a command and handle it properly. */ | |
| 200 | |
| 201 if (message[0] == '/') { | |
| 202 /* I'll change the implementation of this a little later :-) */ | |
| 203 if ((g_strncasecmp(message, "/me ", 4) == 0) && (strlen(message) > 4)) { | |
| 204 /* We have /me!! We have /me!! :-) */ | |
| 205 | |
| 206 gchar *temp = (gchar *) g_malloc(IRC_BUF_LEN + 1); | |
| 207 strcpy(temp, message + 4); | |
| 208 g_snprintf(buf, IRC_BUF_LEN, "PRIVMSG %s :%cACTION %s%c\n", who, '\001', temp, | |
| 209 '\001'); | |
| 210 g_free(temp); | |
| 211 } else if (!g_strncasecmp(message, "/whois ", 7) && (strlen(message) > 7)) { | |
| 212 gchar *temp = (gchar *) g_malloc(IRC_BUF_LEN + 1); | |
| 213 strcpy(temp, message + 7); | |
| 214 irc_get_info(gc, temp); | |
| 215 g_free(temp); | |
| 216 | |
|
2123
56c4382f2909
[gaim-migrate @ 2133]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2100
diff
changeset
|
217 return 0; |
| 2086 | 218 } |
| 219 | |
| 220 } else { | |
| 221 g_snprintf(buf, IRC_BUF_LEN, "PRIVMSG %s :%s\n", who, message); | |
| 222 } | |
| 223 | |
| 224 write(idata->fd, buf, strlen(buf)); | |
| 225 | |
| 226 g_free(buf); | |
|
2123
56c4382f2909
[gaim-migrate @ 2133]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2100
diff
changeset
|
227 return 0; |
| 2086 | 228 } |
| 229 | |
| 230 static int find_id_by_name(struct gaim_connection *gc, char *name) | |
| 231 { | |
| 232 gchar *temp = (gchar *) g_malloc(IRC_BUF_LEN + 1); | |
| 233 GList *templist; | |
| 234 struct irc_channel *channel; | |
| 235 | |
| 236 templist = ((struct irc_data *)gc->proto_data)->channels; | |
| 237 | |
| 238 while (templist) { | |
| 239 channel = (struct irc_channel *)templist->data; | |
| 240 | |
| 241 g_snprintf(temp, IRC_BUF_LEN, "#%s", channel->name); | |
| 242 | |
| 243 if (g_strcasecmp(temp, name) == 0) { | |
| 244 g_free(temp); | |
| 245 return channel->id; | |
| 246 } | |
| 247 | |
| 248 templist = templist->next; | |
| 249 } | |
| 250 | |
| 251 g_free(temp); | |
| 252 | |
| 253 /* Return -1 if we have no ID */ | |
| 254 return -1; | |
| 255 } | |
| 256 | |
| 257 static struct irc_channel *find_channel_by_name(struct gaim_connection *gc, char *name) | |
| 258 { | |
| 259 gchar *temp = (gchar *) g_malloc(IRC_BUF_LEN + 1); | |
| 260 GList *templist; | |
| 261 struct irc_channel *channel; | |
| 262 | |
| 263 templist = ((struct irc_data *)gc->proto_data)->channels; | |
| 264 | |
| 265 while (templist) { | |
| 266 channel = (struct irc_channel *)templist->data; | |
| 267 | |
| 268 g_snprintf(temp, IRC_BUF_LEN, "%s", channel->name); | |
| 269 | |
| 270 if (g_strcasecmp(temp, name) == 0) { | |
| 271 g_free(temp); | |
| 272 return channel; | |
| 273 } | |
| 274 | |
| 275 templist = templist->next; | |
| 276 } | |
| 277 | |
| 278 g_free(temp); | |
| 279 | |
| 280 /* If we found nothing, return nothing :-) */ | |
| 281 return NULL; | |
| 282 } | |
| 283 | |
| 284 static struct irc_channel *find_channel_by_id(struct gaim_connection *gc, int id) | |
| 285 { | |
| 286 struct irc_data *idata = (struct irc_data *)gc->proto_data; | |
| 287 struct irc_channel *channel; | |
| 288 | |
| 289 GList *temp; | |
| 290 | |
| 291 temp = idata->channels; | |
| 292 | |
| 293 while (temp) { | |
| 294 channel = (struct irc_channel *)temp->data; | |
| 295 | |
| 296 if (channel->id == id) { | |
| 297 /* We've found our man */ | |
| 298 return channel; | |
| 299 } | |
| 300 | |
| 301 temp = temp->next; | |
| 302 } | |
| 303 | |
| 304 | |
| 305 /* If we didnt find one, return NULL */ | |
| 306 return NULL; | |
| 307 } | |
| 308 | |
| 309 static struct conversation *find_chat(struct gaim_connection *gc, char *name) | |
| 310 { | |
| 311 GSList *bcs = gc->buddy_chats; | |
| 312 struct conversation *b = NULL; | |
| 313 char *chat = g_strdup(normalize(name)); | |
| 314 | |
| 315 while (bcs) { | |
| 316 b = bcs->data; | |
| 317 if (!strcasecmp(normalize(b->name), chat)) | |
| 318 break; | |
| 319 b = NULL; | |
| 320 bcs = bcs->next; | |
| 321 } | |
| 322 | |
| 323 g_free(chat); | |
| 324 return b; | |
| 325 } | |
| 326 | |
| 327 static void irc_chat_leave(struct gaim_connection *gc, int id); | |
|
2167
edf8c5a70e5b
[gaim-migrate @ 2177]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2162
diff
changeset
|
328 static int irc_chat_send(struct gaim_connection *gc, int id, char *message) |
| 2086 | 329 { |
| 330 | |
| 331 struct irc_data *idata = (struct irc_data *)gc->proto_data; | |
| 332 struct irc_channel *channel = NULL; | |
| 333 gchar *buf = (gchar *) g_malloc(IRC_BUF_LEN + 1); | |
| 334 char **kick; | |
| 335 gboolean is_command = FALSE; | |
| 336 /* First lets get our current channel */ | |
| 337 channel = find_channel_by_id(gc, id); | |
| 338 | |
| 339 | |
| 340 if (!channel) { | |
| 341 /* If for some reason we've lost our channel, let's bolt */ | |
| 342 g_free(buf); | |
|
2167
edf8c5a70e5b
[gaim-migrate @ 2177]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2162
diff
changeset
|
343 return -EINVAL; |
| 2086 | 344 } |
| 345 | |
| 346 | |
| 347 /* Before we actually send this, we should check to see if they're trying | |
| 348 * To issue a command and handle it properly. */ | |
| 349 | |
| 350 if (message[0] == '/') { | |
| 351 | |
| 352 if ((g_strncasecmp(message, "/me ", 4) == 0) && (strlen(message) > 4)) { | |
| 353 /* We have /me!! We have /me!! :-) */ | |
| 354 | |
| 355 gchar *temp = (gchar *) g_malloc(IRC_BUF_LEN + 1); | |
| 356 strcpy(temp, message + 4); | |
| 357 | |
| 358 g_snprintf(buf, IRC_BUF_LEN, "PRIVMSG #%s :%cACTION %s%c\n", channel->name, | |
| 359 '\001', temp, '\001'); | |
| 360 g_free(temp); | |
| 361 } else if ((g_strncasecmp(message, "/op ", 4) == 0) && (strlen(message) > 4)) { | |
| 362 gchar *temp = (gchar *) g_malloc(IRC_BUF_LEN + 1); | |
| 363 strcpy(temp, message + 4); | |
| 364 | |
| 365 g_snprintf(buf, IRC_BUF_LEN, "MODE #%s +o %s\n", channel->name, temp); | |
| 366 | |
| 367 g_free(temp); | |
| 368 is_command = TRUE; | |
| 369 | |
| 370 } else if ((g_strncasecmp(message, "/deop ", 6) == 0) && (strlen(message) > 6)) { | |
| 371 gchar *temp = (gchar *) g_malloc(IRC_BUF_LEN + 1); | |
| 372 strcpy(temp, message + 6); | |
| 373 g_snprintf(buf, IRC_BUF_LEN, "MODE #%s -o %s\n", channel->name, temp); | |
| 374 | |
| 375 g_free(temp); | |
| 376 is_command = TRUE; | |
| 377 } | |
| 378 | |
| 379 else if ((g_strncasecmp(message, "/voice ", 7) == 0) && (strlen(message) > 7)) { | |
| 380 gchar *temp = (gchar *) g_malloc(IRC_BUF_LEN + 1); | |
| 381 strcpy(temp, message + 7); | |
| 382 | |
| 383 g_snprintf(buf, IRC_BUF_LEN, "MODE #%s +v %s\n", channel->name, temp); | |
| 384 | |
| 385 g_free(temp); | |
| 386 is_command = TRUE; | |
| 387 | |
| 388 } else if ((g_strncasecmp(message, "/devoice ", 9) == 0) && (strlen(message) > 9)) { | |
| 389 gchar *temp = (gchar *) g_malloc(IRC_BUF_LEN + 1); | |
| 390 strcpy(temp, message + 6); | |
| 391 g_snprintf(buf, IRC_BUF_LEN, "MODE #%s -v %s\n", channel->name, temp); | |
| 392 | |
| 393 g_free(temp); | |
| 394 is_command = TRUE; | |
| 395 } else if ((g_strncasecmp(message, "/mode ", 6) == 0) && (strlen(message) > 6)) { | |
| 396 gchar *temp = (gchar *) g_malloc(IRC_BUF_LEN + 1); | |
| 397 strcpy(temp, message + 6); | |
| 398 g_snprintf(buf, IRC_BUF_LEN, "MODE #%s %s\n", channel->name, temp); | |
| 399 g_free(temp); | |
| 400 is_command = TRUE; | |
| 401 } | |
| 402 | |
| 403 else if (!g_strncasecmp(message, "/whois ", 7) && (strlen(message) > 7)) { | |
| 404 gchar *temp = (gchar *) g_malloc(IRC_BUF_LEN + 1); | |
| 405 | |
| 406 strcpy(temp, message + 7); | |
| 407 irc_get_info(gc, temp); | |
| 408 g_free(temp); | |
| 409 is_command = TRUE; | |
| 410 | |
| 411 } | |
| 412 | |
| 413 else if (!g_strncasecmp(message, "/topic ", 7) && (strlen(message) > 7)) { | |
| 414 gchar *temp = (gchar *) g_malloc(IRC_BUF_LEN + 1); | |
| 415 strcpy(temp, message + 7); | |
| 416 | |
| 417 /* Send the chat topic change request */ | |
| 418 serv_chat_set_topic(gc, id, temp); | |
| 419 | |
| 420 g_free(temp); | |
| 421 is_command = TRUE; | |
| 422 } | |
| 423 | |
| 424 else if (!g_strncasecmp(message, "/part", 5) && (strlen(message) == 5)) { | |
| 425 | |
| 426 /* If I'm not mistaken, the chat_leave command was coded under the | |
| 427 * pretense that it would only occur when someone closed the window. | |
| 428 * For this reason, the /part command will not close the window. Nor | |
| 429 * will the window close when the user is /kicked. I'll let you decide | |
| 430 * the best way to fix it--I'd imagine it'd just be a little line like | |
| 431 * if (convo) close (convo), but I'll let you decide where to put it. | |
| 432 */ | |
| 433 | |
| 434 irc_chat_leave(gc, id); | |
| 435 is_command = TRUE; | |
|
2167
edf8c5a70e5b
[gaim-migrate @ 2177]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2162
diff
changeset
|
436 return 0; |
| 2086 | 437 |
| 438 | |
| 439 } | |
| 440 | |
| 441 else if (!g_strncasecmp(message, "/join ", 6) && (strlen(message) > 6)) { | |
| 442 | |
| 443 gchar *temp = (gchar *) g_malloc(IRC_BUF_LEN + 1); | |
|
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
444 GList *m = g_list_append(NULL, temp); |
| 2086 | 445 |
| 446 strcpy(temp, message + 6); | |
| 447 | |
| 448 | |
|
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
449 irc_join_chat(gc, m); |
| 2086 | 450 g_free(temp); |
|
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
451 g_list_free(m); |
| 2086 | 452 is_command = TRUE; |
|
2167
edf8c5a70e5b
[gaim-migrate @ 2177]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2162
diff
changeset
|
453 return 0; |
| 2086 | 454 } |
| 455 | |
| 456 else if (!g_strncasecmp(message, "/raw ", 5) && (strlen(message) > 5)) { | |
| 457 gchar *temp = (gchar *) g_malloc(IRC_BUF_LEN + 1); | |
| 458 strcpy(temp, message + 5); | |
| 459 g_snprintf(buf, IRC_BUF_LEN, "%s\r\n", temp); | |
| 460 g_free(temp); | |
| 461 is_command = TRUE; | |
| 462 } | |
| 463 | |
| 464 else if (!g_strncasecmp(message, "/quote ", 7) && (strlen(message) > 7)) { | |
| 465 gchar *temp = (gchar *) g_malloc(IRC_BUF_LEN + 1); | |
| 466 strcpy(temp, message + 7); | |
| 467 g_snprintf(buf, IRC_BUF_LEN, "%s\r\n", temp); | |
| 468 g_free(temp); | |
| 469 is_command = TRUE; | |
| 470 } | |
| 471 | |
| 472 else if (!g_strncasecmp(message, "/kick ", 6) && (strlen(message) > 6)) { | |
| 473 gchar *temp = (gchar *) g_malloc(IRC_BUF_LEN + 1); | |
| 474 strcpy(temp, message + 6); | |
| 475 kick = g_strsplit(temp, " ", 2); | |
| 476 g_snprintf(buf, IRC_BUF_LEN, "KICK #%s %s :%s\r\n", channel->name, kick[0], | |
| 477 kick[1]); | |
| 478 g_free(temp); | |
| 479 is_command = TRUE; | |
| 480 } | |
| 481 | |
| 482 /* FIXME: I'll go back in and grab this later. -- Rob */ | |
| 483 /* | |
| 484 I THOUGHT THIS WOULD WORK, BUT I WAS WRONG. WOULD SOMEONE KINDLY FIX IT? | |
| 485 | |
| 486 | |
| 487 else if (!g_strncasecmp(message, "/help", 5)) { | |
| 488 gchar *temp = (gchar *) g_malloc(IRC_BUF_LEN + 1); | |
| 489 strcpy(temp, message + 5); | |
| 490 if (temp == "") { | |
| 491 | |
| 492 serv_got_chat_in(gc, id, "gAIM", 0, "Available Commands:"); | |
| 493 serv_got_chat_in(gc, id, "gAIM", 0, " "); | |
| 494 serv_got_chat_in(gc, id, "gAIM", 0, "<b>op voice kick </b>"); | |
| 495 serv_got_chat_in(gc, id, "gAIM", 0, "<b>deop devoice whois</b>"); | |
| 496 serv_got_chat_in(gc, id, "gAIM", 0, "<b>me raw quote</b>"); | |
| 497 serv_got_chat_in(gc, id, "gAIM", 0, "<b>mode</b>"); | |
| 498 } | |
| 499 else { | |
| 500 serv_got_chat_in(gc, id, "gAIM", 0, "Usage: "); | |
| 501 if (temp == "op") | |
| 502 serv_got_chat_in(gc, id, "gAIM", 0, "<b>/op <nick></b> - Gives operator status to user."); | |
| 503 else if (temp == "deop") | |
| 504 serv_got_chat_in(gc, id, "gAIM", 0, "<b>/deop <nick></b> - Removes operator status from user."); | |
| 505 else if (temp == "me") | |
| 506 serv_got_chat_in(gc, id, "gAIM", 0, "<b>/me <action></b> - Sends an action to the channel."); | |
| 507 else if (temp == "mode") | |
| 508 serv_got_chat_in(gc, id, "gAIM", 0, "<b>/mode {[+|-}|o|p|s|i|t|n|b|v} [<limit][<nick>][<ban mask]</b> - Changes channel and user modes."); | |
| 509 else if (temp == "voice") | |
| 510 serv_got_chat_in(gc, id, "gAIM", 0, "<b>/voice <nick></b> - Gives voice status to user."); | |
| 511 else if (temp == "devoice") | |
| 512 serv_got_chat_in(gc, id, "gAIM", 0, "<b>/devoice <nick></b> - Removes voice status from user."); | |
| 513 else if (temp == "raw") | |
| 514 serv_got_chat_in(gc, id, "gAIM", 0, "<b>/raw <text></b> - Sends raw text to the server."); | |
| 515 else if (temp == "kick") | |
| 516 serv_got_chat_in(gc, id, "gAIM", 0, "<b>/kick [<comment>]</b> - Kicks a user out of the channel."); | |
| 517 else if (temp == "whois") | |
| 518 serv_got_chat_in(gc, id, "gAIM", 0, "<b>/whois <nick></b> - Gets information about user."); | |
| 519 else if (temp == "quote") | |
| 520 serv_got_chat_in(gc, id, "gAIM", 0, "<b>/raw <text></b> - Sends raw text to the server."); | |
| 521 else | |
| 522 serv_got_chat_in(gc, id, "gAIM", 0, "No such command."); | |
| 523 } | |
| 524 | |
| 525 g_free(temp); | |
| 526 is_command = TRUE; | |
| 527 } | |
| 528 */ | |
| 529 | |
| 530 } | |
| 531 | |
| 532 else { | |
| 533 g_snprintf(buf, IRC_BUF_LEN, "PRIVMSG #%s :%s\n", channel->name, message); | |
| 534 | |
| 535 } | |
| 536 | |
| 537 | |
| 538 write(idata->fd, buf, strlen(buf)); | |
| 539 | |
| 540 /* Since AIM expects us to receive the message we send, we gotta fake it */ | |
| 541 if (is_command == FALSE) | |
| 542 serv_got_chat_in(gc, id, gc->username, 0, message, time((time_t) NULL)); | |
| 543 | |
| 544 g_free(buf); | |
| 545 | |
|
2167
edf8c5a70e5b
[gaim-migrate @ 2177]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2162
diff
changeset
|
546 return 0; |
| 2086 | 547 } |
|
2167
edf8c5a70e5b
[gaim-migrate @ 2177]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2162
diff
changeset
|
548 |
| 2086 | 549 static struct conversation *find_conversation_by_id(struct gaim_connection *gc, int id) |
| 550 { | |
| 551 GSList *bc = gc->buddy_chats; | |
| 552 struct conversation *b = NULL; | |
| 553 | |
| 554 while (bc) { | |
| 555 b = (struct conversation *)bc->data; | |
| 556 if (id == b->id) { | |
| 557 break; | |
| 558 } | |
| 559 bc = bc->next; | |
| 560 b = NULL; | |
| 561 } | |
| 562 | |
| 563 if (!b) { | |
| 564 return NULL; | |
| 565 } | |
| 566 | |
| 567 return b; | |
| 568 } | |
| 569 | |
| 570 static struct conversation *find_conversation_by_name(struct gaim_connection *gc, char *name) | |
| 571 { | |
| 572 GSList *bc = gc->buddy_chats; | |
| 573 struct conversation *b = NULL; | |
| 574 | |
| 575 while (bc) { | |
| 576 b = (struct conversation *)bc->data; | |
| 577 | |
| 578 if (g_strcasecmp(name, b->name) == 0) { | |
| 579 break; | |
| 580 } | |
| 581 bc = bc->next; | |
| 582 b = NULL; | |
| 583 } | |
| 584 | |
| 585 if (!b) { | |
| 586 return NULL; | |
| 587 } | |
| 588 | |
| 589 return b; | |
| 590 } | |
| 591 | |
| 592 | |
| 593 | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
594 static void irc_callback(gpointer data, gint source, GaimInputCondition condition) |
| 2086 | 595 { |
| 596 struct gaim_connection *gc = data; | |
| 597 int i = 0; | |
| 598 gchar buf[4096]; | |
| 599 gchar **buf2; | |
| 600 struct irc_data *idata; | |
| 601 | |
| 602 idata = (struct irc_data *)gc->proto_data; | |
| 603 | |
| 604 | |
| 605 do { | |
| 606 if (read(idata->fd, buf + i, 1) < 0) { | |
| 607 hide_login_progress(gc, "Read error"); | |
| 608 signoff(gc); | |
| 609 return; | |
| 610 } | |
| 611 } while (buf[i++] != '\n'); | |
| 612 | |
| 613 buf[--i] = '\0'; | |
| 614 g_strchomp(buf); | |
| 615 g_print("%s\n", buf); | |
| 616 | |
| 617 /* Check for errors */ | |
| 618 | |
| 619 if (((strstr(buf, "ERROR :") && (!strstr(buf, "PRIVMSG ")) && | |
| 620 (!strstr(buf, "NOTICE ")) && (strlen(buf) > 7)))) { | |
| 621 | |
|
2147
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
622 /* |
|
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
623 * The ERROR command is for use by servers when reporting a serious or |
|
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
624 * fatal error to its operators. It may also be sent from one server to |
|
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
625 * another but must not be accepted from any normal unknown clients. |
|
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
626 * |
|
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
627 * An ERROR message is for use for reporting errors which occur with a |
|
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
628 * server-to-server link only. An ERROR message is sent to the server |
|
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
629 * at the other end (which sends it to all of its connected operators) |
|
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
630 * and to all operators currently connected. It is not to be passed |
|
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
631 * onto any other servers by a server if it is received from a server. |
|
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
632 * |
|
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
633 * When a server sends a received ERROR message to its operators, the |
|
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
634 * message should be encapsulated inside a NOTICE message, indicating |
|
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
635 * that the client was not responsible for the error. |
|
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
636 * |
|
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
637 * |
|
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
638 * Basically, ignore this. |
|
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
639 * |
| 2086 | 640 gchar *u_errormsg; |
| 641 | |
|
2147
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
642 * Let's get our error message * |
| 2086 | 643 u_errormsg = g_strdup(buf + 7); |
| 644 | |
|
2147
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
645 * We got our error message. Now, let's reaise an |
|
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
646 * error dialog * |
| 2086 | 647 |
| 648 do_error_dialog(u_errormsg, "Gaim: IRC Error"); | |
| 649 | |
|
2147
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
650 * And our necessary garbage collection * |
| 2086 | 651 g_free(u_errormsg); |
| 652 return; | |
|
2147
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
653 |
|
134058953a43
[gaim-migrate @ 2157]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
654 */ |
| 2086 | 655 } |
| 656 | |
| 657 /* This should be a whois response. I only care about the first (311) one. I might do | |
| 658 * the other's later. They're boring. */ | |
| 659 | |
| 660 if (((strstr(buf, " 311 ")) && (!strstr(buf, "PRIVMSG")) && (!strstr(buf, "NOTICE")))) { | |
| 661 char **res; | |
| 662 | |
| 663 res = g_strsplit(buf, " ", 7); | |
| 664 | |
| 665 if (!strcmp(res[1], "311")) { | |
| 666 char buf[8192]; | |
| 667 | |
| 668 g_snprintf(buf, 4096, "<b>Nick:</b> %s<br>" | |
| 669 "<b>Host:</b> %s@%s<br>" | |
| 670 "<b>Name:</b> %s<br>", res[3], res[4], res[5], res[7] + 1); | |
| 671 | |
|
2137
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
672 g_show_info_text(buf, NULL); |
| 2086 | 673 } |
| 674 | |
| 675 g_strfreev(res); | |
| 676 return; | |
| 677 } | |
| 678 | |
| 679 /* Autoresponse to an away message */ | |
| 680 if (((strstr(buf, " 301 ")) && (!strstr(buf, "PRIVMSG")) && (!strstr(buf, "NOTICE")))) { | |
| 681 char **res; | |
| 682 | |
| 683 res = g_strsplit(buf, " ", 5); | |
| 684 | |
| 685 if (!strcmp(res[1], "301")) | |
|
2273
0b5c3338fa3d
[gaim-migrate @ 2283]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2231
diff
changeset
|
686 serv_got_im(gc, res[3], res[4] + 1, IM_FLAG_AWAY, time((time_t) NULL)); |
| 2086 | 687 |
| 688 g_strfreev(res); | |
| 689 return; | |
| 690 } | |
| 691 | |
| 692 /* Parse the list of names that we receive when we first sign on to | |
| 693 * a channel */ | |
| 694 | |
| 695 if (((strstr(buf, " 353 ")) && (!strstr(buf, "PRIVMSG")) && (!strstr(buf, "NOTICE")))) { | |
| 696 gchar u_host[255]; | |
| 697 gchar u_command[32]; | |
| 698 gchar u_channel[128]; | |
| 699 gchar u_names[IRC_BUF_LEN + 1]; | |
| 700 struct conversation *convo = NULL; | |
| 701 int j; | |
| 702 | |
| 703 for (j = 0, i = 0; buf[i] != ' '; j++, i++) { | |
| 704 u_host[j] = buf[i]; | |
| 705 } | |
| 706 | |
| 707 u_host[j] = '\0'; | |
| 708 i++; | |
| 709 | |
| 710 for (j = 0; buf[i] != ' '; j++, i++) { | |
| 711 u_command[j] = buf[i]; | |
| 712 } | |
| 713 | |
| 714 u_command[j] = '\0'; | |
| 715 i++; | |
| 716 | |
| 717 for (j = 0; buf[i] != '#'; j++, i++) { | |
| 718 } | |
| 719 i++; | |
| 720 | |
| 721 for (j = 0; buf[i] != ':'; j++, i++) { | |
| 722 u_channel[j] = buf[i]; | |
| 723 } | |
| 724 | |
| 725 u_channel[j - 1] = '\0'; | |
| 726 i++; | |
| 727 | |
| 728 while ((buf[i] == ' ') || (buf[i] == ':')) { | |
| 729 i++; | |
| 730 } | |
| 731 | |
| 732 strcpy(u_names, buf + i); | |
| 733 | |
| 734 buf2 = g_strsplit(u_names, " ", 0); | |
| 735 | |
| 736 /* Let's get our conversation window */ | |
| 737 convo = find_conversation_by_name(gc, u_channel); | |
| 738 | |
| 739 if (!convo) { | |
| 740 return; | |
| 741 } | |
| 742 | |
| 743 /* Now that we've parsed the hell out of this big | |
| 744 * mess, let's try to split up the names properly */ | |
| 745 | |
| 746 for (i = 0; buf2[i] != NULL; i++) | |
| 747 add_chat_buddy(convo, buf2[i]); | |
| 748 | |
| 749 /* And free our pointers */ | |
| 750 g_strfreev(buf2); | |
| 751 | |
| 752 return; | |
| 753 | |
| 754 } | |
| 755 | |
| 756 /* Receive a list of users that are currently online */ | |
| 757 | |
| 758 if (((strstr(buf, " 303 ")) && (!strstr(buf, "PRIVMSG")) && (!strstr(buf, "NOTICE")))) { | |
| 759 gchar u_host[255]; | |
| 760 gchar u_command[32]; | |
| 761 gchar u_names[IRC_BUF_LEN + 1]; | |
| 762 int j; | |
| 763 | |
| 764 for (j = 0, i = 0; buf[i] != ' '; j++, i++) { | |
| 765 u_host[j] = buf[i]; | |
| 766 } | |
| 767 | |
| 768 u_host[j] = '\0'; | |
| 769 i++; | |
| 770 | |
| 771 for (j = 0; buf[i] != ' '; j++, i++) { | |
| 772 u_command[j] = buf[i]; | |
| 773 } | |
| 774 | |
| 775 u_command[j] = '\0'; | |
| 776 i++; | |
| 777 | |
| 778 for (j = 0; buf[i] != ':'; j++, i++) { | |
| 779 /* My Nick */ | |
| 780 } | |
| 781 i++; | |
| 782 | |
| 783 strcpy(u_names, buf + i); | |
| 784 | |
| 785 buf2 = g_strsplit(u_names, " ", 0); | |
| 786 | |
| 787 /* Now that we've parsed the hell out of this big | |
| 788 * mess, let's try to split up the names properly */ | |
| 789 | |
| 790 for (i = 0; buf2[i] != NULL; i++) { | |
| 791 /* If we have a name here then our buddy is online. We should | |
| 792 * update our temporary gslist accordingly. When we achieve our maximum | |
| 793 * list of names then we should force an update */ | |
| 794 | |
| 795 irc_update_user(gc, buf2[i], 1); | |
| 796 } | |
| 797 | |
| 798 /* Increase our received blocks counter */ | |
| 799 idata->recblocks++; | |
| 800 | |
| 801 /* If we have our total number of blocks */ | |
| 802 if (idata->recblocks == idata->totalblocks) { | |
| 803 GSList *temp; | |
| 804 struct irc_channel *u; | |
| 805 | |
| 806 /* Let's grab our list of people and bring them all on or off line */ | |
| 807 temp = idata->templist; | |
| 808 | |
| 809 /* Loop */ | |
| 810 while (temp) { | |
| 811 | |
| 812 u = temp->data; | |
| 813 | |
| 814 /* Tell Gaim to bring the person on or off line */ | |
| 815 serv_got_update(gc, u->name, u->id, 0, 0, 0, 0, 0); | |
| 816 | |
| 817 /* Grab the next entry */ | |
| 818 temp = g_slist_next(temp); | |
| 819 } | |
| 820 | |
| 821 /* And now, let's delete all of our entries */ | |
| 822 temp = idata->templist; | |
| 823 while (temp) { | |
| 824 u = temp->data; | |
| 825 g_free(u->name); | |
| 826 temp = g_slist_remove(temp, u); | |
| 827 } | |
| 828 | |
| 829 /* Reset our list */ | |
| 830 idata->totalblocks = 0; | |
| 831 idata->recblocks = 0; | |
| 832 | |
| 833 idata->templist = NULL; | |
| 834 | |
| 835 return; | |
| 836 } | |
| 837 | |
| 838 /* And free our pointers */ | |
| 839 g_strfreev(buf2); | |
| 840 | |
| 841 return; | |
| 842 | |
| 843 } | |
| 844 | |
| 845 | |
| 846 if ((strstr(buf, " MODE ")) && (strstr(buf, "!")) | |
| 847 && (strstr(buf, "+v") || strstr(buf, "-v") || strstr(buf, "-o") || strstr(buf, "+o")) | |
| 848 && (buf[0] == ':') && (!strstr(buf, " NOTICE "))) { | |
| 849 | |
| 850 gchar u_channel[128]; | |
| 851 gchar u_nick[128]; | |
| 852 | |
| 853 gchar u_mode[5]; | |
| 854 char **people; | |
| 855 gchar *temp, *temp_new; | |
| 856 | |
| 857 | |
| 858 struct irc_channel *channel; | |
| 859 int j; | |
| 860 temp = NULL; | |
| 861 temp_new = NULL; | |
| 862 | |
| 863 | |
| 864 for (j = 0, i = 1; buf[i] != '!'; j++, i++) { | |
| 865 u_nick[j] = buf[i]; | |
| 866 } | |
| 867 u_nick[j] = '\0'; | |
| 868 i++; | |
| 869 | |
| 870 for (j = 0; buf[i] != '#'; j++, i++) { | |
| 871 } | |
| 872 i++; | |
| 873 | |
| 874 for (j = 0; buf[i] != ' '; j++, i++) { | |
| 875 u_channel[j] = buf[i]; | |
| 876 } | |
| 877 | |
| 878 u_channel[j] = '\0'; | |
| 879 i++; | |
| 880 | |
| 881 for (j = 0; buf[i] != ' '; j++, i++) { | |
| 882 u_mode[j] = buf[i]; | |
| 883 } | |
| 884 u_mode[j] = '\0'; | |
| 885 i++; | |
| 886 | |
| 887 | |
| 888 | |
| 889 | |
| 890 people = g_strsplit(buf + i, " ", 3); | |
| 891 | |
| 892 | |
| 893 | |
| 894 channel = find_channel_by_name(gc, u_channel); | |
| 895 | |
| 896 if (!channel) { | |
| 897 return; | |
| 898 } | |
| 899 | |
| 900 for (j = 0; j < strlen(u_mode) - 1; j++) { | |
| 901 | |
| 902 | |
| 903 struct conversation *convo = NULL; | |
| 904 convo = find_conversation_by_id(gc, channel->id); | |
| 905 | |
| 906 | |
| 907 | |
| 908 temp = (gchar *) g_malloc(strlen(people[j]) + 3); | |
| 909 temp_new = (gchar *) g_malloc(strlen(people[j]) + 3); | |
| 910 g_snprintf(temp, strlen(people[j]) + 2, "@%s", people[j]); | |
| 911 | |
| 912 if (u_mode[1] == 'v' && u_mode[0] == '+') { | |
| 913 g_snprintf(temp_new, strlen(people[j]) + 2, "+%s", people[j]); | |
| 914 } else if (u_mode[1] == 'o' && u_mode[0] == '+') { | |
| 915 g_snprintf(temp_new, strlen(people[j]) + 2, "@%s", people[j]); | |
| 916 } | |
| 917 | |
| 918 else if (u_mode[0] == '-') { | |
| 919 g_snprintf(temp_new, strlen(people[j]) + 1, "%s", people[j]); | |
| 920 } | |
| 921 | |
| 922 | |
| 923 | |
| 924 rename_chat_buddy(convo, temp, temp_new); | |
| 925 g_snprintf(temp, strlen(people[j]) + 2, "+%s", people[j]); | |
| 926 rename_chat_buddy(convo, temp, temp_new); | |
| 927 | |
| 928 rename_chat_buddy(convo, people[j], temp_new); | |
| 929 | |
| 930 | |
| 931 | |
| 932 | |
| 933 | |
| 934 } | |
| 935 if (temp) | |
| 936 g_free(temp); | |
| 937 if (temp_new) | |
| 938 g_free(temp_new); | |
| 939 | |
| 940 return; | |
| 941 } | |
| 942 | |
| 943 | |
| 944 if ((strstr(buf, " KICK ")) && (strstr(buf, "!")) && (buf[0] == ':') | |
| 945 && (!strstr(buf, " NOTICE "))) { | |
| 946 gchar u_channel[128]; | |
| 947 gchar u_nick[128]; | |
| 948 gchar u_comment[128]; | |
| 949 gchar u_who[128]; | |
| 950 | |
| 951 int id; | |
| 952 | |
| 953 gchar *temp; | |
| 954 | |
| 955 | |
| 956 | |
| 957 struct irc_channel *channel; | |
| 958 int j; | |
| 959 | |
| 960 temp = NULL; | |
| 961 | |
| 962 for (j = 0, i = 1; buf[i] != '!'; j++, i++) { | |
| 963 u_nick[j] = buf[i]; | |
| 964 } | |
| 965 u_nick[j] = '\0'; | |
| 966 i++; | |
| 967 | |
| 968 for (j = 0; buf[i] != '#'; j++, i++) { | |
| 969 } | |
| 970 i++; | |
| 971 | |
| 972 for (j = 0; buf[i] != ' '; j++, i++) { | |
| 973 u_channel[j] = buf[i]; | |
| 974 } | |
| 975 | |
| 976 u_channel[j] = '\0'; | |
| 977 i++; | |
| 978 | |
| 979 for (j = 0; buf[i] != ' '; j++, i++) { | |
| 980 u_who[j] = buf[i]; | |
| 981 } | |
| 982 u_who[j] = '\0'; | |
| 983 i++; | |
| 984 i++; | |
| 985 strcpy(u_comment, buf + i); | |
| 986 g_strchomp(u_comment); | |
| 987 | |
| 988 channel = find_channel_by_name(gc, u_channel); | |
| 989 | |
| 990 if (!channel) { | |
| 991 return; | |
| 992 } | |
| 993 | |
| 994 | |
| 995 id = find_id_by_name(gc, u_channel); | |
| 996 | |
| 997 | |
| 998 if (g_strcasecmp(u_nick, gc->username) == 0) { | |
| 999 | |
| 1000 /* It looks like you've been naughty! */ | |
| 1001 | |
| 1002 serv_got_chat_left(gc, channel->id); | |
| 1003 | |
| 1004 idata->channels = g_list_remove(idata->channels, channel); | |
| 1005 } else { | |
| 1006 struct conversation *convo = NULL; | |
| 1007 | |
| 1008 /* Find their conversation window */ | |
| 1009 convo = find_conversation_by_id(gc, channel->id); | |
| 1010 | |
| 1011 if (!convo) { | |
| 1012 /* Some how the window doesn't exist. | |
| 1013 * Let's get out of here */ | |
| 1014 return; | |
| 1015 } | |
| 1016 | |
| 1017 /* And remove their name */ | |
| 1018 /* If the person is an op or voice, this won't work. | |
| 1019 * so we'll just do a nice hack and remove nick and | |
| 1020 * @nick and +nick. Truly wasteful. | |
| 1021 */ | |
| 1022 | |
| 1023 temp = (gchar *) g_malloc(strlen(u_who) + 3); | |
| 1024 g_snprintf(temp, strlen(u_who) + 2, "@%s", u_who); | |
| 1025 remove_chat_buddy(convo, temp); | |
| 1026 g_free(temp); | |
| 1027 temp = (gchar *) g_malloc(strlen(u_who) + 3); | |
| 1028 g_snprintf(temp, strlen(u_who) + 2, "+%s", u_who); | |
| 1029 remove_chat_buddy(convo, temp); | |
| 1030 remove_chat_buddy(convo, u_who); | |
| 1031 | |
| 1032 g_free(temp); | |
| 1033 | |
| 1034 } | |
| 1035 | |
| 1036 /* Go Home! */ | |
| 1037 return; | |
| 1038 } | |
| 1039 | |
| 1040 if ((strstr(buf, " TOPIC ")) && (buf[0] == ':') && (!strstr(buf, " NOTICE "))) { | |
| 1041 | |
| 1042 gchar u_channel[128]; | |
| 1043 gchar u_nick[128]; | |
| 1044 gchar u_topic[128]; | |
| 1045 int j; | |
| 1046 struct conversation *chatroom = NULL; | |
| 1047 | |
| 1048 for (j = 0, i = 1; buf[i] != '!'; j++, i++) { | |
| 1049 u_nick[j] = buf[i]; | |
| 1050 } | |
| 1051 u_nick[j] = 0; | |
| 1052 i++; | |
| 1053 | |
| 1054 for (j = 0; buf[i] != '#'; j++, i++) { | |
| 1055 } | |
| 1056 i++; | |
| 1057 | |
| 1058 for (j = 0; buf[i] != ' '; j++, i++) { | |
| 1059 if (buf[i] == '\0') | |
| 1060 break; | |
| 1061 | |
| 1062 u_channel[j] = buf[i]; | |
| 1063 } | |
| 1064 | |
| 1065 for (j = 0; buf[i] != ':'; j++, i++) { | |
| 1066 } | |
| 1067 i++; | |
| 1068 | |
| 1069 strcpy(u_topic, buf + i); | |
| 1070 g_strchomp(u_topic); | |
| 1071 | |
| 1072 chatroom = find_chat(gc, u_channel); | |
| 1073 | |
| 1074 if (!chatroom) | |
| 1075 return; | |
| 1076 | |
| 1077 chat_set_topic(chatroom, u_nick, u_topic); | |
| 1078 | |
| 1079 return; | |
| 1080 } | |
| 1081 | |
| 1082 | |
| 1083 if ((strstr(buf, " JOIN ")) && (strstr(buf, "!")) && (buf[0] == ':') | |
| 1084 && (!strstr(buf, " NOTICE "))) { | |
| 1085 | |
| 1086 gchar u_channel[128]; | |
| 1087 gchar u_nick[128]; | |
| 1088 | |
| 1089 struct irc_channel *channel; | |
| 1090 int j; | |
| 1091 | |
| 1092 for (j = 0, i = 1; buf[i] != '!'; j++, i++) { | |
| 1093 u_nick[j] = buf[i]; | |
| 1094 } | |
| 1095 | |
| 1096 u_nick[j] = '\0'; | |
| 1097 i++; | |
| 1098 | |
| 1099 for (j = 0; buf[i] != '#'; j++, i++) { | |
| 1100 } | |
| 1101 | |
| 1102 i++; | |
| 1103 | |
| 1104 strcpy(u_channel, buf + i); | |
| 1105 | |
| 1106 g_strchomp(u_channel); | |
| 1107 | |
| 1108 /* Looks like we're going to join the channel for real | |
| 1109 * now. Let's create a valid channel structure and add | |
| 1110 * it to our list. Let's make sure that | |
| 1111 * we are not already in a channel first */ | |
| 1112 | |
| 1113 channel = find_channel_by_name(gc, u_channel); | |
| 1114 | |
| 1115 if (!channel) { | |
| 1116 | |
| 1117 chat_id++; | |
| 1118 | |
| 1119 channel = g_new0(struct irc_channel, 1); | |
| 1120 | |
| 1121 channel->id = chat_id; | |
| 1122 channel->name = strdup(u_channel); | |
| 1123 | |
| 1124 idata->channels = g_list_append(idata->channels, channel); | |
| 1125 | |
| 1126 serv_got_joined_chat(gc, chat_id, u_channel); | |
| 1127 } else { | |
| 1128 struct conversation *convo = NULL; | |
| 1129 | |
| 1130 /* Someone else joined. Find their conversation | |
| 1131 * window */ | |
| 1132 convo = find_conversation_by_id(gc, channel->id); | |
| 1133 | |
| 1134 /* And add their name to it */ | |
| 1135 add_chat_buddy(convo, u_nick); | |
| 1136 | |
| 1137 } | |
| 1138 | |
| 1139 return; | |
| 1140 } | |
| 1141 | |
| 1142 if ((strstr(buf, " NICK ")) && (strstr(buf, "!")) && (buf[0] == ':') | |
| 1143 && (!strstr(buf, " NOTICE "))) { | |
| 1144 | |
| 1145 gchar old[128]; | |
| 1146 gchar new[128]; | |
| 1147 | |
| 1148 GList *templist; | |
| 1149 gchar *temp, *temp_new; | |
| 1150 struct irc_channel *channel; | |
| 1151 int j; | |
| 1152 temp = temp_new = NULL; | |
| 1153 for (j = 0, i = 1; buf[i] != '!'; j++, i++) { | |
| 1154 old[j] = buf[i]; | |
| 1155 } | |
| 1156 | |
| 1157 old[j] = '\0'; | |
| 1158 i++; | |
| 1159 | |
| 1160 for (j = 0; buf[i] != ':'; j++, i++) { | |
| 1161 } | |
| 1162 | |
| 1163 i++; | |
| 1164 strcpy(new, buf + i); | |
| 1165 | |
| 1166 g_strchomp(new); | |
| 1167 | |
| 1168 templist = ((struct irc_data *)gc->proto_data)->channels; | |
| 1169 | |
| 1170 while (templist) { | |
| 1171 struct conversation *convo = NULL; | |
| 1172 channel = templist->data; | |
| 1173 | |
| 1174 convo = find_conversation_by_id(gc, channel->id); | |
| 1175 | |
| 1176 /* If the person is an op or voice, this won't work. | |
| 1177 * so we'll just do a nice hack and rename nick and | |
| 1178 * @nick and +nick. Truly wasteful. | |
| 1179 */ | |
| 1180 | |
| 1181 temp = (gchar *) g_malloc(strlen(old) + 5); | |
| 1182 temp_new = (gchar *) g_malloc(strlen(new) + 5); | |
| 1183 g_snprintf(temp_new, strlen(new) + 2, "@%s", new); | |
| 1184 g_snprintf(temp, strlen(old) + 2, "@%s", old); | |
| 1185 rename_chat_buddy(convo, temp, temp_new); | |
| 1186 g_snprintf(temp, strlen(old) + 2, "+%s", old); | |
| 1187 g_snprintf(temp_new, strlen(new) + 2, "+%s", new); | |
| 1188 rename_chat_buddy(convo, temp, temp_new); | |
| 1189 rename_chat_buddy(convo, old, new); | |
| 1190 if (temp) | |
| 1191 g_free(temp); | |
| 1192 if (temp_new) | |
| 1193 g_free(temp_new); | |
| 1194 | |
| 1195 templist = templist->next; | |
| 1196 } | |
| 1197 return; | |
| 1198 } | |
| 1199 | |
| 1200 | |
| 1201 if ((strstr(buf, "QUIT ")) && (buf[0] == ':') && (strstr(buf, "!")) | |
| 1202 && (!strstr(buf, " NOTICE "))) { | |
| 1203 | |
| 1204 gchar u_nick[128]; | |
| 1205 gchar *temp; | |
| 1206 GList *templist; | |
| 1207 | |
| 1208 struct irc_channel *channel; | |
| 1209 int j; | |
| 1210 | |
| 1211 | |
| 1212 temp = NULL; | |
| 1213 for (j = 0, i = 1; buf[i] != '!'; j++, i++) { | |
| 1214 u_nick[j] = buf[i]; | |
| 1215 } | |
| 1216 | |
| 1217 u_nick[j] = '\0'; | |
| 1218 | |
| 1219 templist = ((struct irc_data *)gc->proto_data)->channels; | |
| 1220 | |
| 1221 while (templist) { | |
| 1222 struct conversation *convo = NULL; | |
| 1223 channel = templist->data; | |
| 1224 | |
| 1225 convo = find_conversation_by_id(gc, channel->id); | |
| 1226 | |
| 1227 /* If the person is an op or voice, this won't work. | |
| 1228 * so we'll just do a nice hack and remove nick and | |
| 1229 * @nick and +nick. Truly wasteful. | |
| 1230 */ | |
| 1231 | |
| 1232 temp = (gchar *) g_malloc(strlen(u_nick) + 2); | |
| 1233 g_snprintf(temp, strlen(u_nick) + 2, "@%s", u_nick); | |
| 1234 remove_chat_buddy(convo, temp); | |
| 1235 g_free(temp); | |
| 1236 temp = (gchar *) g_malloc(strlen(u_nick) + 2); | |
| 1237 g_snprintf(temp, strlen(u_nick) + 2, "+%s", u_nick); | |
| 1238 remove_chat_buddy(convo, temp); | |
| 1239 remove_chat_buddy(convo, u_nick); | |
| 1240 | |
| 1241 | |
| 1242 | |
| 1243 templist = templist->next; | |
| 1244 } | |
| 1245 | |
| 1246 g_free(temp); | |
| 1247 | |
| 1248 return; | |
| 1249 } | |
| 1250 | |
| 1251 | |
| 1252 | |
| 1253 if ((strstr(buf, " PART ")) && (strstr(buf, "!")) && (buf[0] == ':') | |
| 1254 && (!strstr(buf, " NOTICE "))) { | |
| 1255 | |
| 1256 gchar u_channel[128]; | |
| 1257 gchar u_nick[128]; | |
| 1258 gchar *temp; | |
| 1259 struct irc_channel *channel; | |
| 1260 int j; | |
| 1261 temp = NULL; | |
| 1262 for (j = 0, i = 1; buf[i] != '!'; j++, i++) { | |
| 1263 u_nick[j] = buf[i]; | |
| 1264 } | |
| 1265 u_nick[j] = '\0'; | |
| 1266 | |
| 1267 i++; | |
| 1268 | |
| 1269 for (j = 0; buf[i] != '#'; j++, i++) { | |
| 1270 } | |
| 1271 | |
| 1272 i++; | |
| 1273 | |
| 1274 for (j = 0; buf[i] != ' '; j++, i++) { | |
| 1275 if (buf[i] == '\0') { | |
| 1276 break; | |
| 1277 } | |
| 1278 u_channel[j] = buf[i]; | |
| 1279 } | |
| 1280 u_channel[j] = '\0'; | |
| 1281 | |
| 1282 /* Now, lets check to see if it was US that was leaving. | |
| 1283 * If so, do the correct thing by closing up all of our | |
| 1284 * old channel stuff. Otherwise, | |
| 1285 * we should just print that someone left */ | |
| 1286 | |
| 1287 channel = find_channel_by_name(gc, u_channel); | |
| 1288 | |
| 1289 if (!channel) { | |
| 1290 return; | |
| 1291 } | |
| 1292 | |
| 1293 if (g_strcasecmp(u_nick, gc->username) == 0) { | |
| 1294 | |
| 1295 /* Looks like we're going to leave the channel for | |
| 1296 * real now. Let's create a valid channel structure | |
| 1297 * and add it to our list */ | |
| 1298 | |
| 1299 serv_got_chat_left(gc, channel->id); | |
| 1300 | |
| 1301 idata->channels = g_list_remove(idata->channels, channel); | |
| 1302 } else { | |
| 1303 struct conversation *convo = NULL; | |
| 1304 | |
| 1305 /* Find their conversation window */ | |
| 1306 convo = find_conversation_by_id(gc, channel->id); | |
| 1307 | |
| 1308 if (!convo) { | |
| 1309 /* Some how the window doesn't exist. | |
| 1310 * Let's get out of here */ | |
| 1311 return; | |
| 1312 } | |
| 1313 | |
| 1314 /* And remove their name */ | |
| 1315 /* If the person is an op or voice, this won't work. | |
| 1316 * so we'll just do a nice hack and remove nick and | |
| 1317 * @nick and +nick. Truly wasteful. | |
| 1318 */ | |
| 1319 | |
| 1320 temp = (gchar *) g_malloc(strlen(u_nick) + 3); | |
| 1321 g_snprintf(temp, strlen(u_nick) + 2, "@%s", u_nick); | |
| 1322 remove_chat_buddy(convo, temp); | |
| 1323 g_free(temp); | |
| 1324 temp = (gchar *) g_malloc(strlen(u_nick) + 3); | |
| 1325 g_snprintf(temp, strlen(u_nick) + 2, "+%s", u_nick); | |
| 1326 remove_chat_buddy(convo, temp); | |
| 1327 g_free(temp); | |
| 1328 remove_chat_buddy(convo, u_nick); | |
| 1329 | |
| 1330 | |
| 1331 } | |
| 1332 | |
| 1333 /* Go Home! */ | |
| 1334 return; | |
| 1335 } | |
| 1336 | |
| 1337 if ((strstr(buf, " NOTICE ")) && (buf[0] == ':')) { | |
| 1338 gchar u_nick[128]; | |
| 1339 gchar u_host[255]; | |
| 1340 gchar u_command[32]; | |
| 1341 gchar u_channel[128]; | |
| 1342 gchar u_message[IRC_BUF_LEN]; | |
| 1343 int j; | |
| 1344 | |
| 1345 for (j = 0, i = 1; buf[i] != '!'; j++, i++) { | |
| 1346 u_nick[j] = buf[i]; | |
| 1347 } | |
| 1348 | |
| 1349 u_nick[j] = '\0'; | |
| 1350 i++; | |
| 1351 | |
| 1352 for (j = 0; buf[i] != ' '; j++, i++) { | |
| 1353 u_host[j] = buf[i]; | |
| 1354 } | |
| 1355 | |
| 1356 u_host[j] = '\0'; | |
| 1357 i++; | |
| 1358 | |
| 1359 for (j = 0; buf[i] != ' '; j++, i++) { | |
| 1360 u_command[j] = buf[i]; | |
| 1361 } | |
| 1362 | |
| 1363 u_command[j] = '\0'; | |
| 1364 i++; | |
| 1365 | |
| 1366 for (j = 0; buf[i] != ':'; j++, i++) { | |
| 1367 u_channel[j] = buf[i]; | |
| 1368 } | |
| 1369 | |
| 1370 u_channel[j - 1] = '\0'; | |
| 1371 i++; | |
| 1372 | |
| 1373 | |
| 1374 /* Now that everything is parsed, the rest of this baby must be our message */ | |
| 1375 strncpy(u_message, buf + i, IRC_BUF_LEN); | |
| 1376 | |
| 1377 /* Now, lets check the message to see if there's anything special in it */ | |
| 1378 if (u_message[0] == '\001') { | |
| 1379 if ((g_strncasecmp(u_message, "\001PING ", 6) == 0) && (strlen(u_message) > 6)) { | |
| 1380 /* Someone's triyng to ping us. Let's respond */ | |
| 1381 gchar u_arg[24]; | |
| 1382 gchar u_buf[200]; | |
| 1383 unsigned long tend = time((time_t *) NULL); | |
| 1384 unsigned long tstart; | |
| 1385 | |
| 1386 printf("LA: %s\n", buf); | |
| 1387 | |
| 1388 strcpy(u_arg, u_message + 6); | |
| 1389 u_arg[strlen(u_arg) - 1] = '\0'; | |
| 1390 | |
| 1391 tstart = atol(u_arg); | |
| 1392 | |
| 1393 g_snprintf(u_buf, sizeof(u_buf), "Ping Reply From %s: [%ld seconds]", | |
| 1394 u_nick, tend - tstart); | |
| 1395 | |
| 1396 do_error_dialog(u_buf, "Gaim IRC - Ping Reply"); | |
| 1397 | |
| 1398 return; | |
| 1399 } | |
| 1400 } | |
| 1401 | |
| 1402 } | |
| 1403 | |
| 1404 | |
| 1405 if ((strstr(buf, " PRIVMSG ")) && (buf[0] == ':')) { | |
| 1406 gchar u_nick[128]; | |
| 1407 gchar u_host[255]; | |
| 1408 gchar u_command[32]; | |
| 1409 gchar u_channel[128]; | |
| 1410 gchar u_message[IRC_BUF_LEN]; | |
| 1411 gboolean is_closing; | |
| 1412 | |
| 1413 int j; | |
| 1414 | |
| 1415 | |
| 1416 for (j = 0, i = 1; buf[i] != '!'; j++, i++) { | |
| 1417 u_nick[j] = buf[i]; | |
| 1418 } | |
| 1419 | |
| 1420 u_nick[j] = '\0'; | |
| 1421 i++; | |
| 1422 | |
| 1423 for (j = 0; buf[i] != ' '; j++, i++) { | |
| 1424 u_host[j] = buf[i]; | |
| 1425 } | |
| 1426 | |
| 1427 u_host[j] = '\0'; | |
| 1428 i++; | |
| 1429 | |
| 1430 for (j = 0; buf[i] != ' '; j++, i++) { | |
| 1431 u_command[j] = buf[i]; | |
| 1432 } | |
| 1433 | |
| 1434 u_command[j] = '\0'; | |
| 1435 i++; | |
| 1436 | |
| 1437 for (j = 0; buf[i] != ':'; j++, i++) { | |
| 1438 u_channel[j] = buf[i]; | |
| 1439 } | |
| 1440 | |
| 1441 u_channel[j - 1] = '\0'; | |
| 1442 i++; | |
| 1443 | |
| 1444 | |
| 1445 /* Now that everything is parsed, the rest of this baby must be our message */ | |
| 1446 strncpy(u_message, buf + i, IRC_BUF_LEN); | |
| 1447 | |
| 1448 /* Now, lets check the message to see if there's anything special in it */ | |
| 1449 if (u_message[0] == '\001') { | |
| 1450 if (g_strncasecmp(u_message, "\001VERSION", 8) == 0) { | |
| 1451 /* Looks like we have a version request. Let | |
| 1452 * us handle it thusly */ | |
| 1453 | |
| 1454 g_snprintf(buf, IRC_BUF_LEN, | |
| 1455 "NOTICE %s :%cVERSION GAIM %s:The Pimpin Penguin AIM Clone:%s%c\n", | |
| 1456 u_nick, '\001', VERSION, WEBSITE, '\001'); | |
| 1457 | |
| 1458 write(idata->fd, buf, strlen(buf)); | |
| 1459 | |
| 1460 /* And get the heck out of dodge */ | |
| 1461 return; | |
| 1462 } | |
| 1463 | |
| 1464 if ((g_strncasecmp(u_message, "\001PING ", 6) == 0) && (strlen(u_message) > 6)) { | |
| 1465 /* Someone's triyng to ping us. Let's respond */ | |
| 1466 gchar u_arg[24]; | |
| 1467 | |
| 1468 strcpy(u_arg, u_message + 6); | |
| 1469 u_arg[strlen(u_arg) - 1] = '\0'; | |
| 1470 | |
| 1471 g_snprintf(buf, IRC_BUF_LEN, "NOTICE %s :%cPING %s%c\n", u_nick, '\001', | |
| 1472 u_arg, '\001'); | |
| 1473 | |
| 1474 write(idata->fd, buf, strlen(buf)); | |
| 1475 | |
| 1476 /* And get the heck out of dodge */ | |
| 1477 return; | |
| 1478 } | |
| 1479 | |
| 1480 if (g_strncasecmp(u_message, "\001ACTION ", 8) == 0) { | |
| 1481 /* Looks like we have an action. Let's parse it a little */ | |
| 1482 strcpy(buf, u_message); | |
| 1483 | |
| 1484 strcpy(u_message, "/me "); | |
| 1485 for (j = 4, i = 8; buf[i] != '\001'; i++, j++) { | |
| 1486 u_message[j] = buf[i]; | |
| 1487 } | |
| 1488 u_message[j] = '\0'; | |
| 1489 } | |
| 1490 } | |
| 1491 | |
| 1492 | |
| 1493 /* OK, It is a chat or IM message. Here, let's translate the IRC formatting into | |
|
2171
b51cd9350d65
[gaim-migrate @ 2181]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1494 * good ol' fashioned imhtml style hypertext markup. */ |
| 2086 | 1495 |
| 1496 | |
| 1497 is_closing = FALSE; | |
| 1498 | |
| 1499 while (strchr(u_message, '\002')) { /* \002 = ^B */ | |
| 1500 gchar *current; | |
| 1501 gchar *temp, *free_here; | |
| 1502 | |
| 1503 | |
| 1504 temp = g_strdup(strchr(u_message, '\002')); | |
| 1505 free_here = temp; | |
| 1506 temp++; | |
| 1507 | |
| 1508 current = strchr(u_message, '\002'); | |
| 1509 *current = '<'; | |
| 1510 current++; | |
| 1511 if (is_closing) { | |
| 1512 *current = '/'; | |
| 1513 current++; | |
| 1514 } | |
| 1515 *current = 'b'; | |
| 1516 current++; | |
| 1517 *current = '>'; | |
| 1518 current++; | |
| 1519 | |
| 1520 | |
| 1521 while (*temp != '\0') { | |
| 1522 *current = *temp; | |
| 1523 current++; | |
| 1524 temp++; | |
| 1525 } | |
| 1526 *current = '\0'; | |
| 1527 g_free(free_here); | |
| 1528 | |
| 1529 is_closing = !is_closing; | |
| 1530 } | |
| 1531 | |
| 1532 is_closing = FALSE; | |
| 1533 while (strchr(u_message, '\037')) { /* \037 = ^_ */ | |
| 1534 gchar *current; | |
| 1535 gchar *temp, *free_here; | |
| 1536 | |
| 1537 | |
| 1538 temp = g_strdup(strchr(u_message, '\037')); | |
| 1539 free_here = temp; | |
| 1540 temp++; | |
| 1541 | |
| 1542 current = strchr(u_message, '\037'); | |
| 1543 *current = '<'; | |
| 1544 current++; | |
| 1545 if (is_closing) { | |
| 1546 *current = '/'; | |
| 1547 current++; | |
| 1548 } | |
| 1549 *current = 'u'; | |
| 1550 current++; | |
| 1551 *current = '>'; | |
| 1552 current++; | |
| 1553 | |
| 1554 | |
| 1555 while (*temp != '\0') { | |
| 1556 *current = *temp; | |
| 1557 current++; | |
| 1558 temp++; | |
| 1559 } | |
| 1560 *current = '\0'; | |
| 1561 g_free(free_here); | |
| 1562 is_closing = !is_closing; | |
| 1563 | |
| 1564 } | |
| 1565 | |
| 1566 while (strchr(u_message, '\003')) { /* \003 = ^C */ | |
| 1567 | |
| 1568 /* This is color formatting. IRC uses its own weird little system | |
| 1569 * that we must translate to HTML. */ | |
| 1570 | |
| 1571 | |
| 1572 /* The format is something like this: | |
| 1573 * ^C5 or ^C5,3 | |
| 1574 * The number before the comma is the foreground color, after is the | |
| 1575 * background color. Either number can be 1 or two digits. | |
| 1576 */ | |
| 1577 | |
| 1578 gchar *current; | |
| 1579 gchar *temp, *free_here; | |
| 1580 gchar *font_tag, *body_tag; | |
| 1581 int fg_color, bg_color; | |
| 1582 | |
| 1583 temp = g_strdup(strchr(u_message, '\003')); | |
| 1584 free_here = temp; | |
| 1585 temp++; | |
| 1586 | |
| 1587 fg_color = bg_color = -1; | |
| 1588 body_tag = font_tag = ""; | |
| 1589 | |
| 1590 /* Parsing the color information: */ | |
| 1591 do { | |
| 1592 if (!isdigit(*temp)) | |
| 1593 break; /* This translates to </font> */ | |
| 1594 fg_color = (int)(*temp - 48); | |
| 1595 temp++; | |
| 1596 if (isdigit(*temp)) { | |
| 1597 fg_color = (fg_color * 10) + (int)(*temp - 48); | |
| 1598 temp++; | |
| 1599 } | |
| 1600 if (*temp != ',') | |
| 1601 break; | |
| 1602 temp++; | |
| 1603 if (!isdigit(*temp)) | |
| 1604 break; /* This translates to </font> */ | |
| 1605 bg_color = (int)(*temp - 48); | |
| 1606 temp++; | |
| 1607 if (isdigit(*temp)) { | |
| 1608 bg_color = (bg_color * 10) + (int)(*temp - 48); | |
| 1609 temp++; | |
| 1610 } | |
| 1611 } while (FALSE); | |
| 1612 | |
| 1613 if (fg_color > 15) | |
| 1614 fg_color = fg_color % 16; | |
| 1615 if (bg_color > 15) | |
| 1616 bg_color = bg_color % 16; | |
| 1617 | |
| 1618 switch (fg_color) { | |
| 1619 case -1: | |
| 1620 font_tag = "</font></body>"; | |
| 1621 break; | |
| 1622 case 0: /* WHITE */ | |
| 1623 font_tag = "<font color=\"#ffffff\">"; | |
| 1624 /* If no background color is specified, we're going to make it black anyway. | |
| 1625 * That's probably what the sender anticipated the background color to be. | |
| 1626 * White on white would be illegible. | |
| 1627 */ | |
| 1628 if (bg_color == -1) { | |
| 1629 body_tag = "<body bgcolor=\"#000000\">"; | |
| 1630 } | |
| 1631 break; | |
| 1632 case 1: /* BLACK */ | |
| 1633 font_tag = "<font color=\"#000000\">"; | |
| 1634 break; | |
| 1635 case 2: /* NAVY BLUE */ | |
| 1636 font_tag = "<font color=\"#000066\">"; | |
| 1637 break; | |
| 1638 case 3: /* GREEN */ | |
| 1639 font_tag = "<font color=\"#006600\">"; | |
| 1640 break; | |
| 1641 case 4: /* RED */ | |
| 1642 font_tag = "<font color=\"#ff0000\">"; | |
| 1643 break; | |
| 1644 case 5: /* MAROON */ | |
| 1645 font_tag = "<font color=\"#660000\">"; | |
| 1646 break; | |
| 1647 case 6: /* PURPLE */ | |
| 1648 font_tag = "<font color=\"#660066\">"; | |
| 1649 break; | |
| 1650 case 7: /* DISGUSTING PUKE COLOR */ | |
| 1651 font_tag = "<font color=\"#666600\">"; | |
| 1652 break; | |
| 1653 case 8: /* YELLOW */ | |
| 1654 font_tag = "<font color=\"#cccc00\">"; | |
| 1655 break; | |
| 1656 case 9: /* LIGHT GREEN */ | |
| 1657 font_tag = "<font color=\"#33cc33\">"; | |
| 1658 break; | |
| 1659 case 10: /* TEAL */ | |
| 1660 font_tag = "<font color=\"#00acac\">"; | |
| 1661 break; | |
| 1662 case 11: /* CYAN */ | |
| 1663 font_tag = "<font color=\"#00ccac\">"; | |
| 1664 break; | |
| 1665 case 12: /* BLUE */ | |
| 1666 font_tag = "<font color=\"#0000ff\">"; | |
| 1667 break; | |
| 1668 case 13: /* PINK */ | |
| 1669 font_tag = "<font color=\"#cc00cc\">"; | |
| 1670 break; | |
| 1671 case 14: /* GREY */ | |
| 1672 font_tag = "<font color=\"#666666\">"; | |
| 1673 break; | |
| 1674 case 15: /* SILVER */ | |
| 1675 font_tag = "<font color=\"#00ccac\">"; | |
| 1676 break; | |
| 1677 } | |
| 1678 | |
| 1679 switch (bg_color) { | |
| 1680 case 0: /* WHITE */ | |
| 1681 body_tag = "<body bgcolor=\"#ffffff\">"; | |
| 1682 break; | |
| 1683 case 1: /* BLACK */ | |
| 1684 body_tag = "<body bgcolor=\"#000000\">"; | |
| 1685 break; | |
| 1686 case 2: /* NAVY BLUE */ | |
| 1687 body_tag = "<body bgcolor=\"#000066\">"; | |
| 1688 break; | |
| 1689 case 3: /* GREEN */ | |
| 1690 body_tag = "<body bgcolor=\"#006600\">"; | |
| 1691 break; | |
| 1692 case 4: /* RED */ | |
| 1693 body_tag = "<body bgcolor=\"#ff0000\">"; | |
| 1694 break; | |
| 1695 case 5: /* MAROON */ | |
| 1696 body_tag = "<body bgcolor=\"#660000\">"; | |
| 1697 break; | |
| 1698 case 6: /* PURPLE */ | |
| 1699 body_tag = "<body bgcolor=\"#660066\">"; | |
| 1700 break; | |
| 1701 case 7: /* DISGUSTING PUKE COLOR */ | |
| 1702 body_tag = "<body bgcolor=\"#666600\">"; | |
| 1703 break; | |
| 1704 case 8: /* YELLOW */ | |
| 1705 body_tag = "<body bgcolor=\"#cccc00\">"; | |
| 1706 break; | |
| 1707 case 9: /* LIGHT GREEN */ | |
| 1708 body_tag = "<body bgcolor=\"#33cc33\">"; | |
| 1709 break; | |
| 1710 case 10: /* TEAL */ | |
| 1711 body_tag = "<body bgcolor=\"#00acac\">"; | |
| 1712 break; | |
| 1713 case 11: /* CYAN */ | |
| 1714 body_tag = "<body bgcolor=\"#00ccac\">"; | |
| 1715 break; | |
| 1716 case 12: /* BLUE */ | |
| 1717 body_tag = "<body bgcolor=\"#0000ff\">"; | |
| 1718 break; | |
| 1719 case 13: /* PINK */ | |
| 1720 body_tag = "<body bgcolor=\"#cc00cc\">"; | |
| 1721 break; | |
| 1722 case 14: /* GREY */ | |
| 1723 body_tag = "<body bgcolor=\"#666666\">"; | |
| 1724 break; | |
| 1725 case 15: /* SILVER */ | |
| 1726 body_tag = "<body bgcolor=\"#00ccac\">"; | |
| 1727 break; | |
| 1728 } | |
| 1729 | |
| 1730 current = strchr(u_message, '\003'); | |
| 1731 | |
| 1732 while (*body_tag != '\0') { | |
| 1733 *current = *body_tag; | |
| 1734 current++; | |
| 1735 body_tag++; | |
| 1736 } | |
| 1737 | |
| 1738 while (*font_tag != '\0') { | |
| 1739 *current = *font_tag; | |
| 1740 current++; | |
| 1741 font_tag++; | |
| 1742 } | |
| 1743 | |
| 1744 while (*temp != '\0') { | |
| 1745 *current = *temp; | |
| 1746 current++; | |
| 1747 temp++; | |
| 1748 } | |
| 1749 *current = '\0'; | |
| 1750 g_free(free_here); | |
| 1751 is_closing = !is_closing; | |
| 1752 | |
| 1753 } | |
| 1754 | |
| 1755 while (strchr(u_message, '\017')) { /* \017 = ^O */ | |
| 1756 gchar *current; | |
| 1757 gchar *temp, *free_here; | |
| 1758 | |
| 1759 | |
| 1760 temp = g_strdup(strchr(u_message, '\017')); | |
| 1761 free_here = temp; | |
| 1762 temp++; | |
| 1763 | |
| 1764 current = strchr(u_message, '\017'); | |
| 1765 *current = '<'; | |
| 1766 current++; | |
| 1767 *current = '/'; | |
| 1768 current++; | |
| 1769 *current = 'b'; | |
| 1770 current++; | |
| 1771 *current = '>'; | |
| 1772 current++; | |
| 1773 *current = '<'; | |
| 1774 current++; | |
| 1775 *current = '/'; | |
| 1776 current++; | |
| 1777 *current = 'u'; | |
| 1778 current++; | |
| 1779 *current = '>'; | |
| 1780 current++; | |
| 1781 | |
| 1782 while (*temp != '\0') { | |
| 1783 *current = *temp; | |
| 1784 current++; | |
| 1785 temp++; | |
| 1786 } | |
| 1787 *current = '\0'; | |
| 1788 g_free(free_here); | |
| 1789 } | |
| 1790 | |
| 1791 /* Let's check to see if we have a channel on our hands */ | |
| 1792 if (u_channel[0] == '#') { | |
| 1793 /* Yup. We have a channel */ | |
| 1794 int id; | |
| 1795 | |
| 1796 id = find_id_by_name(gc, u_channel); | |
| 1797 if (id != -1) { | |
| 1798 serv_got_chat_in(gc, id, u_nick, 0, u_message, time((time_t) NULL)); | |
| 1799 | |
| 1800 } | |
| 1801 | |
| 1802 } else { | |
| 1803 /* Nope. Let's treat it as a private message */ | |
| 1804 | |
| 1805 gchar *temp; | |
| 1806 temp = NULL; | |
| 1807 | |
| 1808 temp = (gchar *) g_malloc(strlen(u_nick) + 5); | |
| 1809 g_snprintf(temp, strlen(u_nick) + 2, "@%s", u_nick); | |
| 1810 | |
| 1811 | |
| 1812 /* If I get a message from SeanEgn, and I already have a window | |
| 1813 * open for him as @SeanEgn or +SeanEgn, this will keep it in the | |
| 1814 * same window. Unfortunately, if SeanEgn loses his op status | |
| 1815 * (a sad thing indeed), the messages will still appear to come from | |
| 1816 * @SeanEgn, until that convo is closed. | |
| 1817 */ | |
| 1818 | |
| 1819 if (find_conversation(temp)) { | |
| 1820 serv_got_im(gc, temp, u_message, 0, time((time_t) NULL)); | |
| 1821 g_free(temp); | |
| 1822 return; | |
| 1823 } else { | |
| 1824 g_snprintf(temp, strlen(u_nick) + 2, "+%s", u_nick); | |
| 1825 if (find_conversation(temp)) { | |
| 1826 serv_got_im(gc, temp, u_message, 0, time((time_t) NULL)); | |
| 1827 g_free(temp); | |
| 1828 return; | |
| 1829 } else { | |
| 1830 g_free(temp); | |
| 1831 serv_got_im(gc, u_nick, u_message, 0, time((time_t) NULL)); | |
| 1832 return; | |
| 1833 } | |
| 1834 } | |
| 1835 } | |
| 1836 | |
| 1837 return; | |
| 1838 } | |
| 1839 | |
| 1840 /* Let's parse PING requests so that we wont get booted for inactivity */ | |
| 1841 | |
| 1842 if (strncmp(buf, "PING :", 6) == 0) { | |
| 1843 buf2 = g_strsplit(buf, ":", 1); | |
| 1844 | |
| 1845 /* Let's build a new response */ | |
| 1846 g_snprintf(buf, IRC_BUF_LEN, "PONG :%s\n", buf2[1]); | |
| 1847 write(idata->fd, buf, strlen(buf)); | |
| 1848 | |
| 1849 /* And clean up after ourselves */ | |
| 1850 g_strfreev(buf2); | |
| 1851 | |
| 1852 return; | |
| 1853 } | |
| 1854 | |
| 1855 } | |
| 1856 | |
| 1857 static void irc_close(struct gaim_connection *gc) | |
| 1858 { | |
| 1859 struct irc_data *idata = (struct irc_data *)gc->proto_data; | |
| 1860 GList *chats = idata->channels; | |
| 1861 struct irc_channel *cc; | |
| 1862 | |
| 1863 gchar *buf = (gchar *) g_malloc(IRC_BUF_LEN); | |
| 1864 | |
| 1865 g_snprintf(buf, IRC_BUF_LEN, "QUIT :Download GAIM [%s]\n", WEBSITE); | |
| 1866 write(idata->fd, buf, strlen(buf)); | |
| 1867 | |
| 1868 g_free(buf); | |
| 1869 | |
| 1870 if (idata->timer) | |
|
2131
acc11216ec5d
[gaim-migrate @ 2141]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1871 g_source_remove(idata->timer); |
| 2086 | 1872 |
| 1873 while (chats) { | |
| 1874 cc = (struct irc_channel *)chats->data; | |
| 1875 g_free(cc->name); | |
| 1876 chats = g_list_remove(chats, cc); | |
| 1877 g_free(cc); | |
| 1878 } | |
| 1879 | |
| 1880 if (gc->inpa) | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1881 gaim_input_remove(gc->inpa); |
| 2086 | 1882 |
| 1883 if (idata->inpa) | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1884 gaim_input_remove(idata->inpa); |
| 2086 | 1885 |
| 1886 close(idata->fd); | |
| 1887 g_free(gc->proto_data); | |
| 1888 } | |
| 1889 | |
| 1890 static void irc_chat_leave(struct gaim_connection *gc, int id) | |
| 1891 { | |
| 1892 struct irc_data *idata = (struct irc_data *)gc->proto_data; | |
| 1893 struct irc_channel *channel; | |
| 1894 gchar *buf = (gchar *) g_malloc(IRC_BUF_LEN + 1); | |
| 1895 | |
| 1896 channel = find_channel_by_id(gc, id); | |
| 1897 | |
| 1898 if (!channel) { | |
| 1899 return; | |
| 1900 } | |
| 1901 | |
| 1902 g_snprintf(buf, IRC_BUF_LEN, "PART #%s\n", channel->name); | |
| 1903 write(idata->fd, buf, strlen(buf)); | |
| 1904 | |
| 1905 g_free(buf); | |
| 1906 } | |
| 1907 | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1908 static void irc_login_callback(gpointer data, gint source, GaimInputCondition condition) |
| 2086 | 1909 { |
| 1910 struct gaim_connection *gc = data; | |
| 1911 struct irc_data *idata; | |
| 1912 char buf[4096]; | |
| 1913 | |
| 1914 if (!g_slist_find(connections, gc)) { | |
| 1915 close(source); | |
| 1916 return; | |
| 1917 } | |
| 1918 | |
| 1919 idata = gc->proto_data; | |
| 1920 | |
| 1921 if (source == -1) { | |
| 1922 hide_login_progress(gc, "Write error"); | |
| 1923 signoff(gc); | |
| 1924 return; | |
| 1925 } | |
| 1926 | |
| 1927 if (idata->fd != source) | |
| 1928 idata->fd = source; | |
| 1929 | |
| 1930 g_snprintf(buf, 4096, "NICK %s\n USER %s localhost %s :GAIM (%s)\n", | |
| 1931 gc->username, g_get_user_name(), gc->user->proto_opt[USEROPT_SERV], WEBSITE); | |
| 1932 | |
| 1933 if (write(idata->fd, buf, strlen(buf)) < 0) { | |
| 1934 hide_login_progress(gc, "Write error"); | |
| 1935 signoff(gc); | |
| 1936 return; | |
| 1937 } | |
| 1938 | |
|
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
1939 idata->inpa = gaim_input_add(idata->fd, GAIM_INPUT_READ, irc_callback, gc); |
| 2086 | 1940 |
| 1941 /* Now lets sign ourselves on */ | |
| 1942 account_online(gc); | |
| 1943 serv_finish_login(gc); | |
| 1944 | |
| 1945 if (bud_list_cache_exists(gc)) | |
| 1946 do_import(NULL, gc); | |
| 1947 | |
| 1948 /* we don't call this now because otherwise some IRC servers might not like us */ | |
|
2131
acc11216ec5d
[gaim-migrate @ 2141]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
1949 idata->timer = g_timeout_add(20000, irc_request_buddy_update, gc); |
| 2086 | 1950 } |
| 1951 | |
| 1952 static void irc_login(struct aim_user *user) | |
| 1953 { | |
| 1954 char buf[4096]; | |
| 1955 | |
| 1956 struct gaim_connection *gc = new_gaim_conn(user); | |
| 1957 struct irc_data *idata = gc->proto_data = g_new0(struct irc_data, 1); | |
| 1958 | |
| 1959 g_snprintf(buf, sizeof(buf), "Signon: %s", gc->username); | |
| 1960 set_login_progress(gc, 2, buf); | |
| 1961 | |
| 1962 idata->fd = proxy_connect(user->proto_opt[USEROPT_SERV], | |
| 1963 user->proto_opt[USEROPT_PORT][0] ? atoi(user-> | |
| 1964 proto_opt[USEROPT_PORT]) : | |
| 1965 6667, irc_login_callback, gc); | |
| 1966 if (!user->gc || (idata->fd < 0)) { | |
| 1967 hide_login_progress(gc, "Unable to create socket"); | |
| 1968 signoff(gc); | |
| 1969 return; | |
| 1970 } | |
| 1971 } | |
| 1972 | |
|
2154
cff133e0ec0c
[gaim-migrate @ 2164]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2147
diff
changeset
|
1973 static GList *irc_user_opts() |
| 2086 | 1974 { |
|
2154
cff133e0ec0c
[gaim-migrate @ 2164]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2147
diff
changeset
|
1975 GList *m = NULL; |
|
cff133e0ec0c
[gaim-migrate @ 2164]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2147
diff
changeset
|
1976 struct proto_user_opt *puo; |
|
cff133e0ec0c
[gaim-migrate @ 2164]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2147
diff
changeset
|
1977 |
|
cff133e0ec0c
[gaim-migrate @ 2164]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2147
diff
changeset
|
1978 puo = g_new0(struct proto_user_opt, 1); |
|
cff133e0ec0c
[gaim-migrate @ 2164]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2147
diff
changeset
|
1979 puo->label = "Server:"; |
|
cff133e0ec0c
[gaim-migrate @ 2164]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2147
diff
changeset
|
1980 puo->def = "irc.mozilla.org"; |
|
cff133e0ec0c
[gaim-migrate @ 2164]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2147
diff
changeset
|
1981 puo->pos = USEROPT_SERV; |
|
cff133e0ec0c
[gaim-migrate @ 2164]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2147
diff
changeset
|
1982 m = g_list_append(m, puo); |
|
cff133e0ec0c
[gaim-migrate @ 2164]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2147
diff
changeset
|
1983 |
|
cff133e0ec0c
[gaim-migrate @ 2164]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2147
diff
changeset
|
1984 puo = g_new0(struct proto_user_opt, 1); |
|
cff133e0ec0c
[gaim-migrate @ 2164]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2147
diff
changeset
|
1985 puo->label = "Port:"; |
|
cff133e0ec0c
[gaim-migrate @ 2164]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2147
diff
changeset
|
1986 puo->def = "6667"; |
|
cff133e0ec0c
[gaim-migrate @ 2164]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2147
diff
changeset
|
1987 puo->pos = USEROPT_PORT; |
|
cff133e0ec0c
[gaim-migrate @ 2164]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2147
diff
changeset
|
1988 m = g_list_append(m, puo); |
|
cff133e0ec0c
[gaim-migrate @ 2164]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2147
diff
changeset
|
1989 |
|
cff133e0ec0c
[gaim-migrate @ 2164]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2147
diff
changeset
|
1990 return m; |
| 2086 | 1991 } |
| 1992 | |
| 1993 static char **irc_list_icon(int uc) | |
| 1994 { | |
| 1995 return free_icon_xpm; | |
| 1996 } | |
| 1997 | |
| 1998 /* Send out a ping request to the specified user */ | |
|
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
1999 static void irc_send_ping(struct gaim_connection *gc, char *who) |
| 2086 | 2000 { |
| 2001 struct irc_data *idata = (struct irc_data *)gc->proto_data; | |
| 2002 char buf[BUF_LEN]; | |
| 2003 | |
| 2004 g_snprintf(buf, BUF_LEN, "PRIVMSG %s :%cPING %ld%c\n", who, '\001', time((time_t *) NULL), | |
| 2005 '\001'); | |
| 2006 | |
| 2007 write(idata->fd, buf, strlen(buf)); | |
| 2008 } | |
| 2009 | |
| 2010 /* Do a whois check on someone :-) */ | |
| 2011 static void irc_get_info(struct gaim_connection *gc, char *who) | |
| 2012 { | |
| 2013 struct irc_data *idata = (struct irc_data *)gc->proto_data; | |
| 2014 char buf[BUF_LEN]; | |
| 2015 | |
| 2016 if (((who[0] == '@') || (who[0] == '+')) && (strlen(who) > 1)) | |
| 2017 g_snprintf(buf, BUF_LEN, "WHOIS %s\n", who + 1); | |
| 2018 else | |
| 2019 g_snprintf(buf, BUF_LEN, "WHOIS %s\n", who); | |
| 2020 write(idata->fd, buf, strlen(buf)); | |
| 2021 } | |
| 2022 | |
|
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
2023 static GList *irc_buddy_menu(struct gaim_connection *gc, char *who) |
| 2086 | 2024 { |
|
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
2025 GList *m = NULL; |
|
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
2026 struct proto_buddy_menu *pbm; |
|
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
2027 |
|
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
2028 pbm = g_new0(struct proto_buddy_menu, 1); |
|
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
2029 pbm->label = _("Ping"); |
|
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
2030 pbm->callback = irc_send_ping; |
|
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
2031 pbm->gc = gc; |
|
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
2032 m = g_list_append(m, pbm); |
|
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
2033 |
|
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
2034 pbm = g_new0(struct proto_buddy_menu, 1); |
|
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
2035 pbm->label = _("Whois"); |
|
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
2036 pbm->callback = irc_get_info; |
|
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
2037 pbm->gc = gc; |
|
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
2038 m = g_list_append(m, pbm); |
|
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
2039 |
|
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
2040 return m; |
| 2086 | 2041 } |
| 2042 | |
| 2043 | |
| 2044 static void irc_set_away(struct gaim_connection *gc, char *state, char *msg) | |
| 2045 { | |
| 2046 struct irc_data *idata = (struct irc_data *)gc->proto_data; | |
| 2047 char buf[BUF_LEN]; | |
| 2048 | |
| 2049 if (msg) | |
| 2050 g_snprintf(buf, BUF_LEN, "AWAY :%s\n", msg); | |
| 2051 else | |
| 2052 g_snprintf(buf, BUF_LEN, "AWAY\n"); | |
| 2053 | |
| 2054 write(idata->fd, buf, strlen(buf)); | |
| 2055 } | |
| 2056 | |
| 2057 static void irc_fake_buddy(struct gaim_connection *gc, char *who) | |
| 2058 { | |
| 2059 /* Heh, there is no buddy list. We fake it. | |
| 2060 * I just need this here so the add and remove buttons will | |
| 2061 * show up */ | |
| 2062 } | |
| 2063 | |
| 2064 static void irc_chat_set_topic(struct gaim_connection *gc, int id, char *topic) | |
| 2065 { | |
| 2066 struct irc_channel *ic = NULL; | |
| 2067 struct irc_data *idata = (struct irc_data *)gc->proto_data; | |
| 2068 char buf[BUF_LEN]; | |
| 2069 | |
| 2070 ic = find_channel_by_id(gc, id); | |
| 2071 | |
| 2072 /* If we ain't in no channel, foo, gets outta da kitchen beeyotch */ | |
| 2073 if (!ic) | |
| 2074 return; | |
| 2075 | |
| 2076 /* Prepare our command */ | |
| 2077 g_snprintf(buf, BUF_LEN, "TOPIC #%s :%s\n", ic->name, topic); | |
| 2078 | |
| 2079 /* And send it */ | |
| 2080 write(idata->fd, buf, strlen(buf)); | |
| 2081 } | |
| 2082 | |
| 2083 static struct prpl *my_protocol = NULL; | |
| 2084 | |
| 2085 void irc_init(struct prpl *ret) | |
| 2086 { | |
| 2087 ret->protocol = PROTO_IRC; | |
|
2100
a93aeb6f813d
[gaim-migrate @ 2110]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
2088 ret->options = OPT_PROTO_CHAT_TOPIC | OPT_PROTO_NO_PASSWORD; |
| 2086 | 2089 ret->name = irc_name; |
| 2090 ret->list_icon = irc_list_icon; | |
| 2091 ret->buddy_menu = irc_buddy_menu; | |
| 2092 ret->user_opts = irc_user_opts; | |
| 2093 ret->login = irc_login; | |
| 2094 ret->close = irc_close; | |
| 2095 ret->send_im = irc_send_im; | |
|
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
2096 ret->chat_info = irc_chat_info; |
| 2086 | 2097 ret->join_chat = irc_join_chat; |
| 2098 ret->chat_leave = irc_chat_leave; | |
| 2099 ret->chat_send = irc_chat_send; | |
| 2100 ret->get_info = irc_get_info; | |
| 2101 ret->set_away = irc_set_away; | |
| 2102 ret->add_buddy = irc_fake_buddy; | |
| 2103 ret->remove_buddy = irc_fake_buddy; | |
| 2104 ret->chat_set_topic = irc_chat_set_topic; | |
| 2105 my_protocol = ret; | |
| 2106 } | |
| 2107 | |
| 2108 #ifndef STATIC | |
| 2109 | |
| 2110 char *gaim_plugin_init(GModule *handle) | |
| 2111 { | |
| 2112 load_protocol(irc_init, sizeof(struct prpl)); | |
| 2113 return NULL; | |
| 2114 } | |
| 2115 | |
| 2116 void gaim_plugin_remove() | |
| 2117 { | |
| 2118 struct prpl *p = find_prpl(PROTO_IRC); | |
| 2119 if (p == my_protocol) | |
| 2120 unload_protocol(p); | |
| 2121 } | |
| 2122 | |
| 2123 char *name() | |
| 2124 { | |
| 2125 return "IRC"; | |
| 2126 } | |
| 2127 | |
| 2128 char *description() | |
| 2129 { | |
|
2162
a464da684307
[gaim-migrate @ 2172]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2154
diff
changeset
|
2130 return PRPL_DESC("IRC"); |
| 2086 | 2131 } |
| 2132 | |
| 2133 #endif |
