comparison src/protocols/oscar/ssi.c @ 2672:c41030cfed76

[gaim-migrate @ 2685] Time has told me You're a rare, rare find A troubled cure For a troubled mind And time has told me Not to ask for more Someday our ocean Will find its shore committer: Tailor Script <tailor@pidgin.im>
author Adam Fritzler <mid@auk.cx>
date Mon, 05 Nov 2001 02:05:06 +0000
parents
children 9d11dbb33b6f
comparison
equal deleted inserted replaced
2671:ffa58bbe595d 2672:c41030cfed76
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 */
18 faim_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 */
26 static 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 */
46 faim_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 */
71 static 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 */
139 faim_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 */
150 faim_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 */
161 faim_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 */
173 static 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
184 static 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
197 faim_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