aboutsummaryrefslogtreecommitdiffstats
path: root/protocols/oscar/search.c
blob: 30d392ae60e11d73cadf5e26d4759e9947d3bef2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/*
 * aim_search.c
 *
 * TODO: Add aim_usersearch_name()
 *
 */

#include <aim.h>

/* XXX can this be integrated with the rest of the error handling? */
static int error(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
{
	int ret = 0;
	aim_rxcallback_t userfunc;
	aim_snac_t *snac2;

	/* XXX the modules interface should have already retrieved this for us */
	if (!(snac2 = aim_remsnac(sess, snac->id))) {
		imcb_error(sess->aux_data, "couldn't get snac");
		return 0;
	}

	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) {
		ret = userfunc(sess, rx, snac2->data /* address */);
	}

	/* XXX freesnac()? */
	if (snac2) {
		g_free(snac2->data);
	}
	g_free(snac2);

	return ret;
}

static int reply(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
{
	int j = 0, m, ret = 0;
	aim_tlvlist_t *tlvlist;
	char *cur = NULL, *buf = NULL;
	aim_rxcallback_t userfunc;
	aim_snac_t *snac2;
	char *searchaddr = NULL;

	if ((snac2 = aim_remsnac(sess, snac->id))) {
		searchaddr = (char *) snac2->data;
	}

	tlvlist = aim_readtlvchain(bs);
	m = aim_counttlvchain(&tlvlist);

	/* XXX uhm. */
	while ((cur = aim_gettlv_str(tlvlist, 0x0001, j + 1)) && j < m) {
		buf = g_realloc(buf, (j + 1) * (MAXSNLEN + 1));

		strncpy(&buf[j * (MAXSNLEN + 1)], cur, MAXSNLEN);
		g_free(cur);

		j++;
	}

	aim_freetlvchain(&tlvlist);

	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) {
		ret = userfunc(sess, rx, searchaddr, j, buf);
	}

	/* XXX freesnac()? */
	if (snac2) {
		g_free(snac2->data);
	}
	g_free(snac2);

	g_free(buf);

	return ret;
}

static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
{

	if (snac->subtype == 0x0001) {
		return error(sess, mod, rx, snac, bs);
	} else if (snac->subtype == 0x0003) {
		return reply(sess, mod, rx, snac, bs);
	}

	return 0;
}

int search_modfirst(aim_session_t *sess, aim_module_t *mod)
{

	mod->family = 0x000a;
	mod->version = 0x0001;
	mod->toolid = 0x0110;
	mod->toolversion = 0x0629;
	mod->flags = 0;
	strncpy(mod->name, "search", sizeof(mod->name));
	mod->snachandler = snachandler;

	return 0;
}
i; /* Create a reverse-lookup for the Base64 sequence. */ if( b64rev[0] == 0 ) { memset( b64rev, 0xff, 256 ); for( i = 0; i <= 64; i ++ ) b64rev[(int)real_b64[i]] = i; } len = strlen( in ); *out = g_malloc( ( len + 6 ) / 4 * 3 ); len = base64_decode_real( (unsigned char*) in, *out, b64rev ); *out = g_realloc( *out, len + 1 ); out[0][len] = 0; /* Zero termination can't hurt. */ return len; } int base64_decode_real(const unsigned char *in, unsigned char *out, char *b64rev) { int i, outlen = 0; for( i = 0; in[i] && in[i+1] && in[i+2] && in[i+3]; i += 4 ) { int sx; sx = b64rev[(int)in[i+0]]; if( sx >= 64 ) break; out[outlen] = ( sx << 2 ) & 0xfc; sx = b64rev[(int)in[i+1]]; if( sx >= 64 ) break; out[outlen] |= ( sx >> 4 ) & 0x03; outlen ++; out[outlen] = ( sx << 4 ) & 0xf0; sx = b64rev[(int)in[i+2]]; if( sx >= 64 ) break; out[outlen] |= ( sx >> 2 ) & 0x0f; outlen ++; out[outlen] = ( sx << 6 ) & 0xc0; sx = b64rev[(int)in[i+3]]; if( sx >= 64 ) break; out[outlen] |= sx; outlen ++; } /* If sx > 64 the base64 string was damaged. Should we ignore this? */ return outlen; }