Exemple #1
0
/**
 * answers status message requests
 * @param sess the oscar session
 * @param sender the guy whos asking
 * @param cookie message id which we are answering for
 * @param message away message
 * @param state our current away state the way icq requests it (0xE8 for away, 0xE9 occupied, ...)
 * @return 0 if no error
 */
int aim_send_im_ch2_statusmessage(aim_session_t *sess, const char *sender, const guint8 *cookie,
        const char *message, const guint8 state, const guint16 dc)
{
    aim_conn_t *conn;
    aim_frame_t *fr;
    aim_snacid_t snacid;

    if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
                return -EINVAL;
        
    if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 
					10+8+2+1+strlen(sender)+2+0x1d+0x10+9+strlen(message)+1)))
                return -ENOMEM;

    snacid = aim_cachesnac(sess, 0x0004, 0x000b, 0x0000, NULL, 0);
    aim_putsnac(&fr->data, 0x0004, 0x000b, 0x0000, snacid);
    
    aimbs_putraw(&fr->data, cookie, 8);
    
    aimbs_put16(&fr->data, 0x0002); /* channel */
    aimbs_put8(&fr->data, strlen(sender));
    aimbs_putraw(&fr->data, (guint8 *)sender, strlen(sender));

    aimbs_put16(&fr->data, 0x0003); /* reason: channel specific */

    aimbs_putle16(&fr->data, 0x001b); /* length of data SEQ1 */
    aimbs_putle16(&fr->data, 0x0008); /* protocol version */

    aimbs_putle32(&fr->data, 0x0000); /* no plugin -> 16 times 0x00 */ 
    aimbs_putle32(&fr->data, 0x0000); 
    aimbs_putle32(&fr->data, 0x0000); 
    aimbs_putle32(&fr->data, 0x0000);

    aimbs_putle16(&fr->data, 0x0000); /* unknown */
    aimbs_putle32(&fr->data, 0x0003); /* client features */
    aimbs_putle8(&fr->data, 0x00); /* unknown */
    aimbs_putle16(&fr->data, dc); /* Sequence number?  XXX - This should decrement by 1 with each request */
    /* end of SEQ1 */

    aimbs_putle16(&fr->data, 0x000e); /* Length of SEQ2 */
    aimbs_putle16(&fr->data, dc); /* Sequence number? same as above
                                       * XXX - This should decrement by 1 with each request */
    aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
    aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
    aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
    /* end of SEQ2 */

    /* now for the real fun */
    aimbs_putle8(&fr->data, state); /* away state */
    aimbs_putle8(&fr->data, 0x03); /* msg-flag: 03 for states */
    aimbs_putle16(&fr->data, 0x0000); /* status code ? */
    aimbs_putle16(&fr->data, 0x0000); /* priority code */
    aimbs_putle16(&fr->data, strlen(message) + 1); /* message length + termination */
    aimbs_putraw(&fr->data, (guint8 *) message, strlen(message) + 1); /* null terminated string */
    
    aim_tx_enqueue(sess, fr);


    return 0;
}
faim_export int aim_icq_reqofflinemsgs(aim_session_t *sess)
{
	aim_conn_t *conn;
	aim_frame_t *fr;
	aim_snacid_t snacid;
	int bslen;

	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
		return -EINVAL;

	bslen = 2 + 4 + 2 + 2;

	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
		return -ENOMEM;

	snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
	aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);

	/* For simplicity, don't bother using a tlvlist */
	aimbs_put16(&fr->data, 0x0001);
	aimbs_put16(&fr->data, bslen);

	aimbs_putle16(&fr->data, bslen - 2);
	aimbs_putle32(&fr->data, atoi(sess->sn));
	aimbs_putle16(&fr->data, 0x003c); /* I command thee. */
	aimbs_putle16(&fr->data, snacid); /* eh. */

	aim_tx_enqueue(sess, fr);

	return 0;
}
faim_export int aim_icq_getalias(aim_session_t *sess, const char *uin)
{
	aim_conn_t *conn;
	aim_frame_t *fr;
	aim_snacid_t snacid;
	int bslen;
	struct aim_icq_info *info;

	if (!uin || uin[0] < '0' || uin[0] > '9')
		return -EINVAL;

	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
		return -EINVAL;

	bslen = 2 + 4 + 2 + 2 + 2 + 4;

	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
		return -ENOMEM;

	snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
	aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);

	/* For simplicity, don't bother using a tlvlist */
	aimbs_put16(&fr->data, 0x0001);
	aimbs_put16(&fr->data, bslen);

	aimbs_putle16(&fr->data, bslen - 2);
	aimbs_putle32(&fr->data, atoi(sess->sn));
	aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
	aimbs_putle16(&fr->data, snacid); /* eh. */
	aimbs_putle16(&fr->data, 0x04ba); /* shrug. */
	aimbs_putle32(&fr->data, atoi(uin));

	aim_tx_enqueue(sess, fr);

	/* Keep track of this request and the ICQ number and request ID */
	info = (struct aim_icq_info *)calloc(1, sizeof(struct aim_icq_info));
	info->reqid = snacid;
	info->uin = atoi(uin);
	info->next = sess->icq_info;
	sess->icq_info = info;

	return 0;
}
faim_export int aim_icq_getsimpleinfo(aim_session_t *sess, const char *uin)
{
	aim_conn_t *conn;
	aim_frame_t *fr;
	aim_snacid_t snacid;
	int bslen;

	if (!uin || uin[0] < '0' || uin[0] > '9')
		return -EINVAL;

	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
		return -EINVAL;

	bslen = 2 + 4 + 2 + 2 + 2 + 4;

	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
		return -ENOMEM;

	snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
	aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);

	/* For simplicity, don't bother using a tlvlist */
	aimbs_put16(&fr->data, 0x0001);
	aimbs_put16(&fr->data, bslen);

	aimbs_putle16(&fr->data, bslen - 2);
	aimbs_putle32(&fr->data, atoi(sess->sn));
	aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
	aimbs_putle16(&fr->data, snacid); /* eh. */
	aimbs_putle16(&fr->data, 0x051f); /* shrug. */
	aimbs_putle32(&fr->data, atoi(uin));

	aim_tx_enqueue(sess, fr);

	return 0;
}
/**
 * Change your ICQ password.
 *
 * @param sess The oscar session
 * @param passwd The new password.  If this is longer than 8 characters it 
 *        will be truncated.
 * @return Return 0 if no errors, otherwise return the error number.
 */
faim_export int aim_icq_changepasswd(aim_session_t *sess, const char *passwd)
{
	aim_conn_t *conn;
	aim_frame_t *fr;
	aim_snacid_t snacid;
	int bslen, passwdlen;

	if (!passwd)
		return -EINVAL;

	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
		return -EINVAL;

	passwdlen = strlen(passwd);
	if (passwdlen > MAXICQPASSLEN)
		passwdlen = MAXICQPASSLEN;
	bslen = 2+4+2+2+2+2+passwdlen+1;

	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
		return -ENOMEM;

	snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
	aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);

	/* For simplicity, don't bother using a tlvlist */
	aimbs_put16(&fr->data, 0x0001);
	aimbs_put16(&fr->data, bslen);

	aimbs_putle16(&fr->data, bslen - 2);
	aimbs_putle32(&fr->data, atoi(sess->sn));
	aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
	aimbs_putle16(&fr->data, snacid); /* eh. */
	aimbs_putle16(&fr->data, 0x042e); /* shrug. */
	aimbs_putle16(&fr->data, passwdlen+1);
	aimbs_putraw(&fr->data, passwd, passwdlen);
	aimbs_putle8(&fr->data, '\0');

	aim_tx_enqueue(sess, fr);

	return 0;
}
faim_export int aim_icq_sendxmlreq(aim_session_t *sess, const char *xml)
{
	aim_conn_t *conn;
	aim_frame_t *fr;
	aim_snacid_t snacid;
	int bslen;

	if (!xml || !strlen(xml))
		return -EINVAL;

	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
		return -EINVAL;

	bslen = 2 + 10 + 2 + strlen(xml) + 1;

	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
		return -ENOMEM;

	snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
	aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);

	/* For simplicity, don't bother using a tlvlist */
	aimbs_put16(&fr->data, 0x0001);
	aimbs_put16(&fr->data, bslen);

	aimbs_putle16(&fr->data, bslen - 2);
	aimbs_putle32(&fr->data, atoi(sess->sn));
	aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
	aimbs_putle16(&fr->data, snacid); /* eh. */
	aimbs_putle16(&fr->data, 0x0998); /* shrug. */
	aimbs_putle16(&fr->data, strlen(xml) + 1);
	aimbs_putraw(&fr->data, xml, strlen(xml) + 1);

	aim_tx_enqueue(sess, fr);

	return 0;
}
/*
 * Send an SMS message.  This is the non-US way.  The US-way is to IM 
 * their cell phone number (+19195551234).
 *
 * We basically construct and send an XML message.  The format is:
 * <icq_sms_message>
 *   <destination>full_phone_without_leading_+</destination>
 *   <text>message</text>
 *   <codepage>1252</codepage>
 *   <senders_UIN>self_uin</senders_UIN>
 *   <senders_name>self_name</senders_name>
 *   <delivery_receipt>Yes|No</delivery_receipt>
 *   <time>Wkd, DD Mmm YYYY HH:MM:SS TMZ</time>
 * </icq_sms_message>
 *
 * Yeah hi Peter, whaaaat's happening.  If there's any way to use 
 * a codepage other than 1252 that would be great.  Thaaaanks.
 */
faim_export int aim_icq_sendsms(aim_session_t *sess, const char *name, const char *msg, const char *alias)
{
	aim_conn_t *conn;
	aim_frame_t *fr;
	aim_snacid_t snacid;
	int bslen, xmllen;
	char *xml, timestr[30];
	time_t t;
	struct tm *tm;

	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
		return -EINVAL;

	if (!name || !msg || !alias)
		return -EINVAL;

	time(&t);
	tm = gmtime(&t);
	strftime(timestr, 30, "%a, %d %b %Y %T %Z", tm);

	/* The length of xml included the null terminating character */
	xmllen = 225 + strlen(name) + strlen(msg) + strlen(sess->sn) + strlen(alias) + strlen(timestr) + 1;

	if (!(xml = (char *)malloc(xmllen*sizeof(char))))
		return -ENOMEM;
	snprintf(xml, xmllen, "<icq_sms_message>\n"
		"\t<destination>%s</destination>\n"
		"\t<text>%s</text>\n"
		"\t<codepage>1252</codepage>\n"
		"\t<senders_UIN>%s</senders_UIN>\n"
		"\t<senders_name>%s</senders_name>\n"
		"\t<delivery_receipt>Yes</delivery_receipt>\n"
		"\t<time>%s</time>\n"
		"</icq_sms_message>\n",
		name, msg, sess->sn, alias, timestr);

	bslen = 37 + xmllen;

	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen))) {
		free(xml);
		return -ENOMEM;
	}

	snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
	aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);

	/* For simplicity, don't bother using a tlvlist */
	aimbs_put16(&fr->data, 0x0001);
	aimbs_put16(&fr->data, bslen);

	aimbs_putle16(&fr->data, bslen - 2);
	aimbs_putle32(&fr->data, atoi(sess->sn));
	aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
	aimbs_putle16(&fr->data, snacid); /* eh. */

	/* From libicq200-0.3.2/src/SNAC-SRV.cpp */
	aimbs_putle16(&fr->data, 0x8214);
	aimbs_put16(&fr->data, 0x0001);
	aimbs_put16(&fr->data, 0x0016);
	aimbs_put32(&fr->data, 0x00000000);
	aimbs_put32(&fr->data, 0x00000000);
	aimbs_put32(&fr->data, 0x00000000);
	aimbs_put32(&fr->data, 0x00000000);

	aimbs_put16(&fr->data, 0x0000);
	aimbs_put16(&fr->data, xmllen);
	aimbs_putraw(&fr->data, xml, xmllen);

	aim_tx_enqueue(sess, fr);

	free(xml);

	return 0;
}
Exemple #8
0
faim_export int aim_icq_sendsms(aim_session_t *sess, const char *dest, const char *body)
{
	aim_conn_t *conn;
	aim_frame_t *fr;
	aim_snacid_t snacid;
	int bslen;
	int a;
	char *xml;
	int xmllen;
	char timestr[30];
	time_t t;
	struct tm *tm;

	if (!body || !strlen(body))
		return -EINVAL;

	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
		return -EINVAL;

	time(&t);
	tm = gmtime(&t);
	strftime(timestr, 30, "%a, %d %b %Y %T %Z", tm);
	xmllen = 17 + 13 + strlen(dest) + 14 + 6 + strlen(body) + 7 +
			25 + 13 + strlen(sess->sn) + 14 +
			14 + strlen(sess->sn /* should be nick */) + 15 +
			18 + 2 + 19 + 6 + strlen(timestr) + 7 + 18 + 1;

	bslen = 2 + 4 + 2 + 2 + 2 + 2 + 2 + 16 + 4 + xmllen;

	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
		return -ENOMEM;

	xml = (char *) malloc(xmllen);
	snprintf(xml, xmllen, "<icq_sms_message><destination>%s</destination>"\
			"<text>%s</text><codepage>1252</codepage>"\
			"<senders_UIN>%s</senders_UIN>"\
			"<senders_name>%s</senders_name>"\
			"<delivery_receipt>No</delivery_receipt>"\
			"<time>%s</time></icq_sms_message>",
			dest, body, sess->sn, sess->sn /* should be nick */, timestr);

	snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
	aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);

	/* For simplicity, don't bother using a tlvlist */
	aimbs_put16(&fr->data, 0x0001);
	aimbs_put16(&fr->data, bslen);

	aimbs_putle16(&fr->data, bslen - 2);
	aimbs_putle32(&fr->data, atoi(sess->sn));
	aimbs_putle16(&fr->data, 2000); /* I command thee. */
	aimbs_putle16(&fr->data, snacid); /* eh. */
	aimbs_put16(&fr->data, 0x8214); /* SMS send subtype */
	aimbs_put16(&fr->data, 0x0001);
	aimbs_put16(&fr->data, 0x0016);
	for(a = 0; a < 16; a++)
		aimbs_put8(&fr->data, 0x00);
	aimbs_put32(&fr->data, xmllen); /* yes, this has to be 32 bits */
	aimbs_putraw(&fr->data, xml, xmllen);

	aim_tx_enqueue(sess, fr);

	free(xml);

	return 0;
}