source: libfaim/ssi.c @ 440ce01

barnowl_perlaimdebianowlrelease-1.10release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 440ce01 was 5e53c4a, checked in by James M. Kretchmar <kretch@mit.edu>, 22 years ago
*** empty log message ***
  • Property mode set to 100644
File size: 4.8 KB
Line 
1/*
2 * Server-Side/Stored Information.
3 *
4 * Relatively new facility that allows storing of certain types of information,
5 * such as a users buddy list, permit/deny list, and permit/deny preferences,
6 * to be stored on the server, so that they can be accessed from any client.
7 *
8 * This is entirely too complicated.
9 *
10 */
11
12#define FAIM_INTERNAL
13#include <aim.h>
14
15/*
16 * Request SSI Rights.
17 */
18faim_export int aim_ssi_reqrights(aim_session_t *sess, aim_conn_t *conn)
19{
20        return aim_genericreq_n(sess, conn, 0x0013, 0x0002);
21}
22
23/*
24 * SSI Rights Information.
25 */
26static int parserights(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
27{
28        int ret = 0;
29        aim_rxcallback_t userfunc;
30
31        if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
32                ret = userfunc(sess, rx);
33
34        return ret;
35}
36
37/*
38 * Request SSI Data.
39 *
40 * The data will only be sent if it is newer than the posted local
41 * timestamp and revision.
42 *
43 * Note that the client should never increment the revision, only the server.
44 *
45 */
46faim_export int aim_ssi_reqdata(aim_session_t *sess, aim_conn_t *conn, time_t localstamp, fu16_t localrev)
47{
48        aim_frame_t *fr;
49        aim_snacid_t snacid;
50
51        if (!sess || !conn)
52                return -EINVAL;
53
54        if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4+2)))
55                return -ENOMEM;
56
57        snacid = aim_cachesnac(sess, 0x0013, 0x0005, 0x0000, NULL, 0);
58
59        aim_putsnac(&fr->data, 0x0013, 0x0005, 0x0000, snacid);
60        aimbs_put32(&fr->data, localstamp);
61        aimbs_put16(&fr->data, localrev);
62
63        aim_tx_enqueue(sess, fr);
64
65        return 0;
66}
67
68/*
69 * SSI Data.
70 */
71static int parsedata(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
72{
73        int ret = 0;
74        aim_rxcallback_t userfunc;
75        struct aim_ssi_item *list = NULL;
76        fu8_t fmtver; /* guess */
77        fu16_t itemcount;
78        fu32_t stamp;
79
80        fmtver = aimbs_get8(bs);
81        itemcount = aimbs_get16(bs);
82
83        while (aim_bstream_empty(bs) > 4) { /* last four bytes are stamp */
84                fu16_t namelen, tbslen;
85                struct aim_ssi_item *nl, *el;
86
87                if (!(nl = malloc(sizeof(struct aim_ssi_item))))
88                        break;
89                memset(nl, 0, sizeof(struct aim_ssi_item));
90
91                if ((namelen = aimbs_get16(bs)))
92                        nl->name = aimbs_getstr(bs, namelen);
93                nl->gid = aimbs_get16(bs);
94                nl->bid = aimbs_get16(bs);
95                nl->type = aimbs_get16(bs);
96
97                if ((tbslen = aimbs_get16(bs))) {
98                        aim_bstream_t tbs;
99
100                        aim_bstream_init(&tbs, bs->data + bs->offset /* XXX */, tbslen);
101                        nl->data = (void *)aim_readtlvchain(&tbs);
102                        aim_bstream_advance(bs, tbslen);
103                }
104
105                for (el = list; el && el->next; el = el->next)
106                        ;
107                if (el)
108                        el->next = nl;
109                else
110                        list = nl;
111        }
112
113        stamp = aimbs_get32(bs);
114
115        if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
116                ret = userfunc(sess, rx, fmtver, itemcount, stamp, list);
117
118        while (list) {
119                struct aim_ssi_item *tmp;
120
121                tmp = list->next;
122                aim_freetlvchain((aim_tlvlist_t **)&list->data);
123                free(list);
124                list = tmp;
125        }
126
127        return ret;
128}
129
130/*
131 * SSI Data Enable Presence.
132 *
133 * Should be sent after receiving 13/6 or 13/f to tell the server you
134 * are ready to begin using the list.  It will promptly give you the
135 * presence information for everyone in your list and put your permit/deny
136 * settings into effect.
137 *
138 */
139faim_export int aim_ssi_enable(aim_session_t *sess, aim_conn_t *conn)
140{
141        return aim_genericreq_n(sess, conn, 0x0013, 0x0007);
142}
143
144/*
145 * SSI Begin Data Modification.
146 *
147 * Tells the server you're going to start modifying data.
148 *
149 */
150faim_export int aim_ssi_modbegin(aim_session_t *sess, aim_conn_t *conn)
151{
152        return aim_genericreq_n(sess, conn, 0x0013, 0x0011);
153}
154
155/*
156 * SSI End Data Modification.
157 *
158 * Tells the server you're done modifying data.
159 *
160 */
161faim_export int aim_ssi_modend(aim_session_t *sess, aim_conn_t *conn)
162{
163        return aim_genericreq_n(sess, conn, 0x0013, 0x0012);
164}
165
166/*
167 * SSI Data Unchanged.
168 *
169 * Response to aim_ssi_reqdata() if the server-side data is not newer than
170 * posted local stamp/revision.
171 *
172 */
173static int parsedataunchanged(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
174{
175        int ret = 0;
176        aim_rxcallback_t userfunc;
177
178        if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
179                ret = userfunc(sess, rx);
180
181        return ret;
182}
183
184static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
185{
186
187        if (snac->subtype == 0x0003)
188                return parserights(sess, mod, rx, snac, bs);
189        else if (snac->subtype == 0x006)
190                return parsedata(sess, mod, rx, snac, bs);
191        else if (snac->subtype == 0x00f)
192                return parsedataunchanged(sess, mod, rx, snac, bs);
193
194        return 0;
195}
196
197faim_internal int ssi_modfirst(aim_session_t *sess, aim_module_t *mod)
198{
199
200        mod->family = 0x0013;
201        mod->version = 0x0001;
202        mod->toolid = 0x0110;
203        mod->toolversion = 0x047b;
204        mod->flags = 0;
205        strncpy(mod->name, "ssi", sizeof(mod->name));
206        mod->snachandler = snachandler;
207
208        return 0;
209}
210
211
Note: See TracBrowser for help on using the repository browser.