Mercurial > pidgin
annotate src/protocols/irc/irc.c @ 9550:de83d2cb87a4
[gaim-migrate @ 10379]
" When unqueuing messages and "sounds while away" is set,
Gaim will play a message receieved for every message
unqueued. If there are a large number of messages, my
SB Audigy tries playing them all and ends up creating a
crackly ugly sound. Friends of mine have complained
about this as well.
This patch fixes that by making sure sounds are
disabled when unqueuing messages. Sounds will be
re-enabled afterwards if necessary.
Something to note is that playing the sounds when
unqueuing messages crashes Gaim on occasion, with about
50% success. After applying this patch, the crashes
stopped. The backtrace isn't particularly
helpful...it's all question marks and valgrind doesn't
say much either. Crash or no crash though, this
eliminates annoying behavior so that is probably more
important.
I originally fixed this for my plugin AutoProfile, but
since they use similar code for queuing messages, it
would be nice if Gaim has it as well :)" --Casey Ho
committer: Tailor Script <tailor@pidgin.im>
| author | Luke Schierer <lschiere@pidgin.im> |
|---|---|
| date | Fri, 16 Jul 2004 14:56:47 +0000 |
| parents | 7a65fdba750f |
| children | 8a64666476e6 |
| rev | line source |
|---|---|
| 6333 | 1 /** |
| 2 * @file irc.c | |
|
6459
b52870734c21
[gaim-migrate @ 6968]
Christian Hammond <chipx86@chipx86.com>
parents:
6371
diff
changeset
|
3 * |
| 6333 | 4 * gaim |
| 2086 | 5 * |
| 8351 | 6 * Copyright (C) 2003, Robbert Haarman <gaim@inglorion.net> |
| 6333 | 7 * Copyright (C) 2003, Ethan Blanton <eblanton@cs.purdue.edu> |
| 8 * Copyright (C) 2000-2003, Rob Flynn <rob@tgflinux.com> | |
| 2086 | 9 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net> |
|
6459
b52870734c21
[gaim-migrate @ 6968]
Christian Hammond <chipx86@chipx86.com>
parents:
6371
diff
changeset
|
10 * |
| 2086 | 11 * This program is free software; you can redistribute it and/or modify |
| 12 * it under the terms of the GNU General Public License as published by | |
| 13 * the Free Software Foundation; either version 2 of the License, or | |
| 14 * (at your option) any later version. | |
| 15 * | |
| 16 * This program is distributed in the hope that it will be useful, | |
| 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 19 * GNU General Public License for more details. | |
| 20 * | |
| 21 * You should have received a copy of the GNU General Public License | |
| 22 * along with this program; if not, write to the Free Software | |
| 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 24 */ | |
| 6333 | 25 |
|
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5791
diff
changeset
|
26 #include "internal.h" |
|
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5791
diff
changeset
|
27 |
|
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5791
diff
changeset
|
28 #include "accountopt.h" |
| 9030 | 29 #include "blist.h" |
| 6333 | 30 #include "conversation.h" |
| 9030 | 31 #include "debug.h" |
| 32 #include "multi.h" | |
| 7148 | 33 #include "notify.h" |
| 9030 | 34 #include "prpl.h" |
| 35 #include "plugin.h" | |
| 6350 | 36 #include "util.h" |
| 9030 | 37 |
| 6333 | 38 #include "irc.h" |
| 4422 | 39 |
| 6333 | 40 static void irc_buddy_append(char *name, struct irc_buddy *ib, GString *string); |
| 2086 | 41 |
| 6695 | 42 static const char *irc_blist_icon(GaimAccount *a, GaimBuddy *b); |
| 43 static void irc_blist_emblems(GaimBuddy *b, char **se, char **sw, char **nw, char **ne); | |
| 6333 | 44 static GList *irc_away_states(GaimConnection *gc); |
| 9015 | 45 static GList *irc_actions(GaimPlugin *plugin, gpointer context); |
| 6333 | 46 /* static GList *irc_chat_info(GaimConnection *gc); */ |
| 47 static void irc_login(GaimAccount *account); | |
| 48 static void irc_login_cb(gpointer data, gint source, GaimInputCondition cond); | |
| 49 static void irc_close(GaimConnection *gc); | |
|
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
50 static int irc_im_send(GaimConnection *gc, const char *who, const char *what, GaimConvImFlags flags); |
| 6333 | 51 static int irc_chat_send(GaimConnection *gc, int id, const char *what); |
| 52 static void irc_chat_join (GaimConnection *gc, GHashTable *data); | |
| 53 static void irc_input_cb(gpointer data, gint source, GaimInputCondition cond); | |
| 3751 | 54 |
| 7711 | 55 static guint irc_nick_hash(const char *nick); |
| 56 static gboolean irc_nick_equal(const char *nick1, const char *nick2); | |
| 57 static void irc_buddy_free(struct irc_buddy *ib); | |
| 58 | |
| 59 static GaimPlugin *_irc_plugin = NULL; | |
| 60 | |
| 61 static const char *status_chars = "@+%&"; | |
| 62 | |
| 9015 | 63 static void irc_view_motd(GaimPluginAction *action) |
| 7148 | 64 { |
| 9015 | 65 GaimConnection *gc = (GaimConnection *) action->context; |
| 7148 | 66 struct irc_conn *irc; |
| 67 char *title; | |
| 68 | |
| 69 if (gc == NULL || gc->proto_data == NULL) { | |
| 70 gaim_debug(GAIM_DEBUG_ERROR, "irc", "got MOTD request for NULL gc\n"); | |
| 71 return; | |
| 72 } | |
| 73 irc = gc->proto_data; | |
| 74 if (irc->motd == NULL) { | |
| 75 gaim_notify_error(gc, _("Error displaying MOTD"), _("No MOTD available"), | |
| 76 _("There is no MOTD associated with this connection.")); | |
| 77 return; | |
| 78 } | |
| 79 title = g_strdup_printf(_("MOTD for %s"), irc->server); | |
| 80 gaim_notify_formatted(gc, title, title, NULL, irc->motd->str, NULL, NULL); | |
| 81 } | |
| 82 | |
| 6333 | 83 int irc_send(struct irc_conn *irc, const char *buf) |
| 3751 | 84 { |
| 9440 | 85 int ret; |
| 86 | |
| 6333 | 87 if (irc->fd < 0) |
| 88 return -1; | |
|
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
89 |
| 6333 | 90 /* gaim_debug(GAIM_DEBUG_MISC, "irc", "sent: %s", buf); */ |
| 9440 | 91 if ((ret = write(irc->fd, buf, strlen(buf))) < 0) |
| 92 gaim_connection_error(gaim_account_get_connection(irc->account), | |
| 93 _("Server has disconnected")); | |
| 94 | |
| 95 return ret; | |
|
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
96 } |
|
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
97 |
| 6333 | 98 /* XXX I don't like messing directly with these buddies */ |
| 99 gboolean irc_blist_timeout(struct irc_conn *irc) | |
| 2086 | 100 { |
| 6333 | 101 GString *string = g_string_sized_new(512); |
| 102 char *list, *buf; | |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
103 |
| 6333 | 104 g_hash_table_foreach(irc->buddies, (GHFunc)irc_buddy_append, (gpointer)string); |
|
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4349
diff
changeset
|
105 |
| 6333 | 106 list = g_string_free(string, FALSE); |
| 107 if (!list || !strlen(list)) { | |
| 108 g_free(list); | |
|
2137
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
109 return TRUE; |
| 2086 | 110 } |
|
4416
8e62cee6d738
[gaim-migrate @ 4689]
Christian Hammond <chipx86@chipx86.com>
parents:
4373
diff
changeset
|
111 |
| 8038 | 112 buf = irc_format(irc, "vn", "ISON", list); |
| 6333 | 113 g_free(list); |
| 114 irc_send(irc, buf); | |
| 115 g_free(buf); | |
|
4416
8e62cee6d738
[gaim-migrate @ 4689]
Christian Hammond <chipx86@chipx86.com>
parents:
4373
diff
changeset
|
116 |
|
2131
acc11216ec5d
[gaim-migrate @ 2141]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
117 return TRUE; |
| 2086 | 118 } |
| 119 | |
| 6333 | 120 static void irc_buddy_append(char *name, struct irc_buddy *ib, GString *string) |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
121 { |
| 6333 | 122 ib->flag = FALSE; |
| 123 g_string_append_printf(string, "%s ", name); | |
| 3511 | 124 } |
| 125 | |
| 6695 | 126 static const char *irc_blist_icon(GaimAccount *a, GaimBuddy *b) |
| 3029 | 127 { |
| 6333 | 128 return "irc"; |
|
2339
9bda60d2d2e6
[gaim-migrate @ 2352]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2331
diff
changeset
|
129 } |
|
9bda60d2d2e6
[gaim-migrate @ 2352]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2331
diff
changeset
|
130 |
| 6695 | 131 static void irc_blist_emblems(GaimBuddy *b, char **se, char **sw, char **nw, char **ne) |
| 3751 | 132 { |
| 6333 | 133 if (b->present == GAIM_BUDDY_OFFLINE) |
| 134 *se = "offline"; | |
| 2086 | 135 } |
| 136 | |
| 6333 | 137 static GList *irc_away_states(GaimConnection *gc) |
| 2086 | 138 { |
| 6333 | 139 return g_list_append(NULL, (gpointer)GAIM_AWAY_CUSTOM); |
| 3452 | 140 } |
| 141 | |
| 9015 | 142 static GList *irc_actions(GaimPlugin *plugin, gpointer context) |
| 7148 | 143 { |
| 144 GList *list = NULL; | |
| 9015 | 145 GaimPluginAction *act = NULL; |
| 7148 | 146 |
| 9015 | 147 act = gaim_plugin_action_new(_("View MOTD"), irc_view_motd); |
| 148 list = g_list_append(list, act); | |
| 7148 | 149 |
| 150 return list; | |
| 151 } | |
| 152 | |
| 9466 | 153 #if 0 |
| 9030 | 154 static GList *irc_blist_node_menu(GaimBlistNode *node) |
| 2086 | 155 { |
| 8351 | 156 GList *m = NULL; |
| 9030 | 157 GaimBlistNodeAction *act; |
| 158 | |
| 8351 | 159 return m; |
| 2086 | 160 } |
| 9466 | 161 #endif |
| 2086 | 162 |
| 6333 | 163 static GList *irc_chat_join_info(GaimConnection *gc) |
| 2086 | 164 { |
|
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
165 GList *m = NULL; |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
166 struct proto_chat_entry *pce; |
|
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
167 |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
168 pce = g_new0(struct proto_chat_entry, 1); |
| 7841 | 169 pce->label = _("_Channel:"); |
| 5234 | 170 pce->identifier = "channel"; |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
171 m = g_list_append(m, pce); |
|
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
172 |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
173 pce = g_new0(struct proto_chat_entry, 1); |
| 7841 | 174 pce->label = _("_Password:"); |
| 5234 | 175 pce->identifier = "password"; |
| 6499 | 176 pce->secret = TRUE; |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
177 m = g_list_append(m, pce); |
|
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
178 |
|
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
179 return m; |
| 2086 | 180 } |
| 181 | |
| 6333 | 182 static void irc_login(GaimAccount *account) |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
183 { |
| 6333 | 184 GaimConnection *gc; |
| 185 struct irc_conn *irc; | |
| 186 char *buf, **userparts; | |
| 187 const char *username = gaim_account_get_username(account); | |
| 188 int err; | |
| 189 | |
| 190 gc = gaim_account_get_connection(account); | |
| 8677 | 191 gc->flags |= GAIM_CONNECTION_NO_NEWLINES; |
| 6333 | 192 |
| 6752 | 193 if (strpbrk(username, " \t\v\r\n") != NULL) { |
| 194 gaim_connection_error(gc, _("IRC nicks may not contain whitespace")); | |
| 195 return; | |
| 196 } | |
| 197 | |
| 6333 | 198 gc->proto_data = irc = g_new0(struct irc_conn, 1); |
| 199 irc->account = account; | |
| 200 | |
| 201 userparts = g_strsplit(username, "@", 2); | |
| 202 gaim_connection_set_display_name(gc, userparts[0]); | |
| 203 irc->server = g_strdup(userparts[1]); | |
| 204 g_strfreev(userparts); | |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
205 |
| 6333 | 206 irc->buddies = g_hash_table_new_full((GHashFunc)irc_nick_hash, (GEqualFunc)irc_nick_equal, |
| 207 NULL, (GDestroyNotify)irc_buddy_free); | |
| 208 irc->cmds = g_hash_table_new(g_str_hash, g_str_equal); | |
| 209 irc_cmd_table_build(irc); | |
| 210 irc->msgs = g_hash_table_new(g_str_hash, g_str_equal); | |
| 211 irc_msg_table_build(irc); | |
| 212 | |
| 213 buf = g_strdup_printf(_("Signon: %s"), username); | |
| 214 gaim_connection_update_progress(gc, buf, 1, 2); | |
| 215 g_free(buf); | |
| 216 | |
| 217 err = gaim_proxy_connect(account, irc->server, | |
| 218 gaim_account_get_int(account, "port", IRC_DEFAULT_PORT), | |
| 219 irc_login_cb, gc); | |
| 220 | |
| 221 if (err || !account->gc) { | |
| 222 gaim_connection_error(gc, _("Couldn't create socket")); | |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
223 return; |
| 6333 | 224 } |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
225 } |
|
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
226 |
| 6333 | 227 static void irc_login_cb(gpointer data, gint source, GaimInputCondition cond) |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
228 { |
| 6333 | 229 GaimConnection *gc = data; |
| 230 struct irc_conn *irc = gc->proto_data; | |
| 231 char hostname[256]; | |
| 232 char *buf; | |
| 7323 | 233 const char *username; |
| 6333 | 234 GList *connections = gaim_connections_get_all(); |
| 235 | |
| 8778 | 236 if (source < 0) { |
| 237 gaim_connection_error(gc, _("Couldn't connect to host")); | |
| 6333 | 238 return; |
| 8778 | 239 } |
| 6333 | 240 |
| 241 if (!g_list_find(connections, gc)) { | |
| 242 close(source); | |
| 243 return; | |
| 244 } | |
| 245 | |
| 246 irc->fd = source; | |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
247 |
| 6333 | 248 if (gc->account->password && *gc->account->password) { |
| 249 buf = irc_format(irc, "vv", "PASS", gc->account->password); | |
| 250 if (irc_send(irc, buf) < 0) { | |
| 251 gaim_connection_error(gc, "Error sending password"); | |
| 252 return; | |
| 253 } | |
| 254 g_free(buf); | |
| 255 } | |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
256 |
| 6333 | 257 gethostname(hostname, sizeof(hostname)); |
| 258 hostname[sizeof(hostname) - 1] = '\0'; | |
| 7323 | 259 username = gaim_account_get_string(irc->account, "username", ""); |
| 260 buf = irc_format(irc, "vvvv:", "USER", strlen(username) ? username : g_get_user_name(), hostname, irc->server, | |
| 6333 | 261 gc->account->alias && *gc->account->alias ? gc->account->alias : IRC_DEFAULT_ALIAS); |
| 262 if (irc_send(irc, buf) < 0) { | |
| 263 gaim_connection_error(gc, "Error registering with server"); | |
| 264 return; | |
| 265 } | |
| 266 g_free(buf); | |
| 267 buf = irc_format(irc, "vn", "NICK", gaim_connection_get_display_name(gc)); | |
| 268 if (irc_send(irc, buf) < 0) { | |
| 269 gaim_connection_error(gc, "Error sending nickname"); | |
| 270 return; | |
| 271 } | |
| 272 g_free(buf); | |
| 273 | |
| 274 gc->inpa = gaim_input_add(irc->fd, GAIM_INPUT_READ, irc_input_cb, gc); | |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
275 } |
|
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
276 |
| 6333 | 277 static void irc_close(GaimConnection *gc) |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
278 { |
| 6333 | 279 struct irc_conn *irc = gc->proto_data; |
| 280 | |
| 6752 | 281 if (irc == NULL) |
| 282 return; | |
| 283 | |
| 6333 | 284 irc_cmd_quit(irc, "quit", NULL, NULL); |
| 285 | |
| 286 if (gc->inpa) | |
| 9441 | 287 gaim_input_remove(gc->inpa); |
| 6333 | 288 |
| 289 g_free(irc->inbuf); | |
| 290 close(irc->fd); | |
| 291 if (irc->timer) | |
|
8287
ef881489396e
[gaim-migrate @ 9011]
Christian Hammond <chipx86@chipx86.com>
parents:
8170
diff
changeset
|
292 gaim_timeout_remove(irc->timer); |
| 6333 | 293 g_hash_table_destroy(irc->cmds); |
| 294 g_hash_table_destroy(irc->msgs); | |
| 295 if (irc->motd) | |
| 296 g_string_free(irc->motd, TRUE); | |
| 297 g_free(irc->server); | |
| 298 g_free(irc); | |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
299 } |
|
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
300 |
|
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
301 static int irc_im_send(GaimConnection *gc, const char *who, const char *what, GaimConvImFlags flags) |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
302 { |
| 6333 | 303 struct irc_conn *irc = gc->proto_data; |
| 304 const char *args[2]; | |
| 305 | |
| 7711 | 306 if (strchr(status_chars, *who) != NULL) |
| 6333 | 307 args[0] = who + 1; |
| 308 else | |
| 309 args[0] = who; | |
| 310 args[1] = what; | |
| 9442 | 311 |
| 6333 | 312 irc_cmd_privmsg(irc, "msg", NULL, args); |
| 313 return 1; | |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
314 } |
| 2086 | 315 |
| 6333 | 316 static void irc_get_info(GaimConnection *gc, const char *who) |
| 2086 | 317 { |
| 6333 | 318 struct irc_conn *irc = gc->proto_data; |
| 319 const char *args[1]; | |
| 320 args[0] = who; | |
| 321 irc_cmd_whois(irc, "whois", NULL, args); | |
| 322 } | |
| 323 | |
| 324 static void irc_set_away(GaimConnection *gc, const char *state, const char *msg) | |
| 325 { | |
| 326 struct irc_conn *irc = gc->proto_data; | |
| 327 const char *args[1]; | |
| 2086 | 328 |
|
4111
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4067
diff
changeset
|
329 if (gc->away) { |
|
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4067
diff
changeset
|
330 g_free(gc->away); |
|
2394
579f8d4347ad
[gaim-migrate @ 2407]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2393
diff
changeset
|
331 gc->away = NULL; |
|
4111
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4067
diff
changeset
|
332 } |
|
2393
a7ecfd3f7714
[gaim-migrate @ 2406]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2382
diff
changeset
|
333 |
| 6333 | 334 if (msg) |
|
4111
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
4067
diff
changeset
|
335 gc->away = g_strdup(msg); |
| 2086 | 336 |
| 6333 | 337 args[0] = msg; |
| 338 irc_cmd_away(irc, "away", NULL, args); | |
| 4916 | 339 } |
| 340 | |
| 9285 | 341 static void irc_add_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) |
| 3029 | 342 { |
| 6333 | 343 struct irc_conn *irc = (struct irc_conn *)gc->proto_data; |
| 344 struct irc_buddy *ib = g_new0(struct irc_buddy, 1); | |
| 9285 | 345 ib->name = g_strdup(buddy->name); |
| 6333 | 346 g_hash_table_insert(irc->buddies, ib->name, ib); |
| 9238 | 347 |
| 348 irc_blist_timeout(irc); | |
| 3029 | 349 } |
| 3622 | 350 |
| 9285 | 351 static void irc_remove_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) |
| 6333 | 352 { |
| 353 struct irc_conn *irc = (struct irc_conn *)gc->proto_data; | |
| 9285 | 354 g_hash_table_remove(irc->buddies, buddy->name); |
| 3616 | 355 } |
|
4514
7521e29658bc
[gaim-migrate @ 4792]
Christian Hammond <chipx86@chipx86.com>
parents:
4509
diff
changeset
|
356 |
| 6333 | 357 static void irc_input_cb(gpointer data, gint source, GaimInputCondition cond) |
| 358 { | |
| 359 GaimConnection *gc = data; | |
| 360 struct irc_conn *irc = gc->proto_data; | |
| 361 char *cur, *end; | |
| 362 int len; | |
| 363 | |
| 364 if (irc->inbuflen < irc->inbufused + IRC_INITIAL_BUFSIZE) { | |
| 365 irc->inbuflen += IRC_INITIAL_BUFSIZE; | |
| 366 irc->inbuf = g_realloc(irc->inbuf, irc->inbuflen); | |
| 3708 | 367 } |
| 3616 | 368 |
| 6333 | 369 if ((len = read(irc->fd, irc->inbuf + irc->inbufused, IRC_INITIAL_BUFSIZE - 1)) < 0) { |
| 7653 | 370 gaim_connection_error(gc, _("Read error")); |
| 6333 | 371 return; |
| 6369 | 372 } else if (len == 0) { |
| 9440 | 373 gaim_connection_error(gc, _("Server has disconnected")); |
| 6369 | 374 return; |
| 6333 | 375 } |
| 6369 | 376 |
| 6333 | 377 irc->inbufused += len; |
| 378 irc->inbuf[irc->inbufused] = '\0'; | |
| 3616 | 379 |
| 8156 | 380 cur = irc->inbuf; |
| 381 while (cur < irc->inbuf + irc->inbufused && | |
| 382 ((end = strstr(cur, "\r\n")) || (end = strstr(cur, "\n")))) { | |
| 383 int step = (*end == '\r' ? 2 : 1); | |
| 6333 | 384 *end = '\0'; |
| 385 irc_parse_msg(irc, cur); | |
| 8156 | 386 cur = end + step; |
| 6333 | 387 } |
| 388 if (cur != irc->inbuf + irc->inbufused) { /* leftover */ | |
| 389 irc->inbufused -= (cur - irc->inbuf); | |
| 390 memmove(irc->inbuf, cur, irc->inbufused); | |
| 391 } else { | |
| 392 irc->inbufused = 0; | |
| 393 } | |
| 3616 | 394 } |
| 395 | |
| 6333 | 396 static void irc_chat_join (GaimConnection *gc, GHashTable *data) |
| 397 { | |
| 398 struct irc_conn *irc = gc->proto_data; | |
| 399 const char *args[2]; | |
| 3616 | 400 |
| 6333 | 401 args[0] = g_hash_table_lookup(data, "channel"); |
| 402 args[1] = g_hash_table_lookup(data, "password"); | |
| 403 irc_cmd_join(irc, "join", NULL, args); | |
| 3622 | 404 } |
| 405 | |
| 6333 | 406 static void irc_chat_invite(GaimConnection *gc, int id, const char *message, const char *name) |
| 3751 | 407 { |
| 6333 | 408 struct irc_conn *irc = gc->proto_data; |
| 409 GaimConversation *convo = gaim_find_chat(gc, id); | |
| 410 const char *args[2]; | |
| 3751 | 411 |
| 6333 | 412 if (!convo) { |
| 413 gaim_debug(GAIM_DEBUG_ERROR, "irc", "Got chat invite request for bogus chat\n"); | |
| 414 return; | |
| 415 } | |
| 416 args[0] = name; | |
| 417 args[1] = gaim_conversation_get_name(convo); | |
| 418 irc_cmd_invite(irc, "invite", gaim_conversation_get_name(convo), args); | |
| 3707 | 419 } |
| 420 | |
| 6333 | 421 |
| 422 static void irc_chat_leave (GaimConnection *gc, int id) | |
| 3707 | 423 { |
| 6333 | 424 struct irc_conn *irc = gc->proto_data; |
| 425 GaimConversation *convo = gaim_find_chat(gc, id); | |
| 426 const char *args[2]; | |
| 5298 | 427 |
| 6333 | 428 if (!convo) |
| 429 return; | |
| 3735 | 430 |
| 6333 | 431 args[0] = gaim_conversation_get_name(convo); |
| 432 args[1] = NULL; | |
| 433 irc_cmd_part(irc, "part", gaim_conversation_get_name(convo), args); | |
| 434 serv_got_chat_left(gc, id); | |
| 3735 | 435 } |
| 436 | |
| 6333 | 437 static int irc_chat_send(GaimConnection *gc, int id, const char *what) |
| 3735 | 438 { |
| 6333 | 439 struct irc_conn *irc = gc->proto_data; |
| 440 GaimConversation *convo = gaim_find_chat(gc, id); | |
| 441 const char *args[2]; | |
| 8163 | 442 char *tmp; |
| 6333 | 443 |
| 444 if (!convo) { | |
| 445 gaim_debug(GAIM_DEBUG_ERROR, "irc", "chat send on nonexistent chat\n"); | |
| 446 return -EINVAL; | |
| 447 } | |
| 9130 | 448 #if 0 |
| 6333 | 449 if (*what == '/') { |
| 450 return irc_parse_cmd(irc, convo->name, what + 1); | |
| 451 } | |
| 9130 | 452 #endif |
| 6333 | 453 args[0] = convo->name; |
| 454 args[1] = what; | |
| 455 | |
| 456 irc_cmd_privmsg(irc, "msg", NULL, args); | |
| 8163 | 457 |
| 458 tmp = gaim_escape_html(what); | |
| 459 serv_got_chat_in(gc, id, gaim_connection_get_display_name(gc), 0, tmp, time(NULL)); | |
| 460 g_free(tmp); | |
| 6333 | 461 return 0; |
| 3707 | 462 } |
| 463 | |
| 6333 | 464 static guint irc_nick_hash(const char *nick) |
| 465 { | |
| 466 char *lc; | |
| 467 guint bucket; | |
|
6270
1bf6fd117797
[gaim-migrate @ 6767]
Christian Hammond <chipx86@chipx86.com>
parents:
6240
diff
changeset
|
468 |
| 6333 | 469 lc = g_utf8_strdown(nick, -1); |
| 470 bucket = g_str_hash(lc); | |
| 471 g_free(lc); | |
|
6270
1bf6fd117797
[gaim-migrate @ 6767]
Christian Hammond <chipx86@chipx86.com>
parents:
6240
diff
changeset
|
472 |
| 6333 | 473 return bucket; |
| 3029 | 474 } |
| 475 | |
| 6333 | 476 static gboolean irc_nick_equal(const char *nick1, const char *nick2) |
|
2619
536198196dc6
[gaim-migrate @ 2632]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2617
diff
changeset
|
477 { |
| 6333 | 478 return (gaim_utf8_strcasecmp(nick1, nick2) == 0); |
|
2619
536198196dc6
[gaim-migrate @ 2632]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2617
diff
changeset
|
479 } |
|
536198196dc6
[gaim-migrate @ 2632]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2617
diff
changeset
|
480 |
| 6333 | 481 static void irc_buddy_free(struct irc_buddy *ib) |
|
2619
536198196dc6
[gaim-migrate @ 2632]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2617
diff
changeset
|
482 { |
| 6333 | 483 g_free(ib->name); |
| 484 g_free(ib); | |
|
2619
536198196dc6
[gaim-migrate @ 2632]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2617
diff
changeset
|
485 } |
|
536198196dc6
[gaim-migrate @ 2632]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2617
diff
changeset
|
486 |
| 9154 | 487 static void irc_chat_set_topic(GaimConnection *gc, int id, const char *topic) |
| 488 { | |
| 489 char *buf; | |
| 490 const char *name = NULL; | |
| 491 struct irc_conn *irc; | |
| 492 | |
| 493 irc = gc->proto_data; | |
| 494 name = gaim_conversation_get_name(gaim_find_chat(gc, id)); | |
| 495 | |
| 496 if (name == NULL) | |
| 497 return; | |
| 498 | |
| 499 buf = irc_format(irc, "vt:", "TOPIC", name, topic); | |
| 500 irc_send(irc, buf); | |
| 501 g_free(buf); | |
| 502 } | |
| 503 | |
| 8114 | 504 static GaimRoomlist *irc_roomlist_get_list(GaimConnection *gc) |
| 505 { | |
| 506 struct irc_conn *irc; | |
| 507 GList *fields = NULL; | |
| 508 GaimRoomlistField *f; | |
| 8352 | 509 char *buf; |
| 8114 | 510 |
| 511 irc = gc->proto_data; | |
| 512 | |
| 513 if (irc->roomlist) | |
| 514 gaim_roomlist_unref(irc->roomlist); | |
| 515 | |
| 516 irc->roomlist = gaim_roomlist_new(gaim_connection_get_account(gc)); | |
| 517 | |
| 518 f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_STRING, "", "channel", TRUE); | |
| 519 fields = g_list_append(fields, f); | |
| 520 | |
| 521 f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_INT, _("Users"), "users", FALSE); | |
| 522 fields = g_list_append(fields, f); | |
| 523 | |
| 524 f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_STRING, _("Topic"), "topic", FALSE); | |
| 525 fields = g_list_append(fields, f); | |
| 526 | |
| 527 gaim_roomlist_set_fields(irc->roomlist, fields); | |
| 528 | |
| 8352 | 529 buf = irc_format(irc, "v", "LIST"); |
| 530 irc_send(irc, buf); | |
| 531 g_free(buf); | |
| 8114 | 532 |
| 533 return irc->roomlist; | |
| 534 } | |
| 535 | |
| 536 static void irc_roomlist_cancel(GaimRoomlist *list) | |
| 537 { | |
| 538 GaimConnection *gc = gaim_account_get_connection(list->account); | |
| 539 struct irc_conn *irc; | |
| 540 | |
| 541 if (gc == NULL) | |
| 542 return; | |
| 543 | |
| 544 irc = gc->proto_data; | |
| 545 | |
| 546 gaim_roomlist_set_in_progress(list, FALSE); | |
| 547 | |
| 548 if (irc->roomlist == list) { | |
| 549 irc->roomlist = NULL; | |
| 550 gaim_roomlist_unref(list); | |
| 551 } | |
| 552 } | |
| 553 | |
|
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
554 static GaimPluginProtocolInfo prpl_info = |
| 2086 | 555 { |
|
8749
d7b8eb1f0a18
[gaim-migrate @ 9504]
Christian Hammond <chipx86@chipx86.com>
parents:
8713
diff
changeset
|
556 GAIM_PRPL_API_VERSION, |
|
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
557 OPT_PROTO_CHAT_TOPIC | OPT_PROTO_PASSWORD_OPTIONAL, |
| 9475 | 558 NULL, /* user_splits */ |
| 559 NULL, /* protocol_options */ | |
| 560 NO_BUDDY_ICONS, /* icon_spec */ | |
| 561 irc_blist_icon, /* list_icon */ | |
| 562 irc_blist_emblems, /* list_emblems */ | |
| 563 NULL, /* status_text */ | |
| 564 NULL, /* tooltip_text */ | |
| 565 irc_away_states, /* away_states */ | |
| 566 NULL, /* blist_node_menu */ | |
| 567 irc_chat_join_info, /* chat_info */ | |
| 568 irc_login, /* login */ | |
| 569 irc_close, /* close */ | |
| 570 irc_im_send, /* send_im */ | |
| 571 NULL, /* set_info */ | |
| 572 NULL, /* send_typing */ | |
| 573 irc_get_info, /* get_info */ | |
| 574 irc_set_away, /* set_away */ | |
| 575 NULL, /* set_idle */ | |
| 576 NULL, /* change_passwd */ | |
| 577 irc_add_buddy, /* add_buddy */ | |
| 578 NULL, /* add_buddies */ | |
| 579 irc_remove_buddy, /* remove_buddy */ | |
| 580 NULL, /* remove_buddies */ | |
| 581 NULL, /* add_permit */ | |
| 582 NULL, /* add_deny */ | |
| 583 NULL, /* rem_permit */ | |
| 584 NULL, /* rem_deny */ | |
| 585 NULL, /* set_permit_deny */ | |
| 586 NULL, /* warn */ | |
| 587 irc_chat_join, /* join_chat */ | |
| 588 NULL, /* reject_chat */ | |
| 589 irc_chat_invite, /* chat_invite */ | |
| 590 irc_chat_leave, /* chat_leave */ | |
| 591 NULL, /* chat_whisper */ | |
| 592 irc_chat_send, /* chat_send */ | |
| 593 NULL, /* keepalive */ | |
| 594 NULL, /* register_user */ | |
| 595 NULL, /* get_cb_info */ | |
| 596 NULL, /* get_cb_away */ | |
| 597 NULL, /* alias_buddy */ | |
| 598 NULL, /* group_buddy */ | |
| 599 NULL, /* rename_group */ | |
| 600 NULL, /* buddy_free */ | |
| 601 NULL, /* convo_closed */ | |
| 602 NULL, /* normalize */ | |
| 603 NULL, /* set_buddy_icon */ | |
| 604 NULL, /* remove_group */ | |
| 605 NULL, /* get_cb_real_name */ | |
| 606 irc_chat_set_topic, /* set_chat_topic */ | |
| 607 NULL, /* find_blist_chat */ | |
| 608 irc_roomlist_get_list, /* roomlist_get_list */ | |
| 609 irc_roomlist_cancel, /* roomlist_cancel */ | |
| 610 NULL, /* roomlist_expand_category */ | |
| 611 NULL, /* can_receive_file */ | |
| 612 irc_dccsend_send_file /* send_file */ | |
|
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
613 }; |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
614 |
| 8114 | 615 |
|
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
616 static GaimPluginInfo info = |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
617 { |
|
8749
d7b8eb1f0a18
[gaim-migrate @ 9504]
Christian Hammond <chipx86@chipx86.com>
parents:
8713
diff
changeset
|
618 GAIM_PLUGIN_API_VERSION, /**< api_version */ |
|
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
619 GAIM_PLUGIN_PROTOCOL, /**< type */ |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
620 NULL, /**< ui_requirement */ |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
621 0, /**< flags */ |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
622 NULL, /**< dependencies */ |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
623 GAIM_PRIORITY_DEFAULT, /**< priority */ |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
624 |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
625 "prpl-irc", /**< id */ |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
626 "IRC", /**< name */ |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
627 VERSION, /**< version */ |
| 6333 | 628 N_("IRC Protocol Plugin"), /** summary */ |
| 629 N_("The IRC Protocol Plugin that Sucks Less"), /** description */ | |
|
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
630 NULL, /**< author */ |
|
6371
8f94cce8faa5
[gaim-migrate @ 6876]
Christian Hammond <chipx86@chipx86.com>
parents:
6369
diff
changeset
|
631 GAIM_WEBSITE, /**< homepage */ |
|
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
632 |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
633 NULL, /**< load */ |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
634 NULL, /**< unload */ |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
635 NULL, /**< destroy */ |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
636 |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
637 NULL, /**< ui_info */ |
| 8993 | 638 &prpl_info, /**< extra_info */ |
| 639 NULL, | |
| 9015 | 640 irc_actions |
|
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
641 }; |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
642 |
| 6333 | 643 static void _init_plugin(GaimPlugin *plugin) |
|
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
644 { |
|
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5618
diff
changeset
|
645 GaimAccountUserSplit *split; |
|
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5618
diff
changeset
|
646 GaimAccountOption *option; |
|
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5618
diff
changeset
|
647 |
| 6333 | 648 split = gaim_account_user_split_new(_("Server"), IRC_DEFAULT_SERVER, '@'); |
|
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5618
diff
changeset
|
649 prpl_info.user_splits = g_list_append(prpl_info.user_splits, split); |
|
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5618
diff
changeset
|
650 |
|
6459
b52870734c21
[gaim-migrate @ 6968]
Christian Hammond <chipx86@chipx86.com>
parents:
6371
diff
changeset
|
651 option = gaim_account_option_int_new(_("Port"), "port", IRC_DEFAULT_PORT); |
| 6333 | 652 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); |
|
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5618
diff
changeset
|
653 |
| 6333 | 654 option = gaim_account_option_string_new(_("Encoding"), "encoding", IRC_DEFAULT_CHARSET); |
| 655 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
|
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
656 |
| 7323 | 657 option = gaim_account_option_string_new(_("Username"), "username", ""); |
| 658 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
| 659 | |
| 6333 | 660 _irc_plugin = plugin; |
| 9130 | 661 |
| 662 irc_register_commands(); | |
| 2086 | 663 } |
| 664 | |
| 6333 | 665 GAIM_INIT_PLUGIN(irc, _init_plugin, info); |
