Mercurial > pidgin.yaz
comparison plugins/zephyr/zephyr.c @ 1808:6a89897c8658
[gaim-migrate @ 1818]
nsanch's patch for zephyr subscriptions. the only changes i made to it were slight style changes, so if there's anything broken, blame him, not me ;)
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Sat, 05 May 2001 11:22:31 +0000 |
parents | 60b3fd819cce |
children | b012f6b9095b |
comparison
equal
deleted
inserted
replaced
1807:ba8f463744c0 | 1808:6a89897c8658 |
---|---|
32 #include "gaim.h" | 32 #include "gaim.h" |
33 #include "prpl.h" | 33 #include "prpl.h" |
34 #include "zephyr/zephyr.h" | 34 #include "zephyr/zephyr.h" |
35 | 35 |
36 typedef struct _zframe zframe; | 36 typedef struct _zframe zframe; |
37 typedef struct _zephyr_triple zephyr_triple; | |
37 | 38 |
38 /* struct I need for zephyr_to_html */ | 39 /* struct I need for zephyr_to_html */ |
39 struct _zframe { | 40 struct _zframe { |
40 /* true for everything but @color, since inside the parens of that one is | 41 /* true for everything but @color, since inside the parens of that one is |
41 * the color. */ | 42 * the color. */ |
45 /* text including the opening html thingie. */ | 46 /* text including the opening html thingie. */ |
46 GString *text; | 47 GString *text; |
47 struct _zframe *enclosing; | 48 struct _zframe *enclosing; |
48 }; | 49 }; |
49 | 50 |
51 struct _zephyr_triple { | |
52 char *class; | |
53 char *instance; | |
54 char *recipient; | |
55 char *name; | |
56 gboolean open; | |
57 int id; | |
58 }; | |
59 | |
50 char *name() | 60 char *name() |
51 { | 61 { |
52 return "Zephyr"; | 62 return "Zephyr"; |
53 } | 63 } |
54 | 64 |
78 * wouldn't do this. but it is so i will. */ | 88 * wouldn't do this. but it is so i will. */ |
79 static guint32 nottimer = 0; | 89 static guint32 nottimer = 0; |
80 static guint32 loctimer = 0; | 90 static guint32 loctimer = 0; |
81 struct gaim_connection *zgc = NULL; | 91 struct gaim_connection *zgc = NULL; |
82 static GList *pending_zloc_names = NULL; | 92 static GList *pending_zloc_names = NULL; |
93 static GSList *subscrips = NULL; | |
94 static int last_id = 0; | |
95 static GtkWidget *class_entry; | |
96 static GtkWidget *inst_entry; | |
97 static GtkWidget *recip_entry; | |
83 | 98 |
84 /* just for debugging | 99 /* just for debugging |
85 static void handle_unknown(ZNotice_t notice) | 100 static void handle_unknown(ZNotice_t notice) |
86 { | 101 { |
87 g_print("z_packet: %s\n", notice.z_packet); | 102 g_print("z_packet: %s\n", notice.z_packet); |
95 g_print("z_message: %s\n", notice.z_message); | 110 g_print("z_message: %s\n", notice.z_message); |
96 g_print("z_message_len: %d\n", notice.z_message_len); | 111 g_print("z_message_len: %d\n", notice.z_message_len); |
97 g_print("\n"); | 112 g_print("\n"); |
98 } | 113 } |
99 */ | 114 */ |
115 | |
116 static zephyr_triple *new_triple(char *c, char *i, char *r) | |
117 { | |
118 zephyr_triple *zt; | |
119 zt = g_new0(zephyr_triple, 1); | |
120 zt->class = g_strdup(c); | |
121 zt->instance = g_strdup(i); | |
122 zt->recipient = g_strdup(r); | |
123 zt->name = g_strdup_printf("%s,%s,%s", c, i, r); | |
124 zt->id = ++last_id; | |
125 zt->open = FALSE; | |
126 return zt; | |
127 } | |
128 | |
129 static void free_triple(zephyr_triple *zt) | |
130 { | |
131 g_free(zt->class); | |
132 g_free(zt->instance); | |
133 g_free(zt->recipient); | |
134 g_free(zt->name); | |
135 g_free(zt); | |
136 } | |
137 | |
138 /* returns true if zt1 is a subset of zt2, i.e. zt2 has the same thing or | |
139 * wildcards in each field of zt1. */ | |
140 static gboolean triple_subset(zephyr_triple *zt1, zephyr_triple *zt2) | |
141 { | |
142 if (g_strcasecmp(zt2->class, zt1->class) && | |
143 g_strcasecmp(zt2->class, "*")) { | |
144 return FALSE; | |
145 } | |
146 if (g_strcasecmp(zt2->instance, zt1->instance) && | |
147 g_strcasecmp(zt2->instance, "*")) { | |
148 return FALSE; | |
149 } | |
150 if (g_strcasecmp(zt2->recipient, zt1->recipient) && | |
151 g_strcasecmp(zt2->recipient, "*")) { | |
152 return FALSE; | |
153 } | |
154 return TRUE; | |
155 } | |
156 | |
157 static zephyr_triple *find_sub_by_triple(zephyr_triple *zt) | |
158 { | |
159 zephyr_triple *curr_t; | |
160 GSList *curr = subscrips; | |
161 while (curr) { | |
162 curr_t = curr->data; | |
163 if (triple_subset(zt, curr_t)) | |
164 return curr_t; | |
165 curr = curr->next; | |
166 } | |
167 return NULL; | |
168 } | |
169 | |
170 static zephyr_triple *find_sub_by_id(int id) | |
171 { | |
172 zephyr_triple *zt; | |
173 GSList *curr = subscrips; | |
174 while (curr) { | |
175 zt = curr->data; | |
176 if (zt->id == id) | |
177 return zt; | |
178 curr = curr->next; | |
179 } | |
180 return NULL; | |
181 } | |
100 | 182 |
101 /* utility macros that are useful for zephyr_to_html */ | 183 /* utility macros that are useful for zephyr_to_html */ |
102 | 184 |
103 #define IS_OPENER(c) ((c == '{') || (c == '[') || (c == '(') || (c == '<')) | 185 #define IS_OPENER(c) ((c == '{') || (c == '[') || (c == '(') || (c == '<')) |
104 #define IS_CLOSER(c) ((c == '}') || (c == ']') || (c == ')') || (c == '>')) | 186 #define IS_CLOSER(c) ((c == '}') || (c == ']') || (c == ')') || (c == '>')) |
302 len = MAX(BUF_LONG, strlen(buf2)); | 384 len = MAX(BUF_LONG, strlen(buf2)); |
303 buf = g_malloc(len + 1); | 385 buf = g_malloc(len + 1); |
304 g_snprintf(buf, len + 1, "%s", buf2); | 386 g_snprintf(buf, len + 1, "%s", buf2); |
305 serv_got_im(zgc, notice.z_sender, buf, 0, time((time_t)NULL)); | 387 serv_got_im(zgc, notice.z_sender, buf, 0, time((time_t)NULL)); |
306 g_free(buf); | 388 g_free(buf); |
389 } else { | |
390 zephyr_triple *zt1, *zt2; | |
391 zt1 = new_triple(notice.z_class, notice.z_class_inst, | |
392 notice.z_recipient); | |
393 zt2 = find_sub_by_triple(zt1); | |
394 if (!zt2) { | |
395 /* we shouldn't be subscribed to this message. ignore. */ | |
396 } else { | |
397 len = MAX(BUF_LONG, strlen(buf2)); | |
398 buf = g_malloc(len + 1); | |
399 g_snprintf(buf, len + 1, "%s", buf2); | |
400 if (!zt2->open) { | |
401 zt2->open = TRUE; | |
402 serv_got_joined_chat(zgc, zt2->id, zt2->name); | |
403 } | |
404 serv_got_chat_in(zgc, zt2->id, notice.z_sender, FALSE, | |
405 buf, time((time_t)NULL)); | |
406 g_free(buf); | |
407 } | |
408 free_triple(zt1); | |
307 } | 409 } |
308 g_free(buf2); | 410 g_free(buf2); |
309 } | 411 } |
310 } | 412 } |
311 } | 413 } |
427 sub.zsub_class, | 529 sub.zsub_class, |
428 sub.zsub_classinst, | 530 sub.zsub_classinst, |
429 sub.zsub_recipient); | 531 sub.zsub_recipient); |
430 } | 532 } |
431 g_free(recip); | 533 g_free(recip); |
534 subscrips = g_slist_append(subscrips, | |
535 new_triple(triple[0], triple[1], recip)); | |
432 } | 536 } |
433 g_strfreev(triple); | 537 g_strfreev(triple); |
434 } | 538 } |
435 } | 539 } |
436 } | 540 } |
481 serv_finish_login(zgc); | 585 serv_finish_login(zgc); |
482 | 586 |
483 if (bud_list_cache_exists(zgc)) | 587 if (bud_list_cache_exists(zgc)) |
484 do_import(NULL, zgc); | 588 do_import(NULL, zgc); |
485 process_anyone(); | 589 process_anyone(); |
486 /* call process_zsubs to subscribe. still commented out since I don't know | 590 process_zsubs(); |
487 * how you want to handle incoming msgs from subs. | |
488 process_zsubs(); */ | |
489 | 591 |
490 nottimer = gtk_timeout_add(100, check_notify, NULL); | 592 nottimer = gtk_timeout_add(100, check_notify, NULL); |
491 loctimer = gtk_timeout_add(2000, check_loc, NULL); | 593 loctimer = gtk_timeout_add(2000, check_loc, NULL); |
594 } | |
595 | |
596 static void write_zsubs() | |
597 { | |
598 GSList *s = subscrips; | |
599 zephyr_triple *zt; | |
600 FILE *fd; | |
601 char *fname; | |
602 | |
603 fname = g_strdup_printf("%s/.zephyr.subs", g_get_home_dir()); | |
604 fd = fopen(fname, "w"); | |
605 | |
606 if (!fd) { | |
607 g_free(fname); | |
608 return; | |
609 } | |
610 | |
611 while (s) { | |
612 zt = s->data; | |
613 fprintf(fd, "%s\n", zt->name); | |
614 s = s->next; | |
615 } | |
616 g_free(fname); | |
617 fclose(fd); | |
492 } | 618 } |
493 | 619 |
494 static void write_anyone() | 620 static void write_anyone() |
495 { | 621 { |
496 GSList *gr, *m; | 622 GSList *gr, *m; |
526 g_free(fname); | 652 g_free(fname); |
527 } | 653 } |
528 | 654 |
529 static void zephyr_close(struct gaim_connection *gc) | 655 static void zephyr_close(struct gaim_connection *gc) |
530 { | 656 { |
531 g_list_foreach(pending_zloc_names, (GFunc)g_free, NULL); | 657 GList *l; |
658 GSList *s; | |
659 l = pending_zloc_names; | |
660 while (l) { | |
661 g_free((char*)l->data); | |
662 l = l->next; | |
663 } | |
532 g_list_free(pending_zloc_names); | 664 g_list_free(pending_zloc_names); |
665 | |
533 write_anyone(); | 666 write_anyone(); |
667 write_zsubs(); | |
668 | |
669 s = subscrips; | |
670 while (s) { | |
671 free_triple((zephyr_triple*)s->data); | |
672 s = s->next; | |
673 } | |
674 g_slist_free(subscrips); | |
675 | |
534 if (nottimer) | 676 if (nottimer) |
535 gtk_timeout_remove(nottimer); | 677 gtk_timeout_remove(nottimer); |
536 nottimer = 0; | 678 nottimer = 0; |
537 if (loctimer) | 679 if (loctimer) |
538 gtk_timeout_remove(loctimer); | 680 gtk_timeout_remove(loctimer); |
543 z_call(ZClosePort()); | 685 z_call(ZClosePort()); |
544 } | 686 } |
545 | 687 |
546 static void zephyr_add_buddy(struct gaim_connection *gc, char *buddy) { } | 688 static void zephyr_add_buddy(struct gaim_connection *gc, char *buddy) { } |
547 static void zephyr_remove_buddy(struct gaim_connection *gc, char *buddy) { } | 689 static void zephyr_remove_buddy(struct gaim_connection *gc, char *buddy) { } |
690 | |
691 static void zephyr_chat_send(struct gaim_connection *gc, int id, char *im) | |
692 { | |
693 ZNotice_t notice; | |
694 zephyr_triple *zt; | |
695 char *buf; | |
696 char *sig; | |
697 | |
698 zt = find_sub_by_id(id); | |
699 if (!zt) | |
700 /* this should never happen. */ | |
701 return; | |
702 | |
703 sig = ZGetVariable("zwrite-signature"); | |
704 if (!sig) { | |
705 sig = g_get_real_name(); | |
706 } | |
707 buf = g_strdup_printf("%s%c%s", sig, '\0', im); | |
708 | |
709 bzero((char *)¬ice, sizeof(notice)); | |
710 notice.z_kind = ACKED; | |
711 notice.z_port = 0; | |
712 notice.z_opcode = ""; | |
713 notice.z_class = zt->class; | |
714 notice.z_class_inst = zt->instance; | |
715 if (!g_strcasecmp(zt->recipient, "*")) | |
716 notice.z_recipient = zephyr_normalize(""); | |
717 else | |
718 notice.z_recipient = zephyr_normalize(zt->recipient); | |
719 notice.z_sender = 0; | |
720 notice.z_default_format = | |
721 "Class $class, Instance $instance:\n" | |
722 "To: @bold($recipient) at $time $date\n" | |
723 "From: @bold($1) <$sender>\n\n$2"; | |
724 notice.z_message_len = strlen(im) + strlen(sig) + 4; | |
725 notice.z_message = buf; | |
726 ZSendNotice(¬ice, ZAUTH); | |
727 g_free(buf); | |
728 } | |
548 | 729 |
549 static void zephyr_send_im(struct gaim_connection *gc, char *who, char *im, int away) { | 730 static void zephyr_send_im(struct gaim_connection *gc, char *who, char *im, int away) { |
550 ZNotice_t notice; | 731 ZNotice_t notice; |
551 char *buf; | 732 char *buf; |
552 char *sig; | 733 char *sig; |
641 m = g_list_append(m, "Hidden"); | 822 m = g_list_append(m, "Hidden"); |
642 | 823 |
643 return m; | 824 return m; |
644 } | 825 } |
645 | 826 |
827 static void zephyr_draw_jc(struct gaim_connection *gc, GtkWidget *vbox) { | |
828 GtkWidget *label; | |
829 GtkWidget *rowbox; | |
830 | |
831 rowbox = gtk_hbox_new(FALSE, 5); | |
832 gtk_box_pack_start(GTK_BOX(vbox), rowbox, FALSE, FALSE, 0); | |
833 | |
834 label = gtk_label_new(_("Class:")); | |
835 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 5); | |
836 gtk_widget_show(label); | |
837 | |
838 class_entry = gtk_entry_new(); | |
839 gtk_box_pack_end(GTK_BOX(rowbox), class_entry, FALSE, FALSE, 5); | |
840 gtk_widget_show(class_entry); | |
841 | |
842 gtk_widget_show(rowbox); | |
843 | |
844 rowbox = gtk_hbox_new(FALSE, 5); | |
845 gtk_box_pack_start(GTK_BOX(vbox), rowbox, FALSE, FALSE, 0); | |
846 | |
847 label = gtk_label_new(_("Instance:")); | |
848 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 5); | |
849 gtk_widget_show(label); | |
850 | |
851 inst_entry = gtk_entry_new(); | |
852 gtk_box_pack_end(GTK_BOX(rowbox), inst_entry, FALSE, FALSE, 5); | |
853 gtk_widget_show(inst_entry); | |
854 | |
855 gtk_widget_show(rowbox); | |
856 | |
857 rowbox = gtk_hbox_new(FALSE, 5); | |
858 gtk_box_pack_start(GTK_BOX(vbox), rowbox, FALSE, FALSE, 0); | |
859 | |
860 label = gtk_label_new(_("Recipient:")); | |
861 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 5); | |
862 gtk_widget_show(label); | |
863 | |
864 recip_entry = gtk_entry_new(); | |
865 gtk_box_pack_end(GTK_BOX(rowbox), recip_entry, FALSE, FALSE, 5); | |
866 gtk_widget_show(recip_entry); | |
867 | |
868 gtk_widget_show(rowbox); | |
869 } | |
870 | |
871 static void zephyr_join_chat(struct gaim_connection *gc, int id, char *nm) | |
872 { | |
873 ZSubscription_t sub; | |
874 zephyr_triple *zt1, *zt2; | |
875 char *classname; | |
876 char *instname; | |
877 char *recip; | |
878 char **splitted; | |
879 | |
880 if (!nm) { | |
881 splitted = NULL; | |
882 classname = gtk_entry_get_text(GTK_ENTRY(class_entry)); | |
883 instname = gtk_entry_get_text(GTK_ENTRY(inst_entry)); | |
884 recip = gtk_entry_get_text(GTK_ENTRY(recip_entry)); | |
885 if (!g_strcasecmp(recip, "%me%")) | |
886 recip = g_getenv("USER"); | |
887 } else { | |
888 splitted = g_strsplit(nm, ",", 3); | |
889 if (!splitted[0] || !splitted[1] || !splitted[2]) { | |
890 g_strfreev(splitted); | |
891 return; | |
892 } | |
893 classname = g_strstrip(splitted[0]); | |
894 instname = g_strstrip(splitted[1]); | |
895 recip = g_strstrip(splitted[2]); | |
896 } | |
897 | |
898 zt1 = new_triple(classname, instname, recip); | |
899 if (splitted) | |
900 g_strfreev(splitted); | |
901 zt2 = find_sub_by_triple(zt1); | |
902 if (zt2) { | |
903 free_triple(zt1); | |
904 if (!zt2->open) | |
905 serv_got_joined_chat(gc, zt2->id, zt2->name); | |
906 return; | |
907 } | |
908 | |
909 sub.zsub_class = zt1->class; | |
910 sub.zsub_classinst = zt1->instance; | |
911 sub.zsub_recipient = zt1->recipient; | |
912 | |
913 if (ZSubscribeTo(&sub, 1, 0) != ZERR_NONE) { | |
914 free_triple(zt1); | |
915 return; | |
916 } | |
917 | |
918 subscrips = g_slist_append(subscrips, zt1); | |
919 zt1->open = TRUE; | |
920 serv_got_joined_chat(gc, zt1->id, zt1->name); | |
921 } | |
922 | |
923 static void zephyr_chat_leave(struct gaim_connection *gc, int id) | |
924 { | |
925 zephyr_triple *zt; | |
926 zt = find_sub_by_id(id); | |
927 if (zt) { | |
928 zt->open = FALSE; | |
929 zt->id = ++last_id; | |
930 } | |
931 } | |
932 | |
646 static struct prpl *my_protocol = NULL; | 933 static struct prpl *my_protocol = NULL; |
647 | 934 |
648 void zephyr_init(struct prpl *ret) | 935 void zephyr_init(struct prpl *ret) |
649 { | 936 { |
650 ret->protocol = PROTO_ZEPHYR; | 937 ret->protocol = PROTO_ZEPHYR; |
657 ret->get_info = zephyr_zloc; | 944 ret->get_info = zephyr_zloc; |
658 ret->normalize = zephyr_normalize; | 945 ret->normalize = zephyr_normalize; |
659 ret->buddy_menu = zephyr_buddy_menu; | 946 ret->buddy_menu = zephyr_buddy_menu; |
660 ret->away_states = zephyr_away_states; | 947 ret->away_states = zephyr_away_states; |
661 ret->set_away = zephyr_set_away; | 948 ret->set_away = zephyr_set_away; |
949 ret->draw_join_chat = zephyr_draw_jc; | |
950 ret->join_chat = zephyr_join_chat; | |
951 ret->chat_send = zephyr_chat_send; | |
952 ret->chat_leave = zephyr_chat_leave; | |
662 | 953 |
663 my_protocol = ret; | 954 my_protocol = ret; |
664 } | 955 } |
665 | 956 |
666 char *gaim_plugin_init(GModule *handle) | 957 char *gaim_plugin_init(GModule *handle) |