Mercurial > pidgin
annotate src/protocols/zephyr/zephyr.c @ 3572:bdd0bebd2d04
[gaim-migrate @ 3670]
Phase II. No longer do you have to worry about protocol plugins. When
Gaim probes plugins on load, it will detect protocol plugins and add them
to the list of available protocols. When you try to log an account on with
one of them, Gaim will automatically load the plugin--when no more accounts
need the protocol--Gaim will automatically unload it. Protocol plugins are
no longer available in the plugins ui, and no protocols are compiled statically
by default.
committer: Tailor Script <tailor@pidgin.im>
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Mon, 30 Sep 2002 01:05:18 +0000 |
parents | 7a3f16a375a5 |
children | 9682c0e022c6 |
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 | |
7 * Jag/Sean Dilda <agrajag@linuxpower.org>/<smdilda@unity.ncsu.edu> | |
8 * http://gtkzephyr.linuxpower.org/ | |
9 * | |
10 * This program is free software; you can redistribute it and/or modify | |
11 * it under the terms of the GNU General Public License as published by | |
12 * the Free Software Foundation; either version 2 of the License, or | |
13 * (at your option) any later version. | |
14 * | |
15 * This program is distributed in the hope that it will be useful, | |
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 * GNU General Public License for more details. | |
19 * | |
20 * You should have received a copy of the GNU General Public License | |
21 * along with this program; if not, write to the Free Software | |
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
23 * | |
24 */ | |
25 | |
26 #ifdef HAVE_CONFIG_H | |
27 #include "config.h" | |
28 #endif | |
29 | |
30 #include <string.h> | |
31 #include <stdlib.h> | |
2167
edf8c5a70e5b
[gaim-migrate @ 2177]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2162
diff
changeset
|
32 #include <errno.h> |
2086 | 33 #include "gaim.h" |
34 #include "prpl.h" | |
35 #include "zephyr/zephyr.h" | |
36 | |
37 extern Code_t ZGetLocations(ZLocations_t *, int *); | |
38 extern Code_t ZSetLocation(char *); | |
39 extern Code_t ZUnsetLocation(); | |
40 | |
41 typedef struct _zframe zframe; | |
42 typedef struct _zephyr_triple zephyr_triple; | |
43 | |
44 /* struct I need for zephyr_to_html */ | |
45 struct _zframe { | |
46 /* true for everything but @color, since inside the parens of that one is | |
47 * the color. */ | |
48 gboolean has_closer; | |
49 /* </i>, </font>, </b>, etc. */ | |
50 char *closing; | |
51 /* text including the opening html thingie. */ | |
52 GString *text; | |
53 struct _zframe *enclosing; | |
54 }; | |
55 | |
56 struct _zephyr_triple { | |
57 char *class; | |
58 char *instance; | |
59 char *recipient; | |
60 char *name; | |
61 gboolean open; | |
62 int id; | |
63 }; | |
64 | |
65 #define z_call(func) if (func != ZERR_NONE)\ | |
66 return; | |
67 #define z_call_r(func) if (func != ZERR_NONE)\ | |
68 return TRUE; | |
69 #define z_call_s(func, err) if (func != ZERR_NONE) {\ | |
70 hide_login_progress(zgc, err);\ | |
71 signoff(zgc);\ | |
72 return;\ | |
73 } | |
74 | |
75 static char *zephyr_normalize(const char *); | |
76 | |
77 /* this is so bad, and if Zephyr weren't so fucked up to begin with I | |
78 * wouldn't do this. but it is so i will. */ | |
79 static guint32 nottimer = 0; | |
80 static guint32 loctimer = 0; | |
81 struct gaim_connection *zgc = NULL; | |
82 static GList *pending_zloc_names = NULL; | |
83 static GSList *subscrips = NULL; | |
84 static int last_id = 0; | |
85 | |
86 /* just for debugging | |
87 static void handle_unknown(ZNotice_t notice) | |
88 { | |
89 g_print("z_packet: %s\n", notice.z_packet); | |
90 g_print("z_version: %s\n", notice.z_version); | |
91 g_print("z_kind: %d\n", notice.z_kind); | |
92 g_print("z_class: %s\n", notice.z_class); | |
93 g_print("z_class_inst: %s\n", notice.z_class_inst); | |
94 g_print("z_opcode: %s\n", notice.z_opcode); | |
95 g_print("z_sender: %s\n", notice.z_sender); | |
96 g_print("z_recipient: %s\n", notice.z_recipient); | |
97 g_print("z_message: %s\n", notice.z_message); | |
98 g_print("z_message_len: %d\n", notice.z_message_len); | |
99 g_print("\n"); | |
100 } | |
101 */ | |
102 | |
103 static zephyr_triple *new_triple(const char *c, const char *i, const char *r) | |
104 { | |
105 zephyr_triple *zt; | |
106 zt = g_new0(zephyr_triple, 1); | |
107 zt->class = g_strdup(c); | |
108 zt->instance = g_strdup(i); | |
109 zt->recipient = g_strdup(r); | |
110 zt->name = g_strdup_printf("%s,%s,%s", c, i, r); | |
111 zt->id = ++last_id; | |
112 zt->open = FALSE; | |
113 return zt; | |
114 } | |
115 | |
116 static void free_triple(zephyr_triple *zt) | |
117 { | |
118 g_free(zt->class); | |
119 g_free(zt->instance); | |
120 g_free(zt->recipient); | |
121 g_free(zt->name); | |
122 g_free(zt); | |
123 } | |
124 | |
125 /* returns true if zt1 is a subset of zt2, i.e. zt2 has the same thing or | |
126 * wildcards in each field of zt1. */ | |
127 static gboolean triple_subset(zephyr_triple *zt1, zephyr_triple *zt2) | |
128 { | |
129 if (g_strcasecmp(zt2->class, zt1->class) && | |
130 g_strcasecmp(zt2->class, "*")) { | |
131 return FALSE; | |
132 } | |
133 if (g_strcasecmp(zt2->instance, zt1->instance) && | |
134 g_strcasecmp(zt2->instance, "*")) { | |
135 return FALSE; | |
136 } | |
137 if (g_strcasecmp(zt2->recipient, zt1->recipient) && | |
138 g_strcasecmp(zt2->recipient, "*")) { | |
139 return FALSE; | |
140 } | |
141 return TRUE; | |
142 } | |
143 | |
144 static zephyr_triple *find_sub_by_triple(zephyr_triple *zt) | |
145 { | |
146 zephyr_triple *curr_t; | |
147 GSList *curr = subscrips; | |
148 while (curr) { | |
149 curr_t = curr->data; | |
150 if (triple_subset(zt, curr_t)) | |
151 return curr_t; | |
152 curr = curr->next; | |
153 } | |
154 return NULL; | |
155 } | |
156 | |
157 static zephyr_triple *find_sub_by_id(int id) | |
158 { | |
159 zephyr_triple *zt; | |
160 GSList *curr = subscrips; | |
161 while (curr) { | |
162 zt = curr->data; | |
163 if (zt->id == id) | |
164 return zt; | |
165 curr = curr->next; | |
166 } | |
167 return NULL; | |
168 } | |
169 | |
170 /* utility macros that are useful for zephyr_to_html */ | |
171 | |
172 #define IS_OPENER(c) ((c == '{') || (c == '[') || (c == '(') || (c == '<')) | |
173 #define IS_CLOSER(c) ((c == '}') || (c == ']') || (c == ')') || (c == '>')) | |
174 | |
175 /* this parses zephyr formatting and converts it to html. For example, if | |
176 * you pass in "@{@color(blue)@i(hello)}" you should get out | |
177 * "<font color=blue><i>hello</i></font>". */ | |
178 static char *zephyr_to_html(char *message) | |
179 { | |
180 int len, cnt; | |
181 zframe *frames, *curr; | |
182 char *ret; | |
183 | |
184 frames = g_new(zframe, 1); | |
185 frames->text = g_string_new(""); | |
186 frames->enclosing = NULL; | |
187 frames->closing = ""; | |
188 frames->has_closer = FALSE; | |
189 | |
190 len = strlen(message); | |
191 cnt = 0; | |
192 while (cnt <= len) { | |
193 if (message[cnt] == '@') { | |
194 zframe *new_f; | |
195 char *buf; | |
196 int end; | |
197 for (end=1; (cnt+end) <= len && | |
198 !IS_OPENER(message[cnt+end]); end++); | |
199 buf = g_new0(char, end); | |
200 if (end) { | |
201 g_snprintf(buf, end, "%s", message+cnt+1); | |
202 } | |
203 if (!g_strcasecmp(buf, "italic") || | |
204 !g_strcasecmp(buf, "i")) { | |
205 new_f = g_new(zframe, 1); | |
206 new_f->enclosing = frames; | |
207 new_f->text = g_string_new("<i>"); | |
208 new_f->closing = "</i>"; | |
209 new_f->has_closer = TRUE; | |
210 frames = new_f; | |
211 cnt += end+1; /* cnt points to char after opener */ | |
212 } else if (!g_strcasecmp(buf, "bold") | |
213 || !g_strcasecmp(buf, "b")) { | |
214 new_f = g_new(zframe, 1); | |
215 new_f->enclosing = frames; | |
216 new_f->text = g_string_new("<b>"); | |
217 new_f->closing = "</b>"; | |
218 new_f->has_closer = TRUE; | |
219 frames = new_f; | |
220 cnt += end+1; | |
221 } else if (!g_strcasecmp(buf, "color")) { | |
222 cnt += end+1; | |
223 new_f = g_new(zframe, 1); | |
224 new_f->enclosing = frames; | |
225 new_f->text = g_string_new("<font color="); | |
226 for (; (cnt <= len) && !IS_CLOSER(message[cnt]); cnt++) { | |
227 g_string_append_c(new_f->text, message[cnt]); | |
228 } | |
229 cnt++; /* point to char after closer */ | |
230 g_string_append_c(new_f->text, '>'); | |
231 new_f->closing = "</font>"; | |
232 new_f->has_closer = FALSE; | |
233 frames = new_f; | |
234 } else if (!g_strcasecmp(buf, "")) { | |
235 new_f = g_new(zframe, 1); | |
236 new_f->enclosing = frames; | |
237 new_f->text = g_string_new(""); | |
238 new_f->closing = ""; | |
239 new_f->has_closer = TRUE; | |
240 frames = new_f; | |
241 cnt += end+1; /* cnt points to char after opener */ | |
242 } else { | |
243 if ((cnt+end) > len) { | |
244 g_string_append_c(frames->text, '@'); | |
245 cnt++; | |
246 } else { | |
247 /* unrecognized thingie. act like it's not there, but we | |
248 * still need to take care of the corresponding closer, | |
249 * make a frame that does nothing. */ | |
250 new_f = g_new(zframe, 1); | |
251 new_f->enclosing = frames; | |
252 new_f->text = g_string_new(""); | |
253 new_f->closing = ""; | |
254 new_f->has_closer = TRUE; | |
255 frames = new_f; | |
256 cnt += end+1; /* cnt points to char after opener */ | |
257 } | |
258 } | |
259 } else if (IS_CLOSER(message[cnt])) { | |
260 zframe *popped; | |
261 gboolean last_had_closer; | |
262 if (frames->enclosing) { | |
263 do { | |
264 popped = frames; | |
265 frames = frames->enclosing; | |
266 g_string_append(frames->text, popped->text->str); | |
267 g_string_append(frames->text, popped->closing); | |
268 g_string_free(popped->text, TRUE); | |
269 last_had_closer = popped->has_closer; | |
270 g_free(popped); | |
271 } while (frames && frames->enclosing && !last_had_closer); | |
272 } else { | |
273 g_string_append_c(frames->text, message[cnt]); | |
274 } | |
275 cnt++; | |
276 } else if (message[cnt] == '\n') { | |
277 g_string_append(frames->text, "<br>"); | |
278 cnt++; | |
279 } else { | |
280 g_string_append_c(frames->text, message[cnt++]); | |
281 } | |
282 } | |
283 /* go through all the stuff that they didn't close */ | |
284 while (frames->enclosing) { | |
285 curr = frames; | |
286 g_string_append(frames->enclosing->text, frames->text->str); | |
287 g_string_append(frames->enclosing->text, frames->closing); | |
288 g_string_free(frames->text, TRUE); | |
289 frames = frames->enclosing; | |
290 g_free(curr); | |
291 } | |
292 ret = frames->text->str; | |
293 g_string_free(frames->text, FALSE); | |
294 g_free(frames); | |
295 return ret; | |
296 } | |
297 | |
298 static gboolean pending_zloc(char *who) | |
299 { | |
300 GList *curr; | |
301 for (curr = pending_zloc_names; curr != NULL; curr = curr->next) { | |
302 if (!g_strcasecmp(who, (char*)curr->data)) { | |
303 g_free((char*)curr->data); | |
304 pending_zloc_names = g_list_remove(pending_zloc_names, curr->data); | |
305 return TRUE; | |
306 } | |
307 } | |
308 return FALSE; | |
309 } | |
310 | |
311 static void handle_message(ZNotice_t notice, struct sockaddr_in from) | |
312 { | |
313 if (!g_strcasecmp(notice.z_class, LOGIN_CLASS)) { | |
3277 | 314 /* well, we'll be updating in 20 seconds anyway, might as well ignore this. */ |
2086 | 315 } else if (!g_strcasecmp(notice.z_class, LOCATE_CLASS)) { |
316 if (!g_strcasecmp(notice.z_opcode, LOCATE_LOCATE)) { | |
317 int nlocs; | |
318 char *user; | |
319 struct buddy *b; | |
320 | |
321 if (ZParseLocations(¬ice, NULL, &nlocs, &user) != ZERR_NONE) | |
322 return; | |
323 if ((b = find_buddy(zgc, user)) == NULL) { | |
324 char *e = strchr(user, '@'); | |
325 if (e) *e = '\0'; | |
326 b = find_buddy(zgc, user); | |
327 } | |
328 if (!b) { | |
329 free(user); | |
330 return; | |
331 } | |
332 if (pending_zloc(b->name)) { | |
333 ZLocations_t locs; | |
334 int one = 1; | |
335 GString *str = g_string_new(""); | |
336 g_string_sprintfa(str, "<b>User:</b> %s<br>" | |
337 "<b>Alias:</b> %s<br>", | |
338 b->name, b->show); | |
339 if (!nlocs) { | |
340 g_string_sprintfa(str, "<br>Hidden or not logged-in"); | |
341 } | |
342 for (; nlocs > 0; nlocs--) { | |
343 ZGetLocations(&locs, &one); | |
344 g_string_sprintfa(str, "<br>At %s since %s", locs.host, | |
345 locs.time); | |
346 } | |
2791
8f6365332a05
[gaim-migrate @ 2804]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2773
diff
changeset
|
347 g_show_info_text(NULL, NULL, 2, str->str, NULL); |
2086 | 348 g_string_free(str, TRUE); |
349 } else | |
350 serv_got_update(zgc, b->name, nlocs, 0, 0, 0, 0, 0); | |
351 | |
352 free(user); | |
353 } | |
354 } else { | |
355 char *buf, *buf2; | |
2804
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
356 char *send_inst; |
3277 | 357 char *realmptr; |
358 char *sendertmp; | |
2086 | 359 char *ptr = notice.z_message + strlen(notice.z_message) + 1; |
360 int len = notice.z_message_len - (ptr - notice.z_message); | |
361 int away; | |
362 if (len > 0) { | |
363 buf = g_malloc(len + 1); | |
364 g_snprintf(buf, len + 1, "%s", ptr); | |
365 g_strchomp(buf); | |
366 buf2 = zephyr_to_html(buf); | |
367 g_free(buf); | |
368 if (!g_strcasecmp(notice.z_class, "MESSAGE") && | |
369 !g_strcasecmp(notice.z_class_inst, "PERSONAL")) { | |
370 if (!g_strcasecmp(notice.z_message, "Automated reply:")) | |
371 away = TRUE; | |
372 else | |
373 away = FALSE; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2804
diff
changeset
|
374 serv_got_im(zgc, notice.z_sender, buf2, 0, time(NULL), -1); |
2086 | 375 } else { |
376 zephyr_triple *zt1, *zt2; | |
377 zt1 = new_triple(notice.z_class, notice.z_class_inst, | |
378 notice.z_recipient); | |
379 zt2 = find_sub_by_triple(zt1); | |
380 if (!zt2) { | |
381 /* we shouldn't be subscribed to this message. ignore. */ | |
382 } else { | |
383 if (!zt2->open) { | |
384 zt2->open = TRUE; | |
385 serv_got_joined_chat(zgc, zt2->id, zt2->name); | |
386 } | |
3277 | 387 /* If the person is in the default Realm, then strip the |
388 Realm from the sender field */ | |
389 sendertmp = g_strdup_printf("%s",notice.z_sender); | |
390 realmptr = strchr(sendertmp,'@'); | |
391 realmptr++; | |
392 if (!g_strcasecmp(realmptr,ZGetRealm())) { | |
393 realmptr--; | |
394 sprintf(realmptr,"%c",'\0'); | |
395 send_inst = g_strdup_printf("%s %s",sendertmp, | |
396 notice.z_class_inst); | |
397 | |
398 } else { | |
399 send_inst = g_strdup_printf("%s %s",notice.z_sender, | |
400 notice.z_class_inst); | |
401 } | |
2804
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
402 serv_got_chat_in(zgc, zt2->id, send_inst, FALSE, |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
403 buf2, time(NULL)); |
3277 | 404 g_free(sendertmp); |
2804
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
405 g_free(send_inst); |
2086 | 406 } |
407 free_triple(zt1); | |
408 } | |
409 g_free(buf2); | |
410 } | |
411 } | |
412 } | |
413 | |
414 static gint check_notify(gpointer data) | |
415 { | |
416 while (ZPending()) { | |
417 ZNotice_t notice; | |
418 struct sockaddr_in from; | |
419 z_call_r(ZReceiveNotice(¬ice, &from)); | |
420 | |
421 switch (notice.z_kind) { | |
422 case UNSAFE: | |
423 case UNACKED: | |
424 case ACKED: | |
425 handle_message(notice, from); | |
426 break; | |
427 default: | |
428 /* we'll just ignore things for now */ | |
429 debug_printf("ZEPHYR: Unhandled Notice\n"); | |
430 break; | |
431 } | |
432 | |
433 ZFreeNotice(¬ice); | |
434 } | |
435 | |
436 return TRUE; | |
437 } | |
438 | |
439 static gint check_loc(gpointer data) | |
440 { | |
441 GSList *gr, *m; | |
442 ZAsyncLocateData_t ald; | |
443 | |
444 ald.user = NULL; | |
445 memset(&(ald.uid), 0, sizeof(ZUnique_Id_t)); | |
446 ald.version = NULL; | |
447 | |
448 gr = zgc->groups; | |
449 while (gr) { | |
450 struct group *g = gr->data; | |
451 m = g->members; | |
452 while (m) { | |
453 struct buddy *b = m->data; | |
454 char *chk; | |
455 chk = zephyr_normalize(b->name); | |
456 /* doesn't matter if this fails or not; we'll just move on to the next one */ | |
457 ZRequestLocations(chk, &ald, UNACKED, ZAUTH); | |
458 free(ald.user); | |
459 free(ald.version); | |
460 m = m->next; | |
461 } | |
462 gr = gr->next; | |
463 } | |
464 | |
465 return TRUE; | |
466 } | |
467 | |
468 static char *get_exposure_level() | |
469 { | |
470 char *exposure = ZGetVariable("exposure"); | |
471 | |
472 if (!exposure) | |
473 return EXPOSE_REALMVIS; | |
474 if (!g_strcasecmp(exposure, EXPOSE_NONE)) | |
475 return EXPOSE_NONE; | |
476 if (!g_strcasecmp(exposure, EXPOSE_OPSTAFF)) | |
477 return EXPOSE_OPSTAFF; | |
478 if (!g_strcasecmp(exposure, EXPOSE_REALMANN)) | |
479 return EXPOSE_REALMANN; | |
480 if (!g_strcasecmp(exposure, EXPOSE_NETVIS)) | |
481 return EXPOSE_NETVIS; | |
482 if (!g_strcasecmp(exposure, EXPOSE_NETANN)) | |
483 return EXPOSE_NETANN; | |
484 return EXPOSE_REALMVIS; | |
485 } | |
486 | |
487 static void strip_comments(char *str) | |
488 { | |
489 char *tmp = strchr(str, '#'); | |
490 if (tmp) | |
491 *tmp = '\0'; | |
492 g_strchug(str); | |
493 g_strchomp(str); | |
494 } | |
495 | |
496 static void process_zsubs() | |
497 { | |
498 FILE *f; | |
499 gchar *fname; | |
500 gchar buff[BUFSIZ]; | |
501 | |
502 fname = g_strdup_printf("%s/.zephyr.subs", g_getenv("HOME")); | |
503 f = fopen(fname, "r"); | |
504 if (f) { | |
505 char **triple; | |
506 ZSubscription_t sub; | |
507 char *recip; | |
508 while (fgets(buff, BUFSIZ, f)) { | |
509 strip_comments(buff); | |
510 if (buff[0]) { | |
511 triple = g_strsplit(buff, ",", 3); | |
3277 | 512 if (triple[0] && triple[1] ) { |
2804
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
513 char *tmp = g_strdup_printf("%s@%s", g_getenv("USER"), |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
514 ZGetRealm()); |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
515 char *atptr; |
2086 | 516 sub.zsub_class = triple[0]; |
517 sub.zsub_classinst = triple[1]; | |
3277 | 518 if(triple[2] == NULL) { |
519 recip = g_malloc0(1); | |
520 } else if (!g_strcasecmp(triple[2], "%me%")) { | |
2086 | 521 recip = g_strdup_printf("%s@%s", g_getenv("USER"), |
522 ZGetRealm()); | |
523 } else if (!g_strcasecmp(triple[2], "*")) { | |
2804
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
524 /* wildcard |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
525 * form of class,instance,* */ |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
526 recip = g_malloc0(1); |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
527 } else if (!g_strcasecmp(triple[2], tmp)) { |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
528 /* form of class,instance,aatharuv@ATHENA.MIT.EDU */ |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
529 recip = g_strdup(triple[2]); |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
530 } else if ((atptr = strchr(triple[2], '@')) != NULL) { |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
531 /* form of class,instance,*@ANDREW.CMU.EDU |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
532 * class,instance,@ANDREW.CMU.EDU |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
533 * If realm is local realm, blank recipient, else |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
534 * @REALM-NAME |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
535 */ |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
536 char *realmat = g_strdup_printf("@%s", ZGetRealm()); |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
537 if (!g_strcasecmp(atptr, realmat)) |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
538 recip = g_malloc0(1); |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
539 else |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
540 recip = g_strdup(atptr); |
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
541 g_free(realmat); |
2086 | 542 } else { |
543 recip = g_strdup(triple[2]); | |
544 } | |
2804
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
545 g_free(tmp); |
2086 | 546 sub.zsub_recipient = recip; |
547 if (ZSubscribeTo(&sub, 1, 0) != ZERR_NONE) { | |
548 debug_printf("Zephyr: Couldn't subscribe to %s, %s, " | |
549 "%s\n", | |
550 sub.zsub_class, | |
551 sub.zsub_classinst, | |
552 sub.zsub_recipient); | |
553 } | |
554 subscrips = g_slist_append(subscrips, | |
555 new_triple(triple[0], triple[1], recip)); | |
556 g_free(recip); | |
557 } | |
558 g_strfreev(triple); | |
559 } | |
560 } | |
561 } | |
562 } | |
563 | |
564 static void process_anyone() | |
565 { | |
566 FILE *fd; | |
567 gchar buff[BUFSIZ], *filename; | |
568 | |
569 filename = g_strconcat(g_get_home_dir(), "/.anyone", NULL); | |
570 if ((fd = fopen(filename, "r")) != NULL) { | |
571 while (fgets(buff, BUFSIZ, fd)) { | |
572 strip_comments(buff); | |
573 if (buff[0]) | |
574 add_buddy(zgc, "Anyone", buff, buff); | |
575 } | |
576 fclose(fd); | |
577 } | |
578 g_free(filename); | |
579 } | |
580 | |
581 static void zephyr_login(struct aim_user *user) | |
582 { | |
583 ZSubscription_t sub; | |
584 | |
585 if (zgc) { | |
3427 | 586 do_error_dialog("Already logged in with Zephyr", "Because Zephyr uses your system username, you are unable to " |
587 "have multiple accounts on it when logged in as the same user.", GAIM_ERROR); | |
2086 | 588 return; |
589 } | |
590 | |
591 zgc = new_gaim_conn(user); | |
592 | |
593 z_call_s(ZInitialize(), "Couldn't initialize zephyr"); | |
594 z_call_s(ZOpenPort(NULL), "Couldn't open port"); | |
595 z_call_s(ZSetLocation(get_exposure_level()), "Couldn't set location"); | |
596 | |
597 sub.zsub_class = "MESSAGE"; | |
598 sub.zsub_classinst = "PERSONAL"; | |
599 sub.zsub_recipient = ZGetSender(); | |
600 | |
601 /* we don't care if this fails. i'm lying right now. */ | |
602 if (ZSubscribeTo(&sub, 1, 0) != ZERR_NONE) { | |
603 debug_printf("Zephyr: Couldn't subscribe to messages!\n"); | |
604 } | |
605 | |
606 account_online(zgc); | |
607 serv_finish_login(zgc); | |
608 | |
609 if (bud_list_cache_exists(zgc)) | |
2382
569ae9f2bb89
[gaim-migrate @ 2395]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2303
diff
changeset
|
610 do_import(zgc, NULL); |
2086 | 611 process_anyone(); |
612 process_zsubs(); | |
613 | |
2131
acc11216ec5d
[gaim-migrate @ 2141]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
614 nottimer = g_timeout_add(100, check_notify, NULL); |
2804
1648c703ddc2
[gaim-migrate @ 2817]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2791
diff
changeset
|
615 loctimer = g_timeout_add(20000, check_loc, NULL); |
2086 | 616 } |
617 | |
618 static void write_zsubs() | |
619 { | |
620 GSList *s = subscrips; | |
621 zephyr_triple *zt; | |
622 FILE *fd; | |
623 char *fname; | |
624 | |
3277 | 625 char** triple; |
2086 | 626 fname = g_strdup_printf("%s/.zephyr.subs", g_get_home_dir()); |
627 fd = fopen(fname, "w"); | |
628 | |
629 if (!fd) { | |
630 g_free(fname); | |
631 return; | |
632 } | |
633 | |
634 while (s) { | |
635 zt = s->data; | |
3277 | 636 triple = g_strsplit(zt->name,",",3); |
637 if (triple[2] != NULL) { | |
638 if (!g_strcasecmp(triple[2], "")) { | |
639 fprintf(fd, "%s,%s,*\n", triple[0], triple[1]); | |
640 } else if (!g_strcasecmp(triple[2], ZGetSender())) { | |
641 fprintf(fd, "%s,%s,%%me%%\n",triple[0],triple[1]); | |
642 } else { | |
643 fprintf(fd, "%s\n", zt->name); | |
644 } | |
645 } else { | |
646 fprintf(fd, "%s,%s,*\n",triple[0], triple[1]); | |
647 } | |
648 g_free(triple); | |
2086 | 649 s = s->next; |
650 } | |
651 g_free(fname); | |
652 fclose(fd); | |
653 } | |
654 | |
655 static void write_anyone() | |
656 { | |
657 GSList *gr, *m; | |
658 struct group *g; | |
659 struct buddy *b; | |
3277 | 660 char *ptr, *fname, *ptr2; |
2086 | 661 FILE *fd; |
662 | |
663 fname = g_strdup_printf("%s/.anyone", g_get_home_dir()); | |
664 fd = fopen(fname, "w"); | |
665 if (!fd) { | |
666 g_free(fname); | |
667 return; | |
668 } | |
669 | |
670 gr = zgc->groups; | |
671 while (gr) { | |
672 g = gr->data; | |
673 m = g->members; | |
674 while (m) { | |
675 b = m->data; | |
3277 | 676 if ((ptr = strchr(b->name, '@')) != NULL) { |
677 ptr2 = ptr + 1; | |
678 /* We should only strip the realm name if the principal | |
679 is in the user's realm | |
680 */ | |
681 if (!g_strcasecmp(ptr2,ZGetRealm())) { | |
682 *ptr = '\0'; | |
683 } | |
684 } | |
2086 | 685 fprintf(fd, "%s\n", b->name); |
686 if (ptr) | |
687 *ptr = '@'; | |
688 m = m->next; | |
689 } | |
690 gr = gr->next; | |
691 } | |
692 | |
693 fclose(fd); | |
694 g_free(fname); | |
695 } | |
696 | |
697 static void zephyr_close(struct gaim_connection *gc) | |
698 { | |
699 GList *l; | |
700 GSList *s; | |
701 l = pending_zloc_names; | |
702 while (l) { | |
703 g_free((char*)l->data); | |
704 l = l->next; | |
705 } | |
706 g_list_free(pending_zloc_names); | |
707 | |
708 write_anyone(); | |
709 write_zsubs(); | |
710 | |
711 s = subscrips; | |
712 while (s) { | |
713 free_triple((zephyr_triple*)s->data); | |
714 s = s->next; | |
715 } | |
716 g_slist_free(subscrips); | |
717 | |
718 if (nottimer) | |
2131
acc11216ec5d
[gaim-migrate @ 2141]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
719 g_source_remove(nottimer); |
2086 | 720 nottimer = 0; |
721 if (loctimer) | |
2131
acc11216ec5d
[gaim-migrate @ 2141]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
722 g_source_remove(loctimer); |
2086 | 723 loctimer = 0; |
724 zgc = NULL; | |
725 z_call(ZCancelSubscriptions(0)); | |
726 z_call(ZUnsetLocation()); | |
727 z_call(ZClosePort()); | |
728 } | |
729 | |
3466 | 730 static void zephyr_add_buddy(struct gaim_connection *gc, const char *buddy) { } |
2681
37d80035e77f
[gaim-migrate @ 2694]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2501
diff
changeset
|
731 static void zephyr_remove_buddy(struct gaim_connection *gc, char *buddy, char *group) { } |
2086 | 732 |
2167
edf8c5a70e5b
[gaim-migrate @ 2177]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2162
diff
changeset
|
733 static int zephyr_chat_send(struct gaim_connection *gc, int id, char *im) |
2086 | 734 { |
735 ZNotice_t notice; | |
736 zephyr_triple *zt; | |
737 char *buf; | |
738 const char *sig; | |
739 | |
740 zt = find_sub_by_id(id); | |
741 if (!zt) | |
742 /* this should never happen. */ | |
2167
edf8c5a70e5b
[gaim-migrate @ 2177]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2162
diff
changeset
|
743 return -EINVAL; |
2086 | 744 |
745 sig = ZGetVariable("zwrite-signature"); | |
746 if (!sig) { | |
747 sig = g_get_real_name(); | |
748 } | |
749 buf = g_strdup_printf("%s%c%s", sig, '\0', im); | |
750 | |
751 bzero((char *)¬ice, sizeof(notice)); | |
752 notice.z_kind = ACKED; | |
753 notice.z_port = 0; | |
754 notice.z_opcode = ""; | |
755 notice.z_class = zt->class; | |
756 notice.z_class_inst = zt->instance; | |
757 if (!g_strcasecmp(zt->recipient, "*")) | |
758 notice.z_recipient = zephyr_normalize(""); | |
759 else | |
760 notice.z_recipient = zephyr_normalize(zt->recipient); | |
761 notice.z_sender = 0; | |
762 notice.z_default_format = | |
763 "Class $class, Instance $instance:\n" | |
764 "To: @bold($recipient) at $time $date\n" | |
765 "From: @bold($1) <$sender>\n\n$2"; | |
766 notice.z_message_len = strlen(im) + strlen(sig) + 4; | |
767 notice.z_message = buf; | |
768 ZSendNotice(¬ice, ZAUTH); | |
769 g_free(buf); | |
2167
edf8c5a70e5b
[gaim-migrate @ 2177]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2162
diff
changeset
|
770 return 0; |
2086 | 771 } |
772 | |
3033 | 773 static int zephyr_send_im(struct gaim_connection *gc, char *who, char *im, int len, int flags) { |
2086 | 774 ZNotice_t notice; |
775 char *buf; | |
776 const char *sig; | |
777 | |
2231
8c4ff1a368bd
[gaim-migrate @ 2241]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2205
diff
changeset
|
778 if (flags & IM_FLAG_AWAY) |
2086 | 779 sig = "Automated reply:"; |
780 else { | |
781 sig = ZGetVariable("zwrite-signature"); | |
782 if (!sig) { | |
783 sig = g_get_real_name(); | |
784 } | |
785 } | |
786 buf = g_strdup_printf("%s%c%s", sig, '\0', im); | |
787 | |
788 bzero((char *)¬ice, sizeof(notice)); | |
789 notice.z_kind = ACKED; | |
790 notice.z_port = 0; | |
791 notice.z_opcode = ""; | |
792 notice.z_class = "MESSAGE"; | |
793 notice.z_class_inst = "PERSONAL"; | |
794 notice.z_sender = 0; | |
795 notice.z_recipient = who; | |
796 notice.z_default_format = | |
797 "Class $class, Instance $instance:\n" | |
798 "To: @bold($recipient) at $time $date\n" | |
799 "From: @bold($1) <$sender>\n\n$2"; | |
800 notice.z_message_len = strlen(im) + strlen(sig) + 4; | |
801 notice.z_message = buf; | |
802 ZSendNotice(¬ice, ZAUTH); | |
803 g_free(buf); | |
2303
f5bf315e6104
[gaim-migrate @ 2313]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2231
diff
changeset
|
804 return 1; |
2086 | 805 } |
806 | |
807 static char *zephyr_normalize(const char *orig) | |
808 { | |
809 static char buf[80]; | |
810 if (strchr(orig, '@')) { | |
811 g_snprintf(buf, 80, "%s", orig); | |
812 } else { | |
813 g_snprintf(buf, 80, "%s@%s", orig, ZGetRealm()); | |
814 } | |
815 return buf; | |
816 } | |
817 | |
818 static void zephyr_zloc(struct gaim_connection *gc, char *who) | |
819 { | |
820 ZAsyncLocateData_t ald; | |
821 | |
822 if (ZRequestLocations(zephyr_normalize(who), &ald, UNACKED, ZAUTH) | |
823 != ZERR_NONE) { | |
824 return; | |
825 } | |
826 pending_zloc_names = g_list_append(pending_zloc_names, | |
827 g_strdup(zephyr_normalize(who))); | |
828 } | |
829 | |
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
830 static GList *zephyr_buddy_menu(struct gaim_connection *gc, char *who) |
2086 | 831 { |
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
832 GList *m = NULL; |
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
833 struct proto_buddy_menu *pbm; |
2086 | 834 |
2170
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
835 pbm = g_new0(struct proto_buddy_menu, 1); |
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
836 pbm->label = _("ZLocate"); |
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
837 pbm->callback = zephyr_zloc; |
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
838 pbm->gc = gc; |
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
839 m = g_list_append(m, pbm); |
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
840 |
c24595d3c364
[gaim-migrate @ 2180]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2167
diff
changeset
|
841 return m; |
2086 | 842 } |
843 | |
844 static void zephyr_set_away(struct gaim_connection *gc, char *state, char *msg) | |
845 { | |
846 if (gc->away) | |
847 g_free(gc->away); | |
848 gc->away = NULL; | |
849 if (!g_strcasecmp(state, "Hidden")) | |
850 ZSetLocation(EXPOSE_OPSTAFF); | |
851 else if (!g_strcasecmp(state, "Online")) | |
852 ZSetLocation(get_exposure_level()); | |
853 else /* state is GAIM_AWAY_CUSTOM */ if (msg) | |
854 gc->away = g_strdup(msg); | |
855 } | |
856 | |
2501
227cc42ffa6e
[gaim-migrate @ 2514]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2417
diff
changeset
|
857 static GList *zephyr_away_states(struct gaim_connection *gc) |
2086 | 858 { |
859 GList *m = NULL; | |
860 | |
861 m = g_list_append(m, "Online"); | |
862 m = g_list_append(m, GAIM_AWAY_CUSTOM); | |
863 m = g_list_append(m, "Hidden"); | |
864 | |
865 return m; | |
866 } | |
867 | |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
868 static GList *zephyr_chat_info(struct gaim_connection *gc) { |
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
869 GList *m = NULL; |
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
870 struct proto_chat_entry *pce; |
2086 | 871 |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
872 pce = g_new0(struct proto_chat_entry, 1); |
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
873 pce->label = _("Class:"); |
3158 | 874 m = g_list_append(m, pce); |
2086 | 875 |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
876 pce = g_new0(struct proto_chat_entry, 1); |
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
877 pce->label = _("Instance:"); |
3158 | 878 m = g_list_append(m, pce); |
2086 | 879 |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
880 pce = g_new0(struct proto_chat_entry, 1); |
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
881 pce->label = _("Recipient:"); |
3158 | 882 m = g_list_append(m, pce); |
2086 | 883 |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
884 return m; |
2086 | 885 } |
886 | |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
887 static void zephyr_join_chat(struct gaim_connection *gc, GList *data) |
2086 | 888 { |
889 ZSubscription_t sub; | |
890 zephyr_triple *zt1, *zt2; | |
891 const char *classname; | |
892 const char *instname; | |
893 const char *recip; | |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
894 |
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
895 if (!data || !data->next || !data->next->next) |
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
896 return; |
2086 | 897 |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
898 classname = data->data; |
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
899 instname = data->next->data; |
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
900 recip = data->next->next->data; |
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
901 if (!g_strcasecmp(recip, "%me%")) |
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
902 recip = g_getenv("USER"); |
2086 | 903 |
904 zt1 = new_triple(classname, instname, recip); | |
905 zt2 = find_sub_by_triple(zt1); | |
906 if (zt2) { | |
907 free_triple(zt1); | |
908 if (!zt2->open) | |
909 serv_got_joined_chat(gc, zt2->id, zt2->name); | |
910 return; | |
911 } | |
912 | |
913 sub.zsub_class = zt1->class; | |
914 sub.zsub_classinst = zt1->instance; | |
915 sub.zsub_recipient = zt1->recipient; | |
916 | |
917 if (ZSubscribeTo(&sub, 1, 0) != ZERR_NONE) { | |
918 free_triple(zt1); | |
919 return; | |
920 } | |
921 | |
922 subscrips = g_slist_append(subscrips, zt1); | |
923 zt1->open = TRUE; | |
924 serv_got_joined_chat(gc, zt1->id, zt1->name); | |
925 } | |
926 | |
927 static void zephyr_chat_leave(struct gaim_connection *gc, int id) | |
928 { | |
929 zephyr_triple *zt; | |
930 zt = find_sub_by_id(id); | |
931 if (zt) { | |
932 zt->open = FALSE; | |
933 zt->id = ++last_id; | |
934 } | |
935 } | |
936 | |
937 static struct prpl *my_protocol = NULL; | |
938 | |
939 void zephyr_init(struct prpl *ret) | |
940 { | |
941 ret->protocol = PROTO_ZEPHYR; | |
2100
a93aeb6f813d
[gaim-migrate @ 2110]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
942 ret->options = OPT_PROTO_NO_PASSWORD; |
3572 | 943 ret->name = g_strdup("Zephyr"); |
2086 | 944 ret->login = zephyr_login; |
945 ret->close = zephyr_close; | |
946 ret->add_buddy = zephyr_add_buddy; | |
947 ret->remove_buddy = zephyr_remove_buddy; | |
948 ret->send_im = zephyr_send_im; | |
949 ret->get_info = zephyr_zloc; | |
950 ret->normalize = zephyr_normalize; | |
951 ret->buddy_menu = zephyr_buddy_menu; | |
952 ret->away_states = zephyr_away_states; | |
953 ret->set_away = zephyr_set_away; | |
2205
cff4fbe01c7b
[gaim-migrate @ 2215]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2170
diff
changeset
|
954 ret->chat_info = zephyr_chat_info; |
2086 | 955 ret->join_chat = zephyr_join_chat; |
956 ret->chat_send = zephyr_chat_send; | |
957 ret->chat_leave = zephyr_chat_leave; | |
958 | |
959 my_protocol = ret; | |
960 } | |
961 | |
962 #ifndef STATIC | |
963 | |
3572 | 964 void *gaim_prpl_init(struct prpl *prpl) |
2086 | 965 { |
3572 | 966 zephyr_init(prpl); |
967 prpl->plug->desc.api_version = PLUGIN_API_VERSION; | |
2086 | 968 } |
969 | |
970 | |
971 #endif |