Changeset 3463
- Timestamp:
- Oct 19, 2007, 12:19:16 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/clients.c
r3462 r3463 25 25 #include <ctype.h> /* isprint */ 26 26 #include <stdio.h> 27 #include <stdlib.h> /* bsearch */28 27 #include <string.h> 29 30 #include <sys/types.h> /* event.h needs this */31 #include <event.h>32 28 33 29 #include "transmission.h" 34 30 #include "trcompat.h" 35 #include "utils.h" /* tr_strdup */36 31 37 32 static int charToInt( char character ) … … 48 43 } 49 44 50 /* 51 * Azureus-style uses the following encoding: '-', two characters for client id, 52 * four ascii digits for version number, '-', followed by random numbers. 53 * For example: '-AZ2060-'... 54 */ 55 56 struct az_client 57 { 58 const char * abbreviation; 59 int version_width[4]; 60 const char * name; 61 }; 62 63 static struct az_client azureus_clients[] = 64 { 65 { "AG", { 1, 1, 1, 0 }, "Ares" }, 66 { "AR", { -1, -1, -1, -1 }, "Arctic Torrent" }, 67 { "AV", { -1, -1, -1, -1 }, "Avicora" }, 68 { "AX", { 2, 2, 0, 0 }, "BitPump" }, 69 { "AZ", { 1, 1, 1, 1 }, "Azureus" }, 70 { "A~", { 1, 1, 1, 0 }, "Ares" }, 71 { "BB", { 1, 3, 0, 0 }, "BitBuddy" }, 72 { "BC", { 2, 2, 0, 0 }, "BitComet" }, 73 { "BF", { -1, -1, -1, -1 }, "Bitflu" }, 74 { "BG", { 1, 1, 1, 1 }, "BTG" }, 75 { "BR", { 1, 1, 2, 0 }, "BitRocket" }, 76 { "BS", { -1, -1, -1, -1 }, "BTSlave" }, 77 { "BX", { -1, -1, -1, -1 }, "Bittorrent X" }, 78 { "CD", { 2, 2, 0, 0 }, "Enhanced CTorrent" }, 79 { "CT", { 1, 1, 2, 0 }, "CTorrent" }, 80 { "DE", { 1, 1, 1, 1 }, "DelugeTorrent" }, 81 { "DP", { -1, -1, -1, -1 }, "Propagate" }, 82 { "EB", { -1, -1, -1, -1 }, "EBit" }, 83 { "ES", { 1, 1, 1, 1 }, "Electric Sheep" }, 84 { "FT", { 4, 0, 0, 0 }, "FoxTorrent" }, 85 { "GR", { 1, 1, 1, 1 }, "GetRight" }, 86 { "GS", { 4, 0, 0, 0 }, "GSTorrent" }, 87 { "HL", { 1, 1, 1, 0 }, "Halite" }, 88 { "HN", { -1, -1, -1, -1 }, "Hydranode" }, 89 { "KT", { 1, 1, 1, 0 }, "KTorrent" }, 90 { "LH", { -1, -1, -1, -1 }, "LH-ABC" }, 91 { "LK", { -1, -1, -1, -1 }, "Linkage" }, 92 { "LP", { 2, 2, 0, 0 }, "Lphant" }, 93 { "LT", { 1, 1, 1, 1 }, "Libtorrent" }, 94 { "LW", { -1, -1, -1, -1 }, "LimeWire" }, 95 { "ML", { -1, -1, -1, -1 }, "MLDonkey" }, 96 { "MO", { -1, -1, -1, -1 }, "MonoTorrent" }, 97 { "MP", { -1, -1, -1, -1 }, "MooPolice" }, 98 { "MT", { -1, -1, -1, -1 }, "MoonlightTorrent" }, 99 { "PD", { 1, 1, 1, 1 }, "Pando" }, 100 { "QD", { -1, -1, -1, -1 }, "QQDownload" }, 101 { "QT", { -1, -1, -1, -1 }, "Qt 4 Torrent Example" }, 102 { "RT", { -1, -1, -1, -1 }, "Retriever" }, 103 { "SB", { -1, -1, -1, -1 }, "Swiftbit" }, 104 { "SN", { -1, -1, -1, -1 }, "ShareNet" }, 105 { "SS", { -1, -1, -1, -1 }, "SwarmScope" }, 106 { "ST", { -1, -1, -1, -1 }, "SymTorrent" }, 107 { "SZ", { 1, 1, 1, 1 }, "Shareaza" }, 108 { "S~", { 1, 1, 1, 1 }, "Shareaza (beta)" }, 109 { "TN", { -1, -1, -1, -1 }, "Torrent.Net" }, 110 { "TR", { 1, 2, 1, 0 }, "Transmission" }, 111 { "TS", { 1, 1, 1, 1 }, "TorrentStorm" }, 112 { "TT", { 1, 1, 1, 1 }, "TuoTu" }, 113 { "UL", { -1, -1, -1, -1 }, "uLeecher" }, 114 { "UT", { 1, 2, 0, 0 }, "uTorrent" }, 115 { "WT", { -1, -1, -1, -1 }, "BitLet" }, 116 { "WY", { -1, -1, -1, -1 }, "FireTorrent" }, 117 { "XL", { -1, -1, -1, -1 }, "Xunlei" }, 118 { "XT", { -1, -1, -1, -1 }, "XanTorrent" }, 119 { "XX", { 1, 1, 2, 0 }, "Xtorrent" }, 120 { "ZT", { -1, -1, -1, -1 }, "ZipTorrent" }, 121 { "lt", { 1, 1, 1, 1 }, "libTorrent" }, 122 { "qB", { 1, 1, 1, 0 }, "qBittorrent" }, 123 { "st", { -1, -1, -1, -1 }, "sharktorrent" } 124 }; 125 126 static int 127 isStyleAzureus( const uint8_t * id ) 128 { 129 return id[0]=='-' && id[7]=='-'; 130 } 131 132 static char* 133 getAzureusAbbreviation( const uint8_t * id, char * setme ) 134 { 135 setme[0] = id[1]; 136 setme[1] = id[2]; 137 setme[2] = '\0'; 138 return setme; 139 } 140 141 static int 142 compareAzureusAbbreviations( const void * va, const void * vb ) 143 { 144 const char * abbreviation = va; 145 const struct az_client * b = vb; 146 return strcmp( abbreviation, b->abbreviation ); 147 } 148 149 static const struct az_client* 150 getAzureusClient( const uint8_t * peer_id ) 151 { 152 const struct az_client * ret = NULL; 153 154 if( isStyleAzureus( peer_id ) ) 155 { 156 char abbreviation[3]; 157 ret = bsearch( getAzureusAbbreviation( peer_id, abbreviation ), 158 azureus_clients, 159 sizeof(azureus_clients) / sizeof(azureus_clients[0]), 160 sizeof(struct az_client), 161 compareAzureusAbbreviations ); 162 } 163 164 return ret; 165 } 166 167 168 struct generic_client 169 { 170 int offset; 171 char const * id; 172 char const * name; 173 }; 174 175 static struct generic_client generic_clients[] = 176 { 177 { 0, "346-", "TorrentTopia" }, 178 { 0, "10-------", "JVtorrent" }, 179 { 0, "Deadman Walking-", "Deadman" }, 180 { 5, "Azureus", "Azureus 2.0.3.2" }, 181 { 0, "DansClient", "XanTorrent" }, 182 { 4, "btfans", "SimpleBT" }, 183 { 0, "eX", "eXeem" }, 184 { 0, "PRC.P---", "Bittorrent Plus! II" }, 185 { 0, "P87.P---", "Bittorrent Plus!" }, 186 { 0, "S587Plus", "Bittorrent Plus!" }, 187 { 0, "martini", "Martini Man" }, 188 { 0, "Plus---", "Bittorrent Plus" }, 189 { 0, "turbobt", "TurboBT" }, 190 { 0, "a00---0", "Swarmy" }, 191 { 0, "a02---0", "Swarmy" }, 192 { 0, "T00---0", "Teeweety" }, 193 { 0, "BTDWV-", "Deadman Walking" }, 194 { 2, "BS", "BitSpirit" }, 195 { 0, "Pando-", "Pando" }, 196 { 0, "LIME", "LimeWire" }, 197 { 0, "btuga", "BTugaXP" }, 198 { 0, "oernu", "BTugaXP" }, 199 { 0, "Mbrst", "Burst!" }, 200 { 0, "PEERAPP", "PeerApp" }, 201 { 0, "Plus", "Plus!" }, 202 { 0, "-Qt-", "Qt" }, 203 { 0, "exbc", "BitComet" }, 204 { 0, "DNA", "BitTorrent DNA" }, 205 { 0, "-G3", "G3 Torrent" }, 206 { 0, "-FG", "FlashGet" }, 207 { 0, "-ML", "MLdonkey" }, 208 { 0, "XBT", "XBT" }, 209 { 0, "OP", "Opera" }, 210 { 2, "RS", "Rufus" } 211 }; 212 213 /*** 214 **** 215 ***/ 216 217 char* 218 tr_clientForId( const uint8_t * id ) 45 char * tr_clientForId( const uint8_t * id ) 219 46 { 220 47 char * ret = NULL; 221 48 222 if( isStyleAzureus( id ) ) 223 { 224 const struct az_client * client = getAzureusClient( id ); 225 226 if( client != NULL ) 227 { 228 struct evbuffer * buf = evbuffer_new( ); 229 230 evbuffer_add_printf( buf, "%s ", client->name ); 231 232 if( client->version_width[0] == -1 ) 233 evbuffer_add( buf, id+3, 4 ); 234 else { 235 int i, offset; 236 for( i=0, offset=3; i<4; ++i ) { 237 const int width = client->version_width[i]; 238 const int isdigit = isdigit( id[offset] ); 239 if( !width ) 240 break; 241 if( offset!=3 ) 242 evbuffer_add( buf, (isdigit?".":" "), 1 ); 243 if( !isdigit || width==1 || offset!=3 ) 244 evbuffer_add( buf, id+offset, width ); 245 else{ 246 char * tmp = tr_strndup( (char*)(id+offset), width ); 247 evbuffer_add_printf( buf, "%d", atoi(tmp) ); 248 tr_free( tmp ); 249 } 250 offset += width; 251 } 252 } 253 254 evbuffer_add( buf, "\0", 1 ); 255 ret = tr_strdup( (char*) EVBUFFER_DATA( buf ) ); 256 evbuffer_free( buf ); 49 /* Azureus-style */ 50 if( id[0] == '-' && id[7] == '-' ) 51 { 52 if( !memcmp( &id[1], "TR", 2 ) ) 53 { 54 /* support old-style Transmission id without maintenance number */ 55 if ( !memcmp( &id[3], "00", 2 ) ) 56 { 57 asprintf( &ret, "Transmission 0.%d", 58 charToInt( id[5] ) * 10 + charToInt( id[6] ) ); 59 } 60 else 61 { 62 asprintf( &ret, "Transmission %d.%c%c%s", 63 charToInt( id[3] ), id[4], id[5], 64 id[6] == 'Z' ? "+" : "" ); 65 } 66 } 67 else if( !memcmp( &id[1], "AZ", 2 ) ) 68 { 69 asprintf( &ret, "Azureus %c.%c.%c.%c", 70 id[3], id[4], id[5], id[6] ); 71 } 72 else if( !memcmp( &id[1], "UT", 2 ) ) 73 { 74 asprintf( &ret, "\xc2\xb5Torrent %c.%d", id[3], 75 charToInt( id[4] ) * 10 + charToInt( id[5] ) ); 76 } 77 else if( !memcmp( &id[1], "BC", 2 ) ) 78 { 79 asprintf( &ret, "BitComet %d.%c%c", 80 charToInt( id[3] ) * 10 + charToInt( id[4] ), 81 id[5], id[6] ); 82 } 83 else if( !memcmp( &id[1], "SZ", 2 ) || !memcmp( &id[1], "S~", 2 ) ) 84 { 85 asprintf( &ret, "Shareaza %c.%c.%c.%c", 86 id[3], id[4], id[5], id[6] ); 87 } 88 else if( !memcmp( &id[1], "BOW", 3 ) ) 89 { 90 if( !memcmp( &id[4], "A0C", 3 ) ) 91 { 92 asprintf( &ret, "Bits on Wheels 1.0.6" ); 93 } 94 else if( !memcmp( &id[4], "A0B", 3 ) ) 95 { 96 asprintf( &ret, "Bits on Wheels 1.0.5" ); 97 } 98 else 99 { 100 asprintf( &ret, "Bits on Wheels (%c%c%c)", 101 id[4], id[5], id[6] ); 102 } 103 } 104 else if( !memcmp( &id[1], "BR", 2 ) ) 105 { 106 asprintf( &ret, "BitRocket %c.%c (%d)", 107 id[3], id[4], charToInt( id[5] ) * 10 + charToInt( id[6] ) ); 108 } 109 else if( !memcmp( &id[1], "XX", 2 ) ) 110 { 111 asprintf( &ret, "Xtorrent %c.%c (%d)", 112 id[3], id[4], charToInt( id[5] ) * 10 + charToInt( id[6] ) ); 113 } 114 else if( !memcmp( &id[1], "TS", 2 ) ) 115 { 116 asprintf( &ret, "TorrentStorm %c.%c.%c.%c", 117 id[3], id[4], id[5], id[6] ); 118 } 119 else if( !memcmp( &id[1], "KT", 2 ) ) 120 { 121 if( id[5] == 'R' ) 122 { 123 asprintf( &ret, "KTorrent %c.%c RC %c", 124 id[3], id[4], id[6] ); 125 } 126 else if( id[5] == 'D' ) 127 { 128 asprintf( &ret, "KTorrent %c.%c Dev", 129 id[3], id[4] ); 130 } 131 else 132 { 133 asprintf( &ret, "KTorrent %c.%c.%c", 134 id[3], id[4], id[5] ); 135 } 136 } 137 else if( !memcmp( &id[1], "lt", 2 ) ) 138 { 139 asprintf( &ret, "libTorrent %d.%d.%d.%d", 140 charToInt( id[3] ), charToInt( id[4] ), 141 charToInt( id[5] ), charToInt( id[6] ) ); 142 } 143 else if( !memcmp( &id[1], "LT", 2 ) ) 144 { 145 asprintf( &ret, "libtorrent %d.%d.%d.%d", 146 charToInt( id[3] ), charToInt( id[4] ), 147 charToInt( id[5] ), charToInt( id[6] ) ); 148 } 149 else if( !memcmp( &id[1], "TT", 2 ) ) 150 { 151 asprintf( &ret, "TuoTu %c.%c.%c", 152 id[3], id[4], id[5] ); 153 } 154 else if( !memcmp( &id[1], "ES", 2 ) ) 155 { 156 asprintf( &ret, "Electric Sheep %c.%c.%c", 157 id[3], id[4], id[5] ); 158 } 159 else if( !memcmp( &id[1], "CD", 2 ) ) 160 { 161 asprintf( &ret, "Enhanced CTorrent %d.%d", 162 charToInt( id[3] ) * 10 + charToInt( id[4] ), 163 charToInt( id[5] ) * 10 + charToInt( id[6] ) ); 164 } 165 else if( !memcmp( &id[1], "CT", 2 ) ) 166 { 167 asprintf( &ret, "CTorrent %c.%c.%d", 168 id[3], id[4], 169 charToInt( id[5] ) * 10 + charToInt( id[6] ) ); 170 } 171 else if( !memcmp( &id[1], "LP", 2 ) ) 172 { 173 asprintf( &ret, "Lphant %d.%c%c", 174 charToInt( id[3] ) * 10 + charToInt( id[4] ), 175 id[5], id[6] ); 176 } 177 else if( !memcmp( &id[1], "AX", 2 ) ) 178 { 179 asprintf( &ret, "BitPump %d.%c%c", 180 charToInt( id[3] ) * 10 + charToInt( id[4] ), 181 id[5], id[6] ); 182 } 183 else if( !memcmp( &id[1], "DE", 2 ) ) 184 { 185 asprintf( &ret, "Deluge %d.%d.%d", 186 charToInt( id[3] ), charToInt( id[4] ), 187 charToInt( id[5] ) ); 188 } 189 else if( !memcmp( &id[1], "AG", 2 ) ) 190 { 191 asprintf( &ret, "Ares Galaxy %d.%d.%d", 192 charToInt( id[3] ), charToInt( id[4] ), 193 charToInt( id[5] ) ); 194 } 195 else if( !memcmp( &id[1], "HL", 2 ) ) 196 { 197 asprintf( &ret, "Halite %d.%d.%d", 198 charToInt( id[3] ), charToInt( id[4] ), 199 charToInt( id[5] ) ); 200 } 201 else if( !memcmp( &id[1], "AR", 2 ) ) 202 { 203 asprintf( &ret, "Arctic Torrent" ); 204 } 205 else if( !memcmp( &id[1], "BG", 2 ) ) 206 { 207 asprintf( &ret, "BTG %c.%c.%c.%c", 208 id[3], id[4], id[5], id[6] ); 209 } 210 else if( !memcmp( &id[1], "BB", 2 ) ) 211 { 212 asprintf( &ret, "BitBuddy %c.%c%c%c", 213 id[3], id[4], id[5], id[6] ); 214 } 215 else if( !memcmp( &id[1], "qB", 2 ) ) 216 { 217 asprintf( &ret, "qBittorrent %d.%d.%d", 218 charToInt( id[3] ), charToInt( id[4] ), 219 charToInt( id[5] ) ); 257 220 } 258 221 else if( !memcmp( &id[1], "BF", 2 ) ) … … 263 226 charToInt( id[3] ) ); 264 227 } 265 else if( !memcmp( &id[1], "BOW", 3 ) ) 266 { 267 if( !memcmp( &id[4], "A0C", 3 ) ) 268 asprintf( &ret, "Bits on Wheels 1.0.6" ); 269 else if( !memcmp( &id[4], "A0B", 3 ) ) 270 asprintf( &ret, "Bits on Wheels 1.0.5" ); 271 else 272 asprintf( &ret, "Bits on Wheels (%3.3s", id+4 ); 273 } 228 else if( !memcmp( &id[1], "FT", 2 ) ) 229 { 230 asprintf( &ret, "FoxTorrent (%c%c%c%c)", 231 id[3], id[4], id[5], id[6] ); 232 } 233 else if( !memcmp( &id[1], "GR", 2 ) ) 234 { 235 asprintf( &ret, "GetRight %c.%c.%c.%c", 236 id[3], id[4], id[5], id[6] ); 237 } 238 else if( !memcmp( &id[1], "PD", 2 ) ) 239 { 240 asprintf( &ret, "Pando %c.%c.%c.%c", 241 id[3], id[4], id[5], id[6] ); 242 } 243 else if( !memcmp( &id[1], "LW", 2 ) ) 244 { 245 asprintf( &ret, "LimeWire" ); 246 } 247 274 248 if( ret ) 275 249 { 276 fprintf( stderr, "peer_id [%8.8s] returns [%s]\n", id, ret );277 250 return ret; 278 251 } 279 }280 281 /* generic clients */282 {283 int i;284 const int n = sizeof(generic_clients) / sizeof(generic_clients[0]);285 for( i=0; !ret && i<n; ++i ) {286 const struct generic_client * client = &generic_clients[i];287 if( !memcmp( id+client->offset, client->id, strlen(client->id) ) )288 ret = tr_strdup( client->name );289 }290 291 if( ret )292 return ret;293 252 } 294 253 … … 414 373 asprintf( &ret, "Blizzard Downloader %d.%d", id[3] + 1, id[4] ); 415 374 } 375 else if( !memcmp( id, "-WT-", 4 ) ) 376 { 377 asprintf( &ret, "BitLet" ); 378 } 379 else if( !memcmp( id, "LIME", 4 ) ) 380 { 381 asprintf( &ret, "LimeWire" ); 382 } 383 else if( !memcmp( id, "-G3", 3 ) ) 384 { 385 asprintf( &ret, "G3 Torrent" ); 386 } 387 else if( !memcmp( id, "10-------", 9 ) ) 388 { 389 asprintf( &ret, "JVtorrent" ); 390 } 391 else if( !memcmp( id, "346-", 4 ) ) 392 { 393 asprintf( &ret, "TorrentTopia" ); 394 } 395 else if( !memcmp( id, "eX", 2 ) ) 396 { 397 asprintf( &ret, "eXeem" ); 398 } 416 399 else if( '\0' == id[0] && !memcmp( &id[1], "BS", 2 ) ) 417 400 {
Note: See TracChangeset
for help on using the changeset viewer.