Mercurial > pidgin
annotate src/protocols/zephyr/zephyr.c @ 9584:fe35f55ee984
[gaim-migrate @ 10427]
" When joining a jabber conference many jabber servers
send a recap of the last 20 or so messages. If you
have sounds enabled, this will result in either 20
sounds in row, or worse if mixing is available, a
horrible mix of 20 overlapping sounds. These recap
messages can be identifed be the presence of the
"jabber:x:delay". This patch identifies delayed
messages, passes that information through flags from
the prpl to the core, and then on to the gui. Detailed
changes:
Add GAIM_MESSAGE_DELAYED to GaimMessageFlags to
indicate a delayed message.
Change gtkconv.c to not play sounds when either
GAIM_MESSAGE_DELAYED or GAIM_MESSAGE_SYSTEM are set.
Add GaimConvChatFlags, parallel to GaimConvImFlags, to
pass flags from protocols to core. Currently contains
two flags:
GAIM_CONV_CHAT_WHISPER
GAIM_CONV_CHAT_DELAYED
Change fourth arg of serv_got_chat_in() from "int
whisper" to "GaimConvChatFlags chatflags".
Change jabber prpl to set delayed flag when the
"jabber:x:delay" element is present. Change toc
protocol since it uses the whisper flag." --Nathan Fredrickson
Date: 2004-07-24 00:49
Sender: marv_sfAccepting Donations
Logged In: YES
user_id=790708
I'm not sure I like naming the flags "DELAYED". I mean
that's okay inside jabber since that's what the jabber
protocol refers to it as, but for the the GAIM_*_DELAYED
flags, I think they should be named something else.
I thought about NOSOUND, but I decided that was wrong,
because the flag should say what kind of message it is, not
what to do with it, that's up to the UI to decide.
What's up with not playing sounds on GAIM_MESSAGE_SYSTEM?
This sounds unrelated to this. Are there times when we want
to play sounds on system messages?
Date: 2004-07-24 09:13
Sender: noif
Logged In: YES
user_id=365548
I purposely did not use a name that implied what the UI
should do with the flag. The only characteristic that makes
these messages unique is that they've been stored in the
server for some period of time and are not current. I'm
open to a better flag name than "DELAYED"... I thought about
"RECAP", but that seemed less generalized than "DELAYED".
As for not playing sounds on GAIM_MESSAGE_SYSTEM, that can
be removed if it's controversial. I think I slipped that
in since the setting of the topic was still playing a sound
every time you joined a jabber conference.
I think we can change the flag name ourselves if something else is better.
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Sat, 24 Jul 2004 15:18:32 +0000 |
parents | 8b2451878e26 |
children | d6f398e80b32 |
rev | line source |
---|---|
2086 | 1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ |
2 /* | |
3 * gaim | |
4 * | |
5 * Copyright (C) 1998-2001, Mark Spencer <markster@marko.net> | |
6 * Some code borrowed from GtkZephyr, by | |
7084
0909ebf6fb28
[gaim-migrate @ 7649]
Christian Hammond <chipx86@chipx86.com>
parents:
7070
diff
changeset
|
7 * Jag/Sean Dilda <agrajag@linuxpower.org>/<smdilda@unity.ncsu.edu> |
0909ebf6fb28
[gaim-migrate @ 7649]
Christian Hammond <chipx86@chipx86.com>
parents:
7070
diff
changeset
|
8 * http://gtkzephyr.linuxpower.org/ |
2086 | 9 * |
10 * This program is free software; you can redistribute it and/or modify | |
11 * it under the terms of the GNU General Public License as published by | |
12 * the Free Software Foundation; either version 2 of the License, or | |
13 * (at your option) any later version. | |
14 * | |
15 * This program is distributed in the hope that it will be useful, | |
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 * GNU General Public License for more details. | |
19 * | |
20 * You should have received a copy of the GNU General Public License | |
21 * along with this program; if not, write to the Free Software | |
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
23 * | |
24 */ | |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
25 /* XXX eww */ |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
26 #include "src/internal.h" |
2086 | 27 |
8212 | 28 #include "accountopt.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
29 #include "debug.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
30 #include "multi.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
31 #include "notify.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
32 #include "prpl.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
33 #include "server.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
34 #include "util.h" |
9434 | 35 #include "cmds.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
36 |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
37 #include "zephyr/zephyr.h" |
9478 | 38 #include "internal.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
39 |
8386 | 40 #include <strings.h> |
41 | |
8560 | 42 #define ZEPHYR_FALLBACK_CHARSET "ISO-8859-1" |
43 | |
9478 | 44 /* these are deliberately high, since most people don't send multiple "PING"s */ |
45 #define ZEPHYR_TYPING_SEND_TIMEOUT 15 | |
46 #define ZEPHYR_TYPING_RECV_TIMEOUT 10 | |
47 | |
2086 | 48 extern Code_t ZGetLocations(ZLocations_t *, int *); |
49 extern Code_t ZSetLocation(char *); | |
50 extern Code_t ZUnsetLocation(); | |
9478 | 51 extern Code_t ZGetSubscriptions(ZSubscription_t *, int*); |
2086 | 52 |
53 typedef struct _zframe zframe; | |
54 typedef struct _zephyr_triple zephyr_triple; | |
55 | |
9478 | 56 char ourhost[MAXHOSTNAMELEN]; |
57 char ourhostcanon[MAXHOSTNAMELEN]; | |
58 | |
2086 | 59 /* struct I need for zephyr_to_html */ |
60 struct _zframe { | |
61 /* true for everything but @color, since inside the parens of that one is | |
8644 | 62 * the color. */ |
2086 | 63 gboolean has_closer; |
64 /* </i>, </font>, </b>, etc. */ | |
65 char *closing; | |
66 /* text including the opening html thingie. */ | |
67 GString *text; | |
68 struct _zframe *enclosing; | |
69 }; | |
70 | |
71 struct _zephyr_triple { | |
72 char *class; | |
73 char *instance; | |
74 char *recipient; | |
75 char *name; | |
76 gboolean open; | |
77 int id; | |
78 }; | |
79 | |
80 #define z_call(func) if (func != ZERR_NONE)\ | |
81 return; | |
82 #define z_call_r(func) if (func != ZERR_NONE)\ | |
83 return TRUE; | |
84 #define z_call_s(func, err) if (func != ZERR_NONE) {\ | |
5606 | 85 gaim_connection_error(zgc, err);\ |
2086 | 86 return;\ |
87 } | |
88 | |
9328 | 89 char *local_zephyr_normalize(const char *); |
7322 | 90 static const char *zephyr_normalize(const GaimAccount *, const char *); |
9328 | 91 static const char *gaim_zephyr_get_realm(); |
9434 | 92 static void zephyr_chat_set_topic(GaimConnection * gc, int id, const char *topic); |
9328 | 93 |
94 char *zephyr_strip_foreign_realm(const char* user){ | |
95 /* | |
96 Takes in a username of the form username or username@realm | |
97 and returns: | |
98 username, if there is no realm, or the realm is the local realm | |
99 or: | |
100 username@realm if there is a realm and it is foreign | |
101 */ | |
102 char *tmp = g_strdup(user); | |
103 char *at = strchr(tmp,'@'); | |
104 if (at && !g_ascii_strcasecmp(at+1,gaim_zephyr_get_realm())) { | |
105 /* We're passed in a username of the form user@users-realm */ | |
106 char* tmp2; | |
107 *at = '\0'; | |
108 tmp2 = g_strdup(tmp); | |
109 g_free(tmp); | |
110 return tmp2; | |
111 } | |
112 else { | |
113 /* We're passed in a username of the form user or user@foreign-realm */ | |
114 return tmp; | |
115 } | |
116 } | |
2086 | 117 |
118 /* this is so bad, and if Zephyr weren't so fucked up to begin with I | |
119 * wouldn't do this. but it is so i will. */ | |
120 static guint32 nottimer = 0; | |
121 static guint32 loctimer = 0; | |
5606 | 122 GaimConnection *zgc = NULL; |
2086 | 123 static GList *pending_zloc_names = NULL; |
124 static GSList *subscrips = NULL; | |
125 static int last_id = 0; | |
9478 | 126 unsigned short zephyr_port; |
9328 | 127 /* just for debugging */ |
2086 | 128 static void handle_unknown(ZNotice_t notice) |
129 { | |
9328 | 130 gaim_debug(GAIM_DEBUG_MISC, "zephyr","z_packet: %s\n", notice.z_packet); |
131 gaim_debug(GAIM_DEBUG_MISC, "zephyr","z_version: %s\n", notice.z_version); | |
132 gaim_debug(GAIM_DEBUG_MISC, "zephyr","z_kind: %d\n", (int)(notice.z_kind)); | |
133 gaim_debug(GAIM_DEBUG_MISC, "zephyr","z_class: %s\n", notice.z_class); | |
134 gaim_debug(GAIM_DEBUG_MISC, "zephyr","z_class_inst: %s\n", notice.z_class_inst); | |
135 gaim_debug(GAIM_DEBUG_MISC, "zephyr","z_opcode: %s\n", notice.z_opcode); | |
136 gaim_debug(GAIM_DEBUG_MISC, "zephyr","z_sender: %s\n", notice.z_sender); | |
137 gaim_debug(GAIM_DEBUG_MISC, "zephyr","z_recipient: %s\n", notice.z_recipient); | |
138 gaim_debug(GAIM_DEBUG_MISC, "zephyr","z_message: %s\n", notice.z_message); | |
139 gaim_debug(GAIM_DEBUG_MISC, "zephyr","z_message_len: %d\n", notice.z_message_len); | |
2086 | 140 } |
9328 | 141 |
2086 | 142 |
143 static zephyr_triple *new_triple(const char *c, const char *i, const char *r) | |
144 { | |
145 zephyr_triple *zt; | |
8644 | 146 |
2086 | 147 zt = g_new0(zephyr_triple, 1); |
148 zt->class = g_strdup(c); | |
149 zt->instance = g_strdup(i); | |
150 zt->recipient = g_strdup(r); | |
151 zt->name = g_strdup_printf("%s,%s,%s", c, i, r); | |
152 zt->id = ++last_id; | |
153 zt->open = FALSE; | |
154 return zt; | |
155 } | |
156 | |
8644 | 157 static void free_triple(zephyr_triple * zt) |
2086 | 158 { |
159 g_free(zt->class); | |
160 g_free(zt->instance); | |
161 g_free(zt->recipient); | |
162 g_free(zt->name); | |
163 g_free(zt); | |
164 } | |
165 | |
9478 | 166 static gchar *gaim_zephyr_get_sender() |
8644 | 167 { |
8568 | 168 /* will be useful once this plugin can use a backend other |
169 than libzephyr */ | |
9478 | 170 /* XXX add zephyr error reporting */ |
171 gchar *sender; | |
172 sender = ZGetSender(); | |
173 if (!sender || !g_ascii_strcasecmp(sender,"")) { | |
174 sender = ""; | |
175 } | |
176 return sender; | |
8354 | 177 } |
178 | |
8644 | 179 static const char *gaim_zephyr_get_realm() |
180 { | |
8568 | 181 /* will be useful once this plugin can use a backend other |
182 than libzephyr */ | |
9478 | 183 gchar *realm=NULL; |
184 /* XXX add zephyr error reporting */ | |
185 realm= ZGetRealm(); | |
186 return realm; | |
8354 | 187 } |
188 | |
9328 | 189 /* returns true if zt1 is a subset of zt2. This function is used to |
190 determine whether a zephyr sent to zt1 should be placed in the chat | |
191 with triple zt2 | |
192 | |
193 zt1 is a subset of zt2 | |
194 iff. the classnames are identical ignoring case | |
195 AND. the instance names are identical (ignoring case), or zt2->instance is *. | |
196 AND. the recipient names are identical | |
197 */ | |
198 | |
8644 | 199 static gboolean triple_subset(zephyr_triple * zt1, zephyr_triple * zt2) |
2086 | 200 { |
9328 | 201 if (g_ascii_strcasecmp(zt2->class, zt1->class)) { |
2086 | 202 return FALSE; |
203 } | |
8644 | 204 if (g_ascii_strcasecmp(zt2->instance, zt1->instance) && g_ascii_strcasecmp(zt2->instance, "*")) { |
2086 | 205 return FALSE; |
206 } | |
9328 | 207 if (g_ascii_strcasecmp(zt2->recipient, zt1->recipient)) { |
2086 | 208 return FALSE; |
209 } | |
210 return TRUE; | |
211 } | |
212 | |
8644 | 213 static zephyr_triple *find_sub_by_triple(zephyr_triple * zt) |
2086 | 214 { |
215 zephyr_triple *curr_t; | |
216 GSList *curr = subscrips; | |
8644 | 217 |
2086 | 218 while (curr) { |
219 curr_t = curr->data; | |
220 if (triple_subset(zt, curr_t)) | |
221 return curr_t; | |
222 curr = curr->next; | |
223 } | |
224 return NULL; | |
225 } | |
226 | |
227 static zephyr_triple *find_sub_by_id(int id) | |
228 { | |
229 zephyr_triple *zt; | |
230 GSList *curr = subscrips; | |
8644 | 231 |
2086 | 232 while (curr) { |
233 zt = curr->data; | |
234 if (zt->id == id) | |
235 return zt; | |
236 curr = curr->next; | |
237 } | |
238 return NULL; | |
239 } | |
240 | |
9328 | 241 /* |
9434 | 242 Converts strings to utf-8 if necessary using user specified encoding |
9328 | 243 */ |
244 | |
9434 | 245 static gchar *zephyr_recv_convert(gchar *string, int len) |
8560 | 246 { |
247 gchar *utf8; | |
248 GError *err = NULL; | |
8644 | 249 |
250 if (g_utf8_validate(string, len, NULL)) { | |
8568 | 251 return g_strdup(string); |
252 } else { | |
8644 | 253 utf8 = g_convert(string, len, "UTF-8", gaim_account_get_string(zgc->account, "encoding", ZEPHYR_FALLBACK_CHARSET), NULL, NULL, &err); |
8568 | 254 if (err) { |
255 gaim_debug(GAIM_DEBUG_ERROR, "zephyr", "recv conversion error: %s\n", err->message); | |
256 utf8 = g_strdup(_("(There was an error converting this message. Check the 'Encoding' option in the Account Editor)")); | |
8954 | 257 g_error_free(err); |
8568 | 258 } |
259 | |
260 return utf8; | |
261 } | |
8560 | 262 } |
263 | |
2086 | 264 /* utility macros that are useful for zephyr_to_html */ |
265 | |
266 #define IS_OPENER(c) ((c == '{') || (c == '[') || (c == '(') || (c == '<')) | |
267 #define IS_CLOSER(c) ((c == '}') || (c == ']') || (c == ')') || (c == '>')) | |
268 | |
8451 | 269 /* This parses HTML formatting (put out by one of the gtkimhtml widgets |
270 And converts it to zephyr formatting. | |
271 It currently deals properly with <b>, <br>, <i>, <font face=...>, <font color=...>, | |
272 It ignores <font back=...> | |
273 It does | |
274 <font size = "1 or 2" -> @small | |
275 3 or 4 @medium() | |
276 5,6, or 7 @large() | |
277 <a href is dealt with by ignoring the description and outputting the link | |
278 */ | |
279 | |
280 static char *html_to_zephyr(const char *message) | |
281 { | |
8644 | 282 int len, cnt, retcount; |
283 char *ret; | |
284 | |
285 len = strlen(message); | |
9478 | 286 if (!len) |
287 return g_strdup(""); | |
288 | |
8644 | 289 ret = g_new0(char, len * 3); |
290 | |
291 bzero(ret, len * 3); | |
292 retcount = 0; | |
293 cnt = 0; | |
294 while (cnt <= len) { | |
295 if (message[cnt] == '<') { | |
296 if (!g_ascii_strncasecmp(message + cnt + 1, "i>", 2)) { | |
297 strncpy(ret + retcount, "@i(", 3); | |
298 cnt += 3; | |
299 retcount += 3; | |
300 } else if (!g_ascii_strncasecmp(message + cnt + 1, "b>", 2)) { | |
301 strncpy(ret + retcount, "@b(", 3); | |
302 cnt += 3; | |
303 retcount += 3; | |
304 } else if (!g_ascii_strncasecmp(message + cnt + 1, "br>", 3)) { | |
305 strncpy(ret + retcount, "\n", 1); | |
306 cnt += 4; | |
307 retcount += 1; | |
308 } else if (!g_ascii_strncasecmp(message + cnt + 1, "a href=\"", 8)) { | |
309 cnt += 9; | |
310 while (g_ascii_strncasecmp(message + cnt, "\">", 2) != 0) { | |
311 ret[retcount] = message[cnt]; | |
312 retcount++; | |
313 cnt++; | |
314 } | |
315 cnt += 2; | |
316 /* ignore descriptive string */ | |
317 while (g_ascii_strncasecmp(message + cnt, "</a>", 4) != 0) { | |
318 cnt++; | |
319 } | |
320 cnt += 4; | |
321 } else if (!g_ascii_strncasecmp(message + cnt + 1, "font", 4)) { | |
322 cnt += 5; | |
323 while (!g_ascii_strncasecmp(message + cnt, " ", 1)) | |
324 cnt++; | |
325 if (!g_ascii_strncasecmp(message + cnt, "color=\"", 7)) { | |
326 cnt += 7; | |
327 strncpy(ret + retcount, "@color(", 7); | |
328 retcount += 7; | |
329 while (g_ascii_strncasecmp(message + cnt, "\">", 2) != 0) { | |
330 ret[retcount] = message[cnt]; | |
331 retcount++; | |
332 cnt++; | |
333 } | |
334 ret[retcount] = ')'; | |
335 retcount++; | |
336 cnt += 2; | |
337 } else if (!g_ascii_strncasecmp(message + cnt, "face=\"", 6)) { | |
338 cnt += 6; | |
339 strncpy(ret + retcount, "@font(", 6); | |
340 retcount += 6; | |
341 while (g_ascii_strncasecmp(message + cnt, "\">", 2) != 0) { | |
342 ret[retcount] = message[cnt]; | |
343 retcount++; | |
344 cnt++; | |
345 } | |
346 ret[retcount] = ')'; | |
347 retcount++; | |
348 cnt += 2; | |
349 } else if (!g_ascii_strncasecmp(message + cnt, "size=\"", 6)) { | |
350 cnt += 6; | |
351 if ((message[cnt] == '1') || (message[cnt] == '2')) { | |
352 strncpy(ret + retcount, "@small(", 7); | |
353 retcount += 7; | |
354 } else if ((message[cnt] == '3') | |
355 || (message[cnt] == '4')) { | |
356 strncpy(ret + retcount, "@medium(", 8); | |
357 retcount += 8; | |
358 } else if ((message[cnt] == '5') | |
359 || (message[cnt] == '6') | |
360 || (message[cnt] == '7')) { | |
361 strncpy(ret + retcount, "@large(", 7); | |
362 retcount += 7; | |
363 } | |
364 cnt += 3; | |
365 } else { | |
366 /* Drop all unrecognized/misparsed font tags */ | |
367 while (g_ascii_strncasecmp(message + cnt, "\">", 2) != 0) { | |
368 cnt++; | |
369 } | |
370 cnt += 2; | |
371 } | |
372 } else if (!g_ascii_strncasecmp(message + cnt + 1, "/i>", 3) | |
373 || !g_ascii_strncasecmp(message + cnt + 1, "/b>", 3)) { | |
374 cnt += 4; | |
375 ret[retcount] = ')'; | |
376 retcount++; | |
377 } else if (!g_ascii_strncasecmp(message + cnt + 1, "/font>", 6)) { | |
378 cnt += 7; | |
379 strncpy(ret + retcount, "@font(fixed)", 12); | |
380 retcount += 12; | |
381 } else { | |
382 /* Catch all for all unrecognized/misparsed <foo> tage */ | |
383 while (g_ascii_strncasecmp(message + cnt, ">", 1) != 0) { | |
384 ret[retcount] = message[cnt]; | |
385 retcount++; | |
386 cnt++; | |
387 } | |
388 } | |
389 } else { | |
390 /* Duh */ | |
391 ret[retcount] = message[cnt]; | |
392 retcount++; | |
393 cnt++; | |
394 } | |
395 } | |
396 return ret; | |
8451 | 397 } |
398 | |
2086 | 399 /* this parses zephyr formatting and converts it to html. For example, if |
400 * you pass in "@{@color(blue)@i(hello)}" you should get out | |
401 * "<font color=blue><i>hello</i></font>". */ | |
402 static char *zephyr_to_html(char *message) | |
403 { | |
404 int len, cnt; | |
405 zframe *frames, *curr; | |
406 char *ret; | |
407 | |
408 frames = g_new(zframe, 1); | |
409 frames->text = g_string_new(""); | |
410 frames->enclosing = NULL; | |
411 frames->closing = ""; | |
412 frames->has_closer = FALSE; | |
413 | |
414 len = strlen(message); | |
415 cnt = 0; | |
416 while (cnt <= len) { | |
417 if (message[cnt] == '@') { | |
418 zframe *new_f; | |
419 char *buf; | |
420 int end; | |
8644 | 421 |
422 for (end = 1; (cnt + end) <= len && !IS_OPENER(message[cnt + end]) | |
423 && !IS_CLOSER(message[cnt + end]); end++); | |
2086 | 424 buf = g_new0(char, end); |
8644 | 425 |
2086 | 426 if (end) { |
8644 | 427 g_snprintf(buf, end, "%s", message + cnt + 1); |
2086 | 428 } |
8644 | 429 if (!g_ascii_strcasecmp(buf, "italic") || !g_ascii_strcasecmp(buf, "i")) { |
2086 | 430 new_f = g_new(zframe, 1); |
431 new_f->enclosing = frames; | |
432 new_f->text = g_string_new("<i>"); | |
433 new_f->closing = "</i>"; | |
434 new_f->has_closer = TRUE; | |
435 frames = new_f; | |
8644 | 436 cnt += end + 1; /* cnt points to char after opener */ |
437 } else if (!g_ascii_strcasecmp(buf, "small")) { | |
438 new_f = g_new(zframe, 1); | |
439 new_f->enclosing = frames; | |
440 new_f->text = g_string_new("<font size=\"1\">"); | |
441 new_f->closing = "</font>"; | |
442 frames = new_f; | |
443 cnt += end + 1; | |
444 } else if (!g_ascii_strcasecmp(buf, "medium")) { | |
445 new_f = g_new(zframe, 1); | |
446 new_f->enclosing = frames; | |
447 new_f->text = g_string_new("<font size=\"3\">"); | |
448 new_f->closing = "</font>"; | |
449 frames = new_f; | |
450 cnt += end + 1; | |
451 } else if (!g_ascii_strcasecmp(buf, "large")) { | |
452 new_f = g_new(zframe, 1); | |
453 new_f->enclosing = frames; | |
454 new_f->text = g_string_new("<font size=\"7\">"); | |
455 new_f->closing = "</font>"; | |
456 frames = new_f; | |
457 cnt += end + 1; | |
458 } else if (!g_ascii_strcasecmp(buf, "bold") | |
459 || !g_ascii_strcasecmp(buf, "b")) { | |
2086 | 460 new_f = g_new(zframe, 1); |
461 new_f->enclosing = frames; | |
462 new_f->text = g_string_new("<b>"); | |
463 new_f->closing = "</b>"; | |
464 new_f->has_closer = TRUE; | |
465 frames = new_f; | |
8644 | 466 cnt += end + 1; |
467 } else if (!g_ascii_strcasecmp(buf, "font")) { | |
468 cnt += end + 1; | |
8451 | 469 new_f = g_new(zframe, 1); |
470 new_f->enclosing = frames; | |
471 new_f->text = g_string_new("<font face="); | |
472 for (; (cnt <= len) && !IS_CLOSER(message[cnt]); cnt++) { | |
473 g_string_append_c(new_f->text, message[cnt]); | |
474 } | |
8644 | 475 cnt++; /* point to char after closer */ |
8451 | 476 g_string_append_c(new_f->text, '>'); |
477 new_f->closing = "</font>"; | |
478 new_f->has_closer = FALSE; | |
479 frames = new_f; | |
8568 | 480 } else if (!g_ascii_strcasecmp(buf, "color")) { |
8644 | 481 cnt += end + 1; |
2086 | 482 new_f = g_new(zframe, 1); |
483 new_f->enclosing = frames; | |
484 new_f->text = g_string_new("<font color="); | |
485 for (; (cnt <= len) && !IS_CLOSER(message[cnt]); cnt++) { | |
486 g_string_append_c(new_f->text, message[cnt]); | |
487 } | |
8644 | 488 cnt++; /* point to char after closer */ |
2086 | 489 g_string_append_c(new_f->text, '>'); |
490 new_f->closing = "</font>"; | |
491 new_f->has_closer = FALSE; | |
492 frames = new_f; | |
4793 | 493 } else if (!g_ascii_strcasecmp(buf, "")) { |
2086 | 494 new_f = g_new(zframe, 1); |
495 new_f->enclosing = frames; | |
496 new_f->text = g_string_new(""); | |
497 new_f->closing = ""; | |
498 new_f->has_closer = TRUE; | |
499 frames = new_f; | |
8644 | 500 cnt += end + 1; /* cnt points to char after opener */ |
2086 | 501 } else { |
8644 | 502 if ((cnt + end) > len) { |
2086 | 503 g_string_append_c(frames->text, '@'); |
504 cnt++; | |
8644 | 505 } else if (IS_CLOSER(message[cnt + end])) { |
506 /* We have @chars..closer . This is | |
507 merely a sequence of chars that isn't a formatting tag | |
508 */ | |
509 int tmp = cnt; | |
510 | |
511 while (tmp <= cnt + end) { | |
512 g_string_append_c(frames->text, message[tmp]); | |
513 tmp++; | |
514 } | |
515 cnt += end + 1; | |
516 } else { | |
2086 | 517 /* unrecognized thingie. act like it's not there, but we |
518 * still need to take care of the corresponding closer, | |
519 * make a frame that does nothing. */ | |
520 new_f = g_new(zframe, 1); | |
521 new_f->enclosing = frames; | |
522 new_f->text = g_string_new(""); | |
523 new_f->closing = ""; | |
524 new_f->has_closer = TRUE; | |
525 frames = new_f; | |
8644 | 526 cnt += end + 1; /* cnt points to char after opener */ |
2086 | 527 } |
528 } | |
529 } else if (IS_CLOSER(message[cnt])) { | |
530 zframe *popped; | |
531 gboolean last_had_closer; | |
8644 | 532 |
2086 | 533 if (frames->enclosing) { |
534 do { | |
535 popped = frames; | |
536 frames = frames->enclosing; | |
537 g_string_append(frames->text, popped->text->str); | |
538 g_string_append(frames->text, popped->closing); | |
539 g_string_free(popped->text, TRUE); | |
540 last_had_closer = popped->has_closer; | |
541 g_free(popped); | |
542 } while (frames && frames->enclosing && !last_had_closer); | |
543 } else { | |
544 g_string_append_c(frames->text, message[cnt]); | |
545 } | |
546 cnt++; | |
547 } else if (message[cnt] == '\n') { | |
548 g_string_append(frames->text, "<br>"); | |
549 cnt++; | |
550 } else { | |
551 g_string_append_c(frames->text, message[cnt++]); | |
552 } | |
553 } | |
554 /* go through all the stuff that they didn't close */ | |
555 while (frames->enclosing) { | |
556 curr = frames; | |
557 g_string_append(frames->enclosing->text, frames->text->str); | |
558 g_string_append(frames->enclosing->text, frames->closing); | |
559 g_string_free(frames->text, TRUE); | |
560 frames = frames->enclosing; | |
561 g_free(curr); | |
562 } | |
563 ret = frames->text->str; | |
564 g_string_free(frames->text, FALSE); | |
565 g_free(frames); | |
566 return ret; | |
567 } | |
568 | |
569 static gboolean pending_zloc(char *who) | |
570 { | |
571 GList *curr; | |
8644 | 572 |
2086 | 573 for (curr = pending_zloc_names; curr != NULL; curr = curr->next) { |
9328 | 574 char* normalized_who = local_zephyr_normalize(who); |
575 if (!g_ascii_strcasecmp(normalized_who, (char *)curr->data)) { | |
8644 | 576 g_free((char *)curr->data); |
2086 | 577 pending_zloc_names = g_list_remove(pending_zloc_names, curr->data); |
578 return TRUE; | |
579 } | |
580 } | |
581 return FALSE; | |
582 } | |
583 | |
9328 | 584 /* Called when the server notifies us a message couldn't get sent */ |
585 | |
8559 | 586 static void message_failed(ZNotice_t notice, struct sockaddr_in from) |
587 { | |
8644 | 588 if (g_ascii_strcasecmp(notice.z_class, "message")) { |
9328 | 589 gchar* chat_failed = g_strdup_printf(_("Unable send to chat %s,%s,%s"),notice.z_class,notice.z_class_inst,notice.z_recipient); |
590 gaim_notify_error(zgc,"",chat_failed,NULL); | |
591 g_free(chat_failed); | |
8644 | 592 } else { |
593 gaim_notify_error(zgc, notice.z_recipient, _("User is offline"), NULL); | |
594 } | |
8559 | 595 } |
596 | |
2086 | 597 static void handle_message(ZNotice_t notice, struct sockaddr_in from) |
598 { | |
4793 | 599 if (!g_ascii_strcasecmp(notice.z_class, LOGIN_CLASS)) { |
3277 | 600 /* well, we'll be updating in 20 seconds anyway, might as well ignore this. */ |
4793 | 601 } else if (!g_ascii_strcasecmp(notice.z_class, LOCATE_CLASS)) { |
602 if (!g_ascii_strcasecmp(notice.z_opcode, LOCATE_LOCATE)) { | |
2086 | 603 int nlocs; |
604 char *user; | |
6695 | 605 GaimBuddy *b; |
2086 | 606 |
9478 | 607 /* XXX add real error reporting */ |
2086 | 608 if (ZParseLocations(¬ice, NULL, &nlocs, &user) != ZERR_NONE) |
609 return; | |
8435 | 610 |
8644 | 611 if ((b = gaim_find_buddy(zgc->account, user)) == NULL) { |
2086 | 612 char *e = strchr(user, '@'); |
8644 | 613 |
614 if (e && !g_ascii_strcasecmp(e + 1, gaim_zephyr_get_realm())) { | |
615 *e = '\0'; | |
616 } | |
4687 | 617 b = gaim_find_buddy(zgc->account, user); |
8644 | 618 } |
619 if ((b && pending_zloc(b->name)) || pending_zloc(user)) { | |
2086 | 620 ZLocations_t locs; |
621 int one = 1; | |
622 GString *str = g_string_new(""); | |
8644 | 623 |
624 g_string_append_printf(str, _("<b>User:</b> %s<br>"), b ? b->name : user); | |
8435 | 625 if (b && b->alias) |
5132 | 626 g_string_append_printf(str, _("<b>Alias:</b> %s<br>"), b->alias); |
2086 | 627 if (!nlocs) { |
5132 | 628 g_string_append_printf(str, _("<br>Hidden or not logged-in")); |
2086 | 629 } |
630 for (; nlocs > 0; nlocs--) { | |
9478 | 631 /* XXX add real error reporting */ |
2086 | 632 ZGetLocations(&locs, &one); |
8644 | 633 g_string_append_printf(str, _("<br>At %s since %s"), locs.host, locs.time); |
2086 | 634 } |
8644 | 635 gaim_notify_formatted(zgc, NULL, _("Buddy Information"), NULL, str->str, NULL, NULL); |
2086 | 636 g_string_free(str, TRUE); |
637 } else | |
4732 | 638 serv_got_update(zgc, b->name, nlocs, 0, 0, 0, 0); |
2086 | 639 |
9434 | 640 g_free(user); |
2086 | 641 } |
642 } else { | |
8560 | 643 char *buf, *buf2, *buf3; |
2804
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
644 char *send_inst; |
8644 | 645 GaimConversation *gconv1; |
646 GaimConvChat *gcc; | |
2086 | 647 char *ptr = notice.z_message + strlen(notice.z_message) + 1; |
9478 | 648 int len; |
8644 | 649 char *sendertmp = g_strdup_printf("%s", gaim_zephyr_get_sender()); |
9478 | 650 int signature_length = strlen(notice.z_message); |
651 int message_has_no_body = 0; | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7084
diff
changeset
|
652 GaimConvImFlags flags = 0; |
8644 | 653 gchar *tmpescape; |
8560 | 654 |
9478 | 655 /* Need to deal with 0 length messages to handle typing notification (OPCODE) ping messages */ |
656 /* One field zephyrs would have caused gaim to crash */ | |
657 if ( (notice.z_message_len == 0) || (signature_length >= notice.z_message_len - 1)) { | |
658 message_has_no_body = 1; | |
659 len = 0; | |
660 gaim_debug_info("zephyr","message_size %d %d %d\n",len,notice.z_message_len,signature_length); | |
661 buf3 = g_strdup(""); | |
662 | |
663 } else { | |
664 len = notice.z_message_len - ( signature_length +1); | |
665 gaim_debug_info("zephyr","message_size %d %d %d\n",len,notice.z_message_len,signature_length); | |
8644 | 666 buf = g_malloc(len + 1); |
667 g_snprintf(buf, len + 1, "%s", ptr); | |
668 g_strchomp(buf); | |
669 tmpescape = gaim_escape_html(buf); | |
9478 | 670 g_free(buf); |
8644 | 671 buf2 = zephyr_to_html(tmpescape); |
672 buf3 = zephyr_recv_convert(buf2, strlen(buf2)); | |
673 g_free(buf2); | |
674 g_free(tmpescape); | |
9478 | 675 } |
8644 | 676 |
9328 | 677 if (!g_ascii_strcasecmp(notice.z_class, "MESSAGE") && !g_ascii_strcasecmp(notice.z_class_inst, "PERSONAL") |
678 && !g_ascii_strcasecmp(notice.z_recipient,gaim_zephyr_get_sender())) { | |
679 gchar* stripped_sender; | |
4793 | 680 if (!g_ascii_strcasecmp(notice.z_message, "Automated reply:")) |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7084
diff
changeset
|
681 flags |= GAIM_CONV_IM_AUTO_RESP; |
9328 | 682 stripped_sender = zephyr_strip_foreign_realm(notice.z_sender); |
9478 | 683 |
684 if (!g_ascii_strcasecmp(notice.z_opcode,"PING")) | |
685 serv_got_typing(zgc,stripped_sender,ZEPHYR_TYPING_RECV_TIMEOUT, GAIM_TYPING); | |
686 else | |
9328 | 687 serv_got_im(zgc, stripped_sender, buf3, flags, time(NULL)); |
9478 | 688 |
9328 | 689 g_free(stripped_sender); |
2086 | 690 } else { |
691 zephyr_triple *zt1, *zt2; | |
9437 | 692 gchar *send_inst_utf8; |
693 | |
8644 | 694 zt1 = new_triple(notice.z_class, notice.z_class_inst, notice.z_recipient); |
2086 | 695 zt2 = find_sub_by_triple(zt1); |
696 if (!zt2) { | |
9434 | 697 /* This is a server supplied subscription */ |
698 subscrips = g_slist_append(subscrips, zt1); | |
699 zt2 = find_sub_by_triple(zt1); | |
700 } | |
701 | |
9437 | 702 if (!zt2->open) { |
703 zt2->open = TRUE; | |
704 serv_got_joined_chat(zgc, zt2->id, zt2->name); | |
705 zephyr_chat_set_topic(zgc,zt2->id,notice.z_class_inst); | |
706 } | |
707 g_free(sendertmp); /* fix memory leak? */ | |
708 /* If the person is in the default Realm, then strip the | |
709 Realm from the sender field */ | |
710 sendertmp = zephyr_strip_foreign_realm(notice.z_sender); | |
711 send_inst = g_strdup_printf("%s %s",sendertmp,notice.z_class_inst); | |
712 send_inst_utf8 = zephyr_recv_convert(send_inst, strlen(send_inst)); | |
713 if (!send_inst_utf8) { | |
714 gaim_debug(GAIM_DEBUG_ERROR, "zephyr","send_inst %s became null\n", send_inst); | |
715 send_inst_utf8 = "malformed instance"; | |
716 } | |
717 | |
9584 | 718 serv_got_chat_in(zgc, zt2->id, send_inst_utf8, 0, buf3, time(NULL)); |
9437 | 719 g_free(send_inst); |
720 gconv1 = gaim_find_conversation_with_account(zt2->name, zgc->account); | |
721 gcc = gaim_conversation_get_chat_data(gconv1); | |
722 | |
9554 | 723 if (!gaim_conv_chat_find_user(gcc, sendertmp)) { |
9437 | 724 /* force interpretation in network byte order */ |
725 unsigned char *addrs = (unsigned char *)&(notice.z_sender_addr.s_addr); | |
726 gchar* ipaddr = g_strdup_printf("%hhd.%hhd.%hhd.%hhd", (unsigned char)addrs[0], | |
727 (unsigned char)addrs[1], (unsigned char)addrs[2], | |
728 (unsigned char) addrs[3]); | |
729 | |
9554 | 730 gaim_conv_chat_add_user(gcc, sendertmp, ipaddr, GAIM_CBFLAGS_NONE); |
9437 | 731 g_free(ipaddr); /* fix memory leak? */ |
732 | |
733 } | |
734 g_free(sendertmp); | |
735 g_free(send_inst_utf8); | |
736 | |
2086 | 737 free_triple(zt1); |
738 } | |
8560 | 739 g_free(buf3); |
9478 | 740 |
2086 | 741 } |
742 } | |
743 | |
744 static gint check_notify(gpointer data) | |
745 { | |
9478 | 746 /* XXX add real error reporting */ |
747 | |
2086 | 748 while (ZPending()) { |
749 ZNotice_t notice; | |
750 struct sockaddr_in from; | |
9478 | 751 /* XXX add real error reporting */ |
8644 | 752 |
2086 | 753 z_call_r(ZReceiveNotice(¬ice, &from)); |
754 | |
755 switch (notice.z_kind) { | |
756 case UNSAFE: | |
757 case UNACKED: | |
758 case ACKED: | |
759 handle_message(notice, from); | |
760 break; | |
8644 | 761 case SERVACK: |
762 if (!(g_ascii_strcasecmp(notice.z_message, ZSRVACK_NOTSENT))) { | |
763 message_failed(notice, from); | |
764 } | |
765 break; | |
9328 | 766 case CLIENTACK: |
9478 | 767 gaim_debug_error("zephyr", "Client ack received\n"); |
2086 | 768 default: |
769 /* we'll just ignore things for now */ | |
9328 | 770 handle_unknown(notice); |
9478 | 771 gaim_debug_error("zephyr", "Unhandled notice.\n"); |
2086 | 772 break; |
773 } | |
9478 | 774 /* XXX add real error reporting */ |
2086 | 775 ZFreeNotice(¬ice); |
776 } | |
777 | |
778 return TRUE; | |
779 } | |
780 | |
781 static gint check_loc(gpointer data) | |
782 { | |
6695 | 783 GaimBlistNode *gnode, *cnode, *bnode; |
2086 | 784 ZAsyncLocateData_t ald; |
785 | |
786 ald.user = NULL; | |
787 memset(&(ald.uid), 0, sizeof(ZUnique_Id_t)); | |
788 ald.version = NULL; | |
789 | |
8644 | 790 for (gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) { |
791 if (!GAIM_BLIST_NODE_IS_GROUP(gnode)) | |
4785 | 792 continue; |
8644 | 793 for (cnode = gnode->child; cnode; cnode = cnode->next) { |
794 if (!GAIM_BLIST_NODE_IS_CONTACT(cnode)) | |
4785 | 795 continue; |
8644 | 796 for (bnode = cnode->child; bnode; bnode = bnode->next) { |
797 GaimBuddy *b = (GaimBuddy *) bnode; | |
798 | |
799 if (!GAIM_BLIST_NODE_IS_BUDDY(bnode)) | |
6695 | 800 continue; |
8644 | 801 if (b->account->gc == zgc) { |
7261 | 802 const char *chk; |
8644 | 803 |
8354 | 804 chk = local_zephyr_normalize(b->name); |
9478 | 805 /* XXX add real error reporting */ |
6695 | 806 /* doesn't matter if this fails or not; we'll just move on to the next one */ |
807 ZRequestLocations(chk, &ald, UNACKED, ZAUTH); | |
9434 | 808 g_free(ald.user); |
809 g_free(ald.version); | |
6695 | 810 } |
4349 | 811 } |
2086 | 812 } |
813 } | |
814 | |
815 return TRUE; | |
816 } | |
817 | |
818 static char *get_exposure_level() | |
819 { | |
9478 | 820 /* XXX add real error reporting */ |
2086 | 821 char *exposure = ZGetVariable("exposure"); |
822 | |
823 if (!exposure) | |
824 return EXPOSE_REALMVIS; | |
4793 | 825 if (!g_ascii_strcasecmp(exposure, EXPOSE_NONE)) |
2086 | 826 return EXPOSE_NONE; |
4793 | 827 if (!g_ascii_strcasecmp(exposure, EXPOSE_OPSTAFF)) |
2086 | 828 return EXPOSE_OPSTAFF; |
4793 | 829 if (!g_ascii_strcasecmp(exposure, EXPOSE_REALMANN)) |
2086 | 830 return EXPOSE_REALMANN; |
4793 | 831 if (!g_ascii_strcasecmp(exposure, EXPOSE_NETVIS)) |
2086 | 832 return EXPOSE_NETVIS; |
4793 | 833 if (!g_ascii_strcasecmp(exposure, EXPOSE_NETANN)) |
2086 | 834 return EXPOSE_NETANN; |
835 return EXPOSE_REALMVIS; | |
836 } | |
837 | |
838 static void strip_comments(char *str) | |
839 { | |
840 char *tmp = strchr(str, '#'); | |
8644 | 841 |
2086 | 842 if (tmp) |
843 *tmp = '\0'; | |
844 g_strchug(str); | |
845 g_strchomp(str); | |
846 } | |
847 | |
9478 | 848 static void zephyr_inithosts() |
849 { | |
850 /* XXX This code may not be Win32 clean */ | |
851 struct hostent *hent; | |
852 | |
853 if (gethostname(ourhost, sizeof(ourhost)-1) == -1) { | |
854 gaim_debug(GAIM_DEBUG_ERROR, "zephyr", "unable to retrieve hostname, %%host%% and %%canon%% will be wrong in subscriptions and have been set to unknown\n"); | |
855 g_stpcpy(ourhost,"unknown"); | |
856 g_stpcpy(ourhostcanon,"unknown"); | |
857 return; | |
858 } | |
859 | |
860 if (!(hent = gethostbyname(ourhost))) { | |
861 gaim_debug(GAIM_DEBUG_ERROR,"zephyr", "unable to resolve hostname, %%canon%% will be wrong in subscriptions.and has been set to the value of %%host%%, %s\n",ourhost); | |
862 g_stpcpy(ourhostcanon,ourhost); | |
863 return; | |
864 } | |
865 g_stpcpy(ourhostcanon,hent->h_name); | |
866 return; | |
867 } | |
868 | |
2086 | 869 static void process_zsubs() |
870 { | |
9434 | 871 /* Loads zephyr chats "(subscriptions) from ~/.zephyr.subs, and |
872 registers (subscribes to) them on the server */ | |
873 | |
874 /* XXX deal with unsubscriptions */ | |
875 /* XXX deal with punts */ | |
876 | |
2086 | 877 FILE *f; |
878 gchar *fname; | |
879 gchar buff[BUFSIZ]; | |
8644 | 880 |
9478 | 881 zephyr_inithosts(); |
3630 | 882 fname = g_strdup_printf("%s/.zephyr.subs", gaim_home_dir()); |
2086 | 883 f = fopen(fname, "r"); |
884 if (f) { | |
885 char **triple; | |
886 ZSubscription_t sub; | |
887 char *recip; | |
9478 | 888 char *z_class; |
889 char *z_instance; | |
8644 | 890 |
2086 | 891 while (fgets(buff, BUFSIZ, f)) { |
892 strip_comments(buff); | |
893 if (buff[0]) { | |
894 triple = g_strsplit(buff, ",", 3); | |
8644 | 895 if (triple[0] && triple[1]) { |
896 char *tmp = g_strdup_printf("%s", gaim_zephyr_get_sender()); | |
2804
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
897 char *atptr; |
8644 | 898 |
2086 | 899 sub.zsub_class = triple[0]; |
900 sub.zsub_classinst = triple[1]; | |
8644 | 901 if (triple[2] == NULL) { |
3277 | 902 recip = g_malloc0(1); |
4793 | 903 } else if (!g_ascii_strcasecmp(triple[2], "%me%")) { |
8644 | 904 recip = g_strdup_printf("%s", gaim_zephyr_get_sender()); |
4793 | 905 } else if (!g_ascii_strcasecmp(triple[2], "*")) { |
2804
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
906 /* wildcard |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
907 * form of class,instance,* */ |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
908 recip = g_malloc0(1); |
4793 | 909 } else if (!g_ascii_strcasecmp(triple[2], tmp)) { |
2804
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
910 /* form of class,instance,aatharuv@ATHENA.MIT.EDU */ |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
911 recip = g_strdup(triple[2]); |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
912 } else if ((atptr = strchr(triple[2], '@')) != NULL) { |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
913 /* form of class,instance,*@ANDREW.CMU.EDU |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
914 * class,instance,@ANDREW.CMU.EDU |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
915 * If realm is local realm, blank recipient, else |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
916 * @REALM-NAME |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
917 */ |
8644 | 918 char *realmat = g_strdup_printf("@%s", |
919 gaim_zephyr_get_realm()); | |
920 | |
4793 | 921 if (!g_ascii_strcasecmp(atptr, realmat)) |
2804
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
922 recip = g_malloc0(1); |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
923 else |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
924 recip = g_strdup(atptr); |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
925 g_free(realmat); |
2086 | 926 } else { |
927 recip = g_strdup(triple[2]); | |
928 } | |
2804
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
929 g_free(tmp); |
2086 | 930 sub.zsub_recipient = recip; |
9478 | 931 |
932 if (!g_ascii_strcasecmp(triple[0],"%host%")) { | |
933 z_class = g_strdup(ourhost); | |
934 } else if (!g_ascii_strcasecmp(triple[0],"%canon%")) { | |
935 z_class = g_strdup(ourhostcanon); | |
936 } else { | |
937 z_class = g_strdup(triple[0]); | |
938 } | |
939 sub.zsub_class = z_class; | |
940 | |
941 if (!g_ascii_strcasecmp(triple[1],"%host%")) { | |
942 z_instance = g_strdup(ourhost); | |
943 } else if (!g_ascii_strcasecmp(triple[1],"%canon%")) { | |
944 z_instance = g_strdup(ourhostcanon); | |
945 } else { | |
946 z_instance = g_strdup(triple[1]); | |
947 } | |
948 sub.zsub_classinst = z_instance; | |
949 | |
950 /* There should be some sort of error report listing classes that couldn't be subbed to. | |
951 Not important right now though */ | |
952 | |
2086 | 953 if (ZSubscribeTo(&sub, 1, 0) != ZERR_NONE) { |
9478 | 954 |
8644 | 955 gaim_debug(GAIM_DEBUG_ERROR, "zephyr", "Couldn't subscribe to %s, %s, %s\n", sub.zsub_class, sub.zsub_classinst, sub.zsub_recipient); |
2086 | 956 } |
9478 | 957 |
958 subscrips = g_slist_append(subscrips, new_triple(sub.zsub_class,sub.zsub_classinst,sub.zsub_recipient)); | |
959 /* g_hash_table_destroy(sub_hash_table); */ | |
960 g_free(z_instance); | |
961 g_free(z_class); | |
2086 | 962 g_free(recip); |
963 } | |
964 g_strfreev(triple); | |
965 } | |
966 } | |
967 } | |
968 } | |
969 | |
970 static void process_anyone() | |
971 { | |
972 FILE *fd; | |
973 gchar buff[BUFSIZ], *filename; | |
6695 | 974 GaimGroup *g; |
975 GaimBuddy *b; | |
4775 | 976 |
977 if (!(g = gaim_find_group(_("Anyone")))) { | |
978 g = gaim_group_new(_("Anyone")); | |
979 gaim_blist_add_group(g, NULL); | |
980 } | |
6695 | 981 |
3630 | 982 filename = g_strconcat(gaim_home_dir(), "/.anyone", NULL); |
2086 | 983 if ((fd = fopen(filename, "r")) != NULL) { |
984 while (fgets(buff, BUFSIZ, fd)) { | |
985 strip_comments(buff); | |
4687 | 986 if (buff[0]) { |
8644 | 987 if (!(b = gaim_find_buddy(zgc->account, buff))) { |
988 b = gaim_buddy_new(zgc->account, buff, NULL); | |
989 gaim_blist_add_buddy(b, NULL, g, NULL); | |
990 } | |
991 } | |
2086 | 992 } |
993 fclose(fd); | |
994 } | |
995 g_free(filename); | |
996 } | |
997 | |
8644 | 998 static void zephyr_login(GaimAccount * account) |
2086 | 999 { |
1000 ZSubscription_t sub; | |
9427 | 1001 |
9478 | 1002 /* This needs to fixed to deal with multiple accounts somehow */ |
2086 | 1003 if (zgc) { |
5436
ad445074d239
[gaim-migrate @ 5818]
Christian Hammond <chipx86@chipx86.com>
parents:
5234
diff
changeset
|
1004 gaim_notify_error(account->gc, NULL, |
8644 | 1005 _("Already logged in with Zephyr"), _("Because Zephyr uses your system username, you " "are unable to have multiple accounts on it " "when logged in as the same user.")); |
2086 | 1006 return; |
1007 } | |
1008 | |
5606 | 1009 zgc = gaim_account_get_connection(account); |
9478 | 1010 zgc->flags |= GAIM_CONNECTION_HTML | GAIM_CONNECTION_NO_BGCOLOR | GAIM_CONNECTION_NO_URLDESC; |
1011 gaim_connection_update_progress(zgc, _("Connecting"), 0, 8); | |
1012 | |
1013 /* XXX z_call_s should actually try to report the com_err determined error */ | |
8645 | 1014 |
2086 | 1015 z_call_s(ZInitialize(), "Couldn't initialize zephyr"); |
9478 | 1016 z_call_s(ZOpenPort(&zephyr_port), "Couldn't open port"); |
8644 | 1017 z_call_s(ZSetLocation((char *) |
1018 gaim_account_get_string(zgc->account, "exposure_level", EXPOSE_REALMVIS)), "Couldn't set location"); | |
2086 | 1019 |
1020 sub.zsub_class = "MESSAGE"; | |
1021 sub.zsub_classinst = "PERSONAL"; | |
8354 | 1022 sub.zsub_recipient = (char *)gaim_zephyr_get_sender(); |
9427 | 1023 |
2086 | 1024 if (ZSubscribeTo(&sub, 1, 0) != ZERR_NONE) { |
9478 | 1025 /* XXX don't translate this yet. It could be written better */ |
1026 /* XXX error messages could be handled with more detail */ | |
1027 gaim_notify_error(account->gc, NULL, | |
1028 "Unable to subscribe to messages", "Unable to subscribe to initial messages"); | |
1029 return; | |
2086 | 1030 } |
1031 | |
5606 | 1032 gaim_connection_set_state(zgc, GAIM_CONNECTED); |
2086 | 1033 serv_finish_login(zgc); |
1034 | |
1035 process_anyone(); | |
1036 process_zsubs(); | |
1037 | |
8273
f24172f53650
[gaim-migrate @ 8997]
Christian Hammond <chipx86@chipx86.com>
parents:
8212
diff
changeset
|
1038 nottimer = gaim_timeout_add(100, check_notify, NULL); |
f24172f53650
[gaim-migrate @ 8997]
Christian Hammond <chipx86@chipx86.com>
parents:
8212
diff
changeset
|
1039 loctimer = gaim_timeout_add(20000, check_loc, NULL); |
2086 | 1040 } |
1041 | |
1042 static void write_zsubs() | |
1043 { | |
9434 | 1044 /* Exports subscription (chat) list back to |
1045 * .zephyr.subs | |
1046 * XXX deal with %host%, %canon%, unsubscriptions, and negative subscriptions (punts?) | |
1047 */ | |
1048 | |
2086 | 1049 GSList *s = subscrips; |
1050 zephyr_triple *zt; | |
1051 FILE *fd; | |
1052 char *fname; | |
1053 | |
8644 | 1054 char **triple; |
1055 | |
3630 | 1056 fname = g_strdup_printf("%s/.zephyr.subs", gaim_home_dir()); |
2086 | 1057 fd = fopen(fname, "w"); |
8644 | 1058 |
2086 | 1059 if (!fd) { |
1060 g_free(fname); | |
1061 return; | |
1062 } | |
8644 | 1063 |
2086 | 1064 while (s) { |
9478 | 1065 char *zclass, *zinst, *zrecip; |
2086 | 1066 zt = s->data; |
8644 | 1067 triple = g_strsplit(zt->name, ",", 3); |
9478 | 1068 |
1069 /* deal with classes */ | |
1070 if (!g_ascii_strcasecmp(triple[0],ourhost)) { | |
1071 zclass = g_strdup("%host%");; | |
1072 } else if (!g_ascii_strcasecmp(triple[0],ourhostcanon)) { | |
1073 zclass = g_strdup("%canon%");; | |
1074 } else { | |
1075 zclass = g_strdup(triple[0]); | |
1076 } | |
1077 | |
1078 /* deal with instances */ | |
1079 | |
1080 if (!g_ascii_strcasecmp(triple[1],ourhost)) { | |
1081 zinst = g_strdup("%host%");; | |
1082 } else if (!g_ascii_strcasecmp(triple[1],ourhostcanon)) { | |
1083 zinst = g_strdup("%canon%");; | |
3277 | 1084 } else { |
9478 | 1085 zinst = g_strdup(triple[1]); |
3277 | 1086 } |
9478 | 1087 |
1088 /* deal with recipients */ | |
1089 if (triple[2] == NULL) { | |
1090 zrecip = g_strdup("*"); | |
1091 } else if (!g_ascii_strcasecmp(triple[2],"")){ | |
1092 zrecip = g_strdup("*"); | |
1093 } else if (!g_ascii_strcasecmp(triple[2], gaim_zephyr_get_sender())) { | |
1094 zrecip = g_strdup("%me%"); | |
3277 | 1095 } else { |
9478 | 1096 zrecip = g_strdup(triple[2]); |
3277 | 1097 } |
9478 | 1098 |
1099 fprintf(fd, "%s,%s,%s\n",zclass,zinst,zrecip); | |
1100 | |
1101 g_free(zclass); | |
1102 g_free(zinst); | |
1103 g_free(zrecip); | |
3277 | 1104 g_free(triple); |
2086 | 1105 s = s->next; |
1106 } | |
1107 g_free(fname); | |
1108 fclose(fd); | |
1109 } | |
1110 | |
1111 static void write_anyone() | |
1112 { | |
6695 | 1113 GaimBlistNode *gnode, *cnode, *bnode; |
1114 GaimBuddy *b; | |
3277 | 1115 char *ptr, *fname, *ptr2; |
2086 | 1116 FILE *fd; |
1117 | |
3630 | 1118 fname = g_strdup_printf("%s/.anyone", gaim_home_dir()); |
2086 | 1119 fd = fopen(fname, "w"); |
1120 if (!fd) { | |
1121 g_free(fname); | |
1122 return; | |
1123 } | |
1124 | |
8644 | 1125 for (gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) { |
1126 if (!GAIM_BLIST_NODE_IS_GROUP(gnode)) | |
4785 | 1127 continue; |
8644 | 1128 for (cnode = gnode->child; cnode; cnode = cnode->next) { |
1129 if (!GAIM_BLIST_NODE_IS_CONTACT(cnode)) | |
4785 | 1130 continue; |
8644 | 1131 for (bnode = cnode->child; bnode; bnode = bnode->next) { |
1132 if (!GAIM_BLIST_NODE_IS_BUDDY(bnode)) | |
6695 | 1133 continue; |
8644 | 1134 b = (GaimBuddy *) bnode; |
1135 if (b->account == zgc->account) { | |
6695 | 1136 if ((ptr = strchr(b->name, '@')) != NULL) { |
1137 ptr2 = ptr + 1; | |
1138 /* We should only strip the realm name if the principal | |
1139 is in the user's realm | |
8644 | 1140 */ |
1141 if (!g_ascii_strcasecmp(ptr2, gaim_zephyr_get_realm())) { | |
6695 | 1142 *ptr = '\0'; |
1143 } | |
4349 | 1144 } |
6695 | 1145 fprintf(fd, "%s\n", b->name); |
1146 if (ptr) | |
1147 *ptr = '@'; | |
3277 | 1148 } |
1149 } | |
2086 | 1150 } |
1151 } | |
1152 | |
1153 fclose(fd); | |
1154 g_free(fname); | |
1155 } | |
1156 | |
8644 | 1157 static void zephyr_close(GaimConnection * gc) |
2086 | 1158 { |
1159 GList *l; | |
1160 GSList *s; | |
8644 | 1161 |
2086 | 1162 l = pending_zloc_names; |
1163 while (l) { | |
8644 | 1164 g_free((char *)l->data); |
2086 | 1165 l = l->next; |
1166 } | |
1167 g_list_free(pending_zloc_names); | |
8644 | 1168 |
1169 if (gaim_account_get_bool(zgc->account, "write_anyone", FALSE)) | |
8212 | 1170 write_anyone(); |
8644 | 1171 |
1172 if (gaim_account_get_bool(zgc->account, "write_zsubs", FALSE)) | |
8212 | 1173 write_zsubs(); |
8644 | 1174 |
2086 | 1175 s = subscrips; |
1176 while (s) { | |
8644 | 1177 free_triple((zephyr_triple *) s->data); |
2086 | 1178 s = s->next; |
1179 } | |
1180 g_slist_free(subscrips); | |
8644 | 1181 |
2086 | 1182 if (nottimer) |
8287
ef881489396e
[gaim-migrate @ 9011]
Christian Hammond <chipx86@chipx86.com>
parents:
8273
diff
changeset
|
1183 gaim_timeout_remove(nottimer); |
2086 | 1184 nottimer = 0; |
1185 if (loctimer) | |
8287
ef881489396e
[gaim-migrate @ 9011]
Christian Hammond <chipx86@chipx86.com>
parents:
8273
diff
changeset
|
1186 gaim_timeout_remove(loctimer); |
2086 | 1187 loctimer = 0; |
1188 zgc = NULL; | |
1189 z_call(ZCancelSubscriptions(0)); | |
1190 z_call(ZUnsetLocation()); | |
1191 z_call(ZClosePort()); | |
1192 } | |
1193 | |
9434 | 1194 static int zephyr_send_message(char* zclass, char* instance, char* recipient, const char *im, |
9478 | 1195 const char *sig, char *opcode) ; |
9434 | 1196 |
1197 const char * zephyr_get_signature() | |
1198 { | |
9478 | 1199 /* XXX add zephyr error reporting */ |
1200 const char * sig =ZGetVariable("zwrite-signature"); | |
9434 | 1201 if (!sig) { |
1202 sig = g_get_real_name(); | |
1203 } | |
1204 return sig; | |
1205 } | |
1206 | |
8644 | 1207 static int zephyr_chat_send(GaimConnection * gc, int id, const char *im) |
2086 | 1208 { |
1209 zephyr_triple *zt; | |
1210 const char *sig; | |
8644 | 1211 GaimConversation *gconv1; |
1212 GaimConvChat *gcc; | |
1213 char *inst; | |
9434 | 1214 char *recipient; |
2086 | 1215 |
1216 zt = find_sub_by_id(id); | |
1217 if (!zt) | |
1218 /* this should never happen. */ | |
2167
edf8c5a70e5b
[gaim-migrate @ 2177]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2162
diff
changeset
|
1219 return -EINVAL; |
8644 | 1220 |
9434 | 1221 sig = zephyr_get_signature(); |
2086 | 1222 |
8644 | 1223 gconv1 = gaim_find_conversation_with_account(zt->name, zgc->account); |
1224 gcc = gaim_conversation_get_chat_data(gconv1); | |
8212 | 1225 |
8644 | 1226 if (!(inst = (char *)gaim_conv_chat_get_topic(gcc))) |
9434 | 1227 inst = g_strdup("PERSONAL"); |
8644 | 1228 |
4793 | 1229 if (!g_ascii_strcasecmp(zt->recipient, "*")) |
9434 | 1230 recipient = local_zephyr_normalize(""); |
2086 | 1231 else |
9434 | 1232 recipient = local_zephyr_normalize(zt->recipient); |
8451 | 1233 |
9478 | 1234 zephyr_send_message(zt->class,inst,recipient,im,sig,""); |
9434 | 1235 /* g_free(inst); */ |
1236 /* g_free(recipient); */ | |
2167
edf8c5a70e5b
[gaim-migrate @ 2177]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2162
diff
changeset
|
1237 return 0; |
2086 | 1238 } |
1239 | |
9434 | 1240 |
8644 | 1241 static int zephyr_send_im(GaimConnection * gc, const char *who, const char *im, GaimConvImFlags flags) |
1242 { | |
2086 | 1243 const char *sig; |
8644 | 1244 |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7084
diff
changeset
|
1245 if (flags & GAIM_CONV_IM_AUTO_RESP) |
2086 | 1246 sig = "Automated reply:"; |
1247 else { | |
9434 | 1248 sig = zephyr_get_signature(); |
2086 | 1249 } |
9478 | 1250 zephyr_send_message("MESSAGE","PERSONAL",local_zephyr_normalize(who),im,sig,""); |
9434 | 1251 |
1252 return 1; | |
1253 } | |
2086 | 1254 |
9434 | 1255 static int zephyr_send_message(char* zclass, char* instance, char* recipient, const char *im, |
9478 | 1256 const char *sig, char *opcode) |
9434 | 1257 { |
1258 char *html_buf; | |
1259 char *html_buf2; | |
1260 char *buf; | |
1261 ZNotice_t notice; | |
8451 | 1262 |
9434 | 1263 html_buf = html_to_zephyr(im); |
1264 html_buf2 = gaim_unescape_html(html_buf); | |
1265 | |
1266 buf = g_strdup_printf("%s%c%s", sig, '\0', html_buf2); | |
2086 | 1267 bzero((char *)¬ice, sizeof(notice)); |
9434 | 1268 |
2086 | 1269 notice.z_kind = ACKED; |
1270 notice.z_port = 0; | |
1271 notice.z_opcode = ""; | |
9434 | 1272 notice.z_class = zclass; |
1273 notice.z_class_inst = instance; | |
1274 notice.z_recipient = recipient; | |
1275 notice.z_sender = 0; | |
1276 notice.z_default_format = "Class $class, Instance $instance:\n" "To: @bold($recipient) at $time $date\n" "From: @bold($1) <$sender>\n\n$2"; | |
8451 | 1277 notice.z_message_len = strlen(html_buf2) + strlen(sig) + 2; |
2086 | 1278 notice.z_message = buf; |
9478 | 1279 notice.z_opcode = g_strdup(opcode); |
1280 gaim_debug_info("zephyr","About to send notice"); | |
1281 if (! ZSendNotice(¬ice, ZAUTH) == ZERR_NONE) { | |
1282 /* XXX handle errors here */ | |
1283 return 0; | |
1284 } | |
1285 gaim_debug_info("zephyr","notice sent"); | |
1286 g_free(buf); | |
1287 | |
8644 | 1288 g_free(html_buf2); |
1289 g_free(html_buf); | |
8451 | 1290 |
9434 | 1291 return 1; |
2086 | 1292 } |
1293 | |
8644 | 1294 static const char *zephyr_normalize(const GaimAccount * account, const char *orig) |
2086 | 1295 { |
9328 | 1296 /* returns the string you gave it. Maybe this function shouldn't be here */ |
2086 | 1297 static char buf[80]; |
8644 | 1298 |
7126 | 1299 if (!g_ascii_strcasecmp(orig, "")) { |
1300 buf[0] = '\0'; | |
1301 return buf; | |
8354 | 1302 } else { |
8644 | 1303 g_snprintf(buf, 80, "%s", orig); |
1304 } | |
1305 return buf; | |
8354 | 1306 } |
1307 | |
1308 | |
9328 | 1309 char *local_zephyr_normalize(const char *orig) |
8354 | 1310 { |
9328 | 1311 /* |
1312 Basically the inverse of zephyr_strip_foreign_realm | |
1313 */ | |
8644 | 1314 static char buf[80]; |
1315 | |
8354 | 1316 if (!g_ascii_strcasecmp(orig, "")) { |
1317 buf[0] = '\0'; | |
1318 return buf; | |
7126 | 1319 } |
8644 | 1320 |
2086 | 1321 if (strchr(orig, '@')) { |
1322 g_snprintf(buf, 80, "%s", orig); | |
1323 } else { | |
8644 | 1324 g_snprintf(buf, 80, "%s@%s", orig, gaim_zephyr_get_realm()); |
2086 | 1325 } |
1326 return buf; | |
1327 } | |
1328 | |
9030 | 1329 static void zephyr_zloc(GaimConnection *gc, const char *who) |
2086 | 1330 { |
1331 ZAsyncLocateData_t ald; | |
9328 | 1332 gchar* normalized_who = local_zephyr_normalize(who); |
7261 | 1333 |
9328 | 1334 if (ZRequestLocations(normalized_who, &ald, UNACKED, ZAUTH) == ZERR_NONE) { |
9030 | 1335 pending_zloc_names = g_list_append(pending_zloc_names, |
9328 | 1336 g_strdup(normalized_who)); |
9478 | 1337 } else { |
1338 /* XXX deal with errors somehow */ | |
2086 | 1339 } |
1340 } | |
1341 | |
8644 | 1342 static void zephyr_set_away(GaimConnection * gc, const char *state, const char *msg) |
2086 | 1343 { |
4111
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
3867
diff
changeset
|
1344 if (gc->away) { |
2086 | 1345 g_free(gc->away); |
4111
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
3867
diff
changeset
|
1346 gc->away = NULL; |
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
3867
diff
changeset
|
1347 } |
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
3867
diff
changeset
|
1348 |
5132 | 1349 if (!g_ascii_strcasecmp(state, _("Hidden"))) { |
9478 | 1350 /* XXX handle errors */ |
2086 | 1351 ZSetLocation(EXPOSE_OPSTAFF); |
4111
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
3867
diff
changeset
|
1352 gc->away = g_strdup(""); |
9478 | 1353 } |
1354 else if (!g_ascii_strcasecmp(state, _("Online"))) { | |
1355 /* XXX handle errors */ | |
2086 | 1356 ZSetLocation(get_exposure_level()); |
9478 | 1357 } |
2086 | 1358 else /* state is GAIM_AWAY_CUSTOM */ if (msg) |
1359 gc->away = g_strdup(msg); | |
1360 } | |
1361 | |
8644 | 1362 static GList *zephyr_away_states(GaimConnection * gc) |
2086 | 1363 { |
1364 GList *m = NULL; | |
1365 | |
5132 | 1366 m = g_list_append(m, _("Online")); |
2086 | 1367 m = g_list_append(m, GAIM_AWAY_CUSTOM); |
5132 | 1368 m = g_list_append(m, _("Hidden")); |
2086 | 1369 |
1370 return m; | |
1371 } | |
1372 | |
8644 | 1373 static GList *zephyr_chat_info(GaimConnection * gc) |
1374 { | |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1375 GList *m = NULL; |
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1376 struct proto_chat_entry *pce; |
2086 | 1377 |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1378 pce = g_new0(struct proto_chat_entry, 1); |
8644 | 1379 |
7841 | 1380 pce->label = _("_Class:"); |
5234 | 1381 pce->identifier = "class"; |
3158 | 1382 m = g_list_append(m, pce); |
2086 | 1383 |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1384 pce = g_new0(struct proto_chat_entry, 1); |
8644 | 1385 |
7841 | 1386 pce->label = _("_Instance:"); |
5234 | 1387 pce->identifier = "instance"; |
3158 | 1388 m = g_list_append(m, pce); |
2086 | 1389 |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1390 pce = g_new0(struct proto_chat_entry, 1); |
8644 | 1391 |
7841 | 1392 pce->label = _("_Recipient:"); |
5234 | 1393 pce->identifier = "recipient"; |
3158 | 1394 m = g_list_append(m, pce); |
2086 | 1395 |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1396 return m; |
2086 | 1397 } |
1398 | |
9478 | 1399 /* Called when the server notifies us a message couldn't get sent */ |
1400 | |
1401 static void zephyr_subscribe_failed(ZSubscription_t *sub) | |
1402 { | |
1403 gchar* subscribe_failed = g_strdup_printf(_("Attempt to subscribe to %s,%s,%s failed"), sub->zsub_class, sub->zsub_classinst,sub->zsub_recipient); | |
1404 gaim_notify_error(zgc,"", subscribe_failed, NULL); | |
1405 g_free(subscribe_failed); | |
1406 } | |
1407 | |
8644 | 1408 static void zephyr_join_chat(GaimConnection * gc, GHashTable * data) |
2086 | 1409 { |
1410 ZSubscription_t sub; | |
1411 zephyr_triple *zt1, *zt2; | |
1412 const char *classname; | |
1413 const char *instname; | |
1414 const char *recip; | |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1415 |
5234 | 1416 classname = g_hash_table_lookup(data, "class"); |
1417 instname = g_hash_table_lookup(data, "instance"); | |
1418 recip = g_hash_table_lookup(data, "recipient"); | |
1419 | |
9478 | 1420 |
9328 | 1421 if (!classname) |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
1422 return; |
9478 | 1423 |
1424 if (!g_ascii_strcasecmp(classname,"%host%")) | |
1425 classname = g_strdup(ourhost); | |
1426 if (!g_ascii_strcasecmp(classname,"%canon%")) | |
1427 classname = g_strdup(ourhostcanon); | |
1428 | |
9328 | 1429 if (!instname || !strlen(instname)) |
1430 instname = "*"; | |
9478 | 1431 |
1432 if (!g_ascii_strcasecmp(instname,"%host%")) | |
1433 instname = g_strdup(ourhost); | |
1434 if (!g_ascii_strcasecmp(instname,"%canon%")) | |
1435 instname = g_strdup(ourhostcanon); | |
1436 | |
9328 | 1437 if (!recip || (*recip == '*')) |
1438 recip = ""; | |
4793 | 1439 if (!g_ascii_strcasecmp(recip, "%me%")) |
8354 | 1440 recip = gaim_zephyr_get_sender(); |
2086 | 1441 |
1442 zt1 = new_triple(classname, instname, recip); | |
1443 zt2 = find_sub_by_triple(zt1); | |
1444 if (zt2) { | |
1445 free_triple(zt1); | |
9328 | 1446 if (!zt2->open) { |
1447 if (!g_ascii_strcasecmp(instname,"*")) | |
1448 instname = "PERSONAL"; | |
9434 | 1449 serv_got_joined_chat(gc, zt2->id, zt2->name); |
1450 zephyr_chat_set_topic(zgc,zt2->id,instname); | |
9328 | 1451 zt2->open = TRUE; |
1452 } | |
2086 | 1453 return; |
1454 } | |
9434 | 1455 |
2086 | 1456 sub.zsub_class = zt1->class; |
1457 sub.zsub_classinst = zt1->instance; | |
1458 sub.zsub_recipient = zt1->recipient; | |
9434 | 1459 |
2086 | 1460 if (ZSubscribeTo(&sub, 1, 0) != ZERR_NONE) { |
9478 | 1461 /* XXX output better subscription information */ |
1462 zephyr_subscribe_failed(&sub); | |
2086 | 1463 free_triple(zt1); |
1464 return; | |
1465 } | |
1466 | |
1467 subscrips = g_slist_append(subscrips, zt1); | |
1468 zt1->open = TRUE; | |
1469 serv_got_joined_chat(gc, zt1->id, zt1->name); | |
9328 | 1470 if (!g_ascii_strcasecmp(instname,"*")) |
1471 instname = "PERSONAL"; | |
9434 | 1472 zephyr_chat_set_topic(zgc,zt1->id,instname); |
2086 | 1473 } |
1474 | |
8644 | 1475 static void zephyr_chat_leave(GaimConnection * gc, int id) |
2086 | 1476 { |
1477 zephyr_triple *zt; | |
8644 | 1478 |
2086 | 1479 zt = find_sub_by_id(id); |
1480 if (zt) { | |
1481 zt->open = FALSE; | |
1482 zt->id = ++last_id; | |
1483 } | |
1484 } | |
1485 | |
9478 | 1486 static GaimChat *zephyr_find_blist_chat(GaimAccount *account, const char *name) |
1487 { | |
1488 GaimBlistNode *gnode, *cnode; | |
1489 | |
1490 /* XXX needs to be %host%,%canon%, and %me% clean */ | |
1491 for(gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) { | |
1492 for(cnode = gnode->child; cnode; cnode = cnode->next) { | |
1493 GaimChat *chat = (GaimChat*)cnode; | |
1494 char *zclass, *inst, *recip; | |
1495 char** triple; | |
1496 if(!GAIM_BLIST_NODE_IS_CHAT(cnode)) | |
1497 continue; | |
1498 if(chat->account !=account) | |
1499 continue; | |
1500 if(!(zclass = g_hash_table_lookup(chat->components, "class"))) | |
1501 continue; | |
1502 if(!(inst = g_hash_table_lookup(chat->components, "instance"))) | |
1503 inst = g_strdup(""); | |
1504 if(!(recip = g_hash_table_lookup(chat->components, "recipient"))) | |
1505 recip = g_strdup(""); | |
1506 triple = g_strsplit(name,",",3); | |
1507 if (!g_ascii_strcasecmp(triple[0],zclass) && !g_ascii_strcasecmp(triple[1],inst) && !g_ascii_strcasecmp(triple[2],recip)) | |
1508 return chat; | |
1509 | |
1510 } | |
1511 } | |
1512 return NULL; | |
1513 } | |
8644 | 1514 static const char *zephyr_list_icon(GaimAccount * a, GaimBuddy * b) |
5202 | 1515 { |
1516 return "zephyr"; | |
1517 } | |
1518 | |
9478 | 1519 static int zephyr_send_typing(GaimConnection *gc, const char *who, int typing) { |
1520 gchar *recipient; | |
1521 if (!typing) | |
1522 return 0; | |
1523 /* XXX We probably should care if this fails. Or maybe we don't want to */ | |
1524 if (!who) { | |
1525 gaim_debug_info("zephyr", "who is null\n"); | |
1526 recipient = local_zephyr_normalize(""); | |
1527 } else { | |
1528 recipient = local_zephyr_normalize(who); | |
1529 } | |
1530 | |
1531 gaim_debug_info("zephyr","about to send typing notification to %s",recipient); | |
1532 zephyr_send_message("MESSAGE","PERSONAL",recipient,"","","PING"); | |
1533 gaim_debug_info("zephyr","sent typing notification"); | |
1534 return ZEPHYR_TYPING_SEND_TIMEOUT; | |
1535 } | |
8212 | 1536 |
9434 | 1537 |
1538 | |
8644 | 1539 static void zephyr_chat_set_topic(GaimConnection * gc, int id, const char *topic) |
1540 { | |
1541 zephyr_triple *zt; | |
1542 GaimConversation *gconv; | |
1543 GaimConvChat *gcc; | |
9434 | 1544 gchar *topic_utf8; |
8644 | 1545 char *sender = (char *)gaim_zephyr_get_sender(); |
8212 | 1546 |
8644 | 1547 zt = find_sub_by_id(id); |
1548 gconv = gaim_find_conversation_with_account(zt->name, zgc->account); | |
1549 gcc = gaim_conversation_get_chat_data(gconv); | |
9434 | 1550 |
1551 topic_utf8 = zephyr_recv_convert((gchar *)topic,strlen(topic)); | |
1552 gaim_conv_chat_set_topic(gcc,sender,topic_utf8); | |
1553 g_free(topic_utf8); | |
1554 return; | |
1555 } | |
1556 | |
1557 /* commands */ | |
1558 | |
1559 static GaimCmdRet zephyr_gaim_cmd_msg(GaimConversation *conv, | |
1560 const char *cmd, char **args, char **error) | |
1561 { | |
1562 char *recipient; | |
9478 | 1563 |
9434 | 1564 if (!g_ascii_strcasecmp(args[0],"*")) |
9478 | 1565 return GAIM_CMD_RET_FAILED; /* "*" is not a valid argument */ |
9434 | 1566 else |
1567 recipient = local_zephyr_normalize(args[0]); | |
1568 | |
9478 | 1569 if (strlen(recipient) < 1) |
1570 return GAIM_CMD_RET_FAILED; /* a null recipient is a chat message, not an IM */ | |
1571 | |
1572 if (zephyr_send_message("MESSAGE","PERSONAL",recipient,args[1],zephyr_get_signature(),"")) | |
9434 | 1573 return GAIM_CMD_RET_OK; |
1574 else | |
1575 return GAIM_CMD_RET_FAILED; | |
1576 } | |
1577 | |
1578 static GaimCmdRet zephyr_gaim_cmd_zlocate(GaimConversation *conv, | |
1579 const char *cmd, char **args, char **error) | |
1580 { | |
1581 zephyr_zloc(zgc,args[0]); | |
1582 return GAIM_CMD_RET_OK; | |
1583 } | |
1584 | |
1585 static GaimCmdRet zephyr_gaim_cmd_instance(GaimConversation *conv, | |
1586 const char *cmd, char **args, char **error) | |
1587 { | |
1588 /* Currently it sets the instance with leading spaces and | |
1589 * all. This might not be the best thing to do, though having | |
1590 * one word isn't ideal either. */ | |
1591 | |
1592 GaimConvChat *gc = gaim_conversation_get_chat_data(conv); | |
1593 int id = gc->id; | |
1594 const char* instance = args[0]; | |
1595 zephyr_chat_set_topic(zgc,id,instance); | |
1596 return GAIM_CMD_RET_OK; | |
1597 } | |
1598 | |
1599 static GaimCmdRet zephyr_gaim_cmd_joinchat_cir(GaimConversation *conv, | |
1600 const char *cmd, char **args, char **error) | |
1601 { | |
1602 /* Join a new zephyr chat */ | |
1603 GHashTable *triple = g_hash_table_new(NULL,NULL); | |
1604 g_hash_table_insert(triple,"class",args[0]); | |
1605 g_hash_table_insert(triple,"instance",args[1]); | |
1606 g_hash_table_insert(triple,"recipient",args[2]); | |
1607 zephyr_join_chat(zgc,triple); | |
1608 return GAIM_CMD_RET_OK; | |
1609 } | |
1610 | |
1611 static GaimCmdRet zephyr_gaim_cmd_zi(GaimConversation *conv, | |
1612 const char *cmd, char **args, char **error) | |
1613 { | |
1614 /* args = instance, message */ | |
9478 | 1615 if ( zephyr_send_message("message",args[0],"",args[1],zephyr_get_signature(),"")) |
9434 | 1616 return GAIM_CMD_RET_OK; |
1617 else | |
1618 return GAIM_CMD_RET_FAILED; | |
1619 } | |
1620 | |
1621 static GaimCmdRet zephyr_gaim_cmd_zci(GaimConversation *conv, | |
1622 const char *cmd, char **args, char **error) | |
1623 { | |
1624 /* args = class, instance, message */ | |
9478 | 1625 if ( zephyr_send_message(args[0],args[1],"",args[2],zephyr_get_signature(),"")) |
9434 | 1626 return GAIM_CMD_RET_OK; |
1627 else | |
1628 return GAIM_CMD_RET_FAILED; | |
1629 } | |
8644 | 1630 |
9434 | 1631 static GaimCmdRet zephyr_gaim_cmd_zcir(GaimConversation *conv, |
1632 const char *cmd, char **args, char **error) | |
1633 { | |
1634 /* args = class, instance, recipient, message */ | |
9478 | 1635 if ( zephyr_send_message(args[0],args[1],args[2],args[3],zephyr_get_signature(),"")) |
9434 | 1636 return GAIM_CMD_RET_OK; |
1637 else | |
1638 return GAIM_CMD_RET_FAILED; | |
8212 | 1639 } |
1640 | |
9434 | 1641 static GaimCmdRet zephyr_gaim_cmd_zir(GaimConversation *conv, |
1642 const char *cmd, char **args, char **error) | |
1643 { | |
1644 /* args = instance, recipient, message */ | |
9478 | 1645 if ( zephyr_send_message("message",args[0],args[1],args[2],zephyr_get_signature(),"")) |
9434 | 1646 return GAIM_CMD_RET_OK; |
1647 else | |
1648 return GAIM_CMD_RET_FAILED; | |
1649 } | |
1650 | |
1651 static GaimCmdRet zephyr_gaim_cmd_zc(GaimConversation *conv, | |
1652 const char *cmd, char **args, char **error) | |
1653 { | |
1654 /* args = class, message */ | |
9478 | 1655 if ( zephyr_send_message(args[0],"PERSONAL","",args[1],zephyr_get_signature(),"")) |
9434 | 1656 return GAIM_CMD_RET_OK; |
1657 else | |
1658 return GAIM_CMD_RET_FAILED; | |
1659 } | |
1660 | |
1661 static void zephyr_register_slash_commands() | |
1662 { | |
1663 | |
1664 gaim_cmd_register("msg","ws", GAIM_CMD_P_PRPL, | |
1665 GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
1666 "prpl-zephyr", | |
1667 zephyr_gaim_cmd_msg, _("msg <nick> <message>: Send a private message to a user")); | |
1668 | |
1669 gaim_cmd_register("zlocate","w", GAIM_CMD_P_PRPL, | |
1670 GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
1671 "prpl-zephyr", | |
1672 zephyr_gaim_cmd_zlocate, _("zlocate <nick>: Locate user")); | |
1673 | |
1674 gaim_cmd_register("zl","w", GAIM_CMD_P_PRPL, | |
1675 GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
1676 "prpl-zephyr", | |
1677 zephyr_gaim_cmd_zlocate, _("zl <nick>: Locate user")); | |
1678 | |
1679 gaim_cmd_register("instance","s", GAIM_CMD_P_PRPL, | |
1680 GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
1681 "prpl-zephyr", | |
9437 | 1682 zephyr_gaim_cmd_instance, _("instance <instance>: Set the instance to be used on this class")); |
9434 | 1683 |
1684 gaim_cmd_register("inst","s", GAIM_CMD_P_PRPL, | |
1685 GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
1686 "prpl-zephyr", | |
9437 | 1687 zephyr_gaim_cmd_instance, _("inst <instance>: Set the instance to be used on this class")); |
9434 | 1688 |
1689 gaim_cmd_register("sub", "www", GAIM_CMD_P_PRPL, | |
1690 GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
1691 "prpl-zephyr", | |
1692 zephyr_gaim_cmd_joinchat_cir, | |
1693 _("sub <class> <instance> <recipient>: Join a new chat")); | |
1694 | |
1695 gaim_cmd_register("zi","ws", GAIM_CMD_P_PRPL, | |
1696 GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
1697 "prpl-zephyr", | |
1698 zephyr_gaim_cmd_zi, _("zi <instance>: Send a message to <message,<i>instance</i>,*>")); | |
1699 | |
1700 gaim_cmd_register("zci","wws",GAIM_CMD_P_PRPL, | |
1701 GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
1702 "prpl-zephyr", | |
1703 zephyr_gaim_cmd_zci, | |
1704 _("zci <class> <instance>: Send a message to <<i>class</i>,<i>instance</i>,*>")); | |
1705 | |
1706 gaim_cmd_register("zcir","wwws",GAIM_CMD_P_PRPL, | |
1707 GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
1708 "prpl-zephyr", | |
1709 zephyr_gaim_cmd_zcir, | |
1710 _("zcir <class> <instance> <recipient>: Send a message to <<i>class</i>,<i>instance</i>,<i>recipient</i>>")); | |
1711 | |
1712 gaim_cmd_register("zir","wws",GAIM_CMD_P_PRPL, | |
1713 GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
1714 "prpl-zephyr", | |
1715 zephyr_gaim_cmd_zir, | |
1716 _("zir <instance> <recipient>: Send a message to <MESSAGE,<i>instance</i>,<i>recipient</i>>")); | |
1717 | |
1718 gaim_cmd_register("zc","ws", GAIM_CMD_P_PRPL, | |
1719 GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
1720 "prpl-zephyr", | |
1721 zephyr_gaim_cmd_zc, _("zc <class>: Send a message to <<i>class</i>,PERSONAL,*>")); | |
1722 | |
1723 } | |
1724 | |
1725 | |
9427 | 1726 static int zephyr_resubscribe(GaimConnection *gc) |
1727 { | |
1728 /* Resubscribe to the in-memory list of subscriptions and also | |
1729 unsubscriptions*/ | |
1730 | |
1731 GSList *s = subscrips; | |
1732 zephyr_triple *zt; | |
1733 ZSubscription_t zst; | |
1734 while (s) { | |
1735 zt = s->data; | |
1736 zst.zsub_class = zt->class; | |
1737 zst.zsub_classinst = zt->instance; | |
1738 zst.zsub_recipient = zt->recipient; | |
1739 /* XXX We really should care if this fails */ | |
9478 | 1740 ZSubscribeTo(&zst, 1, 0); |
9427 | 1741 s = s->next; |
1742 } | |
1743 /* XXX handle unsubscriptions */ | |
1744 return 1; | |
1745 } | |
1746 | |
9434 | 1747 |
9427 | 1748 static void zephyr_action_resubscribe(GaimPluginAction *action) |
1749 { | |
1750 | |
1751 GaimConnection *gc = (GaimConnection *) action->context; | |
1752 zephyr_resubscribe(gc); | |
1753 } | |
1754 | |
1755 | |
9478 | 1756 static void zephyr_action_get_subs_from_server(GaimPluginAction *action) |
1757 { | |
1758 GaimConnection *gc = (GaimConnection *) action->context; | |
1759 gchar *title; | |
1760 int retval, nsubs, one,i; | |
1761 ZSubscription_t subs; | |
1762 GString* subout = g_string_new("Subscription list<br>"); | |
1763 | |
1764 title = g_strdup_printf("Server subscriptions for %s", gaim_zephyr_get_sender()); | |
1765 | |
1766 if (zephyr_port == 0) { | |
1767 gaim_debug(GAIM_DEBUG_ERROR,"zephyr", "error while retrieving port"); | |
1768 return; | |
1769 } | |
1770 if ((retval = ZRetrieveSubscriptions(zephyr_port,&nsubs)) != ZERR_NONE) { | |
1771 /* XXX better error handling */ | |
1772 gaim_debug(GAIM_DEBUG_ERROR,"zephyr", "error while retrieving subscriptions from server"); | |
1773 return; | |
1774 } | |
1775 g_string_append_printf(subout,"Subscription list <br>"); | |
1776 for(i=0;i<nsubs;i++) { | |
1777 one = 1; | |
1778 if ((retval = ZGetSubscriptions(&subs,&one)) != ZERR_NONE) { | |
1779 /* XXX better error handling */ | |
1780 gaim_debug(GAIM_DEBUG_ERROR,"zephyr", "error while retrieving individual subscription"); | |
1781 return; | |
1782 } | |
1783 g_string_append_printf(subout, "Class %s Instance %s Recipient %s<br>", | |
1784 subs.zsub_class, subs.zsub_classinst, | |
1785 subs.zsub_recipient); | |
1786 } | |
1787 gaim_notify_formatted(gc, title, title, NULL, subout->str, NULL, NULL); | |
1788 } | |
1789 | |
1790 | |
9427 | 1791 static GList *zephyr_actions(GaimPlugin *plugin, gpointer context) |
1792 { | |
1793 GList *list = NULL; | |
1794 GaimPluginAction *act = NULL; | |
1795 | |
1796 act = gaim_plugin_action_new(_("Resubscribe"), zephyr_action_resubscribe); | |
1797 list = g_list_append(list, act); | |
1798 | |
9478 | 1799 act = gaim_plugin_action_new(_("Retrieve subscriptions from server"), zephyr_action_get_subs_from_server); |
1800 list = g_list_append(list,act); | |
1801 | |
9427 | 1802 return list; |
1803 } | |
1804 | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
1805 static GaimPlugin *my_protocol = NULL; |
2086 | 1806 |
8644 | 1807 static GaimPluginProtocolInfo prpl_info = { |
8749
d7b8eb1f0a18
[gaim-migrate @ 9504]
Christian Hammond <chipx86@chipx86.com>
parents:
8713
diff
changeset
|
1808 GAIM_PRPL_API_VERSION, |
8644 | 1809 OPT_PROTO_CHAT_TOPIC | OPT_PROTO_NO_PASSWORD, |
9478 | 1810 NULL, /* ??? user_splits */ |
1811 NULL, /* ??? protocol_options */ | |
1812 NO_BUDDY_ICONS, | |
1813 zephyr_list_icon, | |
1814 NULL, /* ??? list_emblems */ | |
1815 NULL, /* ??? status_text */ | |
1816 NULL, /* ??? tooltip_text */ | |
9475 | 1817 zephyr_away_states, /* away_states */ |
9478 | 1818 NULL, /* ??? blist_node_menu - probably all useful actions are already handled*/ |
9475 | 1819 zephyr_chat_info, /* chat_info */ |
1820 zephyr_login, /* login */ | |
1821 zephyr_close, /* close */ | |
1822 zephyr_send_im, /* send_im */ | |
9478 | 1823 NULL, /* XXX set info (Location?) */ |
1824 zephyr_send_typing, /* send_typing */ | |
9475 | 1825 zephyr_zloc, /* get_info */ |
9478 | 1826 zephyr_set_away, /* XXX set_away need to fix */ |
1827 NULL, /* ??? set idle */ | |
1828 NULL, /* change password */ | |
9475 | 1829 NULL, /* add_buddy */ |
1830 NULL, /* add_buddies */ | |
1831 NULL, /* remove_buddy */ | |
1832 NULL, /* remove_buddies */ | |
9478 | 1833 NULL, /* add_permit -- not useful, since anyone can zephyr you by default*/ |
1834 NULL, /* XXX add deny -- maybe put an auto "I'm ignoring your zephyrs*/ | |
1835 NULL, /* remove_permit -- not useful, see add permit */ | |
1836 NULL, /* XXX remove deny -- remove above deny, */ | |
1837 NULL, /* ??? set permit deny */ | |
1838 NULL, /* --- warn */ | |
9475 | 1839 zephyr_join_chat, /* join_chat */ |
1840 NULL, /* reject_chat */ | |
1841 NULL, /* chat_invite */ | |
1842 zephyr_chat_leave, /* chat_leave */ | |
1843 NULL, /* chat_whisper */ | |
1844 zephyr_chat_send, /* chat_send */ | |
1845 NULL, /* keepalive */ | |
1846 NULL, /* register_user */ | |
9478 | 1847 NULL, /* XXX get_cb_info get chat buddy info */ |
9475 | 1848 NULL, /* get_cb_away */ |
1849 NULL, /* alias_buddy */ | |
1850 NULL, /* group_buddy */ | |
1851 NULL, /* rename_group */ | |
9478 | 1852 NULL, /* ??? buddy_free */ |
9475 | 1853 NULL, /* convo_closed */ |
1854 zephyr_normalize, /* normalize */ | |
9478 | 1855 NULL, /* XXX set_buddy_icon */ |
9475 | 1856 NULL, /* remove_group */ |
9478 | 1857 NULL, /* XXX get_cb_real_name */ |
9475 | 1858 zephyr_chat_set_topic, /* set_chat_topic */ |
9478 | 1859 zephyr_find_blist_chat, /* find_blist_chat */ |
9475 | 1860 NULL, /* roomlist_get_list */ |
1861 NULL, /* roomlist_cancel */ | |
9478 | 1862 NULL, /* roomlist_expand_category */ |
9475 | 1863 NULL, /* can_receive_file */ |
1864 NULL /* send_file */ | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
1865 }; |
2086 | 1866 |
8644 | 1867 static GaimPluginInfo info = { |
8749
d7b8eb1f0a18
[gaim-migrate @ 9504]
Christian Hammond <chipx86@chipx86.com>
parents:
8713
diff
changeset
|
1868 GAIM_PLUGIN_API_VERSION, /**< api_version */ |
8644 | 1869 GAIM_PLUGIN_PROTOCOL, /**< type */ |
1870 NULL, /**< ui_requirement */ | |
1871 0, /**< flags */ | |
1872 NULL, /**< dependencies */ | |
1873 GAIM_PRIORITY_DEFAULT, /**< priority */ | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
1874 |
8644 | 1875 "prpl-zephyr", /**< id */ |
1876 "Zephyr", /**< name */ | |
1877 VERSION, /**< version */ | |
1878 /** summary */ | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
1879 N_("Zephyr Protocol Plugin"), |
8644 | 1880 /** description */ |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
1881 N_("Zephyr Protocol Plugin"), |
8644 | 1882 NULL, /**< author */ |
1883 GAIM_WEBSITE, /**< homepage */ | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
1884 |
8644 | 1885 NULL, /**< load */ |
1886 NULL, /**< unload */ | |
1887 NULL, /**< destroy */ | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
1888 |
8644 | 1889 NULL, /**< ui_info */ |
8993 | 1890 &prpl_info, /**< extra_info */ |
1891 NULL, | |
9427 | 1892 zephyr_actions |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
1893 }; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
1894 |
8644 | 1895 static void init_plugin(GaimPlugin * plugin) |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
1896 { |
8212 | 1897 GaimAccountOption *option; |
8644 | 1898 char *tmp = get_exposure_level(); |
1899 | |
1900 option = gaim_account_option_bool_new(_("Export to .anyone"), "write_anyone", FALSE); | |
1901 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
8212 | 1902 |
8644 | 1903 option = gaim_account_option_bool_new(_("Export to .zephyr.subs"), "write_zsubs", FALSE); |
1904 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
8212 | 1905 |
8644 | 1906 option = gaim_account_option_string_new(_("Exposure"), "exposure_level", tmp ? tmp : EXPOSE_REALMVIS); |
1907 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
8212 | 1908 |
8644 | 1909 option = gaim_account_option_string_new(_("Encoding"), "encoding", ZEPHYR_FALLBACK_CHARSET); |
1910 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
8560 | 1911 |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
1912 my_protocol = plugin; |
9434 | 1913 zephyr_register_slash_commands(); |
2086 | 1914 } |
1915 | |
5920
7d385de2f9cd
[gaim-migrate @ 6360]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
1916 GAIM_INIT_PLUGIN(zephyr, init_plugin, info); |