Mercurial > pidgin
annotate src/protocols/irc/irc.c @ 13967:99b9b58b19dd
[gaim-migrate @ 16523]
Fix a crazy MSN crash. Basically it's possible to have more than one
slplink associated with a given switchboard, but our code did not
allow for that. I think it happens when you're in a multi-user
chat and you do stuff with multiple users that involves slplinks.
Like maybe file transfer and buddy icon related stuff.
Tracking this down took an ungodly amount of time, but thanks to
Meebo for letting me do it :-)
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Thu, 20 Jul 2006 07:31:15 +0000 |
parents | 4bfb720a8fc2 |
children | 10e8eb6a4910 |
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" |
9943 | 36 #include "version.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); |
9953 | 43 static void irc_blist_emblems(GaimBuddy *b, const char **se, const char **sw, const char **nw, const char **ne); |
9951 | 44 static GList *irc_status_types(GaimAccount *account); |
9015 | 45 static GList *irc_actions(GaimPlugin *plugin, gpointer context); |
6333 | 46 /* static GList *irc_chat_info(GaimConnection *gc); */ |
11837 | 47 static void irc_login(GaimAccount *account); |
10365 | 48 static void irc_login_cb_ssl(gpointer data, GaimSslConnection *gsc, GaimInputCondition cond); |
6333 | 49 static void irc_login_cb(gpointer data, gint source, GaimInputCondition cond); |
10365 | 50 static void irc_ssl_connect_failure(GaimSslConnection *gsc, GaimSslErrorType error, gpointer data); |
6333 | 51 static void irc_close(GaimConnection *gc); |
12216 | 52 static int irc_im_send(GaimConnection *gc, const char *who, const char *what, GaimMessageFlags flags); |
53 static int irc_chat_send(GaimConnection *gc, int id, const char *what, GaimMessageFlags flags); | |
6333 | 54 static void irc_chat_join (GaimConnection *gc, GHashTable *data); |
55 static void irc_input_cb(gpointer data, gint source, GaimInputCondition cond); | |
10365 | 56 static void irc_input_cb_ssl(gpointer data, GaimSslConnection *gsc, GaimInputCondition cond); |
3751 | 57 |
7711 | 58 static guint irc_nick_hash(const char *nick); |
59 static gboolean irc_nick_equal(const char *nick1, const char *nick2); | |
60 static void irc_buddy_free(struct irc_buddy *ib); | |
61 | |
62 static GaimPlugin *_irc_plugin = NULL; | |
63 | |
64 static const char *status_chars = "@+%&"; | |
65 | |
9015 | 66 static void irc_view_motd(GaimPluginAction *action) |
7148 | 67 { |
9015 | 68 GaimConnection *gc = (GaimConnection *) action->context; |
7148 | 69 struct irc_conn *irc; |
70 char *title; | |
71 | |
72 if (gc == NULL || gc->proto_data == NULL) { | |
73 gaim_debug(GAIM_DEBUG_ERROR, "irc", "got MOTD request for NULL gc\n"); | |
74 return; | |
75 } | |
76 irc = gc->proto_data; | |
77 if (irc->motd == NULL) { | |
78 gaim_notify_error(gc, _("Error displaying MOTD"), _("No MOTD available"), | |
79 _("There is no MOTD associated with this connection.")); | |
80 return; | |
81 } | |
82 title = g_strdup_printf(_("MOTD for %s"), irc->server); | |
83 gaim_notify_formatted(gc, title, title, NULL, irc->motd->str, NULL, NULL); | |
84 } | |
85 | |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
86 static int do_send(struct irc_conn *irc, const char *buf, gsize len) |
3751 | 87 { |
9440 | 88 int ret; |
89 | |
10365 | 90 if (irc->gsc) { |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
91 ret = gaim_ssl_write(irc->gsc, buf, len); |
10365 | 92 } else { |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
93 ret = write(irc->fd, buf, len); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
94 } |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
95 |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
96 return ret; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
97 } |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
98 |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
99 static void |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
100 irc_send_cb(gpointer data, gint source, GaimInputCondition cond) |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
101 { |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
102 struct irc_conn *irc = data; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
103 int ret, writelen; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
104 |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
105 writelen = gaim_circ_buffer_get_max_read(irc->outbuf); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
106 |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
107 if (writelen == 0) { |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
108 gaim_input_remove(irc->writeh); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
109 irc->writeh = 0; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
110 return; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
111 } |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
112 |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
113 ret = do_send(irc, irc->outbuf->outptr, writelen); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
114 |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
115 if (ret < 0 && errno == EAGAIN) |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
116 return; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
117 else if (ret <= 0) { |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
118 gaim_connection_error(gaim_account_get_connection(irc->account), |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
119 _("Server has disconnected")); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
120 return; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
121 } |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
122 |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
123 gaim_circ_buffer_mark_read(irc->outbuf, ret); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
124 |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
125 #if 0 |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
126 /* We *could* try to write more if we wrote it all */ |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
127 if (ret == write_len) { |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
128 irc_send_cb(data, source, cond); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
129 } |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
130 #endif |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
131 } |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
132 |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
133 int irc_send(struct irc_conn *irc, const char *buf) |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
134 { |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
135 int ret, buflen = strlen(buf); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
136 |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
137 /* If we're not buffering writes, try to send immediately */ |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
138 if (!irc->writeh) |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
139 ret = do_send(irc, buf, buflen); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
140 else { |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
141 ret = -1; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
142 errno = EAGAIN; |
10365 | 143 } |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
144 |
10365 | 145 /* gaim_debug(GAIM_DEBUG_MISC, "irc", "sent%s: %s", |
146 irc->gsc ? " (ssl)" : "", buf); */ | |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
147 if (ret <= 0 && errno != EAGAIN) { |
9440 | 148 gaim_connection_error(gaim_account_get_connection(irc->account), |
149 _("Server has disconnected")); | |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
150 } else if (ret < buflen) { |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
151 if (ret < 0) |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
152 ret = 0; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
153 if (!irc->writeh) |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
154 irc->writeh = gaim_input_add( |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
155 irc->gsc ? irc->gsc->fd : irc->fd, |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
156 GAIM_INPUT_WRITE, irc_send_cb, irc); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
157 gaim_circ_buffer_append(irc->outbuf, buf + ret, |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
158 buflen - ret); |
10365 | 159 } |
9440 | 160 |
161 return ret; | |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
162 } |
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
163 |
6333 | 164 /* XXX I don't like messing directly with these buddies */ |
165 gboolean irc_blist_timeout(struct irc_conn *irc) | |
2086 | 166 { |
6333 | 167 GString *string = g_string_sized_new(512); |
168 char *list, *buf; | |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
169 |
6333 | 170 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
|
171 |
6333 | 172 list = g_string_free(string, FALSE); |
173 if (!list || !strlen(list)) { | |
174 g_free(list); | |
2137
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
175 return TRUE; |
2086 | 176 } |
4416
8e62cee6d738
[gaim-migrate @ 4689]
Christian Hammond <chipx86@chipx86.com>
parents:
4373
diff
changeset
|
177 |
8038 | 178 buf = irc_format(irc, "vn", "ISON", list); |
6333 | 179 g_free(list); |
180 irc_send(irc, buf); | |
181 g_free(buf); | |
4416
8e62cee6d738
[gaim-migrate @ 4689]
Christian Hammond <chipx86@chipx86.com>
parents:
4373
diff
changeset
|
182 |
2131
acc11216ec5d
[gaim-migrate @ 2141]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
183 return TRUE; |
2086 | 184 } |
185 | |
6333 | 186 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
|
187 { |
6333 | 188 ib->flag = FALSE; |
189 g_string_append_printf(string, "%s ", name); | |
3511 | 190 } |
191 | |
9553 | 192 static void irc_ison_one(struct irc_conn *irc, struct irc_buddy *ib) |
193 { | |
194 char *buf; | |
195 | |
196 ib->flag = FALSE; | |
197 buf = irc_format(irc, "vn", "ISON", ib->name); | |
198 irc_send(irc, buf); | |
199 g_free(buf); | |
200 } | |
201 | |
202 | |
6695 | 203 static const char *irc_blist_icon(GaimAccount *a, GaimBuddy *b) |
3029 | 204 { |
6333 | 205 return "irc"; |
2339
9bda60d2d2e6
[gaim-migrate @ 2352]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2331
diff
changeset
|
206 } |
9bda60d2d2e6
[gaim-migrate @ 2352]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2331
diff
changeset
|
207 |
9953 | 208 static void irc_blist_emblems(GaimBuddy *b, const char **se, const char **sw, const char **nw, const char **ne) |
3751 | 209 { |
10244 | 210 GaimPresence *presence = gaim_buddy_get_presence(b); |
211 | |
212 if (gaim_presence_is_online(presence) == FALSE) { | |
6333 | 213 *se = "offline"; |
10244 | 214 } |
2086 | 215 } |
216 | |
9944 | 217 static GList *irc_status_types(GaimAccount *account) |
2086 | 218 { |
9944 | 219 GaimStatusType *type; |
220 GList *types = NULL; | |
221 | |
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12323
diff
changeset
|
222 type = gaim_status_type_new(GAIM_STATUS_AVAILABLE, NULL, NULL, TRUE); |
9944 | 223 types = g_list_append(types, type); |
224 | |
225 type = gaim_status_type_new_with_attrs( | |
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12323
diff
changeset
|
226 GAIM_STATUS_AWAY, NULL, NULL, TRUE, TRUE, FALSE, |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12323
diff
changeset
|
227 "message", _("Message"), gaim_value_new(GAIM_TYPE_STRING), |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12323
diff
changeset
|
228 NULL); |
9944 | 229 types = g_list_append(types, type); |
230 | |
12658 | 231 type = gaim_status_type_new(GAIM_STATUS_OFFLINE, NULL, NULL, TRUE); |
232 types = g_list_append(types, type); | |
233 | |
9944 | 234 return types; |
3452 | 235 } |
236 | |
9015 | 237 static GList *irc_actions(GaimPlugin *plugin, gpointer context) |
7148 | 238 { |
239 GList *list = NULL; | |
9015 | 240 GaimPluginAction *act = NULL; |
7148 | 241 |
9015 | 242 act = gaim_plugin_action_new(_("View MOTD"), irc_view_motd); |
243 list = g_list_append(list, act); | |
7148 | 244 |
245 return list; | |
246 } | |
247 | |
6333 | 248 static GList *irc_chat_join_info(GaimConnection *gc) |
2086 | 249 { |
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
250 GList *m = NULL; |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
251 struct proto_chat_entry *pce; |
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
252 |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
253 pce = g_new0(struct proto_chat_entry, 1); |
7841 | 254 pce->label = _("_Channel:"); |
5234 | 255 pce->identifier = "channel"; |
10954 | 256 pce->required = TRUE; |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
257 m = g_list_append(m, pce); |
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
258 |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
259 pce = g_new0(struct proto_chat_entry, 1); |
7841 | 260 pce->label = _("_Password:"); |
5234 | 261 pce->identifier = "password"; |
6499 | 262 pce->secret = TRUE; |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
263 m = g_list_append(m, pce); |
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
264 |
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
265 return m; |
2086 | 266 } |
267 | |
12323
fc464a0abccc
[gaim-migrate @ 14627]
Richard Laager <rlaager@wiktel.com>
parents:
12216
diff
changeset
|
268 static GHashTable *irc_chat_info_defaults(GaimConnection *gc, const char *chat_name) |
9754 | 269 { |
270 GHashTable *defaults; | |
271 | |
272 defaults = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_free); | |
273 | |
274 if (chat_name != NULL) | |
275 g_hash_table_insert(defaults, "channel", g_strdup(chat_name)); | |
276 | |
277 return defaults; | |
278 } | |
279 | |
11837 | 280 static void irc_login(GaimAccount *account) |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
281 { |
6333 | 282 GaimConnection *gc; |
283 struct irc_conn *irc; | |
10494 | 284 char **userparts; |
6333 | 285 const char *username = gaim_account_get_username(account); |
286 int err; | |
287 | |
288 gc = gaim_account_get_connection(account); | |
8677 | 289 gc->flags |= GAIM_CONNECTION_NO_NEWLINES; |
6333 | 290 |
6752 | 291 if (strpbrk(username, " \t\v\r\n") != NULL) { |
292 gaim_connection_error(gc, _("IRC nicks may not contain whitespace")); | |
293 return; | |
294 } | |
295 | |
6333 | 296 gc->proto_data = irc = g_new0(struct irc_conn, 1); |
10960 | 297 irc->fd = -1; |
6333 | 298 irc->account = account; |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
299 irc->outbuf = gaim_circ_buffer_new(512); |
6333 | 300 |
301 userparts = g_strsplit(username, "@", 2); | |
302 gaim_connection_set_display_name(gc, userparts[0]); | |
303 irc->server = g_strdup(userparts[1]); | |
304 g_strfreev(userparts); | |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
305 |
10159 | 306 irc->buddies = g_hash_table_new_full((GHashFunc)irc_nick_hash, (GEqualFunc)irc_nick_equal, |
6333 | 307 NULL, (GDestroyNotify)irc_buddy_free); |
308 irc->cmds = g_hash_table_new(g_str_hash, g_str_equal); | |
309 irc_cmd_table_build(irc); | |
310 irc->msgs = g_hash_table_new(g_str_hash, g_str_equal); | |
311 irc_msg_table_build(irc); | |
312 | |
10494 | 313 gaim_connection_update_progress(gc, _("Connecting"), 1, 2); |
6333 | 314 |
10365 | 315 if (gaim_account_get_bool(account, "ssl", FALSE)) { |
316 if (gaim_ssl_is_supported()) { | |
317 irc->gsc = gaim_ssl_connect(account, irc->server, | |
318 gaim_account_get_int(account, "port", IRC_DEFAULT_SSL_PORT), | |
319 irc_login_cb_ssl, irc_ssl_connect_failure, gc); | |
320 } else { | |
321 gaim_connection_error(gc, _("SSL support unavailable")); | |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
322 return; |
10365 | 323 } |
324 } | |
325 | |
326 if (!irc->gsc) { | |
327 | |
328 err = gaim_proxy_connect(account, irc->server, | |
6333 | 329 gaim_account_get_int(account, "port", IRC_DEFAULT_PORT), |
330 irc_login_cb, gc); | |
331 | |
10555 | 332 if (err || !gaim_account_get_connection(account)) { |
10365 | 333 gaim_connection_error(gc, _("Couldn't create socket")); |
334 return; | |
335 } | |
336 } | |
337 } | |
338 | |
339 static gboolean do_login(GaimConnection *gc) { | |
340 char *buf; | |
341 char hostname[256]; | |
342 const char *username, *realname; | |
343 struct irc_conn *irc = gc->proto_data; | |
10740 | 344 const char *pass = gaim_connection_get_password(gc); |
10365 | 345 |
10555 | 346 if (pass && *pass) { |
347 buf = irc_format(irc, "vv", "PASS", pass); | |
10365 | 348 if (irc_send(irc, buf) < 0) { |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
349 /* gaim_connection_error(gc, "Error sending password"); */ |
10903 | 350 g_free(buf); |
10365 | 351 return FALSE; |
352 } | |
353 g_free(buf); | |
354 } | |
355 | |
356 gethostname(hostname, sizeof(hostname)); | |
357 hostname[sizeof(hostname) - 1] = '\0'; | |
358 username = gaim_account_get_string(irc->account, "username", ""); | |
359 realname = gaim_account_get_string(irc->account, "realname", ""); | |
360 buf = irc_format(irc, "vvvv:", "USER", strlen(username) ? username : g_get_user_name(), hostname, irc->server, | |
361 strlen(realname) ? realname : IRC_DEFAULT_ALIAS); | |
362 if (irc_send(irc, buf) < 0) { | |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
363 /* gaim_connection_error(gc, "Error registering with server");*/ |
10903 | 364 g_free(buf); |
10365 | 365 return FALSE; |
366 } | |
367 g_free(buf); | |
368 buf = irc_format(irc, "vn", "NICK", gaim_connection_get_display_name(gc)); | |
369 if (irc_send(irc, buf) < 0) { | |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
370 /* gaim_connection_error(gc, "Error sending nickname");*/ |
10903 | 371 g_free(buf); |
10365 | 372 return FALSE; |
373 } | |
374 g_free(buf); | |
375 | |
376 return TRUE; | |
377 } | |
378 | |
379 static void irc_login_cb_ssl(gpointer data, GaimSslConnection *gsc, | |
380 GaimInputCondition cond) | |
381 { | |
382 GaimConnection *gc = data; | |
383 struct irc_conn *irc = gc->proto_data; | |
384 | |
385 if(!g_list_find(gaim_connections_get_all(), gc)) { | |
386 gaim_ssl_close(gsc); | |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
387 return; |
6333 | 388 } |
10365 | 389 |
390 irc->gsc = gsc; | |
391 | |
392 if (do_login(gc)) { | |
393 gaim_ssl_input_add(gsc, irc_input_cb_ssl, gc); | |
394 } | |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
395 } |
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
396 |
6333 | 397 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
|
398 { |
6333 | 399 GaimConnection *gc = data; |
400 struct irc_conn *irc = gc->proto_data; | |
401 GList *connections = gaim_connections_get_all(); | |
402 | |
8778 | 403 if (source < 0) { |
404 gaim_connection_error(gc, _("Couldn't connect to host")); | |
6333 | 405 return; |
8778 | 406 } |
6333 | 407 |
408 if (!g_list_find(connections, gc)) { | |
409 close(source); | |
410 return; | |
411 } | |
412 | |
413 irc->fd = source; | |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
414 |
10365 | 415 if (do_login(gc)) { |
416 gc->inpa = gaim_input_add(irc->fd, GAIM_INPUT_READ, irc_input_cb, gc); | |
417 } | |
418 } | |
419 | |
420 static void | |
421 irc_ssl_connect_failure(GaimSslConnection *gsc, GaimSslErrorType error, | |
422 gpointer data) | |
423 { | |
424 GaimConnection *gc = data; | |
425 struct irc_conn *irc = gc->proto_data; | |
426 | |
427 switch(error) { | |
428 case GAIM_SSL_CONNECT_FAILED: | |
429 gaim_connection_error(gc, _("Connection Failed")); | |
430 break; | |
431 case GAIM_SSL_HANDSHAKE_FAILED: | |
432 gaim_connection_error(gc, _("SSL Handshake Failed")); | |
433 break; | |
6333 | 434 } |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
435 |
10365 | 436 irc->gsc = NULL; |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
437 } |
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
438 |
6333 | 439 static void irc_close(GaimConnection *gc) |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
440 { |
6333 | 441 struct irc_conn *irc = gc->proto_data; |
442 | |
6752 | 443 if (irc == NULL) |
444 return; | |
445 | |
6333 | 446 irc_cmd_quit(irc, "quit", NULL, NULL); |
447 | |
448 if (gc->inpa) | |
9441 | 449 gaim_input_remove(gc->inpa); |
6333 | 450 |
451 g_free(irc->inbuf); | |
10365 | 452 if (irc->gsc) { |
453 gaim_ssl_close(irc->gsc); | |
454 } else if (irc->fd > 0) { | |
455 close(irc->fd); | |
456 } | |
6333 | 457 if (irc->timer) |
8287
ef881489396e
[gaim-migrate @ 9011]
Christian Hammond <chipx86@chipx86.com>
parents:
8170
diff
changeset
|
458 gaim_timeout_remove(irc->timer); |
6333 | 459 g_hash_table_destroy(irc->cmds); |
460 g_hash_table_destroy(irc->msgs); | |
10504 | 461 g_hash_table_destroy(irc->buddies); |
6333 | 462 if (irc->motd) |
463 g_string_free(irc->motd, TRUE); | |
464 g_free(irc->server); | |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
465 |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
466 if (irc->writeh) |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
467 gaim_input_remove(irc->writeh); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
468 |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
469 gaim_circ_buffer_destroy(irc->outbuf); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
470 |
6333 | 471 g_free(irc); |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
472 } |
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
473 |
12216 | 474 static int irc_im_send(GaimConnection *gc, const char *who, const char *what, GaimMessageFlags flags) |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
475 { |
6333 | 476 struct irc_conn *irc = gc->proto_data; |
12216 | 477 char *plain; |
6333 | 478 const char *args[2]; |
479 | |
7711 | 480 if (strchr(status_chars, *who) != NULL) |
6333 | 481 args[0] = who + 1; |
482 else | |
483 args[0] = who; | |
12216 | 484 |
485 plain = gaim_unescape_html(what); | |
486 args[1] = plain; | |
9442 | 487 |
6333 | 488 irc_cmd_privmsg(irc, "msg", NULL, args); |
12216 | 489 g_free(plain); |
6333 | 490 return 1; |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
491 } |
2086 | 492 |
6333 | 493 static void irc_get_info(GaimConnection *gc, const char *who) |
2086 | 494 { |
6333 | 495 struct irc_conn *irc = gc->proto_data; |
10618
9eb3b224face
[gaim-migrate @ 12083]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10555
diff
changeset
|
496 const char *args[2]; |
6333 | 497 args[0] = who; |
10624 | 498 args[1] = NULL; |
6333 | 499 irc_cmd_whois(irc, "whois", NULL, args); |
500 } | |
501 | |
9944 | 502 static void irc_set_status(GaimAccount *account, GaimStatus *status) |
6333 | 503 { |
9944 | 504 GaimConnection *gc = gaim_account_get_connection(account); |
13437
4bfb720a8fc2
[gaim-migrate @ 15812]
Richard Laager <rlaager@wiktel.com>
parents:
13296
diff
changeset
|
505 struct irc_conn *irc; |
6333 | 506 const char *args[1]; |
9944 | 507 const char *status_id = gaim_status_get_id(status); |
2086 | 508 |
13437
4bfb720a8fc2
[gaim-migrate @ 15812]
Richard Laager <rlaager@wiktel.com>
parents:
13296
diff
changeset
|
509 g_return_if_fail(gc != NULL); |
4bfb720a8fc2
[gaim-migrate @ 15812]
Richard Laager <rlaager@wiktel.com>
parents:
13296
diff
changeset
|
510 irc = gc->proto_data; |
10646 | 511 |
10504 | 512 if (!gaim_status_is_active(status)) |
513 return; | |
514 | |
515 args[0] = NULL; | |
516 | |
11718 | 517 if (!strcmp(status_id, "away")) { |
9944 | 518 args[0] = gaim_status_get_attr_string(status, "message"); |
12001 | 519 if ((args[0] == NULL) || (*args[0] == '\0')) |
520 args[0] = _("Away"); | |
10646 | 521 irc_cmd_away(irc, "away", NULL, args); |
12210 | 522 } else if (!strcmp(status_id, "available")) { |
523 irc_cmd_away(irc, "back", NULL, args); | |
10646 | 524 } |
4916 | 525 } |
526 | |
9285 | 527 static void irc_add_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) |
3029 | 528 { |
6333 | 529 struct irc_conn *irc = (struct irc_conn *)gc->proto_data; |
530 struct irc_buddy *ib = g_new0(struct irc_buddy, 1); | |
9285 | 531 ib->name = g_strdup(buddy->name); |
6333 | 532 g_hash_table_insert(irc->buddies, ib->name, ib); |
9238 | 533 |
9553 | 534 /* if the timer isn't set, this is during signon, so we don't want to flood |
535 * ourself off with ISON's, so we don't, but after that we want to know when | |
536 * someone's online asap */ | |
537 if (irc->timer) | |
538 irc_ison_one(irc, ib); | |
3029 | 539 } |
3622 | 540 |
9285 | 541 static void irc_remove_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) |
6333 | 542 { |
543 struct irc_conn *irc = (struct irc_conn *)gc->proto_data; | |
9285 | 544 g_hash_table_remove(irc->buddies, buddy->name); |
3616 | 545 } |
4514
7521e29658bc
[gaim-migrate @ 4792]
Christian Hammond <chipx86@chipx86.com>
parents:
4509
diff
changeset
|
546 |
10365 | 547 static void read_input(struct irc_conn *irc, int len) |
6333 | 548 { |
549 char *cur, *end; | |
6369 | 550 |
6333 | 551 irc->inbufused += len; |
552 irc->inbuf[irc->inbufused] = '\0'; | |
3616 | 553 |
8156 | 554 cur = irc->inbuf; |
12752 | 555 |
556 /* This is a hack to work around the fact that marv gets messages | |
557 * with null bytes in them while using some weird irc server at work | |
558 */ | |
559 while ((cur < (irc->inbuf + irc->inbufused)) && !*cur) | |
560 cur++; | |
561 | |
8156 | 562 while (cur < irc->inbuf + irc->inbufused && |
563 ((end = strstr(cur, "\r\n")) || (end = strstr(cur, "\n")))) { | |
564 int step = (*end == '\r' ? 2 : 1); | |
6333 | 565 *end = '\0'; |
566 irc_parse_msg(irc, cur); | |
8156 | 567 cur = end + step; |
6333 | 568 } |
569 if (cur != irc->inbuf + irc->inbufused) { /* leftover */ | |
570 irc->inbufused -= (cur - irc->inbuf); | |
571 memmove(irc->inbuf, cur, irc->inbufused); | |
572 } else { | |
573 irc->inbufused = 0; | |
574 } | |
3616 | 575 } |
576 | |
10365 | 577 static void irc_input_cb_ssl(gpointer data, GaimSslConnection *gsc, |
578 GaimInputCondition cond) | |
579 { | |
580 | |
581 GaimConnection *gc = data; | |
582 struct irc_conn *irc = gc->proto_data; | |
583 int len; | |
584 | |
585 if(!g_list_find(gaim_connections_get_all(), gc)) { | |
586 gaim_ssl_close(gsc); | |
587 return; | |
588 } | |
589 | |
590 if (irc->inbuflen < irc->inbufused + IRC_INITIAL_BUFSIZE) { | |
591 irc->inbuflen += IRC_INITIAL_BUFSIZE; | |
592 irc->inbuf = g_realloc(irc->inbuf, irc->inbuflen); | |
593 } | |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
594 |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
595 len = gaim_ssl_read(gsc, irc->inbuf + irc->inbufused, IRC_INITIAL_BUFSIZE - 1); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
596 |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
597 if (len < 0 && errno == EAGAIN) { |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
598 /* Try again later */ |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
599 return; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
600 } else if (len < 0) { |
10365 | 601 gaim_connection_error(gc, _("Read error")); |
602 return; | |
603 } else if (len == 0) { | |
604 gaim_connection_error(gc, _("Server has disconnected")); | |
605 return; | |
606 } | |
607 | |
608 read_input(irc, len); | |
609 } | |
610 | |
611 static void irc_input_cb(gpointer data, gint source, GaimInputCondition cond) | |
612 { | |
613 GaimConnection *gc = data; | |
614 struct irc_conn *irc = gc->proto_data; | |
615 int len; | |
616 | |
617 if (irc->inbuflen < irc->inbufused + IRC_INITIAL_BUFSIZE) { | |
618 irc->inbuflen += IRC_INITIAL_BUFSIZE; | |
619 irc->inbuf = g_realloc(irc->inbuf, irc->inbuflen); | |
620 } | |
621 | |
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
622 len = read(irc->fd, irc->inbuf + irc->inbufused, IRC_INITIAL_BUFSIZE - 1); |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
623 if (len < 0 && errno == EAGAIN) { |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
624 return; |
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
625 } else if (len < 0) { |
10365 | 626 gaim_connection_error(gc, _("Read error")); |
627 return; | |
628 } else if (len == 0) { | |
629 gaim_connection_error(gc, _("Server has disconnected")); | |
630 return; | |
631 } | |
632 | |
633 read_input(irc, len); | |
634 } | |
635 | |
6333 | 636 static void irc_chat_join (GaimConnection *gc, GHashTable *data) |
637 { | |
638 struct irc_conn *irc = gc->proto_data; | |
639 const char *args[2]; | |
3616 | 640 |
6333 | 641 args[0] = g_hash_table_lookup(data, "channel"); |
642 args[1] = g_hash_table_lookup(data, "password"); | |
643 irc_cmd_join(irc, "join", NULL, args); | |
3622 | 644 } |
645 | |
9917 | 646 static char *irc_get_chat_name(GHashTable *data) { |
647 return g_strdup(g_hash_table_lookup(data, "channel")); | |
648 } | |
649 | |
6333 | 650 static void irc_chat_invite(GaimConnection *gc, int id, const char *message, const char *name) |
3751 | 651 { |
6333 | 652 struct irc_conn *irc = gc->proto_data; |
653 GaimConversation *convo = gaim_find_chat(gc, id); | |
654 const char *args[2]; | |
3751 | 655 |
6333 | 656 if (!convo) { |
657 gaim_debug(GAIM_DEBUG_ERROR, "irc", "Got chat invite request for bogus chat\n"); | |
658 return; | |
659 } | |
660 args[0] = name; | |
661 args[1] = gaim_conversation_get_name(convo); | |
662 irc_cmd_invite(irc, "invite", gaim_conversation_get_name(convo), args); | |
3707 | 663 } |
664 | |
6333 | 665 |
666 static void irc_chat_leave (GaimConnection *gc, int id) | |
3707 | 667 { |
6333 | 668 struct irc_conn *irc = gc->proto_data; |
669 GaimConversation *convo = gaim_find_chat(gc, id); | |
670 const char *args[2]; | |
5298 | 671 |
6333 | 672 if (!convo) |
673 return; | |
3735 | 674 |
6333 | 675 args[0] = gaim_conversation_get_name(convo); |
676 args[1] = NULL; | |
677 irc_cmd_part(irc, "part", gaim_conversation_get_name(convo), args); | |
678 serv_got_chat_left(gc, id); | |
3735 | 679 } |
680 | |
12216 | 681 static int irc_chat_send(GaimConnection *gc, int id, const char *what, GaimMessageFlags flags) |
3735 | 682 { |
6333 | 683 struct irc_conn *irc = gc->proto_data; |
684 GaimConversation *convo = gaim_find_chat(gc, id); | |
685 const char *args[2]; | |
8163 | 686 char *tmp; |
6333 | 687 |
688 if (!convo) { | |
689 gaim_debug(GAIM_DEBUG_ERROR, "irc", "chat send on nonexistent chat\n"); | |
690 return -EINVAL; | |
691 } | |
9130 | 692 #if 0 |
6333 | 693 if (*what == '/') { |
694 return irc_parse_cmd(irc, convo->name, what + 1); | |
695 } | |
9130 | 696 #endif |
12216 | 697 tmp = gaim_unescape_html(what); |
6333 | 698 args[0] = convo->name; |
12216 | 699 args[1] = tmp; |
6333 | 700 |
701 irc_cmd_privmsg(irc, "msg", NULL, args); | |
8163 | 702 |
12216 | 703 serv_got_chat_in(gc, id, gaim_connection_get_display_name(gc), 0, what, time(NULL)); |
8163 | 704 g_free(tmp); |
6333 | 705 return 0; |
3707 | 706 } |
707 | |
6333 | 708 static guint irc_nick_hash(const char *nick) |
709 { | |
710 char *lc; | |
711 guint bucket; | |
6270
1bf6fd117797
[gaim-migrate @ 6767]
Christian Hammond <chipx86@chipx86.com>
parents:
6240
diff
changeset
|
712 |
6333 | 713 lc = g_utf8_strdown(nick, -1); |
714 bucket = g_str_hash(lc); | |
715 g_free(lc); | |
6270
1bf6fd117797
[gaim-migrate @ 6767]
Christian Hammond <chipx86@chipx86.com>
parents:
6240
diff
changeset
|
716 |
6333 | 717 return bucket; |
3029 | 718 } |
719 | |
6333 | 720 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
|
721 { |
6333 | 722 return (gaim_utf8_strcasecmp(nick1, nick2) == 0); |
2619
536198196dc6
[gaim-migrate @ 2632]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2617
diff
changeset
|
723 } |
536198196dc6
[gaim-migrate @ 2632]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2617
diff
changeset
|
724 |
6333 | 725 static void irc_buddy_free(struct irc_buddy *ib) |
2619
536198196dc6
[gaim-migrate @ 2632]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2617
diff
changeset
|
726 { |
6333 | 727 g_free(ib->name); |
728 g_free(ib); | |
2619
536198196dc6
[gaim-migrate @ 2632]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2617
diff
changeset
|
729 } |
536198196dc6
[gaim-migrate @ 2632]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2617
diff
changeset
|
730 |
9154 | 731 static void irc_chat_set_topic(GaimConnection *gc, int id, const char *topic) |
732 { | |
733 char *buf; | |
734 const char *name = NULL; | |
735 struct irc_conn *irc; | |
736 | |
737 irc = gc->proto_data; | |
738 name = gaim_conversation_get_name(gaim_find_chat(gc, id)); | |
739 | |
740 if (name == NULL) | |
741 return; | |
742 | |
743 buf = irc_format(irc, "vt:", "TOPIC", name, topic); | |
744 irc_send(irc, buf); | |
745 g_free(buf); | |
746 } | |
747 | |
8114 | 748 static GaimRoomlist *irc_roomlist_get_list(GaimConnection *gc) |
749 { | |
750 struct irc_conn *irc; | |
751 GList *fields = NULL; | |
752 GaimRoomlistField *f; | |
8352 | 753 char *buf; |
8114 | 754 |
755 irc = gc->proto_data; | |
756 | |
757 if (irc->roomlist) | |
758 gaim_roomlist_unref(irc->roomlist); | |
759 | |
760 irc->roomlist = gaim_roomlist_new(gaim_connection_get_account(gc)); | |
761 | |
762 f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_STRING, "", "channel", TRUE); | |
763 fields = g_list_append(fields, f); | |
764 | |
765 f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_INT, _("Users"), "users", FALSE); | |
766 fields = g_list_append(fields, f); | |
767 | |
768 f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_STRING, _("Topic"), "topic", FALSE); | |
769 fields = g_list_append(fields, f); | |
770 | |
771 gaim_roomlist_set_fields(irc->roomlist, fields); | |
772 | |
8352 | 773 buf = irc_format(irc, "v", "LIST"); |
774 irc_send(irc, buf); | |
775 g_free(buf); | |
8114 | 776 |
777 return irc->roomlist; | |
778 } | |
779 | |
780 static void irc_roomlist_cancel(GaimRoomlist *list) | |
781 { | |
782 GaimConnection *gc = gaim_account_get_connection(list->account); | |
783 struct irc_conn *irc; | |
784 | |
785 if (gc == NULL) | |
786 return; | |
787 | |
788 irc = gc->proto_data; | |
789 | |
790 gaim_roomlist_set_in_progress(list, FALSE); | |
791 | |
792 if (irc->roomlist == list) { | |
793 irc->roomlist = NULL; | |
794 gaim_roomlist_unref(list); | |
795 } | |
796 } | |
797 | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
798 static GaimPluginProtocolInfo prpl_info = |
2086 | 799 { |
11500
9fc7d0153332
[gaim-migrate @ 13745]
Richard Laager <rlaager@wiktel.com>
parents:
11454
diff
changeset
|
800 OPT_PROTO_CHAT_TOPIC | OPT_PROTO_PASSWORD_OPTIONAL, |
9475 | 801 NULL, /* user_splits */ |
802 NULL, /* protocol_options */ | |
9951 | 803 NO_BUDDY_ICONS, /* icon_spec */ |
804 irc_blist_icon, /* list_icon */ | |
805 irc_blist_emblems, /* list_emblems */ | |
9475 | 806 NULL, /* status_text */ |
807 NULL, /* tooltip_text */ | |
9951 | 808 irc_status_types, /* away_states */ |
9475 | 809 NULL, /* blist_node_menu */ |
9951 | 810 irc_chat_join_info, /* chat_info */ |
9754 | 811 irc_chat_info_defaults, /* chat_info_defaults */ |
9951 | 812 irc_login, /* login */ |
813 irc_close, /* close */ | |
814 irc_im_send, /* send_im */ | |
9475 | 815 NULL, /* set_info */ |
816 NULL, /* send_typing */ | |
9951 | 817 irc_get_info, /* get_info */ |
818 irc_set_status, /* set_status */ | |
9475 | 819 NULL, /* set_idle */ |
820 NULL, /* change_passwd */ | |
9951 | 821 irc_add_buddy, /* add_buddy */ |
9475 | 822 NULL, /* add_buddies */ |
9951 | 823 irc_remove_buddy, /* remove_buddy */ |
9475 | 824 NULL, /* remove_buddies */ |
9741 | 825 NULL, /* add_permit */ |
826 NULL, /* add_deny */ | |
827 NULL, /* rem_permit */ | |
828 NULL, /* rem_deny */ | |
829 NULL, /* set_permit_deny */ | |
9951 | 830 irc_chat_join, /* join_chat */ |
9475 | 831 NULL, /* reject_chat */ |
9951 | 832 irc_get_chat_name, /* get_chat_name */ |
833 irc_chat_invite, /* chat_invite */ | |
834 irc_chat_leave, /* chat_leave */ | |
9475 | 835 NULL, /* chat_whisper */ |
9951 | 836 irc_chat_send, /* chat_send */ |
12031 | 837 NULL, /* keepalive */ |
9475 | 838 NULL, /* register_user */ |
839 NULL, /* get_cb_info */ | |
840 NULL, /* get_cb_away */ | |
841 NULL, /* alias_buddy */ | |
842 NULL, /* group_buddy */ | |
843 NULL, /* rename_group */ | |
844 NULL, /* buddy_free */ | |
845 NULL, /* convo_closed */ | |
11153 | 846 gaim_normalize_nocase, /* normalize */ |
9475 | 847 NULL, /* set_buddy_icon */ |
848 NULL, /* remove_group */ | |
849 NULL, /* get_cb_real_name */ | |
9951 | 850 irc_chat_set_topic, /* set_chat_topic */ |
9475 | 851 NULL, /* find_blist_chat */ |
852 irc_roomlist_get_list, /* roomlist_get_list */ | |
853 irc_roomlist_cancel, /* roomlist_cancel */ | |
854 NULL, /* roomlist_expand_category */ | |
855 NULL, /* can_receive_file */ | |
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
12130
diff
changeset
|
856 irc_dccsend_send_file, /* send_file */ |
12600
e856f985a0b9
[gaim-migrate @ 14934]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
857 irc_dccsend_new_xfer, /* new_xfer */ |
12645
fc28451f5d96
[gaim-migrate @ 14983]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
858 NULL, /* offline_message */ |
12600
e856f985a0b9
[gaim-migrate @ 14934]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
859 NULL, /* whiteboard_prpl_ops */ |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
860 }; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
861 |
8114 | 862 |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
863 static GaimPluginInfo info = |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
864 { |
9943 | 865 GAIM_PLUGIN_MAGIC, |
866 GAIM_MAJOR_VERSION, | |
867 GAIM_MINOR_VERSION, | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
868 GAIM_PLUGIN_PROTOCOL, /**< type */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
869 NULL, /**< ui_requirement */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
870 0, /**< flags */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
871 NULL, /**< dependencies */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
872 GAIM_PRIORITY_DEFAULT, /**< priority */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
873 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
874 "prpl-irc", /**< id */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
875 "IRC", /**< name */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
876 VERSION, /**< version */ |
6333 | 877 N_("IRC Protocol Plugin"), /** summary */ |
878 N_("The IRC Protocol Plugin that Sucks Less"), /** description */ | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
879 NULL, /**< author */ |
6371
8f94cce8faa5
[gaim-migrate @ 6876]
Christian Hammond <chipx86@chipx86.com>
parents:
6369
diff
changeset
|
880 GAIM_WEBSITE, /**< homepage */ |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
881 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
882 NULL, /**< load */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
883 NULL, /**< unload */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
884 NULL, /**< destroy */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
885 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
886 NULL, /**< ui_info */ |
8993 | 887 &prpl_info, /**< extra_info */ |
11763 | 888 NULL, /**< prefs_info */ |
9015 | 889 irc_actions |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
890 }; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
891 |
6333 | 892 static void _init_plugin(GaimPlugin *plugin) |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
893 { |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5618
diff
changeset
|
894 GaimAccountUserSplit *split; |
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5618
diff
changeset
|
895 GaimAccountOption *option; |
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5618
diff
changeset
|
896 |
6333 | 897 split = gaim_account_user_split_new(_("Server"), IRC_DEFAULT_SERVER, '@'); |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5618
diff
changeset
|
898 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
|
899 |
6459
b52870734c21
[gaim-migrate @ 6968]
Christian Hammond <chipx86@chipx86.com>
parents:
6371
diff
changeset
|
900 option = gaim_account_option_int_new(_("Port"), "port", IRC_DEFAULT_PORT); |
6333 | 901 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
|
902 |
10258 | 903 option = gaim_account_option_string_new(_("Encodings"), "encoding", IRC_DEFAULT_CHARSET); |
6333 | 904 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
|
905 |
7323 | 906 option = gaim_account_option_string_new(_("Username"), "username", ""); |
907 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
908 | |
10002 | 909 option = gaim_account_option_string_new(_("Real name"), "realname", ""); |
910 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
911 | |
11763 | 912 /* |
913 option = gaim_account_option_string_new(_("Quit message"), "quitmsg", IRC_DEFAULT_QUIT); | |
914 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
915 */ | |
916 | |
10365 | 917 option = gaim_account_option_bool_new(_("Use SSL"), "ssl", FALSE); |
918 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
919 | |
6333 | 920 _irc_plugin = plugin; |
9130 | 921 |
11763 | 922 gaim_prefs_remove("/plugins/prpl/irc/quitmsg"); |
923 gaim_prefs_remove("/plugins/prpl/irc"); | |
11073 | 924 |
9130 | 925 irc_register_commands(); |
2086 | 926 } |
927 | |
6333 | 928 GAIM_INIT_PLUGIN(irc, _init_plugin, info); |