source: libfaim/buddylist.c @ 11a7c6a

barnowl_perlaimdebianowlrelease-1.10release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 11a7c6a was e374dee, checked in by James M. Kretchmar <kretch@mit.edu>, 21 years ago
*** empty log message ***
  • Property mode set to 100644
File size: 6.4 KB
RevLine 
[862371b]1/*
2 * Family 0x0003 - Old-style Buddylist Management (non-SSI).
3 *
4 */
[5e53c4a]5
6#define FAIM_INTERNAL
7#include <aim.h>
8
[e374dee]9#include <string.h>
10
[5e53c4a]11/*
[862371b]12 * Subtype 0x0002 - Request rights.
[5e53c4a]13 *
[862371b]14 * Request Buddy List rights.
[5e53c4a]15 *
16 */
[862371b]17faim_export int aim_bos_reqbuddyrights(aim_session_t *sess, aim_conn_t *conn)
[5e53c4a]18{
[862371b]19        return aim_genericreq_n(sess, conn, 0x0003, 0x0002);
[5e53c4a]20}
21
[862371b]22/*
23 * Subtype 0x0003 - Rights.
24 *
25 */
[5e53c4a]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_readtlvchain(bs);
37
38        /*
39         * TLV type 0x0001: Maximum number of buddies.
40         */
41        if (aim_gettlv(tlvlist, 0x0001, 1))
42                maxbuddies = aim_gettlv16(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_gettlv(tlvlist, 0x0002, 1))
53                maxwatchers = aim_gettlv16(tlvlist, 0x0002, 1);
54
[862371b]55        /*
56         * TLV type 0x0003: Unknown.
57         *
58         * ICQ only?
59         */
60
[5e53c4a]61        if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
62                ret = userfunc(sess, rx, maxbuddies, maxwatchers);
63
64        aim_freetlvchain(&tlvlist);
65
66        return ret; 
67}
68
[862371b]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_add_buddy(aim_session_t *sess, aim_conn_t *conn, const char *sn)
[5e53c4a]77{
[862371b]78        aim_frame_t *fr;
79        aim_snacid_t snacid;
[5e53c4a]80
[862371b]81        if (!sn || !strlen(sn))
82                return -EINVAL;
[5e53c4a]83
[862371b]84        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn))))
85                return -ENOMEM;
[5e53c4a]86
[862371b]87        snacid = aim_cachesnac(sess, 0x0003, 0x0004, 0x0000, sn, strlen(sn)+1);
88        aim_putsnac(&fr->data, 0x0003, 0x0004, 0x0000, snacid);
[5e53c4a]89
[862371b]90        aimbs_put8(&fr->data, strlen(sn));
91        aimbs_putraw(&fr->data, sn, strlen(sn));
92
93        aim_tx_enqueue(sess, fr);
[5e53c4a]94
95        return 0;
96}
97
98/*
[862371b]99 * Subtype 0x0004 - Add multiple buddies to your buddy list.
[5e53c4a]100 *
[862371b]101 * This just builds the "set buddy list" command then queues it.
[5e53c4a]102 *
[862371b]103 * buddy_list = "Screen Name One&ScreenNameTwo&";
104 *
105 * XXX Clean this up. 
[5e53c4a]106 *
107 */
[862371b]108faim_export int aim_bos_setbuddylist(aim_session_t *sess, aim_conn_t *conn, const char *buddy_list)
[5e53c4a]109{
110        aim_frame_t *fr;
111        aim_snacid_t snacid;
[862371b]112        int len = 0;
113        char *localcpy = NULL;
114        char *tmpptr = NULL;
[5e53c4a]115
[862371b]116        if (!buddy_list || !(localcpy = strdup(buddy_list))) 
[5e53c4a]117                return -EINVAL;
118
[862371b]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)))
[5e53c4a]126                return -ENOMEM;
127
[862371b]128        snacid = aim_cachesnac(sess, 0x0003, 0x0004, 0x0000, NULL, 0);
[5e53c4a]129        aim_putsnac(&fr->data, 0x0003, 0x0004, 0x0000, snacid);
130
[862371b]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        }
[5e53c4a]141
142        aim_tx_enqueue(sess, fr);
143
[862371b]144        free(localcpy);
145
[5e53c4a]146        return 0;
147}
148
149/*
[862371b]150 * Subtype 0x0005 - Remove buddy from list.
151 *
[5e53c4a]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_remove_buddy(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
[862371b]178/*
179 * Subtype 0x000b
180 *
181 * XXX Why would we send this?
182 *
183 */
184faim_export int aim_sendbuddyoncoming(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_sendbuddyoffgoing(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
[e374dee]237 * user information structure.  It's close enough to run
238 * through aim_info_extract() however.
[862371b]239 *
240 * Although the offgoing notification contains no information,
[e374dee]241 * it is still in a format parsable by aim_info_extract().
[862371b]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{
[e374dee]246        int ret = 0;
[862371b]247        aim_userinfo_t userinfo;
248        aim_rxcallback_t userfunc;
249
[e374dee]250        aim_info_extract(sess, bs, &userinfo);
[862371b]251
252        if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
[e374dee]253                ret = userfunc(sess, rx, &userinfo);
[862371b]254
[e374dee]255        aim_info_free(&userinfo);
256
257        return ret;
[862371b]258}
259
260static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
261{
262
263        if (snac->subtype == 0x0003)
264                return rights(sess, mod, rx, snac, bs);
265        else if ((snac->subtype == 0x000b) || (snac->subtype == 0x000c))
266                return buddychange(sess, mod, rx, snac, bs);
267
268        return 0;
269}
270
271faim_internal int buddylist_modfirst(aim_session_t *sess, aim_module_t *mod)
272{
273
274        mod->family = 0x0003;
275        mod->version = 0x0001;
276        mod->toolid = 0x0110;
[e374dee]277        mod->toolversion = 0x0629;
[862371b]278        mod->flags = 0;
279        strncpy(mod->name, "buddylist", sizeof(mod->name));
280        mod->snachandler = snachandler;
281
282        return 0;
283}
Note: See TracBrowser for help on using the repository browser.