+ int i;
+
+ if (!sess || !buf || !len)
+ return;
+
+ faimdprintf(sess, 1, "\nDump of %d bytes at %p:", len, buf);
+
+ for (i = 0; i < len; i++) {
+ if ((i % 8) == 0)
+ faimdprintf(sess, 1, "\n\t");
+
+ faimdprintf(sess, 1, "0x%2x ", buf[i]);
+ }
+
+ faimdprintf(sess, 1, "\n\n");
+
+ return;
+}
+#endif
+
+faim_export int aim_sendmemblock(aim_session_t *sess, aim_conn_t *conn, fu32_t offset, fu32_t len, const fu8_t *buf, fu8_t flag)
+{
+ aim_frame_t *fr;
+ aim_snacid_t snacid;
+
+ if (!sess || !conn)
+ return -EINVAL;
+
+ if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+2+16)))
+ return -ENOMEM;
+
+ snacid = aim_cachesnac(sess, 0x0001, 0x0020, 0x0000, NULL, 0);
+
+ aim_putsnac(&fr->data, 0x0001, 0x0020, 0x0000, snacid);
+ aimbs_put16(&fr->data, 0x0010); /* md5 is always 16 bytes */
+
+ if ((flag == AIM_SENDMEMBLOCK_FLAG_ISHASH) && buf && (len == 0x10)) { /* we're getting a hash */
+
+ aimbs_putraw(&fr->data, buf, 0x10);
+
+ } else if (buf && (len > 0)) { /* use input buffer */
+ md5_state_t state;
+ md5_byte_t digest[0x10];
+
+ md5_init(&state);
+ md5_append(&state, (const md5_byte_t *)buf, len);
+ md5_finish(&state, digest);
+
+ aimbs_putraw(&fr->data, (fu8_t *)digest, 0x10);
+
+ } else if (len == 0) { /* no length, just hash NULL (buf is optional) */
+ md5_state_t state;
+ fu8_t nil = '\0';
+ md5_byte_t digest[0x10];
+
+ /*
+ * These MD5 routines are stupid in that you have to have
+ * at least one append. So thats why this doesn't look
+ * real logical.
+ */
+ md5_init(&state);
+ md5_append(&state, (const md5_byte_t *)&nil, 0);
+ md5_finish(&state, digest);
+
+ aimbs_putraw(&fr->data, (fu8_t *)digest, 0x10);
+
+ } else {
+
+ /*
+ * This data is correct for AIM 3.5.1670.
+ *
+ * Using these blocks is as close to "legal" as you can get
+ * without using an AIM binary.
+ *
+ */
+ if ((offset == 0x03ffffff) && (len == 0x03ffffff)) {
+
+#if 1 /* with "AnrbnrAqhfzcd" */
+ aimbs_put32(&fr->data, 0x44a95d26);
+ aimbs_put32(&fr->data, 0xd2490423);
+ aimbs_put32(&fr->data, 0x93b8821f);
+ aimbs_put32(&fr->data, 0x51c54b01);
+#else /* no filename */
+ aimbs_put32(&fr->data, 0x1df8cbae);
+ aimbs_put32(&fr->data, 0x5523b839);
+ aimbs_put32(&fr->data, 0xa0e10db3);
+ aimbs_put32(&fr->data, 0xa46d3b39);
+#endif
+
+ } else if ((offset == 0x00001000) && (len == 0x00000000)) {
+
+ aimbs_put32(&fr->data, 0xd41d8cd9);
+ aimbs_put32(&fr->data, 0x8f00b204);
+ aimbs_put32(&fr->data, 0xe9800998);
+ aimbs_put32(&fr->data, 0xecf8427e);
+
+ } else
+ faimdprintf(sess, 0, "sendmemblock: WARNING: unknown hash request\n");
+
+ }
+
+ aim_tx_enqueue(sess, fr);
+
+ return 0;