source: libfaim/buddylist.c @ 08e9842

barnowl_perlaimdebianowlrelease-1.10release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 08e9842 was cf02dd6, checked in by James M. Kretchmar <kretch@mit.edu>, 21 years ago
*** empty log message ***
  • Property mode set to 100644
File size: 6.5 KB
Line 
1/*
2 * Family 0x0003 - Old-style Buddylist Management (non-SSI).
3 *
4 */
5
6#define FAIM_INTERNAL
7#include <aim.h>
8
9#include <string.h>
10
11/*
12 * Subtype 0x0002 - Request rights.
13 *
14 * Request Buddy List rights.
15 *
16 */
17faim_export int aim_buddylist_reqrights(aim_session_t *sess, aim_conn_t *conn)
18{
19        return aim_genericreq_n_snacid(sess, conn, 0x0003, 0x0002);
20}
21
22/*
23 * Subtype 0x0003 - Rights.
24 *
25 */
26static int rights(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
27{
28        aim_rxcallback_t userfunc;
29        aim_tlvlist_t *tlvlist;
30        fu16_t maxbuddies = 0, maxwatchers = 0;
31        int ret = 0;
32
33        /*
34         * TLVs follow
35         */
36        tlvlist = aim_tlvlist_read(bs);
37
38        /*
39         * TLV type 0x0001: Maximum number of buddies.
40         */
41        if (aim_tlv_gettlv(tlvlist, 0x0001, 1))
42                maxbuddies = aim_tlv_get16(tlvlist, 0x0001, 1);
43
44        /*
45         * TLV type 0x0002: Maximum number of watchers.
46         *
47         * Watchers are other users who have you on their buddy
48         * list.  (This is called the "reverse list" by a certain
49         * other IM protocol.)
50         *
51         */
52        if (aim_tlv_gettlv(tlvlist, 0x0002, 1))
53                maxwatchers = aim_tlv_get16(tlvlist, 0x0002, 1);
54
55        /*
56         * TLV type 0x0003: Unknown.
57         *
58         * ICQ only?
59         */
60
61        if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
62                ret = userfunc(sess, rx, maxbuddies, maxwatchers);
63
64        aim_tlvlist_free(&tlvlist);
65
66        return ret; 
67}
68
69/*
70 * Subtype 0x0004 - Add buddy to list.
71 *
72 * Adds a single buddy to your buddy list after login.
73 * XXX This should just be an extension of setbuddylist()
74 *
75 */
76faim_export int aim_buddylist_addbuddy(aim_session_t *sess, aim_conn_t *conn, const char *sn)
77{
78        aim_frame_t *fr;
79        aim_snacid_t snacid;
80
81        if (!sn || !strlen(sn))
82                return -EINVAL;
83
84        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn))))
85                return -ENOMEM;
86
87        snacid = aim_cachesnac(sess, 0x0003, 0x0004, 0x0000, sn, strlen(sn)+1);
88        aim_putsnac(&fr->data, 0x0003, 0x0004, 0x0000, snacid);
89
90        aimbs_put8(&fr->data, strlen(sn));
91        aimbs_putraw(&fr->data, sn, strlen(sn));
92
93        aim_tx_enqueue(sess, fr);
94
95        return 0;
96}
97
98/*
99 * Subtype 0x0004 - Add multiple buddies to your buddy list.
100 *
101 * This just builds the "set buddy list" command then queues it.
102 *
103 * buddy_list = "Screen Name One&ScreenNameTwo&";
104 *
105 * XXX Clean this up. 
106 *
107 */
108faim_export int aim_buddylist_set(aim_session_t *sess, aim_conn_t *conn, const char *buddy_list)
109{
110        aim_frame_t *fr;
111        aim_snacid_t snacid;
112        int len = 0;
113        char *localcpy = NULL;
114        char *tmpptr = NULL;
115
116        if (!buddy_list || !(localcpy = strdup(buddy_list))) 
117                return -EINVAL;
118
119        for (tmpptr = strtok(localcpy, "&"); tmpptr; ) {
120                faimdprintf(sess, 2, "---adding: %s (%d)\n", tmpptr, strlen(tmpptr));
121                len += 1 + strlen(tmpptr);
122                tmpptr = strtok(NULL, "&");
123        }
124
125        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+len)))
126                return -ENOMEM;
127
128        snacid = aim_cachesnac(sess, 0x0003, 0x0004, 0x0000, NULL, 0);
129        aim_putsnac(&fr->data, 0x0003, 0x0004, 0x0000, snacid);
130
131        strncpy(localcpy, buddy_list, strlen(buddy_list) + 1);
132
133        for (tmpptr = strtok(localcpy, "&"); tmpptr; ) {
134
135                faimdprintf(sess, 2, "---adding: %s (%d)\n", tmpptr, strlen(tmpptr));
136
137                aimbs_put8(&fr->data, strlen(tmpptr));
138                aimbs_putraw(&fr->data, tmpptr, strlen(tmpptr));
139                tmpptr = strtok(NULL, "&");
140        }
141
142        aim_tx_enqueue(sess, fr);
143
144        free(localcpy);
145
146        return 0;
147}
148
149/*
150 * Subtype 0x0005 - Remove buddy from list.
151 *
152 * XXX generalise to support removing multiple buddies (basically, its
153 * the same as setbuddylist() but with a different snac subtype).
154 *
155 */
156faim_export int aim_buddylist_removebuddy(aim_session_t *sess, aim_conn_t *conn, const char *sn)
157{
158        aim_frame_t *fr;
159        aim_snacid_t snacid;
160
161        if (!sn || !strlen(sn))
162                return -EINVAL;
163
164        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn))))
165                return -ENOMEM;
166
167        snacid = aim_cachesnac(sess, 0x0003, 0x0005, 0x0000, sn, strlen(sn)+1);
168        aim_putsnac(&fr->data, 0x0003, 0x0005, 0x0000, snacid);
169
170        aimbs_put8(&fr->data, strlen(sn));
171        aimbs_putraw(&fr->data, sn, strlen(sn));
172
173        aim_tx_enqueue(sess, fr);
174
175        return 0;
176}
177
178/*
179 * Subtype 0x000b
180 *
181 * XXX Why would we send this?
182 *
183 */
184faim_export int aim_buddylist_oncoming(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *info)
185{
186        aim_frame_t *fr;
187        aim_snacid_t snacid;
188
189        if (!sess || !conn || !info)
190                return -EINVAL;
191
192        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152)))
193                return -ENOMEM;
194
195        snacid = aim_cachesnac(sess, 0x0003, 0x000b, 0x0000, NULL, 0);
196       
197        aim_putsnac(&fr->data, 0x0003, 0x000b, 0x0000, snacid);
198        aim_putuserinfo(&fr->data, info);
199
200        aim_tx_enqueue(sess, fr);
201
202        return 0;
203}
204
205/*
206 * Subtype 0x000c
207 *
208 * XXX Why would we send this?
209 *
210 */
211faim_export int aim_buddylist_offgoing(aim_session_t *sess, aim_conn_t *conn, const char *sn)
212{
213        aim_frame_t *fr;
214        aim_snacid_t snacid;
215
216        if (!sess || !conn || !sn)
217                return -EINVAL;
218
219        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn))))
220                return -ENOMEM;
221
222        snacid = aim_cachesnac(sess, 0x0003, 0x000c, 0x0000, NULL, 0);
223       
224        aim_putsnac(&fr->data, 0x0003, 0x000c, 0x0000, snacid);
225        aimbs_put8(&fr->data, strlen(sn));
226        aimbs_putraw(&fr->data, sn, strlen(sn));
227
228        aim_tx_enqueue(sess, fr);
229
230        return 0;
231}
232
233/*
234 * Subtypes 0x000b and 0x000c - Change in buddy status
235 *
236 * Oncoming Buddy notifications contain a subset of the
237 * user information structure.  It's close enough to run
238 * through aim_info_extract() however.
239 *
240 * Although the offgoing notification contains no information,
241 * it is still in a format parsable by aim_info_extract().
242 *
243 */
244static int buddychange(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
245{
246        int ret = 0;
247        aim_userinfo_t userinfo;
248        aim_rxcallback_t userfunc;
249
250        aim_info_extract(sess, bs, &userinfo);
251
252        if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
253                ret = userfunc(sess, rx, &userinfo);
254
255        if (snac->subtype == 0x000b)
256                aim_locate_requestuserinfo(sess, userinfo.sn);
257        aim_info_free(&userinfo);
258
259        return ret;
260}
261
262static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
263{
264
265        if (snac->subtype == 0x0003)
266                return rights(sess, mod, rx, snac, bs);
267        else if ((snac->subtype == 0x000b) || (snac->subtype == 0x000c))
268                return buddychange(sess, mod, rx, snac, bs);
269
270        return 0;
271}
272
273faim_internal int buddylist_modfirst(aim_session_t *sess, aim_module_t *mod)
274{
275
276        mod->family = 0x0003;
277        mod->version = 0x0001;
278        mod->toolid = 0x0110;
279        mod->toolversion = 0x0629;
280        mod->flags = 0;
281        strncpy(mod->name, "buddylist", sizeof(mod->name));
282        mod->snachandler = snachandler;
283
284        return 0;
285}
Note: See TracBrowser for help on using the repository browser.