diff -r a01c1a568878 -r faf919a930fb plugins/zephyr/zephyr.c
--- a/plugins/zephyr/zephyr.c Sun Apr 15 03:47:50 2001 +0000
+++ b/plugins/zephyr/zephyr.c Sun Apr 15 22:48:11 2001 +0000
@@ -63,6 +63,7 @@
static guint32 nottimer = 0;
static guint32 loctimer = 0;
struct gaim_connection *zgc = NULL;
+static GList *pending_zloc_names = NULL;
/* just for debugging
static void handle_unknown(ZNotice_t notice)
@@ -81,6 +82,59 @@
}
*/
+static char *zephyr_normalize(const char *orig)
+{
+ static char buf[80];
+ if (strchr(orig, '@')) {
+ g_snprintf(buf, 80, "%s", orig);
+ } else {
+ g_snprintf(buf, 80, "%s@%s", orig, ZGetRealm());
+ }
+ return buf;
+}
+
+static gboolean pending_zloc(char *who)
+{
+ GList *curr;
+ for (curr = pending_zloc_names; curr != NULL; curr = curr->next) {
+ if (!g_strcasecmp(who, (char*)curr->data)) {
+ g_free((char*)curr->data);
+ pending_zloc_names = g_list_remove(pending_zloc_names, curr->data);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static void zephyr_zloc(struct gaim_connection *gc, char *who)
+{
+ ZAsyncLocateData_t ald;
+
+ if (ZRequestLocations(zephyr_normalize(who), &ald, UNACKED, ZAUTH)
+ != ZERR_NONE) {
+ return;
+ }
+ pending_zloc_names = g_list_append(pending_zloc_names,
+ g_strdup(zephyr_normalize(who)));
+}
+
+static void info_callback(GtkObject *obj, char *who)
+{
+ zephyr_zloc(gtk_object_get_user_data(obj), who);
+}
+
+static void zephyr_buddy_menu(GtkWidget *menu, struct gaim_connection *gc, char *who)
+{
+ GtkWidget *button;
+
+ button = gtk_menu_item_new_with_label(_("ZLocate"));
+ gtk_signal_connect(GTK_OBJECT(button), "activate",
+ GTK_SIGNAL_FUNC(info_callback), who);
+ gtk_object_set_user_data(GTK_OBJECT(button), gc);
+ gtk_menu_append(GTK_MENU(menu), button);
+ gtk_widget_show(button);
+}
+
static void handle_message(ZNotice_t notice, struct sockaddr_in from)
{
if (!g_strcasecmp(notice.z_class, LOGIN_CLASS)) {
@@ -102,6 +156,24 @@
free(user);
return;
}
+ if (pending_zloc(b->name)) {
+ ZLocations_t locs;
+ int one = 1;
+ GString *str = g_string_new("");
+ g_string_sprintfa(str, "User: %s
"
+ "Alias: %s
",
+ b->name, b->show);
+ if (!nlocs) {
+ g_string_sprintfa(str, "
Hidden or not logged-in");
+ }
+ for (; nlocs > 0; nlocs--) {
+ ZGetLocations(&locs, &one);
+ g_string_sprintfa(str, "
At %s since %s", locs.host,
+ locs.time);
+ }
+ g_show_info_text(str->str);
+ g_string_free(str, TRUE);
+ }
serv_got_update(zgc, b->name, nlocs, 0, 0, 0, 0, 0);
free(user);
@@ -161,10 +233,7 @@
while (m) {
struct buddy *b = m->data;
char *chk;
- if (!strchr(b->name, '@'))
- chk = g_strdup_printf("%s@%s", b->name, ZGetRealm());
- else
- chk = g_strdup(b->name);
+ chk = g_strdup(zephyr_normalize(b->name));
/* doesn't matter if this fails or not; we'll just move on to the next one */
ZRequestLocations(chk, &ald, UNACKED, ZAUTH);
g_free(chk);
@@ -204,6 +273,50 @@
g_strchomp(str);
}
+static void process_zsubs()
+{
+ FILE *f;
+ gchar *fname;
+ gchar buff[BUFSIZ];
+
+ fname = g_strdup_printf("%s/.zephyr.subs", g_getenv("HOME"));
+ f = fopen(fname, "r");
+ if (f) {
+ char **triple;
+ ZSubscription_t sub;
+ char *recip;
+ while (fgets(buff, BUFSIZ, f)) {
+ strip_comments(buff);
+ if (buff[0]) {
+ triple = g_strsplit(buff, ",", 3);
+ if (triple[0] && triple[1] && triple[2]) {
+ sub.zsub_class = triple[0];
+ sub.zsub_classinst = triple[1];
+ if (!g_strcasecmp(triple[2], "%me%")) {
+ recip = g_strdup_printf("%s@%s", g_getenv("USER"),
+ ZGetRealm());
+ } else if (!g_strcasecmp(triple[2], "*")) {
+ /* wildcard */
+ recip = g_strdup_printf("@%s", ZGetRealm());
+ } else {
+ recip = g_strdup(triple[2]);
+ }
+ sub.zsub_recipient = recip;
+ if (ZSubscribeTo(&sub, 1, 0) != ZERR_NONE) {
+ debug_printf("Zephyr: Couldn't subscribe to %s, %s, "
+ "%s\n",
+ sub.zsub_class,
+ sub.zsub_classinst,
+ sub.zsub_recipient);
+ }
+ g_free(recip);
+ }
+ g_strfreev(triple);
+ }
+ }
+ }
+}
+
static void process_anyone()
{
FILE *fd;
@@ -241,7 +354,9 @@
sub.zsub_recipient = ZGetSender();
/* we don't care if this fails. i'm lying right now. */
- ZSubscribeTo(&sub, 1, 0);
+ if (ZSubscribeTo(&sub, 1, 0) != ZERR_NONE) {
+ debug_printf("Zephyr: Couldn't subscribe to messages!\n");
+ }
account_online(zgc);
serv_finish_login(zgc);
@@ -249,7 +364,9 @@
if (bud_list_cache_exists(zgc))
do_import(NULL, zgc);
process_anyone();
- /* should also process .zephyr.subs */
+ /* call process_zsubs to subscribe. still commented out since I don't know
+ * how you want to handle incoming msgs from subs.
+ process_zsubs(); */
nottimer = gtk_timeout_add(100, check_notify, NULL);
loctimer = gtk_timeout_add(2000, check_loc, NULL);
@@ -257,6 +374,8 @@
static void zephyr_close(struct gaim_connection *gc)
{
+ g_list_foreach(pending_zloc_names, (GFunc)g_free, NULL);
+ g_list_free(pending_zloc_names);
/* should probably write .anyone, but eh. we all use gaim exclusively, right? :-P */
if (nottimer)
gtk_timeout_remove(nottimer);
@@ -275,6 +394,14 @@
static void zephyr_send_im(struct gaim_connection *gc, char *who, char *im, int away) {
ZNotice_t notice;
+ char *buf;
+ char *sig;
+
+ sig = ZGetVariable("zwrite-signature");
+ if (!sig) {
+ sig = g_get_real_name();
+ }
+ buf = g_strdup_printf("%s%c%s", sig, '\0', im);
bzero((char *)¬ice, sizeof(notice));
notice.z_kind = ACKED;
@@ -285,10 +412,13 @@
notice.z_sender = 0;
notice.z_recipient = who;
notice.z_default_format =
- "Class $class, Instance $instance:\nTo: @bold($recipient) at $time $date\n$message";
- notice.z_message_len = strlen(im) + 1;
- notice.z_message = im;
+ "Class $class, Instance $instance:\n"
+ "To: @bold($recipient) at $time $date\n"
+ "From: @bold($1) <$sender>\n\n$2";
+ notice.z_message_len = strlen(im) + strlen(sig) + 4;
+ notice.z_message = buf;
ZSendNotice(¬ice, ZAUTH);
+ g_free(buf);
}
static struct prpl *my_protocol = NULL;
@@ -302,6 +432,9 @@
ret->add_buddy = zephyr_add_buddy;
ret->remove_buddy = zephyr_remove_buddy;
ret->send_im = zephyr_send_im;
+ ret->get_info = zephyr_zloc;
+ ret->normalize = zephyr_normalize;
+ ret->buddy_menu = zephyr_buddy_menu;
my_protocol = ret;
}