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