Mercurial > pidgin.yaz
annotate src/protocols/zephyr/zephyr.c @ 12216:4d3119205a33
[gaim-migrate @ 14518]
Remove GaimConvImFlags and GaimConvChatFlags - use GaimMessageFlags
everywhere instead.
Add a new GAIM_MESSAGE_IMAGES flag, and set it when sending a message
containing images.
When sending a message, the core will now always send "html" to the prpls,
just like it expects to receive html from the prpls for received messages.
This will allow text prpls such as SILC to support IM images and differentiate
them from user input. Previously gaim_unescape_html() was used before passing
the message to the prpl, now the prpl does this itself if it needs it.
I think I updated all the prpls correctly, but I'm not so sure about sametime.
committer: Tailor Script <tailor@pidgin.im>
author | Stu Tomlinson <stu@nosnilmot.com> |
---|---|
date | Thu, 24 Nov 2005 20:47:46 +0000 |
parents | cbebda5f019c |
children | 7c2e2c4d45a4 |
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 * |
9896 | 10 * Some code borrowed from kzephyr, by |
11 * Chris Colohan <colohan+@cs.cmu.edu> | |
12 * | |
2086 | 13 * This program is free software; you can redistribute it and/or modify |
14 * it under the terms of the GNU General Public License as published by | |
15 * the Free Software Foundation; either version 2 of the License, or | |
16 * (at your option) any later version. | |
17 * | |
18 * This program is distributed in the hope that it will be useful, | |
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
9896 | 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2086 | 21 * GNU General Public License for more details. |
22 * | |
23 * You should have received a copy of the GNU General Public License | |
24 * along with this program; if not, write to the Free Software | |
9896 | 25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
2086 | 26 * |
9896 | 27 |
28 */ | |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
29 /* XXX eww */ |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
30 #include "src/internal.h" |
2086 | 31 |
8212 | 32 #include "accountopt.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
33 #include "debug.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
34 #include "notify.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
35 #include "prpl.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
36 #include "server.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
37 #include "util.h" |
9434 | 38 #include "cmds.h" |
9896 | 39 #include "privacy.h" |
9943 | 40 #include "version.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
41 |
9896 | 42 #include "zephyr.h" |
9478 | 43 #include "internal.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
44 |
8386 | 45 #include <strings.h> |
46 | |
8560 | 47 #define ZEPHYR_FALLBACK_CHARSET "ISO-8859-1" |
48 | |
9478 | 49 /* these are deliberately high, since most people don't send multiple "PING"s */ |
50 #define ZEPHYR_TYPING_SEND_TIMEOUT 15 | |
51 #define ZEPHYR_TYPING_RECV_TIMEOUT 10 | |
9896 | 52 #define ZEPHYR_FD_READ 0 |
53 #define ZEPHYR_FD_WRITE 1 | |
9478 | 54 |
2086 | 55 extern Code_t ZGetLocations(ZLocations_t *, int *); |
56 extern Code_t ZSetLocation(char *); | |
57 extern Code_t ZUnsetLocation(); | |
9478 | 58 extern Code_t ZGetSubscriptions(ZSubscription_t *, int*); |
10038
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
59 extern char __Zephyr_realm[]; |
2086 | 60 typedef struct _zframe zframe; |
61 typedef struct _zephyr_triple zephyr_triple; | |
9610 | 62 typedef struct _zephyr_account zephyr_account; |
9896 | 63 typedef struct _parse_tree parse_tree; |
2086 | 64 |
9896 | 65 typedef enum { |
66 GAIM_ZEPHYR_NONE, /* Non-kerberized ZEPH0.2 */ | |
67 GAIM_ZEPHYR_KRB4, /* ZEPH0.2 w/ KRB4 support */ | |
68 GAIM_ZEPHYR_TZC, /* tzc executable proxy */ | |
69 GAIM_ZEPHYR_INTERGALACTIC_KRB4, /* Kerberized ZEPH0.3 */ | |
70 } zephyr_connection_type; | |
9610 | 71 |
72 struct _zephyr_account { | |
9896 | 73 GaimAccount* account; |
74 char *username; | |
75 char *realm; | |
76 char *encoding; | |
77 char* galaxy; /* not yet useful */ | |
78 char* krbtkfile; /* not yet useful */ | |
79 guint32 nottimer; | |
80 guint32 loctimer; | |
81 GList *pending_zloc_names; | |
82 GSList *subscrips; | |
83 int last_id; | |
84 unsigned short port; | |
85 char ourhost[HOST_NAME_MAX + 1]; | |
86 char ourhostcanon[HOST_NAME_MAX + 1]; | |
87 zephyr_connection_type connection_type; | |
88 int totzc[2]; | |
89 int fromtzc[2]; | |
90 char *exposure; | |
9986 | 91 pid_t tzc_pid; |
92 gchar *away; | |
9610 | 93 }; |
9478 | 94 |
9896 | 95 #define MAXCHILDREN 20 |
96 | |
97 struct _parse_tree { | |
98 gchar* contents; | |
99 parse_tree *children[MAXCHILDREN]; | |
100 int num_children; | |
101 }; | |
102 | |
103 parse_tree null_parse_tree = { | |
104 "", | |
10116 | 105 {NULL}, |
9896 | 106 0, |
107 }; | |
108 | |
109 #define use_none(zephyr) ((zephyr->connection_type == GAIM_ZEPHYR_NONE)?1:0) | |
110 #define use_krb4(zephyr) ((zephyr->connection_type == GAIM_ZEPHYR_KRB4)?1:0) | |
111 #define use_tzc(zephyr) ((zephyr->connection_type == GAIM_ZEPHYR_TZC)?1:0) | |
112 | |
113 #define use_zeph02(zephyr) ( (zephyr->connection_type == GAIM_ZEPHYR_NONE)?1: ((zephyr->connection_type == GAIM_ZEPHYR_KRB4)?1:0)) | |
114 | |
2086 | 115 /* struct I need for zephyr_to_html */ |
116 struct _zframe { | |
117 /* true for everything but @color, since inside the parens of that one is | |
8644 | 118 * the color. */ |
2086 | 119 gboolean has_closer; |
120 /* </i>, </font>, </b>, etc. */ | |
121 char *closing; | |
122 /* text including the opening html thingie. */ | |
123 GString *text; | |
124 struct _zframe *enclosing; | |
125 }; | |
126 | |
127 struct _zephyr_triple { | |
128 char *class; | |
129 char *instance; | |
130 char *recipient; | |
131 char *name; | |
132 gboolean open; | |
133 int id; | |
134 }; | |
135 | |
136 #define z_call(func) if (func != ZERR_NONE)\ | |
137 return; | |
138 #define z_call_r(func) if (func != ZERR_NONE)\ | |
139 return TRUE; | |
9896 | 140 |
2086 | 141 #define z_call_s(func, err) if (func != ZERR_NONE) {\ |
9610 | 142 gaim_connection_error(gc, err);\ |
2086 | 143 return;\ |
144 } | |
145 | |
10867 | 146 #ifdef WIN32 |
147 extern const char *username; | |
148 #endif | |
9896 | 149 |
150 Code_t zephyr_subscribe_to(zephyr_account* zephyr, char* class, char *instance, char *recipient, char* galaxy) { | |
9328 | 151 |
9896 | 152 if (use_tzc(zephyr)) { |
153 /* ((tzcfodder . subscribe) ("class" "instance" "recipient")) */ | |
154 gchar *zsubstr = g_strdup_printf("((tzcfodder . subscribe) (\"%s\" \"%s\" \"%s\"))\n",class,instance,recipient); | |
155 write(zephyr->totzc[ZEPHYR_FD_WRITE],zsubstr,strlen(zsubstr)); | |
156 g_free(zsubstr); | |
157 return ZERR_NONE; | |
158 } | |
159 else { | |
160 if (use_zeph02(zephyr)) { | |
161 ZSubscription_t sub; | |
162 sub.zsub_class = class; | |
163 sub.zsub_classinst = instance; | |
164 sub.zsub_recipient = recipient; | |
165 return ZSubscribeTo(&sub,1,0); | |
166 } else { | |
167 /* This should not happen */ | |
168 return -1; | |
169 } | |
170 } | |
171 return -1; | |
172 } | |
173 | |
174 char *local_zephyr_normalize(zephyr_account* zephyr,const char *); | |
175 static void zephyr_chat_set_topic(GaimConnection * gc, int id, const char *topic); | |
176 char* zephyr_tzc_deescape_str(const char *message); | |
177 | |
9912 | 178 char *zephyr_strip_local_realm(zephyr_account* zephyr,const char* user){ |
9896 | 179 /* |
180 Takes in a username of the form username or username@realm | |
181 and returns: | |
182 username, if there is no realm, or the realm is the local realm | |
183 or: | |
184 username@realm if there is a realm and it is foreign | |
185 */ | |
9328 | 186 char *tmp = g_strdup(user); |
187 char *at = strchr(tmp,'@'); | |
9896 | 188 if (at && !g_ascii_strcasecmp(at+1,zephyr->realm)) { |
9328 | 189 /* We're passed in a username of the form user@users-realm */ |
190 char* tmp2; | |
191 *at = '\0'; | |
192 tmp2 = g_strdup(tmp); | |
193 g_free(tmp); | |
194 return tmp2; | |
195 } | |
196 else { | |
197 /* We're passed in a username of the form user or user@foreign-realm */ | |
198 return tmp; | |
199 } | |
200 } | |
2086 | 201 |
202 /* this is so bad, and if Zephyr weren't so fucked up to begin with I | |
203 * wouldn't do this. but it is so i will. */ | |
9610 | 204 |
9328 | 205 /* just for debugging */ |
2086 | 206 static void handle_unknown(ZNotice_t notice) |
207 { | |
10867 | 208 gaim_debug_error("zephyr","z_packet: %s\n", notice.z_packet); |
209 gaim_debug_error("zephyr","z_version: %s\n", notice.z_version); | |
210 gaim_debug_error("zephyr","z_kind: %d\n", (int)(notice.z_kind)); | |
211 gaim_debug_error("zephyr","z_class: %s\n", notice.z_class); | |
212 gaim_debug_error("zephyr","z_class_inst: %s\n", notice.z_class_inst); | |
213 gaim_debug_error("zephyr","z_opcode: %s\n", notice.z_opcode); | |
214 gaim_debug_error("zephyr","z_sender: %s\n", notice.z_sender); | |
215 gaim_debug_error("zephyr","z_recipient: %s\n", notice.z_recipient); | |
216 gaim_debug_error("zephyr","z_message: %s\n", notice.z_message); | |
217 gaim_debug_error("zephyr","z_message_len: %d\n", notice.z_message_len); | |
2086 | 218 } |
9328 | 219 |
2086 | 220 |
9610 | 221 static zephyr_triple *new_triple(zephyr_account *zephyr,const char *c, const char *i, const char *r) |
2086 | 222 { |
223 zephyr_triple *zt; | |
8644 | 224 |
2086 | 225 zt = g_new0(zephyr_triple, 1); |
226 zt->class = g_strdup(c); | |
227 zt->instance = g_strdup(i); | |
228 zt->recipient = g_strdup(r); | |
9610 | 229 zt->name = g_strdup_printf("%s,%s,%s", c, i?i:"", r?r:""); |
230 zt->id = ++(zephyr->last_id); | |
2086 | 231 zt->open = FALSE; |
232 return zt; | |
233 } | |
234 | |
8644 | 235 static void free_triple(zephyr_triple * zt) |
2086 | 236 { |
237 g_free(zt->class); | |
238 g_free(zt->instance); | |
239 g_free(zt->recipient); | |
240 g_free(zt->name); | |
241 g_free(zt); | |
242 } | |
243 | |
9328 | 244 /* returns true if zt1 is a subset of zt2. This function is used to |
245 determine whether a zephyr sent to zt1 should be placed in the chat | |
246 with triple zt2 | |
247 | |
248 zt1 is a subset of zt2 | |
249 iff. the classnames are identical ignoring case | |
250 AND. the instance names are identical (ignoring case), or zt2->instance is *. | |
251 AND. the recipient names are identical | |
252 */ | |
253 | |
8644 | 254 static gboolean triple_subset(zephyr_triple * zt1, zephyr_triple * zt2) |
2086 | 255 { |
9896 | 256 |
257 if (!zt2) | |
258 gaim_debug_error("zephyr","zt2 doesn't exist\n"); | |
259 if (!zt1) | |
260 gaim_debug_error("zephyr","zt1 doesn't exist\n"); | |
261 if (!(zt1->class)) | |
262 gaim_debug_error("zephyr","zt1c doesn't exist\n"); | |
263 if (!(zt1->instance)) | |
264 gaim_debug_error("zephyr","zt1i doesn't exist\n"); | |
265 if (!(zt1->recipient)) | |
266 gaim_debug_error("zephyr","zt1r doesn't exist\n"); | |
267 if (!(zt2->class)) | |
268 gaim_debug_error("zephyr","zt2c doesn't exist\n"); | |
269 if (!(zt2->recipient)) | |
270 gaim_debug_error("zephyr","zt2r doesn't exist\n"); | |
271 if (!(zt2->instance)) | |
272 gaim_debug_error("zephyr","zt2i doesn't exist\n"); | |
273 | |
274 | |
9328 | 275 if (g_ascii_strcasecmp(zt2->class, zt1->class)) { |
2086 | 276 return FALSE; |
277 } | |
8644 | 278 if (g_ascii_strcasecmp(zt2->instance, zt1->instance) && g_ascii_strcasecmp(zt2->instance, "*")) { |
2086 | 279 return FALSE; |
280 } | |
9328 | 281 if (g_ascii_strcasecmp(zt2->recipient, zt1->recipient)) { |
2086 | 282 return FALSE; |
283 } | |
9896 | 284 gaim_debug_info("zephyr","<%s,%s,%s> is in <%s,%s,%s>\n",zt1->class,zt1->instance,zt1->recipient,zt2->class,zt2->instance,zt2->recipient); |
2086 | 285 return TRUE; |
286 } | |
287 | |
9610 | 288 static zephyr_triple *find_sub_by_triple(zephyr_account *zephyr,zephyr_triple * zt) |
2086 | 289 { |
290 zephyr_triple *curr_t; | |
9610 | 291 GSList *curr = zephyr->subscrips; |
8644 | 292 |
2086 | 293 while (curr) { |
294 curr_t = curr->data; | |
295 if (triple_subset(zt, curr_t)) | |
296 return curr_t; | |
297 curr = curr->next; | |
298 } | |
299 return NULL; | |
300 } | |
301 | |
9610 | 302 static zephyr_triple *find_sub_by_id(zephyr_account *zephyr,int id) |
2086 | 303 { |
304 zephyr_triple *zt; | |
9610 | 305 GSList *curr = zephyr->subscrips; |
8644 | 306 |
2086 | 307 while (curr) { |
308 zt = curr->data; | |
309 if (zt->id == id) | |
310 return zt; | |
311 curr = curr->next; | |
312 } | |
313 return NULL; | |
314 } | |
315 | |
9328 | 316 /* |
9434 | 317 Converts strings to utf-8 if necessary using user specified encoding |
9328 | 318 */ |
319 | |
9610 | 320 static gchar *zephyr_recv_convert(GaimConnection *gc,gchar *string, int len) |
8560 | 321 { |
322 gchar *utf8; | |
323 GError *err = NULL; | |
9896 | 324 zephyr_account *zephyr = gc->proto_data; |
8644 | 325 if (g_utf8_validate(string, len, NULL)) { |
8568 | 326 return g_strdup(string); |
327 } else { | |
9896 | 328 utf8 = g_convert(string, len, "UTF-8", zephyr->encoding, NULL, NULL, &err); |
8568 | 329 if (err) { |
10867 | 330 gaim_debug_error("zephyr", "recv conversion error: %s\n", err->message); |
9896 | 331 utf8 = g_strdup(_("(There was an error converting this message. Check the 'Encoding' option in the Account Editor)")); |
8954 | 332 g_error_free(err); |
8568 | 333 } |
334 | |
335 return utf8; | |
336 } | |
8560 | 337 } |
338 | |
2086 | 339 /* utility macros that are useful for zephyr_to_html */ |
340 | |
341 #define IS_OPENER(c) ((c == '{') || (c == '[') || (c == '(') || (c == '<')) | |
342 #define IS_CLOSER(c) ((c == '}') || (c == ']') || (c == ')') || (c == '>')) | |
343 | |
8451 | 344 /* This parses HTML formatting (put out by one of the gtkimhtml widgets |
345 And converts it to zephyr formatting. | |
346 It currently deals properly with <b>, <br>, <i>, <font face=...>, <font color=...>, | |
347 It ignores <font back=...> | |
348 It does | |
349 <font size = "1 or 2" -> @small | |
350 3 or 4 @medium() | |
351 5,6, or 7 @large() | |
352 <a href is dealt with by ignoring the description and outputting the link | |
353 */ | |
354 | |
355 static char *html_to_zephyr(const char *message) | |
356 { | |
8644 | 357 int len, cnt, retcount; |
358 char *ret; | |
359 | |
360 len = strlen(message); | |
9478 | 361 if (!len) |
362 return g_strdup(""); | |
363 | |
8644 | 364 ret = g_new0(char, len * 3); |
365 | |
366 bzero(ret, len * 3); | |
367 retcount = 0; | |
368 cnt = 0; | |
9896 | 369 gaim_debug_info("zephyr","html received %s\n",message); |
8644 | 370 while (cnt <= len) { |
371 if (message[cnt] == '<') { | |
372 if (!g_ascii_strncasecmp(message + cnt + 1, "i>", 2)) { | |
373 strncpy(ret + retcount, "@i(", 3); | |
374 cnt += 3; | |
375 retcount += 3; | |
376 } else if (!g_ascii_strncasecmp(message + cnt + 1, "b>", 2)) { | |
377 strncpy(ret + retcount, "@b(", 3); | |
378 cnt += 3; | |
379 retcount += 3; | |
380 } else if (!g_ascii_strncasecmp(message + cnt + 1, "br>", 3)) { | |
381 strncpy(ret + retcount, "\n", 1); | |
382 cnt += 4; | |
383 retcount += 1; | |
9896 | 384 } else if (!g_ascii_strncasecmp(message + cnt + 1, "a href=\"mailto:", 15)) { |
385 cnt += 16; | |
11176 | 386 while ((message[cnt] != '\0') && g_ascii_strncasecmp(message + cnt, "\">", 2) != 0) { |
9896 | 387 ret[retcount] = message[cnt]; |
388 retcount++; | |
389 cnt++; | |
390 } | |
11176 | 391 if (message[cnt] != '\0') |
392 cnt += 2; | |
9896 | 393 /* ignore descriptive string */ |
11176 | 394 while ((message[cnt] != '\0') && g_ascii_strncasecmp(message + cnt, "</a>", 4) != 0) { |
9896 | 395 cnt++; |
396 } | |
11176 | 397 if (message[cnt] != '\0') |
398 cnt += 4; | |
8644 | 399 } else if (!g_ascii_strncasecmp(message + cnt + 1, "a href=\"", 8)) { |
400 cnt += 9; | |
11176 | 401 while ((message[cnt] != '\0') && g_ascii_strncasecmp(message + cnt, "\">", 2) != 0) { |
8644 | 402 ret[retcount] = message[cnt]; |
403 retcount++; | |
404 cnt++; | |
405 } | |
11176 | 406 if (message[cnt] != '\0') |
407 cnt += 2; | |
8644 | 408 /* ignore descriptive string */ |
11176 | 409 while ((message[cnt] != '\0') && g_ascii_strncasecmp(message + cnt, "</a>", 4) != 0) { |
8644 | 410 cnt++; |
411 } | |
11176 | 412 if (message[cnt] != '\0') |
413 cnt += 4; | |
8644 | 414 } else if (!g_ascii_strncasecmp(message + cnt + 1, "font", 4)) { |
415 cnt += 5; | |
11176 | 416 while ((message[cnt] != '\0') && (message[cnt] != ' ')) |
8644 | 417 cnt++; |
11176 | 418 if ((message[cnt] != '\0') && !g_ascii_strncasecmp(message + cnt, "color=\"", 7)) { |
8644 | 419 cnt += 7; |
420 strncpy(ret + retcount, "@color(", 7); | |
421 retcount += 7; | |
11176 | 422 while ((message[cnt] != '\0') && g_ascii_strncasecmp(message + cnt, "\">", 2) != 0) { |
8644 | 423 ret[retcount] = message[cnt]; |
424 retcount++; | |
425 cnt++; | |
426 } | |
427 ret[retcount] = ')'; | |
428 retcount++; | |
11176 | 429 if (message[cnt] != '\0') |
430 cnt += 2; | |
8644 | 431 } else if (!g_ascii_strncasecmp(message + cnt, "face=\"", 6)) { |
432 cnt += 6; | |
433 strncpy(ret + retcount, "@font(", 6); | |
434 retcount += 6; | |
11176 | 435 while ((message[cnt] != '\0') && g_ascii_strncasecmp(message + cnt, "\">", 2) != 0) { |
8644 | 436 ret[retcount] = message[cnt]; |
437 retcount++; | |
438 cnt++; | |
439 } | |
440 ret[retcount] = ')'; | |
441 retcount++; | |
11176 | 442 if (message[cnt] != '\0') |
443 cnt += 2; | |
8644 | 444 } else if (!g_ascii_strncasecmp(message + cnt, "size=\"", 6)) { |
445 cnt += 6; | |
446 if ((message[cnt] == '1') || (message[cnt] == '2')) { | |
447 strncpy(ret + retcount, "@small(", 7); | |
448 retcount += 7; | |
449 } else if ((message[cnt] == '3') | |
9896 | 450 || (message[cnt] == '4')) { |
8644 | 451 strncpy(ret + retcount, "@medium(", 8); |
452 retcount += 8; | |
453 } else if ((message[cnt] == '5') | |
9896 | 454 || (message[cnt] == '6') |
455 || (message[cnt] == '7')) { | |
8644 | 456 strncpy(ret + retcount, "@large(", 7); |
457 retcount += 7; | |
458 } | |
459 cnt += 3; | |
460 } else { | |
461 /* Drop all unrecognized/misparsed font tags */ | |
11176 | 462 while ((message[cnt] != '\0') && g_ascii_strncasecmp(message + cnt, "\">", 2) != 0) { |
8644 | 463 cnt++; |
464 } | |
11176 | 465 if (message[cnt] != '\0') |
466 cnt += 2; | |
8644 | 467 } |
468 } else if (!g_ascii_strncasecmp(message + cnt + 1, "/i>", 3) | |
9896 | 469 || !g_ascii_strncasecmp(message + cnt + 1, "/b>", 3)) { |
8644 | 470 cnt += 4; |
471 ret[retcount] = ')'; | |
472 retcount++; | |
473 } else if (!g_ascii_strncasecmp(message + cnt + 1, "/font>", 6)) { | |
474 cnt += 7; | |
475 strncpy(ret + retcount, "@font(fixed)", 12); | |
476 retcount += 12; | |
477 } else { | |
478 /* Catch all for all unrecognized/misparsed <foo> tage */ | |
11176 | 479 while ((message[cnt] != '\0') && (message[cnt] != '>')) { |
8644 | 480 ret[retcount] = message[cnt]; |
481 retcount++; | |
482 cnt++; | |
483 } | |
484 } | |
485 } else { | |
486 /* Duh */ | |
487 ret[retcount] = message[cnt]; | |
488 retcount++; | |
489 cnt++; | |
490 } | |
491 } | |
9896 | 492 gaim_debug_info("zephyr","zephyr outputted %s\n",ret); |
8644 | 493 return ret; |
8451 | 494 } |
495 | |
2086 | 496 /* this parses zephyr formatting and converts it to html. For example, if |
497 * you pass in "@{@color(blue)@i(hello)}" you should get out | |
498 * "<font color=blue><i>hello</i></font>". */ | |
499 static char *zephyr_to_html(char *message) | |
500 { | |
501 int len, cnt; | |
502 zframe *frames, *curr; | |
503 char *ret; | |
504 | |
505 frames = g_new(zframe, 1); | |
506 frames->text = g_string_new(""); | |
507 frames->enclosing = NULL; | |
508 frames->closing = ""; | |
509 frames->has_closer = FALSE; | |
510 | |
511 len = strlen(message); | |
512 cnt = 0; | |
513 while (cnt <= len) { | |
514 if (message[cnt] == '@') { | |
515 zframe *new_f; | |
516 char *buf; | |
517 int end; | |
8644 | 518 |
519 for (end = 1; (cnt + end) <= len && !IS_OPENER(message[cnt + end]) | |
9896 | 520 && !IS_CLOSER(message[cnt + end]); end++); |
2086 | 521 buf = g_new0(char, end); |
8644 | 522 |
2086 | 523 if (end) { |
8644 | 524 g_snprintf(buf, end, "%s", message + cnt + 1); |
2086 | 525 } |
8644 | 526 if (!g_ascii_strcasecmp(buf, "italic") || !g_ascii_strcasecmp(buf, "i")) { |
2086 | 527 new_f = g_new(zframe, 1); |
528 new_f->enclosing = frames; | |
529 new_f->text = g_string_new("<i>"); | |
530 new_f->closing = "</i>"; | |
531 new_f->has_closer = TRUE; | |
532 frames = new_f; | |
8644 | 533 cnt += end + 1; /* cnt points to char after opener */ |
534 } else if (!g_ascii_strcasecmp(buf, "small")) { | |
535 new_f = g_new(zframe, 1); | |
536 new_f->enclosing = frames; | |
537 new_f->text = g_string_new("<font size=\"1\">"); | |
538 new_f->closing = "</font>"; | |
539 frames = new_f; | |
540 cnt += end + 1; | |
541 } else if (!g_ascii_strcasecmp(buf, "medium")) { | |
542 new_f = g_new(zframe, 1); | |
543 new_f->enclosing = frames; | |
544 new_f->text = g_string_new("<font size=\"3\">"); | |
545 new_f->closing = "</font>"; | |
546 frames = new_f; | |
547 cnt += end + 1; | |
548 } else if (!g_ascii_strcasecmp(buf, "large")) { | |
549 new_f = g_new(zframe, 1); | |
550 new_f->enclosing = frames; | |
551 new_f->text = g_string_new("<font size=\"7\">"); | |
552 new_f->closing = "</font>"; | |
553 frames = new_f; | |
554 cnt += end + 1; | |
555 } else if (!g_ascii_strcasecmp(buf, "bold") | |
9896 | 556 || !g_ascii_strcasecmp(buf, "b")) { |
2086 | 557 new_f = g_new(zframe, 1); |
558 new_f->enclosing = frames; | |
559 new_f->text = g_string_new("<b>"); | |
560 new_f->closing = "</b>"; | |
561 new_f->has_closer = TRUE; | |
562 frames = new_f; | |
8644 | 563 cnt += end + 1; |
564 } else if (!g_ascii_strcasecmp(buf, "font")) { | |
565 cnt += end + 1; | |
8451 | 566 new_f = g_new(zframe, 1); |
567 new_f->enclosing = frames; | |
568 new_f->text = g_string_new("<font face="); | |
569 for (; (cnt <= len) && !IS_CLOSER(message[cnt]); cnt++) { | |
570 g_string_append_c(new_f->text, message[cnt]); | |
571 } | |
8644 | 572 cnt++; /* point to char after closer */ |
8451 | 573 g_string_append_c(new_f->text, '>'); |
574 new_f->closing = "</font>"; | |
575 new_f->has_closer = FALSE; | |
576 frames = new_f; | |
8568 | 577 } else if (!g_ascii_strcasecmp(buf, "color")) { |
8644 | 578 cnt += end + 1; |
2086 | 579 new_f = g_new(zframe, 1); |
580 new_f->enclosing = frames; | |
581 new_f->text = g_string_new("<font color="); | |
582 for (; (cnt <= len) && !IS_CLOSER(message[cnt]); cnt++) { | |
583 g_string_append_c(new_f->text, message[cnt]); | |
584 } | |
8644 | 585 cnt++; /* point to char after closer */ |
2086 | 586 g_string_append_c(new_f->text, '>'); |
587 new_f->closing = "</font>"; | |
588 new_f->has_closer = FALSE; | |
589 frames = new_f; | |
4793 | 590 } else if (!g_ascii_strcasecmp(buf, "")) { |
2086 | 591 new_f = g_new(zframe, 1); |
592 new_f->enclosing = frames; | |
593 new_f->text = g_string_new(""); | |
594 new_f->closing = ""; | |
595 new_f->has_closer = TRUE; | |
596 frames = new_f; | |
8644 | 597 cnt += end + 1; /* cnt points to char after opener */ |
2086 | 598 } else { |
8644 | 599 if ((cnt + end) > len) { |
2086 | 600 g_string_append_c(frames->text, '@'); |
601 cnt++; | |
8644 | 602 } else if (IS_CLOSER(message[cnt + end])) { |
603 /* We have @chars..closer . This is | |
604 merely a sequence of chars that isn't a formatting tag | |
9896 | 605 */ |
8644 | 606 int tmp = cnt; |
607 | |
608 while (tmp <= cnt + end) { | |
609 g_string_append_c(frames->text, message[tmp]); | |
610 tmp++; | |
611 } | |
612 cnt += end + 1; | |
613 } else { | |
2086 | 614 /* unrecognized thingie. act like it's not there, but we |
615 * still need to take care of the corresponding closer, | |
616 * make a frame that does nothing. */ | |
617 new_f = g_new(zframe, 1); | |
618 new_f->enclosing = frames; | |
619 new_f->text = g_string_new(""); | |
620 new_f->closing = ""; | |
621 new_f->has_closer = TRUE; | |
622 frames = new_f; | |
8644 | 623 cnt += end + 1; /* cnt points to char after opener */ |
2086 | 624 } |
625 } | |
626 } else if (IS_CLOSER(message[cnt])) { | |
627 zframe *popped; | |
628 gboolean last_had_closer; | |
8644 | 629 |
2086 | 630 if (frames->enclosing) { |
631 do { | |
632 popped = frames; | |
633 frames = frames->enclosing; | |
634 g_string_append(frames->text, popped->text->str); | |
635 g_string_append(frames->text, popped->closing); | |
636 g_string_free(popped->text, TRUE); | |
637 last_had_closer = popped->has_closer; | |
638 g_free(popped); | |
639 } while (frames && frames->enclosing && !last_had_closer); | |
640 } else { | |
641 g_string_append_c(frames->text, message[cnt]); | |
642 } | |
643 cnt++; | |
644 } else if (message[cnt] == '\n') { | |
645 g_string_append(frames->text, "<br>"); | |
646 cnt++; | |
647 } else { | |
648 g_string_append_c(frames->text, message[cnt++]); | |
649 } | |
650 } | |
651 /* go through all the stuff that they didn't close */ | |
652 while (frames->enclosing) { | |
653 curr = frames; | |
654 g_string_append(frames->enclosing->text, frames->text->str); | |
655 g_string_append(frames->enclosing->text, frames->closing); | |
656 g_string_free(frames->text, TRUE); | |
657 frames = frames->enclosing; | |
658 g_free(curr); | |
659 } | |
660 ret = frames->text->str; | |
661 g_string_free(frames->text, FALSE); | |
662 g_free(frames); | |
663 return ret; | |
664 } | |
665 | |
9610 | 666 static gboolean pending_zloc(zephyr_account *zephyr,char *who) |
2086 | 667 { |
668 GList *curr; | |
8644 | 669 |
9610 | 670 for (curr = zephyr->pending_zloc_names; curr != NULL; curr = curr->next) { |
9896 | 671 char* normalized_who = local_zephyr_normalize(zephyr,who); |
9328 | 672 if (!g_ascii_strcasecmp(normalized_who, (char *)curr->data)) { |
8644 | 673 g_free((char *)curr->data); |
9610 | 674 zephyr->pending_zloc_names = g_list_remove(zephyr->pending_zloc_names, curr->data); |
2086 | 675 return TRUE; |
676 } | |
677 } | |
678 return FALSE; | |
679 } | |
680 | |
9328 | 681 /* Called when the server notifies us a message couldn't get sent */ |
682 | |
9610 | 683 static void message_failed(GaimConnection *gc, ZNotice_t notice, struct sockaddr_in from) |
8559 | 684 { |
8644 | 685 if (g_ascii_strcasecmp(notice.z_class, "message")) { |
10690 | 686 gchar* chat_failed = g_strdup_printf(_("Unable to send to chat %s,%s,%s"),notice.z_class,notice.z_class_inst,notice.z_recipient); |
9610 | 687 gaim_notify_error(gc,"",chat_failed,NULL); |
9328 | 688 g_free(chat_failed); |
8644 | 689 } else { |
9610 | 690 gaim_notify_error(gc, notice.z_recipient, _("User is offline"), NULL); |
8644 | 691 } |
8559 | 692 } |
693 | |
10300 | 694 static void handle_message(GaimConnection *gc,ZNotice_t notice) |
2086 | 695 { |
9896 | 696 zephyr_account* zephyr = gc->proto_data; |
697 | |
4793 | 698 if (!g_ascii_strcasecmp(notice.z_class, LOGIN_CLASS)) { |
3277 | 699 /* well, we'll be updating in 20 seconds anyway, might as well ignore this. */ |
4793 | 700 } else if (!g_ascii_strcasecmp(notice.z_class, LOCATE_CLASS)) { |
701 if (!g_ascii_strcasecmp(notice.z_opcode, LOCATE_LOCATE)) { | |
2086 | 702 int nlocs; |
703 char *user; | |
6695 | 704 GaimBuddy *b; |
9478 | 705 /* XXX add real error reporting */ |
2086 | 706 if (ZParseLocations(¬ice, NULL, &nlocs, &user) != ZERR_NONE) |
707 return; | |
8435 | 708 |
9610 | 709 if ((b = gaim_find_buddy(gc->account, user)) == NULL) { |
9986 | 710 char* stripped_user = zephyr_strip_local_realm(zephyr,user); |
711 b = gaim_find_buddy(gc->account,stripped_user); | |
712 g_free(stripped_user); | |
8644 | 713 } |
9896 | 714 if ((b && pending_zloc(zephyr,b->name)) || pending_zloc(zephyr,user)) { |
2086 | 715 ZLocations_t locs; |
716 int one = 1; | |
717 GString *str = g_string_new(""); | |
8644 | 718 |
719 g_string_append_printf(str, _("<b>User:</b> %s<br>"), b ? b->name : user); | |
8435 | 720 if (b && b->alias) |
5132 | 721 g_string_append_printf(str, _("<b>Alias:</b> %s<br>"), b->alias); |
2086 | 722 if (!nlocs) { |
5132 | 723 g_string_append_printf(str, _("<br>Hidden or not logged-in")); |
2086 | 724 } |
725 for (; nlocs > 0; nlocs--) { | |
9478 | 726 /* XXX add real error reporting */ |
2086 | 727 ZGetLocations(&locs, &one); |
8644 | 728 g_string_append_printf(str, _("<br>At %s since %s"), locs.host, locs.time); |
2086 | 729 } |
11533
c9b815aeddc1
[gaim-migrate @ 13782]
Richard Laager <rlaager@wiktel.com>
parents:
11531
diff
changeset
|
730 gaim_notify_userinfo(gc, b ? b->name : user, |
9896 | 731 str->str, NULL, NULL); |
2086 | 732 g_string_free(str, TRUE); |
9986 | 733 } else { |
10038
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
734 if (nlocs>0) |
11638 | 735 gaim_prpl_got_user_status(gc->account,b->name,"available",NULL); |
10038
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
736 else |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
737 gaim_prpl_got_user_status(gc->account,b->name,"offline",NULL); |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
738 } |
2086 | 739 |
9434 | 740 g_free(user); |
2086 | 741 } |
742 } else { | |
8560 | 743 char *buf, *buf2, *buf3; |
2804
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
744 char *send_inst; |
8644 | 745 GaimConversation *gconv1; |
746 GaimConvChat *gcc; | |
2086 | 747 char *ptr = notice.z_message + strlen(notice.z_message) + 1; |
9478 | 748 int len; |
9896 | 749 char *sendertmp = g_strdup_printf("%s", zephyr->username); |
9478 | 750 int signature_length = strlen(notice.z_message); |
751 int message_has_no_body = 0; | |
12216 | 752 GaimMessageFlags flags = 0; |
9896 | 753 gchar *tmpescape; |
8560 | 754 |
9478 | 755 /* Need to deal with 0 length messages to handle typing notification (OPCODE) ping messages */ |
756 /* One field zephyrs would have caused gaim to crash */ | |
757 if ( (notice.z_message_len == 0) || (signature_length >= notice.z_message_len - 1)) { | |
758 message_has_no_body = 1; | |
759 len = 0; | |
760 gaim_debug_info("zephyr","message_size %d %d %d\n",len,notice.z_message_len,signature_length); | |
761 buf3 = g_strdup(""); | |
762 | |
763 } else { | |
764 len = notice.z_message_len - ( signature_length +1); | |
765 gaim_debug_info("zephyr","message_size %d %d %d\n",len,notice.z_message_len,signature_length); | |
8644 | 766 buf = g_malloc(len + 1); |
767 g_snprintf(buf, len + 1, "%s", ptr); | |
768 g_strchomp(buf); | |
10732
c4cb90065e1d
[gaim-migrate @ 12334]
Luke Schierer <lschiere@pidgin.im>
parents:
10690
diff
changeset
|
769 tmpescape = g_markup_escape_text(buf, -1); |
9478 | 770 g_free(buf); |
8644 | 771 buf2 = zephyr_to_html(tmpescape); |
9610 | 772 buf3 = zephyr_recv_convert(gc,buf2, strlen(buf2)); |
8644 | 773 g_free(buf2); |
774 g_free(tmpescape); | |
9478 | 775 } |
8644 | 776 |
9896 | 777 if (!g_ascii_strcasecmp(notice.z_class, "MESSAGE") && !g_ascii_strcasecmp(notice.z_class_inst, "PERSONAL") |
778 && !g_ascii_strcasecmp(notice.z_recipient,zephyr->username)) { | |
779 gchar* stripped_sender; | |
780 if (!g_ascii_strcasecmp(notice.z_message, "Automated reply:")) | |
12216 | 781 flags |= GAIM_MESSAGE_AUTO_RESP; |
9912 | 782 stripped_sender = zephyr_strip_local_realm(zephyr,notice.z_sender); |
9896 | 783 |
9478 | 784 if (!g_ascii_strcasecmp(notice.z_opcode,"PING")) |
9610 | 785 serv_got_typing(gc,stripped_sender,ZEPHYR_TYPING_RECV_TIMEOUT, GAIM_TYPING); |
9896 | 786 else { |
787 /* Based on the values of | |
788 account->permit_deny, | |
789 account->permit, account>deny , and | |
790 the buddylist */ | |
791 | |
792 GSList* l; | |
793 gboolean in_deny; | |
9478 | 794 |
9896 | 795 switch (gc->account->perm_deny) { |
796 case GAIM_PRIVACY_ALLOW_ALL: | |
797 in_deny = 0; break; | |
798 case GAIM_PRIVACY_DENY_ALL: | |
799 in_deny = 1; break; | |
800 case GAIM_PRIVACY_ALLOW_USERS: /* See if stripped_sender is in gc->account->permit and allow appropriately */ | |
801 in_deny = 1; | |
802 for(l=gc->account->permit;l!=NULL;l=l->next) { | |
803 if (!gaim_utf8_strcasecmp(stripped_sender, gaim_normalize(gc->account, (char *)l->data))) { | |
804 in_deny=0; | |
805 break; | |
806 } | |
807 } | |
808 break; | |
809 case GAIM_PRIVACY_DENY_USERS: /* See if stripped_sender is in gc->account->deny and deny if so */ | |
810 in_deny = 0; | |
811 for(l=gc->account->deny;l!=NULL;l=l->next) { | |
812 if (!gaim_utf8_strcasecmp(stripped_sender, gaim_normalize(gc->account, (char *)l->data))) { | |
813 in_deny=1; | |
814 break; | |
815 } | |
816 } | |
817 break; | |
818 case GAIM_PRIVACY_ALLOW_BUDDYLIST: | |
819 in_deny = 1; | |
820 if (gaim_find_buddy(gc->account,stripped_sender)!=NULL) { | |
821 in_deny = 0; | |
822 } | |
823 break; | |
824 default: | |
825 in_deny=0; break; | |
826 } | |
827 | |
828 if (!in_deny) { | |
829 serv_got_im(gc, stripped_sender, buf3, flags, time(NULL)); | |
830 } | |
831 } | |
832 | |
833 g_free(stripped_sender); | |
834 } else { | |
835 zephyr_triple *zt1, *zt2; | |
836 gchar *send_inst_utf8; | |
837 zephyr_account *zephyr = gc->proto_data; | |
838 zt1 = new_triple(gc->proto_data,notice.z_class, notice.z_class_inst, notice.z_recipient); | |
839 zt2 = find_sub_by_triple(gc->proto_data,zt1); | |
840 if (!zt2) { | |
841 /* This is a server supplied subscription */ | |
842 zephyr->subscrips = g_slist_append(zephyr->subscrips, new_triple(zephyr,zt1->class,zt1->instance,zt1->recipient)); | |
9610 | 843 zt2 = find_sub_by_triple(gc->proto_data,zt1); |
9896 | 844 } |
845 | |
846 if (!zt2->open) { | |
847 zt2->open = TRUE; | |
848 serv_got_joined_chat(gc, zt2->id, zt2->name); | |
849 zephyr_chat_set_topic(gc,zt2->id,notice.z_class_inst); | |
850 } | |
851 g_free(sendertmp); /* fix memory leak? */ | |
852 /* If the person is in the default Realm, then strip the | |
853 Realm from the sender field */ | |
9912 | 854 sendertmp = zephyr_strip_local_realm(zephyr,notice.z_sender); |
9896 | 855 send_inst = g_strdup_printf("%s %s",sendertmp,notice.z_class_inst); |
856 send_inst_utf8 = zephyr_recv_convert(gc,send_inst, strlen(send_inst)); | |
857 if (!send_inst_utf8) { | |
10867 | 858 gaim_debug_error("zephyr","send_inst %s became null\n", send_inst); |
9896 | 859 send_inst_utf8 = "malformed instance"; |
2086 | 860 } |
9912 | 861 |
9896 | 862 serv_got_chat_in(gc, zt2->id, send_inst_utf8, 0, buf3, time(NULL)); |
863 g_free(send_inst); | |
11338 | 864 gconv1 = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, |
10246 | 865 zt2->name, gc->account); |
9896 | 866 gcc = gaim_conversation_get_chat_data(gconv1); |
9912 | 867 |
9896 | 868 if (!gaim_conv_chat_find_user(gcc, sendertmp)) { |
869 /* force interpretation in network byte order */ | |
870 unsigned char *addrs = (unsigned char *)&(notice.z_sender_addr.s_addr); | |
871 gchar* ipaddr = g_strdup_printf("%hhd.%hhd.%hhd.%hhd", (unsigned char)addrs[0], | |
872 (unsigned char)addrs[1], (unsigned char)addrs[2], | |
873 (unsigned char) addrs[3]); | |
874 | |
875 gaim_conv_chat_add_user(gcc, sendertmp, ipaddr, GAIM_CBFLAGS_NONE, TRUE); | |
876 g_free(ipaddr); /* fix memory leak? */ | |
877 | |
878 } | |
879 g_free(sendertmp); | |
880 g_free(send_inst_utf8); | |
881 | |
882 free_triple(zt1); | |
883 } | |
884 g_free(buf3); | |
9478 | 885 |
2086 | 886 } |
887 } | |
9896 | 888 int free_parse_tree(parse_tree* tree) { |
889 if (!tree) { | |
890 return 0; | |
891 } | |
892 else { | |
893 int i; | |
894 if (tree->children) { | |
895 for(i=0;i<tree->num_children;i++){ | |
896 if (tree->children[i]) { | |
897 free_parse_tree(tree->children[i]); | |
898 g_free(tree->children[i]); | |
899 } | |
900 } | |
901 } | |
902 if ((tree != &null_parse_tree) && (tree->contents != NULL)) | |
903 g_free(tree->contents); | |
2086 | 904 |
9896 | 905 } |
906 return 0; | |
907 } | |
908 | |
909 parse_tree *tree_child(parse_tree* tree,int index) { | |
910 if (index < tree->num_children) { | |
911 return tree->children[index]; | |
912 } else { | |
913 return &null_parse_tree; | |
914 } | |
915 } | |
916 | |
917 parse_tree *find_node(parse_tree* ptree,gchar* key) | |
918 { | |
919 gchar* tc = tree_child(ptree,0)->contents; | |
920 | |
921 if (!ptree || ! key) | |
922 return &null_parse_tree; | |
923 | |
924 if (ptree->num_children > 0 && tc && !strcasecmp(tc, key)) { | |
925 return ptree; | |
926 } else { | |
927 parse_tree *result = &null_parse_tree; | |
928 int i; | |
929 for(i = 0; i < ptree->num_children; i++) { | |
930 result = find_node(ptree->children[i],key); | |
931 if(result != &null_parse_tree) { | |
932 break; | |
933 } | |
934 } | |
935 return result; | |
936 } | |
937 } | |
938 | |
939 parse_tree *parse_buffer(gchar* source, gboolean do_parse) { | |
940 | |
941 parse_tree *ptree = g_new0(parse_tree,1); | |
942 ptree->contents = NULL; | |
943 ptree->num_children=0; | |
944 if (do_parse) { | |
945 unsigned int p = 0; | |
946 while(p < strlen(source)) { | |
947 unsigned int end; | |
9986 | 948 gchar *newstr; |
9896 | 949 |
950 /* Eat white space: */ | |
951 if(g_ascii_isspace(source[p]) || source[p] == '\001') { | |
952 p++; | |
953 continue; | |
954 } | |
955 | |
956 /* Skip comments */ | |
957 if(source[p] == ';') { | |
958 while(source[p] != '\n' && p < strlen(source)) { | |
959 p++; | |
960 } | |
961 continue; | |
962 } | |
963 | |
964 if(source[p] == '(') { | |
965 int nesting = 0; | |
966 gboolean in_quote = FALSE; | |
967 gboolean escape_next = FALSE; | |
968 p++; | |
969 end = p; | |
970 while(!(source[end] == ')' && nesting == 0 && !in_quote) && end < strlen(source)) { | |
971 if(!escape_next) { | |
972 if(source[end] == '\\') { | |
973 escape_next = TRUE; | |
974 } | |
975 if(!in_quote) { | |
976 if(source[end] == '(') { | |
977 nesting++; | |
978 } | |
979 if(source[end] == ')') { | |
980 nesting--; | |
981 } | |
982 } | |
983 if(source[end] == '"') { | |
984 in_quote = !in_quote; | |
985 } | |
986 } else { | |
987 escape_next = FALSE; | |
988 } | |
989 end++; | |
990 } | |
991 do_parse = TRUE; | |
992 | |
993 } else { | |
994 gchar end_char; | |
995 if(source[p] == '"') { | |
996 end_char = '"'; | |
997 p++; | |
998 } else { | |
999 end_char = ' '; | |
1000 } | |
1001 do_parse = FALSE; | |
1002 | |
1003 end = p; | |
1004 while(source[end] != end_char && end < strlen(source)) { | |
1005 if(source[end] == '\\') | |
1006 end++; | |
1007 end++; | |
1008 } | |
1009 } | |
1010 newstr = g_new0(gchar, end+1-p); | |
1011 strncpy(newstr,source+p,end-p); | |
1012 if (ptree->num_children < MAXCHILDREN) { | |
1013 /* In case we surpass maxchildren, ignore this */ | |
1014 ptree->children[ptree->num_children++] = parse_buffer( newstr, do_parse); | |
1015 } else { | |
1016 gaim_debug_error("zephyr","too many children in tzc output. skipping\n"); | |
1017 } | |
1018 g_free(newstr); | |
1019 p = end + 1; | |
1020 } | |
1021 return ptree; | |
1022 } else { | |
1023 /* XXX does this have to be strdup'd */ | |
1024 ptree->contents = g_strdup(source); | |
1025 return ptree; | |
1026 } | |
1027 } | |
1028 | |
1029 parse_tree *read_from_tzc(zephyr_account* zephyr){ | |
1030 struct timeval tv; | |
1031 fd_set rfds; | |
1032 int bufsize = 2048; | |
1033 char *buf = (char *)calloc(bufsize, 1); | |
1034 char *bufcur = buf; | |
1035 int selected = 0; | |
9986 | 1036 parse_tree *incoming_msg; |
9896 | 1037 |
1038 FD_ZERO(&rfds); | |
1039 FD_SET(zephyr->fromtzc[ZEPHYR_FD_READ], &rfds); | |
1040 tv.tv_sec = 0; | |
1041 tv.tv_usec = 0; | |
9986 | 1042 incoming_msg=NULL; |
9896 | 1043 |
1044 while (select(zephyr->fromtzc[ZEPHYR_FD_READ] + 1, &rfds, NULL, NULL, &tv)) { | |
1045 selected = 1; | |
1046 read(zephyr->fromtzc[ZEPHYR_FD_READ], bufcur, 1); | |
1047 bufcur++; | |
1048 if ((bufcur - buf) > (bufsize - 1)) { | |
1049 if ((buf = realloc(buf, bufsize * 2)) == NULL) { | |
1050 gaim_debug_error("zephyr","Ran out of memory"); | |
1051 exit(-1); | |
1052 } else { | |
1053 bufcur = buf + bufsize; | |
1054 bufsize *= 2; | |
1055 } | |
1056 } | |
1057 } | |
1058 *bufcur = '\0'; | |
1059 | |
1060 if (selected) { | |
1061 incoming_msg = parse_buffer(buf,TRUE); | |
1062 } | |
1063 free(buf); | |
1064 return incoming_msg; | |
1065 } | |
1066 | |
1067 static gint check_notify_tzc(gpointer data) | |
1068 { | |
1069 GaimConnection *gc = (GaimConnection *)data; | |
1070 zephyr_account* zephyr = gc->proto_data; | |
1071 parse_tree *newparsetree = read_from_tzc(zephyr); | |
1072 if (newparsetree != NULL) { | |
1073 gchar *spewtype; | |
1074 if ( (spewtype = tree_child(find_node(newparsetree,"tzcspew"),2)->contents) ) { | |
1075 if (!g_ascii_strncasecmp(spewtype,"message",7)) { | |
1076 ZNotice_t notice; | |
1077 parse_tree *msgnode = tree_child(find_node(newparsetree,"message"),2); | |
1078 parse_tree *bodynode = tree_child(msgnode,1); | |
1079 /* char *zsig = g_strdup(" "); */ /* gaim doesn't care about zsigs */ | |
1080 char *msg = zephyr_tzc_deescape_str(bodynode->contents); | |
1081 size_t bufsize = strlen(msg) + 3; | |
1082 char *buf = g_new0(char,bufsize); | |
1083 g_snprintf(buf,1+strlen(msg)+2," %c%s",'\0',msg); | |
1084 bzero((char *)¬ice, sizeof(notice)); | |
1085 notice.z_kind = ACKED; | |
1086 notice.z_port = 0; | |
1087 notice.z_opcode = tree_child(find_node(newparsetree,"opcode"),2)->contents; | |
1088 notice.z_class = zephyr_tzc_deescape_str(tree_child(find_node(newparsetree,"class"),2)->contents); | |
1089 notice.z_class_inst = tree_child(find_node(newparsetree,"instance"),2)->contents; | |
1090 notice.z_recipient = local_zephyr_normalize(zephyr,tree_child(find_node(newparsetree,"recipient"),2)->contents); | |
1091 notice.z_sender = local_zephyr_normalize(zephyr,tree_child(find_node(newparsetree,"sender"),2)->contents); | |
1092 notice.z_default_format = "Class $class, Instance $instance:\n" "To: @bold($recipient) at $time $date\n" "From: @bold($1) <$sender>\n\n$2"; | |
1093 notice.z_message_len = strlen(msg) + 3; | |
1094 notice.z_message = buf; | |
10300 | 1095 handle_message(gc, notice); |
9896 | 1096 g_free(msg); |
1097 /* g_free(zsig); */ | |
1098 g_free(buf); | |
1099 /* free_parse_tree(msgnode); | |
1100 free_parse_tree(bodynode); | |
1101 g_free(msg); | |
1102 g_free(zsig); | |
1103 g_free(buf); | |
1104 */ | |
1105 } | |
1106 else if (!g_ascii_strncasecmp(spewtype,"zlocation",9)) { | |
1107 /* check_loc or zephyr_zloc respectively */ | |
1108 /* XXX fix */ | |
1109 char *user; | |
1110 GaimBuddy *b; | |
1111 int nlocs = 0; | |
9912 | 1112 parse_tree *locations; |
1113 gchar *locval; | |
9896 | 1114 user = tree_child(find_node(newparsetree,"user"),2)->contents; |
1115 | |
1116 if ((b = gaim_find_buddy(gc->account, user)) == NULL) { | |
9986 | 1117 gchar *stripped_user = zephyr_strip_local_realm(zephyr,user); |
9912 | 1118 b = gaim_find_buddy(gc->account, stripped_user); |
9986 | 1119 g_free(stripped_user); |
9896 | 1120 } |
1121 locations = find_node(newparsetree,"locations"); | |
1122 locval = tree_child(tree_child(tree_child(tree_child(locations,2),0),0),2)->contents; | |
1123 | |
1124 if (!locval || !g_ascii_strcasecmp(locval," ") || (strlen(locval) == 0)) { | |
1125 nlocs = 0; | |
1126 } else { | |
1127 nlocs = 1; | |
1128 } | |
1129 | |
1130 if ((b && pending_zloc(zephyr,b->name)) || pending_zloc(zephyr,user) || pending_zloc(zephyr,local_zephyr_normalize(zephyr,user))){ | |
1131 GString *str = g_string_new(""); | |
1132 | |
1133 g_string_append_printf(str, _("<b>User:</b> %s<br>"), b ? b->name : user); | |
1134 if (b && b->alias) | |
1135 g_string_append_printf(str, _("<b>Alias:</b> %s<br>"), b->alias); | |
1136 | |
1137 if (!nlocs) { | |
1138 g_string_append_printf(str, _("<br>Hidden or not logged-in")); | |
1139 } else { | |
1140 g_string_append_printf(str, _("<br>At %s since %s"), | |
1141 tree_child(tree_child(tree_child(tree_child(locations,2),0),0),2)->contents, | |
1142 tree_child(tree_child(tree_child(tree_child(locations,2),0),2),2)->contents); | |
1143 } | |
1144 | |
11533
c9b815aeddc1
[gaim-migrate @ 13782]
Richard Laager <rlaager@wiktel.com>
parents:
11531
diff
changeset
|
1145 gaim_notify_userinfo(gc, b ? b->name : user, |
9896 | 1146 str->str, NULL, NULL); |
1147 g_string_free(str, TRUE); | |
1148 } else { | |
10038
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1149 if (nlocs>0) |
11638 | 1150 gaim_prpl_got_user_status(gc->account,b->name,"available",NULL); |
10038
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1151 else |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1152 gaim_prpl_got_user_status(gc->account,b->name,"offline",NULL); |
9896 | 1153 } |
1154 } | |
1155 else if (!g_ascii_strncasecmp(spewtype,"subscribed",10)) { | |
1156 } | |
1157 else if (!g_ascii_strncasecmp(spewtype,"start",5)) { | |
1158 } | |
1159 else if (!g_ascii_strncasecmp(spewtype,"error",5)) { | |
1160 /* XXX handle */ | |
1161 } | |
1162 } else { | |
1163 } | |
1164 } else { | |
1165 } | |
1166 | |
1167 free_parse_tree(newparsetree); | |
1168 return TRUE; | |
1169 } | |
1170 | |
1171 static gint check_notify_zeph02(gpointer data) | |
2086 | 1172 { |
9478 | 1173 /* XXX add real error reporting */ |
9896 | 1174 GaimConnection *gc = (GaimConnection*) data; |
2086 | 1175 while (ZPending()) { |
1176 ZNotice_t notice; | |
1177 struct sockaddr_in from; | |
9478 | 1178 /* XXX add real error reporting */ |
8644 | 1179 |
2086 | 1180 z_call_r(ZReceiveNotice(¬ice, &from)); |
1181 | |
1182 switch (notice.z_kind) { | |
1183 case UNSAFE: | |
1184 case UNACKED: | |
1185 case ACKED: | |
10300 | 1186 handle_message(gc,notice); |
2086 | 1187 break; |
8644 | 1188 case SERVACK: |
1189 if (!(g_ascii_strcasecmp(notice.z_message, ZSRVACK_NOTSENT))) { | |
9610 | 1190 message_failed(gc,notice, from); |
8644 | 1191 } |
1192 break; | |
9328 | 1193 case CLIENTACK: |
9478 | 1194 gaim_debug_error("zephyr", "Client ack received\n"); |
2086 | 1195 default: |
1196 /* we'll just ignore things for now */ | |
9328 | 1197 handle_unknown(notice); |
9478 | 1198 gaim_debug_error("zephyr", "Unhandled notice.\n"); |
2086 | 1199 break; |
1200 } | |
9478 | 1201 /* XXX add real error reporting */ |
2086 | 1202 ZFreeNotice(¬ice); |
1203 } | |
1204 | |
1205 return TRUE; | |
1206 } | |
1207 | |
10867 | 1208 #ifdef WIN32 |
1209 | |
1210 static gint check_loc(gpointer_data) | |
1211 { | |
1212 GaimBlistNode *gnode, *cnode, *bnode; | |
1213 ZLocations_t locations; | |
1214 int numlocs; | |
1215 int one = 1; | |
1216 | |
1217 for (gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) { | |
1218 if (!GAIM_BLIST_NODE_IS_GROUP(gnode)) | |
1219 continue; | |
1220 for (cnode = gnode->child; cnode; cnode = cnode->next) { | |
1221 if (!GAIM_BLIST_NODE_IS_CONTACT(cnode)) | |
1222 continue; | |
1223 for (bnode = cnode->child; bnode; bnode = bnode->next) { | |
1224 GaimBuddy *b = (GaimBuddy *) bnode; | |
1225 | |
1226 if (!GAIM_BLIST_NODE_IS_BUDDY(bnode)) | |
1227 continue; | |
1228 if (b->account->gc == zgc) { | |
1229 char *chk; | |
1230 chk = local_zephyr_normalize(b->name); | |
1231 ZLocateUser(chk,&numlocs, ZAUTH); | |
1232 if (numlocs) { | |
1233 int i; | |
1234 for(i=0;i<numlocs;i++) { | |
1235 ZGetLocations(&locations,&one); | |
1236 serv_got_update(zgc,b->name,1,0,0,0,0); | |
1237 } | |
1238 } | |
1239 } | |
1240 } | |
1241 } | |
1242 } | |
1243 return TRUE; | |
1244 } | |
1245 | |
1246 #else | |
1247 | |
2086 | 1248 static gint check_loc(gpointer data) |
1249 { | |
6695 | 1250 GaimBlistNode *gnode, *cnode, *bnode; |
2086 | 1251 ZAsyncLocateData_t ald; |
9896 | 1252 GaimConnection *gc = (GaimConnection *)data; |
1253 zephyr_account *zephyr = gc->proto_data; | |
2086 | 1254 |
9896 | 1255 if (use_zeph02(zephyr)) { |
1256 ald.user = NULL; | |
1257 memset(&(ald.uid), 0, sizeof(ZUnique_Id_t)); | |
1258 ald.version = NULL; | |
1259 } | |
2086 | 1260 |
8644 | 1261 for (gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) { |
1262 if (!GAIM_BLIST_NODE_IS_GROUP(gnode)) | |
4785 | 1263 continue; |
8644 | 1264 for (cnode = gnode->child; cnode; cnode = cnode->next) { |
1265 if (!GAIM_BLIST_NODE_IS_CONTACT(cnode)) | |
4785 | 1266 continue; |
8644 | 1267 for (bnode = cnode->child; bnode; bnode = bnode->next) { |
1268 GaimBuddy *b = (GaimBuddy *) bnode; | |
1269 | |
1270 if (!GAIM_BLIST_NODE_IS_BUDDY(bnode)) | |
6695 | 1271 continue; |
9610 | 1272 if (b->account->gc == gc) { |
7261 | 1273 const char *chk; |
8644 | 1274 |
9896 | 1275 chk = local_zephyr_normalize(zephyr,b->name); |
1276 gaim_debug_info("zephyr","chk: %s b->name %s\n",chk,b->name); | |
9478 | 1277 /* XXX add real error reporting */ |
6695 | 1278 /* doesn't matter if this fails or not; we'll just move on to the next one */ |
9896 | 1279 if (use_zeph02(zephyr)) { |
1280 #ifdef WIN32 | |
9986 | 1281 int numlocs; |
1282 int one=1; | |
1283 ZLocateUser(chk,&numlocs,ZAUTH); | |
1284 if (numlocs) { | |
1285 int i; | |
1286 for(i=0;i<numlocs;i++) { | |
1287 ZGetLocations(&locations,&one); | |
10038
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1288 if (nlocs>0) |
11638 | 1289 gaim_prpl_got_user_status(gc->account,b->name,"available",NULL); |
10038
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1290 else |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1291 gaim_prpl_got_user_status(gc->account,b->name,"offline",NULL); |
9986 | 1292 } |
1293 } | |
9896 | 1294 #else |
1295 ZRequestLocations(chk, &ald, UNACKED, ZAUTH); | |
1296 g_free(ald.user); | |
1297 g_free(ald.version); | |
1298 #endif /* WIN32 */ | |
1299 } else | |
1300 if (use_tzc(zephyr)) { | |
1301 gchar *zlocstr = g_strdup_printf("((tzcfodder . zlocate) \"%s\")\n",chk); | |
1302 write(zephyr->totzc[ZEPHYR_FD_WRITE],zlocstr,strlen(zlocstr)); | |
1303 g_free(zlocstr); | |
1304 } | |
6695 | 1305 } |
4349 | 1306 } |
2086 | 1307 } |
1308 } | |
9896 | 1309 |
2086 | 1310 return TRUE; |
1311 } | |
1312 | |
10867 | 1313 #endif /* WIN32 */ |
1314 | |
2086 | 1315 static char *get_exposure_level() |
1316 { | |
9478 | 1317 /* XXX add real error reporting */ |
2086 | 1318 char *exposure = ZGetVariable("exposure"); |
1319 | |
1320 if (!exposure) | |
1321 return EXPOSE_REALMVIS; | |
4793 | 1322 if (!g_ascii_strcasecmp(exposure, EXPOSE_NONE)) |
2086 | 1323 return EXPOSE_NONE; |
4793 | 1324 if (!g_ascii_strcasecmp(exposure, EXPOSE_OPSTAFF)) |
2086 | 1325 return EXPOSE_OPSTAFF; |
4793 | 1326 if (!g_ascii_strcasecmp(exposure, EXPOSE_REALMANN)) |
2086 | 1327 return EXPOSE_REALMANN; |
4793 | 1328 if (!g_ascii_strcasecmp(exposure, EXPOSE_NETVIS)) |
2086 | 1329 return EXPOSE_NETVIS; |
4793 | 1330 if (!g_ascii_strcasecmp(exposure, EXPOSE_NETANN)) |
2086 | 1331 return EXPOSE_NETANN; |
1332 return EXPOSE_REALMVIS; | |
1333 } | |
1334 | |
1335 static void strip_comments(char *str) | |
1336 { | |
1337 char *tmp = strchr(str, '#'); | |
8644 | 1338 |
2086 | 1339 if (tmp) |
1340 *tmp = '\0'; | |
1341 g_strchug(str); | |
1342 g_strchomp(str); | |
1343 } | |
1344 | |
9896 | 1345 static void zephyr_inithosts(zephyr_account *zephyr) |
9478 | 1346 { |
1347 /* XXX This code may not be Win32 clean */ | |
1348 struct hostent *hent; | |
1349 | |
9802 | 1350 if (gethostname(zephyr->ourhost, sizeof(zephyr->ourhost)) == -1) { |
10867 | 1351 gaim_debug_error("zephyr", "unable to retrieve hostname, %%host%% and %%canon%% will be wrong in subscriptions and have been set to unknown\n"); |
9802 | 1352 g_strlcpy(zephyr->ourhost, "unknown", sizeof(zephyr->ourhost)); |
9803 | 1353 g_strlcpy(zephyr->ourhostcanon, "unknown", sizeof(zephyr->ourhostcanon)); |
9478 | 1354 return; |
1355 } | |
1356 | |
9610 | 1357 if (!(hent = gethostbyname(zephyr->ourhost))) { |
10867 | 1358 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",zephyr->ourhost); |
9803 | 1359 g_strlcpy(zephyr->ourhostcanon, zephyr->ourhost, sizeof(zephyr->ourhostcanon)); |
9478 | 1360 return; |
1361 } | |
9802 | 1362 |
1363 g_strlcpy(zephyr->ourhostcanon, hent->h_name, sizeof(zephyr->ourhostcanon)); | |
1364 | |
9478 | 1365 return; |
1366 } | |
1367 | |
9610 | 1368 static void process_zsubs(zephyr_account *zephyr) |
2086 | 1369 { |
9802 | 1370 /* Loads zephyr chats "(subscriptions) from ~/.zephyr.subs, and |
1371 registers (subscribes to) them on the server */ | |
9434 | 1372 |
9802 | 1373 /* XXX deal with unsubscriptions */ |
1374 /* XXX deal with punts */ | |
9434 | 1375 |
2086 | 1376 FILE *f; |
1377 gchar *fname; | |
1378 gchar buff[BUFSIZ]; | |
8644 | 1379 |
3630 | 1380 fname = g_strdup_printf("%s/.zephyr.subs", gaim_home_dir()); |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10401
diff
changeset
|
1381 f = g_fopen(fname, "r"); |
2086 | 1382 if (f) { |
1383 char **triple; | |
1384 char *recip; | |
9478 | 1385 char *z_class; |
1386 char *z_instance; | |
9896 | 1387 char *z_galaxy = NULL; |
8644 | 1388 |
2086 | 1389 while (fgets(buff, BUFSIZ, f)) { |
1390 strip_comments(buff); | |
1391 if (buff[0]) { | |
1392 triple = g_strsplit(buff, ",", 3); | |
8644 | 1393 if (triple[0] && triple[1]) { |
9896 | 1394 char *tmp = g_strdup_printf("%s", zephyr->username); |
2804
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
1395 char *atptr; |
8644 | 1396 |
9896 | 1397 z_class = triple[0]; |
1398 z_instance = triple[1]; | |
8644 | 1399 if (triple[2] == NULL) { |
3277 | 1400 recip = g_malloc0(1); |
4793 | 1401 } else if (!g_ascii_strcasecmp(triple[2], "%me%")) { |
9896 | 1402 recip = g_strdup_printf("%s", zephyr->username); |
4793 | 1403 } else if (!g_ascii_strcasecmp(triple[2], "*")) { |
2804
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
1404 /* wildcard |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
1405 * form of class,instance,* */ |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
1406 recip = g_malloc0(1); |
4793 | 1407 } else if (!g_ascii_strcasecmp(triple[2], tmp)) { |
2804
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
1408 /* form of class,instance,aatharuv@ATHENA.MIT.EDU */ |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
1409 recip = g_strdup(triple[2]); |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
1410 } else if ((atptr = strchr(triple[2], '@')) != NULL) { |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
1411 /* form of class,instance,*@ANDREW.CMU.EDU |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
1412 * class,instance,@ANDREW.CMU.EDU |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
1413 * If realm is local realm, blank recipient, else |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
1414 * @REALM-NAME |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
1415 */ |
9896 | 1416 char *realmat = g_strdup_printf("@%s",zephyr->realm); |
8644 | 1417 |
4793 | 1418 if (!g_ascii_strcasecmp(atptr, realmat)) |
2804
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
1419 recip = g_malloc0(1); |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
1420 else |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
1421 recip = g_strdup(atptr); |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
1422 g_free(realmat); |
2086 | 1423 } else { |
1424 recip = g_strdup(triple[2]); | |
1425 } | |
2804
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
1426 g_free(tmp); |
9478 | 1427 |
1428 if (!g_ascii_strcasecmp(triple[0],"%host%")) { | |
9610 | 1429 z_class = g_strdup(zephyr->ourhost); |
9478 | 1430 } else if (!g_ascii_strcasecmp(triple[0],"%canon%")) { |
9610 | 1431 z_class = g_strdup(zephyr->ourhostcanon); |
9478 | 1432 } else { |
1433 z_class = g_strdup(triple[0]); | |
1434 } | |
1435 | |
1436 if (!g_ascii_strcasecmp(triple[1],"%host%")) { | |
9610 | 1437 z_instance = g_strdup(zephyr->ourhost); |
9478 | 1438 } else if (!g_ascii_strcasecmp(triple[1],"%canon%")) { |
9610 | 1439 z_instance = g_strdup(zephyr->ourhostcanon); |
9478 | 1440 } else { |
1441 z_instance = g_strdup(triple[1]); | |
1442 } | |
1443 | |
1444 /* There should be some sort of error report listing classes that couldn't be subbed to. | |
1445 Not important right now though */ | |
1446 | |
9896 | 1447 if (zephyr_subscribe_to(zephyr,z_class, z_instance, recip,z_galaxy) != ZERR_NONE) { |
9478 | 1448 |
10867 | 1449 gaim_debug_error("zephyr", "Couldn't subscribe to %s, %s, %s\n", z_class,z_instance,recip); |
2086 | 1450 } |
9478 | 1451 |
9896 | 1452 zephyr->subscrips = g_slist_append(zephyr->subscrips, new_triple(zephyr,z_class,z_instance,recip)); |
9478 | 1453 /* g_hash_table_destroy(sub_hash_table); */ |
1454 g_free(z_instance); | |
1455 g_free(z_class); | |
2086 | 1456 g_free(recip); |
1457 } | |
1458 g_strfreev(triple); | |
1459 } | |
1460 } | |
1461 } | |
1462 } | |
1463 | |
9610 | 1464 static void process_anyone(GaimConnection *gc) |
2086 | 1465 { |
1466 FILE *fd; | |
1467 gchar buff[BUFSIZ], *filename; | |
6695 | 1468 GaimGroup *g; |
1469 GaimBuddy *b; | |
4775 | 1470 |
1471 if (!(g = gaim_find_group(_("Anyone")))) { | |
1472 g = gaim_group_new(_("Anyone")); | |
1473 gaim_blist_add_group(g, NULL); | |
1474 } | |
6695 | 1475 |
3630 | 1476 filename = g_strconcat(gaim_home_dir(), "/.anyone", NULL); |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10401
diff
changeset
|
1477 if ((fd = g_fopen(filename, "r")) != NULL) { |
2086 | 1478 while (fgets(buff, BUFSIZ, fd)) { |
1479 strip_comments(buff); | |
4687 | 1480 if (buff[0]) { |
9610 | 1481 if (!(b = gaim_find_buddy(gc->account, buff))) { |
9986 | 1482 char *stripped_user = zephyr_strip_local_realm(gc->proto_data,buff); |
1483 gaim_debug_info("zephyr","stripped_user %s\n",stripped_user); | |
1484 if (!(b = gaim_find_buddy(gc->account,stripped_user))){ | |
1485 b = gaim_buddy_new(gc->account, stripped_user, NULL); | |
1486 gaim_blist_add_buddy(b, NULL, g, NULL); | |
1487 } | |
1488 g_free(stripped_user); | |
8644 | 1489 } |
1490 } | |
2086 | 1491 } |
1492 fclose(fd); | |
1493 } | |
1494 g_free(filename); | |
1495 } | |
1496 | |
10038
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1497 static char* normalize_zephyr_exposure(const char* exposure) { |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1498 char *exp2 = g_strstrip(g_ascii_strup(exposure,-1)); |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1499 |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1500 if (!exp2) |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1501 return EXPOSE_REALMVIS; |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1502 if (!g_ascii_strcasecmp(exp2, EXPOSE_NONE)) |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1503 return EXPOSE_NONE; |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1504 if (!g_ascii_strcasecmp(exp2, EXPOSE_OPSTAFF)) |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1505 return EXPOSE_OPSTAFF; |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1506 if (!g_ascii_strcasecmp(exp2, EXPOSE_REALMANN)) |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1507 return EXPOSE_REALMANN; |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1508 if (!g_ascii_strcasecmp(exp2, EXPOSE_NETVIS)) |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1509 return EXPOSE_NETVIS; |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1510 if (!g_ascii_strcasecmp(exp2, EXPOSE_NETANN)) |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1511 return EXPOSE_NETANN; |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1512 return EXPOSE_REALMVIS; |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1513 } |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1514 |
11837 | 1515 static void zephyr_login(GaimAccount * account) |
2086 | 1516 { |
9896 | 1517 GaimConnection *gc; |
1518 zephyr_account *zephyr; | |
10038
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1519 gboolean read_anyone; |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1520 gboolean read_zsubs; |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1521 gchar *exposure; |
9427 | 1522 |
9610 | 1523 gc = gaim_account_get_connection(account); |
10038
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1524 read_anyone = gaim_account_get_bool(gc->account,"read_anyone",TRUE); |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1525 read_zsubs = gaim_account_get_bool(gc->account,"read_zsubs",TRUE); |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1526 exposure = (gchar *)gaim_account_get_string(gc->account, "exposure_level", EXPOSE_REALMVIS); |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1527 |
10867 | 1528 #ifdef WIN32 |
1529 username = gaim_account_get_username(account); | |
1530 #endif | |
9610 | 1531 gc->flags |= GAIM_CONNECTION_HTML | GAIM_CONNECTION_NO_BGCOLOR | GAIM_CONNECTION_NO_URLDESC; |
9896 | 1532 gc->proto_data = zephyr=g_new0(zephyr_account,1); |
10038
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1533 |
9896 | 1534 zephyr->account = account; |
10038
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1535 |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1536 /* Make sure that the exposure (visibility) is set to a sane value */ |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1537 zephyr->exposure=g_strdup(normalize_zephyr_exposure(exposure)); |
2086 | 1538 |
9896 | 1539 if (gaim_account_get_bool(gc->account,"use_tzc",0)) { |
1540 zephyr->connection_type = GAIM_ZEPHYR_TZC; | |
1541 } else { | |
1542 zephyr->connection_type = GAIM_ZEPHYR_KRB4; | |
1543 } | |
1544 | |
1545 zephyr->encoding = (char *)gaim_account_get_string(gc->account, "encoding", ZEPHYR_FALLBACK_CHARSET); | |
9610 | 1546 gaim_connection_update_progress(gc, _("Connecting"), 0, 8); |
9478 | 1547 |
1548 /* XXX z_call_s should actually try to report the com_err determined error */ | |
9896 | 1549 if (use_tzc(zephyr)) { |
1550 pid_t pid; | |
1551 /* gaim_connection_error(gc,"tzc not supported yet"); */ | |
1552 if ((pipe(zephyr->totzc) != 0) || (pipe(zephyr->fromtzc) != 0)) { | |
1553 gaim_debug_error("zephyr", "pipe creation failed. killing\n"); | |
1554 exit(-1); | |
1555 } | |
1556 | |
1557 pid = fork(); | |
1558 | |
1559 if (pid == -1) { | |
1560 gaim_debug_error("zephyr", "forking failed\n"); | |
1561 exit(-1); | |
1562 } | |
1563 if (pid == 0) { | |
1564 unsigned int i=0; | |
1565 gboolean found_ps = FALSE; | |
1566 gchar ** tzc_cmd_array = g_strsplit(gaim_account_get_string(gc->account,"tzc_command","/usr/bin/tzc -e %s")," ",0); | |
1567 if (close(1) == -1) { | |
1568 gaim_debug_error("zephyr", "stdout couldn't be closed. dying\n"); | |
1569 exit(-1); | |
1570 } | |
1571 if (dup2(zephyr->fromtzc[1], 1) == -1) { | |
1572 gaim_debug_error("zephyr", "dup2 of stdout failed \n"); | |
1573 exit(-1); | |
1574 } | |
1575 if (close(zephyr->fromtzc[1]) == -1) { | |
1576 gaim_debug_error("zephyr", "closing of piped stdout failed\n"); | |
1577 exit(-1); | |
1578 } | |
1579 if (close(0) == -1) { | |
1580 gaim_debug_error("zephyr", "stdin couldn't be closed. dying\n"); | |
1581 exit(-1); | |
1582 } | |
1583 if (dup2(zephyr->totzc[0], 0) == -1) { | |
1584 gaim_debug_error("zephyr", "dup2 of stdin failed \n"); | |
1585 exit(-1); | |
1586 } | |
1587 if (close(zephyr->totzc[0]) == -1) { | |
1588 gaim_debug_error("zephyr", "closing of piped stdin failed\n"); | |
1589 exit(-1); | |
1590 } | |
1591 /* tzc_command should really be of the form | |
1592 path/to/tzc -e %s | |
1593 or | |
1594 ssh username@hostname pathtotzc -e %s | |
1595 -- this should not require a password, and ideally should be kerberized ssh -- | |
1596 or | |
1597 fsh username@hostname pathtotzc -e %s | |
1598 */ | |
1599 while(tzc_cmd_array[i] != NULL){ | |
1600 if (!g_strncasecmp(tzc_cmd_array[i],"%s",2)) { | |
9986 | 1601 /* fprintf(stderr,"replacing %%s with %s\n",zephyr->exposure); */ |
9896 | 1602 tzc_cmd_array[i] = g_strdup(zephyr->exposure); |
1603 found_ps = TRUE; | |
1604 | |
1605 } else { | |
9986 | 1606 /* fprintf(stderr,"keeping %s\n",tzc_cmd_array[i]); */ |
9896 | 1607 } |
1608 i++; | |
1609 } | |
8645 | 1610 |
9896 | 1611 if (!found_ps) { |
1612 gaim_connection_error(gc,"Tzc command needs %s to set the exposure\n"); | |
1613 return; | |
1614 } | |
1615 | |
1616 execvp(tzc_cmd_array[0], tzc_cmd_array); | |
1617 } | |
1618 else { | |
1619 fd_set rfds; | |
1620 int bufsize = 2048; | |
1621 char *buf = (char *)calloc(bufsize, 1); | |
1622 char *bufcur = buf; | |
1623 struct timeval tv; | |
1624 char *ptr; | |
1625 int parenlevel=0; | |
1626 char* tempstr; | |
1627 int tempstridx; | |
1628 | |
9986 | 1629 zephyr->tzc_pid = pid; |
9896 | 1630 /* wait till we have data to read from ssh */ |
1631 FD_ZERO(&rfds); | |
1632 FD_SET(zephyr->fromtzc[ZEPHYR_FD_READ], &rfds); | |
1633 | |
1634 tv.tv_sec = 10; | |
1635 tv.tv_usec = 0; | |
1636 | |
1637 gaim_debug_info("zephyr", "about to read from tzc\n"); | |
1638 | |
1639 select(zephyr->fromtzc[ZEPHYR_FD_READ] + 1, &rfds, NULL, NULL, NULL); | |
1640 | |
1641 FD_ZERO(&rfds); | |
1642 FD_SET(zephyr->fromtzc[ZEPHYR_FD_READ], &rfds); | |
1643 while (select(zephyr->fromtzc[ZEPHYR_FD_READ] + 1, &rfds, NULL, NULL, &tv)) { | |
1644 read(zephyr->fromtzc[ZEPHYR_FD_READ], bufcur, 1); | |
1645 bufcur++; | |
1646 if ((bufcur - buf) > (bufsize - 1)) { | |
1647 if ((buf = realloc(buf, bufsize * 2)) == NULL) { | |
1648 exit(-1); | |
1649 } else { | |
1650 bufcur = buf + bufsize; | |
1651 bufsize *= 2; | |
1652 } | |
1653 } | |
1654 FD_ZERO(&rfds); | |
1655 FD_SET(zephyr->fromtzc[ZEPHYR_FD_READ], &rfds); | |
1656 tv.tv_sec = 10; | |
1657 tv.tv_usec = 0; | |
2086 | 1658 |
9896 | 1659 } |
9986 | 1660 /* fprintf(stderr, "read from tzc\n"); */ |
9896 | 1661 *bufcur = '\0'; |
1662 ptr = buf; | |
1663 | |
1664 /* ignore all tzcoutput till we've received the first (*/ | |
1665 while (ptr < bufcur && (*ptr !='(')) { | |
1666 ptr++; | |
1667 } | |
1668 if (ptr >=bufcur) { | |
1669 gaim_connection_error(gc,"invalid output by tzc (or bad parsing code)"); | |
1670 return; | |
1671 } | |
9427 | 1672 |
9896 | 1673 while(ptr < bufcur) { |
1674 if (*ptr == '(') { | |
1675 parenlevel++; | |
1676 } | |
1677 else if (*ptr == ')') { | |
1678 parenlevel--; | |
1679 } | |
1680 gaim_debug_info("zephyr","tzc parenlevel is %d\n",parenlevel); | |
1681 switch (parenlevel) { | |
1682 case 0: | |
1683 break; | |
1684 case 1: | |
1685 /* Search for next beginning (, or for the ending */ | |
1686 ptr++; | |
1687 while((*ptr != '(') && (*ptr != ')') && (ptr <bufcur)) | |
1688 ptr++; | |
1689 if (ptr >= bufcur) | |
1690 gaim_debug_error("zephyr","tzc parsing error\n"); | |
1691 break; | |
1692 case 2: | |
1693 /* You are probably at | |
1694 (foo . bar ) or (foo . "bar") or (foo . chars) or (foo . numbers) or (foo . () ) | |
1695 Parse all the data between the first and last f, and move past ) | |
1696 */ | |
1697 tempstr = g_malloc0(20000); | |
1698 tempstridx=0; | |
1699 while(parenlevel >1) { | |
1700 ptr++; | |
1701 if (*ptr == '(') | |
1702 parenlevel++; | |
1703 if (*ptr == ')') | |
1704 parenlevel--; | |
1705 if (parenlevel > 1) { | |
1706 tempstr[tempstridx++]=*ptr; | |
1707 } else { | |
1708 ptr++; | |
1709 } | |
1710 } | |
1711 gaim_debug_info("zephyr","tempstr parsed\n"); | |
1712 /* tempstr should now be a tempstridx length string containing all characters | |
1713 from that after the first ( to the one before the last paren ). */ | |
1714 /* We should have the following possible lisp strings but we don't care | |
1715 (tzcspew . start) (version . "something") (pid . number)*/ | |
1716 /* We care about 'zephyrid . "username@REALM.NAME"' and 'exposure . "SOMETHING"' */ | |
1717 tempstridx=0; | |
1718 if (!g_ascii_strncasecmp(tempstr,"zephyrid",8)) { | |
1719 gchar* username = g_malloc0(100); | |
1720 int username_idx=0; | |
1721 char *realm; | |
1722 gaim_debug_info("zephyr","zephyrid found\n"); | |
1723 tempstridx+=8; | |
1724 while(tempstr[tempstridx] !='"' && tempstridx < 20000) | |
1725 tempstridx++; | |
1726 tempstridx++; | |
1727 while(tempstr[tempstridx] !='"' && tempstridx < 20000) | |
1728 username[username_idx++]=tempstr[tempstridx++]; | |
1729 | |
1730 zephyr->username = g_strdup_printf("%s",username); | |
1731 if ((realm = strchr(username,'@'))) | |
1732 zephyr->realm = g_strdup_printf("%s",realm+1); | |
10038
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1733 else { |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1734 realm = (gchar *)gaim_account_get_string(gc->account,"realm",""); |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1735 if (!g_strcasecmp(realm,"")) { |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1736 realm = "local-realm"; |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1737 } |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1738 zephyr->realm = g_strdup(realm); |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1739 g_strlcpy(__Zephyr_realm, (const char*)zephyr->realm, REALM_SZ-1); |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1740 } |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1741 /* else { |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1742 zephyr->realm = g_strdup("local-realm"); |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1743 }*/ |
9896 | 1744 |
1745 g_free(username); | |
1746 } else { | |
1747 gaim_debug_info("zephyr", "something that's not zephyr id found %s\n",tempstr); | |
1748 } | |
1749 | |
1750 /* We don't care about anything else yet */ | |
1751 g_free(tempstr); | |
1752 break; | |
1753 default: | |
1754 gaim_debug_info("zephyr","parenlevel is not 1 or 2\n"); | |
1755 /* This shouldn't be happening */ | |
1756 break; | |
1757 } | |
1758 if (parenlevel==0) | |
1759 break; | |
1760 } /* while (ptr < bufcur) { */ | |
1761 gaim_debug_info("zephyr", "tzc startup done\n"); | |
1762 } | |
1763 } | |
1764 else if ( use_zeph02(zephyr)) { | |
10038
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1765 gchar* realm; |
9896 | 1766 z_call_s(ZInitialize(), "Couldn't initialize zephyr"); |
1767 z_call_s(ZOpenPort(&(zephyr->port)), "Couldn't open port"); | |
1768 z_call_s(ZSetLocation((char *)zephyr->exposure), "Couldn't set location"); | |
10038
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1769 |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1770 realm = (gchar *)gaim_account_get_string(gc->account,"realm",""); |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1771 if (!g_strcasecmp(realm,"")) { |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1772 realm = ZGetRealm(); |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1773 } |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1774 zephyr->realm = g_strdup(realm); |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1775 g_strlcpy(__Zephyr_realm, (const char*)zephyr->realm, REALM_SZ-1); |
9896 | 1776 zephyr->username = g_strdup(ZGetSender()); |
10038
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1777 |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1778 /* zephyr->realm = g_strdup(ZGetRealm()); */ |
9896 | 1779 gaim_debug_info("zephyr","realm: %s\n",zephyr->realm); |
1780 } | |
1781 else { | |
1782 gaim_connection_error(gc,"Only ZEPH0.2 supported currently"); | |
1783 return; | |
1784 } | |
1785 gaim_debug_info("zephyr","does it get here\n"); | |
1786 gaim_debug_info("zephyr"," realm: %s username:%s\n", zephyr->realm, zephyr->username); | |
1787 | |
1788 /* For now */ | |
1789 zephyr->galaxy = NULL; | |
1790 zephyr->krbtkfile = NULL; | |
1791 zephyr_inithosts(zephyr); | |
1792 | |
1793 if (zephyr_subscribe_to(zephyr,"MESSAGE","PERSONAL",zephyr->username,NULL) != ZERR_NONE) { | |
9478 | 1794 /* XXX don't translate this yet. It could be written better */ |
1795 /* XXX error messages could be handled with more detail */ | |
1796 gaim_notify_error(account->gc, NULL, | |
1797 "Unable to subscribe to messages", "Unable to subscribe to initial messages"); | |
1798 return; | |
2086 | 1799 } |
1800 | |
9610 | 1801 gaim_connection_set_state(gc, GAIM_CONNECTED); |
10038
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1802 |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1803 if (read_anyone) |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1804 process_anyone(gc); |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1805 if (read_zsubs) |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1806 process_zsubs(zephyr); |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
1807 |
9896 | 1808 if (use_zeph02(zephyr)) { |
1809 zephyr->nottimer = gaim_timeout_add(100, check_notify_zeph02, gc); | |
1810 } else if (use_tzc(zephyr)) { | |
1811 zephyr->nottimer = gaim_timeout_add(100, check_notify_tzc, gc); | |
1812 } | |
1813 zephyr->loctimer = gaim_timeout_add(20000, check_loc, gc); | |
2086 | 1814 |
1815 } | |
1816 | |
9610 | 1817 static void write_zsubs(zephyr_account *zephyr) |
2086 | 1818 { |
9896 | 1819 /* Exports subscription (chat) list back to |
1820 * .zephyr.subs | |
1821 * XXX deal with %host%, %canon%, unsubscriptions, and negative subscriptions (punts?) | |
1822 */ | |
9434 | 1823 |
9610 | 1824 GSList *s = zephyr->subscrips; |
2086 | 1825 zephyr_triple *zt; |
1826 FILE *fd; | |
1827 char *fname; | |
1828 | |
8644 | 1829 char **triple; |
1830 | |
3630 | 1831 fname = g_strdup_printf("%s/.zephyr.subs", gaim_home_dir()); |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10401
diff
changeset
|
1832 fd = g_fopen(fname, "w"); |
8644 | 1833 |
2086 | 1834 if (!fd) { |
1835 g_free(fname); | |
1836 return; | |
1837 } | |
8644 | 1838 |
2086 | 1839 while (s) { |
9478 | 1840 char *zclass, *zinst, *zrecip; |
2086 | 1841 zt = s->data; |
8644 | 1842 triple = g_strsplit(zt->name, ",", 3); |
9478 | 1843 |
1844 /* deal with classes */ | |
9610 | 1845 if (!g_ascii_strcasecmp(triple[0],zephyr->ourhost)) { |
9775 | 1846 zclass = g_strdup("%host%"); |
9610 | 1847 } else if (!g_ascii_strcasecmp(triple[0],zephyr->ourhostcanon)) { |
9775 | 1848 zclass = g_strdup("%canon%"); |
9478 | 1849 } else { |
1850 zclass = g_strdup(triple[0]); | |
1851 } | |
1852 | |
1853 /* deal with instances */ | |
1854 | |
9610 | 1855 if (!g_ascii_strcasecmp(triple[1],zephyr->ourhost)) { |
9775 | 1856 zinst = g_strdup("%host%"); |
9610 | 1857 } else if (!g_ascii_strcasecmp(triple[1],zephyr->ourhostcanon)) { |
9896 | 1858 zinst = g_strdup("%canon%");; |
1859 } else { | |
9478 | 1860 zinst = g_strdup(triple[1]); |
9896 | 1861 } |
9478 | 1862 |
1863 /* deal with recipients */ | |
1864 if (triple[2] == NULL) { | |
1865 zrecip = g_strdup("*"); | |
1866 } else if (!g_ascii_strcasecmp(triple[2],"")){ | |
1867 zrecip = g_strdup("*"); | |
9896 | 1868 } else if (!g_ascii_strcasecmp(triple[2], zephyr->username)) { |
9478 | 1869 zrecip = g_strdup("%me%"); |
3277 | 1870 } else { |
9478 | 1871 zrecip = g_strdup(triple[2]); |
3277 | 1872 } |
9478 | 1873 |
1874 fprintf(fd, "%s,%s,%s\n",zclass,zinst,zrecip); | |
1875 | |
1876 g_free(zclass); | |
1877 g_free(zinst); | |
1878 g_free(zrecip); | |
3277 | 1879 g_free(triple); |
2086 | 1880 s = s->next; |
1881 } | |
1882 g_free(fname); | |
1883 fclose(fd); | |
1884 } | |
1885 | |
9610 | 1886 static void write_anyone(GaimConnection *gc) |
2086 | 1887 { |
6695 | 1888 GaimBlistNode *gnode, *cnode, *bnode; |
1889 GaimBuddy *b; | |
9912 | 1890 char *fname; |
2086 | 1891 FILE *fd; |
9896 | 1892 zephyr_account* zephyr = gc->proto_data; |
3630 | 1893 fname = g_strdup_printf("%s/.anyone", gaim_home_dir()); |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10401
diff
changeset
|
1894 fd = g_fopen(fname, "w"); |
2086 | 1895 if (!fd) { |
1896 g_free(fname); | |
1897 return; | |
1898 } | |
1899 | |
8644 | 1900 for (gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) { |
1901 if (!GAIM_BLIST_NODE_IS_GROUP(gnode)) | |
4785 | 1902 continue; |
8644 | 1903 for (cnode = gnode->child; cnode; cnode = cnode->next) { |
1904 if (!GAIM_BLIST_NODE_IS_CONTACT(cnode)) | |
4785 | 1905 continue; |
8644 | 1906 for (bnode = cnode->child; bnode; bnode = bnode->next) { |
1907 if (!GAIM_BLIST_NODE_IS_BUDDY(bnode)) | |
6695 | 1908 continue; |
8644 | 1909 b = (GaimBuddy *) bnode; |
9610 | 1910 if (b->account == gc->account) { |
9986 | 1911 gchar *stripped_user = zephyr_strip_local_realm(zephyr,b->name); |
9912 | 1912 fprintf(fd, "%s\n", stripped_user); |
9986 | 1913 g_free(stripped_user); |
3277 | 1914 } |
1915 } | |
2086 | 1916 } |
1917 } | |
1918 | |
1919 fclose(fd); | |
1920 g_free(fname); | |
1921 } | |
1922 | |
8644 | 1923 static void zephyr_close(GaimConnection * gc) |
2086 | 1924 { |
1925 GList *l; | |
1926 GSList *s; | |
9896 | 1927 zephyr_account *zephyr = gc->proto_data; |
9986 | 1928 pid_t tzc_pid = zephyr->tzc_pid; |
8644 | 1929 |
9610 | 1930 l = zephyr->pending_zloc_names; |
2086 | 1931 while (l) { |
8644 | 1932 g_free((char *)l->data); |
2086 | 1933 l = l->next; |
1934 } | |
9610 | 1935 g_list_free(zephyr->pending_zloc_names); |
8644 | 1936 |
9610 | 1937 if (gaim_account_get_bool(gc->account, "write_anyone", FALSE)) |
1938 write_anyone(gc); | |
8644 | 1939 |
9610 | 1940 if (gaim_account_get_bool(gc->account, "write_zsubs", FALSE)) |
1941 write_zsubs(gc->proto_data); | |
8644 | 1942 |
9610 | 1943 s = zephyr->subscrips; |
2086 | 1944 while (s) { |
8644 | 1945 free_triple((zephyr_triple *) s->data); |
2086 | 1946 s = s->next; |
1947 } | |
9610 | 1948 g_slist_free(zephyr->subscrips); |
8644 | 1949 |
9610 | 1950 if (zephyr->nottimer) |
1951 gaim_timeout_remove(zephyr->nottimer); | |
1952 zephyr->nottimer = 0; | |
1953 if (zephyr->loctimer) | |
1954 gaim_timeout_remove(zephyr->loctimer); | |
1955 zephyr->loctimer = 0; | |
1956 gc = NULL; | |
9896 | 1957 if (use_zeph02(zephyr)) { |
1958 z_call(ZCancelSubscriptions(0)); | |
1959 z_call(ZUnsetLocation()); | |
1960 z_call(ZClosePort()); | |
1961 } else { | |
1962 /* assume tzc */ | |
9986 | 1963 if (kill(tzc_pid,SIGTERM) == -1) { |
1964 int err=errno; | |
1965 if (err==EINVAL) { | |
1966 gaim_debug_error("zephyr","An invalid signal was specified when killing tzc\n"); | |
1967 } | |
1968 else if (err==ESRCH) { | |
1969 gaim_debug_error("zephyr","Tzc's pid didn't exist while killing tzc\n"); | |
1970 } | |
1971 else if (err==EPERM) { | |
1972 gaim_debug_error("zephyr","gaim didn't have permission to kill tzc\n"); | |
1973 } | |
1974 else { | |
1975 gaim_debug_error("zephyr","miscellaneous error while attempting to close tzc\n"); | |
1976 } | |
1977 } | |
9896 | 1978 } |
2086 | 1979 } |
1980 | |
9896 | 1981 static int zephyr_send_message(zephyr_account *zephyr,char* zclass, char* instance, char* recipient, const char *im, |
9478 | 1982 const char *sig, char *opcode) ; |
9434 | 1983 |
1984 const char * zephyr_get_signature() | |
1985 { | |
9478 | 1986 /* XXX add zephyr error reporting */ |
1987 const char * sig =ZGetVariable("zwrite-signature"); | |
9896 | 1988 if (!sig) { |
1989 sig = g_get_real_name(); | |
1990 } | |
1991 return sig; | |
9434 | 1992 } |
1993 | |
12216 | 1994 static int zephyr_chat_send(GaimConnection * gc, int id, const char *im, GaimMessageFlags flags) |
2086 | 1995 { |
1996 zephyr_triple *zt; | |
1997 const char *sig; | |
8644 | 1998 GaimConversation *gconv1; |
1999 GaimConvChat *gcc; | |
2000 char *inst; | |
9896 | 2001 char *recipient; |
2002 zephyr_account *zephyr = gc->proto_data; | |
2086 | 2003 |
9610 | 2004 zt = find_sub_by_id(gc->proto_data,id); |
2086 | 2005 if (!zt) |
2006 /* this should never happen. */ | |
2167
edf8c5a70e5b
[gaim-migrate @ 2177]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2162
diff
changeset
|
2007 return -EINVAL; |
8644 | 2008 |
9896 | 2009 sig = zephyr_get_signature(); |
2086 | 2010 |
11338 | 2011 gconv1 = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, zt->name, |
10246 | 2012 gc->account); |
8644 | 2013 gcc = gaim_conversation_get_chat_data(gconv1); |
8212 | 2014 |
8644 | 2015 if (!(inst = (char *)gaim_conv_chat_get_topic(gcc))) |
9434 | 2016 inst = g_strdup("PERSONAL"); |
8644 | 2017 |
4793 | 2018 if (!g_ascii_strcasecmp(zt->recipient, "*")) |
9896 | 2019 recipient = local_zephyr_normalize(zephyr,""); |
2086 | 2020 else |
9896 | 2021 recipient = local_zephyr_normalize(zephyr,zt->recipient); |
8451 | 2022 |
9896 | 2023 zephyr_send_message(zephyr,zt->class,inst,recipient,im,sig,""); |
2167
edf8c5a70e5b
[gaim-migrate @ 2177]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2162
diff
changeset
|
2024 return 0; |
2086 | 2025 } |
2026 | |
9434 | 2027 |
12216 | 2028 static int zephyr_send_im(GaimConnection * gc, const char *who, const char *im, GaimMessageFlags flags) |
8644 | 2029 { |
2086 | 2030 const char *sig; |
9896 | 2031 zephyr_account *zephyr = gc->proto_data; |
12216 | 2032 if (flags & GAIM_MESSAGE_AUTO_RESP) |
2086 | 2033 sig = "Automated reply:"; |
2034 else { | |
9434 | 2035 sig = zephyr_get_signature(); |
2086 | 2036 } |
9896 | 2037 zephyr_send_message(zephyr,"MESSAGE","PERSONAL",local_zephyr_normalize(zephyr,who),im,sig,""); |
9434 | 2038 |
2039 return 1; | |
2040 } | |
2086 | 2041 |
9896 | 2042 /* Munge the outgoing zephyr so that any quotes or backslashes are |
2043 escaped and do not confuse tzc: */ | |
2044 | |
2045 char* zephyr_tzc_escape_msg(const char *message) | |
2046 { | |
2047 int pos = 0; | |
2048 int pos2 = 0; | |
2049 char *newmsg; | |
2050 | |
2051 if (message && (strlen(message) > 0)) { | |
2052 newmsg = g_new0(char,1+strlen(message)*2); | |
2053 while(pos < strlen(message)) { | |
2054 if (message[pos]=='\\') { | |
2055 newmsg[pos2]='\\'; | |
2056 newmsg[pos2+1]='\\'; | |
2057 pos2+=2; | |
2058 } | |
2059 else if (message[pos]=='"') { | |
2060 newmsg[pos2]='\\'; | |
2061 newmsg[pos2+1]='"'; | |
2062 pos2+=2; | |
2063 } | |
2064 else { | |
2065 newmsg[pos2] = message[pos]; | |
2066 pos2++; | |
2067 } | |
2068 pos++; | |
2069 } | |
2070 } else { | |
2071 newmsg = g_strdup(""); | |
2072 } | |
9986 | 2073 /* fprintf(stderr,"newmsg %s message %s\n",newmsg,message); */ |
9896 | 2074 return newmsg; |
2075 } | |
2076 | |
2077 char* zephyr_tzc_deescape_str(const char *message) | |
2078 { | |
2079 int pos = 0; | |
2080 int pos2 = 0; | |
2081 char *newmsg; | |
2082 | |
2083 if (message && (strlen(message) > 0)) { | |
2084 newmsg = g_new0(char,strlen(message)+1); | |
2085 while(pos < strlen(message)) { | |
2086 if (message[pos]=='\\') { | |
2087 pos++; | |
2088 } | |
2089 newmsg[pos2] = message[pos]; | |
2090 pos++;pos2++; | |
2091 } | |
2092 newmsg[pos2]='\0'; | |
2093 } else { | |
2094 newmsg = g_strdup(""); | |
2095 } | |
2096 | |
2097 return newmsg; | |
2098 } | |
2099 | |
2100 static int zephyr_send_message(zephyr_account *zephyr,char* zclass, char* instance, char* recipient, const char *im, | |
9478 | 2101 const char *sig, char *opcode) |
9434 | 2102 { |
8451 | 2103 |
9896 | 2104 /* (From the tzc source) |
2105 * emacs sends something of the form: | |
2106 * ((class . "MESSAGE") | |
2107 * (auth . t) | |
2108 * (recipients ("PERSONAL" . "bovik") ("test" . "")) | |
2109 * (sender . "bovik") | |
2110 * (message . ("Harry Bovik" "my zgram")) | |
2111 * ) | |
2112 */ | |
2113 char *html_buf; | |
2114 char *html_buf2; | |
2115 html_buf = html_to_zephyr(im); | |
2116 html_buf2 = gaim_unescape_html(html_buf); | |
9434 | 2117 |
9896 | 2118 if(use_tzc(zephyr)) { |
2119 char* zsendstr; | |
2120 /* CMU cclub tzc doesn't grok opcodes for now */ | |
2121 char* tzc_sig = zephyr_tzc_escape_msg(sig); | |
2122 char *tzc_body = zephyr_tzc_escape_msg(html_buf2); | |
2123 zsendstr = g_strdup_printf("((tzcfodder . send) (class . \"%s\") (auth . t) (recipients (\"%s\" . \"%s\")) (message . (\"%s\" \"%s\")) ) \n", | |
9986 | 2124 zclass, instance, recipient, tzc_sig, tzc_body); |
2125 /* fprintf(stderr,"zsendstr = %s\n",zsendstr); */ | |
9896 | 2126 write(zephyr->totzc[ZEPHYR_FD_WRITE],zsendstr,strlen(zsendstr)); |
2127 g_free(zsendstr); | |
2128 } else if (use_zeph02(zephyr)) { | |
2129 ZNotice_t notice; | |
2130 char *buf = g_strdup_printf("%s%c%s", sig, '\0', html_buf2); | |
2131 bzero((char *)¬ice, sizeof(notice)); | |
2132 | |
2133 notice.z_kind = ACKED; | |
2134 notice.z_port = 0; | |
2135 notice.z_opcode = ""; | |
2136 notice.z_class = zclass; | |
2137 notice.z_class_inst = instance; | |
2138 notice.z_recipient = recipient; | |
2139 notice.z_sender = 0; | |
2140 notice.z_default_format = "Class $class, Instance $instance:\n" "To: @bold($recipient) at $time $date\n" "From: @bold($1) <$sender>\n\n$2"; | |
2141 notice.z_message_len = strlen(html_buf2) + strlen(sig) + 2; | |
2142 notice.z_message = buf; | |
2143 notice.z_opcode = g_strdup(opcode); | |
2144 gaim_debug_info("zephyr","About to send notice"); | |
2145 if (! ZSendNotice(¬ice, ZAUTH) == ZERR_NONE) { | |
2146 /* XXX handle errors here */ | |
2147 return 0; | |
2148 } | |
2149 gaim_debug_info("zephyr","notice sent"); | |
2150 g_free(buf); | |
9478 | 2151 } |
2152 | |
8644 | 2153 g_free(html_buf2); |
2154 g_free(html_buf); | |
8451 | 2155 |
9896 | 2156 return 1; |
2086 | 2157 } |
2158 | |
9896 | 2159 char *local_zephyr_normalize(zephyr_account *zephyr,const char *orig) |
8354 | 2160 { |
9328 | 2161 /* |
9912 | 2162 Basically the inverse of zephyr_strip_local_realm |
9896 | 2163 */ |
2164 char* buf; | |
2165 | |
8354 | 2166 if (!g_ascii_strcasecmp(orig, "")) { |
9896 | 2167 return g_strdup(""); |
7126 | 2168 } |
8644 | 2169 |
9896 | 2170 if (strchr(orig,'@')) { |
2171 buf = g_strdup_printf("%s",orig); | |
2086 | 2172 } else { |
9896 | 2173 buf = g_strdup_printf("%s@%s",orig,zephyr->realm); |
2174 } | |
2086 | 2175 return buf; |
2176 } | |
2177 | |
9030 | 2178 static void zephyr_zloc(GaimConnection *gc, const char *who) |
2086 | 2179 { |
2180 ZAsyncLocateData_t ald; | |
9896 | 2181 zephyr_account *zephyr = gc->proto_data; |
2182 gchar* normalized_who = local_zephyr_normalize(zephyr,who); | |
2183 | |
2184 if (use_zeph02(zephyr)) { | |
2185 if (ZRequestLocations(normalized_who, &ald, UNACKED, ZAUTH) == ZERR_NONE) { | |
2186 zephyr->pending_zloc_names = g_list_append(zephyr->pending_zloc_names, | |
2187 g_strdup(normalized_who)); | |
2188 } else { | |
2189 /* XXX deal with errors somehow */ | |
2190 } | |
2191 } else if (use_tzc(zephyr)) { | |
2192 char* zlocstr = g_strdup_printf("((tzcfodder . zlocate) \"%s\")\n",normalized_who); | |
2193 zephyr->pending_zloc_names = g_list_append(zephyr->pending_zloc_names, g_strdup(normalized_who)); | |
2194 write(zephyr->totzc[ZEPHYR_FD_WRITE],zlocstr,strlen(zlocstr)); | |
2195 g_free(zlocstr); | |
2086 | 2196 } |
2197 } | |
2198 | |
9986 | 2199 static void zephyr_set_status(GaimAccount *account, GaimStatus *status) { |
2200 zephyr_account *zephyr = gaim_account_get_connection(account)->proto_data; | |
2201 const char *status_id = gaim_status_get_id(status); | |
2202 | |
2203 if (zephyr->away) { | |
2204 g_free(zephyr->away); | |
2205 zephyr->away=NULL; | |
4111
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
3867
diff
changeset
|
2206 } |
ee884f1d7ae3
[gaim-migrate @ 4326]
Christian Hammond <chipx86@chipx86.com>
parents:
3867
diff
changeset
|
2207 |
9986 | 2208 if (!strcmp(status_id,"away")) { |
2209 zephyr->away = g_strdup(gaim_status_get_attr_string(status,"message")); | |
2210 } | |
11638 | 2211 else if (!strcmp(status_id,"available")) { |
9986 | 2212 if (use_zeph02(zephyr)) { |
10038
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
2213 ZSetLocation(zephyr->exposure); |
9986 | 2214 } |
2215 else { | |
2216 char *zexpstr = g_strdup_printf("((tzcfodder . set-location) (hostname . \"%s\") (exposure . \"%s\"))\n",zephyr->ourhost,zephyr->exposure); | |
2217 write(zephyr->totzc[ZEPHYR_FD_WRITE],zexpstr,strlen(zexpstr)); | |
2218 g_free(zexpstr); | |
2219 } | |
2220 } | |
2221 else if (!strcmp(status_id,"hidden")) { | |
9478 | 2222 /* XXX handle errors */ |
9896 | 2223 if (use_zeph02(zephyr)) { |
2224 ZSetLocation(EXPOSE_OPSTAFF); | |
2225 } else { | |
2226 char *zexpstr = g_strdup_printf("((tzcfodder . set-location) (hostname . \"%s\") (exposure . \"%s\"))\n",zephyr->ourhost,EXPOSE_OPSTAFF); | |
2227 write(zephyr->totzc[ZEPHYR_FD_WRITE],zexpstr,strlen(zexpstr)); | |
2228 g_free(zexpstr); | |
2229 } | |
9478 | 2230 } |
2086 | 2231 } |
2232 | |
9986 | 2233 static GList *zephyr_status_types(GaimAccount *account) |
2086 | 2234 { |
9986 | 2235 GaimStatusType *type; |
2236 GList *types = NULL; | |
2237 | |
2238 /* zephyr has several exposures | |
2239 NONE (where you are hidden, and zephyrs to you are in practice silently dropped -- yes this is wrong) | |
2240 OPSTAFF "hidden" | |
2241 REALM-VISIBLE visible to people in local realm | |
2242 REALM-ANNOUNCED REALM-VISIBLE+ plus your logins/logouts are announced to <login,username,*> | |
2243 NET-VISIBLE REALM-ANNOUNCED, plus visible to people in foreign realm | |
2244 NET-ANNOUNCED NET-VISIBLE, plus logins/logouts are announced to <login,username,*> | |
2245 | |
2246 Online will set the user to the exposure they have in their options (defaulting to REALM-VISIBLE), | |
2247 Hidden, will set the user's exposure to OPSTAFF | |
2086 | 2248 |
9986 | 2249 Away won't change their exposure but will set an auto away message (for IMs only) |
2250 */ | |
2251 | |
11638 | 2252 type = gaim_status_type_new(GAIM_STATUS_AVAILABLE, "available", _("Online"), FALSE); |
9986 | 2253 types = g_list_append(types,type); |
2086 | 2254 |
9986 | 2255 type = gaim_status_type_new(GAIM_STATUS_HIDDEN, "hidden", _("Hidden"), FALSE); |
2256 types = g_list_append(types,type); | |
2257 | |
2258 type = gaim_status_type_new_with_attrs( | |
2259 GAIM_STATUS_AWAY, "away", _("Away"), TRUE, TRUE, FALSE, | |
10009 | 2260 "message", _("Message"), gaim_value_new(GAIM_TYPE_STRING), NULL); |
9986 | 2261 types = g_list_append(types, type); |
2262 | |
2263 return types; | |
2086 | 2264 } |
2265 | |
8644 | 2266 static GList *zephyr_chat_info(GaimConnection * gc) |
2267 { | |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
2268 GList *m = NULL; |
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
2269 struct proto_chat_entry *pce; |
2086 | 2270 |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
2271 pce = g_new0(struct proto_chat_entry, 1); |
8644 | 2272 |
7841 | 2273 pce->label = _("_Class:"); |
5234 | 2274 pce->identifier = "class"; |
3158 | 2275 m = g_list_append(m, pce); |
2086 | 2276 |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
2277 pce = g_new0(struct proto_chat_entry, 1); |
8644 | 2278 |
7841 | 2279 pce->label = _("_Instance:"); |
5234 | 2280 pce->identifier = "instance"; |
3158 | 2281 m = g_list_append(m, pce); |
2086 | 2282 |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
2283 pce = g_new0(struct proto_chat_entry, 1); |
8644 | 2284 |
7841 | 2285 pce->label = _("_Recipient:"); |
5234 | 2286 pce->identifier = "recipient"; |
3158 | 2287 m = g_list_append(m, pce); |
2086 | 2288 |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
2289 return m; |
2086 | 2290 } |
2291 | |
9478 | 2292 /* Called when the server notifies us a message couldn't get sent */ |
2293 | |
9896 | 2294 static void zephyr_subscribe_failed(GaimConnection *gc,char * z_class, char *z_instance, char * z_recipient, char* z_galaxy) |
9478 | 2295 { |
9896 | 2296 gchar* subscribe_failed = g_strdup_printf(_("Attempt to subscribe to %s,%s,%s failed"), z_class, z_instance,z_recipient); |
9610 | 2297 gaim_notify_error(gc,"", subscribe_failed, NULL); |
9478 | 2298 g_free(subscribe_failed); |
2299 } | |
2300 | |
9921 | 2301 static char *zephyr_get_chat_name(GHashTable *data) { |
9922 | 2302 gchar* zclass = g_hash_table_lookup(data,"class"); |
2303 gchar* inst = g_hash_table_lookup(data,"instance"); | |
2304 gchar* recipient = g_hash_table_lookup(data, "recipient"); | |
2305 if (!zclass) /* This should never happen */ | |
2306 zclass = ""; | |
2307 if (!inst) | |
2308 inst = "*"; | |
2309 if (!recipient) | |
2310 recipient = ""; | |
2311 return g_strdup_printf("%s,%s,%s",zclass,inst,recipient); | |
9917 | 2312 } |
2313 | |
9922 | 2314 |
8644 | 2315 static void zephyr_join_chat(GaimConnection * gc, GHashTable * data) |
2086 | 2316 { |
9896 | 2317 /* ZSubscription_t sub; */ |
2086 | 2318 zephyr_triple *zt1, *zt2; |
2319 const char *classname; | |
2320 const char *instname; | |
2321 const char *recip; | |
9896 | 2322 zephyr_account *zephyr=gc->proto_data; |
5234 | 2323 classname = g_hash_table_lookup(data, "class"); |
2324 instname = g_hash_table_lookup(data, "instance"); | |
2325 recip = g_hash_table_lookup(data, "recipient"); | |
2326 | |
9478 | 2327 |
9328 | 2328 if (!classname) |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
2329 return; |
9478 | 2330 |
2331 if (!g_ascii_strcasecmp(classname,"%host%")) | |
9896 | 2332 classname = g_strdup(zephyr->ourhost); |
9478 | 2333 if (!g_ascii_strcasecmp(classname,"%canon%")) |
9896 | 2334 classname = g_strdup(zephyr->ourhostcanon); |
9478 | 2335 |
9328 | 2336 if (!instname || !strlen(instname)) |
2337 instname = "*"; | |
9478 | 2338 |
2339 if (!g_ascii_strcasecmp(instname,"%host%")) | |
9896 | 2340 instname = g_strdup(zephyr->ourhost); |
9478 | 2341 if (!g_ascii_strcasecmp(instname,"%canon%")) |
9896 | 2342 instname = g_strdup(zephyr->ourhostcanon); |
9478 | 2343 |
9328 | 2344 if (!recip || (*recip == '*')) |
2345 recip = ""; | |
4793 | 2346 if (!g_ascii_strcasecmp(recip, "%me%")) |
9896 | 2347 recip = zephyr->username; |
2086 | 2348 |
9610 | 2349 zt1 = new_triple(gc->proto_data,classname, instname, recip); |
2350 zt2 = find_sub_by_triple(gc->proto_data,zt1); | |
2086 | 2351 if (zt2) { |
2352 free_triple(zt1); | |
9328 | 2353 if (!zt2->open) { |
2354 if (!g_ascii_strcasecmp(instname,"*")) | |
2355 instname = "PERSONAL"; | |
9434 | 2356 serv_got_joined_chat(gc, zt2->id, zt2->name); |
9896 | 2357 zephyr_chat_set_topic(gc,zt2->id,instname); |
9328 | 2358 zt2->open = TRUE; |
2359 } | |
2086 | 2360 return; |
2361 } | |
9896 | 2362 |
2363 /* sub.zsub_class = zt1->class; | |
2364 sub.zsub_classinst = zt1->instance; | |
2365 sub.zsub_recipient = zt1->recipient; */ | |
2366 | |
2367 if (zephyr_subscribe_to(zephyr,zt1->class,zt1->instance,zt1->recipient,NULL) != ZERR_NONE) { | |
9478 | 2368 /* XXX output better subscription information */ |
9896 | 2369 zephyr_subscribe_failed(gc,zt1->class,zt1->instance,zt1->recipient,NULL); |
2086 | 2370 free_triple(zt1); |
2371 return; | |
2372 } | |
2373 | |
9610 | 2374 zephyr->subscrips = g_slist_append(zephyr->subscrips, zt1); |
2086 | 2375 zt1->open = TRUE; |
2376 serv_got_joined_chat(gc, zt1->id, zt1->name); | |
9328 | 2377 if (!g_ascii_strcasecmp(instname,"*")) |
2378 instname = "PERSONAL"; | |
9896 | 2379 zephyr_chat_set_topic(gc,zt1->id,instname); |
2086 | 2380 } |
2381 | |
8644 | 2382 static void zephyr_chat_leave(GaimConnection * gc, int id) |
2086 | 2383 { |
2384 zephyr_triple *zt; | |
9896 | 2385 zephyr_account *zephyr = gc->proto_data; |
9610 | 2386 zt = find_sub_by_id(zephyr,id); |
9896 | 2387 |
2086 | 2388 if (zt) { |
2389 zt->open = FALSE; | |
9610 | 2390 zt->id = ++(zephyr->last_id); |
2086 | 2391 } |
2392 } | |
2393 | |
9478 | 2394 static GaimChat *zephyr_find_blist_chat(GaimAccount *account, const char *name) |
2395 { | |
2396 GaimBlistNode *gnode, *cnode; | |
2397 | |
2398 /* XXX needs to be %host%,%canon%, and %me% clean */ | |
2399 for(gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) { | |
2400 for(cnode = gnode->child; cnode; cnode = cnode->next) { | |
2401 GaimChat *chat = (GaimChat*)cnode; | |
2402 char *zclass, *inst, *recip; | |
2403 char** triple; | |
2404 if(!GAIM_BLIST_NODE_IS_CHAT(cnode)) | |
2405 continue; | |
2406 if(chat->account !=account) | |
2407 continue; | |
2408 if(!(zclass = g_hash_table_lookup(chat->components, "class"))) | |
2409 continue; | |
2410 if(!(inst = g_hash_table_lookup(chat->components, "instance"))) | |
2411 inst = g_strdup(""); | |
2412 if(!(recip = g_hash_table_lookup(chat->components, "recipient"))) | |
2413 recip = g_strdup(""); | |
9896 | 2414 /* gaim_debug_info("zephyr","in zephyr_find_blist_chat name: %s\n",name?name:""); */ |
9478 | 2415 triple = g_strsplit(name,",",3); |
2416 if (!g_ascii_strcasecmp(triple[0],zclass) && !g_ascii_strcasecmp(triple[1],inst) && !g_ascii_strcasecmp(triple[2],recip)) | |
2417 return chat; | |
2418 | |
2419 } | |
2420 } | |
2421 return NULL; | |
2422 } | |
8644 | 2423 static const char *zephyr_list_icon(GaimAccount * a, GaimBuddy * b) |
5202 | 2424 { |
2425 return "zephyr"; | |
2426 } | |
2427 | |
9478 | 2428 static int zephyr_send_typing(GaimConnection *gc, const char *who, int typing) { |
2429 gchar *recipient; | |
9896 | 2430 zephyr_account *zephyr = gc->proto_data; |
2431 if (use_tzc(zephyr)) | |
2432 return 0; | |
2433 | |
9478 | 2434 if (!typing) |
2435 return 0; | |
2436 /* XXX We probably should care if this fails. Or maybe we don't want to */ | |
2437 if (!who) { | |
2438 gaim_debug_info("zephyr", "who is null\n"); | |
9896 | 2439 recipient = local_zephyr_normalize(zephyr,""); |
9478 | 2440 } else { |
10111 | 2441 char *comma = strrchr(who, ','); |
9896 | 2442 /* Don't ping broadcast (chat) recipients */ |
2443 /* The strrchr case finds a realm-stripped broadcast subscription | |
2444 e.g. comma is the last character in the string */ | |
10111 | 2445 if (comma && ( (*(comma+1) == '\0') || (*(comma+1) == '@'))) |
9896 | 2446 return 0; |
10111 | 2447 |
9896 | 2448 recipient = local_zephyr_normalize(zephyr,who); |
9478 | 2449 } |
2450 | |
9896 | 2451 gaim_debug_info("zephyr","about to send typing notification to %s\n",recipient); |
2452 zephyr_send_message(zephyr,"MESSAGE","PERSONAL",recipient,"","","PING"); | |
2453 gaim_debug_info("zephyr","sent typing notification\n"); | |
9478 | 2454 return ZEPHYR_TYPING_SEND_TIMEOUT; |
2455 } | |
8212 | 2456 |
9434 | 2457 |
2458 | |
8644 | 2459 static void zephyr_chat_set_topic(GaimConnection * gc, int id, const char *topic) |
2460 { | |
2461 zephyr_triple *zt; | |
2462 GaimConversation *gconv; | |
2463 GaimConvChat *gcc; | |
9896 | 2464 gchar *topic_utf8; |
2465 zephyr_account* zephyr = gc->proto_data; | |
2466 char *sender = (char *)zephyr->username; | |
8212 | 2467 |
9610 | 2468 zt = find_sub_by_id(gc->proto_data,id); |
9986 | 2469 /* find_sub_by_id can return NULL */ |
2470 if (!zt) | |
2471 return; | |
11338 | 2472 gconv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_CHAT, zt->name, |
10246 | 2473 gc->account); |
8644 | 2474 gcc = gaim_conversation_get_chat_data(gconv); |
9434 | 2475 |
9896 | 2476 topic_utf8 = zephyr_recv_convert(gc,(gchar *)topic,strlen(topic)); |
2477 gaim_conv_chat_set_topic(gcc,sender,topic_utf8); | |
2478 g_free(topic_utf8); | |
2479 return; | |
9434 | 2480 } |
2481 | |
2482 /* commands */ | |
2483 | |
2484 static GaimCmdRet zephyr_gaim_cmd_msg(GaimConversation *conv, | |
9896 | 2485 const char *cmd, char **args, char **error, void *data) |
9434 | 2486 { |
9896 | 2487 char *recipient; |
2488 zephyr_account *zephyr = gaim_conversation_get_gc(conv)->proto_data; | |
2489 if (!g_ascii_strcasecmp(args[0],"*")) | |
2490 return GAIM_CMD_RET_FAILED; /* "*" is not a valid argument */ | |
2491 else | |
2492 recipient = local_zephyr_normalize(zephyr,args[0]); | |
9434 | 2493 |
9896 | 2494 if (strlen(recipient) < 1) |
2495 return GAIM_CMD_RET_FAILED; /* a null recipient is a chat message, not an IM */ | |
9478 | 2496 |
9896 | 2497 if (zephyr_send_message(zephyr,"MESSAGE","PERSONAL",recipient,args[1],zephyr_get_signature(),"")) |
2498 return GAIM_CMD_RET_OK; | |
2499 else | |
2500 return GAIM_CMD_RET_FAILED; | |
9434 | 2501 } |
2502 | |
2503 static GaimCmdRet zephyr_gaim_cmd_zlocate(GaimConversation *conv, | |
9896 | 2504 const char *cmd, char **args, char **error, void *data) |
9434 | 2505 { |
9896 | 2506 zephyr_zloc(gaim_conversation_get_gc(conv),args[0]); |
2507 return GAIM_CMD_RET_OK; | |
9434 | 2508 } |
2509 | |
2510 static GaimCmdRet zephyr_gaim_cmd_instance(GaimConversation *conv, | |
9896 | 2511 const char *cmd, char **args, char **error, void *data) |
9434 | 2512 { |
9896 | 2513 /* Currently it sets the instance with leading spaces and |
2514 * all. This might not be the best thing to do, though having | |
2515 * one word isn't ideal either. */ | |
9434 | 2516 |
9896 | 2517 GaimConvChat *gcc = gaim_conversation_get_chat_data(conv); |
2518 int id = gcc->id; | |
2519 const char* instance = args[0]; | |
2520 zephyr_chat_set_topic(gaim_conversation_get_gc(conv),id,instance); | |
2521 return GAIM_CMD_RET_OK; | |
9434 | 2522 } |
2523 | |
2524 static GaimCmdRet zephyr_gaim_cmd_joinchat_cir(GaimConversation *conv, | |
9896 | 2525 const char *cmd, char **args, char **error, void *data) |
9434 | 2526 { |
9896 | 2527 /* Join a new zephyr chat */ |
2528 GHashTable *triple = g_hash_table_new(NULL,NULL); | |
2529 g_hash_table_insert(triple,"class",args[0]); | |
2530 g_hash_table_insert(triple,"instance",args[1]); | |
2531 g_hash_table_insert(triple,"recipient",args[2]); | |
2532 zephyr_join_chat(gaim_conversation_get_gc(conv),triple); | |
2533 return GAIM_CMD_RET_OK; | |
9434 | 2534 } |
2535 | |
2536 static GaimCmdRet zephyr_gaim_cmd_zi(GaimConversation *conv, | |
9896 | 2537 const char *cmd, char **args, char **error, void *data) |
9434 | 2538 { |
9896 | 2539 /* args = instance, message */ |
2540 zephyr_account *zephyr = gaim_conversation_get_gc(conv)->proto_data; | |
2541 if ( zephyr_send_message(zephyr,"message",args[0],"",args[1],zephyr_get_signature(),"")) | |
2542 return GAIM_CMD_RET_OK; | |
2543 else | |
2544 return GAIM_CMD_RET_FAILED; | |
9434 | 2545 } |
2546 | |
2547 static GaimCmdRet zephyr_gaim_cmd_zci(GaimConversation *conv, | |
9896 | 2548 const char *cmd, char **args, char **error, void *data) |
9434 | 2549 { |
9896 | 2550 /* args = class, instance, message */ |
2551 zephyr_account *zephyr = gaim_conversation_get_gc(conv)->proto_data; | |
2552 if ( zephyr_send_message(zephyr,args[0],args[1],"",args[2],zephyr_get_signature(),"")) | |
2553 return GAIM_CMD_RET_OK; | |
2554 else | |
2555 return GAIM_CMD_RET_FAILED; | |
9434 | 2556 } |
8644 | 2557 |
9434 | 2558 static GaimCmdRet zephyr_gaim_cmd_zcir(GaimConversation *conv, |
9896 | 2559 const char *cmd, char **args, char **error, void *data) |
9434 | 2560 { |
9896 | 2561 /* args = class, instance, recipient, message */ |
2562 zephyr_account *zephyr = gaim_conversation_get_gc(conv)->proto_data; | |
2563 if ( zephyr_send_message(zephyr,args[0],args[1],args[2],args[3],zephyr_get_signature(),"")) | |
2564 return GAIM_CMD_RET_OK; | |
2565 else | |
2566 return GAIM_CMD_RET_FAILED; | |
8212 | 2567 } |
2568 | |
9434 | 2569 static GaimCmdRet zephyr_gaim_cmd_zir(GaimConversation *conv, |
9896 | 2570 const char *cmd, char **args, char **error, void *data) |
9434 | 2571 { |
9896 | 2572 /* args = instance, recipient, message */ |
2573 zephyr_account *zephyr = gaim_conversation_get_gc(conv)->proto_data; | |
2574 if ( zephyr_send_message(zephyr,"message",args[0],args[1],args[2],zephyr_get_signature(),"")) | |
2575 return GAIM_CMD_RET_OK; | |
2576 else | |
2577 return GAIM_CMD_RET_FAILED; | |
9434 | 2578 } |
2579 | |
2580 static GaimCmdRet zephyr_gaim_cmd_zc(GaimConversation *conv, | |
9896 | 2581 const char *cmd, char **args, char **error, void *data) |
9434 | 2582 { |
9896 | 2583 /* args = class, message */ |
2584 zephyr_account *zephyr = gaim_conversation_get_gc(conv)->proto_data; | |
2585 if ( zephyr_send_message(zephyr,args[0],"PERSONAL","",args[1],zephyr_get_signature(),"")) | |
2586 return GAIM_CMD_RET_OK; | |
2587 else | |
2588 return GAIM_CMD_RET_FAILED; | |
9434 | 2589 } |
2590 | |
9597 | 2591 static void zephyr_register_slash_commands() |
9434 | 2592 { |
2593 | |
9896 | 2594 gaim_cmd_register("msg","ws", GAIM_CMD_P_PRPL, |
2595 GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
2596 "prpl-zephyr", | |
2597 zephyr_gaim_cmd_msg, _("msg <nick> <message>: Send a private message to a user"), NULL); | |
9434 | 2598 |
9896 | 2599 gaim_cmd_register("zlocate","w", GAIM_CMD_P_PRPL, |
2600 GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
2601 "prpl-zephyr", | |
2602 zephyr_gaim_cmd_zlocate, _("zlocate <nick>: Locate user"), NULL); | |
9434 | 2603 |
9896 | 2604 gaim_cmd_register("zl","w", GAIM_CMD_P_PRPL, |
2605 GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
2606 "prpl-zephyr", | |
2607 zephyr_gaim_cmd_zlocate, _("zl <nick>: Locate user"), NULL); | |
9434 | 2608 |
9896 | 2609 gaim_cmd_register("instance","s", GAIM_CMD_P_PRPL, |
2610 GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
2611 "prpl-zephyr", | |
2612 zephyr_gaim_cmd_instance, _("instance <instance>: Set the instance to be used on this class"), NULL); | |
9434 | 2613 |
9896 | 2614 gaim_cmd_register("inst","s", GAIM_CMD_P_PRPL, |
2615 GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
2616 "prpl-zephyr", | |
2617 zephyr_gaim_cmd_instance, _("inst <instance>: Set the instance to be used on this class"), NULL); | |
9434 | 2618 |
10038
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
2619 gaim_cmd_register("topic","s", GAIM_CMD_P_PRPL, |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
2620 GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
2621 "prpl-zephyr", |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
2622 zephyr_gaim_cmd_instance, _("topic <instance>: Set the instance to be used on this class"), NULL); |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
2623 |
9896 | 2624 gaim_cmd_register("sub", "www", GAIM_CMD_P_PRPL, |
2625 GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
2626 "prpl-zephyr", | |
2627 zephyr_gaim_cmd_joinchat_cir, | |
2628 _("sub <class> <instance> <recipient>: Join a new chat"), NULL); | |
9434 | 2629 |
9896 | 2630 gaim_cmd_register("zi","ws", GAIM_CMD_P_PRPL, |
2631 GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
2632 "prpl-zephyr", | |
2633 zephyr_gaim_cmd_zi, _("zi <instance>: Send a message to <message,<i>instance</i>,*>"), NULL); | |
9434 | 2634 |
9896 | 2635 gaim_cmd_register("zci","wws",GAIM_CMD_P_PRPL, |
2636 GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
2637 "prpl-zephyr", | |
2638 zephyr_gaim_cmd_zci, | |
2639 _("zci <class> <instance>: Send a message to <<i>class</i>,<i>instance</i>,*>"), NULL); | |
9434 | 2640 |
9896 | 2641 gaim_cmd_register("zcir","wwws",GAIM_CMD_P_PRPL, |
2642 GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
2643 "prpl-zephyr", | |
2644 zephyr_gaim_cmd_zcir, | |
2645 _("zcir <class> <instance> <recipient>: Send a message to <<i>class</i>,<i>instance</i>,<i>recipient</i>>"), NULL); | |
9434 | 2646 |
9896 | 2647 gaim_cmd_register("zir","wws",GAIM_CMD_P_PRPL, |
2648 GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
2649 "prpl-zephyr", | |
2650 zephyr_gaim_cmd_zir, | |
2651 _("zir <instance> <recipient>: Send a message to <MESSAGE,<i>instance</i>,<i>recipient</i>>"), NULL); | |
9434 | 2652 |
9896 | 2653 gaim_cmd_register("zc","ws", GAIM_CMD_P_PRPL, |
2654 GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_PRPL_ONLY, | |
2655 "prpl-zephyr", | |
2656 zephyr_gaim_cmd_zc, _("zc <class>: Send a message to <<i>class</i>,PERSONAL,*>"), NULL); | |
9597 | 2657 |
9434 | 2658 } |
2659 | |
2660 | |
9896 | 2661 static void |
2662 zephyr_add_deny(GaimConnection *gc, const char *who) | |
2663 { | |
2664 gaim_privacy_deny_add(gc->account,who,1); | |
2665 } | |
2666 | |
2667 static void | |
2668 zephyr_remove_deny(GaimConnection *gc, const char *who) | |
2669 { | |
2670 gaim_privacy_deny_remove(gc->account,who,1); | |
2671 } | |
2672 | |
2673 static void | |
2674 zephyr_add_permit(GaimConnection *gc, const char *who) | |
2675 { | |
2676 gaim_privacy_permit_add(gc->account,who,1); | |
2677 } | |
2678 | |
2679 static void | |
2680 zephyr_remove_permit(GaimConnection *gc, const char *who) | |
2681 { | |
2682 gaim_privacy_permit_remove(gc->account,who,1); | |
2683 } | |
2684 | |
2685 static void | |
2686 zephyr_set_permit_deny(GaimConnection *gc) | |
2687 { | |
2688 /* This doesn't have to do anything, since really, we can just check account->perm_deny when deciding whether to di */ | |
2689 return; | |
2690 } | |
9427 | 2691 static int zephyr_resubscribe(GaimConnection *gc) |
2692 { | |
9896 | 2693 /* Resubscribe to the in-memory list of subscriptions and also |
2694 unsubscriptions*/ | |
2695 zephyr_account *zephyr = gc->proto_data; | |
2696 GSList *s = zephyr->subscrips; | |
2697 zephyr_triple *zt; | |
2698 while (s) { | |
2699 zt = s->data; | |
2700 /* XXX We really should care if this fails */ | |
2701 zephyr_subscribe_to(zephyr,zt->class,zt->instance,zt->recipient,NULL); | |
2702 s = s->next; | |
2703 } | |
2704 /* XXX handle unsubscriptions */ | |
2705 return 1; | |
9427 | 2706 } |
2707 | |
9434 | 2708 |
9427 | 2709 static void zephyr_action_resubscribe(GaimPluginAction *action) |
2710 { | |
2711 | |
9896 | 2712 GaimConnection *gc = (GaimConnection *) action->context; |
2713 zephyr_resubscribe(gc); | |
9427 | 2714 } |
2715 | |
2716 | |
9478 | 2717 static void zephyr_action_get_subs_from_server(GaimPluginAction *action) |
2718 { | |
2719 GaimConnection *gc = (GaimConnection *) action->context; | |
9896 | 2720 zephyr_account *zephyr = gc->proto_data; |
9478 | 2721 gchar *title; |
2722 int retval, nsubs, one,i; | |
2723 ZSubscription_t subs; | |
9896 | 2724 if (use_zeph02(zephyr)) { |
2725 GString* subout = g_string_new("Subscription list<br>"); | |
2726 | |
2727 title = g_strdup_printf("Server subscriptions for %s", zephyr->username); | |
2728 | |
2729 if (zephyr->port == 0) { | |
10867 | 2730 gaim_debug_error("zephyr", "error while retrieving port"); |
9896 | 2731 return; |
2732 } | |
2733 if ((retval = ZRetrieveSubscriptions(zephyr->port,&nsubs)) != ZERR_NONE) { | |
9478 | 2734 /* XXX better error handling */ |
10867 | 2735 gaim_debug_error("zephyr", "error while retrieving subscriptions from server"); |
9478 | 2736 return; |
2737 } | |
9896 | 2738 for(i=0;i<nsubs;i++) { |
2739 one = 1; | |
2740 if ((retval = ZGetSubscriptions(&subs,&one)) != ZERR_NONE) { | |
2741 /* XXX better error handling */ | |
10867 | 2742 gaim_debug_error("zephyr", "error while retrieving individual subscription"); |
9896 | 2743 return; |
2744 } | |
2745 g_string_append_printf(subout, "Class %s Instance %s Recipient %s<br>", | |
2746 subs.zsub_class, subs.zsub_classinst, | |
2747 subs.zsub_recipient); | |
2748 } | |
2749 gaim_notify_formatted(gc, title, title, NULL, subout->str, NULL, NULL); | |
2750 } else { | |
2751 /* XXX fix */ | |
2752 gaim_notify_error(gc,"","tzc doesn't support this action",NULL); | |
9478 | 2753 } |
2754 } | |
2755 | |
2756 | |
9427 | 2757 static GList *zephyr_actions(GaimPlugin *plugin, gpointer context) |
2758 { | |
2759 GList *list = NULL; | |
2760 GaimPluginAction *act = NULL; | |
2761 | |
2762 act = gaim_plugin_action_new(_("Resubscribe"), zephyr_action_resubscribe); | |
2763 list = g_list_append(list, act); | |
2764 | |
9478 | 2765 act = gaim_plugin_action_new(_("Retrieve subscriptions from server"), zephyr_action_get_subs_from_server); |
2766 list = g_list_append(list,act); | |
2767 | |
9427 | 2768 return list; |
2769 } | |
2770 | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
2771 static GaimPlugin *my_protocol = NULL; |
2086 | 2772 |
8644 | 2773 static GaimPluginProtocolInfo prpl_info = { |
2774 OPT_PROTO_CHAT_TOPIC | OPT_PROTO_NO_PASSWORD, | |
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2775 NULL, /* ??? user_splits */ |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2776 NULL, /* ??? protocol_options */ |
9478 | 2777 NO_BUDDY_ICONS, |
2778 zephyr_list_icon, | |
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2779 NULL, /* ??? list_emblems */ |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2780 NULL, /* ??? status_text */ |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2781 NULL, /* ??? tooltip_text */ |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2782 zephyr_status_types, /* status_types */ |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2783 NULL, /* ??? blist_node_menu - probably all useful actions are already handled*/ |
9475 | 2784 zephyr_chat_info, /* chat_info */ |
9754 | 2785 NULL, /* chat_info_defaults */ |
9475 | 2786 zephyr_login, /* login */ |
2787 zephyr_close, /* close */ | |
2788 zephyr_send_im, /* send_im */ | |
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2789 NULL, /* XXX set info (Location?) */ |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2790 zephyr_send_typing, /* send_typing */ |
9475 | 2791 zephyr_zloc, /* get_info */ |
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2792 zephyr_set_status, /* set_status */ |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2793 NULL, /* ??? set idle */ |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2794 NULL, /* change password */ |
9475 | 2795 NULL, /* add_buddy */ |
2796 NULL, /* add_buddies */ | |
2797 NULL, /* remove_buddy */ | |
2798 NULL, /* remove_buddies */ | |
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2799 zephyr_add_permit, /* add_permit */ |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2800 zephyr_add_deny, /* add_deny */ |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2801 zephyr_remove_permit, /* remove_permit */ |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2802 zephyr_remove_deny, /* remove_deny */ |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2803 zephyr_set_permit_deny, /* set_permit_deny */ |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2804 zephyr_join_chat, /* join_chat */ |
9896 | 2805 NULL, /* reject_chat -- No chat invites*/ |
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2806 zephyr_get_chat_name, /* get_chat_name */ |
9896 | 2807 NULL, /* chat_invite -- No chat invites*/ |
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2808 zephyr_chat_leave, /* chat_leave */ |
9896 | 2809 NULL, /* chat_whisper -- No "whispering"*/ |
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2810 zephyr_chat_send, /* chat_send */ |
9896 | 2811 NULL, /* keepalive -- Not necessary*/ |
2812 NULL, /* register_user -- Not supported*/ | |
2813 NULL, /* XXX get_cb_info */ | |
9475 | 2814 NULL, /* get_cb_away */ |
2815 NULL, /* alias_buddy */ | |
2816 NULL, /* group_buddy */ | |
2817 NULL, /* rename_group */ | |
9896 | 2818 NULL, /* buddy_free */ |
9475 | 2819 NULL, /* convo_closed */ |
11151 | 2820 NULL, /* normalize */ |
9896 | 2821 NULL, /* XXX set_buddy_icon */ |
9475 | 2822 NULL, /* remove_group */ |
9896 | 2823 NULL, /* XXX get_cb_real_name */ |
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2824 zephyr_chat_set_topic, /* set_chat_topic */ |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2825 zephyr_find_blist_chat, /* find_blist_chat */ |
9475 | 2826 NULL, /* roomlist_get_list */ |
2827 NULL, /* roomlist_cancel */ | |
9896 | 2828 NULL, /* roomlist_expand_category */ |
9475 | 2829 NULL, /* can_receive_file */ |
12143
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2830 NULL, /* send_file */ |
cbebda5f019c
[gaim-migrate @ 14444]
Richard Laager <rlaager@wiktel.com>
parents:
11837
diff
changeset
|
2831 NULL /* new_xfer */ |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
2832 }; |
2086 | 2833 |
8644 | 2834 static GaimPluginInfo info = { |
9943 | 2835 GAIM_PLUGIN_MAGIC, |
2836 GAIM_MAJOR_VERSION, | |
2837 GAIM_MINOR_VERSION, | |
9896 | 2838 GAIM_PLUGIN_PROTOCOL, /**< type */ |
8644 | 2839 NULL, /**< ui_requirement */ |
9896 | 2840 0, /**< flags */ |
8644 | 2841 NULL, /**< dependencies */ |
9896 | 2842 GAIM_PRIORITY_DEFAULT, /**< priority */ |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
2843 |
9896 | 2844 "prpl-zephyr", /**< id */ |
2845 "Zephyr", /**< name */ | |
2846 VERSION, /**< version */ | |
2847 /** summary */ | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
2848 N_("Zephyr Protocol Plugin"), |
9896 | 2849 /** description */ |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
2850 N_("Zephyr Protocol Plugin"), |
9896 | 2851 NULL, /**< author */ |
2852 GAIM_WEBSITE, /**< homepage */ | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
2853 |
9896 | 2854 NULL, /**< load */ |
2855 NULL, /**< unload */ | |
2856 NULL, /**< destroy */ | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
2857 |
9896 | 2858 NULL, /**< ui_info */ |
8993 | 2859 &prpl_info, /**< extra_info */ |
2860 NULL, | |
9427 | 2861 zephyr_actions |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
2862 }; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
2863 |
8644 | 2864 static void init_plugin(GaimPlugin * plugin) |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
2865 { |
8212 | 2866 GaimAccountOption *option; |
8644 | 2867 char *tmp = get_exposure_level(); |
11033
50224ac8184d
[gaim-migrate @ 12919]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10867
diff
changeset
|
2868 |
9896 | 2869 option = gaim_account_option_bool_new("Use tzc", "use_tzc", FALSE); |
2870 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
2871 | |
2872 option = gaim_account_option_string_new("tzc command", "tzc_command", "/usr/bin/tzc -e %s"); | |
2873 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
2874 | |
8644 | 2875 option = gaim_account_option_bool_new(_("Export to .anyone"), "write_anyone", FALSE); |
2876 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
8212 | 2877 |
8644 | 2878 option = gaim_account_option_bool_new(_("Export to .zephyr.subs"), "write_zsubs", FALSE); |
2879 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
8212 | 2880 |
10038
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
2881 option = gaim_account_option_bool_new(_("Import from .anyone"), "read_anyone", TRUE); |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
2882 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
2883 |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
2884 option = gaim_account_option_bool_new(_("Import from .zephyr.subs"), "read_zsubs", TRUE); |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
2885 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
2886 |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
2887 option = gaim_account_option_string_new(_("Realm"), "realm", ""); |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
2888 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
2889 |
eb8ccdd6f5f2
[gaim-migrate @ 10997]
Luke Schierer <lschiere@pidgin.im>
parents:
10009
diff
changeset
|
2890 option = gaim_account_option_string_new(_("Exposure"), "exposure_level", tmp?tmp: EXPOSE_REALMVIS); |
8644 | 2891 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); |
8212 | 2892 |
8644 | 2893 option = gaim_account_option_string_new(_("Encoding"), "encoding", ZEPHYR_FALLBACK_CHARSET); |
2894 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); | |
8560 | 2895 |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5202
diff
changeset
|
2896 my_protocol = plugin; |
9896 | 2897 zephyr_register_slash_commands(); |
2086 | 2898 } |
2899 | |
5920
7d385de2f9cd
[gaim-migrate @ 6360]
Christian Hammond <chipx86@chipx86.com>
parents:
5872
diff
changeset
|
2900 GAIM_INIT_PLUGIN(zephyr, init_plugin, info); |