| 754 | static tr_bool |
| 755 | findTrackerById( const tr_info * inf, |
| 756 | uint32_t id, |
| 757 | int * index ) |
| 758 | { |
| 759 | int i; |
| 760 | tr_bool found = FALSE; |
| 761 | |
| 762 | for( i = 0; i < inf->trackerCount; ++i ) |
| 763 | { |
| 764 | const tr_tracker_info * t = &inf->trackers[i]; |
| 765 | if( t->id == id ) |
| 766 | { |
| 767 | if( index ) *index = i; |
| 768 | found = TRUE; |
| 769 | break; |
| 770 | } |
| 771 | } |
| 772 | |
| 773 | return found; |
| 774 | } |
| 775 | |
| 776 | static tr_bool |
| 777 | findTrackerByURL( const tr_info * inf, |
| 778 | const char * url, |
| 779 | int * index ) |
| 780 | { |
| 781 | int i; |
| 782 | tr_bool found = FALSE; |
| 783 | |
| 784 | for( i = 0; i < inf->trackerCount; ++i ) |
| 785 | { |
| 786 | const tr_tracker_info * t = &inf->trackers[i]; |
| 787 | if( !strcmp( t->announce, url ) ) |
| 788 | { |
| 789 | if( index ) *index = i; |
| 790 | found = TRUE; |
| 791 | break; |
| 792 | } |
| 793 | } |
| 794 | |
| 795 | return found; |
| 796 | } |
| 797 | |
| 798 | static const char* |
| 799 | addTracker( tr_torrent * tor, |
| 800 | tr_benc * tracker ) |
| 801 | { |
| 802 | int i; |
| 803 | int64_t tmp; |
| 804 | tr_bool duplicate = FALSE; |
| 805 | const char * errmsg = NULL; |
| 806 | const char * announce; |
| 807 | const tr_info * inf = tr_torrentInfo( tor ); |
| 808 | |
| 809 | if( !tr_bencDictFindStr( tracker, "announce", &announce ) ) |
| 810 | return "no announce url supplied"; |
| 811 | |
| 812 | duplicate = findTrackerByURL( inf, announce, NULL ); |
| 813 | |
| 814 | if( !duplicate ) |
| 815 | { |
| 816 | int tier, trackerCount; |
| 817 | tr_tracker_info * trackers = tr_new0( tr_tracker_info, inf->trackerCount + 1 ); |
| 818 | |
| 819 | if( tr_bencDictFindInt( tracker, "tier", &tmp ) ) |
| 820 | tier = (int)tmp; |
| 821 | else |
| 822 | tier = -1; |
| 823 | |
| 824 | for( i = 0; i < inf->trackerCount; ++i ) |
| 825 | { |
| 826 | const tr_tracker_info * t = &inf->trackers[i]; |
| 827 | trackers[i].tier = t->tier; |
| 828 | trackers[i].announce = tr_strdup( t->announce ); |
| 829 | } |
| 830 | trackers[i].tier = tier < 0 ? trackers[i-1].tier + 1 : tier; |
| 831 | trackers[i].announce = tr_strdup( announce ); |
| 832 | trackerCount = inf->trackerCount + 1; |
| 833 | |
| 834 | if( !tr_torrentSetAnnounceList( tor, trackers, trackerCount ) ) |
| 835 | errmsg = "tracker URL was invalid"; |
| 836 | |
| 837 | for( i = 0; i < trackerCount; ++i ) |
| 838 | tr_free( trackers[i].announce ); |
| 839 | tr_free( trackers ); |
| 840 | } |
| 841 | else |
| 842 | errmsg = "tracker already exists"; |
| 843 | |
| 844 | return errmsg; |
| 845 | } |
| 846 | |
| 847 | static const char* |
| 848 | editTracker( tr_torrent * tor, |
| 849 | tr_benc * tracker ) |
| 850 | { |
| 851 | int trackerIndex; |
| 852 | int64_t tmp; |
| 853 | tr_bool found = FALSE; |
| 854 | const char * errmsg = NULL; |
| 855 | const char * announce; |
| 856 | const tr_info * inf = tr_torrentInfo( tor ); |
| 857 | |
| 858 | if( tr_bencDictFindInt( tracker, "id", &tmp ) ) |
| 859 | found = findTrackerById( inf, (uint32_t)tmp, &trackerIndex ); |
| 860 | else if( tr_bencDictFindStr( tracker, "announce", &announce ) ) |
| 861 | found = findTrackerByURL( inf, announce, &trackerIndex ); |
| 862 | else |
| 863 | errmsg = "no tracker supplied"; |
| 864 | |
| 865 | if( found ) |
| 866 | { |
| 867 | int tier; |
| 868 | const char * new; |
| 869 | tr_bool rename = FALSE; |
| 870 | tr_bool move = FALSE; |
| 871 | |
| 872 | if( tr_bencDictFindStr( tracker, "url", &new ) ) |
| 873 | { |
| 874 | rename = !findTrackerByURL( inf, new, NULL ); |
| 875 | if( !rename ) |
| 876 | errmsg = "tracker already exists"; |
| 877 | } |
| 878 | if( tr_bencDictFindInt( tracker, "tier", &tmp ) ) |
| 879 | { |
| 880 | tier = (int)tmp; |
| 881 | move = TRUE; |
| 882 | } |
| 883 | |
| 884 | if( ( rename || move ) && !errmsg ) |
| 885 | { |
| 886 | int i, trackerCount; |
| 887 | tr_tracker_info * trackers = tr_new0( tr_tracker_info, inf->trackerCount ); |
| 888 | |
| 889 | for( i = 0; i < inf->trackerCount; ++i ) |
| 890 | { |
| 891 | const tr_tracker_info * t = &inf->trackers[i]; |
| 892 | if( i != trackerIndex ) |
| 893 | { |
| 894 | trackers[i].tier = t->tier; |
| 895 | trackers[i].announce = tr_strdup( t->announce ); |
| 896 | } |
| 897 | else |
| 898 | { |
| 899 | trackers[i].tier = move ? tier : t->tier; |
| 900 | trackers[i].announce = tr_strdup( rename ? new : t->announce ); |
| 901 | } |
| 902 | } |
| 903 | trackerCount = i; |
| 904 | |
| 905 | if( !tr_torrentSetAnnounceList( tor, trackers, trackerCount ) ) |
| 906 | errmsg = "big bad error!"; |
| 907 | |
| 908 | for( i = 0; i < trackerCount; ++i ) |
| 909 | tr_free( trackers[i].announce ); |
| 910 | tr_free( trackers ); |
| 911 | } |
| 912 | else if( !errmsg ) |
| 913 | errmsg = "no operation supplied"; |
| 914 | } |
| 915 | else |
| 916 | errmsg = "tracker doesn't exists"; |
| 917 | |
| 918 | return errmsg; |
| 919 | } |
| 920 | |
| 921 | static const char* |
| 922 | removeTracker( tr_torrent * tor, |
| 923 | tr_benc * tracker ) |
| 924 | { |
| 925 | int trackerIndex; |
| 926 | int64_t tmp; |
| 927 | tr_bool found = FALSE; |
| 928 | const char * errmsg = NULL; |
| 929 | const char * announce; |
| 930 | const tr_info * inf = tr_torrentInfo( tor ); |
| 931 | |
| 932 | if( tr_bencDictFindInt( tracker, "id", &tmp ) ) |
| 933 | found = findTrackerById( inf, (uint32_t)tmp, &trackerIndex ); |
| 934 | else if( tr_bencDictFindStr( tracker, "announce", &announce ) ) |
| 935 | found = findTrackerByURL( inf, announce, &trackerIndex ); |
| 936 | else |
| 937 | errmsg = "no tracker supplied"; |
| 938 | |
| 939 | if( found ) |
| 940 | { |
| 941 | int i, j, trackerCount; |
| 942 | tr_tracker_info * trackers = tr_new0( tr_tracker_info, inf->trackerCount - 1 ); |
| 943 | |
| 944 | for( i = 0, j = 0; i < inf->trackerCount; ++i ) |
| 945 | { |
| 946 | if( i != trackerIndex ) |
| 947 | { |
| 948 | const tr_tracker_info * t = &inf->trackers[i]; |
| 949 | trackers[j].tier = t->tier; |
| 950 | trackers[j].announce = tr_strdup( t->announce ); |
| 951 | ++j; |
| 952 | } |
| 953 | } |
| 954 | trackerCount = j; |
| 955 | |
| 956 | if( !tr_torrentSetAnnounceList( tor, trackers, trackerCount ) ) |
| 957 | errmsg = "big bad error!"; |
| 958 | |
| 959 | for( i = 0; i < trackerCount; ++i ) |
| 960 | tr_free( trackers[i].announce ); |
| 961 | tr_free( trackers ); |
| 962 | } |
| 963 | else |
| 964 | errmsg = "tracker doesn't exists"; |
| 965 | |
| 966 | return errmsg; |
| 967 | } |
| 968 | |