diff src/protocols/oscar/ft.c @ 5146:ac9ca88d4b25

[gaim-migrate @ 5510] I guess I'm gonna go ahead and commit this... I don't think there's any real functionality change. AIM file transfer might work a little better, I guess. I probably fixed a bug or two. Like, filenames>64 characters won't cause infinite loopage. Changed AIM file transfer a bit with the following two goals: -Move some code from oscar.c to libfaim. Should make it easier for 3rd parties to use libfaim for file transfer. -Allow for easier code reuse with "get file" (in the works) committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Thu, 17 Apr 2003 03:28:21 +0000
parents 6c02ee2b471d
children 2d9f7d2e3558
line wrap: on
line diff
--- a/src/protocols/oscar/ft.c	Thu Apr 17 01:20:22 2003 +0000
+++ b/src/protocols/oscar/ft.c	Thu Apr 17 03:28:21 2003 +0000
@@ -23,7 +23,7 @@
  *      number that we're listening on.
  *   2) The receiver connects to the sender on the given IP address 
  *      and port.  After the connection is established, the receiver 
- *      sends another ICBM signifying that we are ready and waiting.
+ *      sends an ICBM signifying that we are ready and waiting.
  *   3) The sender sends an OFT PROMPT message over the OFT 
  *      connection.
  *   4) The receiver of the file sends back an exact copy of this 
@@ -35,7 +35,8 @@
  *      until the entire file has been sent.
  *   6) The receiver knows the file is finished because the sender 
  *      sent the file size in an earlier OFT packet.  So then the 
- *      receiver sends the DONE thingy and closes the connection.
+ *      receiver sends the DONE thingy (after filling in the 
+ *      "received" checksum and size) and closes the connection.
  */
 
 #define FAIM_INTERNAL
@@ -521,9 +522,6 @@
  * will accept the pending connection and stop listening.
  *
  * @param sess The session
- * @param conn The BOS conn.
- * @param priv A dummy priv value (we'll let it get filled in later)
- *             (if you pass a %NULL, we alloc one).
  * @param sn The screen name to connect to.
  * @return The new connection.
  */
@@ -598,9 +596,8 @@
 	if (!sess || !sn)
 		return NULL;
 
-	if (!(intdata = malloc(sizeof(struct aim_odc_intdata))))
+	if (!(intdata = calloc(1, sizeof(struct aim_odc_intdata))))
 		return NULL;
-	memset(intdata, 0, sizeof(struct aim_odc_intdata));
 	memcpy(intdata->cookie, cookie, 8);
 	strncpy(intdata->sn, sn, sizeof(intdata->sn));
 	if (addr)
@@ -703,6 +700,78 @@
 	return ret;
 }
 
+faim_export struct aim_oft_info *aim_oft_createinfo(aim_session_t *sess, const fu8_t *cookie, const char *sn, const char *ip, fu16_t port, fu32_t size, fu32_t modtime, char *filename)
+{
+	struct aim_oft_info *new;
+
+	if (!sess)
+		return NULL;
+
+	if (!(new = (struct aim_oft_info *)calloc(1, sizeof(struct aim_oft_info))))
+		return NULL;
+
+	new->sess = sess;
+	if (cookie)
+		memcpy(new->cookie, cookie, 8);
+	if (ip)
+		new->clientip = strdup(ip);
+	if (sn)
+		new->sn = strdup(sn);
+	new->port = port;
+	new->fh.totfiles = 1;
+	new->fh.filesleft = 1;
+	new->fh.totparts = 1;
+	new->fh.partsleft = 1;
+	new->fh.totsize = size;
+	new->fh.size = size;
+	new->fh.modtime = modtime;
+	new->fh.checksum = 0xffff0000;
+	new->fh.rfrcsum = 0xffff0000;
+	new->fh.rfcsum = 0xffff0000;
+	new->fh.recvcsum = 0xffff0000;
+	strncpy(new->fh.idstring, "OFT_Windows ICBMFT V1.1 32", 31);
+	if (filename)
+		strncpy(new->fh.name, filename, 63);
+
+	new->next = sess->oft_info;
+	sess->oft_info = new;
+
+	return new;
+}
+
+/**
+ * Remove the given oft_info struct from the oft_info linked list, and 
+ * then free its memory.
+ *
+ * @param sess The session.
+ * @param oft_info The aim_oft_info struct that we're destroying.
+ * @return Return 0 if no errors, otherwise return the error number.
+ */
+faim_export int aim_oft_destroyinfo(struct aim_oft_info *oft_info)
+{
+	aim_session_t *sess;
+
+	if (!oft_info || !(sess = oft_info->sess))
+		return -EINVAL;
+
+	if (sess->oft_info && (sess->oft_info == oft_info)) {
+		sess->oft_info = sess->oft_info->next;
+	} else {
+		struct aim_oft_info *cur;
+		for (cur=sess->oft_info; (cur->next && (cur->next!=oft_info)); cur=cur->next);
+		if (cur->next)
+			cur->next = cur->next->next;
+	}
+
+	free(oft_info->sn);
+	free(oft_info->proxyip);
+	free(oft_info->clientip);
+	free(oft_info->verifiedip);
+	free(oft_info);
+
+	return 0;
+}
+
 /**
  * Creates a listener socket so the other dude can connect to us.
  *
@@ -712,30 +781,30 @@
  * will accept the pending connection and stop listening.
  *
  * @param sess The session.
- * @param cookie This better be Mrs. Fields or I'm going to be pissed.
- * @param ip Should be 4 bytes,  each byte is 1 quartet of the IP address.
- * @param port Ye olde port number to listen on.
- * @return Return the new conn if everything went as planned.  Otherwise, 
- *         return NULL.
+ * @param oft_info File transfer information associated with this 
+ *        connection.
+ * @return Return 0 if no errors, otherwise return the error number.
  */
-faim_export aim_conn_t *aim_sendfile_listen(aim_session_t *sess, const fu8_t *cookie, const fu8_t *ip, fu16_t port)
+faim_export int aim_sendfile_listen(aim_session_t *sess, struct aim_oft_info *oft_info)
 {
-	aim_conn_t *newconn;
 	int listenfd;
 
-	if ((listenfd = listenestablish(port)) == -1)
-		return NULL;
+	if (!oft_info)
+		return -EINVAL;
 
-	if (!(newconn = aim_newconn(sess, AIM_CONN_TYPE_LISTENER, NULL))) {
+	if ((listenfd = listenestablish(oft_info->port)) == -1)
+		return 1;
+
+	if (!(oft_info->conn = aim_newconn(sess, AIM_CONN_TYPE_LISTENER, NULL))) {
 		close(listenfd);
-		return NULL;
+		return -ENOMEM;
 	}
 
-	newconn->fd = listenfd;
-	newconn->subtype = AIM_CONN_SUBTYPE_OFT_SENDFILE;
-	newconn->lastactivity = time(NULL);
+	oft_info->conn->fd = listenfd;
+	oft_info->conn->subtype = AIM_CONN_SUBTYPE_OFT_SENDFILE;
+	oft_info->conn->lastactivity = time(NULL);
 
-	return newconn;
+	return 0;
 }
 
 /**
@@ -830,110 +899,52 @@
 	return 0;
 }
 
-faim_export struct aim_oft_info *aim_oft_createnewheader(fu8_t *cookie, char *ip, fu32_t size, fu32_t modtime, char *filename)
-{
-	struct aim_oft_info *new;
-
-	if (!(new = (struct aim_oft_info *)calloc(1, sizeof(struct aim_oft_info))))
-		return NULL;
-
-	if (cookie && (sizeof(cookie) == 8)) {
-		memcpy(new->cookie, cookie, 8);
-		memcpy(new->fh.bcookie, cookie, 8);
-	}
-	if (ip)
-		strncpy(new->ip, ip, 30);
-	new->fh.filesleft = 0;
-	new->fh.totparts = 1;
-	new->fh.partsleft = 1;
-	new->fh.totsize = size;
-	new->fh.size = size;
-	new->fh.modtime = modtime;
-	strcpy(new->fh.idstring, "OFT_Windows ICBMFT V1.1 32");
-	if (filename)
-		strncpy(new->fh.name, filename, 64);
-
-	return new;
-}
-
 /**
  * Create an OFT packet based on the given information, and send it on its merry way.
  *
  * @param sess The session.
- * @param conn The already-connected OFT connection.
- * @param cookie The cookie associated with this file transfer.
- * @param filename The filename.
- * @param filesdone Number of files already transferred.
- * @param numfiles Total number of files.
- * @param size Size in bytes of this file.
- * @param totsize Size in bytes of all files combined.
- * @param checksum Funky checksum of this file.
- * @param flags Any flags you want, baby.  Send 0x21 when sending the 
- *        "AIM_CB_OFT_DONE" message, and "0x02" for everything else.
+ * @param type The subtype of the OFT packet we're sending.
+ * @param oft_info The aim_oft_info struct with the connection and OFT 
+ *        info we're sending.
  * @return Return 0 if no errors, otherwise return the error number.
  */
-faim_export int aim_oft_sendheader(aim_session_t *sess, aim_conn_t *conn, fu16_t type, const fu8_t *cookie, const char *filename, fu16_t filesdone, fu16_t numfiles, fu32_t size, fu32_t totsize, fu32_t modtime, fu32_t checksum, fu8_t flags, fu32_t bytesreceived, fu32_t recvcsum)
+faim_export int aim_oft_sendheader(aim_session_t *sess, fu16_t type, struct aim_oft_info *oft_info)
 {
-	aim_frame_t *newoft;
-	struct aim_fileheader_t *fh;
+	aim_frame_t *fr;
 
-	if (!sess || !conn || (conn->type != AIM_CONN_TYPE_RENDEZVOUS) || !filename)
+	if (!sess || !oft_info || !oft_info->conn || (oft_info->conn->type != AIM_CONN_TYPE_RENDEZVOUS))
 		return -EINVAL;
 
-	if (!(fh = (struct aim_fileheader_t *)calloc(1, sizeof(struct aim_fileheader_t))))
-		return -ENOMEM;
-
+#if 0
 	/*
 	 * If you are receiving a file, the cookie should be null, if you are sending a 
 	 * file, the cookie should be the same as the one used in the ICBM negotiation 
 	 * SNACs.
 	 */
-	if (cookie)
-		memcpy(fh->bcookie, cookie, 8);
-	fh->totfiles = numfiles;
-	fh->filesleft = numfiles - filesdone;
-	fh->totparts = 0x0001; /* set to 0x0002 sending Mac resource forks */
-	fh->partsleft = 0x0001;
-	fh->totsize = totsize;
-	fh->size = size;
-	fh->modtime = modtime;
-	fh->checksum = checksum;
-	fh->nrecvd = bytesreceived;
-	fh->recvcsum = recvcsum;
-
-	strncpy(fh->idstring, "OFT_Windows ICBMFT V1.1 32", sizeof(fh->idstring));
-	fh->flags = flags;
 	fh->lnameoffset = 0x1a;
 	fh->lsizeoffset = 0x10;
-	memset(fh->dummy, 0, sizeof(fh->dummy));
-	memset(fh->macfileinfo, 0, sizeof(fh->macfileinfo));
 
 	/* apparently 0 is ASCII, 2 is UCS-2 */
 	/* it is likely that 3 is ISO 8859-1 */
 	/* I think "nlanguage" might be the same thing as "subenc" in im.c */
 	fh->nencode = 0x0000;
 	fh->nlanguage = 0x0000;
+#endif
 
-	strncpy(fh->name, filename, sizeof(fh->name));
-	aim_oft_dirconvert_tostupid(fh->name);
+	aim_oft_dirconvert_tostupid(oft_info->fh.name);
 
-	if (!(newoft = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, type, 0))) {
-		free(fh);
+	if (!(fr = aim_tx_new(sess, oft_info->conn, AIM_FRAMETYPE_OFT, type, 0)))
+		return -ENOMEM;
+
+	if (aim_oft_buildheader(&fr->data, &oft_info->fh) == -1) {
+		aim_frame_destroy(fr);
 		return -ENOMEM;
 	}
 
-	if (aim_oft_buildheader(&newoft->data, fh) == -1) {
-		aim_frame_destroy(newoft);
-		free(fh);
-		return -ENOMEM;
-	}
+	memcpy(fr->hdr.rend.magic, "OFT2", 4);
+	fr->hdr.rend.hdrlen = aim_bstream_curpos(&fr->data);
 
-	memcpy(newoft->hdr.rend.magic, "OFT2", 4);
-	newoft->hdr.rend.hdrlen = aim_bstream_curpos(&newoft->data);
-
-	aim_tx_enqueue(sess, newoft);
-
-	free(fh);
+	aim_tx_enqueue(sess, fr);
 
 	return 0;
 }