Mercurial > pidgin.yaz
annotate src/protocols/irc/irc.c @ 8351:ffa642240fc1
[gaim-migrate @ 9075]
marv is incredibly patient, waiting a long time for this to go in
you should all be using Jabber for file transfer anyway, but if you're
still stuck in the stone age, now you can transfer files via IRC
committer: Tailor Script <tailor@pidgin.im>
author | Nathan Walp <nwalp@pidgin.im> |
---|---|
date | Fri, 27 Feb 2004 01:45:26 +0000 |
parents | ef881489396e |
children | 77baefe979c6 |
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 |
6333 | 28 #include "plugin.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5791
diff
changeset
|
29 #include "accountopt.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5791
diff
changeset
|
30 #include "multi.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5791
diff
changeset
|
31 #include "prpl.h" |
6333 | 32 #include "conversation.h" |
7148 | 33 #include "notify.h" |
6333 | 34 #include "debug.h" |
35 #include "blist.h" | |
6350 | 36 #include "util.h" |
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); |
7148 | 44 static GList *irc_actions(GaimConnection *gc); |
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 | |
7148 | 62 static void irc_view_motd(GaimConnection *gc) |
63 { | |
64 struct irc_conn *irc; | |
65 char *title; | |
66 | |
67 if (gc == NULL || gc->proto_data == NULL) { | |
68 gaim_debug(GAIM_DEBUG_ERROR, "irc", "got MOTD request for NULL gc\n"); | |
69 return; | |
70 } | |
71 irc = gc->proto_data; | |
72 if (irc->motd == NULL) { | |
73 gaim_notify_error(gc, _("Error displaying MOTD"), _("No MOTD available"), | |
74 _("There is no MOTD associated with this connection.")); | |
75 return; | |
76 } | |
77 title = g_strdup_printf(_("MOTD for %s"), irc->server); | |
78 gaim_notify_formatted(gc, title, title, NULL, irc->motd->str, NULL, NULL); | |
79 } | |
80 | |
6333 | 81 int irc_send(struct irc_conn *irc, const char *buf) |
3751 | 82 { |
6333 | 83 if (irc->fd < 0) |
84 return -1; | |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
85 |
6333 | 86 /* gaim_debug(GAIM_DEBUG_MISC, "irc", "sent: %s", buf); */ |
87 return write(irc->fd, buf, strlen(buf)); | |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
88 } |
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2171
diff
changeset
|
89 |
6333 | 90 /* XXX I don't like messing directly with these buddies */ |
91 gboolean irc_blist_timeout(struct irc_conn *irc) | |
2086 | 92 { |
6333 | 93 GString *string = g_string_sized_new(512); |
94 char *list, *buf; | |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
95 |
6333 | 96 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
|
97 |
6333 | 98 list = g_string_free(string, FALSE); |
99 if (!list || !strlen(list)) { | |
100 g_free(list); | |
2137
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2131
diff
changeset
|
101 return TRUE; |
2086 | 102 } |
4416
8e62cee6d738
[gaim-migrate @ 4689]
Christian Hammond <chipx86@chipx86.com>
parents:
4373
diff
changeset
|
103 |
8038 | 104 buf = irc_format(irc, "vn", "ISON", list); |
6333 | 105 g_free(list); |
106 irc_send(irc, buf); | |
107 g_free(buf); | |
4416
8e62cee6d738
[gaim-migrate @ 4689]
Christian Hammond <chipx86@chipx86.com>
parents:
4373
diff
changeset
|
108 |
2131
acc11216ec5d
[gaim-migrate @ 2141]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
109 return TRUE; |
2086 | 110 } |
111 | |
6333 | 112 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
|
113 { |
6333 | 114 ib->flag = FALSE; |
115 g_string_append_printf(string, "%s ", name); | |
3511 | 116 } |
117 | |
6695 | 118 static const char *irc_blist_icon(GaimAccount *a, GaimBuddy *b) |
3029 | 119 { |
6333 | 120 return "irc"; |
2339
9bda60d2d2e6
[gaim-migrate @ 2352]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2331
diff
changeset
|
121 } |
9bda60d2d2e6
[gaim-migrate @ 2352]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2331
diff
changeset
|
122 |
6695 | 123 static void irc_blist_emblems(GaimBuddy *b, char **se, char **sw, char **nw, char **ne) |
3751 | 124 { |
6333 | 125 if (b->present == GAIM_BUDDY_OFFLINE) |
126 *se = "offline"; | |
2086 | 127 } |
128 | |
6333 | 129 static GList *irc_away_states(GaimConnection *gc) |
2086 | 130 { |
6333 | 131 return g_list_append(NULL, (gpointer)GAIM_AWAY_CUSTOM); |
3452 | 132 } |
133 | |
7148 | 134 static GList *irc_actions(GaimConnection *gc) |
135 { | |
136 struct proto_actions_menu *pam; | |
137 GList *list = NULL; | |
138 | |
139 pam = g_new0(struct proto_actions_menu, 1); | |
140 pam->label = _("View MOTD"); | |
141 pam->callback = irc_view_motd; | |
142 pam->gc = gc; | |
143 list = g_list_append(list, pam); | |
144 | |
145 return list; | |
146 } | |
147 | |
6333 | 148 static GList *irc_buddy_menu(GaimConnection *gc, const char *who) |
2086 | 149 { |
8351 | 150 GList *m = NULL; |
151 struct proto_buddy_menu *pbm; | |
152 | |
153 pbm = g_new0(struct proto_buddy_menu, 1); | |
154 pbm->label = _("Send File"); | |
155 pbm->callback = irc_dccsend_send_ask; | |
156 pbm->gc = gc; | |
157 m = g_list_append(m, pbm); | |
158 | |
159 return m; | |
2086 | 160 } |
161 | |
6333 | 162 static GList *irc_chat_join_info(GaimConnection *gc) |
2086 | 163 { |
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
164 GList *m = NULL; |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
165 struct proto_chat_entry *pce; |
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
166 |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
167 pce = g_new0(struct proto_chat_entry, 1); |
7841 | 168 pce->label = _("_Channel:"); |
5234 | 169 pce->identifier = "channel"; |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
170 m = g_list_append(m, pce); |
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
171 |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
172 pce = g_new0(struct proto_chat_entry, 1); |
7841 | 173 pce->label = _("_Password:"); |
5234 | 174 pce->identifier = "password"; |
6499 | 175 pce->secret = TRUE; |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
176 m = g_list_append(m, pce); |
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
177 |
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
178 return m; |
2086 | 179 } |
180 | |
6333 | 181 static void irc_login(GaimAccount *account) |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
182 { |
6333 | 183 GaimConnection *gc; |
184 struct irc_conn *irc; | |
185 char *buf, **userparts; | |
186 const char *username = gaim_account_get_username(account); | |
187 int err; | |
188 | |
189 gc = gaim_account_get_connection(account); | |
190 | |
6752 | 191 if (strpbrk(username, " \t\v\r\n") != NULL) { |
192 gaim_connection_error(gc, _("IRC nicks may not contain whitespace")); | |
193 return; | |
194 } | |
195 | |
6333 | 196 gc->proto_data = irc = g_new0(struct irc_conn, 1); |
197 irc->account = account; | |
198 | |
199 userparts = g_strsplit(username, "@", 2); | |
200 gaim_connection_set_display_name(gc, userparts[0]); | |
201 irc->server = g_strdup(userparts[1]); | |
202 g_strfreev(userparts); | |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
203 |
6333 | 204 irc->buddies = g_hash_table_new_full((GHashFunc)irc_nick_hash, (GEqualFunc)irc_nick_equal, |
205 NULL, (GDestroyNotify)irc_buddy_free); | |
206 irc->cmds = g_hash_table_new(g_str_hash, g_str_equal); | |
207 irc_cmd_table_build(irc); | |
208 irc->msgs = g_hash_table_new(g_str_hash, g_str_equal); | |
209 irc_msg_table_build(irc); | |
210 | |
211 buf = g_strdup_printf(_("Signon: %s"), username); | |
212 gaim_connection_update_progress(gc, buf, 1, 2); | |
213 g_free(buf); | |
214 | |
215 err = gaim_proxy_connect(account, irc->server, | |
216 gaim_account_get_int(account, "port", IRC_DEFAULT_PORT), | |
217 irc_login_cb, gc); | |
218 | |
219 if (err || !account->gc) { | |
220 gaim_connection_error(gc, _("Couldn't create socket")); | |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
221 return; |
6333 | 222 } |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
223 } |
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
224 |
6333 | 225 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
|
226 { |
6333 | 227 GaimConnection *gc = data; |
228 struct irc_conn *irc = gc->proto_data; | |
229 char hostname[256]; | |
230 char *buf; | |
7323 | 231 const char *username; |
6333 | 232 GList *connections = gaim_connections_get_all(); |
233 | |
234 if (source < 0) | |
235 return; | |
236 | |
237 if (!g_list_find(connections, gc)) { | |
238 close(source); | |
239 return; | |
240 } | |
241 | |
242 irc->fd = source; | |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
243 |
6333 | 244 if (gc->account->password && *gc->account->password) { |
245 buf = irc_format(irc, "vv", "PASS", gc->account->password); | |
246 if (irc_send(irc, buf) < 0) { | |
247 gaim_connection_error(gc, "Error sending password"); | |
248 return; | |
249 } | |
250 g_free(buf); | |
251 } | |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
252 |
6333 | 253 gethostname(hostname, sizeof(hostname)); |
254 hostname[sizeof(hostname) - 1] = '\0'; | |
7323 | 255 username = gaim_account_get_string(irc->account, "username", ""); |
256 buf = irc_format(irc, "vvvv:", "USER", strlen(username) ? username : g_get_user_name(), hostname, irc->server, | |
6333 | 257 gc->account->alias && *gc->account->alias ? gc->account->alias : IRC_DEFAULT_ALIAS); |
258 if (irc_send(irc, buf) < 0) { | |
259 gaim_connection_error(gc, "Error registering with server"); | |
260 return; | |
261 } | |
262 g_free(buf); | |
263 buf = irc_format(irc, "vn", "NICK", gaim_connection_get_display_name(gc)); | |
264 if (irc_send(irc, buf) < 0) { | |
265 gaim_connection_error(gc, "Error sending nickname"); | |
266 return; | |
267 } | |
268 g_free(buf); | |
269 | |
270 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
|
271 } |
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
272 |
6333 | 273 static void irc_close(GaimConnection *gc) |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
274 { |
6333 | 275 struct irc_conn *irc = gc->proto_data; |
276 | |
6752 | 277 if (irc == NULL) |
278 return; | |
279 | |
6333 | 280 irc_cmd_quit(irc, "quit", NULL, NULL); |
281 | |
282 if (gc->inpa) | |
8287
ef881489396e
[gaim-migrate @ 9011]
Christian Hammond <chipx86@chipx86.com>
parents:
8170
diff
changeset
|
283 gaim_timeout_remove(gc->inpa); |
6333 | 284 |
285 g_free(irc->inbuf); | |
286 close(irc->fd); | |
287 if (irc->timer) | |
8287
ef881489396e
[gaim-migrate @ 9011]
Christian Hammond <chipx86@chipx86.com>
parents:
8170
diff
changeset
|
288 gaim_timeout_remove(irc->timer); |
6333 | 289 g_hash_table_destroy(irc->cmds); |
290 g_hash_table_destroy(irc->msgs); | |
291 if (irc->motd) | |
292 g_string_free(irc->motd, TRUE); | |
293 g_free(irc->server); | |
294 g_free(irc); | |
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
295 } |
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
296 |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
297 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
|
298 { |
6333 | 299 struct irc_conn *irc = gc->proto_data; |
300 const char *args[2]; | |
301 | |
7711 | 302 if (strchr(status_chars, *who) != NULL) |
6333 | 303 args[0] = who + 1; |
304 else | |
305 args[0] = who; | |
306 args[1] = what; | |
307 | |
308 if (*what == '/') { | |
309 return irc_parse_cmd(irc, who, what + 1); | |
310 } | |
311 | |
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 | |
6787
faa491042c66
[gaim-migrate @ 7326]
Christian Hammond <chipx86@chipx86.com>
parents:
6752
diff
changeset
|
341 static void irc_add_buddy(GaimConnection *gc, const char *who, 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); | |
345 ib->name = g_strdup(who); | |
346 g_hash_table_insert(irc->buddies, ib->name, ib); | |
3029 | 347 } |
3622 | 348 |
6333 | 349 static void irc_remove_buddy(GaimConnection *gc, const char *who, const char *group) |
350 { | |
351 struct irc_conn *irc = (struct irc_conn *)gc->proto_data; | |
352 g_hash_table_remove(irc->buddies, who); | |
3616 | 353 } |
4514
7521e29658bc
[gaim-migrate @ 4792]
Christian Hammond <chipx86@chipx86.com>
parents:
4509
diff
changeset
|
354 |
3616 | 355 |
6333 | 356 static void irc_input_cb(gpointer data, gint source, GaimInputCondition cond) |
357 { | |
358 GaimConnection *gc = data; | |
359 struct irc_conn *irc = gc->proto_data; | |
360 char *cur, *end; | |
361 int len; | |
362 | |
363 if (irc->inbuflen < irc->inbufused + IRC_INITIAL_BUFSIZE) { | |
364 irc->inbuflen += IRC_INITIAL_BUFSIZE; | |
365 irc->inbuf = g_realloc(irc->inbuf, irc->inbuflen); | |
3708 | 366 } |
3616 | 367 |
6333 | 368 if ((len = read(irc->fd, irc->inbuf + irc->inbufused, IRC_INITIAL_BUFSIZE - 1)) < 0) { |
7653 | 369 gaim_connection_error(gc, _("Read error")); |
6333 | 370 return; |
6369 | 371 } else if (len == 0) { |
372 /* Remote closed the connection, probably */ | |
373 return; | |
6333 | 374 } |
6369 | 375 |
6333 | 376 irc->inbufused += len; |
377 irc->inbuf[irc->inbufused] = '\0'; | |
3616 | 378 |
8156 | 379 cur = irc->inbuf; |
380 while (cur < irc->inbuf + irc->inbufused && | |
381 ((end = strstr(cur, "\r\n")) || (end = strstr(cur, "\n")))) { | |
382 int step = (*end == '\r' ? 2 : 1); | |
6333 | 383 *end = '\0'; |
384 irc_parse_msg(irc, cur); | |
8156 | 385 cur = end + step; |
6333 | 386 } |
387 if (cur != irc->inbuf + irc->inbufused) { /* leftover */ | |
388 irc->inbufused -= (cur - irc->inbuf); | |
389 memmove(irc->inbuf, cur, irc->inbufused); | |
390 } else { | |
391 irc->inbufused = 0; | |
392 } | |
3616 | 393 } |
394 | |
6333 | 395 static void irc_chat_join (GaimConnection *gc, GHashTable *data) |
396 { | |
397 struct irc_conn *irc = gc->proto_data; | |
398 const char *args[2]; | |
3616 | 399 |
6333 | 400 args[0] = g_hash_table_lookup(data, "channel"); |
401 args[1] = g_hash_table_lookup(data, "password"); | |
402 irc_cmd_join(irc, "join", NULL, args); | |
3622 | 403 } |
404 | |
6333 | 405 static void irc_chat_invite(GaimConnection *gc, int id, const char *message, const char *name) |
3751 | 406 { |
6333 | 407 struct irc_conn *irc = gc->proto_data; |
408 GaimConversation *convo = gaim_find_chat(gc, id); | |
409 const char *args[2]; | |
3751 | 410 |
6333 | 411 if (!convo) { |
412 gaim_debug(GAIM_DEBUG_ERROR, "irc", "Got chat invite request for bogus chat\n"); | |
413 return; | |
414 } | |
415 args[0] = name; | |
416 args[1] = gaim_conversation_get_name(convo); | |
417 irc_cmd_invite(irc, "invite", gaim_conversation_get_name(convo), args); | |
3707 | 418 } |
419 | |
6333 | 420 |
421 static void irc_chat_leave (GaimConnection *gc, int id) | |
3707 | 422 { |
6333 | 423 struct irc_conn *irc = gc->proto_data; |
424 GaimConversation *convo = gaim_find_chat(gc, id); | |
425 const char *args[2]; | |
5298 | 426 |
6333 | 427 if (!convo) |
428 return; | |
3735 | 429 |
6333 | 430 args[0] = gaim_conversation_get_name(convo); |
431 args[1] = NULL; | |
432 irc_cmd_part(irc, "part", gaim_conversation_get_name(convo), args); | |
433 serv_got_chat_left(gc, id); | |
3735 | 434 } |
435 | |
6333 | 436 static int irc_chat_send(GaimConnection *gc, int id, const char *what) |
3735 | 437 { |
6333 | 438 struct irc_conn *irc = gc->proto_data; |
439 GaimConversation *convo = gaim_find_chat(gc, id); | |
440 const char *args[2]; | |
8163 | 441 char *tmp; |
6333 | 442 |
443 if (!convo) { | |
444 gaim_debug(GAIM_DEBUG_ERROR, "irc", "chat send on nonexistent chat\n"); | |
445 return -EINVAL; | |
446 } | |
447 | |
448 if (*what == '/') { | |
449 return irc_parse_cmd(irc, convo->name, what + 1); | |
450 } | |
451 | |
452 args[0] = convo->name; | |
453 args[1] = what; | |
454 | |
455 irc_cmd_privmsg(irc, "msg", NULL, args); | |
8163 | 456 |
457 tmp = gaim_escape_html(what); | |
458 serv_got_chat_in(gc, id, gaim_connection_get_display_name(gc), 0, tmp, time(NULL)); | |
459 g_free(tmp); | |
6333 | 460 return 0; |
3707 | 461 } |
462 | |
6333 | 463 static guint irc_nick_hash(const char *nick) |
464 { | |
465 char *lc; | |
466 guint bucket; | |
6270
1bf6fd117797
[gaim-migrate @ 6767]
Christian Hammond <chipx86@chipx86.com>
parents:
6240
diff
changeset
|
467 |
6333 | 468 lc = g_utf8_strdown(nick, -1); |
469 bucket = g_str_hash(lc); | |
470 g_free(lc); | |
6270
1bf6fd117797
[gaim-migrate @ 6767]
Christian Hammond <chipx86@chipx86.com>
parents:
6240
diff
changeset
|
471 |
6333 | 472 return bucket; |
3029 | 473 } |
474 | |
6333 | 475 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
|
476 { |
6333 | 477 return (gaim_utf8_strcasecmp(nick1, nick2) == 0); |
2619
536198196dc6
[gaim-migrate @ 2632]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2617
diff
changeset
|
478 } |
536198196dc6
[gaim-migrate @ 2632]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2617
diff
changeset
|
479 |
6333 | 480 static void irc_buddy_free(struct irc_buddy *ib) |
2619
536198196dc6
[gaim-migrate @ 2632]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2617
diff
changeset
|
481 { |
6333 | 482 g_free(ib->name); |
483 g_free(ib); | |
2619
536198196dc6
[gaim-migrate @ 2632]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2617
diff
changeset
|
484 } |
536198196dc6
[gaim-migrate @ 2632]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2617
diff
changeset
|
485 |
8114 | 486 static GaimRoomlist *irc_roomlist_get_list(GaimConnection *gc) |
487 { | |
488 struct irc_conn *irc; | |
489 GList *fields = NULL; | |
490 GaimRoomlistField *f; | |
491 | |
492 irc = gc->proto_data; | |
493 | |
494 if (irc->roomlist) | |
495 gaim_roomlist_unref(irc->roomlist); | |
496 | |
497 irc->roomlist = gaim_roomlist_new(gaim_connection_get_account(gc)); | |
498 | |
499 f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_STRING, "", "channel", TRUE); | |
500 fields = g_list_append(fields, f); | |
501 | |
502 f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_INT, _("Users"), "users", FALSE); | |
503 fields = g_list_append(fields, f); | |
504 | |
505 f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_STRING, _("Topic"), "topic", FALSE); | |
506 fields = g_list_append(fields, f); | |
507 | |
508 gaim_roomlist_set_fields(irc->roomlist, fields); | |
509 | |
510 irc_cmd_list(irc, "LIST", NULL, NULL); | |
511 | |
512 return irc->roomlist; | |
513 } | |
514 | |
515 static void irc_roomlist_cancel(GaimRoomlist *list) | |
516 { | |
517 GaimConnection *gc = gaim_account_get_connection(list->account); | |
518 struct irc_conn *irc; | |
519 | |
520 if (gc == NULL) | |
521 return; | |
522 | |
523 irc = gc->proto_data; | |
524 | |
525 gaim_roomlist_set_in_progress(list, FALSE); | |
526 | |
527 if (irc->roomlist == list) { | |
528 irc->roomlist = NULL; | |
529 gaim_roomlist_unref(list); | |
530 } | |
531 } | |
532 | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
533 static GaimPluginProtocolInfo prpl_info = |
2086 | 534 { |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
535 OPT_PROTO_CHAT_TOPIC | OPT_PROTO_PASSWORD_OPTIONAL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
536 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
537 NULL, |
8170 | 538 NULL, |
6333 | 539 irc_blist_icon, |
540 irc_blist_emblems, | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
541 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
542 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
543 irc_away_states, |
7148 | 544 irc_actions, |
6350 | 545 irc_buddy_menu, |
6333 | 546 irc_chat_join_info, |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
547 irc_login, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
548 irc_close, |
6333 | 549 irc_im_send, |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
550 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
551 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
552 irc_get_info, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
553 irc_set_away, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
554 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
555 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
556 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
557 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
558 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
559 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
560 irc_add_buddy, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
561 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
562 irc_remove_buddy, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
563 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
564 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
565 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
566 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
567 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
568 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
569 NULL, |
6333 | 570 irc_chat_join, |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
571 irc_chat_invite, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
572 irc_chat_leave, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
573 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
574 irc_chat_send, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
575 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
576 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
577 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
578 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
579 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
580 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
581 NULL, |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
582 NULL, |
6333 | 583 NULL, /*irc_convo_closed,*/ |
8114 | 584 NULL, /* normalize */ |
585 NULL, /* set buddy icon */ | |
586 NULL, /* remove group */ | |
587 NULL, /* get_cb_real_name */ | |
588 NULL, | |
589 NULL, | |
590 irc_roomlist_get_list, | |
591 irc_roomlist_cancel, | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
592 NULL |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
593 }; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
594 |
8114 | 595 |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
596 static GaimPluginInfo info = |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
597 { |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
598 2, /**< api_version */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
599 GAIM_PLUGIN_PROTOCOL, /**< type */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
600 NULL, /**< ui_requirement */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
601 0, /**< flags */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
602 NULL, /**< dependencies */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
603 GAIM_PRIORITY_DEFAULT, /**< priority */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
604 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
605 "prpl-irc", /**< id */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
606 "IRC", /**< name */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
607 VERSION, /**< version */ |
6333 | 608 N_("IRC Protocol Plugin"), /** summary */ |
609 N_("The IRC Protocol Plugin that Sucks Less"), /** description */ | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
610 NULL, /**< author */ |
6371
8f94cce8faa5
[gaim-migrate @ 6876]
Christian Hammond <chipx86@chipx86.com>
parents:
6369
diff
changeset
|
611 GAIM_WEBSITE, /**< homepage */ |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
612 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
613 NULL, /**< load */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
614 NULL, /**< unload */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
615 NULL, /**< destroy */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
616 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
617 NULL, /**< ui_info */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
618 &prpl_info /**< extra_info */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
619 }; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
620 |
6333 | 621 static void _init_plugin(GaimPlugin *plugin) |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
622 { |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5618
diff
changeset
|
623 GaimAccountUserSplit *split; |
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5618
diff
changeset
|
624 GaimAccountOption *option; |
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5618
diff
changeset
|
625 |
6333 | 626 split = gaim_account_user_split_new(_("Server"), IRC_DEFAULT_SERVER, '@'); |
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5618
diff
changeset
|
627 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
|
628 |
6459
b52870734c21
[gaim-migrate @ 6968]
Christian Hammond <chipx86@chipx86.com>
parents:
6371
diff
changeset
|
629 option = gaim_account_option_int_new(_("Port"), "port", IRC_DEFAULT_PORT); |
6333 | 630 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
|
631 |
6333 | 632 option = gaim_account_option_string_new(_("Encoding"), "encoding", IRC_DEFAULT_CHARSET); |
633 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
|
634 |
7323 | 635 option = gaim_account_option_string_new(_("Username"), "username", ""); |
636 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
637 | |
6333 | 638 _irc_plugin = plugin; |
2086 | 639 } |
640 | |
6333 | 641 GAIM_INIT_PLUGIN(irc, _init_plugin, info); |