changeset 1719:5800449e7ecc

[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 <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Sun, 15 Apr 2001 22:48:11 +0000
parents 20f070721b9f
children 2ebbbffb043d
files plugins/zephyr/zephyr.c
diffstat 1 files changed, 142 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- 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, "<b>User:</b> %s<br>"
+								"<b>Alias:</b> %s<br>",
+								b->name, b->show);
+				if (!nlocs) {
+					g_string_sprintfa(str, "<br>Hidden or not logged-in");
+				}
+				for (; nlocs > 0; nlocs--) {
+					ZGetLocations(&locs, &one);
+					g_string_sprintfa(str, "<br>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 *)&notice, 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(&notice, 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;
 }