source: libfaim/buddylist.c @ 5d9c664

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