Mercurial > pidgin
annotate src/protocols/irc/irc.c @ 14122:dabbcb9b013d
[gaim-migrate @ 16759]
This initializes threads for glib and dbus, because under some
circumstances multithreaded libraries are causing dbus badness
(namely, gnome-vfs). This fix doesn't really belong in Gaim, but in
the interest of expedience (we don't want to wait for upstream
libraries to get their initializations all worked around to make
things safe) the fix goes here. Note that all Gaim frontends will
have to initialize glib threads if other threaded libraries which
interact with glib or dbus or what-have-you come into play.
committer: Tailor Script <tailor@pidgin.im>
| author | Ethan Blanton <elb@pidgin.im> |
|---|---|
| date | Mon, 14 Aug 2006 21:46:17 +0000 |
| parents | c44af67e2065 |
| children | c8ebbc0110f4 |
| 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); |
| 14111 | 49 static void irc_login_cb(gpointer data, gint source, const gchar *error_message); |
| 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 | |
| 287 gc = gaim_account_get_connection(account); | |
| 8677 | 288 gc->flags |= GAIM_CONNECTION_NO_NEWLINES; |
| 6333 | 289 |
| 6752 | 290 if (strpbrk(username, " \t\v\r\n") != NULL) { |
| 291 gaim_connection_error(gc, _("IRC nicks may not contain whitespace")); | |
| 292 return; | |
| 293 } | |
| 294 | |
| 6333 | 295 gc->proto_data = irc = g_new0(struct irc_conn, 1); |
| 10960 | 296 irc->fd = -1; |
| 6333 | 297 irc->account = account; |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
298 irc->outbuf = gaim_circ_buffer_new(512); |
| 6333 | 299 |
| 300 userparts = g_strsplit(username, "@", 2); | |
| 301 gaim_connection_set_display_name(gc, userparts[0]); | |
| 302 irc->server = g_strdup(userparts[1]); | |
| 303 g_strfreev(userparts); | |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
304 |
| 10159 | 305 irc->buddies = g_hash_table_new_full((GHashFunc)irc_nick_hash, (GEqualFunc)irc_nick_equal, |
| 6333 | 306 NULL, (GDestroyNotify)irc_buddy_free); |
| 307 irc->cmds = g_hash_table_new(g_str_hash, g_str_equal); | |
| 308 irc_cmd_table_build(irc); | |
| 309 irc->msgs = g_hash_table_new(g_str_hash, g_str_equal); | |
| 310 irc_msg_table_build(irc); | |
| 311 | |
| 10494 | 312 gaim_connection_update_progress(gc, _("Connecting"), 1, 2); |
| 6333 | 313 |
| 10365 | 314 if (gaim_account_get_bool(account, "ssl", FALSE)) { |
| 315 if (gaim_ssl_is_supported()) { | |
| 316 irc->gsc = gaim_ssl_connect(account, irc->server, | |
| 317 gaim_account_get_int(account, "port", IRC_DEFAULT_SSL_PORT), | |
| 318 irc_login_cb_ssl, irc_ssl_connect_failure, gc); | |
| 319 } else { | |
| 320 gaim_connection_error(gc, _("SSL support unavailable")); | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
321 return; |
| 10365 | 322 } |
| 323 } | |
| 324 | |
| 325 if (!irc->gsc) { | |
| 326 | |
| 14111 | 327 irc->connect_info = gaim_proxy_connect(account, irc->server, |
| 6333 | 328 gaim_account_get_int(account, "port", IRC_DEFAULT_PORT), |
| 14108 | 329 irc_login_cb, gc); |
| 6333 | 330 |
| 14111 | 331 if (!irc->connect_info || !gaim_account_get_connection(account)) { |
| 10365 | 332 gaim_connection_error(gc, _("Couldn't create socket")); |
| 333 return; | |
| 334 } | |
| 335 } | |
| 336 } | |
| 337 | |
| 338 static gboolean do_login(GaimConnection *gc) { | |
| 339 char *buf; | |
| 340 char hostname[256]; | |
| 341 const char *username, *realname; | |
| 342 struct irc_conn *irc = gc->proto_data; | |
| 10740 | 343 const char *pass = gaim_connection_get_password(gc); |
| 10365 | 344 |
| 10555 | 345 if (pass && *pass) { |
| 346 buf = irc_format(irc, "vv", "PASS", pass); | |
| 10365 | 347 if (irc_send(irc, buf) < 0) { |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
348 /* gaim_connection_error(gc, "Error sending password"); */ |
| 10903 | 349 g_free(buf); |
| 10365 | 350 return FALSE; |
| 351 } | |
| 352 g_free(buf); | |
| 353 } | |
| 354 | |
| 355 gethostname(hostname, sizeof(hostname)); | |
| 356 hostname[sizeof(hostname) - 1] = '\0'; | |
| 357 username = gaim_account_get_string(irc->account, "username", ""); | |
| 358 realname = gaim_account_get_string(irc->account, "realname", ""); | |
| 359 buf = irc_format(irc, "vvvv:", "USER", strlen(username) ? username : g_get_user_name(), hostname, irc->server, | |
| 360 strlen(realname) ? realname : IRC_DEFAULT_ALIAS); | |
| 361 if (irc_send(irc, buf) < 0) { | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
362 /* gaim_connection_error(gc, "Error registering with server");*/ |
| 10903 | 363 g_free(buf); |
| 10365 | 364 return FALSE; |
| 365 } | |
| 366 g_free(buf); | |
| 367 buf = irc_format(irc, "vn", "NICK", gaim_connection_get_display_name(gc)); | |
| 368 if (irc_send(irc, buf) < 0) { | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
369 /* gaim_connection_error(gc, "Error sending nickname");*/ |
| 10903 | 370 g_free(buf); |
| 10365 | 371 return FALSE; |
| 372 } | |
| 373 g_free(buf); | |
| 374 | |
| 375 return TRUE; | |
| 376 } | |
| 377 | |
| 378 static void irc_login_cb_ssl(gpointer data, GaimSslConnection *gsc, | |
| 379 GaimInputCondition cond) | |
| 380 { | |
| 381 GaimConnection *gc = data; | |
| 382 struct irc_conn *irc = gc->proto_data; | |
| 383 | |
| 384 if(!g_list_find(gaim_connections_get_all(), gc)) { | |
| 385 gaim_ssl_close(gsc); | |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
386 return; |
| 6333 | 387 } |
| 10365 | 388 |
| 389 irc->gsc = gsc; | |
| 390 | |
| 391 if (do_login(gc)) { | |
| 392 gaim_ssl_input_add(gsc, irc_input_cb_ssl, gc); | |
| 393 } | |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
394 } |
|
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
395 |
| 14111 | 396 static void irc_login_cb(gpointer data, gint source, const gchar *error_message) |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
397 { |
| 6333 | 398 GaimConnection *gc = data; |
| 399 struct irc_conn *irc = gc->proto_data; | |
| 14111 | 400 |
| 401 irc->connect_info = NULL; | |
| 6333 | 402 |
| 8778 | 403 if (source < 0) { |
| 404 gaim_connection_error(gc, _("Couldn't connect to host")); | |
| 6333 | 405 return; |
| 8778 | 406 } |
| 6333 | 407 |
| 408 irc->fd = source; | |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
409 |
| 10365 | 410 if (do_login(gc)) { |
| 411 gc->inpa = gaim_input_add(irc->fd, GAIM_INPUT_READ, irc_input_cb, gc); | |
| 412 } | |
| 413 } | |
| 414 | |
| 415 static void | |
| 416 irc_ssl_connect_failure(GaimSslConnection *gsc, GaimSslErrorType error, | |
| 417 gpointer data) | |
| 418 { | |
| 419 GaimConnection *gc = data; | |
| 420 struct irc_conn *irc = gc->proto_data; | |
| 421 | |
| 422 switch(error) { | |
| 423 case GAIM_SSL_CONNECT_FAILED: | |
| 424 gaim_connection_error(gc, _("Connection Failed")); | |
| 425 break; | |
| 426 case GAIM_SSL_HANDSHAKE_FAILED: | |
| 427 gaim_connection_error(gc, _("SSL Handshake Failed")); | |
| 428 break; | |
| 6333 | 429 } |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
430 |
| 10365 | 431 irc->gsc = NULL; |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
432 } |
|
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
433 |
| 6333 | 434 static void irc_close(GaimConnection *gc) |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
435 { |
| 6333 | 436 struct irc_conn *irc = gc->proto_data; |
| 437 | |
| 6752 | 438 if (irc == NULL) |
| 439 return; | |
| 440 | |
| 14111 | 441 if (irc->gsc || (irc->fd >= 0)) |
| 442 irc_cmd_quit(irc, "quit", NULL, NULL); | |
| 443 | |
| 444 if (irc->connect_info) | |
| 445 gaim_proxy_connect_cancel(irc->connect_info); | |
| 6333 | 446 |
| 447 if (gc->inpa) | |
| 9441 | 448 gaim_input_remove(gc->inpa); |
| 6333 | 449 |
| 450 g_free(irc->inbuf); | |
| 10365 | 451 if (irc->gsc) { |
| 452 gaim_ssl_close(irc->gsc); | |
| 453 } else if (irc->fd > 0) { | |
| 454 close(irc->fd); | |
| 455 } | |
| 6333 | 456 if (irc->timer) |
|
8287
ef881489396e
[gaim-migrate @ 9011]
Christian Hammond <chipx86@chipx86.com>
parents:
8170
diff
changeset
|
457 gaim_timeout_remove(irc->timer); |
| 6333 | 458 g_hash_table_destroy(irc->cmds); |
| 459 g_hash_table_destroy(irc->msgs); | |
| 10504 | 460 g_hash_table_destroy(irc->buddies); |
| 6333 | 461 if (irc->motd) |
| 462 g_string_free(irc->motd, TRUE); | |
| 463 g_free(irc->server); | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
464 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
465 if (irc->writeh) |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
466 gaim_input_remove(irc->writeh); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
467 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
468 gaim_circ_buffer_destroy(irc->outbuf); |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
469 |
| 6333 | 470 g_free(irc); |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
471 } |
|
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
472 |
| 12216 | 473 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
|
474 { |
| 6333 | 475 struct irc_conn *irc = gc->proto_data; |
| 12216 | 476 char *plain; |
| 6333 | 477 const char *args[2]; |
| 478 | |
| 7711 | 479 if (strchr(status_chars, *who) != NULL) |
| 6333 | 480 args[0] = who + 1; |
| 481 else | |
| 482 args[0] = who; | |
| 12216 | 483 |
| 484 plain = gaim_unescape_html(what); | |
| 485 args[1] = plain; | |
| 9442 | 486 |
| 6333 | 487 irc_cmd_privmsg(irc, "msg", NULL, args); |
| 12216 | 488 g_free(plain); |
| 6333 | 489 return 1; |
|
2289
38e156136896
[gaim-migrate @ 2299]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2273
diff
changeset
|
490 } |
| 2086 | 491 |
| 6333 | 492 static void irc_get_info(GaimConnection *gc, const char *who) |
| 2086 | 493 { |
| 6333 | 494 struct irc_conn *irc = gc->proto_data; |
|
10618
9eb3b224face
[gaim-migrate @ 12083]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10555
diff
changeset
|
495 const char *args[2]; |
| 6333 | 496 args[0] = who; |
| 10624 | 497 args[1] = NULL; |
| 6333 | 498 irc_cmd_whois(irc, "whois", NULL, args); |
| 499 } | |
| 500 | |
| 9944 | 501 static void irc_set_status(GaimAccount *account, GaimStatus *status) |
| 6333 | 502 { |
| 9944 | 503 GaimConnection *gc = gaim_account_get_connection(account); |
|
13437
4bfb720a8fc2
[gaim-migrate @ 15812]
Richard Laager <rlaager@wiktel.com>
parents:
13296
diff
changeset
|
504 struct irc_conn *irc; |
| 6333 | 505 const char *args[1]; |
| 9944 | 506 const char *status_id = gaim_status_get_id(status); |
| 2086 | 507 |
|
13437
4bfb720a8fc2
[gaim-migrate @ 15812]
Richard Laager <rlaager@wiktel.com>
parents:
13296
diff
changeset
|
508 g_return_if_fail(gc != NULL); |
|
4bfb720a8fc2
[gaim-migrate @ 15812]
Richard Laager <rlaager@wiktel.com>
parents:
13296
diff
changeset
|
509 irc = gc->proto_data; |
| 10646 | 510 |
| 10504 | 511 if (!gaim_status_is_active(status)) |
| 512 return; | |
| 513 | |
| 514 args[0] = NULL; | |
| 515 | |
| 11718 | 516 if (!strcmp(status_id, "away")) { |
| 9944 | 517 args[0] = gaim_status_get_attr_string(status, "message"); |
| 12001 | 518 if ((args[0] == NULL) || (*args[0] == '\0')) |
| 519 args[0] = _("Away"); | |
| 10646 | 520 irc_cmd_away(irc, "away", NULL, args); |
| 12210 | 521 } else if (!strcmp(status_id, "available")) { |
| 522 irc_cmd_away(irc, "back", NULL, args); | |
| 10646 | 523 } |
| 4916 | 524 } |
| 525 | |
| 9285 | 526 static void irc_add_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) |
| 3029 | 527 { |
| 6333 | 528 struct irc_conn *irc = (struct irc_conn *)gc->proto_data; |
| 529 struct irc_buddy *ib = g_new0(struct irc_buddy, 1); | |
| 9285 | 530 ib->name = g_strdup(buddy->name); |
| 6333 | 531 g_hash_table_insert(irc->buddies, ib->name, ib); |
| 9238 | 532 |
| 9553 | 533 /* if the timer isn't set, this is during signon, so we don't want to flood |
| 534 * ourself off with ISON's, so we don't, but after that we want to know when | |
| 535 * someone's online asap */ | |
| 536 if (irc->timer) | |
| 537 irc_ison_one(irc, ib); | |
| 3029 | 538 } |
| 3622 | 539 |
| 9285 | 540 static void irc_remove_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) |
| 6333 | 541 { |
| 542 struct irc_conn *irc = (struct irc_conn *)gc->proto_data; | |
| 9285 | 543 g_hash_table_remove(irc->buddies, buddy->name); |
| 3616 | 544 } |
|
4514
7521e29658bc
[gaim-migrate @ 4792]
Christian Hammond <chipx86@chipx86.com>
parents:
4509
diff
changeset
|
545 |
| 10365 | 546 static void read_input(struct irc_conn *irc, int len) |
| 6333 | 547 { |
| 548 char *cur, *end; | |
| 6369 | 549 |
| 6333 | 550 irc->inbufused += len; |
| 551 irc->inbuf[irc->inbufused] = '\0'; | |
| 3616 | 552 |
| 8156 | 553 cur = irc->inbuf; |
| 12752 | 554 |
| 555 /* This is a hack to work around the fact that marv gets messages | |
| 556 * with null bytes in them while using some weird irc server at work | |
| 557 */ | |
| 558 while ((cur < (irc->inbuf + irc->inbufused)) && !*cur) | |
| 559 cur++; | |
| 560 | |
| 8156 | 561 while (cur < irc->inbuf + irc->inbufused && |
| 562 ((end = strstr(cur, "\r\n")) || (end = strstr(cur, "\n")))) { | |
| 563 int step = (*end == '\r' ? 2 : 1); | |
| 6333 | 564 *end = '\0'; |
| 565 irc_parse_msg(irc, cur); | |
| 8156 | 566 cur = end + step; |
| 6333 | 567 } |
| 568 if (cur != irc->inbuf + irc->inbufused) { /* leftover */ | |
| 569 irc->inbufused -= (cur - irc->inbuf); | |
| 570 memmove(irc->inbuf, cur, irc->inbufused); | |
| 571 } else { | |
| 572 irc->inbufused = 0; | |
| 573 } | |
| 3616 | 574 } |
| 575 | |
| 10365 | 576 static void irc_input_cb_ssl(gpointer data, GaimSslConnection *gsc, |
| 577 GaimInputCondition cond) | |
| 578 { | |
| 579 | |
| 580 GaimConnection *gc = data; | |
| 581 struct irc_conn *irc = gc->proto_data; | |
| 582 int len; | |
| 583 | |
| 584 if(!g_list_find(gaim_connections_get_all(), gc)) { | |
| 585 gaim_ssl_close(gsc); | |
| 586 return; | |
| 587 } | |
| 588 | |
| 589 if (irc->inbuflen < irc->inbufused + IRC_INITIAL_BUFSIZE) { | |
| 590 irc->inbuflen += IRC_INITIAL_BUFSIZE; | |
| 591 irc->inbuf = g_realloc(irc->inbuf, irc->inbuflen); | |
| 592 } | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
593 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
594 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
|
595 |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
596 if (len < 0 && errno == EAGAIN) { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
597 /* Try again later */ |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
598 return; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
599 } else if (len < 0) { |
| 10365 | 600 gaim_connection_error(gc, _("Read error")); |
| 601 return; | |
| 602 } else if (len == 0) { | |
| 603 gaim_connection_error(gc, _("Server has disconnected")); | |
| 604 return; | |
| 605 } | |
| 606 | |
| 607 read_input(irc, len); | |
| 608 } | |
| 609 | |
| 610 static void irc_input_cb(gpointer data, gint source, GaimInputCondition cond) | |
| 611 { | |
| 612 GaimConnection *gc = data; | |
| 613 struct irc_conn *irc = gc->proto_data; | |
| 614 int len; | |
| 615 | |
| 616 if (irc->inbuflen < irc->inbufused + IRC_INITIAL_BUFSIZE) { | |
| 617 irc->inbuflen += IRC_INITIAL_BUFSIZE; | |
| 618 irc->inbuf = g_realloc(irc->inbuf, irc->inbuflen); | |
| 619 } | |
| 620 | |
|
13200
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
621 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
|
622 if (len < 0 && errno == EAGAIN) { |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
623 return; |
|
33bef17125c2
[gaim-migrate @ 15563]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
12752
diff
changeset
|
624 } else if (len < 0) { |
| 10365 | 625 gaim_connection_error(gc, _("Read error")); |
| 626 return; | |
| 627 } else if (len == 0) { | |
| 628 gaim_connection_error(gc, _("Server has disconnected")); | |
| 629 return; | |
| 630 } | |
| 631 | |
| 632 read_input(irc, len); | |
| 633 } | |
| 634 | |
| 6333 | 635 static void irc_chat_join (GaimConnection *gc, GHashTable *data) |
| 636 { | |
| 637 struct irc_conn *irc = gc->proto_data; | |
| 638 const char *args[2]; | |
| 3616 | 639 |
| 6333 | 640 args[0] = g_hash_table_lookup(data, "channel"); |
| 641 args[1] = g_hash_table_lookup(data, "password"); | |
| 642 irc_cmd_join(irc, "join", NULL, args); | |
| 3622 | 643 } |
| 644 | |
| 9917 | 645 static char *irc_get_chat_name(GHashTable *data) { |
| 646 return g_strdup(g_hash_table_lookup(data, "channel")); | |
| 647 } | |
| 648 | |
| 6333 | 649 static void irc_chat_invite(GaimConnection *gc, int id, const char *message, const char *name) |
| 3751 | 650 { |
| 6333 | 651 struct irc_conn *irc = gc->proto_data; |
| 652 GaimConversation *convo = gaim_find_chat(gc, id); | |
| 653 const char *args[2]; | |
| 3751 | 654 |
| 6333 | 655 if (!convo) { |
| 656 gaim_debug(GAIM_DEBUG_ERROR, "irc", "Got chat invite request for bogus chat\n"); | |
| 657 return; | |
| 658 } | |
| 659 args[0] = name; | |
| 660 args[1] = gaim_conversation_get_name(convo); | |
| 661 irc_cmd_invite(irc, "invite", gaim_conversation_get_name(convo), args); | |
| 3707 | 662 } |
| 663 | |
| 6333 | 664 |
| 665 static void irc_chat_leave (GaimConnection *gc, int id) | |
| 3707 | 666 { |
| 6333 | 667 struct irc_conn *irc = gc->proto_data; |
| 668 GaimConversation *convo = gaim_find_chat(gc, id); | |
| 669 const char *args[2]; | |
| 5298 | 670 |
| 6333 | 671 if (!convo) |
| 672 return; | |
| 3735 | 673 |
| 6333 | 674 args[0] = gaim_conversation_get_name(convo); |
| 675 args[1] = NULL; | |
| 676 irc_cmd_part(irc, "part", gaim_conversation_get_name(convo), args); | |
| 677 serv_got_chat_left(gc, id); | |
| 3735 | 678 } |
| 679 | |
| 12216 | 680 static int irc_chat_send(GaimConnection *gc, int id, const char *what, GaimMessageFlags flags) |
| 3735 | 681 { |
| 6333 | 682 struct irc_conn *irc = gc->proto_data; |
| 683 GaimConversation *convo = gaim_find_chat(gc, id); | |
| 684 const char *args[2]; | |
| 8163 | 685 char *tmp; |
| 6333 | 686 |
| 687 if (!convo) { | |
| 688 gaim_debug(GAIM_DEBUG_ERROR, "irc", "chat send on nonexistent chat\n"); | |
| 689 return -EINVAL; | |
| 690 } | |
| 9130 | 691 #if 0 |
| 6333 | 692 if (*what == '/') { |
| 693 return irc_parse_cmd(irc, convo->name, what + 1); | |
| 694 } | |
| 9130 | 695 #endif |
| 12216 | 696 tmp = gaim_unescape_html(what); |
| 6333 | 697 args[0] = convo->name; |
| 12216 | 698 args[1] = tmp; |
| 6333 | 699 |
| 700 irc_cmd_privmsg(irc, "msg", NULL, args); | |
| 8163 | 701 |
| 12216 | 702 serv_got_chat_in(gc, id, gaim_connection_get_display_name(gc), 0, what, time(NULL)); |
| 8163 | 703 g_free(tmp); |
| 6333 | 704 return 0; |
| 3707 | 705 } |
| 706 | |
| 6333 | 707 static guint irc_nick_hash(const char *nick) |
| 708 { | |
| 709 char *lc; | |
| 710 guint bucket; | |
|
6270
1bf6fd117797
[gaim-migrate @ 6767]
Christian Hammond <chipx86@chipx86.com>
parents:
6240
diff
changeset
|
711 |
| 6333 | 712 lc = g_utf8_strdown(nick, -1); |
| 713 bucket = g_str_hash(lc); | |
| 714 g_free(lc); | |
|
6270
1bf6fd117797
[gaim-migrate @ 6767]
Christian Hammond <chipx86@chipx86.com>
parents:
6240
diff
changeset
|
715 |
| 6333 | 716 return bucket; |
| 3029 | 717 } |
| 718 | |
| 6333 | 719 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
|
720 { |
| 6333 | 721 return (gaim_utf8_strcasecmp(nick1, nick2) == 0); |
|
2619
536198196dc6
[gaim-migrate @ 2632]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2617
diff
changeset
|
722 } |
|
536198196dc6
[gaim-migrate @ 2632]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2617
diff
changeset
|
723 |
| 6333 | 724 static void irc_buddy_free(struct irc_buddy *ib) |
|
2619
536198196dc6
[gaim-migrate @ 2632]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2617
diff
changeset
|
725 { |
| 6333 | 726 g_free(ib->name); |
| 727 g_free(ib); | |
|
2619
536198196dc6
[gaim-migrate @ 2632]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2617
diff
changeset
|
728 } |
|
536198196dc6
[gaim-migrate @ 2632]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2617
diff
changeset
|
729 |
| 9154 | 730 static void irc_chat_set_topic(GaimConnection *gc, int id, const char *topic) |
| 731 { | |
| 732 char *buf; | |
| 733 const char *name = NULL; | |
| 734 struct irc_conn *irc; | |
| 735 | |
| 736 irc = gc->proto_data; | |
| 737 name = gaim_conversation_get_name(gaim_find_chat(gc, id)); | |
| 738 | |
| 739 if (name == NULL) | |
| 740 return; | |
| 741 | |
| 742 buf = irc_format(irc, "vt:", "TOPIC", name, topic); | |
| 743 irc_send(irc, buf); | |
| 744 g_free(buf); | |
| 745 } | |
| 746 | |
| 8114 | 747 static GaimRoomlist *irc_roomlist_get_list(GaimConnection *gc) |
| 748 { | |
| 749 struct irc_conn *irc; | |
| 750 GList *fields = NULL; | |
| 751 GaimRoomlistField *f; | |
| 8352 | 752 char *buf; |
| 8114 | 753 |
| 754 irc = gc->proto_data; | |
| 755 | |
| 756 if (irc->roomlist) | |
| 757 gaim_roomlist_unref(irc->roomlist); | |
| 758 | |
| 759 irc->roomlist = gaim_roomlist_new(gaim_connection_get_account(gc)); | |
| 760 | |
| 761 f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_STRING, "", "channel", TRUE); | |
| 762 fields = g_list_append(fields, f); | |
| 763 | |
| 764 f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_INT, _("Users"), "users", FALSE); | |
| 765 fields = g_list_append(fields, f); | |
| 766 | |
| 767 f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_STRING, _("Topic"), "topic", FALSE); | |
| 768 fields = g_list_append(fields, f); | |
| 769 | |
| 770 gaim_roomlist_set_fields(irc->roomlist, fields); | |
| 771 | |
| 8352 | 772 buf = irc_format(irc, "v", "LIST"); |
| 773 irc_send(irc, buf); | |
| 774 g_free(buf); | |
| 8114 | 775 |
| 776 return irc->roomlist; | |
| 777 } | |
| 778 | |
| 779 static void irc_roomlist_cancel(GaimRoomlist *list) | |
| 780 { | |
| 781 GaimConnection *gc = gaim_account_get_connection(list->account); | |
| 782 struct irc_conn *irc; | |
| 783 | |
| 784 if (gc == NULL) | |
| 785 return; | |
| 786 | |
| 787 irc = gc->proto_data; | |
| 788 | |
| 789 gaim_roomlist_set_in_progress(list, FALSE); | |
| 790 | |
| 791 if (irc->roomlist == list) { | |
| 792 irc->roomlist = NULL; | |
| 793 gaim_roomlist_unref(list); | |
| 794 } | |
| 795 } | |
| 796 | |
|
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
797 static GaimPluginProtocolInfo prpl_info = |
| 2086 | 798 { |
|
11500
9fc7d0153332
[gaim-migrate @ 13745]
Richard Laager <rlaager@wiktel.com>
parents:
11454
diff
changeset
|
799 OPT_PROTO_CHAT_TOPIC | OPT_PROTO_PASSWORD_OPTIONAL, |
| 9475 | 800 NULL, /* user_splits */ |
| 801 NULL, /* protocol_options */ | |
| 9951 | 802 NO_BUDDY_ICONS, /* icon_spec */ |
| 803 irc_blist_icon, /* list_icon */ | |
| 804 irc_blist_emblems, /* list_emblems */ | |
| 9475 | 805 NULL, /* status_text */ |
| 806 NULL, /* tooltip_text */ | |
| 9951 | 807 irc_status_types, /* away_states */ |
| 9475 | 808 NULL, /* blist_node_menu */ |
| 9951 | 809 irc_chat_join_info, /* chat_info */ |
| 9754 | 810 irc_chat_info_defaults, /* chat_info_defaults */ |
| 9951 | 811 irc_login, /* login */ |
| 812 irc_close, /* close */ | |
| 813 irc_im_send, /* send_im */ | |
| 9475 | 814 NULL, /* set_info */ |
| 815 NULL, /* send_typing */ | |
| 9951 | 816 irc_get_info, /* get_info */ |
| 817 irc_set_status, /* set_status */ | |
| 9475 | 818 NULL, /* set_idle */ |
| 819 NULL, /* change_passwd */ | |
| 9951 | 820 irc_add_buddy, /* add_buddy */ |
| 9475 | 821 NULL, /* add_buddies */ |
| 9951 | 822 irc_remove_buddy, /* remove_buddy */ |
| 9475 | 823 NULL, /* remove_buddies */ |
| 9741 | 824 NULL, /* add_permit */ |
| 825 NULL, /* add_deny */ | |
| 826 NULL, /* rem_permit */ | |
| 827 NULL, /* rem_deny */ | |
| 828 NULL, /* set_permit_deny */ | |
| 9951 | 829 irc_chat_join, /* join_chat */ |
| 9475 | 830 NULL, /* reject_chat */ |
| 9951 | 831 irc_get_chat_name, /* get_chat_name */ |
| 832 irc_chat_invite, /* chat_invite */ | |
| 833 irc_chat_leave, /* chat_leave */ | |
| 9475 | 834 NULL, /* chat_whisper */ |
| 9951 | 835 irc_chat_send, /* chat_send */ |
| 12031 | 836 NULL, /* keepalive */ |
| 9475 | 837 NULL, /* register_user */ |
| 838 NULL, /* get_cb_info */ | |
| 839 NULL, /* get_cb_away */ | |
| 840 NULL, /* alias_buddy */ | |
| 841 NULL, /* group_buddy */ | |
| 842 NULL, /* rename_group */ | |
| 843 NULL, /* buddy_free */ | |
| 844 NULL, /* convo_closed */ | |
| 11153 | 845 gaim_normalize_nocase, /* normalize */ |
| 9475 | 846 NULL, /* set_buddy_icon */ |
| 847 NULL, /* remove_group */ | |
| 848 NULL, /* get_cb_real_name */ | |
| 9951 | 849 irc_chat_set_topic, /* set_chat_topic */ |
| 9475 | 850 NULL, /* find_blist_chat */ |
| 851 irc_roomlist_get_list, /* roomlist_get_list */ | |
| 852 irc_roomlist_cancel, /* roomlist_cancel */ | |
| 853 NULL, /* roomlist_expand_category */ | |
| 854 NULL, /* can_receive_file */ | |
|
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
12130
diff
changeset
|
855 irc_dccsend_send_file, /* send_file */ |
|
12600
e856f985a0b9
[gaim-migrate @ 14934]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
856 irc_dccsend_new_xfer, /* new_xfer */ |
|
12645
fc28451f5d96
[gaim-migrate @ 14983]
Richard Laager <rlaager@wiktel.com>
parents:
12600
diff
changeset
|
857 NULL, /* offline_message */ |
|
12600
e856f985a0b9
[gaim-migrate @ 14934]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
858 NULL, /* whiteboard_prpl_ops */ |
|
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
859 }; |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
860 |
| 8114 | 861 |
|
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
862 static GaimPluginInfo info = |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
863 { |
| 9943 | 864 GAIM_PLUGIN_MAGIC, |
| 865 GAIM_MAJOR_VERSION, | |
| 866 GAIM_MINOR_VERSION, | |
|
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
867 GAIM_PLUGIN_PROTOCOL, /**< type */ |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
868 NULL, /**< ui_requirement */ |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
869 0, /**< flags */ |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
870 NULL, /**< dependencies */ |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
871 GAIM_PRIORITY_DEFAULT, /**< priority */ |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
872 |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
873 "prpl-irc", /**< id */ |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
874 "IRC", /**< name */ |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
875 VERSION, /**< version */ |
| 6333 | 876 N_("IRC Protocol Plugin"), /** summary */ |
| 877 N_("The IRC Protocol Plugin that Sucks Less"), /** description */ | |
|
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
878 NULL, /**< author */ |
|
6371
8f94cce8faa5
[gaim-migrate @ 6876]
Christian Hammond <chipx86@chipx86.com>
parents:
6369
diff
changeset
|
879 GAIM_WEBSITE, /**< homepage */ |
|
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
880 |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
881 NULL, /**< load */ |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
882 NULL, /**< unload */ |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
883 NULL, /**< destroy */ |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
884 |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
885 NULL, /**< ui_info */ |
| 8993 | 886 &prpl_info, /**< extra_info */ |
| 11763 | 887 NULL, /**< prefs_info */ |
| 9015 | 888 irc_actions |
|
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
889 }; |
|
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
890 |
| 6333 | 891 static void _init_plugin(GaimPlugin *plugin) |
|
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5150
diff
changeset
|
892 { |
|
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5618
diff
changeset
|
893 GaimAccountUserSplit *split; |
|
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5618
diff
changeset
|
894 GaimAccountOption *option; |
|
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5618
diff
changeset
|
895 |
| 6333 | 896 split = gaim_account_user_split_new(_("Server"), IRC_DEFAULT_SERVER, '@'); |
|
5638
0bdfa28c678e
[gaim-migrate @ 6047]
Christian Hammond <chipx86@chipx86.com>
parents:
5618
diff
changeset
|
897 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
|
898 |
|
6459
b52870734c21
[gaim-migrate @ 6968]
Christian Hammond <chipx86@chipx86.com>
parents:
6371
diff
changeset
|
899 option = gaim_account_option_int_new(_("Port"), "port", IRC_DEFAULT_PORT); |
| 6333 | 900 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
|
901 |
| 10258 | 902 option = gaim_account_option_string_new(_("Encodings"), "encoding", IRC_DEFAULT_CHARSET); |
| 6333 | 903 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
|
904 |
| 7323 | 905 option = gaim_account_option_string_new(_("Username"), "username", ""); |
| 906 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
| 907 | |
| 10002 | 908 option = gaim_account_option_string_new(_("Real name"), "realname", ""); |
| 909 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
| 910 | |
| 11763 | 911 /* |
| 912 option = gaim_account_option_string_new(_("Quit message"), "quitmsg", IRC_DEFAULT_QUIT); | |
| 913 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
| 914 */ | |
| 915 | |
| 10365 | 916 option = gaim_account_option_bool_new(_("Use SSL"), "ssl", FALSE); |
| 917 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
| 918 | |
| 6333 | 919 _irc_plugin = plugin; |
| 9130 | 920 |
| 11763 | 921 gaim_prefs_remove("/plugins/prpl/irc/quitmsg"); |
| 922 gaim_prefs_remove("/plugins/prpl/irc"); | |
| 11073 | 923 |
| 9130 | 924 irc_register_commands(); |
| 2086 | 925 } |
| 926 | |
| 6333 | 927 GAIM_INIT_PLUGIN(irc, _init_plugin, info); |
