Mercurial > pidgin.yaz
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 |