# HG changeset patch # User Eric Warmenhoven # Date 987374891 0 # Node ID 5800449e7ecc3ae87b10cfff89e82017aee33e9a # Parent 20f070721b9fddf073d982a359f8271c778d3852 [gaim-migrate @ 1729] patch by Neil Sanchala (nsanch). zlocating and signatures, as well as zephyr_normalize for all of its goodness. this is cool, zephyr might actually be useful now. committer: Tailor Script diff -r 20f070721b9f -r 5800449e7ecc 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; }