comparison libpurple/protocols/oscar/family_feedbag.c @ 17445:f80f7e1047be

Cleanup and simplification of some tlvlist stuff in the oscar protocol. No functionality change.
author Mark Doliner <mark@kingant.net>
date Tue, 29 May 2007 09:51:51 +0000
parents 1927f4ead3ca
children 0db74191adbb
comparison
equal deleted inserted replaced
17444:b31f53796f3b 17445:f80f7e1047be
108 * @param bid The buddy ID# you want the new item to have, or 0xFFFF if we should pick something. 108 * @param bid The buddy ID# you want the new item to have, or 0xFFFF if we should pick something.
109 * @param type The type of the item, 0x0000 for a contact, 0x0001 for a group, etc. 109 * @param type The type of the item, 0x0000 for a contact, 0x0001 for a group, etc.
110 * @param data The additional data for the new item. 110 * @param data The additional data for the new item.
111 * @return A pointer to the newly created item. 111 * @return A pointer to the newly created item.
112 */ 112 */
113 static struct aim_ssi_item *aim_ssi_itemlist_add(struct aim_ssi_item **list, const char *name, guint16 gid, guint16 bid, guint16 type, aim_tlvlist_t *data) 113 static struct aim_ssi_item *aim_ssi_itemlist_add(struct aim_ssi_item **list, const char *name, guint16 gid, guint16 bid, guint16 type, GSList *data)
114 { 114 {
115 gboolean exists; 115 gboolean exists;
116 struct aim_ssi_item *cur, *new; 116 struct aim_ssi_item *cur, *new;
117 117
118 new = (struct aim_ssi_item *)g_malloc(sizeof(struct aim_ssi_item)); 118 new = (struct aim_ssi_item *)g_malloc(sizeof(struct aim_ssi_item));
212 cur->next = del->next; 212 cur->next = del->next;
213 } 213 }
214 214
215 /* Free the removed item */ 215 /* Free the removed item */
216 g_free(del->name); 216 g_free(del->name);
217 aim_tlvlist_free(&del->data); 217 aim_tlvlist_free(del->data);
218 g_free(del); 218 g_free(del);
219 219
220 return 0; 220 return 0;
221 } 221 }
222 222
608 cur = od->ssi.official; 608 cur = od->ssi.official;
609 while (cur) { 609 while (cur) {
610 del = cur; 610 del = cur;
611 cur = cur->next; 611 cur = cur->next;
612 g_free(del->name); 612 g_free(del->name);
613 aim_tlvlist_free(&del->data); 613 aim_tlvlist_free(del->data);
614 g_free(del); 614 g_free(del);
615 } 615 }
616 616
617 cur = od->ssi.local; 617 cur = od->ssi.local;
618 while (cur) { 618 while (cur) {
619 del = cur; 619 del = cur;
620 cur = cur->next; 620 cur = cur->next;
621 g_free(del->name); 621 g_free(del->name);
622 aim_tlvlist_free(&del->data); 622 aim_tlvlist_free(del->data);
623 g_free(del); 623 g_free(del);
624 } 624 }
625 625
626 curtmp = od->ssi.pending; 626 curtmp = od->ssi.pending;
627 while (curtmp) { 627 while (curtmp) {
727 * @return Return 0 if no errors, otherwise return the error number. 727 * @return Return 0 if no errors, otherwise return the error number.
728 */ 728 */
729 int aim_ssi_addbuddy(OscarData *od, const char *name, const char *group, const char *alias, const char *comment, const char *smsnum, int needauth) 729 int aim_ssi_addbuddy(OscarData *od, const char *name, const char *group, const char *alias, const char *comment, const char *smsnum, int needauth)
730 { 730 {
731 struct aim_ssi_item *parent; 731 struct aim_ssi_item *parent;
732 aim_tlvlist_t *data = NULL; 732 GSList *data = NULL;
733 733
734 if (!od || !name || !group) 734 if (!od || !name || !group)
735 return -EINVAL; 735 return -EINVAL;
736 736
737 /* Find the parent */ 737 /* Find the parent */
757 if (comment) 757 if (comment)
758 aim_tlvlist_add_str(&data, 0x013c, comment); 758 aim_tlvlist_add_str(&data, 0x013c, comment);
759 759
760 /* Add that bad boy */ 760 /* Add that bad boy */
761 aim_ssi_itemlist_add(&od->ssi.local, name, parent->gid, 0xFFFF, AIM_SSI_TYPE_BUDDY, data); 761 aim_ssi_itemlist_add(&od->ssi.local, name, parent->gid, 0xFFFF, AIM_SSI_TYPE_BUDDY, data);
762 aim_tlvlist_free(&data); 762 aim_tlvlist_free(data);
763 763
764 /* Modify the parent group */ 764 /* Modify the parent group */
765 aim_ssi_itemlist_rebuildgroup(od->ssi.local, group); 765 aim_ssi_itemlist_rebuildgroup(od->ssi.local, group);
766 766
767 /* Sync our local list with the server list */ 767 /* Sync our local list with the server list */
918 * @param sn The name of the buddy to be moved. 918 * @param sn The name of the buddy to be moved.
919 * @return Return 0 if no errors, otherwise return the error number. 919 * @return Return 0 if no errors, otherwise return the error number.
920 */ 920 */
921 int aim_ssi_movebuddy(OscarData *od, const char *oldgn, const char *newgn, const char *sn) 921 int aim_ssi_movebuddy(OscarData *od, const char *oldgn, const char *newgn, const char *sn)
922 { 922 {
923 char *alias; 923 struct aim_ssi_item *buddy, *parent;
924 gboolean waitingforauth; 924 GSList *datacopy;
925 925
926 alias = aim_ssi_getalias(od->ssi.local, oldgn, sn); 926 if (!od | !oldgn | !newgn | !sn)
927 waitingforauth = aim_ssi_waitingforauth(od->ssi.local, oldgn, sn); 927 return -EINVAL;
928 928
929 aim_ssi_delbuddy(od, sn, oldgn); 929 /* Find the buddy */
930 aim_ssi_addbuddy(od, sn, newgn, alias, NULL, NULL, waitingforauth); 930 if (!(buddy = aim_ssi_itemlist_finditem(od->ssi.local, oldgn, sn, AIM_SSI_TYPE_BUDDY)))
931 931 return -EINVAL;
932 g_free(alias); 932
933 933 /* Make a copy of the buddy's TLV list */
934 return 0; 934 datacopy = aim_tlvlist_copy(buddy->data);
935
936 /* Remove the item from the list */
937 aim_ssi_itemlist_del(&od->ssi.local, buddy);
938
939 /* Modify the parent group */
940 aim_ssi_itemlist_rebuildgroup(od->ssi.local, oldgn);
941
942 /* Check if we should delete the parent group */
943 if ((parent = aim_ssi_itemlist_finditem(od->ssi.local, oldgn, NULL, AIM_SSI_TYPE_GROUP)) && (!parent->data)) {
944 aim_ssi_itemlist_del(&od->ssi.local, parent);
945
946 /* Modify the parent group */
947 aim_ssi_itemlist_rebuildgroup(od->ssi.local, NULL);
948 }
949
950 /* Sync our local list with the server list */
951 aim_ssi_sync(od);
952
953 /* Find the parent */
954 if (!(parent = aim_ssi_itemlist_finditem(od->ssi.local, newgn, NULL, AIM_SSI_TYPE_GROUP))) {
955 /* Add the parent */
956 parent = aim_ssi_itemlist_add(&od->ssi.local, newgn, 0xFFFF, 0x0000, AIM_SSI_TYPE_GROUP, NULL);
957
958 /* Modify the parent's parent (the master group) */
959 aim_ssi_itemlist_rebuildgroup(od->ssi.local, NULL);
960 }
961
962 /* Add that bad boy */
963 aim_ssi_itemlist_add(&od->ssi.local, sn, parent->gid, 0xFFFF, AIM_SSI_TYPE_BUDDY, datacopy);
964
965 /* Free the previously created TLV list copy */
966 aim_tlvlist_free(datacopy);
967
968 /* Modify the parent group */
969 aim_ssi_itemlist_rebuildgroup(od->ssi.local, newgn);
970
971 /* Sync our local list with the server list */
972 return aim_ssi_sync(od);
935 } 973 }
936 974
937 /** 975 /**
938 * Change the alias stored on the server for a given buddy. 976 * Change the alias stored on the server for a given buddy.
939 * 977 *
1170 */ 1208 */
1171 static int parserights(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs) 1209 static int parserights(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
1172 { 1210 {
1173 int ret = 0, i; 1211 int ret = 0, i;
1174 aim_rxcallback_t userfunc; 1212 aim_rxcallback_t userfunc;
1175 aim_tlvlist_t *tlvlist; 1213 GSList *tlvlist;
1176 aim_tlv_t *tlv; 1214 aim_tlv_t *tlv;
1177 ByteStream bstream; 1215 ByteStream bstream;
1178 guint16 *maxitems; 1216 guint16 *maxitems;
1179 1217
1180 /* This SNAC is made up of a bunch of TLVs */ 1218 /* This SNAC is made up of a bunch of TLVs */
1181 tlvlist = aim_tlvlist_read(bs); 1219 tlvlist = aim_tlvlist_read(bs);
1182 1220
1183 /* TLV 0x0004 contains the maximum number of each item */ 1221 /* TLV 0x0004 contains the maximum number of each item */
1184 if (!(tlv = aim_tlv_gettlv(tlvlist, 0x0004, 1))) { 1222 if (!(tlv = aim_tlv_gettlv(tlvlist, 0x0004, 1))) {
1185 aim_tlvlist_free(&tlvlist); 1223 aim_tlvlist_free(tlvlist);
1186 return 0; 1224 return 0;
1187 } 1225 }
1188 1226
1189 byte_stream_init(&bstream, tlv->value, tlv->length); 1227 byte_stream_init(&bstream, tlv->value, tlv->length);
1190 1228
1194 maxitems[i] = byte_stream_get16(&bstream); 1232 maxitems[i] = byte_stream_get16(&bstream);
1195 1233
1196 if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) 1234 if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
1197 ret = userfunc(od, conn, frame, tlv->length/2, maxitems); 1235 ret = userfunc(od, conn, frame, tlv->length/2, maxitems);
1198 1236
1199 aim_tlvlist_free(&tlvlist); 1237 aim_tlvlist_free(tlvlist);
1200 g_free(maxitems); 1238 g_free(maxitems);
1201 1239
1202 return ret; 1240 return ret;
1203 } 1241 }
1204 1242
1265 int ret = 0; 1303 int ret = 0;
1266 aim_rxcallback_t userfunc; 1304 aim_rxcallback_t userfunc;
1267 guint8 fmtver; /* guess */ 1305 guint8 fmtver; /* guess */
1268 guint16 namelen, gid, bid, type; 1306 guint16 namelen, gid, bid, type;
1269 char *name; 1307 char *name;
1270 aim_tlvlist_t *data; 1308 GSList *data;
1271 1309
1272 fmtver = byte_stream_get8(bs); /* Version of ssi data. Should be 0x00 */ 1310 fmtver = byte_stream_get8(bs); /* Version of ssi data. Should be 0x00 */
1273 od->ssi.numitems += byte_stream_get16(bs); /* # of items in this SSI SNAC */ 1311 od->ssi.numitems += byte_stream_get16(bs); /* # of items in this SSI SNAC */
1274 1312
1275 /* Read in the list */ 1313 /* Read in the list */
1282 bid = byte_stream_get16(bs); 1320 bid = byte_stream_get16(bs);
1283 type = byte_stream_get16(bs); 1321 type = byte_stream_get16(bs);
1284 data = aim_tlvlist_readlen(bs, byte_stream_get16(bs)); 1322 data = aim_tlvlist_readlen(bs, byte_stream_get16(bs));
1285 aim_ssi_itemlist_add(&od->ssi.official, name, gid, bid, type, data); 1323 aim_ssi_itemlist_add(&od->ssi.official, name, gid, bid, type, data);
1286 g_free(name); 1324 g_free(name);
1287 aim_tlvlist_free(&data); 1325 aim_tlvlist_free(data);
1288 } 1326 }
1289 1327
1290 /* Read in the timestamp */ 1328 /* Read in the timestamp */
1291 od->ssi.timestamp = byte_stream_get32(bs); 1329 od->ssi.timestamp = byte_stream_get32(bs);
1292 1330
1350 for (cur=od->ssi.pending; cur; cur=cur->next) { 1388 for (cur=od->ssi.pending; cur; cur=cur->next) {
1351 snaclen += 10; /* For length, GID, BID, type, and length */ 1389 snaclen += 10; /* For length, GID, BID, type, and length */
1352 if (cur->item->name) 1390 if (cur->item->name)
1353 snaclen += strlen(cur->item->name); 1391 snaclen += strlen(cur->item->name);
1354 if (cur->item->data) 1392 if (cur->item->data)
1355 snaclen += aim_tlvlist_size(&cur->item->data); 1393 snaclen += aim_tlvlist_size(cur->item->data);
1356 } 1394 }
1357 1395
1358 frame = flap_frame_new(od, 0x02, snaclen); 1396 frame = flap_frame_new(od, 0x02, snaclen);
1359 1397
1360 snacid = aim_cachesnac(od, SNAC_FAMILY_FEEDBAG, od->ssi.pending->action, 0x0000, NULL, 0); 1398 snacid = aim_cachesnac(od, SNAC_FAMILY_FEEDBAG, od->ssi.pending->action, 0x0000, NULL, 0);
1365 if (cur->item->name) 1403 if (cur->item->name)
1366 byte_stream_putstr(&frame->data, cur->item->name); 1404 byte_stream_putstr(&frame->data, cur->item->name);
1367 byte_stream_put16(&frame->data, cur->item->gid); 1405 byte_stream_put16(&frame->data, cur->item->gid);
1368 byte_stream_put16(&frame->data, cur->item->bid); 1406 byte_stream_put16(&frame->data, cur->item->bid);
1369 byte_stream_put16(&frame->data, cur->item->type); 1407 byte_stream_put16(&frame->data, cur->item->type);
1370 byte_stream_put16(&frame->data, cur->item->data ? aim_tlvlist_size(&cur->item->data) : 0); 1408 byte_stream_put16(&frame->data, cur->item->data ? aim_tlvlist_size(cur->item->data) : 0);
1371 if (cur->item->data) 1409 if (cur->item->data)
1372 aim_tlvlist_write(&frame->data, &cur->item->data); 1410 aim_tlvlist_write(&frame->data, &cur->item->data);
1373 } 1411 }
1374 1412
1375 flap_connection_send(conn, frame); 1413 flap_connection_send(conn, frame);
1387 { 1425 {
1388 int ret = 0; 1426 int ret = 0;
1389 aim_rxcallback_t userfunc; 1427 aim_rxcallback_t userfunc;
1390 char *name; 1428 char *name;
1391 guint16 len, gid, bid, type; 1429 guint16 len, gid, bid, type;
1392 aim_tlvlist_t *data; 1430 GSList *data;
1393 1431
1394 while (byte_stream_empty(bs)) { 1432 while (byte_stream_empty(bs)) {
1395 if ((len = byte_stream_get16(bs))) 1433 if ((len = byte_stream_get16(bs)))
1396 name = byte_stream_getstr(bs, len); 1434 name = byte_stream_getstr(bs, len);
1397 else 1435 else
1404 else 1442 else
1405 data = NULL; 1443 data = NULL;
1406 1444
1407 aim_ssi_itemlist_add(&od->ssi.local, name, gid, bid, type, data); 1445 aim_ssi_itemlist_add(&od->ssi.local, name, gid, bid, type, data);
1408 aim_ssi_itemlist_add(&od->ssi.official, name, gid, bid, type, data); 1446 aim_ssi_itemlist_add(&od->ssi.official, name, gid, bid, type, data);
1409 aim_tlvlist_free(&data); 1447 aim_tlvlist_free(data);
1410 1448
1411 if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) 1449 if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
1412 ret = userfunc(od, conn, frame, type, name); 1450 ret = userfunc(od, conn, frame, type, name);
1413 1451
1414 g_free(name); 1452 g_free(name);
1426 { 1464 {
1427 int ret = 0; 1465 int ret = 0;
1428 aim_rxcallback_t userfunc; 1466 aim_rxcallback_t userfunc;
1429 char *name; 1467 char *name;
1430 guint16 len, gid, bid, type; 1468 guint16 len, gid, bid, type;
1431 aim_tlvlist_t *data; 1469 GSList *data;
1432 struct aim_ssi_item *item; 1470 struct aim_ssi_item *item;
1433 1471
1434 while (byte_stream_empty(bs)) { 1472 while (byte_stream_empty(bs)) {
1435 if ((len = byte_stream_get16(bs))) 1473 if ((len = byte_stream_get16(bs)))
1436 name = byte_stream_getstr(bs, len); 1474 name = byte_stream_getstr(bs, len);
1451 if (name) { 1489 if (name) {
1452 item->name = (char *)g_malloc((strlen(name)+1)*sizeof(char)); 1490 item->name = (char *)g_malloc((strlen(name)+1)*sizeof(char));
1453 strcpy(item->name, name); 1491 strcpy(item->name, name);
1454 } else 1492 } else
1455 item->name = NULL; 1493 item->name = NULL;
1456 aim_tlvlist_free(&item->data); 1494 aim_tlvlist_free(item->data);
1457 item->data = aim_tlvlist_copy(data); 1495 item->data = aim_tlvlist_copy(data);
1458 } 1496 }
1459 1497
1460 if ((item = aim_ssi_itemlist_find(od->ssi.official, gid, bid))) { 1498 if ((item = aim_ssi_itemlist_find(od->ssi.official, gid, bid))) {
1461 item->type = type; 1499 item->type = type;
1463 if (name) { 1501 if (name) {
1464 item->name = (char *)g_malloc((strlen(name)+1)*sizeof(char)); 1502 item->name = (char *)g_malloc((strlen(name)+1)*sizeof(char));
1465 strcpy(item->name, name); 1503 strcpy(item->name, name);
1466 } else 1504 } else
1467 item->name = NULL; 1505 item->name = NULL;
1468 aim_tlvlist_free(&item->data); 1506 aim_tlvlist_free(item->data);
1469 item->data = aim_tlvlist_copy(data); 1507 item->data = aim_tlvlist_copy(data);
1470 } 1508 }
1471 1509
1472 if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) 1510 if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
1473 ret = userfunc(od, conn, frame); 1511 ret = userfunc(od, conn, frame);
1474 1512
1475 g_free(name); 1513 g_free(name);
1476 aim_tlvlist_free(&data); 1514 aim_tlvlist_free(data);
1477 } 1515 }
1478 1516
1479 return ret; 1517 return ret;
1480 } 1518 }
1481 1519
1559 if (cur1->name) { 1597 if (cur1->name) {
1560 cur->item->name = (char *)g_malloc((strlen(cur1->name)+1)*sizeof(char)); 1598 cur->item->name = (char *)g_malloc((strlen(cur1->name)+1)*sizeof(char));
1561 strcpy(cur->item->name, cur1->name); 1599 strcpy(cur->item->name, cur1->name);
1562 } else 1600 } else
1563 cur->item->name = NULL; 1601 cur->item->name = NULL;
1564 aim_tlvlist_free(&cur->item->data); 1602 aim_tlvlist_free(cur->item->data);
1565 cur->item->data = aim_tlvlist_copy(cur1->data); 1603 cur->item->data = aim_tlvlist_copy(cur1->data);
1566 } 1604 }
1567 } else 1605 } else
1568 cur->item = NULL; 1606 cur->item = NULL;
1569 1607
1593 if (cur->item->name) { 1631 if (cur->item->name) {
1594 cur1->name = (char *)g_malloc((strlen(cur->item->name)+1)*sizeof(char)); 1632 cur1->name = (char *)g_malloc((strlen(cur->item->name)+1)*sizeof(char));
1595 strcpy(cur1->name, cur->item->name); 1633 strcpy(cur1->name, cur->item->name);
1596 } else 1634 } else
1597 cur1->name = NULL; 1635 cur1->name = NULL;
1598 aim_tlvlist_free(&cur1->data); 1636 aim_tlvlist_free(cur1->data);
1599 cur1->data = aim_tlvlist_copy(cur->item->data); 1637 cur1->data = aim_tlvlist_copy(cur->item->data);
1600 } 1638 }
1601 } else 1639 } else
1602 cur->item = NULL; 1640 cur->item = NULL;
1603 1641