*
*/
+#define FAIM_INTERNAL
#include <faim/aim.h>
/*
* 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
aim_tx_enqueue(sess, newpacket);
-#ifdef USE_SNAC_FOR_IMS
- {
- struct aim_snac_t snac;
+ aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, destsn, strlen(destsn)+1);
+ aim_cleansnacs(sess, 60); /* clean out all SNACs over 60sec old */
- snac.id = sess->snac_nextid;
- snac.family = 0x0004;
- snac.type = 0x0006;
- snac.flags = 0x0000;
-
- snac.data = malloc(strlen(destsn)+1);
- memcpy(snac.data, destsn, strlen(destsn)+1);
-
- aim_newsnac(sess, &snac);
- }
-
- aim_cleansnacs(sess, 60); /* clean out all SNACs over 60sec old */
-#endif
-
- return (sess->snac_nextid++);
+ return sess->snac_nextid;
}
-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;
{
struct aim_tlv_t *block1;
struct aim_tlvlist_t *list2;
- struct aim_tlv_t *tmptlv;
unsigned short reqclass = 0;
unsigned short status = 0;
type = aim_msgcookie_gettype(reqclass); /* XXX: fix this shitty code */
- if ((cook = aim_uncachecookie(sess, cookie, type)) == NULL) {
- printf("faim: non-data rendezvous thats not in cache!\n");
- aim_freetlvchain(&list2);
- aim_freetlvchain(&tlvlist);
- return 1;
+ if(type != 17) {
+ if ((cook = aim_uncachecookie(sess, cookie, type)) == NULL) {
+ printf("faim: non-data rendezvous thats not in cache!\n");
+ aim_freetlvchain(&list2);
+ aim_freetlvchain(&tlvlist);
+ return 1;
+ }
}
- if (cook->type == AIM_CAPS_SENDFILE) {
+ if (cook->type == AIM_COOKIETYPE_OFTGET) {
struct aim_filetransfer_priv *ft;
if (cook->data) {
- struct aim_tlv_t *errortlv;
- int errorcode = -1;
+ int errorcode = -1; /* XXX shouldnt this be 0? */
ft = (struct aim_filetransfer_priv *)cook->data;
- if ((errortlv = aim_gettlv(list2, 0x000b, 1))) {
- errorcode = aimutil_get16(errortlv->value);
+ if(status != 0x0002) {
+ if (aim_gettlv(list2, 0x000b, 1))
+ errorcode = aim_gettlv16(list2, 0x000b, 1);
+
+ if (errorcode)
+ printf("faim: transfer from %s (%s) for %s cancelled (error code %d)\n", ft->sn, ft->ip, ft->fh.name, errorcode);
}
- if (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->sn, ft->ip, ft->fh.name);
- }
- free(cook->data);
} else {
- printf("faim: not data attached to file transfer\n");
+ printf("faim: no data attached to file transfer\n");
}
} else if (cook->type == AIM_CAPS_VOICE) {
printf("faim: voice request cancelled\n");
} else {
printf("faim: unknown cookie cache type %d\n", cook->type);
}
-
- free(cook);
+
if (list2)
aim_freetlvchain(&list2);
aim_freetlvchain(&tlvlist);
/*
* 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;
char ip[30];
struct aim_directim_priv *priv;
- memset(ip, 0, sizeof(ip));
+ memset(ip, 0, 30);
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),
free(lang);
} else if (reqclass & AIM_CAPS_GETFILE) {
char ip[30];
- char *desc = NULL;
struct aim_msgcookie_t *cachedcook;
- struct aim_filetransfer_priv *ft;
struct aim_tlv_t *miscinfo;
- struct aim_conn_t *newconn;
if (!(cachedcook = calloc(1, sizeof(struct aim_msgcookie_t))))
return 0;
- memset(ip, 0, sizeof(ip));
+ memset(ip, 0, 30);
if (!(miscinfo = aim_gettlv(list2, 0x2711, 1))) {
free(cachedcook);
return 0;
}
- 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),
printf("faim: rend: file get request from %s (%s)\n", userinfo.sn, ip);
-#if 0 /* XXX finish this */
- 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_filetransfer_priv *priv;
- priv = (struct aim_filetransfer_priv *)calloc(1, sizeof(struct aim_filetransfer_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);
- }
-
- memcpy(cachedcook->cookie, cookie, 8);
-
- ft = malloc(sizeof(struct aim_filetransfer_priv));
- ft->state = 1;
- strncpy(ft->sn, userinfo.sn, sizeof(ft->sn));
- strncpy(ft->ip, ip, sizeof(ft->ip));
-#if 0
- strncpy(ft->fh.name, miscinfo->value+8, sizeof(ft->fh.name));
-#endif
- cachedcook->type = AIM_COOKIETYPE_OFTGET;
- cachedcook->data = ft;
-
- if (aim_cachecookie(sess, cachedcook) != 0)
- printf("faim: ERROR caching message cookie\n");
-
- aim_accepttransfer(sess, command->conn, newconn, ft->sn, cookie, AIM_CAPS_GETFILE);
-
- free(desc);
-#endif
/*
* Call client.
*/
command,
channel,
reqclass,
- &userinfo);
+ &userinfo,
+ ip,
+ cookie);
} else if (reqclass & AIM_CAPS_SENDFILE) {
#if 0
* 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;
+}