* when the message is received (of type 0x0004/0x000c)
*
*/
-u_long aim_send_im(struct aim_session_t *sess,
- struct aim_conn_t *conn,
- char *destsn, u_int flags, char *msg)
+faim_export unsigned long aim_send_im(struct aim_session_t *sess,
+ struct aim_conn_t *conn,
+ char *destsn, u_int flags, char *msg)
{
int curbyte,i;
*
*/
for (i=0;i<8;i++)
- curbyte += aimutil_put8(newpacket->data+curbyte, (u_char) random());
+ curbyte += aimutil_put8(newpacket->data+curbyte, (u_char) rand());
/*
* Channel ID
return (sess->snac_nextid++);
}
-struct aim_directim_priv {
- unsigned char cookie[8];
- char sn[MAXSNLEN+1];
-};
-
-int aim_send_im_direct(struct aim_session_t *sess,
- struct aim_conn_t *conn,
- char *msg)
-{
- struct command_tx_struct *newpacket;
- struct aim_directim_priv *priv = NULL;
- int i;
-
- if (strlen(msg) >= MAXMSGLEN)
- return -1;
-
- if (!sess || !conn || (conn->type != AIM_CONN_TYPE_RENDEZVOUS) || !conn->priv) {
- printf("faim: directim: invalid arguments\n");
- return -1;
- }
-
- if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OFT, 0x0001, conn, strlen(msg)))) {
- printf("faim: directim: tx_new failed\n");
- return -1;
- }
-
- newpacket->lock = 1; /* lock struct */
-
- priv = (struct aim_directim_priv *)conn->priv;
-
- newpacket->hdr.oft.hdr2len = 0x44;
-
- if (!(newpacket->hdr.oft.hdr2 = malloc(newpacket->hdr.oft.hdr2len))) {
- free(newpacket);
- return -1;
- }
-
- i = 0;
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0006);
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
-
- i += aimutil_putstr(newpacket->hdr.oft.hdr2+i, priv->cookie, 8);
-
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
-
- i += aimutil_put32(newpacket->hdr.oft.hdr2+i, strlen(msg));
-
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
-
- i += aimutil_putstr(newpacket->hdr.oft.hdr2+i, sess->logininfo.screen_name, strlen(sess->logininfo.screen_name));
-
- i = 52;
- i += aimutil_put8(newpacket->hdr.oft.hdr2+i, 0x00);
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
- i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);
-
- memcpy(newpacket->data, msg, strlen(msg));
-
- newpacket->lock = 0;
-
- aim_tx_enqueue(sess, newpacket);
-
- return 0;
-}
-
-int aim_parse_outgoing_im_middle(struct aim_session_t *sess,
- struct command_rx_struct *command)
+faim_internal int aim_parse_outgoing_im_middle(struct aim_session_t *sess,
+ struct command_rx_struct *command)
{
unsigned int i = 0, z;
rxcallback_t userfunc = NULL;
return 1;
}
- strncpy(sn, command->data+i+1, (int) *(command->data+i));
+ strncpy(sn, (char *) command->data+i+1, (int) *(command->data+i));
i += 1 + (int) *(command->data+i);
tlvlist = aim_readtlvchain(command->data+i, command->commandlen-i);
if (aim_gettlv(tlvlist, 0x0002, 1)) {
int j = 0;
- msgblock = aim_gettlv_str(tlvlist, 0x0002, 1);
+ msgblock = (unsigned char *)aim_gettlv_str(tlvlist, 0x0002, 1);
/* no, this really is correct. I'm not high or anything either. */
j += 2;
* room we're invited to, but obviously can't attend...
*
*/
-int aim_parse_incoming_im_middle(struct aim_session_t *sess,
- struct command_rx_struct *command)
+faim_internal int aim_parse_incoming_im_middle(struct aim_session_t *sess,
+ struct command_rx_struct *command)
{
u_int i = 0,z;
rxcallback_t userfunc = NULL;
u_int j = 0, y = 0, z = 0;
char *msg = NULL;
u_int icbmflags = 0;
- struct aim_tlv_t *msgblocktlv, *tmptlv;
+ struct aim_tlv_t *msgblocktlv;
u_char *msgblock;
u_short flag1,flag2;
{
struct aim_tlv_t *block1;
struct aim_tlvlist_t *list2;
- struct aim_tlv_t *tmptlv;
unsigned short reqclass = 0;
unsigned short status = 0;
if (!list2 || ((reqclass != AIM_CAPS_IMIMAGE) && !(aim_gettlv(list2, 0x2711, 1)))) {
struct aim_msgcookie_t *cook;
+ int type;
+
+ type = aim_msgcookie_gettype(reqclass); /* XXX: fix this shitty code */
- if ((cook = aim_uncachecookie(sess, cookie)) == NULL) {
+ if ((cook = aim_uncachecookie(sess, cookie, type)) == NULL) {
printf("faim: non-data rendezvous thats not in cache!\n");
aim_freetlvchain(&list2);
aim_freetlvchain(&tlvlist);
}
if (cook->type == AIM_CAPS_SENDFILE) {
- struct aim_filetransfer_t *ft;
+ struct aim_filetransfer_priv *ft;
if (cook->data) {
struct aim_tlv_t *errortlv;
int errorcode = -1;
- ft = (struct aim_filetransfer_t *)cook->data;
+ ft = (struct aim_filetransfer_priv *)cook->data;
if ((errortlv = aim_gettlv(list2, 0x000b, 1))) {
errorcode = aimutil_get16(errortlv->value);
}
if (errorcode) {
- printf("faim: transfer from %s (%s) for %s cancelled (error code %d)\n", ft->sender, ft->ip, ft->filename, errorcode);
+ printf("faim: transfer from %s (%s) for %s cancelled (error code %d)\n", ft->sn, ft->ip, ft->fh.name, errorcode);
} else if (status == 0x0002) { /* connection accepted */
- printf("faim: transfer from %s (%s) for %s accepted\n", ft->sender, ft->ip, ft->filename);
+ printf("faim: transfer from %s (%s) for %s accepted\n", ft->sn, ft->ip, ft->fh.name);
}
free(cook->data);
} else {
/*
* Call client.
*/
+#if 0
userfunc = aim_callhandler(command->conn, 0x0004, 0x0007);
if (userfunc || (i = 0))
i = userfunc(sess,
command,
channel,
reqclass,
- &userinfo);
+ &userinfo,
+ ip,
+ cookie);
+#endif
} else if (reqclass & AIM_CAPS_VOICE) {
- struct aim_msgcookie_t cachedcook;
+ struct aim_msgcookie_t *cachedcook;
printf("faim: rend: voice!\n");
- memcpy(cachedcook.cookie, cookie, 8);
- cachedcook.type = AIM_CAPS_VOICE;
- cachedcook.data = NULL;
- if (aim_cachecookie(sess, &cachedcook) != 0)
+ if(!(cachedcook = (struct aim_msgcookie_t*)calloc(1, sizeof(struct aim_msgcookie_t))))
+ return 1;
+
+ memcpy(cachedcook->cookie, cookie, 8);
+ cachedcook->type = AIM_COOKIETYPE_OFTVOICE;
+ cachedcook->data = NULL;
+
+ if (aim_cachecookie(sess, cachedcook) != 0)
printf("faim: ERROR caching message cookie\n");
/* XXX: implement all this */
*/
userfunc = aim_callhandler(command->conn, 0x0004, 0x0007);
if (userfunc || (i = 0)) {
- i = userfunc(sess,
- command,
- channel,
- reqclass,
- &userinfo);
+ i = userfunc(sess, command, channel, reqclass, &userinfo);
}
- } else if (reqclass & AIM_CAPS_IMIMAGE) {
+ } else if ((reqclass & AIM_CAPS_IMIMAGE) || (reqclass & AIM_CAPS_BUDDYICON)) {
char ip[30];
- struct aim_msgcookie_t cachedcook;
+ struct aim_directim_priv *priv;
- memset(ip, 0, sizeof(ip));
+ memset(ip, 0, 30);
- if (aim_gettlv(list2, 0x0003, 1) && aim_gettlv(list2, 0x0003, 1)) {
+ if (aim_gettlv(list2, 0x0003, 1) && aim_gettlv(list2, 0x0005, 1)) {
struct aim_tlv_t *iptlv, *porttlv;
iptlv = aim_gettlv(list2, 0x0003, 1);
porttlv = aim_gettlv(list2, 0x0005, 1);
- snprintf(ip, sizeof(ip)-1, "%d.%d.%d.%d:%d",
+ snprintf(ip, 30, "%d.%d.%d.%d:%d",
aimutil_get8(iptlv->value+0),
aimutil_get8(iptlv->value+1),
aimutil_get8(iptlv->value+2),
userinfo.sn,
ip);
-#if 0
- {
- struct aim_conn_t *newconn;
-
- newconn = aim_newconn(sess, AIM_CONN_TYPE_RENDEZVOUS, ip);
- if (!newconn || (newconn->fd == -1)) {
- printf("could not connect to %s\n", ip);
- perror("aim_newconn");
- aim_conn_kill(sess, &newconn);
- } else {
- struct aim_directim_priv *priv;
- priv = (struct aim_directim_priv *)malloc(sizeof(struct aim_directim_priv));
- memcpy(priv->cookie, cookie, 8);
- strncpy(priv->sn, userinfo.sn, MAXSNLEN);
- newconn->priv = priv;
- printf("faim: connected to peer (fd = %d)\n", newconn->fd);
- }
- }
-#endif
-
-#if 0
- memcpy(cachedcook.cookie, cookie, 8);
+ /* XXX: there are a couple of different request packets for
+ * different things */
- ft = malloc(sizeof(struct aim_filetransfer_t));
- strncpy(ft->sender, userinfo.sn, sizeof(ft->sender));
- strncpy(ft->ip, ip, sizeof(ft->ip));
- ft->filename = strdup(miscinfo->value+8);
- cachedcook.type = AIM_CAPS_SENDFILE;
- cachedcook.data = ft;
-
- if (aim_cachecookie(sess, &cachedcook) != 0)
- printf("faim: ERROR caching message cookie\n");
-#endif
+ priv = (struct aim_directim_priv *)calloc(1, sizeof(struct aim_directim_priv));
+ memcpy(priv->ip, ip, sizeof(priv->ip));
+ memcpy(priv->sn, userinfo.sn, sizeof(priv->sn));
+ memcpy(priv->cookie, cookie, sizeof(priv->cookie));
/*
* Call client.
command,
channel,
reqclass,
- &userinfo);
+ &userinfo, priv);
} else if (reqclass & AIM_CAPS_CHAT) {
struct aim_tlv_t *miscinfo;
free(encoding);
free(lang);
} else if (reqclass & AIM_CAPS_GETFILE) {
+ char ip[30];
+ struct aim_msgcookie_t *cachedcook;
+ struct aim_tlv_t *miscinfo;
+
+ if (!(cachedcook = calloc(1, sizeof(struct aim_msgcookie_t))))
+ return 0;
+
+ memset(ip, 0, 30);
+
+ if (!(miscinfo = aim_gettlv(list2, 0x2711, 1))) {
+ free(cachedcook);
+ return 0;
+ }
+
+ if (aim_gettlv(list2, 0x0003, 1) && aim_gettlv(list2, 0x0005, 1)) {
+ struct aim_tlv_t *iptlv, *porttlv;
+
+ if (!(iptlv = aim_gettlv(list2, 0x0003, 1)) || !(porttlv = aim_gettlv(list2, 0x0005, 1))) {
+ free(cachedcook);
+ return 0;
+ }
+
+ snprintf(ip, 30, "%d.%d.%d.%d:%d",
+ aimutil_get8(iptlv->value+0),
+ aimutil_get8(iptlv->value+1),
+ aimutil_get8(iptlv->value+2),
+ aimutil_get8(iptlv->value+3),
+ aimutil_get16(porttlv->value));
+ }
+
+ printf("faim: rend: file get request from %s (%s)\n", userinfo.sn, ip);
/*
* Call client.
command,
channel,
reqclass,
- &userinfo);
+ &userinfo,
+ ip,
+ cookie);
} else if (reqclass & AIM_CAPS_SENDFILE) {
- /*
- * Call client.
- */
- userfunc = aim_callhandler(command->conn, 0x0004, 0x0007);
- if (userfunc || (i = 0))
- i = userfunc(sess,
- command,
- channel,
- reqclass,
- &userinfo);
#if 0
- char ip[30];
- char *desc = NULL;
- struct aim_msgcookie_t cachedcook;
- struct aim_filetransfer_t *ft;
- struct aim_tlv_t *miscinfo;
+ char ip[30];
+ char *desc = NULL;
+ struct aim_msgcookie_t *cachedcook;
+ struct aim_filetransfer_priv *ft;
+ struct aim_tlv_t *miscinfo;
memset(ip, 0, sizeof(ip));
- miscinfo = aim_gettlv(list2, 0x2711, 1);
+ if (!(miscinfo = aim_gettlv(list2, 0x2711, 1)))
+ return 0;
if (aim_gettlv(list2, 0x0003, 1) && aim_gettlv(list2, 0x0003, 1)) {
struct aim_tlv_t *iptlv, *porttlv;
desc,
ip);
- memcpy(cachedcook.cookie, cookie, 8);
+ memcpy(cachedcook->cookie, cookie, 8);
- ft = malloc(sizeof(struct aim_filetransfer_t));
- strncpy(ft->sender, userinfo.sn, sizeof(ft->sender));
+ ft = malloc(sizeof(struct aim_filetransfer_priv));
+ strncpy(ft->sn, userinfo.sn, sizeof(ft->sn));
strncpy(ft->ip, ip, sizeof(ft->ip));
- ft->filename = strdup(miscinfo->value+8);
- cachedcook.type = AIM_CAPS_SENDFILE;
- cachedcook.data = ft;
+ strncpy(ft->fh.name, miscinfo->value+8, sizeof(ft->fh.name));
+ cachedcook->type = AIM_COOKIETYPE_OFTSEND;
+ cachedcook->data = ft;
- if (aim_cachecookie(sess, &cachedcook) != 0)
+ if (aim_cachecookie(sess, cachedcook) != 0)
printf("faim: ERROR caching message cookie\n");
- aim_accepttransfer(sess, command->conn, ft->sender, cookie, AIM_CAPS_SENDFILE);
-
- free(desc);
+ aim_accepttransfer(sess, command->conn, ft->sn, cookie, AIM_CAPS_SENDFILE);
+
+ if (desc)
+ free(desc);
#endif
- i = 1;
+ /*
+ * Call client.
+ */
+ userfunc = aim_callhandler(command->conn, 0x0004, 0x0007);
+ if (userfunc || (i = 0))
+ i = userfunc(sess,
+ command,
+ channel,
+ reqclass,
+ &userinfo);
} else {
printf("faim: rend: unknown rendezvous 0x%04x\n", reqclass);
}
return i;
}
-u_long aim_accepttransfer(struct aim_session_t *sess,
- struct aim_conn_t *conn,
- char *sender,
- char *cookie,
- unsigned short rendid)
-{
- struct command_tx_struct *newpacket;
- int curbyte, i;
-
- if(!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10+8+2+1+strlen(sender)+4+2+8+16)))
- return -1;
-
- newpacket->lock = 1;
-
- curbyte = aim_putsnac(newpacket->data, 0x0004, 0x0006, 0x0000, sess->snac_nextid);
- for (i = 0; i < 8; i++)
- curbyte += aimutil_put8(newpacket->data+curbyte, cookie[i]);
- curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002);
- curbyte += aimutil_put8(newpacket->data+curbyte, strlen(sender));
- curbyte += aimutil_putstr(newpacket->data+curbyte, sender, strlen(sender));
- curbyte += aimutil_put16(newpacket->data+curbyte, 0x0005);
- curbyte += aimutil_put16(newpacket->data+curbyte, 0x001a);
- curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002 /* accept */);
- for (i = 0; i < 8; i++)
- curbyte += aimutil_put8(newpacket->data+curbyte, cookie[i]);
- curbyte += aim_putcap(newpacket->data+curbyte, 0x10, rendid);
-
- newpacket->lock = 0;
- aim_tx_enqueue(sess, newpacket);
-
- return (sess->snac_nextid++);
-}
-
/*
* Possible codes:
* AIM_TRANSFER_DENY_NOTSUPPORTED -- "client does not support"
* AIM_TRANSFER_DENY_NOTACCEPTING -- "client is not accepting transfers"
*
*/
-u_long aim_denytransfer(struct aim_session_t *sess,
- struct aim_conn_t *conn,
- char *sender,
- char *cookie,
- unsigned short code)
+faim_export unsigned long aim_denytransfer(struct aim_session_t *sess,
+ struct aim_conn_t *conn,
+ char *sender,
+ char *cookie,
+ unsigned short code)
{
struct command_tx_struct *newpacket;
int curbyte, i;
* idea.
*
*/
-u_long aim_seticbmparam(struct aim_session_t *sess,
- struct aim_conn_t *conn)
+faim_export unsigned long aim_seticbmparam(struct aim_session_t *sess,
+ struct aim_conn_t *conn)
{
struct command_tx_struct *newpacket;
int curbyte;
return (sess->snac_nextid++);
}
-int aim_parse_msgerror_middle(struct aim_session_t *sess,
- struct command_rx_struct *command)
+faim_internal int aim_parse_msgerror_middle(struct aim_session_t *sess,
+ struct command_rx_struct *command)
{
u_long snacid = 0x000000000;
struct aim_snac_t *snac = NULL;
int ret = 0;
rxcallback_t userfunc = NULL;
+ char *dest;
+ unsigned short reason = 0;
/*
* Get SNAC from packet and look it up
if (!snac) {
printf("faim: msgerr: got an ICBM-failed error on an unknown SNAC ID! (%08lx)\n", snacid);
- }
+ dest = NULL;
+ } else
+ dest = snac->data;
+
+ reason = aimutil_get16(command->data+10);
/*
* Call client.
*/
userfunc = aim_callhandler(command->conn, 0x0004, 0x0001);
if (userfunc)
- ret = userfunc(sess, command, (snac)?snac->data:"(UNKNOWN)");
+ ret = userfunc(sess, command, dest, reason);
else
ret = 0;
}
+faim_internal int aim_parse_missedcall(struct aim_session_t *sess,
+ struct command_rx_struct *command)
+{
+ int i, ret = 1;
+ rxcallback_t userfunc = NULL;
+ unsigned short channel, nummissed, reason;
+ struct aim_userinfo_s userinfo;
+
+ i = 10; /* Skip SNAC header */
+
+
+ /*
+ * XXX: supposedly, this entire packet can repeat as many times
+ * as necessary. Should implement that.
+ */
+
+ /*
+ * Channel ID.
+ */
+ channel = aimutil_get16(command->data+i);
+ i += 2;
+
+ /*
+ * Extract the standard user info block.
+ */
+ i += aim_extractuserinfo(command->data+i, &userinfo);
+
+ nummissed = aimutil_get16(command->data+i);
+ i += 2;
+
+ reason = aimutil_get16(command->data+i);
+ i += 2;
+
+ /*
+ * Call client.
+ */
+ userfunc = aim_callhandler(command->conn, 0x0004, 0x000a);
+ if (userfunc)
+ ret = userfunc(sess, command, channel, &userinfo, nummissed, reason);
+ else
+ ret = 0;
+
+ return ret;
+}