diff --git a/libtransmission/bandwidth.c b/libtransmission/bandwidth.c index 91ce91e67..0e28d32a8 100644 --- a/libtransmission/bandwidth.c +++ b/libtransmission/bandwidth.c @@ -21,10 +21,12 @@ #include "utils.h" #define dbgmsg(...) \ - do { \ - if (tr_deepLoggingIsActive ()) \ - tr_deepLog (__FILE__, __LINE__, NULL, __VA_ARGS__); \ - } while (0) + do \ + { \ + if (tr_deepLoggingIsActive ()) \ + tr_deepLog (__FILE__, __LINE__, NULL, __VA_ARGS__); \ + } \ + while (0) /*** **** @@ -33,48 +35,54 @@ static unsigned int getSpeed_Bps (const struct bratecontrol * r, unsigned int interval_msec, uint64_t now) { - if (!now) - now = tr_time_msec (); + if (!now) + now = tr_time_msec (); - if (now != r->cache_time) + if (now != r->cache_time) { - int i = r->newest; - uint64_t bytes = 0; - const uint64_t cutoff = now - interval_msec; - struct bratecontrol * rvolatile = (struct bratecontrol*) r; + int i = r->newest; + uint64_t bytes = 0; + const uint64_t cutoff = now - interval_msec; + struct bratecontrol * rvolatile = (struct bratecontrol*) r; - for (;;) + for (;;) { - if (r->transfers[i].date <= cutoff) - break; + if (r->transfers[i].date <= cutoff) + break; - bytes += r->transfers[i].size; + bytes += r->transfers[i].size; - if (--i == -1) i = HISTORY_SIZE - 1; /* circular history */ - if (i == r->newest) break; /* we've come all the way around */ + if (--i == -1) + i = HISTORY_SIZE - 1; /* circular history */ + + if (i == r->newest) + break; /* we've come all the way around */ } - rvolatile->cache_val = (unsigned int)((bytes * 1000u) / interval_msec); - rvolatile->cache_time = now; + rvolatile->cache_val = (unsigned int)((bytes * 1000u) / interval_msec); + rvolatile->cache_time = now; } - return r->cache_val; + return r->cache_val; } static void bytesUsed (const uint64_t now, struct bratecontrol * r, size_t size) { - if (r->transfers[r->newest].date + GRANULARITY_MSEC >= now) - r->transfers[r->newest].size += size; - else + if (r->transfers[r->newest].date + GRANULARITY_MSEC >= now) { - if (++r->newest == HISTORY_SIZE) r->newest = 0; - r->transfers[r->newest].date = now; - r->transfers[r->newest].size = size; + r->transfers[r->newest].size += size; + } + else + { + if (++r->newest == HISTORY_SIZE) + r->newest = 0; + r->transfers[r->newest].date = now; + r->transfers[r->newest].size = size; } - /* invalidate cache_val*/ - r->cache_time = 0; + /* invalidate cache_val*/ + r->cache_time = 0; } /****** @@ -85,9 +93,9 @@ bytesUsed (const uint64_t now, struct bratecontrol * r, size_t size) static int compareBandwidth (const void * va, const void * vb) { - const tr_bandwidth * a = va; - const tr_bandwidth * b = vb; - return a->uniqueKey - b->uniqueKey; + const tr_bandwidth * a = va; + const tr_bandwidth * b = vb; + return a->uniqueKey - b->uniqueKey; } /*** @@ -97,26 +105,26 @@ compareBandwidth (const void * va, const void * vb) void tr_bandwidthConstruct (tr_bandwidth * b, tr_session * session, tr_bandwidth * parent) { - static unsigned int uniqueKey = 0; + static unsigned int uniqueKey = 0; - b->session = session; - b->children = TR_PTR_ARRAY_INIT; - b->magicNumber = BANDWIDTH_MAGIC_NUMBER; - b->uniqueKey = uniqueKey++; - b->band[TR_UP].honorParentLimits = true; - b->band[TR_DOWN].honorParentLimits = true; - tr_bandwidthSetParent (b, parent); + b->session = session; + b->children = TR_PTR_ARRAY_INIT; + b->magicNumber = BANDWIDTH_MAGIC_NUMBER; + b->uniqueKey = uniqueKey++; + b->band[TR_UP].honorParentLimits = true; + b->band[TR_DOWN].honorParentLimits = true; + tr_bandwidthSetParent (b, parent); } void tr_bandwidthDestruct (tr_bandwidth * b) { - assert (tr_isBandwidth (b)); + assert (tr_isBandwidth (b)); - tr_bandwidthSetParent (b, NULL); - tr_ptrArrayDestruct (&b->children, NULL); + tr_bandwidthSetParent (b, NULL); + tr_ptrArrayDestruct (&b->children, NULL); - memset (b, ~0, sizeof (tr_bandwidth)); + memset (b, ~0, sizeof (tr_bandwidth)); } /*** @@ -127,31 +135,31 @@ void tr_bandwidthSetParent (tr_bandwidth * b, tr_bandwidth * parent) { - assert (tr_isBandwidth (b)); - assert (b != parent); + assert (tr_isBandwidth (b)); + assert (b != parent); - if (b->parent) + if (b->parent) { - void * removed; + void * removed; - assert (tr_isBandwidth (b->parent)); + assert (tr_isBandwidth (b->parent)); - removed = tr_ptrArrayRemoveSorted (&b->parent->children, b, compareBandwidth); - assert (removed == b); - assert (tr_ptrArrayFindSorted (&b->parent->children, b, compareBandwidth) == NULL); + removed = tr_ptrArrayRemoveSorted (&b->parent->children, b, compareBandwidth); + assert (removed == b); + assert (tr_ptrArrayFindSorted (&b->parent->children, b, compareBandwidth) == NULL); - b->parent = NULL; + b->parent = NULL; } - if (parent) + if (parent) { - assert (tr_isBandwidth (parent)); - assert (parent->parent != b); + assert (tr_isBandwidth (parent)); + assert (parent->parent != b); - assert (tr_ptrArrayFindSorted (&parent->children, b, compareBandwidth) == NULL); - tr_ptrArrayInsertSorted (&parent->children, b, compareBandwidth); - assert (tr_ptrArrayFindSorted (&parent->children, b, compareBandwidth) == b); - b->parent = parent; + assert (tr_ptrArrayFindSorted (&parent->children, b, compareBandwidth) == NULL); + tr_ptrArrayInsertSorted (&parent->children, b, compareBandwidth); + assert (tr_ptrArrayFindSorted (&parent->children, b, compareBandwidth) == b); + b->parent = parent; } } @@ -166,66 +174,69 @@ allocateBandwidth (tr_bandwidth * b, unsigned int period_msec, tr_ptrArray * peer_pool) { - const tr_priority_t priority = MAX (parent_priority, b->priority); + const tr_priority_t priority = MAX (parent_priority, b->priority); - assert (tr_isBandwidth (b)); - assert (tr_isDirection (dir)); + assert (tr_isBandwidth (b)); + assert (tr_isDirection (dir)); - /* set the available bandwidth */ - if (b->band[dir].isLimited) + /* set the available bandwidth */ + if (b->band[dir].isLimited) { - const uint64_t nextPulseSpeed = b->band[dir].desiredSpeed_Bps; - b->band[dir].bytesLeft = (unsigned int)(nextPulseSpeed * period_msec) / 1000u; + const uint64_t nextPulseSpeed = b->band[dir].desiredSpeed_Bps; + b->band[dir].bytesLeft = (unsigned int)(nextPulseSpeed * period_msec) / 1000u; } - /* add this bandwidth's peer, if any, to the peer pool */ - if (b->peer != NULL) { - b->peer->priority = priority; - tr_ptrArrayAppend (peer_pool, b->peer); + /* add this bandwidth's peer, if any, to the peer pool */ + if (b->peer != NULL) + { + b->peer->priority = priority; + tr_ptrArrayAppend (peer_pool, b->peer); } - /* traverse & repeat for the subtree */ - if (1) { - int i; - struct tr_bandwidth ** children = (struct tr_bandwidth**) tr_ptrArrayBase (&b->children); - const int n = tr_ptrArraySize (&b->children); - for (i=0; ichildren); + const int n = tr_ptrArraySize (&b->children); + for (i=0; i 0) + /* First phase of IO. Tries to distribute bandwidth fairly to keep faster + * peers from starving the others. Loop through the peers, giving each a + * small chunk of bandwidth. Keep looping until we run out of bandwidth + * and/or peers that can use it */ + n = peerCount; + dbgmsg ("%d peers to go round-robin for %s", n, (dir==TR_UP?"upload":"download")); + while (n > 0) { - const int i = tr_cryptoWeakRandInt (n); /* pick a peer at random */ + const int i = tr_cryptoWeakRandInt (n); /* pick a peer at random */ - /* value of 3000 bytes chosen so that when using uTP we'll send a full-size - * frame right away and leave enough buffered data for the next frame to go - * out in a timely manner. */ - const size_t increment = 3000; + /* value of 3000 bytes chosen so that when using uTP we'll send a full-size + * frame right away and leave enough buffered data for the next frame to go + * out in a timely manner. */ + const size_t increment = 3000; - const int bytesUsed = tr_peerIoFlush (peers[i], dir, increment); + const int bytesUsed = tr_peerIoFlush (peers[i], dir, increment); - dbgmsg ("peer #%d of %d used %d bytes in this pass", i, n, bytesUsed); + dbgmsg ("peer #%d of %d used %d bytes in this pass", i, n, bytesUsed); - if (bytesUsed != (int)increment) { - /* peer is done writing for now; move it to the end of the list */ - tr_peerIo * pio = peers[i]; - peers[i] = peers[n-1]; - peers[n-1] = pio; - --n; + if (bytesUsed != (int)increment) + { + /* peer is done writing for now; move it to the end of the list */ + tr_peerIo * pio = peers[i]; + peers[i] = peers[n-1]; + peers[n-1] = pio; + --n; } } } @@ -235,66 +246,67 @@ tr_bandwidthAllocate (tr_bandwidth * b, tr_direction dir, unsigned int period_msec) { - int i, peerCount; - tr_ptrArray tmp = TR_PTR_ARRAY_INIT; - tr_ptrArray low = TR_PTR_ARRAY_INIT; - tr_ptrArray high = TR_PTR_ARRAY_INIT; - tr_ptrArray normal = TR_PTR_ARRAY_INIT; - struct tr_peerIo ** peers; + int i, peerCount; + tr_ptrArray tmp = TR_PTR_ARRAY_INIT; + tr_ptrArray low = TR_PTR_ARRAY_INIT; + tr_ptrArray high = TR_PTR_ARRAY_INIT; + tr_ptrArray normal = TR_PTR_ARRAY_INIT; + struct tr_peerIo ** peers; - /* allocateBandwidth () is a helper function with two purposes: - * 1. allocate bandwidth to b and its subtree - * 2. accumulate an array of all the peerIos from b and its subtree. */ - allocateBandwidth (b, TR_PRI_LOW, dir, period_msec, &tmp); - peers = (struct tr_peerIo**) tr_ptrArrayBase (&tmp); - peerCount = tr_ptrArraySize (&tmp); + /* allocateBandwidth () is a helper function with two purposes: + * 1. allocate bandwidth to b and its subtree + * 2. accumulate an array of all the peerIos from b and its subtree. */ + allocateBandwidth (b, TR_PRI_LOW, dir, period_msec, &tmp); + peers = (struct tr_peerIo**) tr_ptrArrayBase (&tmp); + peerCount = tr_ptrArraySize (&tmp); - for (i=0; ipriority) { - case TR_PRI_HIGH: tr_ptrArrayAppend (&high, io); /* fall through */ - case TR_PRI_NORMAL: tr_ptrArrayAppend (&normal, io); /* fall through */ - default: tr_ptrArrayAppend (&low, io); + switch (io->priority) + { + case TR_PRI_HIGH: tr_ptrArrayAppend (&high, io); /* fall through */ + case TR_PRI_NORMAL: tr_ptrArrayAppend (&normal, io); /* fall through */ + default: tr_ptrArrayAppend (&low, io); } } - /* First phase of IO. Tries to distribute bandwidth fairly to keep faster - * peers from starving the others. Loop through the peers, giving each a - * small chunk of bandwidth. Keep looping until we run out of bandwidth - * and/or peers that can use it */ - phaseOne (&high, dir); - phaseOne (&normal, dir); - phaseOne (&low, dir); + /* First phase of IO. Tries to distribute bandwidth fairly to keep faster + * peers from starving the others. Loop through the peers, giving each a + * small chunk of bandwidth. Keep looping until we run out of bandwidth + * and/or peers that can use it */ + phaseOne (&high, dir); + phaseOne (&normal, dir); + phaseOne (&low, dir); - /* Second phase of IO. To help us scale in high bandwidth situations, - * enable on-demand IO for peers with bandwidth left to burn. - * This on-demand IO is enabled until (1) the peer runs out of bandwidth, - * or (2) the next tr_bandwidthAllocate () call, when we start over again. */ - for (i=0; ipeer = peer; + b->peer = peer; } /*** @@ -307,85 +319,85 @@ bandwidthClamp (const tr_bandwidth * b, tr_direction dir, unsigned int byteCount) { - assert (tr_isBandwidth (b)); - assert (tr_isDirection (dir)); + assert (tr_isBandwidth (b)); + assert (tr_isDirection (dir)); - if (b) + if (b) { - if (b->band[dir].isLimited) + if (b->band[dir].isLimited) { - byteCount = MIN (byteCount, b->band[dir].bytesLeft); + byteCount = MIN (byteCount, b->band[dir].bytesLeft); - /* if we're getting close to exceeding the speed limit, - * clamp down harder on the bytes available */ - if (byteCount > 0) + /* if we're getting close to exceeding the speed limit, + * clamp down harder on the bytes available */ + if (byteCount > 0) { - double current; - double desired; - double r; + double current; + double desired; + double r; - if (now == 0) - now = tr_time_msec (); + if (now == 0) + now = tr_time_msec (); - current = tr_bandwidthGetRawSpeed_Bps (b, now, TR_DOWN); - desired = tr_bandwidthGetDesiredSpeed_Bps (b, TR_DOWN); - r = desired >= 1 ? current / desired : 0; + current = tr_bandwidthGetRawSpeed_Bps (b, now, TR_DOWN); + desired = tr_bandwidthGetDesiredSpeed_Bps (b, TR_DOWN); + r = desired >= 1 ? current / desired : 0; - if (r > 1.0) byteCount = 0; - else if (r > 0.9) byteCount *= 0.8; - else if (r > 0.8) byteCount *= 0.9; + if (r > 1.0) byteCount = 0; + else if (r > 0.9) byteCount *= 0.8; + else if (r > 0.8) byteCount *= 0.9; } } - if (b->parent && b->band[dir].honorParentLimits && (byteCount > 0)) - byteCount = bandwidthClamp (b->parent, now, dir, byteCount); + if (b->parent && b->band[dir].honorParentLimits && (byteCount > 0)) + byteCount = bandwidthClamp (b->parent, now, dir, byteCount); } - return byteCount; + return byteCount; } unsigned int tr_bandwidthClamp (const tr_bandwidth * b, tr_direction dir, unsigned int byteCount) { - return bandwidthClamp (b, 0, dir, byteCount); + return bandwidthClamp (b, 0, dir, byteCount); } unsigned int tr_bandwidthGetRawSpeed_Bps (const tr_bandwidth * b, const uint64_t now, const tr_direction dir) { - assert (tr_isBandwidth (b)); - assert (tr_isDirection (dir)); + assert (tr_isBandwidth (b)); + assert (tr_isDirection (dir)); - return getSpeed_Bps (&b->band[dir].raw, HISTORY_MSEC, now); + return getSpeed_Bps (&b->band[dir].raw, HISTORY_MSEC, now); } unsigned int tr_bandwidthGetPieceSpeed_Bps (const tr_bandwidth * b, const uint64_t now, const tr_direction dir) { - assert (tr_isBandwidth (b)); - assert (tr_isDirection (dir)); + assert (tr_isBandwidth (b)); + assert (tr_isDirection (dir)); - return getSpeed_Bps (&b->band[dir].piece, HISTORY_MSEC, now); + return getSpeed_Bps (&b->band[dir].piece, HISTORY_MSEC, now); } void tr_bandwidthUsed (tr_bandwidth * b, tr_direction dir, size_t byteCount, - bool isPieceData, + bool isPieceData, uint64_t now) { - struct tr_band * band; + struct tr_band * band; - assert (tr_isBandwidth (b)); - assert (tr_isDirection (dir)); + assert (tr_isBandwidth (b)); + assert (tr_isDirection (dir)); - band = &b->band[dir]; + band = &b->band[dir]; - if (band->isLimited && isPieceData) - band->bytesLeft -= MIN (band->bytesLeft, byteCount); + if (band->isLimited && isPieceData) + band->bytesLeft -= MIN (band->bytesLeft, byteCount); #ifdef DEBUG_DIRECTION if ((dir == DEBUG_DIRECTION) && (band->isLimited)) @@ -393,11 +405,11 @@ fprintf (stderr, "%p consumed %5zu bytes of %5s data... was %6zu, now %6zu left\ b, byteCount, (isPieceData?"piece":"raw"), oldBytesLeft, band->bytesLeft); #endif - bytesUsed (now, &band->raw, byteCount); + bytesUsed (now, &band->raw, byteCount); - if (isPieceData) - bytesUsed (now, &band->piece, byteCount); + if (isPieceData) + bytesUsed (now, &band->piece, byteCount); - if (b->parent != NULL) - tr_bandwidthUsed (b->parent, dir, byteCount, isPieceData, now); + if (b->parent != NULL) + tr_bandwidthUsed (b->parent, dir, byteCount, isPieceData, now); } diff --git a/libtransmission/crypto.c b/libtransmission/crypto.c index cf4c9af30..f1b76d17d 100644 --- a/libtransmission/crypto.c +++ b/libtransmission/crypto.c @@ -37,19 +37,19 @@ void tr_sha1 (uint8_t * setme, const void * content1, int content1_len, ...) { - va_list vl; - SHA_CTX sha; - const void * content; + va_list vl; + SHA_CTX sha; + const void * content; - SHA1_Init (&sha); - SHA1_Update (&sha, content1, content1_len); + SHA1_Init (&sha); + SHA1_Update (&sha, content1, content1_len); - va_start (vl, content1_len); - while ((content = va_arg (vl, const void*))) - SHA1_Update (&sha, content, va_arg (vl, int)); - va_end (vl); + va_start (vl, content1_len); + while ((content = va_arg (vl, const void*))) + SHA1_Update (&sha, content, va_arg (vl, int)); + va_end (vl); - SHA1_Final (setme, &sha); + SHA1_Final (setme, &sha); } /** @@ -65,14 +65,14 @@ tr_sha1 (uint8_t * setme, const void * content1, int content1_len, ...) static const uint8_t dh_P[PRIME_LEN] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, - 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, - 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, - 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, - 0xA6, 0x3A, 0x36, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x05, 0x63, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, + 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, + 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, + 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, + 0xA6, 0x3A, 0x36, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x05, 0x63, }; static const uint8_t dh_G[] = { 2 }; @@ -82,68 +82,70 @@ static const uint8_t dh_G[] = { 2 }; **/ #define logErrorFromSSL(...) \ - do { \ - if (tr_msgLoggingIsActive (TR_MSG_ERR)) { \ - char buf[512]; \ - ERR_error_string_n (ERR_get_error (), buf, sizeof (buf)); \ - tr_msg (__FILE__, __LINE__, TR_MSG_ERR, MY_NAME, "%s", buf); \ - } \ - } while (0) + do { \ + if (tr_msgLoggingIsActive (TR_MSG_ERR)) { \ + char buf[512]; \ + ERR_error_string_n (ERR_get_error (), buf, sizeof (buf)); \ + tr_msg (__FILE__, __LINE__, TR_MSG_ERR, MY_NAME, "%s", buf); \ + } \ + } while (0) static void ensureKeyExists (tr_crypto * crypto) { - if (crypto->dh == NULL) + if (crypto->dh == NULL) { - int len, offset; - DH * dh = DH_new (); + int len, offset; + DH * dh = DH_new (); - dh->p = BN_bin2bn (dh_P, sizeof (dh_P), NULL); - if (dh->p == NULL) + dh->p = BN_bin2bn (dh_P, sizeof (dh_P), NULL); + if (dh->p == NULL) + logErrorFromSSL (); + + dh->g = BN_bin2bn (dh_G, sizeof (dh_G), NULL); + if (dh->g == NULL) + logErrorFromSSL (); + + /* private DH value: strong random BN of DH_PRIVKEY_LEN*8 bits */ + dh->priv_key = BN_new (); + do + { + if (BN_rand (dh->priv_key, DH_PRIVKEY_LEN * 8, -1, 0) != 1) logErrorFromSSL (); + } + while (BN_num_bits (dh->priv_key) < DH_PRIVKEY_LEN_MIN * 8); - dh->g = BN_bin2bn (dh_G, sizeof (dh_G), NULL); - if (dh->g == NULL) - logErrorFromSSL (); + if (!DH_generate_key (dh)) + logErrorFromSSL (); - /* private DH value: strong random BN of DH_PRIVKEY_LEN*8 bits */ - dh->priv_key = BN_new (); - do { - if (BN_rand (dh->priv_key, DH_PRIVKEY_LEN * 8, -1, 0) != 1) - logErrorFromSSL (); - } while (BN_num_bits (dh->priv_key) < DH_PRIVKEY_LEN_MIN * 8); + /* DH can generate key sizes that are smaller than the size of + P with exponentially decreasing probability, in which case + the msb's of myPublicKey need to be zeroed appropriately. */ + len = BN_num_bytes (dh->pub_key); + offset = KEY_LEN - len; + assert (len <= KEY_LEN); + memset (crypto->myPublicKey, 0, offset); + BN_bn2bin (dh->pub_key, crypto->myPublicKey + offset); - if (!DH_generate_key (dh)) - logErrorFromSSL (); - - /* DH can generate key sizes that are smaller than the size of - P with exponentially decreasing probability, in which case - the msb's of myPublicKey need to be zeroed appropriately. */ - len = BN_num_bytes (dh->pub_key); - offset = KEY_LEN - len; - assert (len <= KEY_LEN); - memset (crypto->myPublicKey, 0, offset); - BN_bn2bin (dh->pub_key, crypto->myPublicKey + offset); - - crypto->dh = dh; + crypto->dh = dh; } } void tr_cryptoConstruct (tr_crypto * crypto, const uint8_t * torrentHash, bool isIncoming) { - memset (crypto, 0, sizeof (tr_crypto)); + memset (crypto, 0, sizeof (tr_crypto)); - crypto->dh = NULL; - crypto->isIncoming = isIncoming; - tr_cryptoSetTorrentHash (crypto, torrentHash); + crypto->dh = NULL; + crypto->isIncoming = isIncoming; + tr_cryptoSetTorrentHash (crypto, torrentHash); } void tr_cryptoDestruct (tr_crypto * crypto) { - if (crypto->dh != NULL) - DH_free (crypto->dh); + if (crypto->dh != NULL) + DH_free (crypto->dh); } /** @@ -154,39 +156,42 @@ const uint8_t* tr_cryptoComputeSecret (tr_crypto * crypto, const uint8_t * peerPublicKey) { - int len; - uint8_t secret[KEY_LEN]; - BIGNUM * bn = BN_bin2bn (peerPublicKey, KEY_LEN, NULL); - DH * dh; + DH * dh; + int len; + uint8_t secret[KEY_LEN]; + BIGNUM * bn = BN_bin2bn (peerPublicKey, KEY_LEN, NULL); - ensureKeyExists (crypto); - dh = crypto->dh; + ensureKeyExists (crypto); + dh = crypto->dh; - assert (DH_size (dh) == KEY_LEN); + assert (DH_size (dh) == KEY_LEN); - len = DH_compute_key (secret, bn, dh); - if (len == -1) - logErrorFromSSL (); - else { - int offset; - assert (len <= KEY_LEN); - offset = KEY_LEN - len; - memset (crypto->mySecret, 0, offset); - memcpy (crypto->mySecret + offset, secret, len); - crypto->mySecretIsSet = 1; + len = DH_compute_key (secret, bn, dh); + if (len == -1) + { + logErrorFromSSL (); + } + else + { + int offset; + assert (len <= KEY_LEN); + offset = KEY_LEN - len; + memset (crypto->mySecret, 0, offset); + memcpy (crypto->mySecret + offset, secret, len); + crypto->mySecretIsSet = 1; } - BN_free (bn); - return crypto->mySecret; + BN_free (bn); + return crypto->mySecret; } const uint8_t* tr_cryptoGetMyPublicKey (const tr_crypto * crypto, - int * setme_len) + int * setme_len) { - ensureKeyExists ((tr_crypto *) crypto); - *setme_len = KEY_LEN; - return crypto->myPublicKey; + ensureKeyExists ((tr_crypto *) crypto); + *setme_len = KEY_LEN; + return crypto->myPublicKey; } /** @@ -194,47 +199,47 @@ tr_cryptoGetMyPublicKey (const tr_crypto * crypto, **/ static void -initRC4 (tr_crypto * crypto, - RC4_KEY * setme, +initRC4 (tr_crypto * crypto, + RC4_KEY * setme, const char * key) { - SHA_CTX sha; - uint8_t buf[SHA_DIGEST_LENGTH]; + SHA_CTX sha; + uint8_t buf[SHA_DIGEST_LENGTH]; - assert (crypto->torrentHashIsSet); - assert (crypto->mySecretIsSet); + assert (crypto->torrentHashIsSet); + assert (crypto->mySecretIsSet); - if (SHA1_Init (&sha) - && SHA1_Update (&sha, key, 4) - && SHA1_Update (&sha, crypto->mySecret, KEY_LEN) - && SHA1_Update (&sha, crypto->torrentHash, SHA_DIGEST_LENGTH) - && SHA1_Final (buf, &sha)) + if (SHA1_Init (&sha) + && SHA1_Update (&sha, key, 4) + && SHA1_Update (&sha, crypto->mySecret, KEY_LEN) + && SHA1_Update (&sha, crypto->torrentHash, SHA_DIGEST_LENGTH) + && SHA1_Final (buf, &sha)) { - RC4_set_key (setme, SHA_DIGEST_LENGTH, buf); + RC4_set_key (setme, SHA_DIGEST_LENGTH, buf); } - else + else { - logErrorFromSSL (); + logErrorFromSSL (); } } void tr_cryptoDecryptInit (tr_crypto * crypto) { - unsigned char discard[1024]; - const char * txt = crypto->isIncoming ? "keyA" : "keyB"; + unsigned char discard[1024]; + const char * txt = crypto->isIncoming ? "keyA" : "keyB"; - initRC4 (crypto, &crypto->dec_key, txt); - RC4 (&crypto->dec_key, sizeof (discard), discard, discard); + initRC4 (crypto, &crypto->dec_key, txt); + RC4 (&crypto->dec_key, sizeof (discard), discard, discard); } void -tr_cryptoDecrypt (tr_crypto * crypto, +tr_cryptoDecrypt (tr_crypto * crypto, size_t buf_len, const void * buf_in, - void * buf_out) + void * buf_out) { - RC4 (&crypto->dec_key, buf_len, + RC4 (&crypto->dec_key, buf_len, (const unsigned char*)buf_in, (unsigned char*)buf_out); } @@ -242,20 +247,20 @@ tr_cryptoDecrypt (tr_crypto * crypto, void tr_cryptoEncryptInit (tr_crypto * crypto) { - unsigned char discard[1024]; - const char * txt = crypto->isIncoming ? "keyB" : "keyA"; + unsigned char discard[1024]; + const char * txt = crypto->isIncoming ? "keyB" : "keyA"; - initRC4 (crypto, &crypto->enc_key, txt); - RC4 (&crypto->enc_key, sizeof (discard), discard, discard); + initRC4 (crypto, &crypto->enc_key, txt); + RC4 (&crypto->enc_key, sizeof (discard), discard, discard); } void -tr_cryptoEncrypt (tr_crypto * crypto, +tr_cryptoEncrypt (tr_crypto * crypto, size_t buf_len, const void * buf_in, - void * buf_out) + void * buf_out) { - RC4 (&crypto->enc_key, buf_len, + RC4 (&crypto->enc_key, buf_len, (const unsigned char*)buf_in, (unsigned char*)buf_out); } @@ -265,75 +270,75 @@ tr_cryptoEncrypt (tr_crypto * crypto, **/ void -tr_cryptoSetTorrentHash (tr_crypto * crypto, +tr_cryptoSetTorrentHash (tr_crypto * crypto, const uint8_t * hash) { - crypto->torrentHashIsSet = hash ? 1 : 0; + crypto->torrentHashIsSet = hash ? 1 : 0; - if (hash) - memcpy (crypto->torrentHash, hash, SHA_DIGEST_LENGTH); - else - memset (crypto->torrentHash, 0, SHA_DIGEST_LENGTH); + if (hash) + memcpy (crypto->torrentHash, hash, SHA_DIGEST_LENGTH); + else + memset (crypto->torrentHash, 0, SHA_DIGEST_LENGTH); } const uint8_t* tr_cryptoGetTorrentHash (const tr_crypto * crypto) { - assert (crypto); - assert (crypto->torrentHashIsSet); + assert (crypto); + assert (crypto->torrentHashIsSet); - return crypto->torrentHash; + return crypto->torrentHash; } int tr_cryptoHasTorrentHash (const tr_crypto * crypto) { - assert (crypto); + assert (crypto); - return crypto->torrentHashIsSet ? 1 : 0; + return crypto->torrentHashIsSet ? 1 : 0; } int tr_cryptoRandInt (int upperBound) { - int noise; - int val; + int noise; + int val; - assert (upperBound > 0); + assert (upperBound > 0); - if (RAND_pseudo_bytes ((unsigned char *) &noise, sizeof noise) >= 0) + if (RAND_pseudo_bytes ((unsigned char *) &noise, sizeof noise) >= 0) { - val = abs (noise) % upperBound; + val = abs (noise) % upperBound; } - else /* fall back to a weaker implementation... */ + else /* fall back to a weaker implementation... */ { - val = tr_cryptoWeakRandInt (upperBound); + val = tr_cryptoWeakRandInt (upperBound); } - return val; + return val; } int tr_cryptoWeakRandInt (int upperBound) { - static bool init = false; + static bool init = false; - assert (upperBound > 0); + assert (upperBound > 0); - if (!init) + if (!init) { - srand (tr_time_msec ()); - init = true; + srand (tr_time_msec ()); + init = true; } - return rand () % upperBound; + return rand () % upperBound; } void tr_cryptoRandBuf (void * buf, size_t len) { - if (RAND_pseudo_bytes ((unsigned char*)buf, len) != 1) - logErrorFromSSL (); + if (RAND_pseudo_bytes ((unsigned char*)buf, len) != 1) + logErrorFromSSL (); } /*** @@ -343,61 +348,60 @@ tr_cryptoRandBuf (void * buf, size_t len) char* tr_ssha1 (const void * plaintext) { - enum { saltval_len = 8, - salter_len = 64 }; - static const char * salter = "0123456789" - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "./"; + enum { saltval_len = 8, + salter_len = 64 }; + static const char * salter = "0123456789" + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "./"; - size_t i; - unsigned char salt[saltval_len]; - uint8_t sha[SHA_DIGEST_LENGTH]; - char buf[2*SHA_DIGEST_LENGTH + saltval_len + 2]; + size_t i; + unsigned char salt[saltval_len]; + uint8_t sha[SHA_DIGEST_LENGTH]; + char buf[2*SHA_DIGEST_LENGTH + saltval_len + 2]; - tr_cryptoRandBuf (salt, saltval_len); - for (i=0; ifromFirst < TR_PEER_FROM__MAX) - && (atom->fromBest < TR_PEER_FROM__MAX) - && (tr_address_is_valid (&atom->addr)); + return (atom != NULL) + && (atom->fromFirst < TR_PEER_FROM__MAX) + && (atom->fromBest < TR_PEER_FROM__MAX) + && (tr_address_is_valid (&atom->addr)); } #endif static const char* tr_atomAddrStr (const struct peer_atom * atom) { - return atom ? tr_peerIoAddrStr (&atom->addr, atom->port) : "[no atom]"; + return atom ? tr_peerIoAddrStr (&atom->addr, atom->port) : "[no atom]"; } struct block_request { - tr_block_index_t block; - tr_peer * peer; - time_t sentAt; + tr_block_index_t block; + tr_peer * peer; + time_t sentAt; }; struct weighted_piece { - tr_piece_index_t index; - int16_t salt; - int16_t requestCount; + tr_piece_index_t index; + int16_t salt; + int16_t requestCount; }; enum piece_sort_state { - PIECES_UNSORTED, - PIECES_SORTED_BY_INDEX, - PIECES_SORTED_BY_WEIGHT + PIECES_UNSORTED, + PIECES_SORTED_BY_INDEX, + PIECES_SORTED_BY_WEIGHT }; /** @brief Opaque, per-torrent data structure for peer connection information */ typedef struct tr_torrent_peers { - tr_ptrArray outgoingHandshakes; /* tr_handshake */ - tr_ptrArray pool; /* struct peer_atom */ - tr_ptrArray peers; /* tr_peer */ - tr_ptrArray webseeds; /* tr_webseed */ + tr_ptrArray outgoingHandshakes; /* tr_handshake */ + tr_ptrArray pool; /* struct peer_atom */ + tr_ptrArray peers; /* tr_peer */ + tr_ptrArray webseeds; /* tr_webseed */ - tr_torrent * tor; - struct tr_peerMgr * manager; + tr_torrent * tor; + struct tr_peerMgr * manager; - tr_peer * optimistic; /* the optimistic peer, or NULL if none */ - int optimisticUnchokeTimeScaler; + tr_peer * optimistic; /* the optimistic peer, or NULL if none */ + int optimisticUnchokeTimeScaler; - bool isRunning; - bool needsCompletenessCheck; + bool isRunning; + bool needsCompletenessCheck; - struct block_request * requests; - int requestCount; - int requestAlloc; + struct block_request * requests; + int requestCount; + int requestAlloc; - struct weighted_piece * pieces; - int pieceCount; - enum piece_sort_state pieceSortState; + struct weighted_piece * pieces; + int pieceCount; + enum piece_sort_state pieceSortState; - /* An array of pieceCount items stating how many peers have each piece. - This is used to help us for downloading pieces "rarest first." - This may be NULL if we don't have metainfo yet, or if we're not - downloading and don't care about rarity */ - uint16_t * pieceReplication; - size_t pieceReplicationSize; + /* An array of pieceCount items stating how many peers have each piece. + This is used to help us for downloading pieces "rarest first." + This may be NULL if we don't have metainfo yet, or if we're not + downloading and don't care about rarity */ + uint16_t * pieceReplication; + size_t pieceReplicationSize; - int interestedCount; - int maxPeers; - time_t lastCancel; + int interestedCount; + int maxPeers; + time_t lastCancel; - /* Before the endgame this should be 0. In endgame, is contains the average - * number of pending requests per peer. Only peers which have more pending - * requests are considered 'fast' are allowed to request a block that's - * already been requested from another (slower?) peer. */ - int endgame; + /* Before the endgame this should be 0. In endgame, is contains the average + * number of pending requests per peer. Only peers which have more pending + * requests are considered 'fast' are allowed to request a block that's + * already been requested from another (slower?) peer. */ + int endgame; } Torrent; struct tr_peerMgr { - tr_session * session; - tr_ptrArray incomingHandshakes; /* tr_handshake */ - struct event * bandwidthTimer; - struct event * rechokeTimer; - struct event * refillUpkeepTimer; - struct event * atomTimer; + tr_session * session; + tr_ptrArray incomingHandshakes; /* tr_handshake */ + struct event * bandwidthTimer; + struct event * rechokeTimer; + struct event * refillUpkeepTimer; + struct event * atomTimer; }; #define tordbg(t, ...) \ @@ -257,31 +257,31 @@ struct tr_peerMgr static inline void managerLock (const struct tr_peerMgr * manager) { - tr_sessionLock (manager->session); + tr_sessionLock (manager->session); } static inline void managerUnlock (const struct tr_peerMgr * manager) { - tr_sessionUnlock (manager->session); + tr_sessionUnlock (manager->session); } static inline void torrentLock (Torrent * torrent) { - managerLock (torrent->manager); + managerLock (torrent->manager); } static inline void torrentUnlock (Torrent * torrent) { - managerUnlock (torrent->manager); + managerUnlock (torrent->manager); } static inline int torrentIsLocked (const Torrent * t) { - return tr_sessionIsLocked (t->manager->session); + return tr_sessionIsLocked (t->manager->session); } /** @@ -291,42 +291,42 @@ torrentIsLocked (const Torrent * t) static int handshakeCompareToAddr (const void * va, const void * vb) { - const tr_handshake * a = va; + const tr_handshake * a = va; - return tr_address_compare (tr_handshakeGetAddr (a, NULL), vb); + return tr_address_compare (tr_handshakeGetAddr (a, NULL), vb); } static int handshakeCompare (const void * a, const void * b) { - return handshakeCompareToAddr (a, tr_handshakeGetAddr (b, NULL)); + return handshakeCompareToAddr (a, tr_handshakeGetAddr (b, NULL)); } static inline tr_handshake* getExistingHandshake (tr_ptrArray * handshakes, const tr_address * addr) { - if (tr_ptrArrayEmpty (handshakes)) - return NULL; + if (tr_ptrArrayEmpty (handshakes)) + return NULL; - return tr_ptrArrayFindSorted (handshakes, addr, handshakeCompareToAddr); + return tr_ptrArrayFindSorted (handshakes, addr, handshakeCompareToAddr); } static int comparePeerAtomToAddress (const void * va, const void * vb) { - const struct peer_atom * a = va; + const struct peer_atom * a = va; - return tr_address_compare (&a->addr, vb); + return tr_address_compare (&a->addr, vb); } static int compareAtomsByAddress (const void * va, const void * vb) { - const struct peer_atom * b = vb; + const struct peer_atom * b = vb; - assert (tr_isAtom (b)); + assert (tr_isAtom (b)); - return comparePeerAtomToAddress (va, &b->addr); + return comparePeerAtomToAddress (va, &b->addr); } /** @@ -336,82 +336,82 @@ compareAtomsByAddress (const void * va, const void * vb) const tr_address * tr_peerAddress (const tr_peer * peer) { - return &peer->atom->addr; + return &peer->atom->addr; } static Torrent* getExistingTorrent (tr_peerMgr * manager, const uint8_t * hash) { - tr_torrent * tor = tr_torrentFindFromHash (manager->session, hash); + tr_torrent * tor = tr_torrentFindFromHash (manager->session, hash); - return tor == NULL ? NULL : tor->torrentPeers; + return tor == NULL ? NULL : tor->torrentPeers; } static int peerCompare (const void * a, const void * b) { - return tr_address_compare (tr_peerAddress (a), tr_peerAddress (b)); + return tr_address_compare (tr_peerAddress (a), tr_peerAddress (b)); } static struct peer_atom* getExistingAtom (const Torrent * t, const tr_address * addr) { - Torrent * tt = (Torrent*)t; - return tr_ptrArrayFindSorted (&tt->pool, addr, comparePeerAtomToAddress); + Torrent * tt = (Torrent*)t; + return tr_ptrArrayFindSorted (&tt->pool, addr, comparePeerAtomToAddress); } static bool peerIsInUse (const Torrent * ct, const struct peer_atom * atom) { - Torrent * t = (Torrent*) ct; + Torrent * t = (Torrent*) ct; - assert (torrentIsLocked (t)); + assert (torrentIsLocked (t)); - return (atom->peer != NULL) - || getExistingHandshake (&t->outgoingHandshakes, &atom->addr) - || getExistingHandshake (&t->manager->incomingHandshakes, &atom->addr); + return (atom->peer != NULL) + || getExistingHandshake (&t->outgoingHandshakes, &atom->addr) + || getExistingHandshake (&t->manager->incomingHandshakes, &atom->addr); } void tr_peerConstruct (tr_peer * peer) { - memset (peer, 0, sizeof (tr_peer)); + memset (peer, 0, sizeof (tr_peer)); - peer->have = TR_BITFIELD_INIT; + peer->have = TR_BITFIELD_INIT; } static tr_peer* peerNew (struct peer_atom * atom) { - tr_peer * peer = tr_new (tr_peer, 1); - tr_peerConstruct (peer); + tr_peer * peer = tr_new (tr_peer, 1); + tr_peerConstruct (peer); - peer->atom = atom; - atom->peer = peer; + peer->atom = atom; + atom->peer = peer; - return peer; + return peer; } static tr_peer* getPeer (Torrent * torrent, struct peer_atom * atom) { - tr_peer * peer; + tr_peer * peer; - assert (torrentIsLocked (torrent)); + assert (torrentIsLocked (torrent)); - peer = atom->peer; + peer = atom->peer; - if (peer == NULL) + if (peer == NULL) { - peer = peerNew (atom); - tr_bitfieldConstruct (&peer->have, torrent->tor->info.pieceCount); - tr_bitfieldConstruct (&peer->blame, torrent->tor->blockCount); - tr_ptrArrayInsertSorted (&torrent->peers, peer, peerCompare); + peer = peerNew (atom); + tr_bitfieldConstruct (&peer->have, torrent->tor->info.pieceCount); + tr_bitfieldConstruct (&peer->blame, torrent->tor->blockCount); + tr_ptrArrayInsertSorted (&torrent->peers, peer, peerCompare); } - return peer; + return peer; } static void peerDeclinedAllRequests (Torrent *, const tr_peer *); @@ -419,93 +419,94 @@ static void peerDeclinedAllRequests (Torrent *, const tr_peer *); void tr_peerDestruct (tr_torrent * tor, tr_peer * peer) { - assert (peer != NULL); + assert (peer != NULL); - peerDeclinedAllRequests (tor->torrentPeers, peer); + peerDeclinedAllRequests (tor->torrentPeers, peer); - if (peer->msgs != NULL) - tr_peerMsgsFree (peer->msgs); + if (peer->msgs != NULL) + tr_peerMsgsFree (peer->msgs); - if (peer->io) { - tr_peerIoClear (peer->io); - tr_peerIoUnref (peer->io); /* balanced by the ref in handshakeDoneCB () */ + if (peer->io) + { + tr_peerIoClear (peer->io); + tr_peerIoUnref (peer->io); /* balanced by the ref in handshakeDoneCB () */ } - tr_bitfieldDestruct (&peer->have); - tr_bitfieldDestruct (&peer->blame); + tr_bitfieldDestruct (&peer->have); + tr_bitfieldDestruct (&peer->blame); - if (peer->atom) - peer->atom->peer = NULL; + if (peer->atom) + peer->atom->peer = NULL; } static void peerDelete (Torrent * t, tr_peer * peer) { - tr_peerDestruct (t->tor, peer); - tr_free (peer); + tr_peerDestruct (t->tor, peer); + tr_free (peer); } static bool replicationExists (const Torrent * t) { - return t->pieceReplication != NULL; + return t->pieceReplication != NULL; } static void replicationFree (Torrent * t) { - tr_free (t->pieceReplication); - t->pieceReplication = NULL; - t->pieceReplicationSize = 0; + tr_free (t->pieceReplication); + t->pieceReplication = NULL; + t->pieceReplicationSize = 0; } static void replicationNew (Torrent * t) { - tr_piece_index_t piece_i; - const tr_piece_index_t piece_count = t->tor->info.pieceCount; - tr_peer ** peers = (tr_peer**) tr_ptrArrayBase (&t->peers); - const int peer_count = tr_ptrArraySize (&t->peers); + tr_piece_index_t piece_i; + const tr_piece_index_t piece_count = t->tor->info.pieceCount; + tr_peer ** peers = (tr_peer**) tr_ptrArrayBase (&t->peers); + const int peer_count = tr_ptrArraySize (&t->peers); - assert (!replicationExists (t)); + assert (!replicationExists (t)); - t->pieceReplicationSize = piece_count; - t->pieceReplication = tr_new0 (uint16_t, piece_count); + t->pieceReplicationSize = piece_count; + t->pieceReplication = tr_new0 (uint16_t, piece_count); - for (piece_i=0; piece_ihave, piece_i)) - ++r; + for (peer_i=0; peer_ihave, piece_i)) + ++r; - t->pieceReplication[piece_i] = r; + t->pieceReplication[piece_i] = r; } } static void torrentFree (void * vt) { - Torrent * t = vt; + Torrent * t = vt; - assert (t); - assert (!t->isRunning); - assert (torrentIsLocked (t)); - assert (tr_ptrArrayEmpty (&t->outgoingHandshakes)); - assert (tr_ptrArrayEmpty (&t->peers)); + assert (t); + assert (!t->isRunning); + assert (torrentIsLocked (t)); + assert (tr_ptrArrayEmpty (&t->outgoingHandshakes)); + assert (tr_ptrArrayEmpty (&t->peers)); - tr_ptrArrayDestruct (&t->webseeds, (PtrArrayForeachFunc)tr_webseedFree); - tr_ptrArrayDestruct (&t->pool, (PtrArrayForeachFunc)tr_free); - tr_ptrArrayDestruct (&t->outgoingHandshakes, NULL); - tr_ptrArrayDestruct (&t->peers, NULL); + tr_ptrArrayDestruct (&t->webseeds, (PtrArrayForeachFunc)tr_webseedFree); + tr_ptrArrayDestruct (&t->pool, (PtrArrayForeachFunc)tr_free); + tr_ptrArrayDestruct (&t->outgoingHandshakes, NULL); + tr_ptrArrayDestruct (&t->peers, NULL); - replicationFree (t); + replicationFree (t); - tr_free (t->requests); - tr_free (t->pieces); - tr_free (t); + tr_free (t->requests); + tr_free (t->pieces); + tr_free (t); } static void peerCallbackFunc (tr_peer *, const tr_peer_event *, void *); @@ -513,37 +514,37 @@ static void peerCallbackFunc (tr_peer *, const tr_peer_event *, void *); static void rebuildWebseedArray (Torrent * t, tr_torrent * tor) { - unsigned int i; - const tr_info * inf = &tor->info; + unsigned int i; + const tr_info * inf = &tor->info; - /* clear the array */ - tr_ptrArrayDestruct (&t->webseeds, (PtrArrayForeachFunc)tr_webseedFree); - t->webseeds = TR_PTR_ARRAY_INIT; + /* clear the array */ + tr_ptrArrayDestruct (&t->webseeds, (PtrArrayForeachFunc)tr_webseedFree); + t->webseeds = TR_PTR_ARRAY_INIT; - /* repopulate it */ - for (i = 0; i < inf->webseedCount; ++i) + /* repopulate it */ + for (i = 0; i < inf->webseedCount; ++i) { - tr_webseed * w = tr_webseedNew (tor, inf->webseeds[i], peerCallbackFunc, t); - tr_ptrArrayAppend (&t->webseeds, w); + tr_webseed * w = tr_webseedNew (tor, inf->webseeds[i], peerCallbackFunc, t); + tr_ptrArrayAppend (&t->webseeds, w); } } static Torrent* torrentNew (tr_peerMgr * manager, tr_torrent * tor) { - Torrent * t; + Torrent * t; - t = tr_new0 (Torrent, 1); - t->manager = manager; - t->tor = tor; - t->pool = TR_PTR_ARRAY_INIT; - t->peers = TR_PTR_ARRAY_INIT; - t->webseeds = TR_PTR_ARRAY_INIT; - t->outgoingHandshakes = TR_PTR_ARRAY_INIT; + t = tr_new0 (Torrent, 1); + t->manager = manager; + t->tor = tor; + t->pool = TR_PTR_ARRAY_INIT; + t->peers = TR_PTR_ARRAY_INIT; + t->webseeds = TR_PTR_ARRAY_INIT; + t->outgoingHandshakes = TR_PTR_ARRAY_INIT; - rebuildWebseedArray (t, tor); + rebuildWebseedArray (t, tor); - return t; + return t; } static void ensureMgrTimersExist (struct tr_peerMgr * m); @@ -551,63 +552,63 @@ static void ensureMgrTimersExist (struct tr_peerMgr * m); tr_peerMgr* tr_peerMgrNew (tr_session * session) { - tr_peerMgr * m = tr_new0 (tr_peerMgr, 1); - m->session = session; - m->incomingHandshakes = TR_PTR_ARRAY_INIT; - ensureMgrTimersExist (m); - return m; + tr_peerMgr * m = tr_new0 (tr_peerMgr, 1); + m->session = session; + m->incomingHandshakes = TR_PTR_ARRAY_INIT; + ensureMgrTimersExist (m); + return m; } static void deleteTimer (struct event ** t) { - if (*t != NULL) + if (*t != NULL) { - event_free (*t); - *t = NULL; + event_free (*t); + *t = NULL; } } static void deleteTimers (struct tr_peerMgr * m) { - deleteTimer (&m->atomTimer); - deleteTimer (&m->bandwidthTimer); - deleteTimer (&m->rechokeTimer); - deleteTimer (&m->refillUpkeepTimer); + deleteTimer (&m->atomTimer); + deleteTimer (&m->bandwidthTimer); + deleteTimer (&m->rechokeTimer); + deleteTimer (&m->refillUpkeepTimer); } void tr_peerMgrFree (tr_peerMgr * manager) { - managerLock (manager); + managerLock (manager); - deleteTimers (manager); + deleteTimers (manager); - /* free the handshakes. Abort invokes handshakeDoneCB (), which removes - * the item from manager->handshakes, so this is a little roundabout... */ - while (!tr_ptrArrayEmpty (&manager->incomingHandshakes)) - tr_handshakeAbort (tr_ptrArrayNth (&manager->incomingHandshakes, 0)); + /* free the handshakes. Abort invokes handshakeDoneCB (), which removes + * the item from manager->handshakes, so this is a little roundabout... */ + while (!tr_ptrArrayEmpty (&manager->incomingHandshakes)) + tr_handshakeAbort (tr_ptrArrayNth (&manager->incomingHandshakes, 0)); - tr_ptrArrayDestruct (&manager->incomingHandshakes, NULL); + tr_ptrArrayDestruct (&manager->incomingHandshakes, NULL); - managerUnlock (manager); - tr_free (manager); + managerUnlock (manager); + tr_free (manager); } static int clientIsDownloadingFrom (const tr_torrent * tor, const tr_peer * peer) { - if (!tr_torrentHasMetadata (tor)) - return true; + if (!tr_torrentHasMetadata (tor)) + return true; - return peer->clientIsInterested && !peer->clientIsChoked; + return peer->clientIsInterested && !peer->clientIsChoked; } static int clientIsUploadingTo (const tr_peer * peer) { - return peer->peerIsInterested && !peer->peerIsChoked; + return peer->peerIsInterested && !peer->peerIsChoked; } /*** @@ -617,19 +618,20 @@ clientIsUploadingTo (const tr_peer * peer) void tr_peerMgrOnBlocklistChanged (tr_peerMgr * mgr) { - tr_torrent * tor = NULL; - tr_session * session = mgr->session; + tr_torrent * tor = NULL; + tr_session * session = mgr->session; - /* we cache whether or not a peer is blocklisted... - since the blocklist has changed, erase that cached value */ - while ((tor = tr_torrentNext (session, tor))) + /* we cache whether or not a peer is blocklisted... + since the blocklist has changed, erase that cached value */ + while ((tor = tr_torrentNext (session, tor))) { - int i; - Torrent * t = tor->torrentPeers; - const int n = tr_ptrArraySize (&t->pool); - for (i=0; ipool, i); - atom->blocklisted = -1; + int i; + Torrent * t = tor->torrentPeers; + const int n = tr_ptrArraySize (&t->pool); + for (i=0; ipool, i); + atom->blocklisted = -1; } } } @@ -637,11 +639,11 @@ tr_peerMgrOnBlocklistChanged (tr_peerMgr * mgr) static bool isAtomBlocklisted (tr_session * session, struct peer_atom * atom) { - if (atom->blocklisted < 0) - atom->blocklisted = tr_sessionIsAddressBlocked (session, &atom->addr); + if (atom->blocklisted < 0) + atom->blocklisted = tr_sessionIsAddressBlocked (session, &atom->addr); - assert (tr_isBool (atom->blocklisted)); - return atom->blocklisted; + assert (tr_isBool (atom->blocklisted)); + return atom->blocklisted; } @@ -652,31 +654,31 @@ isAtomBlocklisted (tr_session * session, struct peer_atom * atom) static void atomSetSeedProbability (struct peer_atom * atom, int seedProbability) { - assert (atom != NULL); - assert (-1<=seedProbability && seedProbability<=100); + assert (atom != NULL); + assert (-1<=seedProbability && seedProbability<=100); - atom->seedProbability = seedProbability; + atom->seedProbability = seedProbability; - if (seedProbability == 100) - atom->flags |= ADDED_F_SEED_FLAG; - else if (seedProbability != -1) - atom->flags &= ~ADDED_F_SEED_FLAG; + if (seedProbability == 100) + atom->flags |= ADDED_F_SEED_FLAG; + else if (seedProbability != -1) + atom->flags &= ~ADDED_F_SEED_FLAG; } static inline bool atomIsSeed (const struct peer_atom * atom) { - return atom->seedProbability == 100; + return atom->seedProbability == 100; } static void atomSetSeed (const Torrent * t, struct peer_atom * atom) { - if (!atomIsSeed (atom)) + if (!atomIsSeed (atom)) { - tordbg (t, "marking peer %s as a seed", tr_atomAddrStr (atom)); + tordbg (t, "marking peer %s as a seed", tr_atomAddrStr (atom)); - atomSetSeedProbability (atom, 100); + atomSetSeedProbability (atom, 100); } } @@ -685,32 +687,32 @@ bool tr_peerMgrPeerIsSeed (const tr_torrent * tor, const tr_address * addr) { - bool isSeed = false; - const Torrent * t = tor->torrentPeers; - const struct peer_atom * atom = getExistingAtom (t, addr); + bool isSeed = false; + const Torrent * t = tor->torrentPeers; + const struct peer_atom * atom = getExistingAtom (t, addr); - if (atom) - isSeed = atomIsSeed (atom); + if (atom) + isSeed = atomIsSeed (atom); - return isSeed; + return isSeed; } void tr_peerMgrSetUtpSupported (tr_torrent * tor, const tr_address * addr) { - struct peer_atom * atom = getExistingAtom (tor->torrentPeers, addr); + struct peer_atom * atom = getExistingAtom (tor->torrentPeers, addr); - if (atom) - atom->flags |= ADDED_F_UTP_FLAGS; + if (atom) + atom->flags |= ADDED_F_UTP_FLAGS; } void tr_peerMgrSetUtpFailed (tr_torrent *tor, const tr_address *addr, bool failed) { - struct peer_atom * atom = getExistingAtom (tor->torrentPeers, addr); + struct peer_atom * atom = getExistingAtom (tor->torrentPeers, addr); - if (atom) - atom->utp_failed = failed; + if (atom) + atom->utp_failed = failed; } diff --git a/libtransmission/port-forwarding.c b/libtransmission/port-forwarding.c index 43ab9f21e..918c37a60 100644 --- a/libtransmission/port-forwarding.c +++ b/libtransmission/port-forwarding.c @@ -32,18 +32,18 @@ getKey (void) { return _("Port Forwarding"); } struct tr_shared { - bool isEnabled; - bool isShuttingDown; - bool doPortCheck; + bool isEnabled; + bool isShuttingDown; + bool doPortCheck; - tr_port_forwarding natpmpStatus; - tr_port_forwarding upnpStatus; + tr_port_forwarding natpmpStatus; + tr_port_forwarding upnpStatus; - tr_upnp * upnp; - tr_natpmp * natpmp; - tr_session * session; + tr_upnp * upnp; + tr_natpmp * natpmp; + tr_session * session; - struct event * timer; + struct event * timer; }; /*** @@ -53,90 +53,91 @@ struct tr_shared static const char* getNatStateStr (int state) { - switch (state) + switch (state) { - case TR_PORT_MAPPING: return _("Starting"); - case TR_PORT_MAPPED: return _("Forwarded"); - case TR_PORT_UNMAPPING: return _("Stopping"); - case TR_PORT_UNMAPPED: return _("Not forwarded"); - default: return "???"; + case TR_PORT_MAPPING: return _("Starting"); + case TR_PORT_MAPPED: return _("Forwarded"); + case TR_PORT_UNMAPPING: return _("Stopping"); + case TR_PORT_UNMAPPED: return _("Not forwarded"); + default: return "???"; } } static void natPulse (tr_shared * s, bool do_check) { - const tr_port private_peer_port = s->session->private_peer_port; - const int is_enabled = s->isEnabled && !s->isShuttingDown; - tr_port public_peer_port; - int oldStatus; - int newStatus; + int oldStatus; + int newStatus; + tr_port public_peer_port; + const tr_port private_peer_port = s->session->private_peer_port; + const int is_enabled = s->isEnabled && !s->isShuttingDown; - if (s->natpmp == NULL) - s->natpmp = tr_natpmpInit (); - if (s->upnp == NULL) - s->upnp = tr_upnpInit (); + if (s->natpmp == NULL) + s->natpmp = tr_natpmpInit (); - oldStatus = tr_sharedTraversalStatus (s); + if (s->upnp == NULL) + s->upnp = tr_upnpInit (); - s->natpmpStatus = tr_natpmpPulse (s->natpmp, private_peer_port, is_enabled, &public_peer_port); - if (s->natpmpStatus == TR_PORT_MAPPED) - s->session->public_peer_port = public_peer_port; + oldStatus = tr_sharedTraversalStatus (s); - s->upnpStatus = tr_upnpPulse (s->upnp, private_peer_port, is_enabled, do_check); + s->natpmpStatus = tr_natpmpPulse (s->natpmp, private_peer_port, is_enabled, &public_peer_port); + if (s->natpmpStatus == TR_PORT_MAPPED) + s->session->public_peer_port = public_peer_port; - newStatus = tr_sharedTraversalStatus (s); + s->upnpStatus = tr_upnpPulse (s->upnp, private_peer_port, is_enabled, do_check); - if (newStatus != oldStatus) - tr_ninf (getKey (), _("State changed from \"%1$s\" to \"%2$s\""), - getNatStateStr (oldStatus), - getNatStateStr (newStatus)); + newStatus = tr_sharedTraversalStatus (s); + + if (newStatus != oldStatus) + tr_ninf (getKey (), _("State changed from \"%1$s\" to \"%2$s\""), + getNatStateStr (oldStatus), + getNatStateStr (newStatus)); } static void set_evtimer_from_status (tr_shared * s) { - int sec=0, msec=0; + int sec=0, msec=0; - /* when to wake up again */ - switch (tr_sharedTraversalStatus (s)) + /* when to wake up again */ + switch (tr_sharedTraversalStatus (s)) { - case TR_PORT_MAPPED: - /* if we're mapped, everything is fine... check back in 20 minutes - * to renew the port forwarding if it's expired */ - s->doPortCheck = true; - sec = 60 * 20; - break; + case TR_PORT_MAPPED: + /* if we're mapped, everything is fine... check back in 20 minutes + * to renew the port forwarding if it's expired */ + s->doPortCheck = true; + sec = 60 * 20; + break; - case TR_PORT_ERROR: - /* some kind of an error. wait 60 seconds and retry */ - sec = 60; - break; + case TR_PORT_ERROR: + /* some kind of an error. wait 60 seconds and retry */ + sec = 60; + break; - default: - /* in progress. pulse frequently. */ - msec = 333000; - break; + default: + /* in progress. pulse frequently. */ + msec = 333000; + break; } - if (s->timer != NULL) - tr_timerAdd (s->timer, sec, msec); + if (s->timer != NULL) + tr_timerAdd (s->timer, sec, msec); } static void onTimer (int fd UNUSED, short what UNUSED, void * vshared) { - tr_shared * s = vshared; + tr_shared * s = vshared; - assert (s); - assert (s->timer); + assert (s); + assert (s->timer); - /* do something */ - natPulse (s, s->doPortCheck); - s->doPortCheck = false; + /* do something */ + natPulse (s, s->doPortCheck); + s->doPortCheck = false; - /* set up the timer for the next pulse */ - set_evtimer_from_status (s); + /* set up the timer for the next pulse */ + set_evtimer_from_status (s); } /*** @@ -146,100 +147,100 @@ onTimer (int fd UNUSED, short what UNUSED, void * vshared) tr_shared * tr_sharedInit (tr_session * session) { - tr_shared * s = tr_new0 (tr_shared, 1); + tr_shared * s = tr_new0 (tr_shared, 1); - s->session = session; - s->isEnabled = false; - s->upnpStatus = TR_PORT_UNMAPPED; - s->natpmpStatus = TR_PORT_UNMAPPED; + s->session = session; + s->isEnabled = false; + s->upnpStatus = TR_PORT_UNMAPPED; + s->natpmpStatus = TR_PORT_UNMAPPED; #if 0 - if (isEnabled) + if (isEnabled) { - s->timer = tr_new0 (struct event, 1); - evtimer_set (s->timer, onTimer, s); - tr_timerAdd (s->timer, 0, 333000); + s->timer = tr_new0 (struct event, 1); + evtimer_set (s->timer, onTimer, s); + tr_timerAdd (s->timer, 0, 333000); } #endif - return s; + return s; } static void stop_timer (tr_shared * s) { - if (s->timer != NULL) + if (s->timer != NULL) { - event_free (s->timer); - s->timer = NULL; + event_free (s->timer); + s->timer = NULL; } } static void stop_forwarding (tr_shared * s) { - tr_ninf (getKey (), "%s", _("Stopped")); - natPulse (s, false); + tr_ninf (getKey (), "%s", _("Stopped")); + natPulse (s, false); - tr_natpmpClose (s->natpmp); - s->natpmp = NULL; - s->natpmpStatus = TR_PORT_UNMAPPED; + tr_natpmpClose (s->natpmp); + s->natpmp = NULL; + s->natpmpStatus = TR_PORT_UNMAPPED; - tr_upnpClose (s->upnp); - s->upnp = NULL; - s->upnpStatus = TR_PORT_UNMAPPED; + tr_upnpClose (s->upnp); + s->upnp = NULL; + s->upnpStatus = TR_PORT_UNMAPPED; - stop_timer (s); + stop_timer (s); } void tr_sharedClose (tr_session * session) { - tr_shared * s = session->shared; + tr_shared * s = session->shared; - s->isShuttingDown = true; - stop_forwarding (s); - s->session->shared = NULL; - tr_free (s); + s->isShuttingDown = true; + stop_forwarding (s); + s->session->shared = NULL; + tr_free (s); } static void start_timer (tr_shared * s) { - s->timer = evtimer_new (s->session->event_base, onTimer, s); - set_evtimer_from_status (s); + s->timer = evtimer_new (s->session->event_base, onTimer, s); + set_evtimer_from_status (s); } void tr_sharedTraversalEnable (tr_shared * s, bool isEnabled) { - if ((s->isEnabled = isEnabled)) - start_timer (s); - else - stop_forwarding (s); + if ((s->isEnabled = isEnabled)) + start_timer (s); + else + stop_forwarding (s); } void tr_sharedPortChanged (tr_session * session) { - tr_shared * s = session->shared; + tr_shared * s = session->shared; - if (s->isEnabled) + if (s->isEnabled) { - stop_timer (s); - natPulse (s, false); - start_timer (s); + stop_timer (s); + natPulse (s, false); + start_timer (s); } } bool tr_sharedTraversalIsEnabled (const tr_shared * s) { - return s->isEnabled; + return s->isEnabled; } int tr_sharedTraversalStatus (const tr_shared * s) { - return MAX (s->natpmpStatus, s->upnpStatus); + return MAX (s->natpmpStatus, s->upnpStatus); } diff --git a/libtransmission/utils.c b/libtransmission/utils.c index 881fe5571..8110cc0fa 100644 --- a/libtransmission/utils.c +++ b/libtransmission/utils.c @@ -71,9 +71,9 @@ static tr_msg_list ** messageQueueTail = &messageQueue; static int messageQueueCount = 0; #ifndef WIN32 - /* make null versions of these win32 functions */ - static inline int IsDebuggerPresent (void) { return false; } - static inline void OutputDebugString (const void * unused UNUSED) { } + /* make null versions of these win32 functions */ + static inline int IsDebuggerPresent (void) { return false; } + static inline void OutputDebugString (const void * unused UNUSED) { } #endif /*** @@ -83,41 +83,47 @@ static int messageQueueCount = 0; static tr_lock* getMessageLock (void) { - static tr_lock * l = NULL; + static tr_lock * l = NULL; - if (!l) - l = tr_lockNew (); + if (!l) + l = tr_lockNew (); - return l; + return l; } void* tr_getLog (void) { - static bool initialized = false; - static FILE * file = NULL; + static bool initialized = false; + static FILE * file = NULL; - if (!initialized) + if (!initialized) { - const char * str = getenv ("TR_DEBUG_FD"); - int fd = 0; - if (str && *str) - fd = atoi (str); - switch (fd) + int fd = 0; + const char * str = getenv ("TR_DEBUG_FD"); + + if (str && *str) + fd = atoi (str); + + switch (fd) { - case 1: - file = stdout; break; + case 1: + file = stdout; + break; - case 2: - file = stderr; break; + case 2: + file = stderr; + break; - default: - file = NULL; break; + default: + file = NULL; + break; } - initialized = true; + + initialized = true; } - return file; + return file; } void @@ -129,43 +135,43 @@ tr_setMessageLevel (tr_msg_level level) void tr_setMessageQueuing (bool enabled) { - messageQueuing = enabled; + messageQueuing = enabled; } bool tr_getMessageQueuing (void) { - return messageQueuing != 0; + return messageQueuing != 0; } tr_msg_list * tr_getQueuedMessages (void) { - tr_msg_list * ret; - tr_lockLock (getMessageLock ()); + tr_msg_list * ret; + tr_lockLock (getMessageLock ()); - ret = messageQueue; - messageQueue = NULL; - messageQueueTail = &messageQueue; + ret = messageQueue; + messageQueue = NULL; + messageQueueTail = &messageQueue; - messageQueueCount = 0; + messageQueueCount = 0; - tr_lockUnlock (getMessageLock ()); - return ret; + tr_lockUnlock (getMessageLock ()); + return ret; } void tr_freeMessageList (tr_msg_list * list) { - tr_msg_list * next; + tr_msg_list * next; - while (NULL != list) + while (NULL != list) { - next = list->next; - free (list->message); - free (list->name); - free (list); - list = next; + next = list->next; + free (list->message); + free (list->name); + free (list); + list = next; } } @@ -177,44 +183,44 @@ struct tm * tr_localtime_r (const time_t *_clock, struct tm *_result) { #ifdef HAVE_LOCALTIME_R - return localtime_r (_clock, _result); + return localtime_r (_clock, _result); #else - struct tm *p = localtime (_clock); - if (p) - * (_result) = *p; - return p; + struct tm *p = localtime (_clock); + if (p) + * (_result) = *p; + return p; #endif } char* tr_getLogTimeStr (char * buf, int buflen) { - char tmp[64]; - struct tm now_tm; - struct timeval tv; - time_t seconds; - int milliseconds; + char tmp[64]; + struct tm now_tm; + struct timeval tv; + time_t seconds; + int milliseconds; - gettimeofday (&tv, NULL); + gettimeofday (&tv, NULL); - seconds = tv.tv_sec; - tr_localtime_r (&seconds, &now_tm); - strftime (tmp, sizeof (tmp), "%H:%M:%S", &now_tm); - milliseconds = tv.tv_usec / 1000; - tr_snprintf (buf, buflen, "%s.%03d", tmp, milliseconds); + seconds = tv.tv_sec; + tr_localtime_r (&seconds, &now_tm); + strftime (tmp, sizeof (tmp), "%H:%M:%S", &now_tm); + milliseconds = tv.tv_usec / 1000; + tr_snprintf (buf, buflen, "%s.%03d", tmp, milliseconds); - return buf; + return buf; } bool tr_deepLoggingIsActive (void) { - static int8_t deepLoggingIsActive = -1; + static int8_t deepLoggingIsActive = -1; - if (deepLoggingIsActive < 0) - deepLoggingIsActive = IsDebuggerPresent () || (tr_getLog ()!=NULL); + if (deepLoggingIsActive < 0) + deepLoggingIsActive = IsDebuggerPresent () || (tr_getLog ()!=NULL); - return deepLoggingIsActive != 0; + return deepLoggingIsActive != 0; } void @@ -224,31 +230,31 @@ tr_deepLog (const char * file, const char * fmt, ...) { - FILE * fp = tr_getLog (); - if (fp || IsDebuggerPresent ()) + FILE * fp = tr_getLog (); + if (fp || IsDebuggerPresent ()) { - va_list args; - char timestr[64]; - struct evbuffer * buf = evbuffer_new (); - char * base = tr_basename (file); - char * message; + va_list args; + char timestr[64]; + char * message; + struct evbuffer * buf = evbuffer_new (); + char * base = tr_basename (file); - evbuffer_add_printf (buf, "[%s] ", - tr_getLogTimeStr (timestr, sizeof (timestr))); - if (name) - evbuffer_add_printf (buf, "%s ", name); - va_start (args, fmt); - evbuffer_add_vprintf (buf, fmt, args); - va_end (args); - evbuffer_add_printf (buf, " (%s:%d)\n", base, line); - /* FIXME (libevent2) ifdef this out for nonwindows platforms */ - message = evbuffer_free_to_str (buf); - OutputDebugString (message); - if (fp) - fputs (message, fp); + evbuffer_add_printf (buf, "[%s] ", + tr_getLogTimeStr (timestr, sizeof (timestr))); + if (name) + evbuffer_add_printf (buf, "%s ", name); + va_start (args, fmt); + evbuffer_add_vprintf (buf, fmt, args); + va_end (args); + evbuffer_add_printf (buf, " (%s:%d)\n", base, line); + /* FIXME (libevent2) ifdef this out for nonwindows platforms */ + message = evbuffer_free_to_str (buf); + OutputDebugString (message); + if (fp) + fputs (message, fp); - tr_free (message); - tr_free (base); + tr_free (message); + tr_free (base); } } @@ -262,69 +268,67 @@ tr_msg (const char * file, int line, const char * name, const char * fmt, ...) { - const int err = errno; /* message logging shouldn't affect errno */ - char buf[1024]; - va_list ap; - tr_lockLock (getMessageLock ()); + const int err = errno; /* message logging shouldn't affect errno */ + char buf[1024]; + va_list ap; + tr_lockLock (getMessageLock ()); - /* build the text message */ - *buf = '\0'; - va_start (ap, fmt); - evutil_vsnprintf (buf, sizeof (buf), fmt, ap); - va_end (ap); + /* build the text message */ + *buf = '\0'; + va_start (ap, fmt); + evutil_vsnprintf (buf, sizeof (buf), fmt, ap); + va_end (ap); - OutputDebugString (buf); + OutputDebugString (buf); - if (*buf) + if (*buf) { - if (messageQueuing) + if (messageQueuing) { - tr_msg_list * newmsg; - newmsg = tr_new0 (tr_msg_list, 1); - newmsg->level = level; - newmsg->when = tr_time (); - newmsg->message = tr_strdup (buf); - newmsg->file = file; - newmsg->line = line; - newmsg->name = tr_strdup (name); + tr_msg_list * newmsg; + newmsg = tr_new0 (tr_msg_list, 1); + newmsg->level = level; + newmsg->when = tr_time (); + newmsg->message = tr_strdup (buf); + newmsg->file = file; + newmsg->line = line; + newmsg->name = tr_strdup (name); - *messageQueueTail = newmsg; - messageQueueTail = &newmsg->next; - ++messageQueueCount; + *messageQueueTail = newmsg; + messageQueueTail = &newmsg->next; + ++messageQueueCount; - if (messageQueueCount > TR_MAX_MSG_LOG) + if (messageQueueCount > TR_MAX_MSG_LOG) { - tr_msg_list * old = messageQueue; - messageQueue = old->next; - old->next = NULL; - tr_freeMessageList (old); - - --messageQueueCount; - - assert (messageQueueCount == TR_MAX_MSG_LOG); + tr_msg_list * old = messageQueue; + messageQueue = old->next; + old->next = NULL; + tr_freeMessageList (old); + --messageQueueCount; + assert (messageQueueCount == TR_MAX_MSG_LOG); } } - else + else { - char timestr[64]; - FILE * fp; + FILE * fp; + char timestr[64]; - fp = tr_getLog (); - if (fp == NULL) - fp = stderr; + fp = tr_getLog (); + if (fp == NULL) + fp = stderr; - tr_getLogTimeStr (timestr, sizeof (timestr)); + tr_getLogTimeStr (timestr, sizeof (timestr)); - if (name) - fprintf (fp, "[%s] %s: %s\n", timestr, name, buf); - else - fprintf (fp, "[%s] %s\n", timestr, buf); - fflush (fp); + if (name) + fprintf (fp, "[%s] %s: %s\n", timestr, name, buf); + else + fprintf (fp, "[%s] %s\n", timestr, buf); + fflush (fp); } } - tr_lockUnlock (getMessageLock ()); - errno = err; + tr_lockUnlock (getMessageLock ()); + errno = err; } /*** @@ -334,26 +338,26 @@ tr_msg (const char * file, int line, void* tr_malloc (size_t size) { - return size ? malloc (size) : NULL; + return size ? malloc (size) : NULL; } void* tr_malloc0 (size_t size) { - return size ? calloc (1, size) : NULL; + return size ? calloc (1, size) : NULL; } void tr_free (void * p) { - if (p != NULL) - free (p); + if (p != NULL) + free (p); } void* tr_memdup (const void * src, size_t byteCount) { - return memcpy (tr_malloc (byteCount), src, byteCount); + return memcpy (tr_malloc (byteCount), src, byteCount); } /*** @@ -363,38 +367,38 @@ tr_memdup (const void * src, size_t byteCount) const char* tr_strip_positional_args (const char* str) { - const char * in = str; - static size_t bufsize = 0; - static char * buf = NULL; - const size_t len = str ? strlen (str) : 0; - char * out; + char * out; + static size_t bufsize = 0; + static char * buf = NULL; + const char * in = str; + const size_t len = str ? strlen (str) : 0; - if (!buf || (bufsize < len)) + if (!buf || (bufsize < len)) { - bufsize = len * 2 + 1; - buf = tr_renew (char, buf, bufsize); + bufsize = len * 2 + 1; + buf = tr_renew (char, buf, bufsize); } - for (out = buf; str && *str; ++str) + for (out = buf; str && *str; ++str) { - *out++ = *str; + *out++ = *str; - if ((*str == '%') && isdigit (str[1])) + if ((*str == '%') && isdigit (str[1])) { - const char * tmp = str + 1; - while (isdigit (*tmp)) - ++tmp; - if (*tmp == '$') - str = tmp[1]=='\'' ? tmp+1 : tmp; + const char * tmp = str + 1; + while (isdigit (*tmp)) + ++tmp; + if (*tmp == '$') + str = tmp[1]=='\'' ? tmp+1 : tmp; } - if ((*str == '%') && (str[1] == '\'')) - str = str + 1; + if ((*str == '%') && (str[1] == '\'')) + str = str + 1; } - *out = '\0'; - return !in || strcmp (buf, in) ? buf : in; + *out = '\0'; + return !in || strcmp (buf, in) ? buf : in; } /** @@ -404,23 +408,23 @@ tr_strip_positional_args (const char* str) void tr_timerAdd (struct event * timer, int seconds, int microseconds) { - struct timeval tv; - tv.tv_sec = seconds; - tv.tv_usec = microseconds; + struct timeval tv; + tv.tv_sec = seconds; + tv.tv_usec = microseconds; - assert (tv.tv_sec >= 0); - assert (tv.tv_usec >= 0); - assert (tv.tv_usec < 1000000); + assert (tv.tv_sec >= 0); + assert (tv.tv_usec >= 0); + assert (tv.tv_usec < 1000000); - evtimer_add (timer, &tv); + evtimer_add (timer, &tv); } void tr_timerAddMsec (struct event * timer, int msec) { - const int seconds = msec / 1000; - const int usec = (msec%1000) * 1000; - tr_timerAdd (timer, seconds, usec); + const int seconds = msec / 1000; + const int usec = (msec%1000) * 1000; + tr_timerAdd (timer, seconds, usec); } /** @@ -429,93 +433,93 @@ tr_timerAddMsec (struct event * timer, int msec) uint8_t * tr_loadFile (const char * path, - size_t * size) + size_t * size) { - uint8_t * buf; - struct stat sb; - int fd; - ssize_t n; - const char * const err_fmt = _("Couldn't read \"%1$s\": %2$s"); + uint8_t * buf; + struct stat sb; + int fd; + ssize_t n; + const char * const err_fmt = _("Couldn't read \"%1$s\": %2$s"); - /* try to stat the file */ - errno = 0; - if (stat (path, &sb)) + /* try to stat the file */ + errno = 0; + if (stat (path, &sb)) { - const int err = errno; - tr_dbg (err_fmt, path, tr_strerror (errno)); - errno = err; - return NULL; + const int err = errno; + tr_dbg (err_fmt, path, tr_strerror (errno)); + errno = err; + return NULL; } - if ((sb.st_mode & S_IFMT) != S_IFREG) + if ((sb.st_mode & S_IFMT) != S_IFREG) { - tr_err (err_fmt, path, _("Not a regular file")); - errno = EISDIR; - return NULL; + tr_err (err_fmt, path, _("Not a regular file")); + errno = EISDIR; + return NULL; } - /* Load the torrent file into our buffer */ - fd = tr_open_file_for_scanning (path); - if (fd < 0) + /* Load the torrent file into our buffer */ + fd = tr_open_file_for_scanning (path); + if (fd < 0) { - const int err = errno; - tr_err (err_fmt, path, tr_strerror (errno)); - errno = err; - return NULL; + const int err = errno; + tr_err (err_fmt, path, tr_strerror (errno)); + errno = err; + return NULL; } - buf = tr_malloc (sb.st_size + 1); - if (!buf) + buf = tr_malloc (sb.st_size + 1); + if (!buf) { - const int err = errno; - tr_err (err_fmt, path, _("Memory allocation failed")); - tr_close_file (fd); - errno = err; - return NULL; + const int err = errno; + tr_err (err_fmt, path, _("Memory allocation failed")); + tr_close_file (fd); + errno = err; + return NULL; } - n = read (fd, buf, (size_t)sb.st_size); - if (n == -1) + n = read (fd, buf, (size_t)sb.st_size); + if (n == -1) { - const int err = errno; - tr_err (err_fmt, path, tr_strerror (errno)); - tr_close_file (fd); - free (buf); - errno = err; - return NULL; + const int err = errno; + tr_err (err_fmt, path, tr_strerror (errno)); + tr_close_file (fd); + free (buf); + errno = err; + return NULL; } - tr_close_file (fd); - buf[ sb.st_size ] = '\0'; - *size = sb.st_size; - return buf; + tr_close_file (fd); + buf[ sb.st_size ] = '\0'; + *size = sb.st_size; + return buf; } char* tr_basename (const char * path) { - char * tmp = tr_strdup (path); - char * ret = tr_strdup (basename (tmp)); - tr_free (tmp); - return ret; + char * tmp = tr_strdup (path); + char * ret = tr_strdup (basename (tmp)); + tr_free (tmp); + return ret; } char* tr_dirname (const char * path) { - char * tmp = tr_strdup (path); - char * ret = tr_strdup (dirname (tmp)); - tr_free (tmp); - return ret; + char * tmp = tr_strdup (path); + char * ret = tr_strdup (dirname (tmp)); + tr_free (tmp); + return ret; } char* tr_mkdtemp (char * template) { #ifdef HAVE_MKDTEMP - return mkdtemp (template); + return mkdtemp (template); #else - if (!mktemp (template) || mkdir (template, 0700)) - return NULL; - return template; + if (!mktemp (template) || mkdir (template, 0700)) + return NULL; + return template; #endif } @@ -532,11 +536,11 @@ static int tr_mkdir (const char * path, int permissions UNUSED) { #ifdef WIN32 - if (path && isalpha (path[0]) && path[1] == ':' && !path[2]) - return 0; - return mkdir (path); + if (path && isalpha (path[0]) && path[1] == ':' && !path[2]) + return 0; + return mkdir (path); #else - return mkdir (path, permissions); + return mkdir (path, permissions); #endif } @@ -544,104 +548,107 @@ int tr_mkdirp (const char * path_in, int permissions) { - char * path = tr_strdup (path_in); - char * p, * pp; - struct stat sb; - bool done; - int tmperr; - int rv; + char * p; + char * pp; + bool done; + int tmperr; + int rv; + struct stat sb; + char * path = tr_strdup (path_in); - /* walk past the root */ - p = path; - while (*p == TR_PATH_DELIMITER) - ++p; + /* walk past the root */ + p = path; + while (*p == TR_PATH_DELIMITER) + ++p; - pp = p; - done = false; - while ((p = strchr (pp, TR_PATH_DELIMITER)) || (p = strchr (pp, '\0'))) + pp = p; + done = false; + while ((p = strchr (pp, TR_PATH_DELIMITER)) || (p = strchr (pp, '\0'))) { - if (!*p) - done = true; - else - *p = '\0'; + if (!*p) + done = true; + else + *p = '\0'; - tmperr = errno; - rv = stat (path, &sb); - errno = tmperr; - if (rv) + tmperr = errno; + rv = stat (path, &sb); + errno = tmperr; + if (rv) { - /* Folder doesn't exist yet */ - if (tr_mkdir (path, permissions)) + /* Folder doesn't exist yet */ + if (tr_mkdir (path, permissions)) { - tmperr = errno; - tr_err (_("Couldn't create \"%1$s\": %2$s"), path, tr_strerror (tmperr)); - tr_free (path); - errno = tmperr; - return -1; + tmperr = errno; + tr_err (_("Couldn't create \"%1$s\": %2$s"), path, tr_strerror (tmperr)); + tr_free (path); + errno = tmperr; + return -1; } } - else if ((sb.st_mode & S_IFMT) != S_IFDIR) + else if ((sb.st_mode & S_IFMT) != S_IFDIR) { - /* Node exists but isn't a folder */ - char * buf = tr_strdup_printf (_("File \"%s\" is in the way"), path); - tr_err (_("Couldn't create \"%1$s\": %2$s"), path_in, buf); - tr_free (buf); - tr_free (path); - errno = ENOTDIR; - return -1; + /* Node exists but isn't a folder */ + char * buf = tr_strdup_printf (_("File \"%s\" is in the way"), path); + tr_err (_("Couldn't create \"%1$s\": %2$s"), path_in, buf); + tr_free (buf); + tr_free (path); + errno = ENOTDIR; + return -1; } - if (done) - break; + if (done) + break; - *p = TR_PATH_DELIMITER; - p++; - pp = p; + *p = TR_PATH_DELIMITER; + p++; + pp = p; } - tr_free (path); - return 0; + tr_free (path); + return 0; } char* tr_buildPath (const char *first_element, ...) { - size_t bufLen = 0; - const char * element; - char * buf; - char * pch; - va_list vl; + const char * element; + char * buf; + char * pch; + va_list vl; + size_t bufLen = 0; - /* pass 1: allocate enough space for the string */ - va_start (vl, first_element); - element = first_element; - while (element) { - bufLen += strlen (element) + 1; - element = va_arg (vl, const char*); + /* pass 1: allocate enough space for the string */ + va_start (vl, first_element); + element = first_element; + while (element) + { + bufLen += strlen (element) + 1; + element = va_arg (vl, const char*); } - pch = buf = tr_new (char, bufLen); - va_end (vl); + pch = buf = tr_new (char, bufLen); + va_end (vl); - /* pass 2: build the string piece by piece */ - va_start (vl, first_element); - element = first_element; - while (element) { - const size_t elementLen = strlen (element); - memcpy (pch, element, elementLen); - pch += elementLen; - *pch++ = TR_PATH_DELIMITER; - element = va_arg (vl, const char*); + /* pass 2: build the string piece by piece */ + va_start (vl, first_element); + element = first_element; + while (element) + { + const size_t elementLen = strlen (element); + memcpy (pch, element, elementLen); + pch += elementLen; + *pch++ = TR_PATH_DELIMITER; + element = va_arg (vl, const char*); } - va_end (vl); + va_end (vl); - /* terminate the string. if nonempty, eat the unwanted trailing slash */ - if (pch != buf) - --pch; - *pch++ = '\0'; + /* terminate the string. if nonempty, eat the unwanted trailing slash */ + if (pch != buf) + --pch; + *pch++ = '\0'; - /* sanity checks & return */ - assert (pch - buf == (off_t)bufLen); - return buf; + /* sanity checks & return */ + assert (pch - buf == (off_t)bufLen); + return buf; } #ifdef SYS_DARWIN @@ -653,13 +660,13 @@ tr_buildPath (const char *first_element, ...) bool tr_fileExists (const char * filename, time_t * mtime) { - struct stat sb; - const bool ok = !stat (filename, &sb); + struct stat sb; + const bool ok = !stat (filename, &sb); - if (ok && (mtime != NULL)) - *mtime = TR_STAT_MTIME (sb); + if (ok && (mtime != NULL)) + *mtime = TR_STAT_MTIME (sb); - return ok; + return ok; } /**** @@ -669,37 +676,37 @@ tr_fileExists (const char * filename, time_t * mtime) char* evbuffer_free_to_str (struct evbuffer * buf) { - const size_t n = evbuffer_get_length (buf); - char * ret = tr_new (char, n + 1); - evbuffer_copyout (buf, ret, n); - evbuffer_free (buf); - ret[n] = '\0'; - return ret; + const size_t n = evbuffer_get_length (buf); + char * ret = tr_new (char, n + 1); + evbuffer_copyout (buf, ret, n); + evbuffer_free (buf); + ret[n] = '\0'; + return ret; } char* tr_strdup (const void * in) { - return tr_strndup (in, in ? (int)strlen ((const char *)in) : 0); + return tr_strndup (in, in ? (int)strlen ((const char *)in) : 0); } char* tr_strndup (const void * in, int len) { - char * out = NULL; + char * out = NULL; - if (len < 0) + if (len < 0) { - out = tr_strdup (in); + out = tr_strdup (in); } - else if (in) + else if (in) { - out = tr_malloc (len + 1); - memcpy (out, in, len); - out[len] = '\0'; + out = tr_malloc (len + 1); + memcpy (out, in, len); + out[len] = '\0'; } - return out; + return out; } const char* @@ -707,60 +714,65 @@ tr_memmem (const char * haystack, size_t haystacklen, const char * needle, size_t needlelen) { #ifdef HAVE_MEMMEM - return memmem (haystack, haystacklen, needle, needlelen); + return memmem (haystack, haystacklen, needle, needlelen); #else - size_t i; - if (!needlelen) - return haystack; - if (needlelen > haystacklen || !haystack || !needle) - return NULL; - for (i=0; i<=haystacklen-needlelen; ++i) - if (!memcmp (haystack+i, needle, needlelen)) - return haystack+i; + size_t i; + if (!needlelen) + return haystack; + if (needlelen > haystacklen || !haystack || !needle) return NULL; + for (i=0; i<=haystacklen-needlelen; ++i) + if (!memcmp (haystack+i, needle, needlelen)) + return haystack+i; + return NULL; #endif } char* tr_strdup_printf (const char * fmt, ...) { - va_list ap; - char * ret; - size_t len; - char statbuf[2048]; + va_list ap; + char * ret; + size_t len; + char statbuf[2048]; - va_start (ap, fmt); - len = evutil_vsnprintf (statbuf, sizeof (statbuf), fmt, ap); - va_end (ap); - if (len < sizeof (statbuf)) - ret = tr_strndup (statbuf, len); - else { - ret = tr_new (char, len + 1); - va_start (ap, fmt); - evutil_vsnprintf (ret, len + 1, fmt, ap); - va_end (ap); + va_start (ap, fmt); + len = evutil_vsnprintf (statbuf, sizeof (statbuf), fmt, ap); + va_end (ap); + + if (len < sizeof (statbuf)) + { + ret = tr_strndup (statbuf, len); + } + else + { + ret = tr_new (char, len + 1); + va_start (ap, fmt); + evutil_vsnprintf (ret, len + 1, fmt, ap); + va_end (ap); } - return ret; + return ret; } const char* tr_strerror (int i) { - const char * ret = strerror (i); + const char * ret = strerror (i); - if (ret == NULL) - ret = "Unknown Error"; - return ret; + if (ret == NULL) + ret = "Unknown Error"; + + return ret; } int tr_strcmp0 (const char * str1, const char * str2) { - if (str1 && str2) return strcmp (str1, str2); - if (str1) return 1; - if (str2) return -1; - return 0; + if (str1 && str2) return strcmp (str1, str2); + if (str1) return 1; + if (str2) return -1; + return 0; } /**** @@ -772,71 +784,71 @@ char* tr_strsep (char ** str, const char * delims) { #ifdef HAVE_STRSEP - return strsep (str, delims); + return strsep (str, delims); #else - char *token; + char *token; - if (*str == NULL) { - /* No more tokens */ - return NULL; - } + if (*str == NULL) /* no more tokens */ + return NULL; - token = *str; - while (**str != '\0') { - if (strchr (delims, **str) != NULL) { - **str = '\0'; + token = *str; + while (**str != '\0') + { + if (strchr (delims, **str) != NULL) + { + **str = '\0'; (*str)++; return token; } (*str)++; } - /* There is not another token */ - *str = NULL; + /* there is not another token */ + *str = NULL; - return token; + return token; #endif } char* tr_strstrip (char * str) { - if (str != NULL) + if (str != NULL) { - size_t pos; - size_t len = strlen (str); + size_t pos; + size_t len = strlen (str); - while (len && isspace (str[len - 1])) - --len; + while (len && isspace (str[len - 1])) + --len; - for (pos = 0; pos < len && isspace (str[pos]);) - ++pos; + for (pos = 0; pos < len && isspace (str[pos]);) + ++pos; - len -= pos; - memmove (str, str + pos, len); - str[len] = '\0'; + len -= pos; + memmove (str, str + pos, len); + str[len] = '\0'; } - return str; + return str; } bool tr_str_has_suffix (const char *str, const char *suffix) { - size_t str_len; - size_t suffix_len; + size_t str_len; + size_t suffix_len; - if (!str) - return false; - if (!suffix) - return true; + if (!str) + return false; + if (!suffix) + return true; - str_len = strlen (str); - suffix_len = strlen (suffix); - if (str_len < suffix_len) - return false; + str_len = strlen (str); + suffix_len = strlen (suffix); + if (str_len < suffix_len) + return false; - return !evutil_ascii_strncasecmp (str + str_len - suffix_len, suffix, suffix_len); + return !evutil_ascii_strncasecmp (str + str_len - suffix_len, suffix, suffix_len); } /**** @@ -846,22 +858,22 @@ tr_str_has_suffix (const char *str, const char *suffix) uint64_t tr_time_msec (void) { - struct timeval tv; + struct timeval tv; - gettimeofday (&tv, NULL); - return (uint64_t) tv.tv_sec * 1000 + (tv.tv_usec / 1000); + gettimeofday (&tv, NULL); + return (uint64_t) tv.tv_sec * 1000 + (tv.tv_usec / 1000); } void tr_wait_msec (long int msec) { #ifdef WIN32 - Sleep ((DWORD)msec); + Sleep ((DWORD)msec); #else - struct timespec ts; - ts.tv_sec = msec / 1000; - ts.tv_nsec = (msec % 1000) * 1000000; - nanosleep (&ts, NULL); + struct timespec ts; + ts.tv_sec = msec / 1000; + ts.tv_nsec = (msec % 1000) * 1000000; + nanosleep (&ts, NULL); #endif } @@ -872,13 +884,13 @@ tr_wait_msec (long int msec) int tr_snprintf (char * buf, size_t buflen, const char * fmt, ...) { - int len; - va_list args; + int len; + va_list args; - va_start (args, fmt); - len = evutil_vsnprintf (buf, buflen, fmt, args); - va_end (args); - return len; + va_start (args, fmt); + len = evutil_vsnprintf (buf, buflen, fmt, args); + va_end (args); + return len; } /* @@ -890,35 +902,35 @@ size_t tr_strlcpy (char * dst, const void * src, size_t siz) { #ifdef HAVE_STRLCPY - return strlcpy (dst, src, siz); + return strlcpy (dst, src, siz); #else - char * d = dst; - const char *s = src; - size_t n = siz; + char * d = dst; + const char *s = src; + size_t n = siz; - assert (s); - assert (d); + assert (s); + assert (d); - /* Copy as many bytes as will fit */ - if (n != 0) + /* Copy as many bytes as will fit */ + if (n != 0) { - while (--n != 0) + while (--n != 0) { - if ((*d++ = *s++) == '\0') - break; + if ((*d++ = *s++) == '\0') + break; } } - /* Not enough room in dst, add NUL and traverse rest of src */ - if (n == 0) + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { - if (siz != 0) - *d = '\0'; /* NUL-terminate dst */ - while (*s++) - ; + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; } - return s - (char*)src - 1; /* count does not include NUL */ + return s - (char*)src - 1; /* count does not include NUL */ #endif } @@ -929,45 +941,45 @@ tr_strlcpy (char * dst, const void * src, size_t siz) double tr_getRatio (uint64_t numerator, uint64_t denominator) { - double ratio; + double ratio; - if (denominator > 0) - ratio = numerator / (double)denominator; - else if (numerator > 0) - ratio = TR_RATIO_INF; - else - ratio = TR_RATIO_NA; + if (denominator > 0) + ratio = numerator / (double)denominator; + else if (numerator > 0) + ratio = TR_RATIO_INF; + else + ratio = TR_RATIO_NA; - return ratio; + return ratio; } void tr_sha1_to_hex (char * out, const uint8_t * sha1) { - int i; - static const char hex[] = "0123456789abcdef"; + int i; + static const char hex[] = "0123456789abcdef"; - for (i=0; i<20; ++i) + for (i=0; i<20; ++i) { - const unsigned int val = *sha1++; - *out++ = hex[val >> 4]; - *out++ = hex[val & 0xf]; + const unsigned int val = *sha1++; + *out++ = hex[val >> 4]; + *out++ = hex[val & 0xf]; } - *out = '\0'; + *out = '\0'; } void tr_hex_to_sha1 (uint8_t * out, const char * in) { - int i; - static const char hex[] = "0123456789abcdef"; + int i; + static const char hex[] = "0123456789abcdef"; - for (i=0; i<20; ++i) + for (i=0; i<20; ++i) { - const int hi = strchr (hex, tolower (*in++)) - hex; - const int lo = strchr (hex, tolower (*in++)) - hex; - *out++ = (uint8_t)((hi<<4) | lo); + const int hi = strchr (hex, tolower (*in++)) - hex; + const int lo = strchr (hex, tolower (*in++)) - hex; + *out++ = (uint8_t)((hi<<4) | lo); } } @@ -978,77 +990,77 @@ tr_hex_to_sha1 (uint8_t * out, const char * in) static bool isValidURLChars (const char * url, int url_len) { - const char * c; - const char * end; - static const char * rfc2396_valid_chars = - "abcdefghijklmnopqrstuvwxyz" /* lowalpha */ - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" /* upalpha */ - "0123456789" /* digit */ - "-_.!~*'()" /* mark */ - ";/?:@&=+$," /* reserved */ - "<>#%<\"" /* delims */ - "{}|\\^[]`"; /* unwise */ + const char * c; + const char * end; + static const char * rfc2396_valid_chars = + "abcdefghijklmnopqrstuvwxyz" /* lowalpha */ + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" /* upalpha */ + "0123456789" /* digit */ + "-_.!~*'()" /* mark */ + ";/?:@&=+$," /* reserved */ + "<>#%<\"" /* delims */ + "{}|\\^[]`"; /* unwise */ - if (url == NULL) - return false; + if (url == NULL) + return false; - for (c=url, end=c+url_len; c && *c && c!=end; ++c) - if (!strchr (rfc2396_valid_chars, *c)) - return false; + for (c=url, end=c+url_len; c && *c && c!=end; ++c) + if (!strchr (rfc2396_valid_chars, *c)) + return false; - return true; + return true; } /** @brief return true if the URL is a http or https or UDP one that Transmission understands */ bool tr_urlIsValidTracker (const char * url) { - bool valid; + bool valid; - if (url == NULL) + if (url == NULL) { - valid = false; + valid = false; } - else + else { - const int len = strlen (url); + const int len = strlen (url); - valid = isValidURLChars (url, len) - && !tr_urlParse (url, len, NULL, NULL, NULL, NULL) - && (!memcmp (url,"http://",7) || !memcmp (url,"https://",8) || !memcmp (url,"udp://",6)); + valid = isValidURLChars (url, len) + && !tr_urlParse (url, len, NULL, NULL, NULL, NULL) + && (!memcmp (url,"http://",7) || !memcmp (url,"https://",8) || !memcmp (url,"udp://",6)); } - return valid; + return valid; } /** @brief return true if the URL is a http or https or ftp or sftp one that Transmission understands */ bool tr_urlIsValid (const char * url, int url_len) { - bool valid; + bool valid; - if (url == NULL) + if (url == NULL) { - valid = false; + valid = false; } - else + else { - if (url_len < 0) - url_len = strlen (url); + if (url_len < 0) + url_len = strlen (url); - valid = isValidURLChars (url, url_len) - && !tr_urlParse (url, url_len, NULL, NULL, NULL, NULL) - && (!memcmp (url,"http://",7) || !memcmp (url,"https://",8) || !memcmp (url,"ftp://",6) || !memcmp (url,"sftp://",7)); + valid = isValidURLChars (url, url_len) + && !tr_urlParse (url, url_len, NULL, NULL, NULL, NULL) + && (!memcmp (url,"http://",7) || !memcmp (url,"https://",8) || !memcmp (url,"ftp://",6) || !memcmp (url,"sftp://",7)); } - return valid; + return valid; } bool tr_addressIsIP (const char * str) { - tr_address tmp; - return tr_address_from_string (&tmp, str); + tr_address tmp; + return tr_address_from_string (&tmp, str); } int @@ -1059,72 +1071,70 @@ tr_urlParse (const char * url_in, int * setme_port, char ** setme_path) { - int err; - int port = 0; - int n; - char * tmp; - char * pch; - size_t host_len; - size_t protocol_len; - const char * host = NULL; - const char * protocol = NULL; - const char * path = NULL; + int err; + int port = 0; + int n; + char * tmp; + char * pch; + size_t host_len; + size_t protocol_len; + const char * host = NULL; + const char * protocol = NULL; + const char * path = NULL; - tmp = tr_strndup (url_in, len); - if ((pch = strstr (tmp, "://"))) + tmp = tr_strndup (url_in, len); + if ((pch = strstr (tmp, "://"))) { - *pch = '\0'; - protocol = tmp; - protocol_len = pch - protocol; - pch += 3; -/*fprintf (stderr, "protocol is [%s]... what's left is [%s]\n", protocol, pch);*/ - if ((n = strcspn (pch, ":/"))) + *pch = '\0'; + protocol = tmp; + protocol_len = pch - protocol; + pch += 3; + if ((n = strcspn (pch, ":/"))) { - const int havePort = pch[n] == ':'; - host = pch; - host_len = n; - pch += n; - if (pch && *pch) - *pch++ = '\0'; -/*fprintf (stderr, "host is [%s]... what's left is [%s]\n", host, pch);*/ - if (havePort) + const int havePort = pch[n] == ':'; + host = pch; + host_len = n; + pch += n; + if (pch && *pch) + *pch++ = '\0'; + if (havePort) { - char * end; - port = strtol (pch, &end, 10); - pch = end; -/*fprintf (stderr, "port is [%d]... what's left is [%s]\n", port, pch);*/ + char * end; + port = strtol (pch, &end, 10); + pch = end; } - path = pch; -/*fprintf (stderr, "path is [%s]\n", path);*/ + path = pch; } } - err = !host || !path || !protocol; + err = !host || !path || !protocol; - if (!err && !port) + if (!err && !port) { - if (!strcmp (protocol, "udp")) port = 80; - else if (!strcmp (protocol, "ftp")) port = 21; - else if (!strcmp (protocol, "sftp")) port = 22; - else if (!strcmp (protocol, "http")) port = 80; - else if (!strcmp (protocol, "https")) port = 443; + if (!strcmp (protocol, "udp")) port = 80; + else if (!strcmp (protocol, "ftp")) port = 21; + else if (!strcmp (protocol, "sftp")) port = 22; + else if (!strcmp (protocol, "http")) port = 80; + else if (!strcmp (protocol, "https")) port = 443; } - if (!err) + if (!err) { - if (setme_protocol) *setme_protocol = tr_strndup (protocol, protocol_len); + if (setme_protocol) *setme_protocol = tr_strndup (protocol, protocol_len); - if (setme_host){ ((char*)host)[-3] = ':'; *setme_host = - tr_strndup (host, host_len); } - if (setme_path){ if (!*path) *setme_path = tr_strdup ("/"); - else if (path[0] == '/') *setme_path = tr_strdup (path); - else { ((char*)path)[-1] = '/'; *setme_path = tr_strdup (path - 1); } } - if (setme_port) *setme_port = port; + if (setme_host){ ((char*)host)[-3] = ':'; *setme_host = + tr_strndup (host, host_len); } + + if (setme_path){ if (!*path) *setme_path = tr_strdup ("/"); + else if (path[0] == '/') *setme_path = tr_strdup (path); + else { ((char*)path)[-1] = '/'; *setme_path = tr_strdup (path - 1); } } + + if (setme_port) *setme_port = port; } - tr_free (tmp); - return err; + tr_free (tmp); + return err; } #include @@ -1137,34 +1147,34 @@ tr_urlParse (const char * url_in, char * tr_base64_encode (const void * input, int length, int * setme_len) { - int retlen = 0; - char * ret = NULL; + int retlen = 0; + char * ret = NULL; - if (input != NULL) + if (input != NULL) { - BIO * b64; - BIO * bmem; - BUF_MEM * bptr; + BIO * b64; + BIO * bmem; + BUF_MEM * bptr; - if (length < 1) - length = (int)strlen (input); + if (length < 1) + length = (int)strlen (input); - bmem = BIO_new (BIO_s_mem ()); - b64 = BIO_new (BIO_f_base64 ()); - BIO_set_flags (b64, BIO_FLAGS_BASE64_NO_NL); - b64 = BIO_push (b64, bmem); - BIO_write (b64, input, length); + bmem = BIO_new (BIO_s_mem ()); + b64 = BIO_new (BIO_f_base64 ()); + BIO_set_flags (b64, BIO_FLAGS_BASE64_NO_NL); + b64 = BIO_push (b64, bmem); + BIO_write (b64, input, length); (void) BIO_flush (b64); - BIO_get_mem_ptr (b64, &bptr); - ret = tr_strndup (bptr->data, bptr->length); - retlen = bptr->length; - BIO_free_all (b64); + BIO_get_mem_ptr (b64, &bptr); + ret = tr_strndup (bptr->data, bptr->length); + retlen = bptr->length; + BIO_free_all (b64); } - if (setme_len) - *setme_len = retlen; + if (setme_len) + *setme_len = retlen; - return ret; + return ret; } char * @@ -1172,35 +1182,35 @@ tr_base64_decode (const void * input, int length, int * setme_len) { - char * ret; - BIO * b64; - BIO * bmem; - int retlen; + char * ret; + BIO * b64; + BIO * bmem; + int retlen; - if (length < 1) - length = strlen (input); + if (length < 1) + length = strlen (input); - ret = tr_new0 (char, length); - b64 = BIO_new (BIO_f_base64 ()); - bmem = BIO_new_mem_buf ((unsigned char*)input, length); - bmem = BIO_push (b64, bmem); - retlen = BIO_read (bmem, ret, length); - if (!retlen) + ret = tr_new0 (char, length); + b64 = BIO_new (BIO_f_base64 ()); + bmem = BIO_new_mem_buf ((unsigned char*)input, length); + bmem = BIO_push (b64, bmem); + retlen = BIO_read (bmem, ret, length); + if (!retlen) { - /* try again, but with the BIO_FLAGS_BASE64_NO_NL flag */ - BIO_free_all (bmem); - b64 = BIO_new (BIO_f_base64 ()); - BIO_set_flags (b64, BIO_FLAGS_BASE64_NO_NL); - bmem = BIO_new_mem_buf ((unsigned char*)input, length); - bmem = BIO_push (b64, bmem); - retlen = BIO_read (bmem, ret, length); + /* try again, but with the BIO_FLAGS_BASE64_NO_NL flag */ + BIO_free_all (bmem); + b64 = BIO_new (BIO_f_base64 ()); + BIO_set_flags (b64, BIO_FLAGS_BASE64_NO_NL); + bmem = BIO_new_mem_buf ((unsigned char*)input, length); + bmem = BIO_push (b64, bmem); + retlen = BIO_read (bmem, ret, length); } - if (setme_len) - *setme_len = retlen; + if (setme_len) + *setme_len = retlen; - BIO_free_all (bmem); - return ret; + BIO_free_all (bmem); + return ret; } /*** @@ -1213,11 +1223,11 @@ tr_removeElementFromArray (void * array, size_t sizeof_element, size_t nmemb) { - char * a = array; + char * a = array; - memmove (a + sizeof_element * index_to_remove, - a + sizeof_element * (index_to_remove + 1), - sizeof_element * (--nmemb - index_to_remove)); + memmove (a + sizeof_element * index_to_remove, + a + sizeof_element * (index_to_remove + 1), + sizeof_element * (--nmemb - index_to_remove)); } int @@ -1228,29 +1238,31 @@ tr_lowerBound (const void * key, int (* compar)(const void* key, const void* arrayMember), bool * exact_match) { - size_t first = 0; - const char * cbase = base; - bool exact = false; + size_t first = 0; + const char * cbase = base; + bool exact = false; - while (nmemb != 0) + while (nmemb != 0) { - const size_t half = nmemb / 2; - const size_t middle = first + half; - const int c = compar (key, cbase + size*middle); + const size_t half = nmemb / 2; + const size_t middle = first + half; + const int c = compar (key, cbase + size*middle); - if (c <= 0) { - if (c == 0) - exact = true; - nmemb = half; - } else { - first = middle + 1; - nmemb = nmemb - half - 1; + if (c <= 0) + { + if (c == 0) + exact = true; + nmemb = half; + } + else + { + first = middle + 1; + nmemb = nmemb - half - 1; } } - *exact_match = exact; - - return first; + *exact_match = exact; + return first; } /*** @@ -1366,78 +1378,79 @@ tr_quickfindFirstK (void * base, size_t nmemb, size_t size, static char* strip_non_utf8 (const char * in, size_t inlen) { - const char * end; - const char zero = '\0'; - struct evbuffer * buf = evbuffer_new (); + const char * end; + const char zero = '\0'; + struct evbuffer * buf = evbuffer_new (); - while (!tr_utf8_validate (in, inlen, &end)) + while (!tr_utf8_validate (in, inlen, &end)) { - const int good_len = end - in; + const int good_len = end - in; - evbuffer_add (buf, in, good_len); - inlen -= (good_len + 1); - in += (good_len + 1); - evbuffer_add (buf, "?", 1); + evbuffer_add (buf, in, good_len); + inlen -= (good_len + 1); + in += (good_len + 1); + evbuffer_add (buf, "?", 1); } - evbuffer_add (buf, in, inlen); - evbuffer_add (buf, &zero, 1); - return evbuffer_free_to_str (buf); + evbuffer_add (buf, in, inlen); + evbuffer_add (buf, &zero, 1); + return evbuffer_free_to_str (buf); } static char* to_utf8 (const char * in, size_t inlen) { - char * ret = NULL; + char * ret = NULL; #ifdef HAVE_ICONV_OPEN - int i; - const char * encodings[] = { "CURRENT", "ISO-8859-15" }; - const int encoding_count = sizeof (encodings) / sizeof (encodings[1]); - const size_t buflen = inlen*4 + 10; - char * out = tr_new (char, buflen); + int i; + const char * encodings[] = { "CURRENT", "ISO-8859-15" }; + const int encoding_count = sizeof (encodings) / sizeof (encodings[1]); + const size_t buflen = inlen*4 + 10; + char * out = tr_new (char, buflen); - for (i=0; !ret && ilow = MIN (a, b); - setme->high = MAX (a, b); + tr_free (tmp); - errno = error; - return success; + setme->low = MIN (a, b); + setme->high = MAX (a, b); + + errno = error; + return success; } int compareInt (const void * va, const void * vb) { - const int a = * (const int *)va; - const int b = * (const int *)vb; - return a - b; + const int a = * (const int *)va; + const int b = * (const int *)vb; + return a - b; } /** @@ -1506,72 +1525,78 @@ compareInt (const void * va, const void * vb) int* tr_parseNumberRange (const char * str_in, int len, int * setmeCount) { - int n = 0; - int * uniq = NULL; - char * str = tr_strndup (str_in, len); - const char * walk; - tr_list * ranges = NULL; - bool success = true; + int n = 0; + int * uniq = NULL; + char * str = tr_strndup (str_in, len); + const char * walk; + tr_list * ranges = NULL; + bool success = true; - walk = str; - while (walk && *walk && success) { - struct number_range range; - const char * pch = strchr (walk, ','); - if (pch) { - success = parseNumberSection (walk, pch-walk, &range); - walk = pch + 1; - } else { - success = parseNumberSection (walk, strlen (walk), &range); - walk += strlen (walk); - } - if (success) - tr_list_append (&ranges, tr_memdup (&range, sizeof (struct number_range))); - } - - if (!success) + walk = str; + while (walk && *walk && success) { - *setmeCount = 0; - uniq = NULL; + struct number_range range; + const char * pch = strchr (walk, ','); + if (pch) + { + success = parseNumberSection (walk, pch-walk, &range); + walk = pch + 1; + } + else + { + success = parseNumberSection (walk, strlen (walk), &range); + walk += strlen (walk); + } + if (success) + tr_list_append (&ranges, tr_memdup (&range, sizeof (struct number_range))); } - else + + if (!success) { - int i; - int n2; - tr_list * l; - int * sorted = NULL; + *setmeCount = 0; + uniq = NULL; + } + else + { + int i; + int n2; + tr_list * l; + int * sorted = NULL; - /* build a sorted number array */ - n = n2 = 0; - for (l=ranges; l!=NULL; l=l->next) { - const struct number_range * r = l->data; - n += r->high + 1 - r->low; + /* build a sorted number array */ + n = n2 = 0; + for (l=ranges; l!=NULL; l=l->next) + { + const struct number_range * r = l->data; + n += r->high + 1 - r->low; } - sorted = tr_new (int, n); - for (l=ranges; l!=NULL; l=l->next) { - const struct number_range * r = l->data; - int i; - for (i=r->low; i<=r->high; ++i) - sorted[n2++] = i; + sorted = tr_new (int, n); + for (l=ranges; l!=NULL; l=l->next) + { + int i; + const struct number_range * r = l->data; + for (i=r->low; i<=r->high; ++i) + sorted[n2++] = i; } - qsort (sorted, n, sizeof (int), compareInt); - assert (n == n2); + qsort (sorted, n, sizeof (int), compareInt); + assert (n == n2); - /* remove duplicates */ - uniq = tr_new (int, n); - for (i=n=0; idecimal_point))) - pt[precision ? precision+1 : 0] = '\0'; - return atof (buf); + char * pt; + char buf[128]; + const int max_precision = (int) log10 (1.0 / DBL_EPSILON) - 1; + tr_snprintf (buf, sizeof (buf), "%.*f", max_precision, x); + if ((pt = strstr (buf, localeconv ()->decimal_point))) + pt[precision ? precision+1 : 0] = '\0'; + return atof (buf); } /* return a truncated double as a string */ static char* tr_strtruncd (char * buf, double x, int precision, size_t buflen) { - tr_snprintf (buf, buflen, "%.*f", precision, tr_truncd (x, precision)); - return buf; + tr_snprintf (buf, buflen, "%.*f", precision, tr_truncd (x, precision)); + return buf; } char* tr_strpercent (char * buf, double x, size_t buflen) { - if (x < 10.0) - tr_strtruncd (buf, x, 2, buflen); - else if (x < 100.0) - tr_strtruncd (buf, x, 1, buflen); - else - tr_strtruncd (buf, x, 0, buflen); - return buf; + if (x < 10.0) + tr_strtruncd (buf, x, 2, buflen); + else if (x < 100.0) + tr_strtruncd (buf, x, 1, buflen); + else + tr_strtruncd (buf, x, 0, buflen); + + return buf; } char* tr_strratio (char * buf, size_t buflen, double ratio, const char * infinity) { - if ((int)ratio == TR_RATIO_NA) - tr_strlcpy (buf, _("None"), buflen); - else if ((int)ratio == TR_RATIO_INF) - tr_strlcpy (buf, infinity, buflen); - else - tr_strpercent (buf, ratio, buflen); - return buf; + if ((int)ratio == TR_RATIO_NA) + tr_strlcpy (buf, _("None"), buflen); + else if ((int)ratio == TR_RATIO_INF) + tr_strlcpy (buf, infinity, buflen); + else + tr_strpercent (buf, ratio, buflen); + + return buf; } /*** @@ -1629,80 +1656,82 @@ tr_strratio (char * buf, size_t buflen, double ratio, const char * infinity) int tr_moveFile (const char * oldpath, const char * newpath, bool * renamed) { - int in; - int out; - char * buf; - struct stat st; - off_t bytesLeft; - const size_t buflen = 1024 * 128; /* 128 KiB buffer */ + int in; + int out; + char * buf; + struct stat st; + off_t bytesLeft; + const size_t buflen = 1024 * 128; /* 128 KiB buffer */ - /* make sure the old file exists */ - if (stat (oldpath, &st)) { - const int err = errno; - errno = err; - return -1; - } - if (!S_ISREG (st.st_mode)) { - errno = ENOENT; - return -1; - } - bytesLeft = st.st_size; - - /* make sure the target directory exists */ + /* make sure the old file exists */ + if (stat (oldpath, &st)) { - char * newdir = tr_dirname (newpath); - int i = tr_mkdirp (newdir, 0777); - tr_free (newdir); - if (i) - return i; + const int err = errno; + errno = err; + return -1; } - - /* they might be on the same filesystem... */ + if (!S_ISREG (st.st_mode)) { - const int i = rename (oldpath, newpath); - if (renamed != NULL) - *renamed = i == 0; - if (!i) - return 0; + errno = ENOENT; + return -1; } + bytesLeft = st.st_size; - /* copy the file */ - in = tr_open_file_for_scanning (oldpath); - out = tr_open_file_for_writing (newpath); - buf = tr_valloc (buflen); - while (bytesLeft > 0) + /* make sure the target directory exists */ + { + char * newdir = tr_dirname (newpath); + int i = tr_mkdirp (newdir, 0777); + tr_free (newdir); + if (i) + return i; + } + + /* they might be on the same filesystem... */ + { + const int i = rename (oldpath, newpath); + if (renamed != NULL) + *renamed = i == 0; + if (!i) + return 0; + } + + /* copy the file */ + in = tr_open_file_for_scanning (oldpath); + out = tr_open_file_for_writing (newpath); + buf = tr_valloc (buflen); + while (bytesLeft > 0) { - ssize_t bytesWritten; - const off_t bytesThisPass = MIN (bytesLeft, (off_t)buflen); - const int numRead = read (in, buf, bytesThisPass); - if (numRead < 0) - break; - bytesWritten = write (out, buf, numRead); - if (bytesWritten < 0) - break; - bytesLeft -= bytesWritten; + ssize_t bytesWritten; + const off_t bytesThisPass = MIN (bytesLeft, (off_t)buflen); + const int numRead = read (in, buf, bytesThisPass); + if (numRead < 0) + break; + bytesWritten = write (out, buf, numRead); + if (bytesWritten < 0) + break; + bytesLeft -= bytesWritten; } - /* cleanup */ - tr_free (buf); - tr_close_file (out); - tr_close_file (in); - if (bytesLeft != 0) - return -1; + /* cleanup */ + tr_free (buf); + tr_close_file (out); + tr_close_file (in); + if (bytesLeft != 0) + return -1; - unlink (oldpath); - return 0; + unlink (oldpath); + return 0; } bool tr_is_same_file (const char * filename1, const char * filename2) { - struct stat sb1, sb2; + struct stat sb1, sb2; - return !stat (filename1, &sb1) - && !stat (filename2, &sb2) - && (sb1.st_dev == sb2.st_dev) - && (sb1.st_ino == sb2.st_ino); + return !stat (filename1, &sb1) + && !stat (filename2, &sb2) + && (sb1.st_dev == sb2.st_dev) + && (sb1.st_ino == sb2.st_ino); } /*** @@ -1712,47 +1741,48 @@ tr_is_same_file (const char * filename1, const char * filename2) void* tr_valloc (size_t bufLen) { - size_t allocLen; - void * buf = NULL; - static size_t pageSize = 0; + size_t allocLen; + void * buf = NULL; + static size_t pageSize = 0; - if (!pageSize) { + if (!pageSize) + { #ifdef HAVE_GETPAGESIZE - pageSize = (size_t) getpagesize (); + pageSize = (size_t) getpagesize (); #else /* guess */ - pageSize = 4096; + pageSize = 4096; #endif } - allocLen = pageSize; - while (allocLen < bufLen) - allocLen += pageSize; + allocLen = pageSize; + while (allocLen < bufLen) + allocLen += pageSize; #ifdef HAVE_POSIX_MEMALIGN - if (!buf) - if (posix_memalign (&buf, pageSize, allocLen)) - buf = NULL; /* just retry with valloc/malloc */ + if (!buf) + if (posix_memalign (&buf, pageSize, allocLen)) + buf = NULL; /* just retry with valloc/malloc */ #endif #ifdef HAVE_VALLOC - if (!buf) - buf = valloc (allocLen); + if (!buf) + buf = valloc (allocLen); #endif - if (!buf) - buf = tr_malloc (allocLen); + if (!buf) + buf = tr_malloc (allocLen); - return buf; + return buf; } char * tr_realpath (const char * path, char * resolved_path) { #ifdef WIN32 - /* From a message to the Mingw-msys list, Jun 2, 2005 by Mark Junker. */ - if (GetFullPathNameA (path, TR_PATH_MAX, resolved_path, NULL) == 0) - return NULL; - return resolved_path; + /* From a message to the Mingw-msys list, Jun 2, 2005 by Mark Junker. */ + if (GetFullPathNameA (path, TR_PATH_MAX, resolved_path, NULL) == 0) + return NULL; + return resolved_path; #else - return realpath (path, resolved_path); + return realpath (path, resolved_path); #endif } @@ -1764,14 +1794,14 @@ uint64_t tr_htonll (uint64_t x) { #ifdef HAVE_HTONLL - return htonll (x); + return htonll (x); #else - /* fallback code by bdonlan at - * http://stackoverflow.com/questions/809902/64-bit-ntohl-in-c/875505#875505 */ - union { uint32_t lx[2]; uint64_t llx; } u; - u.lx[0] = htonl (x >> 32); - u.lx[1] = htonl (x & 0xFFFFFFFFULL); - return u.llx; + /* fallback code by bdonlan at + * http://stackoverflow.com/questions/809902/64-bit-ntohl-in-c/875505#875505 */ + union { uint32_t lx[2]; uint64_t llx; } u; + u.lx[0] = htonl (x >> 32); + u.lx[1] = htonl (x & 0xFFFFFFFFULL); + return u.llx; #endif } @@ -1779,13 +1809,13 @@ uint64_t tr_ntohll (uint64_t x) { #ifdef HAVE_NTOHLL - return ntohll (x); + return ntohll (x); #else - /* fallback code by bdonlan at - * http://stackoverflow.com/questions/809902/64-bit-ntohl-in-c/875505#875505 */ - union { uint32_t lx[2]; uint64_t llx; } u; - u.llx = x; - return ((uint64_t)ntohl (u.lx[0]) << 32) | (uint64_t)ntohl (u.lx[1]); + /* fallback code by bdonlan at + * http://stackoverflow.com/questions/809902/64-bit-ntohl-in-c/875505#875505 */ + union { uint32_t lx[2]; uint64_t llx; } u; + u.llx = x; + return ((uint64_t)ntohl (u.lx[0]) << 32) | (uint64_t)ntohl (u.lx[1]); #endif } @@ -1797,13 +1827,13 @@ tr_ntohll (uint64_t x) struct formatter_unit { - char * name; - int64_t value; + char * name; + int64_t value; }; struct formatter_units { - struct formatter_unit units[4]; + struct formatter_unit units[4]; }; enum { TR_FMT_KB, TR_FMT_MB, TR_FMT_GB, TR_FMT_TB }; @@ -1814,47 +1844,51 @@ formatter_init (struct formatter_units * units, const char * kb, const char * mb, const char * gb, const char * tb) { - uint64_t value = kilo; - units->units[TR_FMT_KB].name = tr_strdup (kb); - units->units[TR_FMT_KB].value = value; + uint64_t value; - value *= kilo; - units->units[TR_FMT_MB].name = tr_strdup (mb); - units->units[TR_FMT_MB].value = value; + value = kilo; + units->units[TR_FMT_KB].name = tr_strdup (kb); + units->units[TR_FMT_KB].value = value; - value *= kilo; - units->units[TR_FMT_GB].name = tr_strdup (gb); - units->units[TR_FMT_GB].value = value; + value *= kilo; + units->units[TR_FMT_MB].name = tr_strdup (mb); + units->units[TR_FMT_MB].value = value; - value *= kilo; - units->units[TR_FMT_TB].name = tr_strdup (tb); - units->units[TR_FMT_TB].value = value; + value *= kilo; + units->units[TR_FMT_GB].name = tr_strdup (gb); + units->units[TR_FMT_GB].value = value; + + value *= kilo; + units->units[TR_FMT_TB].name = tr_strdup (tb); + units->units[TR_FMT_TB].value = value; } static char* formatter_get_size_str (const struct formatter_units * u, char * buf, int64_t bytes, size_t buflen) { - int precision; - double value; - const char * units; - const struct formatter_unit * unit; + int precision; + double value; + const char * units; + const struct formatter_unit * unit; - if (bytes < u->units[1].value) unit = &u->units[0]; - else if (bytes < u->units[2].value) unit = &u->units[1]; - else if (bytes < u->units[3].value) unit = &u->units[2]; - else unit = &u->units[3]; + if (bytes < u->units[1].value) unit = &u->units[0]; + else if (bytes < u->units[2].value) unit = &u->units[1]; + else if (bytes < u->units[3].value) unit = &u->units[2]; + else unit = &u->units[3]; - value = (double)bytes / unit->value; - units = unit->name; - if (unit->value == 1) - precision = 0; - else if (value < 100) - precision = 2; - else - precision = 1; - tr_snprintf (buf, buflen, "%.*f %s", precision, value, units); - return buf; + value = (double)bytes / unit->value; + units = unit->name; + + if (unit->value == 1) + precision = 0; + else if (value < 100) + precision = 2; + else + precision = 1; + + tr_snprintf (buf, buflen, "%.*f %s", precision, value, units); + return buf; } static struct formatter_units size_units; @@ -1864,13 +1898,13 @@ tr_formatter_size_init (unsigned int kilo, const char * kb, const char * mb, const char * gb, const char * tb) { - formatter_init (&size_units, kilo, kb, mb, gb, tb); + formatter_init (&size_units, kilo, kb, mb, gb, tb); } char* tr_formatter_size_B (char * buf, int64_t bytes, size_t buflen) { - return formatter_get_size_str (&size_units, buf, bytes, buflen); + return formatter_get_size_str (&size_units, buf, bytes, buflen); } static struct formatter_units speed_units; @@ -1882,31 +1916,33 @@ tr_formatter_speed_init (unsigned int kilo, const char * kb, const char * mb, const char * gb, const char * tb) { - tr_speed_K = kilo; - formatter_init (&speed_units, kilo, kb, mb, gb, tb); + tr_speed_K = kilo; + formatter_init (&speed_units, kilo, kb, mb, gb, tb); } char* tr_formatter_speed_KBps (char * buf, double KBps, size_t buflen) { - const double K = speed_units.units[TR_FMT_KB].value; - double speed = KBps; + const double K = speed_units.units[TR_FMT_KB].value; + double speed = KBps; - if (speed <= 999.95) /* 0.0 KB to 999.9 KB */ - tr_snprintf (buf, buflen, "%d %s", (int)speed, speed_units.units[TR_FMT_KB].name); - else { - speed /= K; - if (speed <= 99.995) /* 0.98 MB to 99.99 MB */ - tr_snprintf (buf, buflen, "%.2f %s", speed, speed_units.units[TR_FMT_MB].name); - else if (speed <= 999.95) /* 100.0 MB to 999.9 MB */ - tr_snprintf (buf, buflen, "%.1f %s", speed, speed_units.units[TR_FMT_MB].name); - else { - speed /= K; - tr_snprintf (buf, buflen, "%.1f %s", speed, speed_units.units[TR_FMT_GB].name); - } + if (speed <= 999.95) /* 0.0 KB to 999.9 KB */ + { + tr_snprintf (buf, buflen, "%d %s", (int)speed, speed_units.units[TR_FMT_KB].name); + } + else + { + speed /= K; + + if (speed <= 99.995) /* 0.98 MB to 99.99 MB */ + tr_snprintf (buf, buflen, "%.2f %s", speed, speed_units.units[TR_FMT_MB].name); + else if (speed <= 999.95) /* 100.0 MB to 999.9 MB */ + tr_snprintf (buf, buflen, "%.1f %s", speed, speed_units.units[TR_FMT_MB].name); + else + tr_snprintf (buf, buflen, "%.1f %s", speed/K, speed_units.units[TR_FMT_GB].name); } - return buf; + return buf; } static struct formatter_units mem_units; @@ -1918,14 +1954,14 @@ tr_formatter_mem_init (unsigned int kilo, const char * kb, const char * mb, const char * gb, const char * tb) { - tr_mem_K = kilo; - formatter_init (&mem_units, kilo, kb, mb, gb, tb); + tr_mem_K = kilo; + formatter_init (&mem_units, kilo, kb, mb, gb, tb); } char* tr_formatter_mem_B (char * buf, int64_t bytes_per_second, size_t buflen) { - return formatter_get_size_str (&mem_units, buf, bytes_per_second, buflen); + return formatter_get_size_str (&mem_units, buf, bytes_per_second, buflen); } void diff --git a/libtransmission/web.c b/libtransmission/web.c index b328180d4..867f82732 100644 --- a/libtransmission/web.c +++ b/libtransmission/web.c @@ -38,21 +38,21 @@ enum { - THREADFUNC_MAX_SLEEP_MSEC = 1000, + THREADFUNC_MAX_SLEEP_MSEC = 1000, }; #if 0 #define dbgmsg(...) \ - do { \ - fprintf (stderr, __VA_ARGS__); \ - fprintf (stderr, "\n"); \ - } while (0) + do { \ + fprintf (stderr, __VA_ARGS__); \ + fprintf (stderr, "\n"); \ + } while (0) #else #define dbgmsg(...) \ - do { \ - if (tr_deepLoggingIsActive ()) \ - tr_deepLog (__FILE__, __LINE__, "web", __VA_ARGS__); \ - } while (0) + do { \ + if (tr_deepLoggingIsActive ()) \ + tr_deepLog (__FILE__, __LINE__, "web", __VA_ARGS__); \ + } while (0) #endif /*** @@ -61,31 +61,31 @@ enum struct tr_web_task { - long code; - long timeout_secs; - bool did_connect; - bool did_timeout; - struct evbuffer * response; - struct evbuffer * freebuf; - char * url; - char * range; - char * cookies; - tr_session * session; - tr_web_done_func * done_func; - void * done_func_user_data; - CURL * curl_easy; - struct tr_web_task * next; + long code; + long timeout_secs; + bool did_connect; + bool did_timeout; + struct evbuffer * response; + struct evbuffer * freebuf; + char * url; + char * range; + char * cookies; + tr_session * session; + tr_web_done_func * done_func; + void * done_func_user_data; + CURL * curl_easy; + struct tr_web_task * next; }; static void task_free (struct tr_web_task * task) { - if (task->freebuf) - evbuffer_free (task->freebuf); - tr_free (task->cookies); - tr_free (task->range); - tr_free (task->url); - tr_free (task); + if (task->freebuf) + evbuffer_free (task->freebuf); + tr_free (task->cookies); + tr_free (task->range); + tr_free (task->url); + tr_free (task); } /*** @@ -94,13 +94,13 @@ task_free (struct tr_web_task * task) struct tr_web { - bool curl_verbose; - bool curl_ssl_verify; - const char * curl_ca_bundle; - int close_mode; - struct tr_web_task * tasks; - tr_lock * taskLock; - char * cookie_filename; + bool curl_verbose; + bool curl_ssl_verify; + const char * curl_ca_bundle; + int close_mode; + struct tr_web_task * tasks; + tr_lock * taskLock; + char * cookie_filename; }; /*** @@ -110,97 +110,101 @@ struct tr_web static size_t writeFunc (void * ptr, size_t size, size_t nmemb, void * vtask) { - const size_t byteCount = size * nmemb; - struct tr_web_task * task = vtask; - evbuffer_add (task->response, ptr, byteCount); - dbgmsg ("wrote %zu bytes to task %p's buffer", byteCount, task); - return byteCount; + const size_t byteCount = size * nmemb; + struct tr_web_task * task = vtask; + evbuffer_add (task->response, ptr, byteCount); + dbgmsg ("wrote %zu bytes to task %p's buffer", byteCount, task); + return byteCount; } #ifdef USE_LIBCURL_SOCKOPT static int sockoptfunction (void * vtask, curl_socket_t fd, curlsocktype purpose UNUSED) { - struct tr_web_task * task = vtask; - const bool isScrape = strstr (task->url, "scrape") != NULL; - const bool isAnnounce = strstr (task->url, "announce") != NULL; + struct tr_web_task * task = vtask; + const bool isScrape = strstr (task->url, "scrape") != NULL; + const bool isAnnounce = strstr (task->url, "announce") != NULL; - /* announce and scrape requests have tiny payloads. */ - if (isScrape || isAnnounce) + /* announce and scrape requests have tiny payloads. */ + if (isScrape || isAnnounce) { - const int sndbuf = 1024; - const int rcvbuf = isScrape ? 2048 : 3072; - setsockopt (fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof (sndbuf)); - setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof (rcvbuf)); + const int sndbuf = 1024; + const int rcvbuf = isScrape ? 2048 : 3072; + setsockopt (fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof (sndbuf)); + setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof (rcvbuf)); } - /* return nonzero if this function encountered an error */ - return 0; + /* return nonzero if this function encountered an error */ + return 0; } #endif static long getTimeoutFromURL (const struct tr_web_task * task) { - long timeout; - const tr_session * session = task->session; + long timeout; + const tr_session * session = task->session; - if (!session || session->isClosed) timeout = 20L; - else if (strstr (task->url, "scrape") != NULL) timeout = 30L; - else if (strstr (task->url, "announce") != NULL) timeout = 90L; - else timeout = 240L; + if (!session || session->isClosed) timeout = 20L; + else if (strstr (task->url, "scrape") != NULL) timeout = 30L; + else if (strstr (task->url, "announce") != NULL) timeout = 90L; + else timeout = 240L; - return timeout; + return timeout; } static CURL * createEasy (tr_session * s, struct tr_web * web, struct tr_web_task * task) { - bool is_default_value; - const tr_address * addr; - CURL * e = task->curl_easy = curl_easy_init (); + bool is_default_value; + const tr_address * addr; + CURL * e = task->curl_easy = curl_easy_init (); - task->timeout_secs = getTimeoutFromURL (task); + task->timeout_secs = getTimeoutFromURL (task); - curl_easy_setopt (e, CURLOPT_AUTOREFERER, 1L); - curl_easy_setopt (e, CURLOPT_COOKIEFILE, web->cookie_filename); - curl_easy_setopt (e, CURLOPT_ENCODING, "gzip;q=1.0, deflate, identity"); - curl_easy_setopt (e, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt (e, CURLOPT_MAXREDIRS, -1L); - curl_easy_setopt (e, CURLOPT_NOSIGNAL, 1L); - curl_easy_setopt (e, CURLOPT_PRIVATE, task); + curl_easy_setopt (e, CURLOPT_AUTOREFERER, 1L); + curl_easy_setopt (e, CURLOPT_COOKIEFILE, web->cookie_filename); + curl_easy_setopt (e, CURLOPT_ENCODING, "gzip;q=1.0, deflate, identity"); + curl_easy_setopt (e, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt (e, CURLOPT_MAXREDIRS, -1L); + curl_easy_setopt (e, CURLOPT_NOSIGNAL, 1L); + curl_easy_setopt (e, CURLOPT_PRIVATE, task); #ifdef USE_LIBCURL_SOCKOPT - curl_easy_setopt (e, CURLOPT_SOCKOPTFUNCTION, sockoptfunction); - curl_easy_setopt (e, CURLOPT_SOCKOPTDATA, task); + curl_easy_setopt (e, CURLOPT_SOCKOPTFUNCTION, sockoptfunction); + curl_easy_setopt (e, CURLOPT_SOCKOPTDATA, task); #endif - if (web->curl_ssl_verify) - curl_easy_setopt (e, CURLOPT_CAINFO, web->curl_ca_bundle); - else { - curl_easy_setopt (e, CURLOPT_SSL_VERIFYHOST, 0L); - curl_easy_setopt (e, CURLOPT_SSL_VERIFYPEER, 0L); + if (web->curl_ssl_verify) + { + curl_easy_setopt (e, CURLOPT_CAINFO, web->curl_ca_bundle); } - curl_easy_setopt (e, CURLOPT_TIMEOUT, task->timeout_secs); - curl_easy_setopt (e, CURLOPT_URL, task->url); - curl_easy_setopt (e, CURLOPT_USERAGENT, TR_NAME "/" SHORT_VERSION_STRING); - curl_easy_setopt (e, CURLOPT_VERBOSE, (long)(web->curl_verbose?1:0)); - curl_easy_setopt (e, CURLOPT_WRITEDATA, task); - curl_easy_setopt (e, CURLOPT_WRITEFUNCTION, writeFunc); + else + { + curl_easy_setopt (e, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt (e, CURLOPT_SSL_VERIFYPEER, 0L); + } + curl_easy_setopt (e, CURLOPT_TIMEOUT, task->timeout_secs); + curl_easy_setopt (e, CURLOPT_URL, task->url); + curl_easy_setopt (e, CURLOPT_USERAGENT, TR_NAME "/" SHORT_VERSION_STRING); + curl_easy_setopt (e, CURLOPT_VERBOSE, (long)(web->curl_verbose?1:0)); + curl_easy_setopt (e, CURLOPT_WRITEDATA, task); + curl_easy_setopt (e, CURLOPT_WRITEFUNCTION, writeFunc); - if (((addr = tr_sessionGetPublicAddress (s, TR_AF_INET, &is_default_value))) && !is_default_value) - curl_easy_setopt (e, CURLOPT_INTERFACE, tr_address_to_string (addr)); - else if (((addr = tr_sessionGetPublicAddress (s, TR_AF_INET6, &is_default_value))) && !is_default_value) - curl_easy_setopt (e, CURLOPT_INTERFACE, tr_address_to_string (addr)); + if (((addr = tr_sessionGetPublicAddress (s, TR_AF_INET, &is_default_value))) && !is_default_value) + curl_easy_setopt (e, CURLOPT_INTERFACE, tr_address_to_string (addr)); + else if (((addr = tr_sessionGetPublicAddress (s, TR_AF_INET6, &is_default_value))) && !is_default_value) + curl_easy_setopt (e, CURLOPT_INTERFACE, tr_address_to_string (addr)); - if (task->cookies != NULL) - curl_easy_setopt (e, CURLOPT_COOKIE, task->cookies); + if (task->cookies != NULL) + curl_easy_setopt (e, CURLOPT_COOKIE, task->cookies); - if (task->range != NULL) { - curl_easy_setopt (e, CURLOPT_RANGE, task->range); - /* don't bother asking the server to compress webseed fragments */ - curl_easy_setopt (e, CURLOPT_ENCODING, "identity"); + if (task->range != NULL) + { + curl_easy_setopt (e, CURLOPT_RANGE, task->range); + /* don't bother asking the server to compress webseed fragments */ + curl_easy_setopt (e, CURLOPT_ENCODING, "identity"); } - return e; + return e; } /*** @@ -210,19 +214,19 @@ createEasy (tr_session * s, struct tr_web * web, struct tr_web_task * task) static void task_finish_func (void * vtask) { - struct tr_web_task * task = vtask; - dbgmsg ("finished web task %p; got %ld", task, task->code); + struct tr_web_task * task = vtask; + dbgmsg ("finished web task %p; got %ld", task, task->code); - if (task->done_func != NULL) - task->done_func (task->session, - task->did_connect, - task->did_timeout, - task->code, - evbuffer_pullup (task->response, -1), - evbuffer_get_length (task->response), - task->done_func_user_data); + if (task->done_func != NULL) + task->done_func (task->session, + task->did_connect, + task->did_timeout, + task->code, + evbuffer_pullup (task->response, -1), + evbuffer_get_length (task->response), + task->done_func_user_data); - task_free (task); + task_free (task); } /**** @@ -237,9 +241,9 @@ tr_webRun (tr_session * session, tr_web_done_func done_func, void * done_func_user_data) { - return tr_webRunWithBuffer (session, url, range, cookies, - done_func, done_func_user_data, - NULL); + return tr_webRunWithBuffer (session, url, range, cookies, + done_func, done_func_user_data, + NULL); } struct tr_web_task * @@ -251,28 +255,29 @@ tr_webRunWithBuffer (tr_session * session, void * done_func_user_data, struct evbuffer * buffer) { - struct tr_web * web = session->web; + struct tr_web * web = session->web; - if (web != NULL) + if (web != NULL) { - struct tr_web_task * task = tr_new0 (struct tr_web_task, 1); + struct tr_web_task * task = tr_new0 (struct tr_web_task, 1); - task->session = session; - task->url = tr_strdup (url); - task->range = tr_strdup (range); - task->cookies = tr_strdup (cookies); - task->done_func = done_func; - task->done_func_user_data = done_func_user_data; - task->response = buffer ? buffer : evbuffer_new (); - task->freebuf = buffer ? NULL : task->response; + task->session = session; + task->url = tr_strdup (url); + task->range = tr_strdup (range); + task->cookies = tr_strdup (cookies); + task->done_func = done_func; + task->done_func_user_data = done_func_user_data; + task->response = buffer ? buffer : evbuffer_new (); + task->freebuf = buffer ? NULL : task->response; - tr_lockLock (web->taskLock); - task->next = web->tasks; - web->tasks = task; - tr_lockUnlock (web->taskLock); - return task; + tr_lockLock (web->taskLock); + task->next = web->tasks; + web->tasks = task; + tr_lockUnlock (web->taskLock); + return task; } - return NULL; + + return NULL; } /** @@ -289,183 +294,184 @@ tr_select (int nfds, struct timeval * t) { #ifdef WIN32 - if (!r_fd_set->fd_count && !w_fd_set->fd_count && !c_fd_set->fd_count) + if (!r_fd_set->fd_count && !w_fd_set->fd_count && !c_fd_set->fd_count) { - const long int msec = t->tv_sec*1000 + t->tv_usec/1000; - tr_wait_msec (msec); + const long int msec = t->tv_sec*1000 + t->tv_usec/1000; + tr_wait_msec (msec); } - else if (select (0, r_fd_set->fd_count ? r_fd_set : NULL, - w_fd_set->fd_count ? w_fd_set : NULL, - c_fd_set->fd_count ? c_fd_set : NULL, t) < 0) + else if (select (0, r_fd_set->fd_count ? r_fd_set : NULL, + w_fd_set->fd_count ? w_fd_set : NULL, + c_fd_set->fd_count ? c_fd_set : NULL, t) < 0) { - char errstr[512]; - const int e = EVUTIL_SOCKET_ERROR (); - tr_net_strerror (errstr, sizeof (errstr), e); - dbgmsg ("Error: select (%d) %s", e, errstr); + char errstr[512]; + const int e = EVUTIL_SOCKET_ERROR (); + tr_net_strerror (errstr, sizeof (errstr), e); + dbgmsg ("Error: select (%d) %s", e, errstr); } #else - select (nfds, r_fd_set, w_fd_set, c_fd_set, t); + select (nfds, r_fd_set, w_fd_set, c_fd_set, t); #endif } static void tr_webThreadFunc (void * vsession) { - CURLM * multi; - struct tr_web * web; - int taskCount = 0; - struct tr_web_task * task; - tr_session * session = vsession; + CURLM * multi; + struct tr_web * web; + int taskCount = 0; + struct tr_web_task * task; + tr_session * session = vsession; - /* try to enable ssl for https support; but if that fails, - * try a plain vanilla init */ - if (curl_global_init (CURL_GLOBAL_SSL)) - curl_global_init (0); + /* try to enable ssl for https support; but if that fails, + * try a plain vanilla init */ + if (curl_global_init (CURL_GLOBAL_SSL)) + curl_global_init (0); - web = tr_new0 (struct tr_web, 1); - web->close_mode = ~0; - web->taskLock = tr_lockNew (); - web->tasks = NULL; - web->curl_verbose = getenv ("TR_CURL_VERBOSE") != NULL; - web->curl_ssl_verify = getenv ("TR_CURL_SSL_VERIFY") != NULL; - web->curl_ca_bundle = getenv ("CURL_CA_BUNDLE"); - if (web->curl_ssl_verify) { - tr_ninf ("web", "will verify tracker certs using envvar CURL_CA_BUNDLE: %s", - web->curl_ca_bundle == NULL ? "none" : web->curl_ca_bundle); - tr_ninf ("web", "NB: this only works if you built against libcurl with openssl or gnutls, NOT nss"); - tr_ninf ("web", "NB: invalid certs will show up as 'Could not connect to tracker' like many other errors"); - } - web->cookie_filename = tr_buildPath (session->configDir, "cookies.txt", NULL); - - multi = curl_multi_init (); - session->web = web; - - for (;;) + web = tr_new0 (struct tr_web, 1); + web->close_mode = ~0; + web->taskLock = tr_lockNew (); + web->tasks = NULL; + web->curl_verbose = getenv ("TR_CURL_VERBOSE") != NULL; + web->curl_ssl_verify = getenv ("TR_CURL_SSL_VERIFY") != NULL; + web->curl_ca_bundle = getenv ("CURL_CA_BUNDLE"); + if (web->curl_ssl_verify) { - long msec; - int unused; - CURLMsg * msg; - CURLMcode mcode; + tr_ninf ("web", "will verify tracker certs using envvar CURL_CA_BUNDLE: %s", + web->curl_ca_bundle == NULL ? "none" : web->curl_ca_bundle); + tr_ninf ("web", "NB: this only works if you built against libcurl with openssl or gnutls, NOT nss"); + tr_ninf ("web", "NB: invalid certs will show up as 'Could not connect to tracker' like many other errors"); + } + web->cookie_filename = tr_buildPath (session->configDir, "cookies.txt", NULL); - if (web->close_mode == TR_WEB_CLOSE_NOW) - break; - if ((web->close_mode == TR_WEB_CLOSE_WHEN_IDLE) && (web->tasks == NULL)) - break; + multi = curl_multi_init (); + session->web = web; - /* add tasks from the queue */ - tr_lockLock (web->taskLock); - while (web->tasks != NULL) + for (;;) + { + long msec; + int unused; + CURLMsg * msg; + CURLMcode mcode; + + if (web->close_mode == TR_WEB_CLOSE_NOW) + break; + if ((web->close_mode == TR_WEB_CLOSE_WHEN_IDLE) && (web->tasks == NULL)) + break; + + /* add tasks from the queue */ + tr_lockLock (web->taskLock); + while (web->tasks != NULL) { - /* pop the task */ - task = web->tasks; - web->tasks = task->next; - task->next = NULL; + /* pop the task */ + task = web->tasks; + web->tasks = task->next; + task->next = NULL; - dbgmsg ("adding task to curl: [%s]", task->url); - curl_multi_add_handle (multi, createEasy (session, web, task)); - /*fprintf (stderr, "adding a task.. taskCount is now %d\n", taskCount);*/ - ++taskCount; + dbgmsg ("adding task to curl: [%s]", task->url); + curl_multi_add_handle (multi, createEasy (session, web, task)); + /*fprintf (stderr, "adding a task.. taskCount is now %d\n", taskCount);*/ + ++taskCount; } - tr_lockUnlock (web->taskLock); + tr_lockUnlock (web->taskLock); - /* maybe wait a little while before calling curl_multi_perform () */ - msec = 0; - curl_multi_timeout (multi, &msec); - if (msec < 0) + /* maybe wait a little while before calling curl_multi_perform () */ + msec = 0; + curl_multi_timeout (multi, &msec); + if (msec < 0) + msec = THREADFUNC_MAX_SLEEP_MSEC; + if (session->isClosed) + msec = 100; /* on shutdown, call perform () more frequently */ + if (msec > 0) + { + int usec; + int max_fd; + struct timeval t; + fd_set r_fd_set, w_fd_set, c_fd_set; + + max_fd = 0; + FD_ZERO (&r_fd_set); + FD_ZERO (&w_fd_set); + FD_ZERO (&c_fd_set); + curl_multi_fdset (multi, &r_fd_set, &w_fd_set, &c_fd_set, &max_fd); + + if (msec > THREADFUNC_MAX_SLEEP_MSEC) msec = THREADFUNC_MAX_SLEEP_MSEC; - if (session->isClosed) - msec = 100; /* on shutdown, call perform () more frequently */ - if (msec > 0) - { - int usec; - int max_fd; - struct timeval t; - fd_set r_fd_set, w_fd_set, c_fd_set; - max_fd = 0; - FD_ZERO (&r_fd_set); - FD_ZERO (&w_fd_set); - FD_ZERO (&c_fd_set); - curl_multi_fdset (multi, &r_fd_set, &w_fd_set, &c_fd_set, &max_fd); - - if (msec > THREADFUNC_MAX_SLEEP_MSEC) - msec = THREADFUNC_MAX_SLEEP_MSEC; - - usec = msec * 1000; - t.tv_sec = usec / 1000000; - t.tv_usec = usec % 1000000; - tr_select (max_fd+1, &r_fd_set, &w_fd_set, &c_fd_set, &t); + usec = msec * 1000; + t.tv_sec = usec / 1000000; + t.tv_usec = usec % 1000000; + tr_select (max_fd+1, &r_fd_set, &w_fd_set, &c_fd_set, &t); } - /* call curl_multi_perform () */ - do { - mcode = curl_multi_perform (multi, &unused); - } while (mcode == CURLM_CALL_MULTI_PERFORM); + /* call curl_multi_perform () */ + do + mcode = curl_multi_perform (multi, &unused); + while (mcode == CURLM_CALL_MULTI_PERFORM); - /* pump completed tasks from the multi */ - while ((msg = curl_multi_info_read (multi, &unused))) + /* pump completed tasks from the multi */ + while ((msg = curl_multi_info_read (multi, &unused))) { - if ((msg->msg == CURLMSG_DONE) && (msg->easy_handle != NULL)) + if ((msg->msg == CURLMSG_DONE) && (msg->easy_handle != NULL)) { - double total_time; - struct tr_web_task * task; - long req_bytes_sent; - CURL * e = msg->easy_handle; - curl_easy_getinfo (e, CURLINFO_PRIVATE, (void*)&task); - curl_easy_getinfo (e, CURLINFO_RESPONSE_CODE, &task->code); - curl_easy_getinfo (e, CURLINFO_REQUEST_SIZE, &req_bytes_sent); - curl_easy_getinfo (e, CURLINFO_TOTAL_TIME, &total_time); - task->did_connect = task->code>0 || req_bytes_sent>0; - task->did_timeout = !task->code && (total_time >= task->timeout_secs); - curl_multi_remove_handle (multi, e); - curl_easy_cleanup (e); -/*fprintf (stderr, "removing a completed task.. taskCount is now %d (response code: %d, response len: %d)\n", taskCount, (int)task->code, (int)evbuffer_get_length (task->response));*/ - tr_runInEventThread (task->session, task_finish_func, task); - --taskCount; + double total_time; + struct tr_web_task * task; + long req_bytes_sent; + CURL * e = msg->easy_handle; + curl_easy_getinfo (e, CURLINFO_PRIVATE, (void*)&task); + curl_easy_getinfo (e, CURLINFO_RESPONSE_CODE, &task->code); + curl_easy_getinfo (e, CURLINFO_REQUEST_SIZE, &req_bytes_sent); + curl_easy_getinfo (e, CURLINFO_TOTAL_TIME, &total_time); + task->did_connect = task->code>0 || req_bytes_sent>0; + task->did_timeout = !task->code && (total_time >= task->timeout_secs); + curl_multi_remove_handle (multi, e); + curl_easy_cleanup (e); + tr_runInEventThread (task->session, task_finish_func, task); + --taskCount; } } } - /* Discard any remaining tasks. - * This is rare, but can happen on shutdown with unresponsive trackers. */ - while (web->tasks != NULL) { - task = web->tasks; - web->tasks = task->next; - dbgmsg ("Discarding task \"%s\"", task->url); - task_free (task); + /* Discard any remaining tasks. + * This is rare, but can happen on shutdown with unresponsive trackers. */ + while (web->tasks != NULL) + { + task = web->tasks; + web->tasks = task->next; + dbgmsg ("Discarding task \"%s\"", task->url); + task_free (task); } - /* cleanup */ - curl_multi_cleanup (multi); - tr_lockFree (web->taskLock); - tr_free (web->cookie_filename); - tr_free (web); - session->web = NULL; + /* cleanup */ + curl_multi_cleanup (multi); + tr_lockFree (web->taskLock); + tr_free (web->cookie_filename); + tr_free (web); + session->web = NULL; } void tr_webInit (tr_session * session) { - tr_threadNew (tr_webThreadFunc, session); + tr_threadNew (tr_webThreadFunc, session); } void tr_webClose (tr_session * session, tr_web_close_mode close_mode) { - if (session->web != NULL) + if (session->web != NULL) { - session->web->close_mode = close_mode; + session->web->close_mode = close_mode; - if (close_mode == TR_WEB_CLOSE_NOW) - while (session->web != NULL) - tr_wait_msec (100); + if (close_mode == TR_WEB_CLOSE_NOW) + while (session->web != NULL) + tr_wait_msec (100); } } void tr_webGetTaskInfo (struct tr_web_task * task, tr_web_task_info info, void * dst) { - curl_easy_getinfo (task->curl_easy, (CURLINFO) info, dst); + curl_easy_getinfo (task->curl_easy, (CURLINFO) info, dst); } /***** @@ -476,108 +482,110 @@ tr_webGetTaskInfo (struct tr_web_task * task, tr_web_task_info info, void * dst) const char * tr_webGetResponseStr (long code) { - switch (code) + switch (code) { - case 0: return "No Response"; - case 101: return "Switching Protocols"; - case 200: return "OK"; - case 201: return "Created"; - case 202: return "Accepted"; - case 203: return "Non-Authoritative Information"; - case 204: return "No Content"; - case 205: return "Reset Content"; - case 206: return "Partial Content"; - case 300: return "Multiple Choices"; - case 301: return "Moved Permanently"; - case 302: return "Found"; - case 303: return "See Other"; - case 304: return "Not Modified"; - case 305: return "Use Proxy"; - case 306: return " (Unused)"; - case 307: return "Temporary Redirect"; - case 400: return "Bad Request"; - case 401: return "Unauthorized"; - case 402: return "Payment Required"; - case 403: return "Forbidden"; - case 404: return "Not Found"; - case 405: return "Method Not Allowed"; - case 406: return "Not Acceptable"; - case 407: return "Proxy Authentication Required"; - case 408: return "Request Timeout"; - case 409: return "Conflict"; - case 410: return "Gone"; - case 411: return "Length Required"; - case 412: return "Precondition Failed"; - case 413: return "Request Entity Too Large"; - case 414: return "Request-URI Too Long"; - case 415: return "Unsupported Media Type"; - case 416: return "Requested Range Not Satisfiable"; - case 417: return "Expectation Failed"; - case 500: return "Internal Server Error"; - case 501: return "Not Implemented"; - case 502: return "Bad Gateway"; - case 503: return "Service Unavailable"; - case 504: return "Gateway Timeout"; - case 505: return "HTTP Version Not Supported"; - default: return "Unknown Error"; + case 0: return "No Response"; + case 101: return "Switching Protocols"; + case 200: return "OK"; + case 201: return "Created"; + case 202: return "Accepted"; + case 203: return "Non-Authoritative Information"; + case 204: return "No Content"; + case 205: return "Reset Content"; + case 206: return "Partial Content"; + case 300: return "Multiple Choices"; + case 301: return "Moved Permanently"; + case 302: return "Found"; + case 303: return "See Other"; + case 304: return "Not Modified"; + case 305: return "Use Proxy"; + case 306: return " (Unused)"; + case 307: return "Temporary Redirect"; + case 400: return "Bad Request"; + case 401: return "Unauthorized"; + case 402: return "Payment Required"; + case 403: return "Forbidden"; + case 404: return "Not Found"; + case 405: return "Method Not Allowed"; + case 406: return "Not Acceptable"; + case 407: return "Proxy Authentication Required"; + case 408: return "Request Timeout"; + case 409: return "Conflict"; + case 410: return "Gone"; + case 411: return "Length Required"; + case 412: return "Precondition Failed"; + case 413: return "Request Entity Too Large"; + case 414: return "Request-URI Too Long"; + case 415: return "Unsupported Media Type"; + case 416: return "Requested Range Not Satisfiable"; + case 417: return "Expectation Failed"; + case 500: return "Internal Server Error"; + case 501: return "Not Implemented"; + case 502: return "Bad Gateway"; + case 503: return "Service Unavailable"; + case 504: return "Gateway Timeout"; + case 505: return "HTTP Version Not Supported"; + default: return "Unknown Error"; } } void tr_http_escape (struct evbuffer * out, - const char * str, int len, bool escape_slashes) + const char * str, + int len, + bool escape_slashes) { - const char * end; + const char * end; - if ((len < 0) && (str != NULL)) - len = strlen (str); + if ((len < 0) && (str != NULL)) + len = strlen (str); - for (end=str+len; str && str!=end; ++str) { - if ((*str == ',') - || (*str == '-') - || (*str == '.') - || (('0' <= *str) && (*str <= '9')) - || (('A' <= *str) && (*str <= 'Z')) - || (('a' <= *str) && (*str <= 'z')) - || ((*str == '/') && (!escape_slashes))) - evbuffer_add_printf (out, "%c", *str); - else - evbuffer_add_printf (out, "%%%02X", (unsigned)(*str&0xFF)); + for (end=str+len; str && str!=end; ++str) + { + if ((*str == ',') || (*str == '-') + || (*str == '.') + || (('0' <= *str) && (*str <= '9')) + || (('A' <= *str) && (*str <= 'Z')) + || (('a' <= *str) && (*str <= 'z')) + || ((*str == '/') && (!escape_slashes))) + evbuffer_add_printf (out, "%c", *str); + else + evbuffer_add_printf (out, "%%%02X", (unsigned)(*str&0xFF)); } } char * tr_http_unescape (const char * str, int len) { - char * tmp = curl_unescape (str, len); - char * ret = tr_strdup (tmp); - curl_free (tmp); - return ret; + char * tmp = curl_unescape (str, len); + char * ret = tr_strdup (tmp); + curl_free (tmp); + return ret; } static int is_rfc2396_alnum (uint8_t ch) { - return ('0' <= ch && ch <= '9') - || ('A' <= ch && ch <= 'Z') - || ('a' <= ch && ch <= 'z') - || ch == '.' - || ch == '-' - || ch == '_' - || ch == '~'; + return ('0' <= ch && ch <= '9') + || ('A' <= ch && ch <= 'Z') + || ('a' <= ch && ch <= 'z') + || ch == '.' + || ch == '-' + || ch == '_' + || ch == '~'; } void tr_http_escape_sha1 (char * out, const uint8_t * sha1_digest) { - const uint8_t * in = sha1_digest; - const uint8_t * end = in + SHA_DIGEST_LENGTH; + const uint8_t * in = sha1_digest; + const uint8_t * end = in + SHA_DIGEST_LENGTH; - while (in != end) - if (is_rfc2396_alnum (*in)) - *out++ = (char) *in++; - else - out += tr_snprintf (out, 4, "%%%02x", (unsigned int)*in++); + while (in != end) + if (is_rfc2396_alnum (*in)) + *out++ = (char) *in++; + else + out += tr_snprintf (out, 4, "%%%02x", (unsigned int)*in++); - *out = '\0'; + *out = '\0'; }