1535
|
1
|
|
2 /*
|
|
3 * aim_search.c
|
|
4 *
|
|
5 * TODO: Add aim_usersearch_name()
|
|
6 *
|
|
7 */
|
|
8
|
|
9 #define FAIM_INTERNAL
|
|
10 #include <aim.h>
|
|
11
|
|
12 faim_export unsigned long aim_usersearch_address(struct aim_session_t *sess,
|
|
13 struct aim_conn_t *conn,
|
|
14 char *address)
|
|
15 {
|
|
16 struct command_tx_struct *newpacket;
|
|
17
|
|
18 if (!address)
|
|
19 return -1;
|
|
20
|
|
21 if (!(newpacket = aim_tx_new(sess, conn, AIM_FRAMETYPE_OSCAR, 0x0002, 10+strlen(address))))
|
|
22 return -1;
|
|
23
|
|
24 newpacket->lock = 1;
|
|
25
|
|
26 aim_putsnac(newpacket->data, 0x000a, 0x0002, 0x0000, sess->snac_nextid);
|
|
27
|
|
28 aimutil_putstr(newpacket->data+10, address, strlen(address));
|
|
29
|
|
30 aim_tx_enqueue(sess, newpacket);
|
|
31
|
|
32 aim_cachesnac(sess, 0x000a, 0x0002, 0x0000, address, strlen(address)+1);
|
|
33
|
|
34 return sess->snac_nextid;
|
|
35 }
|
|
36
|
1649
|
37 /* XXX can this be integrated with the rest of the error handling? */
|
|
38 static int error(struct aim_session_t *sess, aim_module_t *mod, struct command_rx_struct *rx, aim_modsnac_t *snac, unsigned char *data, int datalen)
|
1535
|
39 {
|
1649
|
40 int ret = 0;
|
1535
|
41 rxcallback_t userfunc;
|
1649
|
42 struct aim_snac_t *snac2;
|
1535
|
43
|
1649
|
44 /* XXX the modules interface should have already retrieved this for us */
|
|
45 if(!(snac2 = aim_remsnac(sess, snac->id))) {
|
|
46 faimdprintf(sess, 2, "couldn't get a snac for 0x%08lx\n", snac->id);
|
1535
|
47 return 0;
|
|
48 }
|
|
49
|
1649
|
50 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
|
|
51 ret = userfunc(sess, rx, snac2->data /* address */);
|
1535
|
52
|
1649
|
53 /* XXX freesnac()? */
|
|
54 if (snac2) {
|
|
55 if(snac2->data)
|
|
56 free(snac2->data);
|
|
57 free(snac2);
|
1535
|
58 }
|
|
59
|
|
60 return ret;
|
|
61 }
|
1649
|
62
|
|
63 static int reply(struct aim_session_t *sess, aim_module_t *mod, struct command_rx_struct *rx, aim_modsnac_t *snac, unsigned char *data, int datalen)
|
1535
|
64 {
|
1649
|
65 unsigned int j, m, ret = 0;
|
1535
|
66 struct aim_tlvlist_t *tlvlist;
|
|
67 char *cur = NULL, *buf = NULL;
|
|
68 rxcallback_t userfunc;
|
1649
|
69 struct aim_snac_t *snac2;
|
1535
|
70
|
1649
|
71 if (!(snac2 = aim_remsnac(sess, snac->id))) {
|
|
72 faimdprintf(sess, 2, "faim: couldn't get a snac for 0x%08lx\n", snac->id);
|
1535
|
73 return 0;
|
|
74 }
|
|
75
|
1649
|
76 if (!(tlvlist = aim_readtlvchain(data, datalen)))
|
|
77 return 0;
|
1535
|
78
|
|
79 j = 0;
|
|
80
|
|
81 m = aim_counttlvchain(&tlvlist);
|
|
82
|
|
83 while((cur = aim_gettlv_str(tlvlist, 0x0001, j+1)) && j < m) {
|
|
84 if(!(buf = realloc(buf, (j+1) * (MAXSNLEN+1))))
|
|
85 faimdprintf(sess, 2, "faim: couldn't realloc buf. oh well.\n");
|
|
86
|
|
87 strncpy(&buf[j * (MAXSNLEN+1)], cur, MAXSNLEN);
|
|
88 free(cur);
|
|
89
|
|
90 j++;
|
|
91 }
|
|
92
|
|
93 aim_freetlvchain(&tlvlist);
|
|
94
|
1649
|
95 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
|
|
96 ret = userfunc(sess, rx, snac2->data /* address */, j, buf);
|
1535
|
97
|
1649
|
98 /* XXX freesnac()? */
|
|
99 if(snac2) {
|
|
100 if(snac2->data)
|
|
101 free(snac2->data);
|
|
102 free(snac2);
|
1535
|
103 }
|
|
104
|
|
105 if(buf)
|
|
106 free(buf);
|
|
107
|
|
108 return ret;
|
|
109 }
|
1649
|
110
|
|
111 static int snachandler(struct aim_session_t *sess, aim_module_t *mod, struct command_rx_struct *rx, aim_modsnac_t *snac, unsigned char *data, int datalen)
|
|
112 {
|
|
113
|
|
114 if (snac->subtype == 0x0001)
|
|
115 return error(sess, mod, rx, snac, data, datalen);
|
|
116 else if (snac->subtype == 0x0003)
|
|
117 return reply(sess, mod, rx, snac, data, datalen);
|
|
118
|
|
119 return 0;
|
|
120 }
|
|
121
|
|
122 faim_internal int search_modfirst(struct aim_session_t *sess, aim_module_t *mod)
|
|
123 {
|
|
124
|
|
125 mod->family = 0x000a;
|
|
126 mod->version = 0x0000;
|
|
127 mod->flags = 0;
|
|
128 strncpy(mod->name, "search", sizeof(mod->name));
|
|
129 mod->snachandler = snachandler;
|
|
130
|
|
131 return 0;
|
|
132 }
|