- Timestamp:
- Oct 15, 2003, 2:37:23 PM (22 years ago)
- Branches:
- master, barnowl_perlaim, debian, owl, release-1.10, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
- Children:
- c5f3b46
- Parents:
- 257a22f
- File:
-
- 1 edited
-
libfaim/ssi.c (modified) (45 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libfaim/ssi.c
re374dee r2ecac24 39 39 static struct aim_ssi_item *aim_ssi_itemlist_rebuildgroup(struct aim_ssi_item *list, const char *name) 40 40 { 41 int newlen;42 struct aim_ssi_item *cur, *group;43 44 if (!list)45 return NULL;46 47 /* Find the group */48 if (!(group = aim_ssi_itemlist_finditem(list, name, NULL, AIM_SSI_TYPE_GROUP)))49 return NULL;50 51 /* Free the old data */52 aim_freetlvchain(&group->data);53 group->data = NULL;54 55 /* Find the length for the new additional data */56 newlen = 0;57 if (group->gid == 0x0000) {58 for (cur=list; cur; cur=cur->next)59 if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid != 0x0000))60 newlen += 2;61 } else {62 for (cur=list; cur; cur=cur->next)63 if ((cur->gid == group->gid) && (cur->type == AIM_SSI_TYPE_BUDDY))64 newlen += 2;65 }66 67 /* Build the new TLV list */68 if (newlen > 0) {69 fu8_t *newdata;70 71 if (!(newdata = (fu8_t *)malloc((newlen)*sizeof(fu8_t))))72 return NULL;73 newlen = 0;74 if (group->gid == 0x0000) {75 for (cur=list; cur; cur=cur->next)76 if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid != 0x0000))77 newlen += aimutil_put16(newdata+newlen, cur->gid);78 } else {79 for (cur=list; cur; cur=cur->next)80 if ((cur->gid == group->gid) && (cur->type == AIM_SSI_TYPE_BUDDY))81 newlen += aimutil_put16(newdata+newlen, cur->bid);82 }83 aim_addtlvtochain_raw(&group->data, 0x00c8, newlen, newdata);84 85 free(newdata);86 }87 88 return group;41 int newlen; 42 struct aim_ssi_item *cur, *group; 43 44 if (!list) 45 return NULL; 46 47 /* Find the group */ 48 if (!(group = aim_ssi_itemlist_finditem(list, name, NULL, AIM_SSI_TYPE_GROUP))) 49 return NULL; 50 51 /* Free the old data */ 52 aim_freetlvchain(&group->data); 53 group->data = NULL; 54 55 /* Find the length for the new additional data */ 56 newlen = 0; 57 if (group->gid == 0x0000) { 58 for (cur=list; cur; cur=cur->next) 59 if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid != 0x0000)) 60 newlen += 2; 61 } else { 62 for (cur=list; cur; cur=cur->next) 63 if ((cur->gid == group->gid) && (cur->type == AIM_SSI_TYPE_BUDDY)) 64 newlen += 2; 65 } 66 67 /* Build the new TLV list */ 68 if (newlen > 0) { 69 fu8_t *newdata; 70 71 if (!(newdata = (fu8_t *)malloc((newlen)*sizeof(fu8_t)))) 72 return NULL; 73 newlen = 0; 74 if (group->gid == 0x0000) { 75 for (cur=list; cur; cur=cur->next) 76 if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid != 0x0000)) 77 newlen += aimutil_put16(newdata+newlen, cur->gid); 78 } else { 79 for (cur=list; cur; cur=cur->next) 80 if ((cur->gid == group->gid) && (cur->type == AIM_SSI_TYPE_BUDDY)) 81 newlen += aimutil_put16(newdata+newlen, cur->bid); 82 } 83 aim_addtlvtochain_raw(&group->data, 0x00c8, newlen, newdata); 84 85 free(newdata); 86 } 87 88 return group; 89 89 } 90 90 … … 103 103 static struct aim_ssi_item *aim_ssi_itemlist_add(struct aim_ssi_item **list, const char *name, fu16_t gid, fu16_t bid, fu16_t type, aim_tlvlist_t *data) 104 104 { 105 int i; 106 struct aim_ssi_item *cur, *new; 107 108 if (!list) 109 return NULL; 110 111 if (!(new = (struct aim_ssi_item *)malloc(sizeof(struct aim_ssi_item)))) 112 return NULL; 113 114 /* Set the name */ 115 if (name) { 116 new->name = (char *)malloc((strlen(name)+1)*sizeof(char)); 117 strcpy(new->name, name); 118 } else 119 new->name = NULL; 120 121 /* Set the group ID# and buddy ID# */ 122 new->gid = gid; 123 new->bid = bid; 124 if (type == AIM_SSI_TYPE_GROUP) { 125 if ((new->gid == 0xFFFF) && name) { 126 do { 127 new->gid += 0x0001; 128 for (cur=*list, i=0; ((cur) && (!i)); cur=cur->next) 129 if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid == new->gid)) 130 i=1; 131 } while (i); 132 } 133 } else { 134 if (new->bid == 0xFFFF) { 135 do { 136 new->bid += 0x0001; 137 for (cur=*list, i=0; ((cur) && (!i)); cur=cur->next) 138 if ((cur->bid == new->bid) && (cur->gid == new->gid)) 139 i=1; 140 } while (i); 141 } 142 } 143 144 /* Set the type */ 145 new->type = type; 146 147 /* Set the TLV list */ 148 new->data = aim_tlvlist_copy(data); 149 150 /* Add the item to the list in the correct numerical position. Fancy, eh? */ 151 if (*list) { 152 if ((new->gid < (*list)->gid) || ((new->gid == (*list)->gid) && (new->bid < (*list)->bid))) { 153 new->next = *list; 154 *list = new; 155 } else { 156 struct aim_ssi_item *prev; 157 for ((prev=*list, cur=(*list)->next); (cur && ((new->gid > cur->gid) || ((new->gid == cur->gid) && (new->bid > cur->bid)))); prev=cur, cur=cur->next); 158 new->next = prev->next; 159 prev->next = new; 160 } 161 } else { 162 new->next = *list; 163 *list = new; 164 } 165 166 return new; 105 int i; 106 struct aim_ssi_item *cur, *new; 107 108 if (!list) return(NULL); 109 110 if (!(new = (struct aim_ssi_item *)malloc(sizeof(struct aim_ssi_item)))) return(NULL); 111 112 /* Set the name */ 113 if (name) { 114 new->name = (char *)malloc((strlen(name)+1)*sizeof(char)); 115 strcpy(new->name, name); 116 } else { 117 new->name = NULL; 118 } 119 120 /* Set the group ID# and buddy ID# */ 121 new->gid = gid; 122 new->bid = bid; 123 if (type == AIM_SSI_TYPE_GROUP) { 124 if ((new->gid == 0xFFFF) && name) { 125 do { 126 new->gid += 0x0001; 127 for (cur=*list, i=0; ((cur) && (!i)); cur=cur->next) 128 if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid == new->gid)) 129 i=1; 130 } while (i); 131 } 132 } else { 133 if (new->bid == 0xFFFF) { 134 do { 135 new->bid += 0x0001; 136 for (cur=*list, i=0; ((cur) && (!i)); cur=cur->next) 137 if ((cur->bid == new->bid) && (cur->gid == new->gid)) 138 i=1; 139 } while (i); 140 } 141 } 142 143 /* Set the type */ 144 new->type = type; 145 146 /* Set the TLV list */ 147 new->data = aim_tlvlist_copy(data); 148 149 /* Add the item to the list in the correct numerical position. Fancy, eh? */ 150 if (*list) { 151 if ((new->gid < (*list)->gid) || ((new->gid == (*list)->gid) && (new->bid < (*list)->bid))) { 152 new->next = *list; 153 *list = new; 154 } else { 155 struct aim_ssi_item *prev; 156 for ((prev=*list, cur=(*list)->next); (cur && ((new->gid > cur->gid) || ((new->gid == cur->gid) && (new->bid > cur->bid)))); prev=cur, cur=cur->next); 157 new->next = prev->next; 158 prev->next = new; 159 } 160 } else { 161 new->next = *list; 162 *list = new; 163 } 164 165 return(new); 167 166 } 168 167 … … 176 175 static int aim_ssi_itemlist_del(struct aim_ssi_item **list, struct aim_ssi_item *del) 177 176 { 178 if (!list || !(*list) || !del) 179 return -EINVAL; 180 181 /* Remove the item from the list */ 182 if (*list == del) { 183 *list = (*list)->next; 184 } else { 185 struct aim_ssi_item *cur; 186 for (cur=*list; (cur->next && (cur->next!=del)); cur=cur->next); 187 if (cur->next) 188 cur->next = cur->next->next; 189 } 190 191 /* Free the deleted item */ 192 free(del->name); 193 aim_freetlvchain(&del->data); 194 free(del); 195 196 return 0; 177 if (!list || !(*list) || !del) return -EINVAL; 178 179 /* Remove the item from the list */ 180 if (*list == del) { 181 *list = (*list)->next; 182 } else { 183 struct aim_ssi_item *cur; 184 for (cur=*list; (cur->next && (cur->next!=del)); cur=cur->next); 185 if (cur->next) cur->next=cur->next->next; 186 } 187 188 /* Free the deleted item */ 189 free(del->name); 190 aim_freetlvchain(&del->data); 191 free(del); 192 193 return(0); 197 194 } 198 195 … … 206 203 static int aim_ssi_itemlist_cmp(struct aim_ssi_item *cur1, struct aim_ssi_item *cur2) 207 204 { 208 if (!cur1 || !cur2)209 return 1;210 211 if (cur1->data && !cur2->data)212 return 2;213 214 if (!cur1->data && cur2->data)215 return 3;216 217 if ((cur1->data && cur2->data) && (aim_tlvlist_cmp(cur1->data, cur2->data)))218 return 4;219 220 if (cur1->name && !cur2->name)221 return 5;222 223 if (!cur1->name && cur2->name)224 return 6;225 226 if (cur1->name && cur2->name && aim_sncmp(cur1->name, cur2->name))227 return 7;228 229 if (cur1->gid != cur2->gid)230 return 8;231 232 if (cur1->bid != cur2->bid)233 return 9;234 235 if (cur1->type != cur2->type)236 return 10;237 238 return 0;205 if (!cur1 || !cur2) 206 return 1; 207 208 if (cur1->data && !cur2->data) 209 return 2; 210 211 if (!cur1->data && cur2->data) 212 return 3; 213 214 if ((cur1->data && cur2->data) && (aim_tlvlist_cmp(cur1->data, cur2->data))) 215 return 4; 216 217 if (cur1->name && !cur2->name) 218 return 5; 219 220 if (!cur1->name && cur2->name) 221 return 6; 222 223 if (cur1->name && cur2->name && aim_sncmp(cur1->name, cur2->name)) 224 return 7; 225 226 if (cur1->gid != cur2->gid) 227 return 8; 228 229 if (cur1->bid != cur2->bid) 230 return 9; 231 232 if (cur1->type != cur2->type) 233 return 10; 234 235 return 0; 239 236 } 240 237 241 238 faim_export int aim_ssi_itemlist_valid(struct aim_ssi_item *list, struct aim_ssi_item *item) 242 239 { 243 struct aim_ssi_item *cur;244 for (cur=list; cur; cur=cur->next)245 if (cur == item)246 return 1;247 return 0;240 struct aim_ssi_item *cur; 241 for (cur=list; cur; cur=cur->next) 242 if (cur == item) 243 return 1; 244 return 0; 248 245 } 249 246 … … 258 255 faim_export struct aim_ssi_item *aim_ssi_itemlist_find(struct aim_ssi_item *list, fu16_t gid, fu16_t bid) 259 256 { 260 struct aim_ssi_item *cur;261 for (cur=list; cur; cur=cur->next)262 if ((cur->gid == gid) && (cur->bid == bid))263 return cur;264 return NULL;257 struct aim_ssi_item *cur; 258 for (cur=list; cur; cur=cur->next) 259 if ((cur->gid == gid) && (cur->bid == bid)) 260 return cur; 261 return NULL; 265 262 } 266 263 … … 277 274 faim_export struct aim_ssi_item *aim_ssi_itemlist_finditem(struct aim_ssi_item *list, const char *gn, const char *sn, fu16_t type) 278 275 { 279 struct aim_ssi_item *cur;280 if (!list)281 return NULL;282 283 if (gn && sn) { /* For finding buddies in groups */284 for (cur=list; cur; cur=cur->next)285 if ((cur->type == type) && (cur->name) && !(aim_sncmp(cur->name, sn))) {286 struct aim_ssi_item *curg;287 for (curg=list; curg; curg=curg->next)288 if ((curg->type == AIM_SSI_TYPE_GROUP) && (curg->gid == cur->gid) && (curg->name) && !(aim_sncmp(curg->name, gn)))289 return cur;290 }291 292 } else if (gn) { /* For finding groups */293 for (cur=list; cur; cur=cur->next) {294 if ((cur->type == type) && (cur->bid == 0x0000) && (cur->name) && !(aim_sncmp(cur->name, gn))) {295 return cur;296 }297 }298 299 } else if (sn) { /* For finding permits, denies, and ignores */300 for (cur=list; cur; cur=cur->next) {301 if ((cur->type == type) && (cur->name) && !(aim_sncmp(cur->name, sn))) {302 return cur;303 }304 }305 306 /* For stuff without names--permit deny setting, visibility mask, etc. */307 } else for (cur=list; cur; cur=cur->next) {308 if ((cur->type == type) && (!cur->name))309 return cur;310 }311 312 return NULL;276 struct aim_ssi_item *cur; 277 if (!list) 278 return NULL; 279 280 if (gn && sn) { /* For finding buddies in groups */ 281 for (cur=list; cur; cur=cur->next) 282 if ((cur->type == type) && (cur->name) && !(aim_sncmp(cur->name, sn))) { 283 struct aim_ssi_item *curg; 284 for (curg=list; curg; curg=curg->next) 285 if ((curg->type == AIM_SSI_TYPE_GROUP) && (curg->gid == cur->gid) && (curg->name) && !(aim_sncmp(curg->name, gn))) 286 return cur; 287 } 288 289 } else if (gn) { /* For finding groups */ 290 for (cur=list; cur; cur=cur->next) { 291 if ((cur->type == type) && (cur->bid == 0x0000) && (cur->name) && !(aim_sncmp(cur->name, gn))) { 292 return cur; 293 } 294 } 295 296 } else if (sn) { /* For finding permits, denies, and ignores */ 297 for (cur=list; cur; cur=cur->next) { 298 if ((cur->type == type) && (cur->name) && !(aim_sncmp(cur->name, sn))) { 299 return cur; 300 } 301 } 302 303 /* For stuff without names--permit deny setting, visibility mask, etc. */ 304 } else for (cur=list; cur; cur=cur->next) { 305 if ((cur->type == type) && (!cur->name)) 306 return cur; 307 } 308 309 return NULL; 313 310 } 314 311 … … 322 319 faim_export struct aim_ssi_item *aim_ssi_itemlist_exists(struct aim_ssi_item *list, const char *sn) 323 320 { 324 struct aim_ssi_item *cur;325 if (!list || !sn)326 return NULL;327 for (cur=list; cur; cur=cur->next)328 if ((cur->type == AIM_SSI_TYPE_BUDDY) && (cur->name) && (!aim_sncmp(cur->name, sn)))329 return cur;330 return NULL;321 struct aim_ssi_item *cur; 322 if (!list || !sn) 323 return NULL; 324 for (cur=list; cur; cur=cur->next) 325 if ((cur->type == AIM_SSI_TYPE_BUDDY) && (cur->name) && (!aim_sncmp(cur->name, sn))) 326 return cur; 327 return NULL; 331 328 } 332 329 … … 340 337 faim_export char *aim_ssi_itemlist_findparentname(struct aim_ssi_item *list, const char *sn) 341 338 { 342 struct aim_ssi_item *cur, *curg;343 if (!list || !sn)344 return NULL;345 if (!(cur = aim_ssi_itemlist_exists(list, sn)))346 return NULL;347 if (!(curg = aim_ssi_itemlist_find(list, cur->gid, 0x0000)))348 return NULL;349 return curg->name;339 struct aim_ssi_item *cur, *curg; 340 if (!list || !sn) 341 return NULL; 342 if (!(cur = aim_ssi_itemlist_exists(list, sn))) 343 return NULL; 344 if (!(curg = aim_ssi_itemlist_find(list, cur->gid, 0x0000))) 345 return NULL; 346 return curg->name; 350 347 } 351 348 … … 358 355 faim_export int aim_ssi_getpermdeny(struct aim_ssi_item *list) 359 356 { 360 struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, NULL, NULL, AIM_SSI_TYPE_PDINFO);361 if (cur) {362 aim_tlvlist_t *tlvlist = cur->data;363 if (tlvlist) {364 aim_tlv_t *tlv = aim_gettlv(tlvlist, 0x00ca, 1);365 if (tlv && tlv->value)366 return aimutil_get8(tlv->value);367 }368 }369 return 0;357 struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, NULL, NULL, AIM_SSI_TYPE_PDINFO); 358 if (cur) { 359 aim_tlvlist_t *tlvlist = cur->data; 360 if (tlvlist) { 361 aim_tlv_t *tlv = aim_gettlv(tlvlist, 0x00ca, 1); 362 if (tlv && tlv->value) 363 return aimutil_get8(tlv->value); 364 } 365 } 366 return 0; 370 367 } 371 368 … … 380 377 faim_export fu32_t aim_ssi_getpresence(struct aim_ssi_item *list) 381 378 { 382 struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS);383 if (cur) {384 aim_tlvlist_t *tlvlist = cur->data;385 if (tlvlist) {386 aim_tlv_t *tlv = aim_gettlv(tlvlist, 0x00c9, 1);387 if (tlv && tlv->length)388 return aimutil_get32(tlv->value);389 }390 }391 return 0xFFFFFFFF;379 struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS); 380 if (cur) { 381 aim_tlvlist_t *tlvlist = cur->data; 382 if (tlvlist) { 383 aim_tlv_t *tlv = aim_gettlv(tlvlist, 0x00c9, 1); 384 if (tlv && tlv->length) 385 return aimutil_get32(tlv->value); 386 } 387 } 388 return 0xFFFFFFFF; 392 389 } 393 390 … … 404 401 faim_export char *aim_ssi_getalias(struct aim_ssi_item *list, const char *gn, const char *sn) 405 402 { 406 struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, sn, AIM_SSI_TYPE_BUDDY);407 if (cur) {408 aim_tlvlist_t *tlvlist = cur->data;409 if (tlvlist) {410 aim_tlv_t *tlv = aim_gettlv(tlvlist, 0x0131, 1);411 if (tlv && tlv->length) {412 char *alias = (char *)malloc((tlv->length+1)*sizeof(char));413 strncpy(alias, tlv->value, tlv->length);414 alias[tlv->length] = 0;415 return alias;416 }417 }418 }419 return NULL;403 struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, sn, AIM_SSI_TYPE_BUDDY); 404 if (cur) { 405 aim_tlvlist_t *tlvlist = cur->data; 406 if (tlvlist) { 407 aim_tlv_t *tlv = aim_gettlv(tlvlist, 0x0131, 1); 408 if (tlv && tlv->length) { 409 char *alias = (char *)malloc((tlv->length+1)*sizeof(char)); 410 strncpy(alias, tlv->value, tlv->length); 411 alias[tlv->length] = 0; 412 return alias; 413 } 414 } 415 } 416 return NULL; 420 417 } 421 418 … … 432 429 faim_export int aim_ssi_waitingforauth(struct aim_ssi_item *list, const char *gn, const char *sn) 433 430 { 434 struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, sn, AIM_SSI_TYPE_BUDDY);435 if (cur) {436 aim_tlvlist_t *tlvlist = cur->data;437 if (tlvlist)438 if (aim_gettlv(tlvlist, 0x0066, 1))439 return 1;440 }441 return 0;431 struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, sn, AIM_SSI_TYPE_BUDDY); 432 if (cur) { 433 aim_tlvlist_t *tlvlist = cur->data; 434 if (tlvlist) 435 if (aim_gettlv(tlvlist, 0x0066, 1)) 436 return 1; 437 } 438 return 0; 442 439 } 443 440 … … 451 448 static int aim_ssi_sync(aim_session_t *sess) 452 449 { 453 struct aim_ssi_item *cur1, *cur2;454 struct aim_ssi_tmp *cur, *new;455 456 if (!sess)457 return -EINVAL;458 459 /* If we're waiting for an ack, we shouldn't do anything else */460 if (sess->ssi.waiting_for_ack)461 return 0;462 463 /*464 * Compare the 2 lists and create an aim_ssi_tmp for each difference.465 * We should only send either additions, modifications, or deletions466 * before waiting for an acknowledgement. So first do deletions, then467 * additions, then modifications. Also, both the official and the local468 * list should be in ascending numerical order for the group ID#s and the469 * buddy ID#s, which makes things more efficient. I think.470 */471 472 /* Additions */473 if (!sess->ssi.pending) {474 for (cur1=sess->ssi.local; cur1; cur1=cur1->next) {475 if (!aim_ssi_itemlist_find(sess->ssi.official, cur1->gid, cur1->bid)) {476 new = (struct aim_ssi_tmp *)malloc(sizeof(struct aim_ssi_tmp));477 new->action = AIM_CB_SSI_ADD;478 new->ack = 0xffff;479 new->name = NULL;480 new->item = cur1;481 new->next = NULL;482 if (sess->ssi.pending) {483 for (cur=sess->ssi.pending; cur->next; cur=cur->next);484 cur->next = new;485 } else486 sess->ssi.pending = new;487 }488 }489 }490 491 /* Deletions */492 if (!sess->ssi.pending) {493 for (cur1=sess->ssi.official; cur1; cur1=cur1->next) {494 if (!aim_ssi_itemlist_find(sess->ssi.local, cur1->gid, cur1->bid)) {495 new = (struct aim_ssi_tmp *)malloc(sizeof(struct aim_ssi_tmp));496 new->action = AIM_CB_SSI_DEL;497 new->ack = 0xffff;498 new->name = NULL;499 new->item = cur1;500 new->next = NULL;501 if (sess->ssi.pending) {502 for (cur=sess->ssi.pending; cur->next; cur=cur->next);503 cur->next = new;504 } else505 sess->ssi.pending = new;506 }507 }508 }509 510 /* Modifications */511 if (!sess->ssi.pending) {512 for (cur1=sess->ssi.local; cur1; cur1=cur1->next) {513 cur2 = aim_ssi_itemlist_find(sess->ssi.official, cur1->gid, cur1->bid);514 if (cur2 && (aim_ssi_itemlist_cmp(cur1, cur2))) {515 new = (struct aim_ssi_tmp *)malloc(sizeof(struct aim_ssi_tmp));516 new->action = AIM_CB_SSI_MOD;517 new->ack = 0xffff;518 new->name = NULL;519 new->item = cur1;520 new->next = NULL;521 if (sess->ssi.pending) {522 for (cur=sess->ssi.pending; cur->next; cur=cur->next);523 cur->next = new;524 } else525 sess->ssi.pending = new;526 }527 }528 }529 530 /* We're out of stuff to do, so tell the AIM servers we're done and exit */531 if (!sess->ssi.pending) {532 aim_ssi_modend(sess);533 return 0;534 }535 536 /* Make sure we don't send anything else between now537 * and when we receive the ack for the following operation */538 sess->ssi.waiting_for_ack = 1;539 540 /* Now go mail off our data and wait 4 to 6 weeks */541 aim_ssi_addmoddel(sess);542 543 return 0;450 struct aim_ssi_item *cur1, *cur2; 451 struct aim_ssi_tmp *cur, *new; 452 453 if (!sess) 454 return -EINVAL; 455 456 /* If we're waiting for an ack, we shouldn't do anything else */ 457 if (sess->ssi.waiting_for_ack) 458 return 0; 459 460 /* 461 * Compare the 2 lists and create an aim_ssi_tmp for each difference. 462 * We should only send either additions, modifications, or deletions 463 * before waiting for an acknowledgement. So first do deletions, then 464 * additions, then modifications. Also, both the official and the local 465 * list should be in ascending numerical order for the group ID#s and the 466 * buddy ID#s, which makes things more efficient. I think. 467 */ 468 469 /* Additions */ 470 if (!sess->ssi.pending) { 471 for (cur1=sess->ssi.local; cur1; cur1=cur1->next) { 472 if (!aim_ssi_itemlist_find(sess->ssi.official, cur1->gid, cur1->bid)) { 473 new = (struct aim_ssi_tmp *)malloc(sizeof(struct aim_ssi_tmp)); 474 new->action = AIM_CB_SSI_ADD; 475 new->ack = 0xffff; 476 new->name = NULL; 477 new->item = cur1; 478 new->next = NULL; 479 if (sess->ssi.pending) { 480 for (cur=sess->ssi.pending; cur->next; cur=cur->next); 481 cur->next = new; 482 } else 483 sess->ssi.pending = new; 484 } 485 } 486 } 487 488 /* Deletions */ 489 if (!sess->ssi.pending) { 490 for (cur1=sess->ssi.official; cur1; cur1=cur1->next) { 491 if (!aim_ssi_itemlist_find(sess->ssi.local, cur1->gid, cur1->bid)) { 492 new = (struct aim_ssi_tmp *)malloc(sizeof(struct aim_ssi_tmp)); 493 new->action = AIM_CB_SSI_DEL; 494 new->ack = 0xffff; 495 new->name = NULL; 496 new->item = cur1; 497 new->next = NULL; 498 if (sess->ssi.pending) { 499 for (cur=sess->ssi.pending; cur->next; cur=cur->next); 500 cur->next = new; 501 } else 502 sess->ssi.pending = new; 503 } 504 } 505 } 506 507 /* Modifications */ 508 if (!sess->ssi.pending) { 509 for (cur1=sess->ssi.local; cur1; cur1=cur1->next) { 510 cur2 = aim_ssi_itemlist_find(sess->ssi.official, cur1->gid, cur1->bid); 511 if (cur2 && (aim_ssi_itemlist_cmp(cur1, cur2))) { 512 new = (struct aim_ssi_tmp *)malloc(sizeof(struct aim_ssi_tmp)); 513 new->action = AIM_CB_SSI_MOD; 514 new->ack = 0xffff; 515 new->name = NULL; 516 new->item = cur1; 517 new->next = NULL; 518 if (sess->ssi.pending) { 519 for (cur=sess->ssi.pending; cur->next; cur=cur->next); 520 cur->next = new; 521 } else 522 sess->ssi.pending = new; 523 } 524 } 525 } 526 527 /* We're out of stuff to do, so tell the AIM servers we're done and exit */ 528 if (!sess->ssi.pending) { 529 aim_ssi_modend(sess); 530 return 0; 531 } 532 533 /* Make sure we don't send anything else between now 534 * and when we receive the ack for the following operation */ 535 sess->ssi.waiting_for_ack = 1; 536 537 /* Now go mail off our data and wait 4 to 6 weeks */ 538 aim_ssi_addmoddel(sess); 539 540 return 0; 544 541 } 545 542 … … 554 551 static int aim_ssi_freelist(aim_session_t *sess) 555 552 { 556 struct aim_ssi_item *cur, *del;557 struct aim_ssi_tmp *curtmp, *deltmp;558 559 cur = sess->ssi.official;560 while (cur) {561 del = cur;562 cur = cur->next;563 free(del->name);564 aim_freetlvchain(&del->data);565 free(del);566 }567 568 cur = sess->ssi.local;569 while (cur) {570 del = cur;571 cur = cur->next;572 free(del->name);573 aim_freetlvchain(&del->data);574 free(del);575 }576 577 curtmp = sess->ssi.pending;578 while (curtmp) {579 deltmp = curtmp;580 curtmp = curtmp->next;581 free(deltmp);582 }583 584 sess->ssi.numitems = 0;585 sess->ssi.official = NULL;586 sess->ssi.local = NULL;587 sess->ssi.pending = NULL;588 sess->ssi.timestamp = (time_t)0;589 590 return 0;553 struct aim_ssi_item *cur, *del; 554 struct aim_ssi_tmp *curtmp, *deltmp; 555 556 cur = sess->ssi.official; 557 while (cur) { 558 del = cur; 559 cur = cur->next; 560 free(del->name); 561 aim_freetlvchain(&del->data); 562 free(del); 563 } 564 565 cur = sess->ssi.local; 566 while (cur) { 567 del = cur; 568 cur = cur->next; 569 free(del->name); 570 aim_freetlvchain(&del->data); 571 free(del); 572 } 573 574 curtmp = sess->ssi.pending; 575 while (curtmp) { 576 deltmp = curtmp; 577 curtmp = curtmp->next; 578 free(deltmp); 579 } 580 581 sess->ssi.numitems = 0; 582 sess->ssi.official = NULL; 583 sess->ssi.local = NULL; 584 sess->ssi.pending = NULL; 585 sess->ssi.timestamp = (time_t)0; 586 587 return 0; 591 588 } 592 589 … … 599 596 faim_export int aim_ssi_deletelist(aim_session_t *sess) 600 597 { 601 struct aim_ssi_item *cur, *del; 602 603 if (!sess) 604 return -EINVAL; 605 606 /* Free the local list */ 607 cur = sess->ssi.local; 608 while (cur) { 609 del = cur; 610 cur = cur->next; 611 free(del->name); 612 aim_freetlvchain(&del->data); 613 free(del); 614 } 615 sess->ssi.local = NULL; 616 617 /* Sync our local list with the server list */ 618 aim_ssi_sync(sess); 619 620 return 0; 598 struct aim_ssi_item *cur, *del; 599 600 if (!sess) return (-EINVAL); 601 602 /* Free the local list */ 603 cur = sess->ssi.local; 604 while (cur) { 605 del = cur; 606 cur = cur->next; 607 free(del->name); 608 aim_freetlvchain(&del->data); 609 free(del); 610 } 611 sess->ssi.local = NULL; 612 613 /* Sync our local list with the server list */ 614 aim_ssi_sync(sess); 615 616 return 0; 621 617 } 622 618 … … 632 628 faim_export int aim_ssi_cleanlist(aim_session_t *sess) 633 629 { 634 struct aim_ssi_item *cur, *next; 635 636 if (!sess) 637 return -EINVAL; 638 639 /* Delete any buddies, permits, or denies with empty names. */ 640 /* If there are any buddies directly in the master group, add them to a real group. */ 641 /* DESTROY any buddies that are directly in the master group. */ 642 /* Do the same for buddies that are in a non-existant group. */ 643 /* This will kind of mess up if you hit the item limit, but this function isn't too critical */ 644 cur = sess->ssi.local; 645 while (cur) { 646 next = cur->next; 647 if (!cur->name) { 648 if (cur->type == AIM_SSI_TYPE_BUDDY) 649 aim_ssi_delbuddy(sess, NULL, NULL); 650 else if (cur->type == AIM_SSI_TYPE_PERMIT) 651 aim_ssi_delpermit(sess, NULL); 652 else if (cur->type == AIM_SSI_TYPE_DENY) 653 aim_ssi_deldeny(sess, NULL); 654 } else if ((cur->type == AIM_SSI_TYPE_BUDDY) && ((cur->gid == 0x0000) || (!aim_ssi_itemlist_find(sess->ssi.local, cur->gid, 0x0000)))) { 655 aim_ssi_addbuddy(sess, cur->name, "orphans", NULL, NULL, NULL, 0); 656 aim_ssi_delbuddy(sess, cur->name, NULL); 657 } 658 cur = next; 659 } 660 661 /* Check if there are empty groups and delete them */ 662 cur = sess->ssi.local; 663 while (cur) { 664 next = cur->next; 665 if (cur->type == AIM_SSI_TYPE_GROUP) { 666 aim_tlv_t *tlv = aim_gettlv(cur->data, 0x00c8, 1); 667 if (!tlv || !tlv->length) 668 aim_ssi_itemlist_del(&sess->ssi.local, cur); 669 } 670 cur = next; 671 } 672 673 /* Check if the master group is empty */ 674 if ((cur = aim_ssi_itemlist_find(sess->ssi.local, 0x0000, 0x0000)) && (!cur->data)) 675 aim_ssi_itemlist_del(&sess->ssi.local, cur); 676 677 return 0; 630 struct aim_ssi_item *cur, *next; 631 632 if (!sess) return -EINVAL; 633 634 /* Delete any buddies, permits, or denies with empty names. */ 635 /* If there are any buddies directly in the master group, add them to a real group. */ 636 /* DESTROY any buddies that are directly in the master group. */ 637 /* Do the same for buddies that are in a non-existant group. */ 638 /* This will kind of mess up if you hit the item limit, but this function isn't too critical */ 639 cur = sess->ssi.local; 640 while (cur) { 641 next = cur->next; 642 if (!cur->name) { 643 if (cur->type == AIM_SSI_TYPE_BUDDY) 644 aim_ssi_delbuddy(sess, NULL, NULL); 645 else if (cur->type == AIM_SSI_TYPE_PERMIT) 646 aim_ssi_delpermit(sess, NULL); 647 else if (cur->type == AIM_SSI_TYPE_DENY) 648 aim_ssi_deldeny(sess, NULL); 649 } else if ((cur->type == AIM_SSI_TYPE_BUDDY) && ((cur->gid == 0x0000) || (!aim_ssi_itemlist_find(sess->ssi.local, cur->gid, 0x0000)))) { 650 aim_ssi_addbuddy(sess, cur->name, "orphans", NULL, NULL, NULL, 0); 651 aim_ssi_delbuddy(sess, cur->name, NULL); 652 } 653 cur = next; 654 } 655 656 /* Check if there are empty groups and delete them */ 657 cur = sess->ssi.local; 658 while (cur) { 659 next = cur->next; 660 if (cur->type == AIM_SSI_TYPE_GROUP) { 661 aim_tlv_t *tlv = aim_gettlv(cur->data, 0x00c8, 1); 662 if (!tlv || !tlv->length) 663 aim_ssi_itemlist_del(&sess->ssi.local, cur); 664 } 665 cur = next; 666 } 667 668 /* Check if the master group is empty */ 669 if ((cur = aim_ssi_itemlist_find(sess->ssi.local, 0x0000, 0x0000)) && (!cur->data)) 670 aim_ssi_itemlist_del(&sess->ssi.local, cur); 671 672 return 0; 678 673 } 679 674 … … 691 686 faim_export int aim_ssi_addbuddy(aim_session_t *sess, const char *name, const char *group, const char *alias, const char *comment, const char *smsnum, int needauth) 692 687 { 693 struct aim_ssi_item *parent; 694 aim_tlvlist_t *data = NULL; 695 696 if (!sess || !name || !group) 697 return -EINVAL; 698 699 /* Find the parent */ 700 if (!(parent = aim_ssi_itemlist_finditem(sess->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP))) { 701 /* Find the parent's parent (the master group) */ 702 if (!(parent = aim_ssi_itemlist_find(sess->ssi.local, 0x0000, 0x0000))) 703 if (!(parent = aim_ssi_itemlist_add(&sess->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL))) 704 return -ENOMEM; 705 /* Add the parent */ 706 if (!(parent = aim_ssi_itemlist_add(&sess->ssi.local, group, 0xFFFF, 0x0000, AIM_SSI_TYPE_GROUP, NULL))) 707 return -ENOMEM; 708 709 /* Modify the parent's parent (the master group) */ 710 aim_ssi_itemlist_rebuildgroup(sess->ssi.local, NULL); 711 } 712 713 /* Create a TLV list for the new buddy */ 714 if (needauth) 715 aim_addtlvtochain_noval(&data, 0x0066); 716 if (alias) 717 aim_addtlvtochain_raw(&data, 0x0131, strlen(alias), alias); 718 if (smsnum) 719 aim_addtlvtochain_raw(&data, 0x013a, strlen(smsnum), smsnum); 720 if (comment) 721 aim_addtlvtochain_raw(&data, 0x013c, strlen(comment), comment); 722 723 /* Add that bad boy */ 724 aim_ssi_itemlist_add(&sess->ssi.local, name, parent->gid, 0xFFFF, AIM_SSI_TYPE_BUDDY, data); 725 aim_freetlvchain(&data); 726 727 /* Modify the parent group */ 728 aim_ssi_itemlist_rebuildgroup(sess->ssi.local, group); 729 730 /* Sync our local list with the server list */ 731 aim_ssi_sync(sess); 732 733 return 0; 688 struct aim_ssi_item *parent; 689 aim_tlvlist_t *data = NULL; 690 691 if (!sess || !name || !group) return (-EINVAL); 692 693 /* Find the parent */ 694 if (!(parent = aim_ssi_itemlist_finditem(sess->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP))) { 695 /* Find the parent's parent (the master group) */ 696 if (!(parent = aim_ssi_itemlist_find(sess->ssi.local, 0x0000, 0x0000))) { 697 if (!(parent = aim_ssi_itemlist_add(&sess->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL))) { 698 return -ENOMEM; 699 } 700 } 701 /* Add the parent */ 702 if (!(parent = aim_ssi_itemlist_add(&sess->ssi.local, group, 0xFFFF, 0x0000, AIM_SSI_TYPE_GROUP, NULL))) { 703 return -ENOMEM; 704 } 705 706 /* Modify the parent's parent (the master group) */ 707 aim_ssi_itemlist_rebuildgroup(sess->ssi.local, NULL); 708 } 709 710 /* Create a TLV list for the new buddy */ 711 if (needauth) aim_addtlvtochain_noval(&data, 0x0066); 712 if (alias) aim_addtlvtochain_raw(&data, 0x0131, strlen(alias), alias); 713 if (smsnum) aim_addtlvtochain_raw(&data, 0x013a, strlen(smsnum), smsnum); 714 if (comment) aim_addtlvtochain_raw(&data, 0x013c, strlen(comment), comment); 715 716 /* Add that bad boy */ 717 aim_ssi_itemlist_add(&sess->ssi.local, name, parent->gid, 0xFFFF, AIM_SSI_TYPE_BUDDY, data); 718 aim_freetlvchain(&data); 719 720 /* Modify the parent group */ 721 aim_ssi_itemlist_rebuildgroup(sess->ssi.local, group); 722 723 /* Sync our local list with the server list */ 724 aim_ssi_sync(sess); 725 726 return(0); 734 727 } 735 728 … … 744 737 { 745 738 746 if (!sess || !name) 747 return -EINVAL; 748 749 /* Add that bad boy */ 750 aim_ssi_itemlist_add(&sess->ssi.local, name, 0x0000, 0xFFFF, AIM_SSI_TYPE_PERMIT, NULL); 751 752 /* Sync our local list with the server list */ 753 aim_ssi_sync(sess); 754 755 return 0; 739 if (!sess || !name) return -EINVAL; 740 741 /* Add that bad boy */ 742 aim_ssi_itemlist_add(&sess->ssi.local, name, 0x0000, 0xFFFF, AIM_SSI_TYPE_PERMIT, NULL); 743 744 /* Sync our local list with the server list */ 745 aim_ssi_sync(sess); 746 747 return(0); 756 748 } 757 749 … … 766 758 { 767 759 768 if (!sess || !name) 769 return -EINVAL; 770 771 /* Add that bad boy */ 772 aim_ssi_itemlist_add(&sess->ssi.local, name, 0x0000, 0xFFFF, AIM_SSI_TYPE_DENY, NULL); 773 774 /* Sync our local list with the server list */ 775 aim_ssi_sync(sess); 776 777 return 0; 760 if (!sess || !name) return (-EINVAL); 761 762 /* Add that bad boy */ 763 aim_ssi_itemlist_add(&sess->ssi.local, name, 0x0000, 0xFFFF, AIM_SSI_TYPE_DENY, NULL); 764 765 /* Sync our local list with the server list */ 766 aim_ssi_sync(sess); 767 768 return(0); 778 769 } 779 770 … … 788 779 faim_export int aim_ssi_delbuddy(aim_session_t *sess, const char *name, const char *group) 789 780 { 790 struct aim_ssi_item *del; 791 792 if (!sess) 793 return -EINVAL; 794 795 /* Find the buddy */ 796 if (!(del = aim_ssi_itemlist_finditem(sess->ssi.local, group, name, AIM_SSI_TYPE_BUDDY))) 797 return -EINVAL; 798 799 /* Remove the item from the list */ 800 aim_ssi_itemlist_del(&sess->ssi.local, del); 801 802 /* Modify the parent group */ 803 aim_ssi_itemlist_rebuildgroup(sess->ssi.local, group); 804 805 /* Check if we should delete the parent group */ 806 if ((del = aim_ssi_itemlist_finditem(sess->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP)) && (!del->data)) { 807 aim_ssi_itemlist_del(&sess->ssi.local, del); 808 809 /* Modify the parent group */ 810 aim_ssi_itemlist_rebuildgroup(sess->ssi.local, NULL); 811 812 /* Check if we should delete the parent's parent (the master group) */ 813 if ((del = aim_ssi_itemlist_find(sess->ssi.local, 0x0000, 0x0000)) && (!del->data)) { 814 aim_ssi_itemlist_del(&sess->ssi.local, del); 815 } 816 } 817 818 /* Sync our local list with the server list */ 819 aim_ssi_sync(sess); 820 821 return 0; 781 struct aim_ssi_item *del; 782 783 owl_function_debugmsg("aim_ssi_delbuddy: here"); 784 if (!sess) return -EINVAL; 785 786 /* Find the buddy */ 787 owl_function_debugmsg("aim_ssi_delbuddy: here too"); 788 del=aim_ssi_itemlist_finditem(sess->ssi.local, group, name, AIM_SSI_TYPE_BUDDY); 789 if (!del) return(-EINVAL); 790 791 /* Remove the item from the list */ 792 owl_function_debugmsg("aim_ssi_delbuddy: removing buddy %s group %s", name, group); 793 aim_ssi_itemlist_del(&sess->ssi.local, del); 794 795 /* Modify the parent group */ 796 aim_ssi_itemlist_rebuildgroup(sess->ssi.local, group); 797 798 /* Check if we should delete the parent group */ 799 if ((del = aim_ssi_itemlist_finditem(sess->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP)) && (!del->data)) { 800 owl_function_debugmsg("aim_ssi_delbuddy: deleting parent group"); 801 aim_ssi_itemlist_del(&sess->ssi.local, del); 802 803 /* Modify the parent group */ 804 aim_ssi_itemlist_rebuildgroup(sess->ssi.local, NULL); 805 806 /* Check if we should delete the parent's parent (the master group) */ 807 if ((del = aim_ssi_itemlist_find(sess->ssi.local, 0x0000, 0x0000)) && (!del->data)) { 808 aim_ssi_itemlist_del(&sess->ssi.local, del); 809 } 810 } 811 812 /* Sync our local list with the server list */ 813 owl_function_debugmsg("aim_ssi_delbuddy: syncing"); 814 aim_ssi_sync(sess); 815 816 return(0); 822 817 } 823 818 … … 831 826 faim_export int aim_ssi_delpermit(aim_session_t *sess, const char *name) 832 827 { 833 struct aim_ssi_item *del;834 835 if (!sess)836 return -EINVAL;837 838 /* Find the item */839 if (!(del = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, name, AIM_SSI_TYPE_PERMIT)))840 return -EINVAL;841 842 /* Remove the item from the list */843 aim_ssi_itemlist_del(&sess->ssi.local, del);844 845 /* Sync our local list with the server list */846 aim_ssi_sync(sess);847 848 return 0;828 struct aim_ssi_item *del; 829 830 if (!sess) 831 return -EINVAL; 832 833 /* Find the item */ 834 if (!(del = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, name, AIM_SSI_TYPE_PERMIT))) 835 return -EINVAL; 836 837 /* Remove the item from the list */ 838 aim_ssi_itemlist_del(&sess->ssi.local, del); 839 840 /* Sync our local list with the server list */ 841 aim_ssi_sync(sess); 842 843 return 0; 849 844 } 850 845 … … 858 853 faim_export int aim_ssi_deldeny(aim_session_t *sess, const char *name) 859 854 { 860 struct aim_ssi_item *del;861 862 if (!sess)863 return -EINVAL;864 865 /* Find the item */866 if (!(del = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, name, AIM_SSI_TYPE_DENY)))867 return -EINVAL;868 869 /* Remove the item from the list */870 aim_ssi_itemlist_del(&sess->ssi.local, del);871 872 /* Sync our local list with the server list */873 aim_ssi_sync(sess);874 875 return 0;855 struct aim_ssi_item *del; 856 857 if (!sess) 858 return -EINVAL; 859 860 /* Find the item */ 861 if (!(del = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, name, AIM_SSI_TYPE_DENY))) 862 return -EINVAL; 863 864 /* Remove the item from the list */ 865 aim_ssi_itemlist_del(&sess->ssi.local, del); 866 867 /* Sync our local list with the server list */ 868 aim_ssi_sync(sess); 869 870 return 0; 876 871 } 877 872 … … 888 883 faim_export int aim_ssi_movebuddy(aim_session_t *sess, const char *oldgn, const char *newgn, const char *sn) 889 884 { 890 aim_ssi_addbuddy(sess, sn, newgn, aim_ssi_getalias(sess->ssi.local, oldgn, sn), NULL, NULL, aim_ssi_waitingforauth(sess->ssi.local, oldgn, sn));891 aim_ssi_delbuddy(sess, sn, oldgn);892 return 0;885 aim_ssi_addbuddy(sess, sn, newgn, aim_ssi_getalias(sess->ssi.local, oldgn, sn), NULL, NULL, aim_ssi_waitingforauth(sess->ssi.local, oldgn, sn)); 886 aim_ssi_delbuddy(sess, sn, oldgn); 887 return 0; 893 888 } 894 889 … … 904 899 faim_export int aim_ssi_aliasbuddy(aim_session_t *sess, const char *gn, const char *sn, const char *alias) 905 900 { 906 struct aim_ssi_item *tmp;907 aim_tlvlist_t *data = NULL;908 909 if (!sess || !gn || !sn)910 return -EINVAL;911 912 if (!(tmp = aim_ssi_itemlist_finditem(sess->ssi.local, gn, sn, AIM_SSI_TYPE_BUDDY)))913 return -EINVAL;914 915 if (alias && !strlen(alias))916 alias = NULL;917 918 /* Need to add the x0131 TLV to the TLV chain */919 if (alias)920 aim_addtlvtochain_raw(&data, 0x0131, strlen(alias), alias);921 922 aim_freetlvchain(&tmp->data);923 tmp->data = data;924 925 /* Sync our local list with the server list */926 aim_ssi_sync(sess);927 928 return 0;901 struct aim_ssi_item *tmp; 902 aim_tlvlist_t *data = NULL; 903 904 if (!sess || !gn || !sn) 905 return -EINVAL; 906 907 if (!(tmp = aim_ssi_itemlist_finditem(sess->ssi.local, gn, sn, AIM_SSI_TYPE_BUDDY))) 908 return -EINVAL; 909 910 if (alias && !strlen(alias)) 911 alias = NULL; 912 913 /* Need to add the x0131 TLV to the TLV chain */ 914 if (alias) 915 aim_addtlvtochain_raw(&data, 0x0131, strlen(alias), alias); 916 917 aim_freetlvchain(&tmp->data); 918 tmp->data = data; 919 920 /* Sync our local list with the server list */ 921 aim_ssi_sync(sess); 922 923 return 0; 929 924 } 930 925 … … 939 934 faim_export int aim_ssi_rename_group(aim_session_t *sess, const char *oldgn, const char *newgn) 940 935 { 941 struct aim_ssi_item *group;942 943 if (!sess || !oldgn || !newgn)944 return -EINVAL;945 946 if (!(group = aim_ssi_itemlist_finditem(sess->ssi.local, oldgn, NULL, AIM_SSI_TYPE_GROUP)))947 return -EINVAL;948 949 free(group->name);950 group->name = (char *)malloc((strlen(newgn)+1)*sizeof(char));951 strcpy(group->name, newgn);952 953 /* Sync our local list with the server list */954 aim_ssi_sync(sess);955 956 return 0;936 struct aim_ssi_item *group; 937 938 if (!sess || !oldgn || !newgn) 939 return -EINVAL; 940 941 if (!(group = aim_ssi_itemlist_finditem(sess->ssi.local, oldgn, NULL, AIM_SSI_TYPE_GROUP))) 942 return -EINVAL; 943 944 free(group->name); 945 group->name = (char *)malloc((strlen(newgn)+1)*sizeof(char)); 946 strcpy(group->name, newgn); 947 948 /* Sync our local list with the server list */ 949 aim_ssi_sync(sess); 950 951 return 0; 957 952 } 958 953 … … 973 968 faim_export int aim_ssi_setpermdeny(aim_session_t *sess, fu8_t permdeny, fu32_t vismask) 974 969 { 975 struct aim_ssi_item *tmp;976 aim_tlvlist_t *data = NULL;977 978 if (!sess)979 return -EINVAL;980 981 /* Need to add the x00ca TLV to the TLV chain */982 aim_addtlvtochain8(&data, 0x00ca, permdeny);983 984 /* Need to add the x00cb TLV to the TLV chain */985 aim_addtlvtochain32(&data, 0x00cb, vismask);986 987 if ((tmp = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, NULL, AIM_SSI_TYPE_PDINFO))) {988 aim_freetlvchain(&tmp->data);989 tmp->data = data;990 } else {991 tmp = aim_ssi_itemlist_add(&sess->ssi.local, NULL, 0x0000, 0xFFFF, AIM_SSI_TYPE_PDINFO, data);992 aim_freetlvchain(&data);993 }994 995 /* Sync our local list with the server list */996 aim_ssi_sync(sess);997 998 return 0;970 struct aim_ssi_item *tmp; 971 aim_tlvlist_t *data = NULL; 972 973 if (!sess) 974 return -EINVAL; 975 976 /* Need to add the x00ca TLV to the TLV chain */ 977 aim_addtlvtochain8(&data, 0x00ca, permdeny); 978 979 /* Need to add the x00cb TLV to the TLV chain */ 980 aim_addtlvtochain32(&data, 0x00cb, vismask); 981 982 if ((tmp = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, NULL, AIM_SSI_TYPE_PDINFO))) { 983 aim_freetlvchain(&tmp->data); 984 tmp->data = data; 985 } else { 986 tmp = aim_ssi_itemlist_add(&sess->ssi.local, NULL, 0x0000, 0xFFFF, AIM_SSI_TYPE_PDINFO, data); 987 aim_freetlvchain(&data); 988 } 989 990 /* Sync our local list with the server list */ 991 aim_ssi_sync(sess); 992 993 return 0; 999 994 } 1000 995 … … 1009 1004 faim_export int aim_ssi_seticon(aim_session_t *sess, fu8_t *iconsum, fu16_t iconsumlen) 1010 1005 { 1011 struct aim_ssi_item *tmp;1012 aim_tlvlist_t *data = NULL;1013 fu8_t *csumdata;1014 1015 if (!sess || !iconsum || !iconsumlen)1016 return -EINVAL;1017 1018 if (!(csumdata = (fu8_t *)malloc((iconsumlen+2)*sizeof(fu8_t))))1019 return -ENOMEM;1020 csumdata[0] = 0x00;1021 csumdata[1] = 0x10;1022 memcpy(&csumdata[2], iconsum, iconsumlen);1023 1024 /* Need to add the x00d5 TLV to the TLV chain */1025 aim_addtlvtochain_raw(&data, 0x00d5, (iconsumlen+2) * sizeof(fu8_t), csumdata);1026 1027 /* This TLV is added to cache the icon. */1028 aim_addtlvtochain_noval(&data, 0x0131);1029 1030 if ((tmp = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, "1", AIM_SSI_TYPE_ICONINFO))) {1031 /* If the new tlvchain and oldtlvchain are the same, then do nothing */1032 if (!aim_tlvlist_cmp(tmp->data, data)) {1033 /* The new tlvlist is the identical to the old one */1034 aim_freetlvchain(&data);1035 free(csumdata);1036 return 0;1037 }1038 aim_freetlvchain(&tmp->data);1039 tmp->data = data;1040 } else {1041 tmp = aim_ssi_itemlist_add(&sess->ssi.local, "1", 0x0000, 0x51F4, AIM_SSI_TYPE_ICONINFO, data);1042 aim_freetlvchain(&data);1043 }1044 1045 /* Sync our local list with the server list */1046 aim_ssi_sync(sess);1047 free(csumdata);1048 return 0;1006 struct aim_ssi_item *tmp; 1007 aim_tlvlist_t *data = NULL; 1008 fu8_t *csumdata; 1009 1010 if (!sess || !iconsum || !iconsumlen) 1011 return -EINVAL; 1012 1013 if (!(csumdata = (fu8_t *)malloc((iconsumlen+2)*sizeof(fu8_t)))) 1014 return -ENOMEM; 1015 csumdata[0] = 0x00; 1016 csumdata[1] = 0x10; 1017 memcpy(&csumdata[2], iconsum, iconsumlen); 1018 1019 /* Need to add the x00d5 TLV to the TLV chain */ 1020 aim_addtlvtochain_raw(&data, 0x00d5, (iconsumlen+2) * sizeof(fu8_t), csumdata); 1021 1022 /* This TLV is added to cache the icon. */ 1023 aim_addtlvtochain_noval(&data, 0x0131); 1024 1025 if ((tmp = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, "1", AIM_SSI_TYPE_ICONINFO))) { 1026 /* If the new tlvchain and oldtlvchain are the same, then do nothing */ 1027 if (!aim_tlvlist_cmp(tmp->data, data)) { 1028 /* The new tlvlist is the identical to the old one */ 1029 aim_freetlvchain(&data); 1030 free(csumdata); 1031 return 0; 1032 } 1033 aim_freetlvchain(&tmp->data); 1034 tmp->data = data; 1035 } else { 1036 tmp = aim_ssi_itemlist_add(&sess->ssi.local, "1", 0x0000, 0x51F4, AIM_SSI_TYPE_ICONINFO, data); 1037 aim_freetlvchain(&data); 1038 } 1039 1040 /* Sync our local list with the server list */ 1041 aim_ssi_sync(sess); 1042 free(csumdata); 1043 return 0; 1049 1044 } 1050 1045 … … 1058 1053 */ 1059 1054 faim_export int aim_ssi_setpresence(aim_session_t *sess, fu32_t presence) { 1060 struct aim_ssi_item *tmp;1061 aim_tlvlist_t *data = NULL;1062 1063 if (!sess)1064 return -EINVAL;1065 1066 /* Need to add the x00c9 TLV to the TLV chain */1067 aim_addtlvtochain32(&data, 0x00c9, presence);1068 1069 if ((tmp = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS))) {1070 aim_freetlvchain(&tmp->data);1071 tmp->data = data;1072 } else {1073 tmp = aim_ssi_itemlist_add(&sess->ssi.local, NULL, 0x0000, 0xFFFF, AIM_SSI_TYPE_PRESENCEPREFS, data);1074 aim_freetlvchain(&data);1075 }1076 1077 /* Sync our local list with the server list */1078 aim_ssi_sync(sess);1079 1080 return 0;1055 struct aim_ssi_item *tmp; 1056 aim_tlvlist_t *data = NULL; 1057 1058 if (!sess) 1059 return -EINVAL; 1060 1061 /* Need to add the x00c9 TLV to the TLV chain */ 1062 aim_addtlvtochain32(&data, 0x00c9, presence); 1063 1064 if ((tmp = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS))) { 1065 aim_freetlvchain(&tmp->data); 1066 tmp->data = data; 1067 } else { 1068 tmp = aim_ssi_itemlist_add(&sess->ssi.local, NULL, 0x0000, 0xFFFF, AIM_SSI_TYPE_PRESENCEPREFS, data); 1069 aim_freetlvchain(&data); 1070 } 1071 1072 /* Sync our local list with the server list */ 1073 aim_ssi_sync(sess); 1074 1075 return 0; 1081 1076 } 1082 1077 … … 1086 1081 faim_export int aim_ssi_reqrights(aim_session_t *sess) 1087 1082 { 1088 aim_conn_t *conn;1089 1090 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)))1091 return -EINVAL;1092 1093 return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_REQRIGHTS);1083 aim_conn_t *conn; 1084 1085 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI))) 1086 return -EINVAL; 1087 1088 return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_REQRIGHTS); 1094 1089 } 1095 1090 … … 1099 1094 static int parserights(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1100 1095 { 1101 int ret = 0, i;1102 aim_rxcallback_t userfunc;1103 aim_tlvlist_t *tlvlist;1104 aim_tlv_t *tlv;1105 aim_bstream_t bstream;1106 fu16_t *maxitems;1107 1108 /* This SNAC is made up of a bunch of TLVs */1109 tlvlist = aim_readtlvchain(bs);1110 1111 /* TLV 0x0004 contains the maximum number of each item */1112 if (!(tlv = aim_gettlv(tlvlist, 0x0004, 1))) {1113 aim_freetlvchain(&tlvlist);1114 return 0;1115 }1116 1117 aim_bstream_init(&bstream, tlv->value, tlv->length);1118 1119 if (!(maxitems = (fu16_t *)malloc((tlv->length/2)*sizeof(fu16_t)))) {1120 aim_freetlvchain(&tlvlist);1121 return 0;1122 }1123 1124 for (i=0; i<(tlv->length/2); i++)1125 maxitems[i] = aimbs_get16(&bstream);1126 1127 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))1128 ret = userfunc(sess, rx, tlv->length/2, maxitems);1129 1130 aim_freetlvchain(&tlvlist);1131 free(maxitems);1132 1133 return ret;1096 int ret = 0, i; 1097 aim_rxcallback_t userfunc; 1098 aim_tlvlist_t *tlvlist; 1099 aim_tlv_t *tlv; 1100 aim_bstream_t bstream; 1101 fu16_t *maxitems; 1102 1103 /* This SNAC is made up of a bunch of TLVs */ 1104 tlvlist = aim_readtlvchain(bs); 1105 1106 /* TLV 0x0004 contains the maximum number of each item */ 1107 if (!(tlv = aim_gettlv(tlvlist, 0x0004, 1))) { 1108 aim_freetlvchain(&tlvlist); 1109 return 0; 1110 } 1111 1112 aim_bstream_init(&bstream, tlv->value, tlv->length); 1113 1114 if (!(maxitems = (fu16_t *)malloc((tlv->length/2)*sizeof(fu16_t)))) { 1115 aim_freetlvchain(&tlvlist); 1116 return 0; 1117 } 1118 1119 for (i=0; i<(tlv->length/2); i++) 1120 maxitems[i] = aimbs_get16(&bstream); 1121 1122 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1123 ret = userfunc(sess, rx, tlv->length/2, maxitems); 1124 1125 aim_freetlvchain(&tlvlist); 1126 free(maxitems); 1127 1128 return ret; 1134 1129 } 1135 1130 … … 1141 1136 faim_export int aim_ssi_reqdata(aim_session_t *sess) 1142 1137 { 1143 aim_conn_t *conn;1144 1145 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)))1146 return -EINVAL;1147 1148 /* Free any current data, just in case */1149 aim_ssi_freelist(sess);1150 1151 return aim_genericreq_n_snacid(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_REQDATA);1138 aim_conn_t *conn; 1139 1140 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI))) 1141 return -EINVAL; 1142 1143 /* Free any current data, just in case */ 1144 aim_ssi_freelist(sess); 1145 1146 return aim_genericreq_n_snacid(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_REQDATA); 1152 1147 } 1153 1148 … … 1164 1159 faim_export int aim_ssi_reqifchanged(aim_session_t *sess, time_t timestamp, fu16_t numitems) 1165 1160 { 1166 aim_conn_t *conn;1167 aim_frame_t *fr;1168 aim_snacid_t snacid;1169 1170 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)))1171 return -EINVAL;1172 1173 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4+2)))1174 return -ENOMEM;1175 1176 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_REQIFCHANGED, 0x0000, NULL, 0);1177 1178 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_REQIFCHANGED, 0x0000, snacid);1179 aimbs_put32(&fr->data, timestamp);1180 aimbs_put16(&fr->data, numitems);1181 1182 aim_tx_enqueue(sess, fr);1183 1184 /* Free any current data, just in case */1185 aim_ssi_freelist(sess);1186 1187 return 0;1161 aim_conn_t *conn; 1162 aim_frame_t *fr; 1163 aim_snacid_t snacid; 1164 1165 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI))) 1166 return -EINVAL; 1167 1168 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4+2))) 1169 return -ENOMEM; 1170 1171 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_REQIFCHANGED, 0x0000, NULL, 0); 1172 1173 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_REQIFCHANGED, 0x0000, snacid); 1174 aimbs_put32(&fr->data, timestamp); 1175 aimbs_put16(&fr->data, numitems); 1176 1177 aim_tx_enqueue(sess, fr); 1178 1179 /* Free any current data, just in case */ 1180 aim_ssi_freelist(sess); 1181 1182 return 0; 1188 1183 } 1189 1184 … … 1193 1188 static int parsedata(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1194 1189 { 1195 int ret = 0;1196 aim_rxcallback_t userfunc;1197 fu8_t fmtver; /* guess */1198 fu16_t namelen, gid, bid, type;1199 char *name;1200 aim_tlvlist_t *data;1201 1202 fmtver = aimbs_get8(bs); /* Version of ssi data. Should be 0x00 */1203 sess->ssi.numitems += aimbs_get16(bs); /* # of items in this SSI SNAC */1204 1205 /* Read in the list */1206 while (aim_bstream_empty(bs) > 4) { /* last four bytes are timestamp */1207 if ((namelen = aimbs_get16(bs)))1208 name = aimbs_getstr(bs, namelen);1209 else1210 name = NULL;1211 gid = aimbs_get16(bs);1212 bid = aimbs_get16(bs);1213 type = aimbs_get16(bs);1214 data = aim_readtlvchain_len(bs, aimbs_get16(bs));1215 aim_ssi_itemlist_add(&sess->ssi.official, name, gid, bid, type, data);1216 free(name);1217 aim_freetlvchain(&data);1218 }1219 1220 /* Read in the timestamp */1221 sess->ssi.timestamp = aimbs_get32(bs);1222 1223 if (!(snac->flags & 0x0001)) {1224 /* Make a copy of the list */1225 struct aim_ssi_item *cur;1226 for (cur=sess->ssi.official; cur; cur=cur->next)1227 aim_ssi_itemlist_add(&sess->ssi.local, cur->name, cur->gid, cur->bid, cur->type, cur->data);1228 1229 sess->ssi.received_data = 1;1230 1231 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))1232 ret = userfunc(sess, rx, fmtver, sess->ssi.numitems, sess->ssi.official, sess->ssi.timestamp);1233 }1234 1235 return ret;1190 int ret = 0; 1191 aim_rxcallback_t userfunc; 1192 fu8_t fmtver; /* guess */ 1193 fu16_t namelen, gid, bid, type; 1194 char *name; 1195 aim_tlvlist_t *data; 1196 1197 fmtver = aimbs_get8(bs); /* Version of ssi data. Should be 0x00 */ 1198 sess->ssi.numitems += aimbs_get16(bs); /* # of items in this SSI SNAC */ 1199 1200 /* Read in the list */ 1201 while (aim_bstream_empty(bs) > 4) { /* last four bytes are timestamp */ 1202 if ((namelen = aimbs_get16(bs))) 1203 name = aimbs_getstr(bs, namelen); 1204 else 1205 name = NULL; 1206 gid = aimbs_get16(bs); 1207 bid = aimbs_get16(bs); 1208 type = aimbs_get16(bs); 1209 data = aim_readtlvchain_len(bs, aimbs_get16(bs)); 1210 aim_ssi_itemlist_add(&sess->ssi.official, name, gid, bid, type, data); 1211 free(name); 1212 aim_freetlvchain(&data); 1213 } 1214 1215 /* Read in the timestamp */ 1216 sess->ssi.timestamp = aimbs_get32(bs); 1217 1218 if (!(snac->flags & 0x0001)) { 1219 /* Make a copy of the list */ 1220 struct aim_ssi_item *cur; 1221 for (cur=sess->ssi.official; cur; cur=cur->next) 1222 aim_ssi_itemlist_add(&sess->ssi.local, cur->name, cur->gid, cur->bid, cur->type, cur->data); 1223 1224 sess->ssi.received_data = 1; 1225 1226 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1227 ret = userfunc(sess, rx, fmtver, sess->ssi.numitems, sess->ssi.official, sess->ssi.timestamp); 1228 } 1229 1230 return ret; 1236 1231 } 1237 1232 … … 1247 1242 faim_export int aim_ssi_enable(aim_session_t *sess) 1248 1243 { 1249 aim_conn_t *conn;1250 1251 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)))1252 return -EINVAL;1253 1254 return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, 0x0007);1244 aim_conn_t *conn; 1245 1246 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI))) 1247 return -EINVAL; 1248 1249 return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, 0x0007); 1255 1250 } 1256 1251 … … 1265 1260 faim_export int aim_ssi_addmoddel(aim_session_t *sess) 1266 1261 { 1267 aim_conn_t *conn; 1268 aim_frame_t *fr; 1269 aim_snacid_t snacid; 1270 int snaclen; 1271 struct aim_ssi_tmp *cur; 1272 1273 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sess->ssi.pending || !sess->ssi.pending->item) 1274 return -EINVAL; 1275 1276 /* Calculate total SNAC size */ 1277 snaclen = 10; /* For family, subtype, flags, and SNAC ID */ 1278 for (cur=sess->ssi.pending; cur; cur=cur->next) { 1279 snaclen += 10; /* For length, GID, BID, type, and length */ 1280 if (cur->item->name) 1281 snaclen += strlen(cur->item->name); 1282 if (cur->item->data) 1283 snaclen += aim_sizetlvchain(&cur->item->data); 1262 aim_conn_t *conn; 1263 aim_frame_t *fr; 1264 aim_snacid_t snacid; 1265 int snaclen; 1266 struct aim_ssi_tmp *cur; 1267 1268 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sess->ssi.pending || !sess->ssi.pending->item) 1269 return -EINVAL; 1270 1271 /* Calculate total SNAC size */ 1272 snaclen = 10; /* For family, subtype, flags, and SNAC ID */ 1273 for (cur=sess->ssi.pending; cur; cur=cur->next) { 1274 snaclen += 10; /* For length, GID, BID, type, and length */ 1275 if (cur->item->name) 1276 snaclen += strlen(cur->item->name); 1277 if (cur->item->data) 1278 snaclen += aim_sizetlvchain(&cur->item->data); 1279 } 1280 1281 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, snaclen))) 1282 return -ENOMEM; 1283 1284 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, sess->ssi.pending->action, 0x0000, NULL, 0); 1285 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, sess->ssi.pending->action, 0x0000, snacid); 1286 1287 for (cur=sess->ssi.pending; cur; cur=cur->next) { 1288 aimbs_put16(&fr->data, cur->item->name ? strlen(cur->item->name) : 0); 1289 if (cur->item->name) 1290 aimbs_putraw(&fr->data, cur->item->name, strlen(cur->item->name)); 1291 aimbs_put16(&fr->data, cur->item->gid); 1292 aimbs_put16(&fr->data, cur->item->bid); 1293 aimbs_put16(&fr->data, cur->item->type); 1294 aimbs_put16(&fr->data, cur->item->data ? aim_sizetlvchain(&cur->item->data) : 0); 1295 if (cur->item->data) 1296 aim_writetlvchain(&fr->data, &cur->item->data); 1297 } 1298 1299 aim_tx_enqueue(sess, fr); 1300 1301 return 0; 1302 } 1303 1304 /* 1305 * Subtype 0x0008 - Incoming SSI add. 1306 * 1307 * XXX - It would probably be good for the client to actually do something when it gets this. 1308 */ 1309 static int parseadd(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1310 { 1311 int ret = 0; 1312 aim_rxcallback_t userfunc; 1313 char *name; 1314 fu16_t len, gid, bid, type; 1315 aim_tlvlist_t *data; 1316 1317 while (aim_bstream_empty(bs)) { 1318 if ((len = aimbs_get16(bs))) 1319 name = aimbs_getstr(bs, len); 1320 else 1321 name = NULL; 1322 gid = aimbs_get16(bs); 1323 bid = aimbs_get16(bs); 1324 type = aimbs_get16(bs); 1325 if ((len = aimbs_get16(bs))) 1326 data = aim_readtlvchain_len(bs, len); 1327 else 1328 data = NULL; 1329 1330 aim_ssi_itemlist_add(&sess->ssi.local, name, gid, bid, type, data); 1331 aim_ssi_itemlist_add(&sess->ssi.official, name, gid, bid, type, data); 1332 free(name); 1333 aim_freetlvchain(&data); 1334 1335 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1336 ret = userfunc(sess, rx); 1337 1338 free(name); 1339 } 1340 1341 return ret; 1342 } 1343 1344 /* 1345 * Subtype 0x0009 - Incoming SSI mod. 1346 * 1347 * XXX - It would probably be good for the client to actually do something when it gets this. 1348 */ 1349 static int parsemod(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1350 { 1351 int ret = 0; 1352 aim_rxcallback_t userfunc; 1353 char *name; 1354 fu16_t len, gid, bid, type; 1355 aim_tlvlist_t *data; 1356 struct aim_ssi_item *item; 1357 1358 while (aim_bstream_empty(bs)) { 1359 if ((len = aimbs_get16(bs))) 1360 name = aimbs_getstr(bs, len); 1361 else 1362 name = NULL; 1363 gid = aimbs_get16(bs); 1364 bid = aimbs_get16(bs); 1365 type = aimbs_get16(bs); 1366 if ((len = aimbs_get16(bs))) 1367 data = aim_readtlvchain_len(bs, len); 1368 else 1369 data = NULL; 1370 1371 /* Replace the 2 local items with the given one */ 1372 if ((item = aim_ssi_itemlist_find(sess->ssi.local, gid, bid))) { 1373 item->type = type; 1374 free(item->name); 1375 if (name) { 1376 item->name = (char *)malloc((strlen(name)+1)*sizeof(char)); 1377 strcpy(item->name, name); 1378 } else 1379 item->name = NULL; 1380 aim_freetlvchain(&item->data); 1381 item->data = aim_tlvlist_copy(data); 1382 } 1383 1384 if ((item = aim_ssi_itemlist_find(sess->ssi.official, gid, bid))) { 1385 item->type = type; 1386 free(item->name); 1387 if (name) { 1388 item->name = (char *)malloc((strlen(name)+1)*sizeof(char)); 1389 strcpy(item->name, name); 1390 } else 1391 item->name = NULL; 1392 aim_freetlvchain(&item->data); 1393 item->data = aim_tlvlist_copy(data); 1394 } 1395 1396 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1397 ret = userfunc(sess, rx); 1398 1399 free(name); 1400 aim_freetlvchain(&data); 1401 } 1402 1403 return ret; 1404 } 1405 1406 /* 1407 * Subtype 0x000a - Incoming SSI del. 1408 * 1409 * XXX - It would probably be good for the client to actually do something when it gets this. 1410 */ 1411 static int parsedel(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1412 { 1413 int ret = 0; 1414 aim_rxcallback_t userfunc; 1415 fu16_t gid, bid; 1416 struct aim_ssi_item *del; 1417 1418 while (aim_bstream_empty(bs)) { 1419 aim_bstream_advance(bs, aimbs_get16(bs)); 1420 gid = aimbs_get16(bs); 1421 bid = aimbs_get16(bs); 1422 aimbs_get16(bs); 1423 aim_bstream_advance(bs, aimbs_get16(bs)); 1424 1425 if ((del = aim_ssi_itemlist_find(sess->ssi.local, gid, bid))) 1426 aim_ssi_itemlist_del(&sess->ssi.local, del); 1427 if ((del = aim_ssi_itemlist_find(sess->ssi.official, gid, bid))) 1428 aim_ssi_itemlist_del(&sess->ssi.official, del); 1429 1430 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1431 ret = userfunc(sess, rx); 1432 } 1433 1434 return ret; 1435 } 1436 1437 /* 1438 * Subtype 0x000e - SSI Add/Mod/Del Ack. 1439 * 1440 * Response to add, modify, or delete SNAC (sent with aim_ssi_addmoddel). 1441 * 1442 */ 1443 static int parseack(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1444 { 1445 int ret = 0; 1446 aim_rxcallback_t userfunc; 1447 struct aim_ssi_tmp *cur, *del; 1448 1449 /* Read in the success/failure flags from the ack SNAC */ 1450 cur = sess->ssi.pending; 1451 while (cur && (aim_bstream_empty(bs)>0)) { 1452 cur->ack = aimbs_get16(bs); 1453 cur = cur->next; 1454 } 1455 1456 /* 1457 * If outcome is 0, then add the item to the item list, or replace the other item, 1458 * or remove the old item. If outcome is non-zero, then remove the item from the 1459 * local list, or unmodify it, or add it. 1460 */ 1461 for (cur=sess->ssi.pending; (cur && (cur->ack != 0xffff)); cur=cur->next) { 1462 if (cur->item) { 1463 if (cur->ack) { 1464 /* Our action was unsuccessful, so change the local list back to how it was */ 1465 if (cur->action == AIM_CB_SSI_ADD) { 1466 /* Remove the item from the local list */ 1467 /* Make sure cur->item is still valid memory */ 1468 if (aim_ssi_itemlist_valid(sess->ssi.local, cur->item)) { 1469 if (cur->item->name) { 1470 cur->name = (char *)malloc((strlen(cur->item->name)+1)*sizeof(char)); 1471 strcpy(cur->name, cur->item->name); 1472 } 1473 aim_ssi_itemlist_del(&sess->ssi.local, cur->item); 1474 } 1475 cur->item = NULL; 1476 1477 } else if (cur->action == AIM_CB_SSI_MOD) { 1478 /* Replace the local item with the item from the official list */ 1479 if (aim_ssi_itemlist_valid(sess->ssi.local, cur->item)) { 1480 struct aim_ssi_item *cur1; 1481 if ((cur1 = aim_ssi_itemlist_find(sess->ssi.official, cur->item->gid, cur->item->bid))) { 1482 free(cur->item->name); 1483 if (cur1->name) { 1484 cur->item->name = (char *)malloc((strlen(cur1->name)+1)*sizeof(char)); 1485 strcpy(cur->item->name, cur1->name); 1486 } else 1487 cur->item->name = NULL; 1488 aim_freetlvchain(&cur->item->data); 1489 cur->item->data = aim_tlvlist_copy(cur1->data); 1490 } 1491 } else 1492 cur->item = NULL; 1493 1494 } else if (cur->action == AIM_CB_SSI_DEL) { 1495 /* Add the item back into the local list */ 1496 if (aim_ssi_itemlist_valid(sess->ssi.official, cur->item)) { 1497 aim_ssi_itemlist_add(&sess->ssi.local, cur->item->name, cur->item->gid, cur->item->bid, cur->item->type, cur->item->data); 1498 } else 1499 cur->item = NULL; 1284 1500 } 1285 1286 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, snaclen))) 1287 return -ENOMEM; 1288 1289 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, sess->ssi.pending->action, 0x0000, NULL, 0); 1290 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, sess->ssi.pending->action, 0x0000, snacid); 1291 1292 for (cur=sess->ssi.pending; cur; cur=cur->next) { 1293 aimbs_put16(&fr->data, cur->item->name ? strlen(cur->item->name) : 0); 1294 if (cur->item->name) 1295 aimbs_putraw(&fr->data, cur->item->name, strlen(cur->item->name)); 1296 aimbs_put16(&fr->data, cur->item->gid); 1297 aimbs_put16(&fr->data, cur->item->bid); 1298 aimbs_put16(&fr->data, cur->item->type); 1299 aimbs_put16(&fr->data, cur->item->data ? aim_sizetlvchain(&cur->item->data) : 0); 1300 if (cur->item->data) 1301 aim_writetlvchain(&fr->data, &cur->item->data); 1501 1502 } else { 1503 /* Do the exact opposite */ 1504 if (cur->action == AIM_CB_SSI_ADD) { 1505 /* Add the local item to the official list */ 1506 if (aim_ssi_itemlist_valid(sess->ssi.local, cur->item)) { 1507 aim_ssi_itemlist_add(&sess->ssi.official, cur->item->name, cur->item->gid, cur->item->bid, cur->item->type, cur->item->data); 1508 } else 1509 cur->item = NULL; 1510 1511 } else if (cur->action == AIM_CB_SSI_MOD) { 1512 /* Replace the official item with the item from the local list */ 1513 if (aim_ssi_itemlist_valid(sess->ssi.local, cur->item)) { 1514 struct aim_ssi_item *cur1; 1515 if ((cur1 = aim_ssi_itemlist_find(sess->ssi.official, cur->item->gid, cur->item->bid))) { 1516 free(cur1->name); 1517 if (cur->item->name) { 1518 cur1->name = (char *)malloc((strlen(cur->item->name)+1)*sizeof(char)); 1519 strcpy(cur1->name, cur->item->name); 1520 } else 1521 cur1->name = NULL; 1522 aim_freetlvchain(&cur1->data); 1523 cur1->data = aim_tlvlist_copy(cur->item->data); 1524 } 1525 } else 1526 cur->item = NULL; 1527 1528 } else if (cur->action == AIM_CB_SSI_DEL) { 1529 /* Remove the item from the official list */ 1530 if (aim_ssi_itemlist_valid(sess->ssi.official, cur->item)) 1531 aim_ssi_itemlist_del(&sess->ssi.official, cur->item); 1532 cur->item = NULL; 1302 1533 } 1303 1304 aim_tx_enqueue(sess, fr); 1305 1306 return 0; 1307 } 1308 1309 /* 1310 * Subtype 0x0008 - Incoming SSI add. 1311 * 1312 * XXX - It would probably be good for the client to actually do something when it gets this. 1313 */ 1314 static int parseadd(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1315 { 1316 int ret = 0; 1317 aim_rxcallback_t userfunc; 1318 char *name; 1319 fu16_t len, gid, bid, type; 1320 aim_tlvlist_t *data; 1321 1322 while (aim_bstream_empty(bs)) { 1323 if ((len = aimbs_get16(bs))) 1324 name = aimbs_getstr(bs, len); 1325 else 1326 name = NULL; 1327 gid = aimbs_get16(bs); 1328 bid = aimbs_get16(bs); 1329 type = aimbs_get16(bs); 1330 if ((len = aimbs_get16(bs))) 1331 data = aim_readtlvchain_len(bs, len); 1332 else 1333 data = NULL; 1334 1335 aim_ssi_itemlist_add(&sess->ssi.local, name, gid, bid, type, data); 1336 aim_ssi_itemlist_add(&sess->ssi.official, name, gid, bid, type, data); 1337 free(name); 1338 aim_freetlvchain(&data); 1339 1340 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1341 ret = userfunc(sess, rx); 1342 1343 free(name); 1344 } 1345 1346 return ret; 1347 } 1348 1349 /* 1350 * Subtype 0x0009 - Incoming SSI mod. 1351 * 1352 * XXX - It would probably be good for the client to actually do something when it gets this. 1353 */ 1354 static int parsemod(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1355 { 1356 int ret = 0; 1357 aim_rxcallback_t userfunc; 1358 char *name; 1359 fu16_t len, gid, bid, type; 1360 aim_tlvlist_t *data; 1361 struct aim_ssi_item *item; 1362 1363 while (aim_bstream_empty(bs)) { 1364 if ((len = aimbs_get16(bs))) 1365 name = aimbs_getstr(bs, len); 1366 else 1367 name = NULL; 1368 gid = aimbs_get16(bs); 1369 bid = aimbs_get16(bs); 1370 type = aimbs_get16(bs); 1371 if ((len = aimbs_get16(bs))) 1372 data = aim_readtlvchain_len(bs, len); 1373 else 1374 data = NULL; 1375 1376 /* Replace the 2 local items with the given one */ 1377 if ((item = aim_ssi_itemlist_find(sess->ssi.local, gid, bid))) { 1378 item->type = type; 1379 free(item->name); 1380 if (name) { 1381 item->name = (char *)malloc((strlen(name)+1)*sizeof(char)); 1382 strcpy(item->name, name); 1383 } else 1384 item->name = NULL; 1385 aim_freetlvchain(&item->data); 1386 item->data = aim_tlvlist_copy(data); 1387 } 1388 1389 if ((item = aim_ssi_itemlist_find(sess->ssi.official, gid, bid))) { 1390 item->type = type; 1391 free(item->name); 1392 if (name) { 1393 item->name = (char *)malloc((strlen(name)+1)*sizeof(char)); 1394 strcpy(item->name, name); 1395 } else 1396 item->name = NULL; 1397 aim_freetlvchain(&item->data); 1398 item->data = aim_tlvlist_copy(data); 1399 } 1400 1401 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1402 ret = userfunc(sess, rx); 1403 1404 free(name); 1405 aim_freetlvchain(&data); 1406 } 1407 1408 return ret; 1409 } 1410 1411 /* 1412 * Subtype 0x000a - Incoming SSI del. 1413 * 1414 * XXX - It would probably be good for the client to actually do something when it gets this. 1415 */ 1416 static int parsedel(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1417 { 1418 int ret = 0; 1419 aim_rxcallback_t userfunc; 1420 fu16_t gid, bid; 1421 struct aim_ssi_item *del; 1422 1423 while (aim_bstream_empty(bs)) { 1424 aim_bstream_advance(bs, aimbs_get16(bs)); 1425 gid = aimbs_get16(bs); 1426 bid = aimbs_get16(bs); 1427 aimbs_get16(bs); 1428 aim_bstream_advance(bs, aimbs_get16(bs)); 1429 1430 if ((del = aim_ssi_itemlist_find(sess->ssi.local, gid, bid))) 1431 aim_ssi_itemlist_del(&sess->ssi.local, del); 1432 if ((del = aim_ssi_itemlist_find(sess->ssi.official, gid, bid))) 1433 aim_ssi_itemlist_del(&sess->ssi.official, del); 1434 1435 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1436 ret = userfunc(sess, rx); 1437 } 1438 1439 return ret; 1440 } 1441 1442 /* 1443 * Subtype 0x000e - SSI Add/Mod/Del Ack. 1444 * 1445 * Response to add, modify, or delete SNAC (sent with aim_ssi_addmoddel). 1446 * 1447 */ 1448 static int parseack(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1449 { 1450 int ret = 0; 1451 aim_rxcallback_t userfunc; 1452 struct aim_ssi_tmp *cur, *del; 1453 1454 /* Read in the success/failure flags from the ack SNAC */ 1455 cur = sess->ssi.pending; 1456 while (cur && (aim_bstream_empty(bs)>0)) { 1457 cur->ack = aimbs_get16(bs); 1458 cur = cur->next; 1459 } 1460 1461 /* 1462 * If outcome is 0, then add the item to the item list, or replace the other item, 1463 * or remove the old item. If outcome is non-zero, then remove the item from the 1464 * local list, or unmodify it, or add it. 1465 */ 1466 for (cur=sess->ssi.pending; (cur && (cur->ack != 0xffff)); cur=cur->next) { 1467 if (cur->item) { 1468 if (cur->ack) { 1469 /* Our action was unsuccessful, so change the local list back to how it was */ 1470 if (cur->action == AIM_CB_SSI_ADD) { 1471 /* Remove the item from the local list */ 1472 /* Make sure cur->item is still valid memory */ 1473 if (aim_ssi_itemlist_valid(sess->ssi.local, cur->item)) { 1474 if (cur->item->name) { 1475 cur->name = (char *)malloc((strlen(cur->item->name)+1)*sizeof(char)); 1476 strcpy(cur->name, cur->item->name); 1477 } 1478 aim_ssi_itemlist_del(&sess->ssi.local, cur->item); 1479 } 1480 cur->item = NULL; 1481 1482 } else if (cur->action == AIM_CB_SSI_MOD) { 1483 /* Replace the local item with the item from the official list */ 1484 if (aim_ssi_itemlist_valid(sess->ssi.local, cur->item)) { 1485 struct aim_ssi_item *cur1; 1486 if ((cur1 = aim_ssi_itemlist_find(sess->ssi.official, cur->item->gid, cur->item->bid))) { 1487 free(cur->item->name); 1488 if (cur1->name) { 1489 cur->item->name = (char *)malloc((strlen(cur1->name)+1)*sizeof(char)); 1490 strcpy(cur->item->name, cur1->name); 1491 } else 1492 cur->item->name = NULL; 1493 aim_freetlvchain(&cur->item->data); 1494 cur->item->data = aim_tlvlist_copy(cur1->data); 1495 } 1496 } else 1497 cur->item = NULL; 1498 1499 } else if (cur->action == AIM_CB_SSI_DEL) { 1500 /* Add the item back into the local list */ 1501 if (aim_ssi_itemlist_valid(sess->ssi.official, cur->item)) { 1502 aim_ssi_itemlist_add(&sess->ssi.local, cur->item->name, cur->item->gid, cur->item->bid, cur->item->type, cur->item->data); 1503 } else 1504 cur->item = NULL; 1505 } 1506 1507 } else { 1508 /* Do the exact opposite */ 1509 if (cur->action == AIM_CB_SSI_ADD) { 1510 /* Add the local item to the official list */ 1511 if (aim_ssi_itemlist_valid(sess->ssi.local, cur->item)) { 1512 aim_ssi_itemlist_add(&sess->ssi.official, cur->item->name, cur->item->gid, cur->item->bid, cur->item->type, cur->item->data); 1513 } else 1514 cur->item = NULL; 1515 1516 } else if (cur->action == AIM_CB_SSI_MOD) { 1517 /* Replace the official item with the item from the local list */ 1518 if (aim_ssi_itemlist_valid(sess->ssi.local, cur->item)) { 1519 struct aim_ssi_item *cur1; 1520 if ((cur1 = aim_ssi_itemlist_find(sess->ssi.official, cur->item->gid, cur->item->bid))) { 1521 free(cur1->name); 1522 if (cur->item->name) { 1523 cur1->name = (char *)malloc((strlen(cur->item->name)+1)*sizeof(char)); 1524 strcpy(cur1->name, cur->item->name); 1525 } else 1526 cur1->name = NULL; 1527 aim_freetlvchain(&cur1->data); 1528 cur1->data = aim_tlvlist_copy(cur->item->data); 1529 } 1530 } else 1531 cur->item = NULL; 1532 1533 } else if (cur->action == AIM_CB_SSI_DEL) { 1534 /* Remove the item from the official list */ 1535 if (aim_ssi_itemlist_valid(sess->ssi.official, cur->item)) 1536 aim_ssi_itemlist_del(&sess->ssi.official, cur->item); 1537 cur->item = NULL; 1538 } 1539 1540 } 1541 } /* End if (cur->item) */ 1542 } /* End for loop */ 1543 1544 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1545 ret = userfunc(sess, rx, sess->ssi.pending); 1546 1547 /* Free all aim_ssi_tmp's with an outcome */ 1548 cur = sess->ssi.pending; 1549 while (cur && (cur->ack != 0xffff)) { 1550 del = cur; 1551 cur = cur->next; 1552 free(del->name); 1553 free(del); 1554 } 1555 sess->ssi.pending = cur; 1556 1557 /* If we're not waiting for any more acks, then send more SNACs */ 1558 if (!sess->ssi.pending) { 1559 sess->ssi.pending = NULL; 1560 sess->ssi.waiting_for_ack = 0; 1561 aim_ssi_sync(sess); 1562 } 1563 1564 return ret; 1534 1535 } 1536 } /* End if (cur->item) */ 1537 } /* End for loop */ 1538 1539 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1540 ret = userfunc(sess, rx, sess->ssi.pending); 1541 1542 /* Free all aim_ssi_tmp's with an outcome */ 1543 cur = sess->ssi.pending; 1544 while (cur && (cur->ack != 0xffff)) { 1545 del = cur; 1546 cur = cur->next; 1547 free(del->name); 1548 free(del); 1549 } 1550 sess->ssi.pending = cur; 1551 1552 /* If we're not waiting for any more acks, then send more SNACs */ 1553 if (!sess->ssi.pending) { 1554 sess->ssi.pending = NULL; 1555 sess->ssi.waiting_for_ack = 0; 1556 aim_ssi_sync(sess); 1557 } 1558 1559 return ret; 1565 1560 } 1566 1561 … … 1574 1569 static int parsedataunchanged(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1575 1570 { 1576 int ret = 0;1577 aim_rxcallback_t userfunc;1578 1579 sess->ssi.received_data = 1;1580 1581 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))1582 ret = userfunc(sess, rx);1583 1584 return ret;1571 int ret = 0; 1572 aim_rxcallback_t userfunc; 1573 1574 sess->ssi.received_data = 1; 1575 1576 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1577 ret = userfunc(sess, rx); 1578 1579 return ret; 1585 1580 } 1586 1581 … … 1593 1588 faim_export int aim_ssi_modbegin(aim_session_t *sess) 1594 1589 { 1595 aim_conn_t *conn;1596 1597 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)))1598 return -EINVAL;1599 1600 return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_EDITSTART);1590 aim_conn_t *conn; 1591 1592 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI))) 1593 return -EINVAL; 1594 1595 return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_EDITSTART); 1601 1596 } 1602 1597 … … 1609 1604 faim_export int aim_ssi_modend(aim_session_t *sess) 1610 1605 { 1611 aim_conn_t *conn;1612 1613 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)))1614 return -EINVAL;1615 1616 return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_EDITSTOP);1606 aim_conn_t *conn; 1607 1608 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI))) 1609 return -EINVAL; 1610 1611 return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_EDITSTOP); 1617 1612 } 1618 1613 … … 1625 1620 faim_export int aim_ssi_sendauth(aim_session_t *sess, char *sn, char *msg) 1626 1621 { 1627 aim_conn_t *conn;1628 aim_frame_t *fr;1629 aim_snacid_t snacid;1630 1631 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sn)1632 return -EINVAL;1633 1634 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn)+2+(msg ? strlen(msg)+1 : 0)+2)))1635 return -ENOMEM;1636 1637 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTH, 0x0000, NULL, 0);1638 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTH, 0x0000, snacid);1639 1640 /* Screen name */1641 aimbs_put8(&fr->data, strlen(sn));1642 aimbs_putraw(&fr->data, sn, strlen(sn));1643 1644 /* Message (null terminated) */1645 aimbs_put16(&fr->data, msg ? strlen(msg) : 0);1646 if (msg) {1647 aimbs_putraw(&fr->data, msg, strlen(msg));1648 aimbs_put8(&fr->data, 0x00);1649 }1650 1651 /* Unknown */1652 aimbs_put16(&fr->data, 0x0000);1653 1654 aim_tx_enqueue(sess, fr);1655 1656 return 0;1622 aim_conn_t *conn; 1623 aim_frame_t *fr; 1624 aim_snacid_t snacid; 1625 1626 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sn) 1627 return -EINVAL; 1628 1629 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn)+2+(msg ? strlen(msg)+1 : 0)+2))) 1630 return -ENOMEM; 1631 1632 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTH, 0x0000, NULL, 0); 1633 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTH, 0x0000, snacid); 1634 1635 /* Screen name */ 1636 aimbs_put8(&fr->data, strlen(sn)); 1637 aimbs_putraw(&fr->data, sn, strlen(sn)); 1638 1639 /* Message (null terminated) */ 1640 aimbs_put16(&fr->data, msg ? strlen(msg) : 0); 1641 if (msg) { 1642 aimbs_putraw(&fr->data, msg, strlen(msg)); 1643 aimbs_put8(&fr->data, 0x00); 1644 } 1645 1646 /* Unknown */ 1647 aimbs_put16(&fr->data, 0x0000); 1648 1649 aim_tx_enqueue(sess, fr); 1650 1651 return 0; 1657 1652 } 1658 1653 … … 1662 1657 static int receiveauthgrant(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1663 1658 { 1664 int ret = 0;1665 aim_rxcallback_t userfunc;1666 fu16_t tmp;1667 char *sn, *msg;1668 1669 /* Read screen name */1670 if ((tmp = aimbs_get8(bs)))1671 sn = aimbs_getstr(bs, tmp);1672 else1673 sn = NULL;1674 1675 /* Read message (null terminated) */1676 if ((tmp = aimbs_get16(bs)))1677 msg = aimbs_getstr(bs, tmp);1678 else1679 msg = NULL;1680 1681 /* Unknown */1682 tmp = aimbs_get16(bs);1683 1684 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))1685 ret = userfunc(sess, rx, sn, msg);1686 1687 free(sn);1688 free(msg);1689 1690 return ret;1659 int ret = 0; 1660 aim_rxcallback_t userfunc; 1661 fu16_t tmp; 1662 char *sn, *msg; 1663 1664 /* Read screen name */ 1665 if ((tmp = aimbs_get8(bs))) 1666 sn = aimbs_getstr(bs, tmp); 1667 else 1668 sn = NULL; 1669 1670 /* Read message (null terminated) */ 1671 if ((tmp = aimbs_get16(bs))) 1672 msg = aimbs_getstr(bs, tmp); 1673 else 1674 msg = NULL; 1675 1676 /* Unknown */ 1677 tmp = aimbs_get16(bs); 1678 1679 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1680 ret = userfunc(sess, rx, sn, msg); 1681 1682 free(sn); 1683 free(msg); 1684 1685 return ret; 1691 1686 } 1692 1687 … … 1700 1695 faim_export int aim_ssi_sendauthrequest(aim_session_t *sess, char *sn, char *msg) 1701 1696 { 1702 aim_conn_t *conn;1703 aim_frame_t *fr;1704 aim_snacid_t snacid;1705 1706 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sn)1707 return -EINVAL;1708 1709 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn)+2+(msg ? strlen(msg)+1 : 0)+2)))1710 return -ENOMEM;1711 1712 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTHREQ, 0x0000, NULL, 0);1713 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTHREQ, 0x0000, snacid);1714 1715 /* Screen name */1716 aimbs_put8(&fr->data, strlen(sn));1717 aimbs_putraw(&fr->data, sn, strlen(sn));1718 1719 /* Message (null terminated) */1720 aimbs_put16(&fr->data, msg ? strlen(msg) : 0);1721 if (msg) {1722 aimbs_putraw(&fr->data, msg, strlen(msg));1723 aimbs_put8(&fr->data, 0x00);1724 }1725 1726 /* Unknown */1727 aimbs_put16(&fr->data, 0x0000);1728 1729 aim_tx_enqueue(sess, fr);1730 1731 return 0;1697 aim_conn_t *conn; 1698 aim_frame_t *fr; 1699 aim_snacid_t snacid; 1700 1701 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sn) 1702 return -EINVAL; 1703 1704 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn)+2+(msg ? strlen(msg)+1 : 0)+2))) 1705 return -ENOMEM; 1706 1707 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTHREQ, 0x0000, NULL, 0); 1708 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTHREQ, 0x0000, snacid); 1709 1710 /* Screen name */ 1711 aimbs_put8(&fr->data, strlen(sn)); 1712 aimbs_putraw(&fr->data, sn, strlen(sn)); 1713 1714 /* Message (null terminated) */ 1715 aimbs_put16(&fr->data, msg ? strlen(msg) : 0); 1716 if (msg) { 1717 aimbs_putraw(&fr->data, msg, strlen(msg)); 1718 aimbs_put8(&fr->data, 0x00); 1719 } 1720 1721 /* Unknown */ 1722 aimbs_put16(&fr->data, 0x0000); 1723 1724 aim_tx_enqueue(sess, fr); 1725 1726 return 0; 1732 1727 } 1733 1728 … … 1737 1732 static int receiveauthrequest(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1738 1733 { 1739 int ret = 0;1740 aim_rxcallback_t userfunc;1741 fu16_t tmp;1742 char *sn, *msg;1743 1744 /* Read screen name */1745 if ((tmp = aimbs_get8(bs)))1746 sn = aimbs_getstr(bs, tmp);1747 else1748 sn = NULL;1749 1750 /* Read message (null terminated) */1751 if ((tmp = aimbs_get16(bs)))1752 msg = aimbs_getstr(bs, tmp);1753 else1754 msg = NULL;1755 1756 /* Unknown */1757 tmp = aimbs_get16(bs);1758 1759 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))1760 ret = userfunc(sess, rx, sn, msg);1761 1762 free(sn);1763 free(msg);1764 1765 return ret;1734 int ret = 0; 1735 aim_rxcallback_t userfunc; 1736 fu16_t tmp; 1737 char *sn, *msg; 1738 1739 /* Read screen name */ 1740 if ((tmp = aimbs_get8(bs))) 1741 sn = aimbs_getstr(bs, tmp); 1742 else 1743 sn = NULL; 1744 1745 /* Read message (null terminated) */ 1746 if ((tmp = aimbs_get16(bs))) 1747 msg = aimbs_getstr(bs, tmp); 1748 else 1749 msg = NULL; 1750 1751 /* Unknown */ 1752 tmp = aimbs_get16(bs); 1753 1754 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1755 ret = userfunc(sess, rx, sn, msg); 1756 1757 free(sn); 1758 free(msg); 1759 1760 return ret; 1766 1761 } 1767 1762 … … 1778 1773 faim_export int aim_ssi_sendauthreply(aim_session_t *sess, char *sn, fu8_t reply, char *msg) 1779 1774 { 1780 aim_conn_t *conn;1781 aim_frame_t *fr;1782 aim_snacid_t snacid;1783 1784 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sn)1785 return -EINVAL;1786 1787 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 1+strlen(sn) + 1 + 2+(msg ? strlen(msg)+1 : 0) + 2)))1788 return -ENOMEM;1789 1790 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTHREP, 0x0000, NULL, 0);1791 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTHREP, 0x0000, snacid);1792 1793 /* Screen name */1794 aimbs_put8(&fr->data, strlen(sn));1795 aimbs_putraw(&fr->data, sn, strlen(sn));1796 1797 /* Grant or deny */1798 aimbs_put8(&fr->data, reply);1799 1800 /* Message (null terminated) */1801 aimbs_put16(&fr->data, msg ? (strlen(msg)+1) : 0);1802 if (msg) {1803 aimbs_putraw(&fr->data, msg, strlen(msg));1804 aimbs_put8(&fr->data, 0x00);1805 }1806 1807 /* Unknown */1808 aimbs_put16(&fr->data, 0x0000);1809 1810 aim_tx_enqueue(sess, fr);1811 1812 return 0;1775 aim_conn_t *conn; 1776 aim_frame_t *fr; 1777 aim_snacid_t snacid; 1778 1779 if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sn) 1780 return -EINVAL; 1781 1782 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 1+strlen(sn) + 1 + 2+(msg ? strlen(msg)+1 : 0) + 2))) 1783 return -ENOMEM; 1784 1785 snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTHREP, 0x0000, NULL, 0); 1786 aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTHREP, 0x0000, snacid); 1787 1788 /* Screen name */ 1789 aimbs_put8(&fr->data, strlen(sn)); 1790 aimbs_putraw(&fr->data, sn, strlen(sn)); 1791 1792 /* Grant or deny */ 1793 aimbs_put8(&fr->data, reply); 1794 1795 /* Message (null terminated) */ 1796 aimbs_put16(&fr->data, msg ? (strlen(msg)+1) : 0); 1797 if (msg) { 1798 aimbs_putraw(&fr->data, msg, strlen(msg)); 1799 aimbs_put8(&fr->data, 0x00); 1800 } 1801 1802 /* Unknown */ 1803 aimbs_put16(&fr->data, 0x0000); 1804 1805 aim_tx_enqueue(sess, fr); 1806 1807 return 0; 1813 1808 } 1814 1809 … … 1820 1815 static int receiveauthreply(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1821 1816 { 1822 int ret = 0;1823 aim_rxcallback_t userfunc;1824 fu16_t tmp;1825 fu8_t reply;1826 char *sn, *msg;1827 1828 /* Read screen name */1829 if ((tmp = aimbs_get8(bs)))1830 sn = aimbs_getstr(bs, tmp);1831 else1832 sn = NULL;1833 1834 /* Read reply */1835 reply = aimbs_get8(bs);1836 1837 /* Read message (null terminated) */1838 if ((tmp = aimbs_get16(bs)))1839 msg = aimbs_getstr(bs, tmp);1840 else1841 msg = NULL;1842 1843 /* Unknown */1844 tmp = aimbs_get16(bs);1845 1846 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))1847 ret = userfunc(sess, rx, sn, reply, msg);1848 1849 free(sn);1850 free(msg);1851 1852 return ret;1817 int ret = 0; 1818 aim_rxcallback_t userfunc; 1819 fu16_t tmp; 1820 fu8_t reply; 1821 char *sn, *msg; 1822 1823 /* Read screen name */ 1824 if ((tmp = aimbs_get8(bs))) 1825 sn = aimbs_getstr(bs, tmp); 1826 else 1827 sn = NULL; 1828 1829 /* Read reply */ 1830 reply = aimbs_get8(bs); 1831 1832 /* Read message (null terminated) */ 1833 if ((tmp = aimbs_get16(bs))) 1834 msg = aimbs_getstr(bs, tmp); 1835 else 1836 msg = NULL; 1837 1838 /* Unknown */ 1839 tmp = aimbs_get16(bs); 1840 1841 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1842 ret = userfunc(sess, rx, sn, reply, msg); 1843 1844 free(sn); 1845 free(msg); 1846 1847 return ret; 1853 1848 } 1854 1849 … … 1858 1853 static int receiveadded(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1859 1854 { 1860 int ret = 0; 1861 aim_rxcallback_t userfunc; 1862 fu16_t tmp; 1863 char *sn; 1864 1865 /* Read screen name */ 1866 if ((tmp = aimbs_get8(bs))) 1867 sn = aimbs_getstr(bs, tmp); 1868 else 1869 sn = NULL; 1870 1871 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) 1872 ret = userfunc(sess, rx, sn); 1873 1874 free(sn); 1875 1876 return ret; 1855 int ret = 0; 1856 aim_rxcallback_t userfunc; 1857 fu16_t tmp; 1858 char *sn; 1859 1860 /* Read screen name */ 1861 if ((tmp = aimbs_get8(bs))) { 1862 sn = aimbs_getstr(bs, tmp); 1863 } else { 1864 sn = NULL; 1865 } 1866 1867 if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) { 1868 ret = userfunc(sess, rx, sn); 1869 } 1870 1871 free(sn); 1872 return(ret); 1877 1873 } 1878 1874 1879 1875 static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs) 1880 1876 { 1881 1882 if (snac->subtype == AIM_CB_SSI_RIGHTSINFO) 1883 return parserights(sess, mod, rx, snac, bs); 1884 else if (snac->subtype == AIM_CB_SSI_LIST) 1885 return parsedata(sess, mod, rx, snac, bs); 1886 else if (snac->subtype == AIM_CB_SSI_ADD) 1887 return parseadd(sess, mod, rx, snac, bs); 1888 else if (snac->subtype == AIM_CB_SSI_MOD) 1889 return parsemod(sess, mod, rx, snac, bs); 1890 else if (snac->subtype == AIM_CB_SSI_DEL) 1891 return parsedel(sess, mod, rx, snac, bs); 1892 else if (snac->subtype == AIM_CB_SSI_SRVACK) 1893 return parseack(sess, mod, rx, snac, bs); 1894 else if (snac->subtype == AIM_CB_SSI_NOLIST) 1895 return parsedataunchanged(sess, mod, rx, snac, bs); 1896 else if (snac->subtype == AIM_CB_SSI_RECVAUTH) 1897 return receiveauthgrant(sess, mod, rx, snac, bs); 1898 else if (snac->subtype == AIM_CB_SSI_RECVAUTHREQ) 1899 return receiveauthrequest(sess, mod, rx, snac, bs); 1900 else if (snac->subtype == AIM_CB_SSI_RECVAUTHREP) 1901 return receiveauthreply(sess, mod, rx, snac, bs); 1902 else if (snac->subtype == AIM_CB_SSI_ADDED) 1903 return receiveadded(sess, mod, rx, snac, bs); 1904 1905 return 0; 1877 if (snac->subtype == AIM_CB_SSI_RIGHTSINFO) { 1878 return parserights(sess, mod, rx, snac, bs); 1879 } else if (snac->subtype == AIM_CB_SSI_LIST) { 1880 return parsedata(sess, mod, rx, snac, bs); 1881 } else if (snac->subtype == AIM_CB_SSI_ADD) { 1882 return parseadd(sess, mod, rx, snac, bs); 1883 } else if (snac->subtype == AIM_CB_SSI_MOD) { 1884 return parsemod(sess, mod, rx, snac, bs); 1885 } else if (snac->subtype == AIM_CB_SSI_DEL) { 1886 return parsedel(sess, mod, rx, snac, bs); 1887 } else if (snac->subtype == AIM_CB_SSI_SRVACK) { 1888 return parseack(sess, mod, rx, snac, bs); 1889 } else if (snac->subtype == AIM_CB_SSI_NOLIST) { 1890 return parsedataunchanged(sess, mod, rx, snac, bs); 1891 } else if (snac->subtype == AIM_CB_SSI_RECVAUTH) { 1892 return receiveauthgrant(sess, mod, rx, snac, bs); 1893 } else if (snac->subtype == AIM_CB_SSI_RECVAUTHREQ) { 1894 return receiveauthrequest(sess, mod, rx, snac, bs); 1895 } else if (snac->subtype == AIM_CB_SSI_RECVAUTHREP) { 1896 return receiveauthreply(sess, mod, rx, snac, bs); 1897 } else if (snac->subtype == AIM_CB_SSI_ADDED) { 1898 return receiveadded(sess, mod, rx, snac, bs); 1899 } 1900 return(0); 1906 1901 } 1907 1902 1908 1903 static void ssi_shutdown(aim_session_t *sess, aim_module_t *mod) 1909 1904 { 1910 aim_ssi_freelist(sess); 1911 1912 return; 1905 aim_ssi_freelist(sess); 1906 return; 1913 1907 } 1914 1908 1915 1909 faim_internal int ssi_modfirst(aim_session_t *sess, aim_module_t *mod) 1916 1910 { 1917 1918 mod->family = AIM_CB_FAM_SSI;1919 mod->version = 0x0004;1920 mod->toolid = 0x0110;1921 mod->toolversion = 0x0629;1922 mod->flags = 0;1923 strncpy(mod->name, "ssi", sizeof(mod->name));1924 mod->snachandler = snachandler;1925 mod->shutdown = ssi_shutdown;1926 1927 return 0;1928 } 1911 1912 mod->family = AIM_CB_FAM_SSI; 1913 mod->version = 0x0004; 1914 mod->toolid = 0x0110; 1915 mod->toolversion = 0x0629; 1916 mod->flags = 0; 1917 strncpy(mod->name, "ssi", sizeof(mod->name)); 1918 mod->snachandler = snachandler; 1919 mod->shutdown = ssi_shutdown; 1920 1921 return 0; 1922 }
Note: See TracChangeset
for help on using the changeset viewer.
