source: libfaim/misc.c @ e075479

barnowl_perlaimdebianowlrelease-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since e075479 was 5e53c4a, checked in by James M. Kretchmar <kretch@mit.edu>, 18 years ago
*** empty log message ***
  • Property mode set to 100644
File size: 10.0 KB
Line 
1
2/*
3 * aim_misc.c
4 *
5 * TODO: Seperate a lot of this into an aim_bos.c.
6 *
7 * Other things...
8 *
9 *   - Idle setting
10 *
11 *
12 */
13
14#define FAIM_INTERNAL
15#include <aim.h>
16
17/*
18 * aim_bos_setbuddylist(buddylist)
19 *
20 * This just builds the "set buddy list" command then queues it.
21 *
22 * buddy_list = "Screen Name One&ScreenNameTwo&";
23 *
24 * TODO: Clean this up. 
25 *
26 * XXX: I can't stress the TODO enough.
27 *
28 */
29faim_export int aim_bos_setbuddylist(aim_session_t *sess, aim_conn_t *conn, const char *buddy_list)
30{
31        aim_frame_t *fr;
32        aim_snacid_t snacid;
33        int len = 0;
34        char *localcpy = NULL;
35        char *tmpptr = NULL;
36
37        if (!buddy_list || !(localcpy = strdup(buddy_list))) 
38                return -EINVAL;
39
40        for (tmpptr = strtok(localcpy, "&"); tmpptr; ) {
41                faimdprintf(sess, 2, "---adding: %s (%d)\n", tmpptr, strlen(tmpptr));
42                len += 1 + strlen(tmpptr);
43                tmpptr = strtok(NULL, "&");
44        }
45
46        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+len)))
47                return -ENOMEM;
48
49        snacid = aim_cachesnac(sess, 0x0003, 0x0004, 0x0000, NULL, 0);
50        aim_putsnac(&fr->data, 0x0003, 0x0004, 0x0000, snacid);
51
52        strncpy(localcpy, buddy_list, strlen(buddy_list) + 1);
53
54        for (tmpptr = strtok(localcpy, "&"); tmpptr; ) {
55
56                faimdprintf(sess, 2, "---adding: %s (%d)\n", tmpptr, strlen(tmpptr));
57
58                aimbs_put8(&fr->data, strlen(tmpptr));
59                aimbs_putraw(&fr->data, tmpptr, strlen(tmpptr));
60                tmpptr = strtok(NULL, "&");
61        }
62
63        aim_tx_enqueue(sess, fr);
64
65        free(localcpy);
66
67        return 0;
68}
69
70/*
71 * aim_bos_setprofile(profile)
72 *
73 * Gives BOS your profile.
74 *
75 */
76faim_export int aim_bos_setprofile(aim_session_t *sess, aim_conn_t *conn, const char *profile, const char *awaymsg, fu32_t caps)
77{
78        static const char defencoding[] = {"text/aolrtf; charset=\"us-ascii\""};
79        aim_frame_t *fr;
80        aim_tlvlist_t *tl = NULL;
81        aim_snacid_t snacid;
82
83        /* Build to packet first to get real length */
84        if (profile) {
85                aim_addtlvtochain_raw(&tl, 0x0001, strlen(defencoding), defencoding);
86                aim_addtlvtochain_raw(&tl, 0x0002, strlen(profile), profile);
87        }
88
89        /*
90         * So here's how this works:
91         *   - You are away when you have a non-zero-length type 4 TLV stored.
92         *   - You become unaway when you clear the TLV with a zero-length
93         *       type 4 TLV.
94         *   - If you do not send the type 4 TLV, your status does not change
95         *       (that is, if you were away, you'll remain away).
96         */
97        if (awaymsg) {
98                if (strlen(awaymsg)) {
99                        aim_addtlvtochain_raw(&tl, 0x0003, strlen(defencoding), defencoding);
100                        aim_addtlvtochain_raw(&tl, 0x0004, strlen(awaymsg), awaymsg);
101                } else
102                        aim_addtlvtochain_noval(&tl, 0x0004);
103        }
104
105        aim_addtlvtochain_caps(&tl, 0x0005, caps);
106
107        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + aim_sizetlvchain(&tl))))
108                return -ENOMEM;
109
110        snacid = aim_cachesnac(sess, 0x0002, 0x0004, 0x0000, NULL, 0);
111       
112        aim_putsnac(&fr->data, 0x0002, 0x004, 0x0000, snacid);
113        aim_writetlvchain(&fr->data, &tl);
114        aim_freetlvchain(&tl);
115
116        aim_tx_enqueue(sess, fr);
117
118        return 0;
119}
120
121/*
122 * aim_bos_reqbuddyrights()
123 *
124 * Request Buddy List rights.
125 *
126 */
127faim_export int aim_bos_reqbuddyrights(aim_session_t *sess, aim_conn_t *conn)
128{
129        return aim_genericreq_n(sess, conn, 0x0003, 0x0002);
130}
131
132/*
133 * Send a warning to destsn.
134 *
135 * Flags:
136 *  AIM_WARN_ANON  Send as an anonymous (doesn't count as much)
137 *
138 * returns -1 on error (couldn't alloc packet), 0 on success.
139 *
140 */
141faim_export int aim_send_warning(aim_session_t *sess, aim_conn_t *conn, const char *destsn, fu32_t flags)
142{
143        aim_frame_t *fr;
144        aim_snacid_t snacid;
145        fu16_t outflags = 0x0000;
146
147        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, strlen(destsn)+13)))
148                return -ENOMEM;
149
150        snacid = aim_cachesnac(sess, 0x0004, 0x0008, 0x0000, destsn, strlen(destsn)+1);
151
152        aim_putsnac(&fr->data, 0x0004, 0x0008, 0x0000, snacid);
153
154        if (flags & AIM_WARN_ANON)
155                outflags |= 0x0001;
156
157        aimbs_put16(&fr->data, outflags); 
158        aimbs_put8(&fr->data, strlen(destsn));
159        aimbs_putraw(&fr->data, destsn, strlen(destsn));
160
161        aim_tx_enqueue(sess, fr);
162
163        return 0;
164}
165
166/*
167 * Generic routine for sending commands.
168 *
169 *
170 * I know I can do this in a smarter way...but I'm not thinking straight
171 * right now...
172 *
173 * I had one big function that handled all three cases, but then it broke
174 * and I split it up into three.  But then I fixed it.  I just never went
175 * back to the single.  I don't see any advantage to doing it either way.
176 *
177 */
178faim_internal int aim_genericreq_n(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t subtype)
179{
180        aim_frame_t *fr;
181        aim_snacid_t snacid = 0x00000000;
182
183        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10)))
184                return -ENOMEM;
185
186        aim_putsnac(&fr->data, family, subtype, 0x0000, snacid);
187
188        aim_tx_enqueue(sess, fr);
189
190        return 0;
191}
192
193faim_internal int aim_genericreq_n_snacid(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t subtype)
194{
195        aim_frame_t *fr;
196        aim_snacid_t snacid;
197
198        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10)))
199                return -ENOMEM;
200
201        snacid = aim_cachesnac(sess, family, subtype, 0x0000, NULL, 0);
202        aim_putsnac(&fr->data, family, subtype, 0x0000, snacid);
203
204        aim_tx_enqueue(sess, fr);
205
206        return 0;
207}
208
209faim_internal int aim_genericreq_l(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t subtype, fu32_t *longdata)
210{
211        aim_frame_t *fr;
212        aim_snacid_t snacid;
213
214        if (!longdata)
215                return aim_genericreq_n(sess, conn, family, subtype);
216
217        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4)))
218                return -ENOMEM; 
219
220        snacid = aim_cachesnac(sess, family, subtype, 0x0000, NULL, 0);
221
222        aim_putsnac(&fr->data, family, subtype, 0x0000, snacid);
223        aimbs_put32(&fr->data, *longdata);
224
225        aim_tx_enqueue(sess, fr);
226
227        return 0;
228}
229
230faim_internal int aim_genericreq_s(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t subtype, fu16_t *shortdata)
231{
232        aim_frame_t *fr;
233        aim_snacid_t snacid;
234
235        if (!shortdata)
236                return aim_genericreq_n(sess, conn, family, subtype);
237
238        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+2)))
239                return -ENOMEM; 
240
241        snacid = aim_cachesnac(sess, family, subtype, 0x0000, NULL, 0);
242
243        aim_putsnac(&fr->data, family, subtype, 0x0000, snacid);
244        aimbs_put16(&fr->data, *shortdata);
245
246        aim_tx_enqueue(sess, fr);
247
248        return 0;
249}
250
251/*
252 * aim_bos_reqlocaterights()
253 *
254 * Request Location services rights.
255 *
256 */
257faim_export int aim_bos_reqlocaterights(aim_session_t *sess, aim_conn_t *conn)
258{
259        return aim_genericreq_n(sess, conn, 0x0002, 0x0002);
260}
261
262/*
263 * Set directory profile data (not the same as aim_bos_setprofile!)
264 *
265 * privacy: 1 to allow searching, 0 to disallow.
266 */
267faim_export int aim_setdirectoryinfo(aim_session_t *sess, aim_conn_t *conn, const char *first, const char *middle, const char *last, const char *maiden, const char *nickname, const char *street, const char *city, const char *state, const char *zip, int country, fu16_t privacy) 
268{
269        aim_frame_t *fr;
270        aim_snacid_t snacid;
271        aim_tlvlist_t *tl = NULL;
272
273
274        aim_addtlvtochain16(&tl, 0x000a, privacy);
275
276        if (first)
277                aim_addtlvtochain_raw(&tl, 0x0001, strlen(first), first);
278        if (last)
279                aim_addtlvtochain_raw(&tl, 0x0002, strlen(last), last);
280        if (middle)
281                aim_addtlvtochain_raw(&tl, 0x0003, strlen(middle), middle);
282        if (maiden)
283                aim_addtlvtochain_raw(&tl, 0x0004, strlen(maiden), maiden);
284
285        if (state)
286                aim_addtlvtochain_raw(&tl, 0x0007, strlen(state), state);
287        if (city)
288                aim_addtlvtochain_raw(&tl, 0x0008, strlen(city), city);
289
290        if (nickname)
291                aim_addtlvtochain_raw(&tl, 0x000c, strlen(nickname), nickname);
292        if (zip)
293                aim_addtlvtochain_raw(&tl, 0x000d, strlen(zip), zip);
294
295        if (street)
296                aim_addtlvtochain_raw(&tl, 0x0021, strlen(street), street);
297
298        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_sizetlvchain(&tl))))
299                return -ENOMEM;
300
301        snacid = aim_cachesnac(sess, 0x0002, 0x0009, 0x0000, NULL, 0);
302       
303        aim_putsnac(&fr->data, 0x0002, 0x0009, 0x0000, snacid);
304        aim_writetlvchain(&fr->data, &tl);
305        aim_freetlvchain(&tl);
306
307        aim_tx_enqueue(sess, fr);
308
309        return 0;
310}
311
312/* XXX pass these in better */
313faim_export int aim_setuserinterests(aim_session_t *sess, aim_conn_t *conn, const char *interest1, const char *interest2, const char *interest3, const char *interest4, const char *interest5, fu16_t privacy)
314{
315        aim_frame_t *fr;
316        aim_snacid_t snacid;
317        aim_tlvlist_t *tl = NULL;
318
319        /* ?? privacy ?? */
320        aim_addtlvtochain16(&tl, 0x000a, privacy);
321
322        if (interest1)
323                aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest1), interest1);
324        if (interest2)
325                aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest2), interest2);
326        if (interest3)
327                aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest3), interest3);
328        if (interest4)
329                aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest4), interest4);
330        if (interest5)
331                aim_addtlvtochain_raw(&tl, 0x0000b, strlen(interest5), interest5);
332
333        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_sizetlvchain(&tl))))
334                return -ENOMEM;
335
336        snacid = aim_cachesnac(sess, 0x0002, 0x000f, 0x0000, NULL, 0);
337
338        aim_putsnac(&fr->data, 0x0002, 0x000f, 0x0000, 0);
339        aim_writetlvchain(&fr->data, &tl);
340        aim_freetlvchain(&tl);
341
342        aim_tx_enqueue(sess, fr);
343
344        return 0;
345}
346
347/*
348 * Should be generic enough to handle the errors for all groups.
349 *
350 */
351static int generror(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
352{
353        int ret = 0;
354        int error = 0;
355        aim_rxcallback_t userfunc;
356        aim_snac_t *snac2;
357
358        snac2 = aim_remsnac(sess, snac->id);
359
360        if (aim_bstream_empty(bs))
361                error = aimbs_get16(bs);
362
363        if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
364                ret = userfunc(sess, rx, error, snac2 ? snac2->data : NULL);
365
366        if (snac2)
367                free(snac2->data);
368        free(snac2);
369
370        return ret;
371}
372
373static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
374{
375
376        if (snac->subtype == 0x0001)
377                return generror(sess, mod, rx, snac, bs);
378        else if ((snac->family == 0xffff) && (snac->subtype == 0xffff)) {
379                aim_rxcallback_t userfunc;
380
381                if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
382                        return userfunc(sess, rx);
383        }
384
385        return 0;
386}
387
388faim_internal int misc_modfirst(aim_session_t *sess, aim_module_t *mod)
389{
390
391        mod->family = 0xffff;
392        mod->version = 0x0000;
393        mod->flags = AIM_MODFLAG_MULTIFAMILY;
394        strncpy(mod->name, "misc", sizeof(mod->name));
395        mod->snachandler = snachandler;
396
397        return 0;
398}
399
400
Note: See TracBrowser for help on using the repository browser.