changeset 3109:51f49dcbd14b

[gaim-migrate @ 3123] Mark Doliner fixed idle times. Thanks, Mark. committer: Tailor Script <tailor@pidgin.im>
author Sean Egan <seanegan@gmail.com>
date Fri, 29 Mar 2002 04:08:41 +0000
parents 592e6adf68c8
children 13e5dc68efbc
files ChangeLog src/protocols/oscar/aim.h src/protocols/oscar/oscar.c src/protocols/oscar/ssi.c
diffstat 4 files changed, 125 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Mar 29 04:05:03 2002 +0000
+++ b/ChangeLog	Fri Mar 29 04:08:41 2002 +0000
@@ -18,6 +18,7 @@
 	* HTTP Proxy settings now HTTP compliant (Thanks Robert McQueen)	
 	* Speling corections (Thanks Tero Kuusela)
 	* Oscar list icon fixes (Thanks Mark Doliner)
+	* Oscar idle times work again (Thanks Mark Doliner)
 
 version 0.54 (03/14/2002):
 	* Compiles without GdkPixbuf again
--- a/src/protocols/oscar/aim.h	Fri Mar 29 04:05:03 2002 +0000
+++ b/src/protocols/oscar/aim.h	Fri Mar 29 04:08:41 2002 +0000
@@ -1016,6 +1016,7 @@
 	struct aim_ssi_item *next;
 };
 
+/* These build the actual SNACs and queue them to be sent */
 faim_export int aim_ssi_reqrights(aim_session_t *sess, aim_conn_t *conn);
 faim_export int aim_ssi_reqdata(aim_session_t *sess, aim_conn_t *conn, time_t localstamp, fu16_t localrev);
 faim_export int aim_ssi_enable(aim_session_t *sess, aim_conn_t *conn);
@@ -1023,9 +1024,11 @@
 faim_export int aim_ssi_modbegin(aim_session_t *sess, aim_conn_t *conn);
 faim_export int aim_ssi_modend(aim_session_t *sess, aim_conn_t *conn);
 
+/* These handle the local variables */
 faim_export int aim_ssi_inlist(aim_session_t *sess, aim_conn_t *conn, char *name, fu16_t type);
 faim_export char *aim_ssi_getparentgroup(aim_session_t *sess, aim_conn_t *conn, char *name);
-/* faim_export int aim_ssi_getpermdeny(aim_tlvlist_t *tlvlist); */
+faim_export int aim_ssi_getpermdeny(aim_session_t *sess, aim_conn_t *conn);
+faim_export fu32_t aim_ssi_getpresence(aim_session_t *sess, aim_conn_t *conn);
 faim_export int aim_ssi_cleanlist(aim_session_t *sess, aim_conn_t *conn);
 faim_export int aim_ssi_addbuddies(aim_session_t *sess, aim_conn_t *conn, char *gn, char **sn, unsigned int num);
 faim_export int aim_ssi_addmastergroup(aim_session_t *sess, aim_conn_t *conn);
@@ -1037,6 +1040,7 @@
 faim_export int aim_ssi_deletelist(aim_session_t *sess, aim_conn_t *conn);
 faim_export int aim_ssi_delpord(aim_session_t *sess, aim_conn_t *conn, char **sn, unsigned int num, fu16_t type);
 faim_export int aim_ssi_setpermdeny(aim_session_t *sess, aim_conn_t *conn, int permdeny);
+faim_export int aim_ssi_setpresence(aim_session_t *sess, aim_conn_t *conn, fu32_t presence);
 
 struct aim_icq_offlinemsg {
 	fu32_t sender;
--- a/src/protocols/oscar/oscar.c	Fri Mar 29 04:05:03 2002 +0000
+++ b/src/protocols/oscar/oscar.c	Fri Mar 29 04:08:41 2002 +0000
@@ -2251,8 +2251,11 @@
 
 	aim_reqservice(sess, fr->conn, AIM_CONN_TYPE_CHATNAV);
 
-	if (!odata->icq)
+	if (!odata->icq) {
+		debug_printf("ssi: requesting ssi list\n");
 		aim_ssi_reqrights(sess, fr->conn);
+		aim_ssi_reqdata(sess, fr->conn, sess->ssi.timestamp, sess->ssi.revision);
+	}
 
 	return 1;
 }
@@ -2781,9 +2784,6 @@
 
 	debug_printf("ssi rights: Max buddies = %d / Max groups = %d / Max permits = %d / Max denies = %d\n", maxbuddies, maxgroups, maxpermits, maxdenies);
 */
-	debug_printf("ssi: requesting ssi list\n");
-
-	aim_ssi_reqdata(sess, fr->conn, sess->ssi.timestamp, sess->ssi.revision);
 
 	return 1;
 }
@@ -2797,12 +2797,8 @@
 
 	debug_printf("ssi: syncing local list and server list\n");
 
-	if (odata->icq) {
-		/* Delete the buddy list */
-		debug_printf("ssi: using ICQ, removing ssi data\n");
-		aim_ssi_deletelist(sess, fr->conn);
+	if (odata->icq)
 		return 1;
-	}
 
 	/* Activate SSI */
 	debug_printf("ssi: activating server-stored buddy list\n");
@@ -2862,13 +2858,17 @@
 			case 0x0004: /* Permit/deny setting */
 				if (curitem->data) {
 					fu8_t permdeny;
-					if ((permdeny = aim_ssi_getpermdeny(curitem->data)) && (permdeny != gc->permdeny)) {
+					if ((permdeny = aim_ssi_getpermdeny(sess, fr->conn)) && (permdeny != gc->permdeny)) {
 						debug_printf("ssi: changing permdeny from %d to %d\n", gc->permdeny, permdeny);
 						gc->permdeny = permdeny;
 						tmp++;
 					}
 				}
 				break;
+
+			case 0x0005: /* Presence setting */
+				/* We don't want to change Gaim's setting because it applies to all accounts */
+				break;
 		} /* End of switch on curitem->type */
 	} /* End of for loop */
 	if (tmp)
@@ -2940,6 +2940,11 @@
 				free(sns);
 			}
 		}
+
+		/* Presence settings (idle time visibility) */
+		if ((tmp = aim_ssi_getpresence(sess, fr->conn)) != 0xFFFFFFFF)
+			if (report_idle && !(tmp & 0x400))
+				aim_ssi_setpresence(sess, fr->conn, tmp | 0x400);
 	}
 
 	return 1;
--- a/src/protocols/oscar/ssi.c	Fri Mar 29 04:05:03 2002 +0000
+++ b/src/protocols/oscar/ssi.c	Fri Mar 29 04:08:41 2002 +0000
@@ -51,19 +51,6 @@
 }
 
 /*
- * Returns the permit/deny byte
- * This should be removed and the byte should be passed directly to
- * the handler for x0006, along with all the buddies and other info.
- */
-faim_export int aim_ssi_getpermdeny(aim_tlvlist_t *tlvlist)
-{
-	aim_tlv_t *tlv;
-	if ((tlv = aim_gettlv(tlvlist, 0x00ca, 1)) && tlv->value)
-		return tlv->value[0];
-	return 0;
-}
-
-/*
  * Returns a pointer to an item with the given name and type, or NULL if one does not exist.
  */
 static struct aim_ssi_item *get_ssi_item(struct aim_ssi_item *items, char *name, fu16_t type)
@@ -73,7 +60,7 @@
 		for (cur=items; cur; cur=cur->next)
 			if ((cur->type == type) && (cur->name) && !(aim_sncmp(cur->name, name)))
 				return cur;
-	 } else { /* return the master group */
+	 } else { /* return the given type with gid 0 */
 		for (cur=items; cur; cur=cur->next)
 			if ((cur->type == type) && (cur->gid == 0x0000))
 				return cur;
@@ -82,6 +69,44 @@
 }
 
 /*
+ * Returns the permit/deny byte
+ */
+faim_export int aim_ssi_getpermdeny(aim_session_t *sess, aim_conn_t *conn)
+{
+	struct aim_ssi_item *cur = get_ssi_item(sess->ssi.items, NULL, AIM_SSI_TYPE_PDINFO);
+	if (cur) {
+		aim_tlvlist_t *tlvlist = cur->data;
+		if (tlvlist) {
+			aim_tlv_t *tlv = aim_gettlv(tlvlist, 0x00ca, 1);
+			if (tlv && tlv->value)
+				return aimutil_get8(tlv->value);
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * Returns the presence flag
+ * I'm pretty sure this is a bitmask, but really have no evidence for that.
+ * 0x00000400 - Show up as visible to others
+ */
+faim_export fu32_t aim_ssi_getpresence(aim_session_t *sess, aim_conn_t *conn)
+{
+	struct aim_ssi_item *cur = get_ssi_item(sess->ssi.items, NULL, AIM_SSI_TYPE_PRESENCEPREFS);
+	if (cur) {
+		aim_tlvlist_t *tlvlist = cur->data;
+		if (tlvlist) {
+			aim_tlv_t *tlv = aim_gettlv(tlvlist, 0x00c9, 1);
+			if (tlv && tlv->length)
+				return aimutil_get32(tlv->value);
+		}
+	}
+
+	return 0xFFFFFFFF;
+}
+
+/*
  * Add the given packet to the holding queue.
  */
 static int aim_ssi_enqueue(aim_session_t *sess, aim_conn_t *conn, aim_frame_t *fr)
@@ -809,7 +834,7 @@
 		return -EINVAL;
 
 	/* Look up the permit/deny settings item */
-	for (cur=sess->ssi.items; (cur && (cur->type!=AIM_SSI_TYPE_PDINFO)); cur=cur->next);
+	cur = get_ssi_item(sess->ssi.items, NULL, AIM_SSI_TYPE_PDINFO);
 
 	if (cur) {
 		/* The permit/deny item exists */
@@ -861,6 +886,70 @@
 }
 
 /*
+ * Stores your setting for whether you should show up as idle or not.
+ * presence is a bitmask (at least, I think so...)
+ * 0x00000400 if you want others to see your idle time
+ */
+faim_export int aim_ssi_setpresence(aim_session_t *sess, aim_conn_t *conn, fu32_t presence) {
+	struct aim_ssi_item *cur, *tmp;
+	fu16_t j;
+	aim_tlv_t *tlv;
+
+	if (!sess || !conn)
+		return -EINVAL;
+
+	/* Look up the item */
+	cur = get_ssi_item(sess->ssi.items, NULL, AIM_SSI_TYPE_PRESENCEPREFS);
+
+	if (cur) {
+		/* The item exists */
+		if (cur->data && (tlv = aim_gettlv(cur->data, 0x00c9, 1))) {
+			/* Just change the value of the x00c9 TLV */
+			if (tlv->length != 4) {
+				tlv->length = 4;
+				free(tlv->value);
+				tlv->value = (fu8_t *)malloc(4*sizeof(fu8_t));
+			}
+			aimutil_put32(tlv->value, presence);
+		} else {
+			/* Need to add the x00c9 TLV to the TLV chain */
+			aim_addtlvtochain32((aim_tlvlist_t**)&cur->data, 0x00c9, presence);
+		}
+
+		/* Send the mod item SNAC */
+		aim_ssi_addmoddel(sess, conn, &cur, 1, AIM_CB_SSI_MOD);
+	} else {
+		/* Need to add the item */
+		if (!(cur = (struct aim_ssi_item *)malloc(sizeof(struct aim_ssi_item))))
+			return -ENOMEM;
+		cur->name = NULL;
+		cur->gid = 0x0000;
+		cur->bid = 0x007a; /* XXX - Is this number significant? */
+		do {
+			cur->bid += 0x0001;
+			for (tmp=sess->ssi.items, j=0; ((tmp) && (!j)); tmp=tmp->next)
+				if (tmp->bid == cur->bid)
+					j=1;
+		} while (j);
+		cur->type = AIM_SSI_TYPE_PRESENCEPREFS;
+		cur->data = NULL;
+		aim_addtlvtochain32((aim_tlvlist_t**)&cur->data, 0x00c9, presence);
+
+		/* Add the item to our list */
+		cur->next = sess->ssi.items;
+		sess->ssi.items = cur;
+
+		/* Send the add item SNAC */
+		aim_ssi_addmoddel(sess, conn, &cur, 1, AIM_CB_SSI_ADD);
+	}
+
+	/* Begin sending SSI SNACs */
+	aim_ssi_dispatch(sess, conn);
+
+	return 0;
+}
+
+/*
  * Request SSI Rights.
  */
 faim_export int aim_ssi_reqrights(aim_session_t *sess, aim_conn_t *conn)