source: libfaim/buddylist.c @ 6e3980e

barnowl_perlaimdebianowlrelease-1.10release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 6e3980e 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
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 */
[cf02dd6]17faim_export int aim_buddylist_reqrights(aim_session_t *sess, aim_conn_t *conn)
[5e53c4a]18{
[cf02dd6]19        return aim_genericreq_n_snacid(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         */
[cf02dd6]36        tlvlist = aim_tlvlist_read(bs);
[5e53c4a]37
38        /*
39         * TLV type 0x0001: Maximum number of buddies.
40         */
[cf02dd6]41        if (aim_tlv_gettlv(tlvlist, 0x0001, 1))
42                maxbuddies = aim_tlv_get16(tlvlist, 0x0001, 1);
[5e53c4a]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         */
[cf02dd6]52        if (aim_tlv_gettlv(tlvlist, 0x0002, 1))
53                maxwatchers = aim_tlv_get16(tlvlist, 0x0002, 1);
[5e53c4a]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
[cf02dd6]64        aim_tlvlist_free(&tlvlist);
[5e53c4a]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 */
[cf02dd6]76faim_export int aim_buddylist_addbuddy(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 */
[cf02dd6]108faim_export int aim_buddylist_set(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 */
[cf02dd6]156faim_export int aim_buddylist_removebuddy(aim_session_t *sess, aim_conn_t *conn, const char *sn)
[5e53c4a]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 */
[cf02dd6]184faim_export int aim_buddylist_oncoming(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *info)
[862371b]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 */
[cf02dd6]211faim_export int aim_buddylist_offgoing(aim_session_t *sess, aim_conn_t *conn, const char *sn)
[862371b]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
[cf02dd6]255        if (snac->subtype == 0x000b)
256                aim_locate_requestuserinfo(sess, userinfo.sn);
[e374dee]257        aim_info_free(&userinfo);
258
259        return ret;
[862371b]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;
[e374dee]279        mod->toolversion = 0x0629;
[862371b]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.