changeset 2717:03bf072c6238

[gaim-migrate @ 2730] these are changes i made, all by myself. aren't you impressed. mid's going to change around im.c here in a minute anyway. committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Wed, 14 Nov 2001 19:21:20 +0000
parents 48274976c79b
children 757688c301b5
files src/protocols/oscar/aim.h src/protocols/oscar/aim_internal.h src/protocols/oscar/ft.c src/protocols/oscar/im.c src/protocols/oscar/oscar.c
diffstat 5 files changed, 240 insertions(+), 82 deletions(-) [+]
line wrap: on
line diff
--- a/src/protocols/oscar/aim.h	Wed Nov 14 10:48:08 2001 +0000
+++ b/src/protocols/oscar/aim.h	Wed Nov 14 19:21:20 2001 +0000
@@ -801,9 +801,11 @@
 faim_export fu16_t aim_iconsum(const fu8_t *buf, int buflen);
 faim_export int aim_send_im_direct(aim_session_t *, aim_conn_t *, const char *msg);
 faim_export const char *aim_directim_getsn(aim_conn_t *conn);
-faim_export aim_conn_t *aim_directim_initiate(aim_session_t *, aim_conn_t *, const char *destsn);
+faim_export aim_conn_t *aim_directim_initiate(aim_session_t *, const char *destsn);
 faim_export aim_conn_t *aim_directim_connect(aim_session_t *, const char *sn, const char *addr, const fu8_t *cookie);
 
+faim_export aim_conn_t *aim_sendfile_initiate(aim_session_t *, const char *destsn, const char *filename, fu16_t numfiles, fu32_t totsize);
+
 faim_export aim_conn_t *aim_getfile_initiate(aim_session_t *sess, aim_conn_t *conn, const char *destsn);
 faim_export int aim_oft_getfile_request(aim_session_t *sess, aim_conn_t *conn, const char *name, int size);
 faim_export int aim_oft_getfile_ack(aim_session_t *sess, aim_conn_t *conn);
--- a/src/protocols/oscar/aim_internal.h	Wed Nov 14 10:48:08 2001 +0000
+++ b/src/protocols/oscar/aim_internal.h	Wed Nov 14 19:21:20 2001 +0000
@@ -203,6 +203,8 @@
 
 faim_internal void faimdprintf(aim_session_t *sess, int dlevel, const char *format, ...);
 
+faim_internal int aim_request_directim(aim_session_t *sess, const char *destsn, fu8_t *ip, fu16_t port, fu8_t *ckret);
+faim_internal int aim_request_sendfile(aim_session_t *sess, const char *sn, const char *filename, fu16_t numfiles, fu32_t totsize, fu8_t *ip, fu16_t port, fu8_t *ckret);
 faim_internal void aim_conn_close_rend(aim_session_t *sess, aim_conn_t *conn);
 faim_internal void aim_conn_kill_rend(aim_session_t *sess, aim_conn_t *conn);
 
--- a/src/protocols/oscar/ft.c	Wed Nov 14 10:48:08 2001 +0000
+++ b/src/protocols/oscar/ft.c	Wed Nov 14 19:21:20 2001 +0000
@@ -190,10 +190,6 @@
 	return 0;
 } 
 
-/* XXX: give the client author the responsibility of setting up a
- * listener, then we no longer have a libfaim problem with broken
- * solaris *innocent smile* -jbm */
-
 static int getlocalip(fu8_t *ip)
 {
 	struct hostent *hptr;
@@ -213,79 +209,6 @@
 	return 0;
 }
 
-/* XXX this should probably go in im.c */
-static int aim_request_directim(aim_session_t *sess, aim_conn_t *conn, const char *destsn, fu8_t *ip, fu16_t port, fu8_t *ckret)
-{
-	fu8_t ck[8];
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	aim_tlvlist_t *tl = NULL, *itl = NULL;
-	int hdrlen, i;
-	fu8_t *hdr;
-	aim_bstream_t hdrbs;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 256+strlen(destsn))))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
-
-	/* 
-	 * Generate a random message cookie 
-	 *
-	 * This cookie needs to be alphanumeric and NULL-terminated to be 
-	 * TOC-compatible.
-	 *
-	 * XXX have I mentioned these should be generated in msgcookie.c?
-	 *
-	 */
-	for (i = 0; i < 7; i++)
-	       	ck[i] = 0x30 + ((fu8_t) rand() % 10);
-	ck[7] = '\0';
-
-	if (ckret)
-		memcpy(ckret, ck, 8);
-
-	/* Cookie */
-	aimbs_putraw(&fr->data, ck, 8);
-
-	/* Channel */
-	aimbs_put16(&fr->data, 0x0002);
-
-	/* Destination SN */
-	aimbs_put8(&fr->data, strlen(destsn));
-	aimbs_putraw(&fr->data, destsn, strlen(destsn));
-
-	aim_addtlvtochain_noval(&tl, 0x0003);
-
-	hdrlen = 2+8+16+6+8+6+4;
-	hdr = malloc(hdrlen);
-	aim_bstream_init(&hdrbs, hdr, hdrlen);
-
-	aimbs_put16(&hdrbs, 0x0000);
-	aimbs_putraw(&hdrbs, ck, 8);
-	aim_putcap(&hdrbs, AIM_CAPS_IMIMAGE);
-
-	aim_addtlvtochain16(&itl, 0x000a, 0x0001);
-	aim_addtlvtochain_raw(&itl, 0x0003, 4, ip);
-	aim_addtlvtochain16(&itl, 0x0005, port);
-	aim_addtlvtochain_noval(&itl, 0x000f);
-	
-	aim_writetlvchain(&hdrbs, &itl);
-
-	aim_addtlvtochain_raw(&tl, 0x0005, aim_bstream_curpos(&hdrbs), hdr);
-
-	aim_writetlvchain(&fr->data, &tl);
-
-	free(hdr);
-	aim_freetlvchain(&itl);
-	aim_freetlvchain(&tl);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
 /**
  * aim_directim_intitiate - For those times when we want to open up the directim channel ourselves.
  * @sess: your session,
@@ -294,7 +217,7 @@
  * @destsn: the SN to connect to.
  *
  */
-faim_export aim_conn_t *aim_directim_initiate(aim_session_t *sess, aim_conn_t *conn, const char *destsn)
+faim_export aim_conn_t *aim_directim_initiate(aim_session_t *sess, const char *destsn)
 { 
 	aim_conn_t *newconn;
 	aim_msgcookie_t *cookie;
@@ -310,7 +233,7 @@
 	if ((listenfd = listenestablish(port)) == -1)
 		return NULL;
 
-	aim_request_directim(sess, conn, destsn, localip, port, ck);
+	aim_request_directim(sess, destsn, localip, port, ck);
 
 	cookie = (aim_msgcookie_t *)calloc(1, sizeof(aim_msgcookie_t));
 	memcpy(cookie->cookie, ck, 8);
@@ -344,7 +267,67 @@
 	faimdprintf(sess, 2,"faim: listening (fd = %d, unconnected)\n", newconn->fd);
 
 	return newconn;
-} 
+}
+
+/**
+ * aim_sendfile_intitiate - For those times when we want to send the file ourselves.
+ * @sess: your session,
+ * @conn: the BOS conn,
+ * @destsn: the SN to connect to.
+ * @filename: the name of the files you want to send
+ *
+ */
+faim_export aim_conn_t *aim_sendfile_initiate(aim_session_t *sess, const char *destsn, const char *filename, fu16_t numfiles, fu32_t totsize)
+{ 
+	aim_conn_t *newconn;
+	aim_msgcookie_t *cookie;
+	struct aim_directim_intdata *priv;
+	int listenfd;
+	fu16_t port = 4443;
+	fu8_t localip[4];
+	fu8_t ck[8];
+
+	if (getlocalip(localip) == -1)
+		return NULL;
+
+	if ((listenfd = listenestablish(port)) == -1)
+		return NULL;
+
+	aim_request_sendfile(sess, destsn, filename, numfiles, totsize, localip, port, ck);
+
+	cookie = (aim_msgcookie_t *)calloc(1, sizeof(aim_msgcookie_t));
+	memcpy(cookie->cookie, ck, 8);
+	cookie->type = AIM_COOKIETYPE_OFTIM;
+
+	/* this one is for the cookie */
+	priv = (struct aim_directim_intdata *)calloc(1, sizeof(struct aim_directim_intdata));
+
+	memcpy(priv->cookie, ck, 8);
+	strncpy(priv->sn, destsn, sizeof(priv->sn));
+	cookie->data = priv;
+	aim_cachecookie(sess, cookie);
+
+	/* XXX switch to aim_cloneconn()? */
+	if (!(newconn = aim_newconn(sess, AIM_CONN_TYPE_RENDEZVOUS_OUT, NULL))) {
+		close(listenfd);
+		return NULL;
+	}
+
+	/* this one is for the conn */
+	priv = (struct aim_directim_intdata *)calloc(1, sizeof(struct aim_directim_intdata));
+
+	memcpy(priv->cookie, ck, 8);
+	strncpy(priv->sn, destsn, sizeof(priv->sn));
+
+	newconn->fd = listenfd;
+	newconn->subtype = AIM_CONN_SUBTYPE_OFT_SENDFILE;
+	newconn->internal = priv;
+	newconn->lastactivity = time(NULL);
+
+	faimdprintf(sess, 2,"faim: listening (fd = %d, unconnected)\n", newconn->fd);
+
+	return newconn;
+}
 
 #if 0
 /**
@@ -776,6 +759,9 @@
  *
  * you need to call accept() when it's connected. returns your fd 
  *
+ * XXX: give the client author the responsibility of setting up a
+ * listener, then we no longer have a libfaim problem with broken
+ * solaris *innocent smile* -jbm
  */
 static int listenestablish(fu16_t portnum)
 {
--- a/src/protocols/oscar/im.c	Wed Nov 14 10:48:08 2001 +0000
+++ b/src/protocols/oscar/im.c	Wed Nov 14 19:21:20 2001 +0000
@@ -449,6 +449,174 @@
 	return 0;
 }
 
+faim_internal int aim_request_directim(aim_session_t *sess, const char *destsn, fu8_t *ip, fu16_t port, fu8_t *ckret)
+{
+	aim_conn_t *conn;
+	fu8_t ck[8];
+	aim_frame_t *fr;
+	aim_snacid_t snacid;
+	aim_tlvlist_t *tl = NULL, *itl = NULL;
+	int hdrlen, i;
+	fu8_t *hdr;
+	aim_bstream_t hdrbs;
+
+	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
+		return -EINVAL;
+
+	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 256+strlen(destsn))))
+		return -ENOMEM;
+
+	snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);
+	aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
+
+	/* 
+	 * Generate a random message cookie 
+	 *
+	 * This cookie needs to be alphanumeric and NULL-terminated to be 
+	 * TOC-compatible.
+	 *
+	 * XXX have I mentioned these should be generated in msgcookie.c?
+	 *
+	 */
+	for (i = 0; i < 7; i++)
+	       	ck[i] = 0x30 + ((fu8_t) rand() % 10);
+	ck[7] = '\0';
+
+	if (ckret)
+		memcpy(ckret, ck, 8);
+
+	/* Cookie */
+	aimbs_putraw(&fr->data, ck, 8);
+
+	/* Channel */
+	aimbs_put16(&fr->data, 0x0002);
+
+	/* Destination SN */
+	aimbs_put8(&fr->data, strlen(destsn));
+	aimbs_putraw(&fr->data, destsn, strlen(destsn));
+
+	aim_addtlvtochain_noval(&tl, 0x0003);
+
+	hdrlen = 2+8+16+6+8+6+4;
+	hdr = malloc(hdrlen);
+	aim_bstream_init(&hdrbs, hdr, hdrlen);
+
+	aimbs_put16(&hdrbs, 0x0000);
+	aimbs_putraw(&hdrbs, ck, 8);
+	aim_putcap(&hdrbs, AIM_CAPS_IMIMAGE);
+
+	aim_addtlvtochain16(&itl, 0x000a, 0x0001);
+	aim_addtlvtochain_raw(&itl, 0x0003, 4, ip);
+	aim_addtlvtochain16(&itl, 0x0005, port);
+	aim_addtlvtochain_noval(&itl, 0x000f);
+	
+	aim_writetlvchain(&hdrbs, &itl);
+
+	aim_addtlvtochain_raw(&tl, 0x0005, aim_bstream_curpos(&hdrbs), hdr);
+
+	aim_writetlvchain(&fr->data, &tl);
+
+	free(hdr);
+	aim_freetlvchain(&itl);
+	aim_freetlvchain(&tl);
+
+	aim_tx_enqueue(sess, fr);
+
+	return 0;
+}
+
+faim_internal int aim_request_sendfile(aim_session_t *sess, const char *sn, const char *filename, fu16_t numfiles, fu32_t totsize, fu8_t *ip, fu16_t port, fu8_t *ckret)
+{
+	aim_conn_t *conn;
+	int i;
+	fu8_t ck[8];
+	aim_frame_t *fr;
+	aim_snacid_t snacid;
+
+	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
+		return -EINVAL;
+
+	if (!sn || !filename)
+		return -EINVAL;
+
+	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+8+2+1+strlen(sn)+2+2+2+8+16+6+8+6+4+2+2+2+2+4+strlen(filename)+4)))
+		return -ENOMEM;
+
+	snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);
+	aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
+
+	for (i = 0; i < 7; i++)
+		aimutil_put8(ck+i, 0x30 + ((fu8_t) rand() % 10));
+	ck[7] = '\0';
+
+	if (ckret)
+		memcpy(ckret, ck, 8);
+
+	/*
+	 * Cookie
+	 */
+	aimbs_putraw(&fr->data, ck, 8);
+
+	/*
+	 * Channel (2)
+	 */
+	aimbs_put16(&fr->data, 0x0002);
+
+	/*
+	 * Dest sn
+	 */
+	aimbs_put8(&fr->data, strlen(sn));
+	aimbs_putraw(&fr->data, sn, strlen(sn));
+
+	/*
+	 * TLV t(0005)
+	 *
+	 * Encompasses everything below. Gee.
+	 */
+	aimbs_put16(&fr->data, 0x0005);
+	aimbs_put16(&fr->data, 2+8+16+6+8+6+4+2+2+2+2+4+strlen(filename)+4);
+
+	aimbs_put16(&fr->data, 0x0000);
+	aimbs_putraw(&fr->data, ck, 8);
+	aim_putcap(&fr->data, AIM_CAPS_SENDFILE);
+
+	/* TLV t(000a) */
+	aimbs_put16(&fr->data, 0x000a);
+	aimbs_put16(&fr->data, 0x0002);
+	aimbs_put16(&fr->data, 0x0001);
+
+	/* TLV t(0003) (IP) */
+	aimbs_put16(&fr->data, 0x0003);
+	aimbs_put16(&fr->data, 0x0004);
+	aimbs_putraw(&fr->data, ip, 4);
+
+	/* TLV t(0005) (port) */
+	aimbs_put16(&fr->data, 0x0005);
+	aimbs_put16(&fr->data, 0x0002);
+	aimbs_put16(&fr->data, port);
+
+	/* TLV t(000f) */
+	aimbs_put16(&fr->data, 0x000f);
+	aimbs_put16(&fr->data, 0x0000);
+
+	/* TLV t(2711) */
+	aimbs_put16(&fr->data, 0x2711);
+	aimbs_put16(&fr->data, 2+2+4+strlen(filename)+4);
+
+	/* ? */
+	aimbs_put16(&fr->data, 0x0001);
+	aimbs_put16(&fr->data, numfiles);
+	aimbs_put32(&fr->data, totsize);
+	aimbs_putraw(&fr->data, filename, strlen(filename));
+
+	/* ? */
+	aimbs_put32(&fr->data, 0x00000000);
+
+	aim_tx_enqueue(sess, fr);
+
+	return 0;
+}
+
 static int outgoingim(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
 {
 	int i, ret = 0;
--- a/src/protocols/oscar/oscar.c	Wed Nov 14 10:48:08 2001 +0000
+++ b/src/protocols/oscar/oscar.c	Wed Nov 14 19:21:20 2001 +0000
@@ -2588,7 +2588,7 @@
 	dim->gc = gc;
 	g_snprintf(dim->name, sizeof dim->name, "%s", data->who);
 
-	dim->conn = aim_directim_initiate(od->sess, od->conn, data->who);
+	dim->conn = aim_directim_initiate(od->sess, data->who);
 	if (dim->conn != NULL) {
 		od->direct_ims = g_slist_append(od->direct_ims, dim);
 		dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ,