Mercurial > pidgin
comparison src/protocols/oscar/ssi.c @ 3017:f0e8770d786d
[gaim-migrate @ 3030]
Better SSI stuff? Thanks, KingAnt.
committer: Tailor Script <tailor@pidgin.im>
author | Rob Flynn <gaim@robflynn.com> |
---|---|
date | Thu, 07 Mar 2002 02:19:38 +0000 |
parents | 6d95285533df |
children | 25c2f11e92fa |
comparison
equal
deleted
inserted
replaced
3016:8863555aacc6 | 3017:f0e8770d786d |
---|---|
8 * This is entirely too complicated. | 8 * This is entirely too complicated. |
9 * You don't know the half of it. | 9 * You don't know the half of it. |
10 * | 10 * |
11 * XXX - Make sure moving buddies from group to group moves the buddy in the server list also | 11 * XXX - Make sure moving buddies from group to group moves the buddy in the server list also |
12 * XXX - Test for memory leaks | 12 * XXX - Test for memory leaks |
13 * XXX - Write a c plugin to manage ssi data | |
14 * XXX - Better parsing of rights, and use the rights info to limit adds | 13 * XXX - Better parsing of rights, and use the rights info to limit adds |
15 * | 14 * |
16 */ | 15 */ |
17 | 16 |
18 #define FAIM_INTERNAL | 17 #define FAIM_INTERNAL |
22 * Checks if the given screen name is anywhere in our buddy list. | 21 * Checks if the given screen name is anywhere in our buddy list. |
23 */ | 22 */ |
24 faim_export int aim_ssi_inlist(aim_session_t *sess, aim_conn_t *conn, char *name, fu16_t type) | 23 faim_export int aim_ssi_inlist(aim_session_t *sess, aim_conn_t *conn, char *name, fu16_t type) |
25 { | 24 { |
26 struct aim_ssi_item *cur; | 25 struct aim_ssi_item *cur; |
26 if (!sess && !conn && !name) | |
27 return -EINVAL; | |
27 for (cur=sess->ssi.items; cur; cur=cur->next) | 28 for (cur=sess->ssi.items; cur; cur=cur->next) |
28 if ((cur->type==type) && (cur->name) && (!aim_sncmp(cur->name, name))) | 29 if ((cur->type==type) && (cur->name) && (!aim_sncmp(cur->name, name))) |
29 return 1; | 30 return 1; |
30 return 0; | 31 return 0; |
31 } | 32 } |
32 | 33 |
33 /* | 34 /* |
35 * Return the parent group of a given buddy. | |
36 */ | |
37 faim_export char *aim_ssi_getparentgroup(aim_session_t *sess, aim_conn_t *conn, char *name) | |
38 { | |
39 fu16_t gid; | |
40 struct aim_ssi_item *cur; | |
41 if (!sess && !conn && !name) | |
42 return NULL; | |
43 for (cur=sess->ssi.items; cur && (cur->type!=AIM_SSI_TYPE_BUDDY || !cur->name || aim_sncmp(cur->name, name)); cur=cur->next) | |
44 if (!cur) | |
45 return NULL; | |
46 gid = cur->gid; | |
47 for (cur=sess->ssi.items; cur; cur=cur->next) | |
48 if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid == gid) && (cur->name)) | |
49 return cur->name; | |
50 return 0; | |
51 } | |
52 | |
53 /* | |
34 * Returns the permit/deny byte | 54 * Returns the permit/deny byte |
35 * Should should be removed and the byte should be passed directly to | 55 * This should be removed and the byte should be passed directly to |
36 * the handler | 56 * the handler for x0006, along with all the buddies and other info. |
37 */ | 57 */ |
38 faim_export int aim_ssi_getpermdeny(aim_tlvlist_t *tlvlist) | 58 faim_export int aim_ssi_getpermdeny(aim_tlvlist_t *tlvlist) |
39 { | 59 { |
40 aim_tlv_t *tlv; | 60 aim_tlv_t *tlv; |
41 if ((tlv = aim_gettlv(tlvlist, 0x00ca, 1)) && tlv->value) | 61 if ((tlv = aim_gettlv(tlvlist, 0x00ca, 1)) && tlv->value) |
51 struct aim_ssi_item *cur; | 71 struct aim_ssi_item *cur; |
52 if (name) { | 72 if (name) { |
53 for (cur=items; cur; cur=cur->next) | 73 for (cur=items; cur; cur=cur->next) |
54 if ((cur->type == type) && (cur->name) && !(aim_sncmp(cur->name, name))) | 74 if ((cur->type == type) && (cur->name) && !(aim_sncmp(cur->name, name))) |
55 return cur; | 75 return cur; |
56 } else { /* they probably want the master group */ | 76 } else { /* return the master group */ |
57 for (cur=items; cur; cur=cur->next) | 77 for (cur=items; cur; cur=cur->next) |
58 if ((cur->type == type) && (cur->gid == 0x0000)) | 78 if ((cur->type == type) && (cur->gid == 0x0000)) |
59 return cur; | 79 return cur; |
60 } | 80 } |
61 return NULL; | 81 return NULL; |
127 | 147 |
128 /* Find the length for the new additional data */ | 148 /* Find the length for the new additional data */ |
129 newlen = 0; | 149 newlen = 0; |
130 if (parentgroup->gid == 0x0000) { | 150 if (parentgroup->gid == 0x0000) { |
131 for (cur=sess->ssi.items; cur; cur=cur->next) | 151 for (cur=sess->ssi.items; cur; cur=cur->next) |
132 if ((cur->gid != 0x0000) && (cur->type == 0x0001)) | 152 if ((cur->gid != 0x0000) && (cur->type == AIM_SSI_TYPE_GROUP)) |
133 newlen += 2; | 153 newlen += 2; |
134 } else { | 154 } else { |
135 for (cur=sess->ssi.items; cur; cur=cur->next) | 155 for (cur=sess->ssi.items; cur; cur=cur->next) |
136 if ((cur->gid == parentgroup->gid) && (cur->type == 0x0000)) | 156 if ((cur->gid == parentgroup->gid) && (cur->type == AIM_SSI_TYPE_BUDDY)) |
137 newlen += 2; | 157 newlen += 2; |
138 } | 158 } |
139 | 159 |
140 /* Rebuild the additional data */ | 160 /* Rebuild the additional data */ |
141 if (newlen>0) { | 161 if (newlen>0) { |
146 return -ENOMEM; | 166 return -ENOMEM; |
147 aimbs_put16(&tbs, 0x00c8); | 167 aimbs_put16(&tbs, 0x00c8); |
148 aimbs_put16(&tbs, tbs.len-4); | 168 aimbs_put16(&tbs, tbs.len-4); |
149 if (parentgroup->gid == 0x0000) { | 169 if (parentgroup->gid == 0x0000) { |
150 for (cur=sess->ssi.items; cur; cur=cur->next) | 170 for (cur=sess->ssi.items; cur; cur=cur->next) |
151 if ((cur->gid != 0x0000) && (cur->type == 0x0001)) | 171 if ((cur->gid != 0x0000) && (cur->type == AIM_SSI_TYPE_GROUP)) |
152 aimbs_put16(&tbs, cur->gid); | 172 aimbs_put16(&tbs, cur->gid); |
153 } else { | 173 } else { |
154 for (cur=sess->ssi.items; cur; cur=cur->next) | 174 for (cur=sess->ssi.items; cur; cur=cur->next) |
155 if ((cur->gid == parentgroup->gid) && (cur->type == 0x0000)) | 175 if ((cur->gid == parentgroup->gid) && (cur->type == AIM_SSI_TYPE_BUDDY)) |
156 aimbs_put16(&tbs, cur->bid); | 176 aimbs_put16(&tbs, cur->bid); |
157 } | 177 } |
158 tbs.offset = 0; | 178 tbs.offset = 0; |
159 parentgroup->data = (void *)aim_readtlvchain(&tbs); | 179 parentgroup->data = (void *)aim_readtlvchain(&tbs); |
160 free(tbs.data); | 180 free(tbs.data); |
164 if (!(newdata = (fu8_t *)malloc((newlen)*sizeof(fu8_t)))) | 184 if (!(newdata = (fu8_t *)malloc((newlen)*sizeof(fu8_t)))) |
165 return -ENOMEM; | 185 return -ENOMEM; |
166 newlen = 0; | 186 newlen = 0; |
167 if (parentgroup->gid == 0x0000) { | 187 if (parentgroup->gid == 0x0000) { |
168 for (cur=sess->ssi.items; cur; cur=cur->next) | 188 for (cur=sess->ssi.items; cur; cur=cur->next) |
169 if ((cur->gid != 0x0000) && (cur->type == 0x0001)) { | 189 if ((cur->gid != 0x0000) && (cur->type == AIM_SSI_TYPE_GROUP)) { |
170 memcpy(&newdata[newlen*2], &cur->gid, 2); | 190 memcpy(&newdata[newlen*2], &cur->gid, 2); |
171 newlen += 2; | 191 newlen += 2; |
172 } | 192 } |
173 } else { | 193 } else { |
174 for (cur=sess->ssi.items; cur; cur=cur->next) | 194 for (cur=sess->ssi.items; cur; cur=cur->next) |
175 if ((cur->gid == parentgroup->gid) && (cur->type == 0x0000)) { | 195 if ((cur->gid == parentgroup->gid) && (cur->type == AIM_SSI_TYPE_BUDDY)) { |
176 memcpy(newdata+newlen*2, &cur->bid, 2); | 196 memcpy(&newdata[newlen*2], &cur->bid, 2); |
177 newlen += 2; | 197 newlen += 2; |
178 } | 198 } |
179 } | 199 } |
180 aim_addtlvtochain_raw((aim_tlvlist_t **)&parentgroup->data, 0x00c8, newlen, newdata); | 200 aim_addtlvtochain_raw((aim_tlvlist_t **)&parentgroup->data, 0x00c8, newlen, newdata); |
181 free(newdata); */ | 201 free(newdata); */ |
218 for (cur=sess->ssi.items, num=0; cur; cur=cur->next) | 238 for (cur=sess->ssi.items, num=0; cur; cur=cur->next) |
219 num++; | 239 num++; |
220 | 240 |
221 if (!(items = (struct aim_ssi_item **)malloc(num*sizeof(struct aim_ssi_item *)))) | 241 if (!(items = (struct aim_ssi_item **)malloc(num*sizeof(struct aim_ssi_item *)))) |
222 return -ENOMEM; | 242 return -ENOMEM; |
223 bzero(items, num*sizeof(struct aim_ssi_item *)); | 243 memset(items, 0, num*sizeof(struct aim_ssi_item *)); |
224 for (cur=sess->ssi.items, num=0; cur; cur=cur->next) { | 244 for (cur=sess->ssi.items, num=0; cur; cur=cur->next) { |
225 items[num] = cur; | 245 items[num] = cur; |
226 num++; | 246 num++; |
227 } | 247 } |
228 | 248 |
229 aim_ssi_delitems(sess, conn, items, num); | 249 aim_ssi_addmoddel(sess, conn, items, num, AIM_CB_SSI_DEL); |
230 free(items); | 250 free(items); |
231 aim_ssi_dispatch(sess, conn); | 251 aim_ssi_dispatch(sess, conn); |
232 aim_ssi_freelist(sess); | 252 aim_ssi_freelist(sess); |
233 | 253 |
234 return 0; | 254 return 0; |
246 struct aim_ssi_item *cur, *parentgroup; | 266 struct aim_ssi_item *cur, *parentgroup; |
247 | 267 |
248 /* Make sure we actually need to clean out the list */ | 268 /* Make sure we actually need to clean out the list */ |
249 for (cur=sess->ssi.items, num_to_be_fixed=0; cur; cur=cur->next) { | 269 for (cur=sess->ssi.items, num_to_be_fixed=0; cur; cur=cur->next) { |
250 /* Any buddies directly in the master group */ | 270 /* Any buddies directly in the master group */ |
251 if ((cur->type == 0x0000) && (cur->gid == 0x0000)) | 271 if ((cur->type == AIM_SSI_TYPE_BUDDY) && (cur->gid == 0x0000)) |
252 num_to_be_fixed++; | 272 num_to_be_fixed++; |
253 } | 273 } |
254 if (!num_to_be_fixed) | 274 if (!num_to_be_fixed) |
255 return 0; | 275 return 0; |
256 | 276 |
257 /* Remove all the additional data from all groups and buddies */ | 277 /* Remove all the additional data from all groups and buddies */ |
258 for (cur=sess->ssi.items; cur; cur=cur->next) | 278 for (cur=sess->ssi.items; cur; cur=cur->next) |
259 if (cur->data && ((cur->type == 0x0000) || (cur->type == 0x0001))) { | 279 if (cur->data && ((cur->type == AIM_SSI_TYPE_BUDDY) || (cur->type == AIM_SSI_TYPE_GROUP))) { |
260 aim_freetlvchain((aim_tlvlist_t **)&cur->data); | 280 aim_freetlvchain((aim_tlvlist_t **)&cur->data); |
261 cur->data = NULL; | 281 cur->data = NULL; |
262 } | 282 } |
263 | 283 |
264 /* If there are buddies directly in the master group, make sure */ | 284 /* If there are buddies directly in the master group, make sure */ |
265 /* there is a group to put them in. Any group, any group at all. */ | 285 /* there is a group to put them in. Any group, any group at all. */ |
266 for (cur=sess->ssi.items; ((cur) && ((cur->type != 0x0000) || (cur->gid != 0x0000))); cur=cur->next); | 286 for (cur=sess->ssi.items; ((cur) && ((cur->type != AIM_SSI_TYPE_BUDDY) || (cur->gid != 0x0000))); cur=cur->next); |
267 if (!cur) { | 287 if (!cur) { |
268 for (parentgroup=sess->ssi.items; ((parentgroup) && ((parentgroup->type!=0x0001) || (parentgroup->gid!=0x0000))); parentgroup=parentgroup->next); | 288 for (parentgroup=sess->ssi.items; ((parentgroup) && ((parentgroup->type!=AIM_SSI_TYPE_GROUP) || (parentgroup->gid!=0x0000))); parentgroup=parentgroup->next); |
269 if (!parentgroup) { | 289 if (!parentgroup) { |
270 char *newgroup; | 290 char *newgroup; |
271 newgroup = (char*)malloc(strlen("Unknown")*sizeof(char)); | 291 newgroup = (char*)malloc(strlen("Unknown")*sizeof(char)); |
272 strcpy(newgroup, "Unknown"); | 292 strcpy(newgroup, "Unknown"); |
273 aim_ssi_addgroups(sess, conn, &newgroup, 1); | 293 aim_ssi_addgroups(sess, conn, &newgroup, 1); |
274 } | 294 } |
275 } | 295 } |
276 | 296 |
277 /* Set parentgroup equal to any arbitray group */ | 297 /* Set parentgroup equal to any arbitray group */ |
278 for (parentgroup=sess->ssi.items; parentgroup->gid==0x0000 || parentgroup->type!=0x0001; parentgroup=parentgroup->next); | 298 for (parentgroup=sess->ssi.items; parentgroup->gid==0x0000 || parentgroup->type!=AIM_SSI_TYPE_GROUP; parentgroup=parentgroup->next); |
279 | 299 |
280 /* If there are any buddies directly in the master group, put them in a real group */ | 300 /* If there are any buddies directly in the master group, put them in a real group */ |
281 for (cur=sess->ssi.items; cur; cur=cur->next) | 301 for (cur=sess->ssi.items; cur; cur=cur->next) |
282 if ((cur->type == 0x0000) && (cur->gid == 0x0000)) { | 302 if ((cur->type == AIM_SSI_TYPE_BUDDY) && (cur->gid == 0x0000)) { |
283 aim_ssi_delitems(sess, conn, &cur, 1); | 303 aim_ssi_addmoddel(sess, conn, &cur, 1, AIM_CB_SSI_DEL); |
284 cur->gid = parentgroup->gid; | 304 cur->gid = parentgroup->gid; |
285 aim_ssi_additems(sess, conn, &cur, 1); | 305 aim_ssi_addmoddel(sess, conn, &cur, 1, AIM_CB_SSI_ADD); |
286 } | 306 } |
287 | 307 |
288 /* Rebuild additional data for all groups */ | 308 /* Rebuild additional data for all groups */ |
289 for (parentgroup=sess->ssi.items; parentgroup; parentgroup=parentgroup->next) | 309 for (parentgroup=sess->ssi.items; parentgroup; parentgroup=parentgroup->next) |
290 if (parentgroup->type == 0x0001) | 310 if (parentgroup->type == AIM_SSI_TYPE_GROUP) |
291 aim_ssi_rebuildgroup(sess, conn, parentgroup); | 311 aim_ssi_rebuildgroup(sess, conn, parentgroup); |
292 | 312 |
293 /* Send a mod snac for all groups */ | 313 /* Send a mod snac for all groups */ |
294 for (cur=sess->ssi.items; cur; cur=cur->next) | 314 for (cur=sess->ssi.items; cur; cur=cur->next) |
295 if (cur->type == 0x0001) | 315 if (cur->type == AIM_SSI_TYPE_GROUP) |
296 aim_ssi_moditems(sess, conn, &cur, 1); | 316 aim_ssi_addmoddel(sess, conn, &cur, 1, AIM_CB_SSI_MOD); |
297 | |
298 /* Begin sending SSI SNACs */ | |
299 aim_ssi_dispatch(sess, conn); | |
300 | |
301 return 0; | |
302 } | |
303 | |
304 /* | |
305 * This adds the master group (the group containing all groups) if it doesn't exist. | |
306 * It's called by aim_ssi_addgroups, if your list is empty. | |
307 */ | |
308 faim_export int aim_ssi_addmastergroup(aim_session_t *sess, aim_conn_t *conn) { | |
309 struct aim_ssi_item *newitem; | |
310 | |
311 if (!sess || !conn) | |
312 return -EINVAL; | |
313 | |
314 /* Allocate an array of pointers to each of the new items */ | |
315 if (!(newitem = (struct aim_ssi_item *)malloc(sizeof(struct aim_ssi_item)))) | |
316 return -ENOMEM; | |
317 bzero(newitem, sizeof(struct aim_ssi_item)); | |
318 | |
319 /* bzero sets most of the vars to what they should be */ | |
320 newitem->type = 0x0001; | |
321 | |
322 /* Add the item to our list */ | |
323 newitem->next = sess->ssi.items; | |
324 sess->ssi.items = newitem; | |
325 | |
326 /* If there are any existing groups (technically there shouldn't be, but */ | |
327 /* just in case) then add their group ID#'s to the additional data */ | |
328 if (sess->ssi.items) | |
329 aim_ssi_rebuildgroup(sess, conn, newitem); | |
330 | |
331 /* Send the add item SNAC */ | |
332 aim_ssi_additems(sess, conn, &newitem, 1); | |
333 | 317 |
334 /* Begin sending SSI SNACs */ | 318 /* Begin sending SSI SNACs */ |
335 aim_ssi_dispatch(sess, conn); | 319 aim_ssi_dispatch(sess, conn); |
336 | 320 |
337 return 0; | 321 return 0; |
353 | 337 |
354 if (!sess || !conn || !gn || !sn || !num) | 338 if (!sess || !conn || !gn || !sn || !num) |
355 return -EINVAL; | 339 return -EINVAL; |
356 | 340 |
357 /* Look up the parent group */ | 341 /* Look up the parent group */ |
358 if (!(parentgroup = get_ssi_item(sess->ssi.items, gn, 0x0001))) { | 342 if (!(parentgroup = get_ssi_item(sess->ssi.items, gn, AIM_SSI_TYPE_GROUP))) { |
359 aim_ssi_addgroups(sess, conn, &gn, 1); | 343 aim_ssi_addgroups(sess, conn, &gn, 1); |
360 if (!(parentgroup = get_ssi_item(sess->ssi.items, gn, 0x0001))) | 344 if (!(parentgroup = get_ssi_item(sess->ssi.items, gn, AIM_SSI_TYPE_GROUP))) |
361 return -ENOMEM; | 345 return -ENOMEM; |
362 } | 346 } |
363 | 347 |
364 /* Allocate an array of pointers to each of the new items */ | 348 /* Allocate an array of pointers to each of the new items */ |
365 if (!(newitems = (struct aim_ssi_item **)malloc(num*sizeof(struct aim_ssi_item *)))) | 349 if (!(newitems = (struct aim_ssi_item **)malloc(num*sizeof(struct aim_ssi_item *)))) |
366 return -ENOMEM; | 350 return -ENOMEM; |
367 bzero(newitems, num*sizeof(struct aim_ssi_item *)); | 351 memset(newitems, 0, num*sizeof(struct aim_ssi_item *)); |
368 | 352 |
369 /* The following for loop iterates once per item that needs to be added. */ | 353 /* The following for loop iterates once per item that needs to be added. */ |
370 /* For each i, create an item and tack it onto the newitems array */ | 354 /* For each i, create an item and tack it onto the newitems array */ |
371 for (i=0; i<num; i++) { | 355 for (i=0; i<num; i++) { |
372 if (!(newitems[i] = (struct aim_ssi_item *)malloc(sizeof(struct aim_ssi_item)))) { | 356 if (!(newitems[i] = (struct aim_ssi_item *)malloc(sizeof(struct aim_ssi_item)))) { |
390 newitems[i]->gid = parentgroup->gid; | 374 newitems[i]->gid = parentgroup->gid; |
391 newitems[i]->bid = i ? newitems[i-1]->bid : 0; | 375 newitems[i]->bid = i ? newitems[i-1]->bid : 0; |
392 do { | 376 do { |
393 newitems[i]->bid += 0x0001; | 377 newitems[i]->bid += 0x0001; |
394 for (cur=sess->ssi.items, j=0; ((cur) && (!j)); cur=cur->next) | 378 for (cur=sess->ssi.items, j=0; ((cur) && (!j)); cur=cur->next) |
395 if ((cur->bid == newitems[i]->bid) && (cur->gid == newitems[i]->gid) && (cur->type == 0x0000)) | 379 if ((cur->bid == newitems[i]->bid) && (cur->gid == newitems[i]->gid) && (cur->type == AIM_SSI_TYPE_BUDDY)) |
396 j=1; | 380 j=1; |
397 } while (j); | 381 } while (j); |
398 newitems[i]->type = 0x0000; | 382 newitems[i]->type = AIM_SSI_TYPE_BUDDY; |
399 newitems[i]->data = NULL; | 383 newitems[i]->data = NULL; |
400 newitems[i]->next = i ? newitems[i-1] : NULL; | 384 newitems[i]->next = i ? newitems[i-1] : NULL; |
401 } | 385 } |
402 | 386 |
403 /* Add the items to our list */ | 387 /* Add the items to our list */ |
404 newitems[0]->next = sess->ssi.items; | 388 newitems[0]->next = sess->ssi.items; |
405 sess->ssi.items = newitems[num-1]; | 389 sess->ssi.items = newitems[num-1]; |
406 | 390 |
407 /* Send the add item SNAC */ | 391 /* Send the add item SNAC */ |
408 aim_ssi_additems(sess, conn, newitems, num); | 392 aim_ssi_addmoddel(sess, conn, newitems, num, AIM_CB_SSI_ADD); |
409 | 393 |
410 /* Free the array of pointers to each of the new items */ | 394 /* Free the array of pointers to each of the new items */ |
411 free(newitems); | 395 free(newitems); |
412 | 396 |
413 /* Rebuild the additional data in the parent group */ | 397 /* Rebuild the additional data in the parent group */ |
414 aim_ssi_rebuildgroup(sess, conn, parentgroup); | 398 aim_ssi_rebuildgroup(sess, conn, parentgroup); |
415 | 399 |
416 /* Send the mod item SNAC */ | 400 /* Send the mod item SNAC */ |
417 aim_ssi_moditems(sess, conn, &parentgroup, 1); | 401 aim_ssi_addmoddel(sess, conn, &parentgroup, 1, AIM_CB_SSI_MOD); |
418 | 402 |
419 /* Begin sending SSI SNACs */ | 403 /* Begin sending SSI SNACs */ |
420 aim_ssi_dispatch(sess, conn); | 404 aim_ssi_dispatch(sess, conn); |
421 | 405 |
422 return 0; | 406 return 0; |
423 } | 407 } |
424 | 408 |
409 /* | |
410 * This adds the master group (the group containing all groups) if it doesn't exist. | |
411 * It's called by aim_ssi_addgroups, if your list is empty. | |
412 */ | |
413 faim_export int aim_ssi_addmastergroup(aim_session_t *sess, aim_conn_t *conn) { | |
414 struct aim_ssi_item *newitem; | |
415 | |
416 if (!sess || !conn) | |
417 return -EINVAL; | |
418 | |
419 /* Allocate an array of pointers to each of the new items */ | |
420 if (!(newitem = (struct aim_ssi_item *)malloc(sizeof(struct aim_ssi_item)))) | |
421 return -ENOMEM; | |
422 memset(newitem, 0, sizeof(struct aim_ssi_item)); | |
423 | |
424 /* memset to 0 sets most of the vars to what they should be */ | |
425 newitem->type = AIM_SSI_TYPE_GROUP; | |
426 | |
427 /* Add the item to our list */ | |
428 newitem->next = sess->ssi.items; | |
429 sess->ssi.items = newitem; | |
430 | |
431 /* If there are any existing groups (technically there shouldn't be, but */ | |
432 /* just in case) then add their group ID#'s to the additional data */ | |
433 if (sess->ssi.items) | |
434 aim_ssi_rebuildgroup(sess, conn, newitem); | |
435 | |
436 /* Send the add item SNAC */ | |
437 aim_ssi_addmoddel(sess, conn, &newitem, 1, AIM_CB_SSI_ADD); | |
438 | |
439 /* Begin sending SSI SNACs */ | |
440 aim_ssi_dispatch(sess, conn); | |
441 | |
442 return 0; | |
443 } | |
444 | |
425 faim_export int aim_ssi_addgroups(aim_session_t *sess, aim_conn_t *conn, char **gn, unsigned int num) | 445 faim_export int aim_ssi_addgroups(aim_session_t *sess, aim_conn_t *conn, char **gn, unsigned int num) |
426 { | 446 { |
427 struct aim_ssi_item *cur, *parentgroup, **newitems; | 447 struct aim_ssi_item *cur, *parentgroup, **newitems; |
428 fu16_t i, j; | 448 fu16_t i, j; |
429 | 449 |
430 if (!sess || !conn || !gn || !num) | 450 if (!sess || !conn || !gn || !num) |
431 return -EINVAL; | 451 return -EINVAL; |
432 | 452 |
433 /* Look up the parent group */ | 453 /* Look up the parent group */ |
434 if (!(parentgroup = get_ssi_item(sess->ssi.items, NULL, 0x0001))) { | 454 if (!(parentgroup = get_ssi_item(sess->ssi.items, NULL, AIM_SSI_TYPE_GROUP))) { |
435 aim_ssi_addmastergroup(sess, conn); | 455 aim_ssi_addmastergroup(sess, conn); |
436 if (!(parentgroup = get_ssi_item(sess->ssi.items, NULL, 0x0001))) | 456 if (!(parentgroup = get_ssi_item(sess->ssi.items, NULL, AIM_SSI_TYPE_GROUP))) |
437 return -ENOMEM; | 457 return -ENOMEM; |
438 } | 458 } |
439 | 459 |
440 /* Allocate an array of pointers to each of the new items */ | 460 /* Allocate an array of pointers to each of the new items */ |
441 if (!(newitems = (struct aim_ssi_item **)malloc(num*sizeof(struct aim_ssi_item *)))) | 461 if (!(newitems = (struct aim_ssi_item **)malloc(num*sizeof(struct aim_ssi_item *)))) |
442 return -ENOMEM; | 462 return -ENOMEM; |
443 bzero(newitems, num*sizeof(struct aim_ssi_item *)); | 463 memset(newitems, 0, num*sizeof(struct aim_ssi_item *)); |
444 | 464 |
445 /* The following for loop iterates once per item that needs to be added. */ | 465 /* The following for loop iterates once per item that needs to be added. */ |
446 /* For each i, create an item and tack it onto the newitems array */ | 466 /* For each i, create an item and tack it onto the newitems array */ |
447 for (i=0; i<num; i++) { | 467 for (i=0; i<num; i++) { |
448 if (!(newitems[i] = (struct aim_ssi_item *)malloc(sizeof(struct aim_ssi_item)))) { | 468 if (!(newitems[i] = (struct aim_ssi_item *)malloc(sizeof(struct aim_ssi_item)))) { |
465 strcpy(newitems[i]->name, gn[i]); | 485 strcpy(newitems[i]->name, gn[i]); |
466 newitems[i]->gid = i ? newitems[i-1]->gid : 0; | 486 newitems[i]->gid = i ? newitems[i-1]->gid : 0; |
467 do { | 487 do { |
468 newitems[i]->gid += 0x0001; | 488 newitems[i]->gid += 0x0001; |
469 for (cur=sess->ssi.items, j=0; ((cur) && (!j)); cur=cur->next) | 489 for (cur=sess->ssi.items, j=0; ((cur) && (!j)); cur=cur->next) |
470 if ((cur->gid == newitems[i]->gid) && (cur->type == 0x0001)) | 490 if ((cur->gid == newitems[i]->gid) && (cur->type == AIM_SSI_TYPE_GROUP)) |
471 j=1; | 491 j=1; |
472 } while (j); | 492 } while (j); |
473 newitems[i]->bid = 0x0000; | 493 newitems[i]->bid = 0x0000; |
474 newitems[i]->type = 0x0001; | 494 newitems[i]->type = AIM_SSI_TYPE_GROUP; |
475 newitems[i]->data = NULL; | 495 newitems[i]->data = NULL; |
476 newitems[i]->next = i ? newitems[i-1] : NULL; | 496 newitems[i]->next = i ? newitems[i-1] : NULL; |
477 } | 497 } |
478 | 498 |
479 /* Add the items to our list */ | 499 /* Add the items to our list */ |
480 newitems[0]->next = sess->ssi.items; | 500 newitems[0]->next = sess->ssi.items; |
481 sess->ssi.items = newitems[num-1]; | 501 sess->ssi.items = newitems[num-1]; |
482 | 502 |
483 /* Send the add item SNAC */ | 503 /* Send the add item SNAC */ |
484 aim_ssi_additems(sess, conn, newitems, num); | 504 aim_ssi_addmoddel(sess, conn, newitems, num, AIM_CB_SSI_ADD); |
485 | 505 |
486 /* Free the array of pointers to each of the new items */ | 506 /* Free the array of pointers to each of the new items */ |
487 free(newitems); | 507 free(newitems); |
488 | 508 |
489 /* Rebuild the additional data in the parent group */ | 509 /* Rebuild the additional data in the parent group */ |
490 aim_ssi_rebuildgroup(sess, conn, parentgroup); | 510 aim_ssi_rebuildgroup(sess, conn, parentgroup); |
491 | 511 |
492 /* Send the mod item SNAC */ | 512 /* Send the mod item SNAC */ |
493 aim_ssi_moditems(sess, conn, &parentgroup, 1); | 513 aim_ssi_addmoddel(sess, conn, &parentgroup, 1, AIM_CB_SSI_MOD); |
494 | 514 |
495 /* Begin sending SSI SNACs */ | 515 /* Begin sending SSI SNACs */ |
496 aim_ssi_dispatch(sess, conn); | 516 aim_ssi_dispatch(sess, conn); |
497 | 517 |
498 return 0; | 518 return 0; |
499 } | 519 } |
500 | 520 |
501 faim_export int aim_ssi_addpermits(aim_session_t *sess, aim_conn_t *conn, char **sn, unsigned int num) | 521 /* |
522 * Add permit or deny buddies to the permit or deny list. | |
523 * The buddies are passed as an array of pointers to char strings. | |
524 */ | |
525 faim_export int aim_ssi_addpord(aim_session_t *sess, aim_conn_t *conn, char **sn, unsigned int num, fu16_t type) | |
502 { | 526 { |
503 struct aim_ssi_item *cur, **newitems; | 527 struct aim_ssi_item *cur, **newitems; |
504 fu16_t i, j; | 528 fu16_t i, j; |
505 | 529 |
506 if (!sess || !conn || !sn || !num) | 530 if (!sess || !conn || !sn || !num || (type!=AIM_SSI_TYPE_PERMIT && type!=AIM_SSI_TYPE_DENY)) |
507 return -EINVAL; | 531 return -EINVAL; |
508 | 532 |
509 /* Allocate an array of pointers to each of the new items */ | 533 /* Allocate an array of pointers to each of the new items */ |
510 if (!(newitems = (struct aim_ssi_item **)malloc(num*sizeof(struct aim_ssi_item *)))) | 534 if (!(newitems = (struct aim_ssi_item **)malloc(num*sizeof(struct aim_ssi_item *)))) |
511 return -ENOMEM; | 535 return -ENOMEM; |
512 bzero(newitems, num*sizeof(struct aim_ssi_item *)); | 536 memset(newitems, 0, num*sizeof(struct aim_ssi_item *)); |
513 | 537 |
514 /* The following for loop iterates once per item that needs to be added. */ | 538 /* The following for loop iterates once per item that needs to be added. */ |
515 /* For each i, create an item and tack it onto the newitems array */ | 539 /* For each i, create an item and tack it onto the newitems array */ |
516 for (i=0; i<num; i++) { | 540 for (i=0; i<num; i++) { |
517 if (!(newitems[i] = (struct aim_ssi_item *)malloc(sizeof(struct aim_ssi_item)))) { | 541 if (!(newitems[i] = (struct aim_ssi_item *)malloc(sizeof(struct aim_ssi_item)))) { |
535 newitems[i]->gid = 0x0000; | 559 newitems[i]->gid = 0x0000; |
536 newitems[i]->bid = i ? newitems[i-1]->bid : 0x0000; | 560 newitems[i]->bid = i ? newitems[i-1]->bid : 0x0000; |
537 do { | 561 do { |
538 newitems[i]->bid += 0x0001; | 562 newitems[i]->bid += 0x0001; |
539 for (cur=sess->ssi.items, j=0; ((cur) && (!j)); cur=cur->next) | 563 for (cur=sess->ssi.items, j=0; ((cur) && (!j)); cur=cur->next) |
540 if ((cur->bid == newitems[i]->bid) && ((cur->type == 0x0002) || (cur->type == 0x0003))) | 564 if ((cur->bid == newitems[i]->bid) && ((cur->type == AIM_SSI_TYPE_PERMIT) || (cur->type == AIM_SSI_TYPE_DENY))) |
541 j=1; | 565 j=1; |
542 } while (j); | 566 } while (j); |
543 newitems[i]->type = 0x0002; | 567 newitems[i]->type = type; |
544 newitems[i]->data = NULL; | 568 newitems[i]->data = NULL; |
545 newitems[i]->next = i ? newitems[i-1] : NULL; | 569 newitems[i]->next = i ? newitems[i-1] : NULL; |
546 } | 570 } |
547 | 571 |
548 /* Add the items to our list */ | 572 /* Add the items to our list */ |
549 newitems[0]->next = sess->ssi.items; | 573 newitems[0]->next = sess->ssi.items; |
550 sess->ssi.items = newitems[num-1]; | 574 sess->ssi.items = newitems[num-1]; |
551 | 575 |
552 /* Send the add item SNAC */ | 576 /* Send the add item SNAC */ |
553 aim_ssi_additems(sess, conn, newitems, num); | 577 aim_ssi_addmoddel(sess, conn, newitems, num, AIM_CB_SSI_ADD); |
554 | 578 |
555 /* Free the array of pointers to each of the new items */ | 579 /* Free the array of pointers to each of the new items */ |
556 free(newitems); | 580 free(newitems); |
557 | 581 |
558 /* Begin sending SSI SNACs */ | 582 /* Begin sending SSI SNACs */ |
559 aim_ssi_dispatch(sess, conn); | 583 aim_ssi_dispatch(sess, conn); |
560 | 584 |
561 return 0; | 585 return 0; |
562 } | 586 } |
563 | 587 |
564 faim_export int aim_ssi_adddenies(aim_session_t *sess, aim_conn_t *conn, char **sn, unsigned int num) | |
565 { | |
566 struct aim_ssi_item *cur, **newitems; | |
567 fu16_t i, j; | |
568 | |
569 if (!sess || !conn || !sn || !num) | |
570 return -EINVAL; | |
571 | |
572 /* Allocate an array of pointers to each of the new items */ | |
573 if (!(newitems = (struct aim_ssi_item **)malloc(num*sizeof(struct aim_ssi_item *)))) | |
574 return -ENOMEM; | |
575 bzero(newitems, num*sizeof(struct aim_ssi_item *)); | |
576 | |
577 /* The following for loop iterates once per item that needs to be added. */ | |
578 /* For each i, create an item and tack it onto the newitems array */ | |
579 for (i=0; i<num; i++) { | |
580 if (!(newitems[i] = (struct aim_ssi_item *)malloc(sizeof(struct aim_ssi_item)))) { | |
581 for (j=0; j<(i-1); j++) { | |
582 free(newitems[j]->name); | |
583 free(newitems[j]); | |
584 } | |
585 free(newitems); | |
586 return -ENOMEM; | |
587 } | |
588 if (!(newitems[i]->name = (char *)malloc((strlen(sn[i])+1)*sizeof(char)))) { | |
589 for (j=0; j<(i-1); j++) { | |
590 free(newitems[j]->name); | |
591 free(newitems[j]); | |
592 } | |
593 free(newitems[i]); | |
594 free(newitems); | |
595 return -ENOMEM; | |
596 } | |
597 strcpy(newitems[i]->name, sn[i]); | |
598 newitems[i]->gid = 0x0000; | |
599 newitems[i]->bid = i ? newitems[i-1]->bid : 0x0000; | |
600 do { | |
601 newitems[i]->bid += 0x0001; | |
602 for (cur=sess->ssi.items, j=0; ((cur) && (!j)); cur=cur->next) | |
603 if ((cur->bid == newitems[i]->bid) && ((cur->type == 0x0002) || (cur->type == 0x0003))) | |
604 j=1; | |
605 } while (j); | |
606 newitems[i]->type = 0x0003; | |
607 newitems[i]->data = NULL; | |
608 newitems[i]->next = i ? newitems[i-1] : NULL; | |
609 } | |
610 | |
611 /* Add the items to our list */ | |
612 newitems[0]->next = sess->ssi.items; | |
613 sess->ssi.items = newitems[num-1]; | |
614 | |
615 /* Send the add item SNAC */ | |
616 aim_ssi_additems(sess, conn, newitems, num); | |
617 | |
618 /* Free the array of pointers to each of the new items */ | |
619 free(newitems); | |
620 | |
621 /* Begin sending SSI SNACs */ | |
622 aim_ssi_dispatch(sess, conn); | |
623 | |
624 return 0; | |
625 } | |
626 | |
627 faim_export int aim_ssi_delbuddies(aim_session_t *sess, aim_conn_t *conn, char *gn, char **sn, unsigned int num) | 588 faim_export int aim_ssi_delbuddies(aim_session_t *sess, aim_conn_t *conn, char *gn, char **sn, unsigned int num) |
628 { | 589 { |
629 struct aim_ssi_item *cur, *parentgroup, **delitems; | 590 struct aim_ssi_item *cur, *parentgroup, **delitems; |
630 int i; | 591 int i; |
631 | 592 |
632 if (!sess || !conn || !gn || !sn || !num) | 593 if (!sess || !conn || !gn || !sn || !num) |
633 return -EINVAL; | 594 return -EINVAL; |
634 | 595 |
635 /* Look up the parent group */ | 596 /* Look up the parent group */ |
636 if (!(parentgroup = get_ssi_item(sess->ssi.items, gn, 0x0001))) | 597 if (!(parentgroup = get_ssi_item(sess->ssi.items, gn, AIM_SSI_TYPE_GROUP))) |
637 return -EINVAL; | 598 return -EINVAL; |
638 | 599 |
639 /* Allocate an array of pointers to each of the items to be deleted */ | 600 /* Allocate an array of pointers to each of the items to be deleted */ |
640 delitems = (struct aim_ssi_item **)malloc(num*sizeof(struct aim_ssi_item *)); | 601 delitems = (struct aim_ssi_item **)malloc(num*sizeof(struct aim_ssi_item *)); |
641 bzero(delitems, num*sizeof(struct aim_ssi_item *)); | 602 memset(delitems, 0, num*sizeof(struct aim_ssi_item *)); |
642 | 603 |
643 /* Make the delitems array a pointer to the aim_ssi_item structs to be deleted */ | 604 /* Make the delitems array a pointer to the aim_ssi_item structs to be deleted */ |
644 for (i=0; i<num; i++) { | 605 for (i=0; i<num; i++) { |
645 if (!(delitems[i] = get_ssi_item(sess->ssi.items, sn[i], 0x0000))) { | 606 if (!(delitems[i] = get_ssi_item(sess->ssi.items, sn[i], AIM_SSI_TYPE_BUDDY))) { |
646 free(delitems); | 607 free(delitems); |
647 return -EINVAL; | 608 return -EINVAL; |
648 } | 609 } |
649 | 610 |
650 /* Remove the delitems from the item list */ | 611 /* Remove the delitems from the item list */ |
656 cur->next = cur->next->next; | 617 cur->next = cur->next->next; |
657 } | 618 } |
658 } | 619 } |
659 | 620 |
660 /* Send the del item SNAC */ | 621 /* Send the del item SNAC */ |
661 aim_ssi_delitems(sess, conn, delitems, num); | 622 aim_ssi_addmoddel(sess, conn, delitems, num, AIM_CB_SSI_DEL); |
662 | 623 |
663 /* Free the items */ | 624 /* Free the items */ |
664 for (i=0; i<num; i++) { | 625 for (i=0; i<num; i++) { |
665 if (delitems[i]->name) | 626 if (delitems[i]->name) |
666 free(delitems[i]->name); | 627 free(delitems[i]->name); |
672 | 633 |
673 /* Rebuild the additional data in the parent group */ | 634 /* Rebuild the additional data in the parent group */ |
674 aim_ssi_rebuildgroup(sess, conn, parentgroup); | 635 aim_ssi_rebuildgroup(sess, conn, parentgroup); |
675 | 636 |
676 /* Send the mod item SNAC */ | 637 /* Send the mod item SNAC */ |
677 aim_ssi_moditems(sess, conn, &parentgroup, 1); | 638 aim_ssi_addmoddel(sess, conn, &parentgroup, 1, AIM_CB_SSI_MOD); |
678 | 639 |
679 /* Delete the group, but only if it's empty */ | 640 /* Delete the group, but only if it's empty */ |
680 if (!parentgroup->data) | 641 if (!parentgroup->data) |
681 aim_ssi_delgroups(sess, conn, &parentgroup->name, 1); | 642 aim_ssi_delgroups(sess, conn, &parentgroup->name, 1); |
682 | 643 |
684 aim_ssi_dispatch(sess, conn); | 645 aim_ssi_dispatch(sess, conn); |
685 | 646 |
686 return 0; | 647 return 0; |
687 } | 648 } |
688 | 649 |
650 faim_export int aim_ssi_delmastergroup(aim_session_t *sess, aim_conn_t *conn) { | |
651 struct aim_ssi_item *cur, *delitem; | |
652 | |
653 if (!sess || !conn) | |
654 return -EINVAL; | |
655 | |
656 /* Make delitem a pointer to the aim_ssi_item to be deleted */ | |
657 if (!(delitem = get_ssi_item(sess->ssi.items, NULL, AIM_SSI_TYPE_GROUP))) | |
658 return -EINVAL; | |
659 | |
660 /* Remove delitem from the item list */ | |
661 if (sess->ssi.items == delitem) { | |
662 sess->ssi.items = sess->ssi.items->next; | |
663 } else { | |
664 for (cur=sess->ssi.items; (cur->next && (cur->next!=delitem)); cur=cur->next); | |
665 if (cur->next) | |
666 cur->next = cur->next->next; | |
667 } | |
668 | |
669 /* Send the del item SNAC */ | |
670 aim_ssi_addmoddel(sess, conn, &delitem, 1, AIM_CB_SSI_DEL); | |
671 | |
672 /* Free the item */ | |
673 if (delitem->name) | |
674 free(delitem->name); | |
675 if (delitem->data) | |
676 aim_freetlvchain((aim_tlvlist_t **)&delitem->data); | |
677 free(delitem); | |
678 | |
679 /* Begin sending SSI SNACs */ | |
680 aim_ssi_dispatch(sess, conn); | |
681 | |
682 return 0; | |
683 } | |
684 | |
689 faim_export int aim_ssi_delgroups(aim_session_t *sess, aim_conn_t *conn, char **gn, unsigned int num) { | 685 faim_export int aim_ssi_delgroups(aim_session_t *sess, aim_conn_t *conn, char **gn, unsigned int num) { |
690 struct aim_ssi_item *cur, *parentgroup, **delitems; | 686 struct aim_ssi_item *cur, *parentgroup, **delitems; |
691 int i; | 687 int i; |
692 | 688 |
693 if (!sess || !conn || !gn || !num) | 689 if (!sess || !conn || !gn || !num) |
694 return -EINVAL; | 690 return -EINVAL; |
695 | 691 |
696 /* Look up the parent group */ | 692 /* Look up the parent group */ |
697 if (!(parentgroup = get_ssi_item(sess->ssi.items, NULL, 0x0001))) | 693 if (!(parentgroup = get_ssi_item(sess->ssi.items, NULL, AIM_SSI_TYPE_GROUP))) |
698 return -EINVAL; | 694 return -EINVAL; |
699 | 695 |
700 /* Allocate an array of pointers to each of the items to be deleted */ | 696 /* Allocate an array of pointers to each of the items to be deleted */ |
701 delitems = (struct aim_ssi_item **)malloc(num*sizeof(struct aim_ssi_item *)); | 697 delitems = (struct aim_ssi_item **)malloc(num*sizeof(struct aim_ssi_item *)); |
702 bzero(delitems, num*sizeof(struct aim_ssi_item *)); | 698 memset(delitems, 0, num*sizeof(struct aim_ssi_item *)); |
703 | 699 |
704 /* Make the delitems array a pointer to the aim_ssi_item structs to be deleted */ | 700 /* Make the delitems array a pointer to the aim_ssi_item structs to be deleted */ |
705 for (i=0; i<num; i++) { | 701 for (i=0; i<num; i++) { |
706 if (!(delitems[i] = get_ssi_item(sess->ssi.items, gn[i], 0x0001))) { | 702 if (!(delitems[i] = get_ssi_item(sess->ssi.items, gn[i], AIM_SSI_TYPE_GROUP))) { |
707 free(delitems); | 703 free(delitems); |
708 return -EINVAL; | 704 return -EINVAL; |
709 } | 705 } |
710 | 706 |
711 /* Remove the delitems from the item list */ | 707 /* Remove the delitems from the item list */ |
717 cur->next = cur->next->next; | 713 cur->next = cur->next->next; |
718 } | 714 } |
719 } | 715 } |
720 | 716 |
721 /* Send the del item SNAC */ | 717 /* Send the del item SNAC */ |
722 aim_ssi_delitems(sess, conn, delitems, num); | 718 aim_ssi_addmoddel(sess, conn, delitems, num, AIM_CB_SSI_DEL); |
723 | 719 |
724 /* Free the items */ | 720 /* Free the items */ |
725 for (i=0; i<num; i++) { | 721 for (i=0; i<num; i++) { |
726 if (delitems[i]->name) | 722 if (delitems[i]->name) |
727 free(delitems[i]->name); | 723 free(delitems[i]->name); |
733 | 729 |
734 /* Rebuild the additional data in the parent group */ | 730 /* Rebuild the additional data in the parent group */ |
735 aim_ssi_rebuildgroup(sess, conn, parentgroup); | 731 aim_ssi_rebuildgroup(sess, conn, parentgroup); |
736 | 732 |
737 /* Send the mod item SNAC */ | 733 /* Send the mod item SNAC */ |
738 aim_ssi_moditems(sess, conn, &parentgroup, 1); | 734 aim_ssi_addmoddel(sess, conn, &parentgroup, 1, AIM_CB_SSI_MOD); |
739 | 735 |
740 /* Delete the group, but only if it's empty */ | 736 /* Delete the group, but only if it's empty */ |
741 if (!parentgroup->data) | 737 if (!parentgroup->data) |
742 aim_ssi_delgroups(sess, conn, &parentgroup->name, 1); | 738 aim_ssi_delmastergroup(sess, conn); |
743 | 739 |
744 /* Begin sending SSI SNACs */ | 740 /* Begin sending SSI SNACs */ |
745 aim_ssi_dispatch(sess, conn); | 741 aim_ssi_dispatch(sess, conn); |
746 | 742 |
747 return 0; | 743 return 0; |
748 } | 744 } |
749 | 745 |
750 faim_export int aim_ssi_delpermits(aim_session_t *sess, aim_conn_t *conn, char **sn, unsigned int num) { | 746 faim_export int aim_ssi_delpord(aim_session_t *sess, aim_conn_t *conn, char **sn, unsigned int num, fu16_t type) { |
751 struct aim_ssi_item *cur, **delitems; | 747 struct aim_ssi_item *cur, **delitems; |
752 int i; | 748 int i; |
753 | 749 |
754 if (!sess || !conn || !sn || !num) | 750 if (!sess || !conn || !sn || !num || (type!=AIM_SSI_TYPE_PERMIT && type!=AIM_SSI_TYPE_DENY)) |
755 return -EINVAL; | 751 return -EINVAL; |
756 | 752 |
757 /* Allocate an array of pointers to each of the items to be deleted */ | 753 /* Allocate an array of pointers to each of the items to be deleted */ |
758 delitems = (struct aim_ssi_item **)malloc(num*sizeof(struct aim_ssi_item *)); | 754 delitems = (struct aim_ssi_item **)malloc(num*sizeof(struct aim_ssi_item *)); |
759 bzero(delitems, num*sizeof(struct aim_ssi_item *)); | 755 memset(delitems, 0, num*sizeof(struct aim_ssi_item *)); |
760 | 756 |
761 /* Make the delitems array a pointer to the aim_ssi_item structs to be deleted */ | 757 /* Make the delitems array a pointer to the aim_ssi_item structs to be deleted */ |
762 for (i=0; i<num; i++) { | 758 for (i=0; i<num; i++) { |
763 if (!(delitems[i] = get_ssi_item(sess->ssi.items, sn[i], 0x0002))) { | 759 if (!(delitems[i] = get_ssi_item(sess->ssi.items, sn[i], type))) { |
764 free(delitems); | 760 free(delitems); |
765 return -EINVAL; | 761 return -EINVAL; |
766 } | 762 } |
767 | 763 |
768 /* Remove the delitems from the item list */ | 764 /* Remove the delitems from the item list */ |
774 cur->next = cur->next->next; | 770 cur->next = cur->next->next; |
775 } | 771 } |
776 } | 772 } |
777 | 773 |
778 /* Send the del item SNAC */ | 774 /* Send the del item SNAC */ |
779 aim_ssi_delitems(sess, conn, delitems, num); | 775 aim_ssi_addmoddel(sess, conn, delitems, num, AIM_CB_SSI_DEL); |
780 | |
781 /* Free the items */ | |
782 for (i=0; i<num; i++) { | |
783 if (delitems[i]->name) | |
784 free(delitems[i]->name); | |
785 if (delitems[i]->data) | |
786 aim_freetlvchain((aim_tlvlist_t **)&delitems[i]->data); | |
787 free(delitems[i]); | |
788 } | |
789 free(delitems); | |
790 | |
791 /* Begin sending SSI SNACs */ | |
792 aim_ssi_dispatch(sess, conn); | |
793 | |
794 return 0; | |
795 } | |
796 | |
797 faim_export int aim_ssi_deldenies(aim_session_t *sess, aim_conn_t *conn, char **sn, unsigned int num) { | |
798 struct aim_ssi_item *cur, **delitems; | |
799 int i; | |
800 | |
801 if (!sess || !conn || !sn || !num) | |
802 return -EINVAL; | |
803 | |
804 /* Allocate an array of pointers to each of the items to be deleted */ | |
805 delitems = (struct aim_ssi_item **)malloc(num*sizeof(struct aim_ssi_item *)); | |
806 bzero(delitems, num*sizeof(struct aim_ssi_item *)); | |
807 | |
808 /* Make the delitems array a pointer to the aim_ssi_item structs to be deleted */ | |
809 for (i=0; i<num; i++) { | |
810 if (!(delitems[i] = get_ssi_item(sess->ssi.items, sn[i], 0x0003))) { | |
811 free(delitems); | |
812 return -EINVAL; | |
813 } | |
814 | |
815 /* Remove the delitems from the item list */ | |
816 if (sess->ssi.items == delitems[i]) { | |
817 sess->ssi.items = sess->ssi.items->next; | |
818 } else { | |
819 for (cur=sess->ssi.items; (cur->next && (cur->next!=delitems[i])); cur=cur->next); | |
820 if (cur->next) | |
821 cur->next = cur->next->next; | |
822 } | |
823 } | |
824 | |
825 /* Send the del item SNAC */ | |
826 aim_ssi_delitems(sess, conn, delitems, num); | |
827 | 776 |
828 /* Free the items */ | 777 /* Free the items */ |
829 for (i=0; i<num; i++) { | 778 for (i=0; i<num; i++) { |
830 if (delitems[i]->name) | 779 if (delitems[i]->name) |
831 free(delitems[i]->name); | 780 free(delitems[i]->name); |
858 | 807 |
859 if (!sess || !conn) | 808 if (!sess || !conn) |
860 return -EINVAL; | 809 return -EINVAL; |
861 | 810 |
862 /* Look up the permit/deny settings item */ | 811 /* Look up the permit/deny settings item */ |
863 for (cur=sess->ssi.items; (cur && (cur->type!=0x0004)); cur=cur->next); | 812 for (cur=sess->ssi.items; (cur && (cur->type!=AIM_SSI_TYPE_PDINFO)); cur=cur->next); |
864 | 813 |
865 if (cur) { | 814 if (cur) { |
866 /* The permit/deny item exists */ | 815 /* The permit/deny item exists */ |
867 if (cur->data && (tlv = aim_gettlv(cur->data, 0x00ca, 1))) { | 816 if (cur->data && (tlv = aim_gettlv(cur->data, 0x00ca, 1))) { |
868 /* Just change the value of the x00ca TLV */ | 817 /* Just change the value of the x00ca TLV */ |
876 /* Need to add the x00ca TLV to the TLV chain */ | 825 /* Need to add the x00ca TLV to the TLV chain */ |
877 aim_addtlvtochain8((aim_tlvlist_t**)&cur->data, 0x00ca, permdeny); | 826 aim_addtlvtochain8((aim_tlvlist_t**)&cur->data, 0x00ca, permdeny); |
878 } | 827 } |
879 | 828 |
880 /* Send the mod item SNAC */ | 829 /* Send the mod item SNAC */ |
881 aim_ssi_moditems(sess, conn, &cur, 1); | 830 aim_ssi_addmoddel(sess, conn, &cur, 1, AIM_CB_SSI_MOD); |
882 } else { | 831 } else { |
883 /* Need to add the permit/deny item */ | 832 /* Need to add the permit/deny item */ |
884 if (!(cur = (struct aim_ssi_item *)malloc(sizeof(struct aim_ssi_item)))) | 833 if (!(cur = (struct aim_ssi_item *)malloc(sizeof(struct aim_ssi_item)))) |
885 return -ENOMEM; | 834 return -ENOMEM; |
886 cur->name = NULL; | 835 cur->name = NULL; |
890 cur->bid += 0x0001; | 839 cur->bid += 0x0001; |
891 for (tmp=sess->ssi.items, j=0; ((tmp) && (!j)); tmp=tmp->next) | 840 for (tmp=sess->ssi.items, j=0; ((tmp) && (!j)); tmp=tmp->next) |
892 if (tmp->bid == cur->bid) | 841 if (tmp->bid == cur->bid) |
893 j=1; | 842 j=1; |
894 } while (j); | 843 } while (j); |
895 cur->type = 0x0004; | 844 cur->type = AIM_SSI_TYPE_PDINFO; |
896 cur->data = NULL; | 845 cur->data = NULL; |
897 aim_addtlvtochain8((aim_tlvlist_t**)&cur->data, 0x00ca, permdeny); | 846 aim_addtlvtochain8((aim_tlvlist_t**)&cur->data, 0x00ca, permdeny); |
898 aim_addtlvtochain32((aim_tlvlist_t**)&cur->data, 0x00cb, 0xffffffff); | 847 aim_addtlvtochain32((aim_tlvlist_t**)&cur->data, 0x00cb, 0xffffffff); |
899 | 848 |
900 /* Add the item to our list */ | 849 /* Add the item to our list */ |
901 cur->next = sess->ssi.items; | 850 cur->next = sess->ssi.items; |
902 sess->ssi.items = cur; | 851 sess->ssi.items = cur; |
903 | 852 |
904 /* Send the add item SNAC */ | 853 /* Send the add item SNAC */ |
905 aim_ssi_additems(sess, conn, &cur, 1); | 854 aim_ssi_addmoddel(sess, conn, &cur, 1, AIM_CB_SSI_ADD); |
906 } | 855 } |
907 | 856 |
908 /* Begin sending SSI SNACs */ | 857 /* Begin sending SSI SNACs */ |
909 aim_ssi_dispatch(sess, conn); | 858 aim_ssi_dispatch(sess, conn); |
910 | 859 |
914 /* | 863 /* |
915 * Request SSI Rights. | 864 * Request SSI Rights. |
916 */ | 865 */ |
917 faim_export int aim_ssi_reqrights(aim_session_t *sess, aim_conn_t *conn) | 866 faim_export int aim_ssi_reqrights(aim_session_t *sess, aim_conn_t *conn) |
918 { | 867 { |
919 return aim_genericreq_n(sess, conn, 0x0013, 0x0002); | 868 return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_REQRIGHTS); |
920 } | 869 } |
921 | 870 |
922 /* | 871 /* |
923 * SSI Rights Information. | 872 * SSI Rights Information. |
924 */ | 873 */ |
951 return -EINVAL; | 900 return -EINVAL; |
952 | 901 |
953 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4+2))) | 902 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4+2))) |
954 return -ENOMEM; | 903 return -ENOMEM; |
955 | 904 |
956 snacid = aim_cachesnac(sess, 0x0013, 0x0005, 0x0000, NULL, 0); | 905 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_REQLIST, 0x0000, NULL, 0); |
957 | 906 |
958 aim_putsnac(&fr->data, 0x0013, 0x0005, 0x0000, snacid); | 907 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_REQLIST, 0x0000, snacid); |
959 aimbs_put32(&fr->data, localstamp); | 908 aimbs_put32(&fr->data, localstamp); |
960 aimbs_put16(&fr->data, localrev); | 909 aimbs_put16(&fr->data, localrev); |
961 | 910 |
962 aim_tx_enqueue(sess, fr); | 911 aim_tx_enqueue(sess, fr); |
963 | 912 |
1032 * settings into effect. | 981 * settings into effect. |
1033 * | 982 * |
1034 */ | 983 */ |
1035 faim_export int aim_ssi_enable(aim_session_t *sess, aim_conn_t *conn) | 984 faim_export int aim_ssi_enable(aim_session_t *sess, aim_conn_t *conn) |
1036 { | 985 { |
1037 return aim_genericreq_n(sess, conn, 0x0013, 0x0007); | 986 return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, 0x0007); |
1038 } | 987 } |
1039 | 988 |
1040 /* | 989 /* |
1041 * SSI Add Item. | 990 * SSI Add/Mod/Del Item(s). |
1042 * | 991 * |
1043 * Adds an item to the data stored on the AIM server. An item could | 992 * Sends the SNAC to add, modify, or delete an item from the server-stored |
1044 * be a group, buddy, or permit or deny buddy. | 993 * information. These 3 SNACs all have an identical structure. The only |
994 * difference is the subtype that is set for the SNAC. | |
1045 * | 995 * |
1046 */ | 996 */ |
1047 faim_export int aim_ssi_additems(aim_session_t *sess, aim_conn_t *conn, struct aim_ssi_item **items, unsigned int num) | 997 faim_export int aim_ssi_addmoddel(aim_session_t *sess, aim_conn_t *conn, struct aim_ssi_item **items, unsigned int num, fu16_t subtype) |
1048 { | 998 { |
1049 aim_frame_t *fr; | 999 aim_frame_t *fr; |
1050 aim_snacid_t snacid; | 1000 aim_snacid_t snacid; |
1051 int i, snaclen; | 1001 int i, snaclen; |
1052 | 1002 |
1063 } | 1013 } |
1064 | 1014 |
1065 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, snaclen))) | 1015 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, snaclen))) |
1066 return -ENOMEM; | 1016 return -ENOMEM; |
1067 | 1017 |
1068 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_ADD, 0x0000, NULL, 0); | 1018 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, subtype, 0x0000, NULL, 0); |
1069 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_ADD, 0x0000, snacid); | 1019 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, subtype, 0x0000, snacid); |
1070 | 1020 |
1071 for (i=0; i<num; i++) { | 1021 for (i=0; i<num; i++) { |
1072 aimbs_put16(&fr->data, items[i]->name ? strlen(items[i]->name) : 0); | 1022 aimbs_put16(&fr->data, items[i]->name ? strlen(items[i]->name) : 0); |
1073 if (items[i]->name) | 1023 if (items[i]->name) |
1074 aimbs_putraw(&fr->data, items[i]->name, strlen(items[i]->name)); | 1024 aimbs_putraw(&fr->data, items[i]->name, strlen(items[i]->name)); |
1084 | 1034 |
1085 return 0; | 1035 return 0; |
1086 } | 1036 } |
1087 | 1037 |
1088 /* | 1038 /* |
1089 * SSI Mod Item. | |
1090 * | |
1091 * Modifies an item in the data stored on the AIM server. An item could | |
1092 * be a group, buddy, or permit or deny buddy. | |
1093 * | |
1094 */ | |
1095 faim_export int aim_ssi_moditems(aim_session_t *sess, aim_conn_t *conn, struct aim_ssi_item **items, unsigned int num) | |
1096 { | |
1097 aim_frame_t *fr; | |
1098 aim_snacid_t snacid; | |
1099 int i, snaclen; | |
1100 | |
1101 if (!sess || !conn || !items || !num) | |
1102 return -EINVAL; | |
1103 | |
1104 snaclen = 10; /* For family, subtype, flags, and SNAC ID */ | |
1105 for (i=0; i<num; i++) { | |
1106 snaclen += 10; /* For length, GID, BID, type, and length */ | |
1107 if (items[i]->name) | |
1108 snaclen += strlen(items[i]->name); | |
1109 if (items[i]->data) | |
1110 snaclen += aim_sizetlvchain((aim_tlvlist_t **)&items[i]->data); | |
1111 } | |
1112 | |
1113 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, snaclen))) | |
1114 return -ENOMEM; | |
1115 | |
1116 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_MOD, 0x0000, NULL, 0); | |
1117 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_MOD, 0x0000, snacid); | |
1118 | |
1119 for (i=0; i<num; i++) { | |
1120 aimbs_put16(&fr->data, items[i]->name ? strlen(items[i]->name) : 0); | |
1121 if (items[i]->name) | |
1122 aimbs_putraw(&fr->data, items[i]->name, strlen(items[i]->name)); | |
1123 aimbs_put16(&fr->data, items[i]->gid); | |
1124 aimbs_put16(&fr->data, items[i]->bid); | |
1125 aimbs_put16(&fr->data, items[i]->type); | |
1126 aimbs_put16(&fr->data, items[i]->data ? aim_sizetlvchain((aim_tlvlist_t **)&items[i]->data) : 0); | |
1127 if (items[i]->data) | |
1128 aim_writetlvchain(&fr->data, (aim_tlvlist_t **)&items[i]->data); | |
1129 } | |
1130 | |
1131 aim_ssi_enqueue(sess, conn, fr); | |
1132 | |
1133 return 0; | |
1134 } | |
1135 | |
1136 /* | |
1137 * SSI Del Item. | |
1138 * | |
1139 * Deletes an item from the data stored on the AIM server. An item | |
1140 * could be a group, buddy, or permit or deny buddy. | |
1141 * | |
1142 */ | |
1143 faim_export int aim_ssi_delitems(aim_session_t *sess, aim_conn_t *conn, struct aim_ssi_item **items, unsigned int num) | |
1144 { | |
1145 aim_frame_t *fr; | |
1146 aim_snacid_t snacid; | |
1147 int i, snaclen; | |
1148 | |
1149 if (!sess || !conn || !items || !num) | |
1150 return -EINVAL; | |
1151 | |
1152 snaclen = 10; /* For family, subtype, flags, and SNAC ID */ | |
1153 for (i=0; i<num; i++) { | |
1154 snaclen += 10; /* For length, GID, BID, type, and length */ | |
1155 if (items[i]->name) | |
1156 snaclen += strlen(items[i]->name); | |
1157 if (items[i]->data) | |
1158 snaclen += aim_sizetlvchain((aim_tlvlist_t **)&items[i]->data); | |
1159 } | |
1160 | |
1161 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, snaclen))) | |
1162 return -ENOMEM; | |
1163 | |
1164 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_DEL, 0x0000, NULL, 0); | |
1165 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_DEL, 0x0000, snacid); | |
1166 | |
1167 for (i=0; i<num; i++) { | |
1168 aimbs_put16(&fr->data, items[i]->name ? strlen(items[i]->name) : 0); | |
1169 if (items[i]->name) | |
1170 aimbs_putraw(&fr->data, items[i]->name, strlen(items[i]->name)); | |
1171 aimbs_put16(&fr->data, items[i]->gid); | |
1172 aimbs_put16(&fr->data, items[i]->bid); | |
1173 aimbs_put16(&fr->data, items[i]->type); | |
1174 aimbs_put16(&fr->data, items[i]->data ? aim_sizetlvchain((aim_tlvlist_t **)&items[i]->data) : 0); | |
1175 if (items[i]->data) | |
1176 aim_writetlvchain(&fr->data, (aim_tlvlist_t **)&items[i]->data); | |
1177 } | |
1178 | |
1179 aim_ssi_enqueue(sess, conn, fr); | |
1180 | |
1181 return 0; | |
1182 } | |
1183 | |
1184 /* | |
1185 * SSI Add/Mod/Del Ack. | 1039 * SSI Add/Mod/Del Ack. |
1186 * | 1040 * |
1187 * Response to aim_ssi_additem(), aim_ssi_moditem(), or aim_ssi_delitem(). | 1041 * Response to add, modify, or delete SNAC (sent with aim_ssi_addmoddel). |
1188 * | 1042 * |
1189 */ | 1043 */ |
1190 static int parseack(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) | 1044 static int parseack(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) |
1191 { | 1045 { |
1192 int ret = 0; | 1046 int ret = 0; |
1207 * Tells the server you're going to start modifying data. | 1061 * Tells the server you're going to start modifying data. |
1208 * | 1062 * |
1209 */ | 1063 */ |
1210 faim_export int aim_ssi_modbegin(aim_session_t *sess, aim_conn_t *conn) | 1064 faim_export int aim_ssi_modbegin(aim_session_t *sess, aim_conn_t *conn) |
1211 { | 1065 { |
1212 return aim_genericreq_n(sess, conn, 0x0013, 0x0011); | 1066 return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_EDITSTART); |
1213 } | 1067 } |
1214 | 1068 |
1215 /* | 1069 /* |
1216 * SSI End Data Modification. | 1070 * SSI End Data Modification. |
1217 * | 1071 * |
1218 * Tells the server you're done modifying data. | 1072 * Tells the server you're done modifying data. |
1219 * | 1073 * |
1220 */ | 1074 */ |
1221 faim_export int aim_ssi_modend(aim_session_t *sess, aim_conn_t *conn) | 1075 faim_export int aim_ssi_modend(aim_session_t *sess, aim_conn_t *conn) |
1222 { | 1076 { |
1223 return aim_genericreq_n(sess, conn, 0x0013, 0x0012); | 1077 return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_EDITSTOP); |
1224 } | 1078 } |
1225 | 1079 |
1226 /* | 1080 /* |
1227 * SSI Data Unchanged. | 1081 * SSI Data Unchanged. |
1228 * | 1082 * |
1244 } | 1098 } |
1245 | 1099 |
1246 static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) | 1100 static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) |
1247 { | 1101 { |
1248 | 1102 |
1249 if (snac->subtype == 0x0003) | 1103 if (snac->subtype == AIM_CB_SSI_RIGHTSINFO) |
1250 return parserights(sess, mod, rx, snac, bs); | 1104 return parserights(sess, mod, rx, snac, bs); |
1251 else if (snac->subtype == 0x006) | 1105 else if (snac->subtype == AIM_CB_SSI_LIST) |
1252 return parsedata(sess, mod, rx, snac, bs); | 1106 return parsedata(sess, mod, rx, snac, bs); |
1253 else if (snac->subtype == AIM_CB_SSI_SRVACK) | 1107 else if (snac->subtype == AIM_CB_SSI_SRVACK) |
1254 return parseack(sess, mod, rx, snac, bs); | 1108 return parseack(sess, mod, rx, snac, bs); |
1255 else if (snac->subtype == 0x00f) | 1109 else if (snac->subtype == AIM_CB_SSI_NOLIST) |
1256 return parsedataunchanged(sess, mod, rx, snac, bs); | 1110 return parsedataunchanged(sess, mod, rx, snac, bs); |
1257 | 1111 |
1258 return 0; | 1112 return 0; |
1259 } | 1113 } |
1260 | 1114 |
1266 } | 1120 } |
1267 | 1121 |
1268 faim_internal int ssi_modfirst(aim_session_t *sess, aim_module_t *mod) | 1122 faim_internal int ssi_modfirst(aim_session_t *sess, aim_module_t *mod) |
1269 { | 1123 { |
1270 | 1124 |
1271 mod->family = 0x0013; | 1125 mod->family = AIM_CB_FAM_SSI; |
1272 mod->version = 0x0001; | 1126 mod->version = 0x0001; |
1273 mod->toolid = 0x0110; | 1127 mod->toolid = 0x0110; |
1274 mod->toolversion = 0x047b; | 1128 mod->toolversion = 0x047b; |
1275 mod->flags = 0; | 1129 mod->flags = 0; |
1276 strncpy(mod->name, "ssi", sizeof(mod->name)); | 1130 strncpy(mod->name, "ssi", sizeof(mod->name)); |