Transmission 2.33
[tomato.git] / release / src / router / transmission / libtransmission / utils.c
blobb4a6ae90a60df91d88ee94c9aa7e0be2826eb7a6
1 /*
2 * This file Copyright (C) Mnemosyne LLC
4 * This file is licensed by the GPL version 2. Works owned by the
5 * Transmission project are granted a special exemption to clause 2(b)
6 * so that the bulk of its code can remain under the MIT license.
7 * This exemption does not extend to derived works not owned by
8 * the Transmission project.
10 * $Id: utils.c 12551 2011-07-17 14:15:02Z jordan $
13 #ifdef HAVE_MEMMEM
14 #define _GNU_SOURCE /* glibc's string.h needs this to pick up memmem */
15 #endif
17 #if defined(SYS_DARWIN)
18 #define HAVE_GETPAGESIZE
19 #define HAVE_ICONV_OPEN
20 #define HAVE_VALLOC
21 #undef HAVE_POSIX_MEMALIGN /* not supported on OS X 10.5 and lower */
22 #endif
24 #include <assert.h>
25 #include <ctype.h> /* isdigit(), isalpha(), tolower() */
26 #include <errno.h>
27 #include <float.h> /* DBL_EPSILON */
28 #include <locale.h> /* localeconv() */
29 #include <math.h> /* pow(), fabs(), floor() */
30 #include <stdarg.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h> /* strerror(), memset(), memmem() */
34 #include <time.h> /* nanosleep() */
36 #ifdef HAVE_ICONV_OPEN
37 #include <iconv.h>
38 #endif
39 #include <libgen.h> /* basename() */
40 #include <sys/time.h>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #include <unistd.h> /* stat(), getcwd(), getpagesize(), unlink() */
45 #include <event2/buffer.h>
46 #include <event2/event.h>
48 #ifdef WIN32
49 #include <w32api.h>
50 #define WINVER WindowsXP /* freeaddrinfo(), getaddrinfo(), getnameinfo() */
51 #include <direct.h> /* _getcwd() */
52 #include <windows.h> /* Sleep() */
53 #endif
55 #include "transmission.h"
56 #include "bencode.h"
57 #include "fdlimit.h"
58 #include "ConvertUTF.h"
59 #include "list.h"
60 #include "utils.h"
61 #include "platform.h" /* tr_lockLock(), TR_PATH_MAX */
62 #include "version.h"
65 time_t __tr_current_time = 0;
66 tr_msg_level __tr_message_level = TR_MSG_ERR;
68 static bool messageQueuing = false;
69 static tr_msg_list * messageQueue = NULL;
70 static tr_msg_list ** messageQueueTail = &messageQueue;
71 static int messageQueueCount = 0;
73 #ifndef WIN32
74 /* make null versions of these win32 functions */
75 static inline int IsDebuggerPresent( void ) { return false; }
76 static inline void OutputDebugString( const void * unused UNUSED ) { }
77 #endif
79 /***
80 ****
81 ***/
83 static tr_lock*
84 getMessageLock( void )
86 static tr_lock * l = NULL;
88 if( !l )
89 l = tr_lockNew( );
91 return l;
94 void*
95 tr_getLog( void )
97 static bool initialized = false;
98 static FILE * file = NULL;
100 if( !initialized )
102 const char * str = getenv( "TR_DEBUG_FD" );
103 int fd = 0;
104 if( str && *str )
105 fd = atoi( str );
106 switch( fd )
108 case 1:
109 file = stdout; break;
111 case 2:
112 file = stderr; break;
114 default:
115 file = NULL; break;
117 initialized = true;
120 return file;
123 void
124 tr_setMessageLevel( tr_msg_level level )
126 __tr_message_level = level;
129 void
130 tr_setMessageQueuing( bool enabled )
132 messageQueuing = enabled;
135 bool
136 tr_getMessageQueuing( void )
138 return messageQueuing != 0;
141 tr_msg_list *
142 tr_getQueuedMessages( void )
144 tr_msg_list * ret;
145 tr_lockLock( getMessageLock( ) );
147 ret = messageQueue;
148 messageQueue = NULL;
149 messageQueueTail = &messageQueue;
151 messageQueueCount = 0;
153 tr_lockUnlock( getMessageLock( ) );
154 return ret;
157 void
158 tr_freeMessageList( tr_msg_list * list )
160 tr_msg_list * next;
162 while( NULL != list )
164 next = list->next;
165 free( list->message );
166 free( list->name );
167 free( list );
168 list = next;
176 struct tm *
177 tr_localtime_r( const time_t *_clock, struct tm *_result )
179 #ifdef HAVE_LOCALTIME_R
180 return localtime_r( _clock, _result );
181 #else
182 struct tm *p = localtime( _clock );
183 if( p )
184 *(_result) = *p;
185 return p;
186 #endif
189 char*
190 tr_getLogTimeStr( char * buf, int buflen )
192 char tmp[64];
193 struct tm now_tm;
194 struct timeval tv;
195 time_t seconds;
196 int milliseconds;
198 gettimeofday( &tv, NULL );
200 seconds = tv.tv_sec;
201 tr_localtime_r( &seconds, &now_tm );
202 strftime( tmp, sizeof( tmp ), "%H:%M:%S", &now_tm );
203 milliseconds = tv.tv_usec / 1000;
204 tr_snprintf( buf, buflen, "%s.%03d", tmp, milliseconds );
206 return buf;
209 bool
210 tr_deepLoggingIsActive( void )
212 static int8_t deepLoggingIsActive = -1;
214 if( deepLoggingIsActive < 0 )
215 deepLoggingIsActive = IsDebuggerPresent() || (tr_getLog()!=NULL);
217 return deepLoggingIsActive != 0;
220 void
221 tr_deepLog( const char * file,
222 int line,
223 const char * name,
224 const char * fmt,
225 ... )
227 FILE * fp = tr_getLog( );
228 if( fp || IsDebuggerPresent( ) )
230 va_list args;
231 char timestr[64];
232 struct evbuffer * buf = evbuffer_new( );
233 char * base = tr_basename( file );
235 evbuffer_add_printf( buf, "[%s] ",
236 tr_getLogTimeStr( timestr, sizeof( timestr ) ) );
237 if( name )
238 evbuffer_add_printf( buf, "%s ", name );
239 va_start( args, fmt );
240 evbuffer_add_vprintf( buf, fmt, args );
241 va_end( args );
242 evbuffer_add_printf( buf, " (%s:%d)\n", base, line );
243 /* FIXME(libevent2) ifdef this out for nonwindows platforms */
244 OutputDebugString( evbuffer_pullup( buf, -1 ) );
245 if( fp )
246 fputs( (const char*)evbuffer_pullup( buf, -1 ), fp );
248 tr_free( base );
249 evbuffer_free( buf );
253 /***
254 ****
255 ***/
257 void
258 tr_msg( const char * file, int line,
259 tr_msg_level level,
260 const char * name,
261 const char * fmt, ... )
263 const int err = errno; /* message logging shouldn't affect errno */
264 char buf[1024];
265 va_list ap;
266 tr_lockLock( getMessageLock( ) );
268 /* build the text message */
269 *buf = '\0';
270 va_start( ap, fmt );
271 evutil_vsnprintf( buf, sizeof( buf ), fmt, ap );
272 va_end( ap );
274 OutputDebugString( buf );
276 if( *buf )
278 if( messageQueuing )
280 tr_msg_list * newmsg;
281 newmsg = tr_new0( tr_msg_list, 1 );
282 newmsg->level = level;
283 newmsg->when = tr_time( );
284 newmsg->message = tr_strdup( buf );
285 newmsg->file = file;
286 newmsg->line = line;
287 newmsg->name = tr_strdup( name );
289 *messageQueueTail = newmsg;
290 messageQueueTail = &newmsg->next;
291 ++messageQueueCount;
293 if( messageQueueCount > TR_MAX_MSG_LOG )
295 tr_msg_list * old = messageQueue;
296 messageQueue = old->next;
297 old->next = NULL;
298 tr_freeMessageList(old);
300 --messageQueueCount;
302 assert( messageQueueCount == TR_MAX_MSG_LOG );
305 else
307 char timestr[64];
308 FILE * fp;
310 fp = tr_getLog( );
311 if( fp == NULL )
312 fp = stderr;
314 tr_getLogTimeStr( timestr, sizeof( timestr ) );
316 if( name )
317 fprintf( fp, "[%s] %s: %s\n", timestr, name, buf );
318 else
319 fprintf( fp, "[%s] %s\n", timestr, buf );
320 fflush( fp );
324 tr_lockUnlock( getMessageLock( ) );
325 errno = err;
328 /***
329 ****
330 ***/
332 void*
333 tr_malloc( size_t size )
335 return size ? malloc( size ) : NULL;
338 void*
339 tr_malloc0( size_t size )
341 return size ? calloc( 1, size ) : NULL;
344 void
345 tr_free( void * p )
347 if( p != NULL )
348 free( p );
351 void*
352 tr_memdup( const void * src, size_t byteCount )
354 return memcpy( tr_malloc( byteCount ), src, byteCount );
357 /***
358 ****
359 ***/
361 const char*
362 tr_strip_positional_args( const char* str )
364 const char * in = str;
365 static size_t bufsize = 0;
366 static char * buf = NULL;
367 const size_t len = str ? strlen( str ) : 0;
368 char * out;
370 if( !buf || ( bufsize < len ) )
372 bufsize = len * 2 + 1;
373 buf = tr_renew( char, buf, bufsize );
376 for( out = buf; str && *str; ++str )
378 *out++ = *str;
380 if( ( *str == '%' ) && isdigit( str[1] ) )
382 const char * tmp = str + 1;
383 while( isdigit( *tmp ) )
384 ++tmp;
385 if( *tmp == '$' )
386 str = tmp[1]=='\'' ? tmp+1 : tmp;
389 if( ( *str == '%' ) && ( str[1] == '\'' ) )
390 str = str + 1;
393 *out = '\0';
395 return !in || strcmp( buf, in ) ? buf : in;
402 void
403 tr_timerAdd( struct event * timer, int seconds, int microseconds )
405 struct timeval tv;
406 tv.tv_sec = seconds;
407 tv.tv_usec = microseconds;
409 assert( tv.tv_sec >= 0 );
410 assert( tv.tv_usec >= 0 );
411 assert( tv.tv_usec < 1000000 );
413 evtimer_add( timer, &tv );
416 void
417 tr_timerAddMsec( struct event * timer, int msec )
419 const int seconds = msec / 1000;
420 const int usec = (msec%1000) * 1000;
421 tr_timerAdd( timer, seconds, usec );
428 uint8_t *
429 tr_loadFile( const char * path,
430 size_t * size )
432 uint8_t * buf;
433 struct stat sb;
434 int fd;
435 ssize_t n;
436 const char * const err_fmt = _( "Couldn't read \"%1$s\": %2$s" );
438 /* try to stat the file */
439 errno = 0;
440 if( stat( path, &sb ) )
442 const int err = errno;
443 tr_dbg( err_fmt, path, tr_strerror( errno ) );
444 errno = err;
445 return NULL;
448 if( ( sb.st_mode & S_IFMT ) != S_IFREG )
450 tr_err( err_fmt, path, _( "Not a regular file" ) );
451 errno = EISDIR;
452 return NULL;
455 /* Load the torrent file into our buffer */
456 fd = tr_open_file_for_scanning( path );
457 if( fd < 0 )
459 const int err = errno;
460 tr_err( err_fmt, path, tr_strerror( errno ) );
461 errno = err;
462 return NULL;
464 buf = tr_malloc( sb.st_size + 1 );
465 if( !buf )
467 const int err = errno;
468 tr_err( err_fmt, path, _( "Memory allocation failed" ) );
469 tr_close_file( fd );
470 errno = err;
471 return NULL;
473 n = read( fd, buf, (size_t)sb.st_size );
474 if( n == -1 )
476 const int err = errno;
477 tr_err( err_fmt, path, tr_strerror( errno ) );
478 tr_close_file( fd );
479 free( buf );
480 errno = err;
481 return NULL;
484 tr_close_file( fd );
485 buf[ sb.st_size ] = '\0';
486 *size = sb.st_size;
487 return buf;
490 char*
491 tr_basename( const char * path )
493 char * tmp = tr_strdup( path );
494 char * ret = tr_strdup( basename( tmp ) );
495 tr_free( tmp );
496 return ret;
499 char*
500 tr_dirname( const char * path )
502 char * tmp = tr_strdup( path );
503 char * ret = tr_strdup( dirname( tmp ) );
504 tr_free( tmp );
505 return ret;
509 tr_mkdir( const char * path,
510 int permissions
511 #ifdef WIN32
512 UNUSED
513 #endif
516 #ifdef WIN32
517 if( path && isalpha( path[0] ) && path[1] == ':' && !path[2] )
518 return 0;
519 return mkdir( path );
520 #else
521 return mkdir( path, permissions );
522 #endif
526 tr_mkdirp( const char * path_in,
527 int permissions )
529 char * path = tr_strdup( path_in );
530 char * p, * pp;
531 struct stat sb;
532 int done;
534 /* walk past the root */
535 p = path;
536 while( *p == TR_PATH_DELIMITER )
537 ++p;
539 pp = p;
540 done = 0;
541 while( ( p =
542 strchr( pp, TR_PATH_DELIMITER ) ) || ( p = strchr( pp, '\0' ) ) )
544 if( !*p )
545 done = 1;
546 else
547 *p = '\0';
549 if( stat( path, &sb ) )
551 /* Folder doesn't exist yet */
552 if( tr_mkdir( path, permissions ) )
554 const int err = errno;
555 tr_err( _(
556 "Couldn't create \"%1$s\": %2$s" ), path,
557 tr_strerror( err ) );
558 tr_free( path );
559 errno = err;
560 return -1;
563 else if( ( sb.st_mode & S_IFMT ) != S_IFDIR )
565 /* Node exists but isn't a folder */
566 char * buf = tr_strdup_printf( _( "File \"%s\" is in the way" ), path );
567 tr_err( _( "Couldn't create \"%1$s\": %2$s" ), path_in, buf );
568 tr_free( buf );
569 tr_free( path );
570 errno = ENOTDIR;
571 return -1;
574 if( done )
575 break;
577 *p = TR_PATH_DELIMITER;
578 p++;
579 pp = p;
582 tr_free( path );
583 return 0;
586 char*
587 tr_buildPath( const char *first_element, ... )
589 size_t bufLen = 0;
590 const char * element;
591 char * buf;
592 char * pch;
593 va_list vl;
595 /* pass 1: allocate enough space for the string */
596 va_start( vl, first_element );
597 element = first_element;
598 while( element ) {
599 bufLen += strlen( element ) + 1;
600 element = va_arg( vl, const char* );
602 pch = buf = tr_new( char, bufLen );
603 va_end( vl );
605 /* pass 2: build the string piece by piece */
606 va_start( vl, first_element );
607 element = first_element;
608 while( element ) {
609 const size_t elementLen = strlen( element );
610 memcpy( pch, element, elementLen );
611 pch += elementLen;
612 *pch++ = TR_PATH_DELIMITER;
613 element = va_arg( vl, const char* );
615 va_end( vl );
617 /* terminate the string. if nonempty, eat the unwanted trailing slash */
618 if( pch != buf )
619 --pch;
620 *pch++ = '\0';
622 /* sanity checks & return */
623 assert( pch - buf == (off_t)bufLen );
624 return buf;
627 /****
628 *****
629 ****/
631 char*
632 evbuffer_free_to_str( struct evbuffer * buf )
634 const size_t n = evbuffer_get_length( buf );
635 char * ret = tr_new( char, n + 1 );
636 evbuffer_copyout( buf, ret, n );
637 evbuffer_free( buf );
638 ret[n] = '\0';
639 return ret;
642 char*
643 tr_strdup( const void * in )
645 return tr_strndup( in, in ? (int)strlen((const char *)in) : 0 );
648 char*
649 tr_strndup( const void * in, int len )
651 char * out = NULL;
653 if( len < 0 )
655 out = tr_strdup( in );
657 else if( in )
659 out = tr_malloc( len + 1 );
660 memcpy( out, in, len );
661 out[len] = '\0';
664 return out;
667 const char*
668 tr_memmem( const char * haystack, size_t haystacklen,
669 const char * needle, size_t needlelen )
671 #ifdef HAVE_MEMMEM
672 return memmem( haystack, haystacklen, needle, needlelen );
673 #else
674 size_t i;
675 if( !needlelen )
676 return haystack;
677 if( needlelen > haystacklen || !haystack || !needle )
678 return NULL;
679 for( i=0; i<=haystacklen-needlelen; ++i )
680 if( !memcmp( haystack+i, needle, needlelen ) )
681 return haystack+i;
682 return NULL;
683 #endif
686 char*
687 tr_strdup_printf( const char * fmt, ... )
689 va_list ap;
690 char * ret;
691 size_t len;
692 char statbuf[2048];
694 va_start( ap, fmt );
695 len = evutil_vsnprintf( statbuf, sizeof( statbuf ), fmt, ap );
696 va_end( ap );
697 if( len < sizeof( statbuf ) )
698 ret = tr_strndup( statbuf, len );
699 else {
700 ret = tr_new( char, len + 1 );
701 va_start( ap, fmt );
702 evutil_vsnprintf( ret, len + 1, fmt, ap );
703 va_end( ap );
706 return ret;
709 const char*
710 tr_strerror( int i )
712 const char * ret = strerror( i );
714 if( ret == NULL )
715 ret = "Unknown Error";
716 return ret;
720 tr_strcmp0( const char * str1, const char * str2 )
722 if( str1 && str2 ) return strcmp( str1, str2 );
723 if( str1 ) return 1;
724 if( str2 ) return -1;
725 return 0;
728 /****
729 *****
730 ****/
732 /* https://bugs.launchpad.net/percona-patches/+bug/526863/+attachment/1160199/+files/solaris_10_fix.patch */
733 char*
734 tr_strsep( char ** str, const char * delims )
736 #ifdef HAVE_STRSEP
737 return strsep( str, delims );
738 #else
739 char *token;
741 if (*str == NULL) {
742 /* No more tokens */
743 return NULL;
746 token = *str;
747 while (**str != '\0') {
748 if (strchr(delims, **str) != NULL) {
749 **str = '\0';
750 (*str)++;
751 return token;
753 (*str)++;
756 /* There is not another token */
757 *str = NULL;
759 return token;
760 #endif
763 char*
764 tr_strstrip( char * str )
766 if( str != NULL )
768 size_t pos;
769 size_t len = strlen( str );
771 while( len && isspace( str[len - 1] ) )
772 --len;
774 for( pos = 0; pos < len && isspace( str[pos] ); )
775 ++pos;
777 len -= pos;
778 memmove( str, str + pos, len );
779 str[len] = '\0';
782 return str;
785 bool
786 tr_str_has_suffix( const char *str, const char *suffix )
788 size_t str_len;
789 size_t suffix_len;
791 if( !str )
792 return false;
793 if( !suffix )
794 return true;
796 str_len = strlen( str );
797 suffix_len = strlen( suffix );
798 if( str_len < suffix_len )
799 return false;
801 return !evutil_ascii_strncasecmp( str + str_len - suffix_len, suffix, suffix_len );
804 /****
805 *****
806 ****/
808 uint64_t
809 tr_time_msec( void )
811 struct timeval tv;
813 gettimeofday( &tv, NULL );
814 return (uint64_t) tv.tv_sec * 1000 + ( tv.tv_usec / 1000 );
817 void
818 tr_wait_msec( long int msec )
820 #ifdef WIN32
821 Sleep( (DWORD)msec );
822 #else
823 struct timespec ts;
824 ts.tv_sec = msec / 1000;
825 ts.tv_nsec = ( msec % 1000 ) * 1000000;
826 nanosleep( &ts, NULL );
827 #endif
830 /***
831 ****
832 ***/
835 tr_snprintf( char * buf, size_t buflen, const char * fmt, ... )
837 int len;
838 va_list args;
840 va_start( args, fmt );
841 len = evutil_vsnprintf( buf, buflen, fmt, args );
842 va_end( args );
843 return len;
847 * Copy src to string dst of size siz. At most siz-1 characters
848 * will be copied. Always NUL terminates (unless siz == 0).
849 * Returns strlen(src); if retval >= siz, truncation occurred.
851 size_t
852 tr_strlcpy( char * dst, const void * src, size_t siz )
854 #ifdef HAVE_STRLCPY
855 return strlcpy( dst, src, siz );
856 #else
857 char * d = dst;
858 const char *s = src;
859 size_t n = siz;
861 assert( s );
862 assert( d );
864 /* Copy as many bytes as will fit */
865 if( n != 0 )
867 while( --n != 0 )
869 if( ( *d++ = *s++ ) == '\0' )
870 break;
874 /* Not enough room in dst, add NUL and traverse rest of src */
875 if( n == 0 )
877 if( siz != 0 )
878 *d = '\0'; /* NUL-terminate dst */
879 while( *s++ )
883 return s - (char*)src - 1; /* count does not include NUL */
884 #endif
887 /***
888 ****
889 ***/
891 double
892 tr_getRatio( uint64_t numerator, uint64_t denominator )
894 double ratio;
896 if( denominator > 0 )
897 ratio = numerator / (double)denominator;
898 else if( numerator > 0 )
899 ratio = TR_RATIO_INF;
900 else
901 ratio = TR_RATIO_NA;
903 return ratio;
906 void
907 tr_sha1_to_hex( char * out, const uint8_t * sha1 )
909 int i;
910 static const char hex[] = "0123456789abcdef";
912 for( i=0; i<20; ++i )
914 const unsigned int val = *sha1++;
915 *out++ = hex[val >> 4];
916 *out++ = hex[val & 0xf];
919 *out = '\0';
922 void
923 tr_hex_to_sha1( uint8_t * out, const char * in )
925 int i;
926 static const char hex[] = "0123456789abcdef";
928 for( i=0; i<20; ++i )
930 const int hi = strchr( hex, tolower( *in++ ) ) - hex;
931 const int lo = strchr( hex, tolower( *in++ ) ) - hex;
932 *out++ = (uint8_t)( (hi<<4) | lo );
936 /***
937 ****
938 ***/
940 static bool
941 isValidURLChars( const char * url, int url_len )
943 const char * c;
944 const char * end;
945 static const char * rfc2396_valid_chars =
946 "abcdefghijklmnopqrstuvwxyz" /* lowalpha */
947 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" /* upalpha */
948 "0123456789" /* digit */
949 "-_.!~*'()" /* mark */
950 ";/?:@&=+$," /* reserved */
951 "<>#%<\"" /* delims */
952 "{}|\\^[]`"; /* unwise */
954 if( url == NULL )
955 return false;
957 for( c=url, end=c+url_len; c && *c && c!=end; ++c )
958 if( !strchr( rfc2396_valid_chars, *c ) )
959 return false;
961 return true;
964 /** @brief return true if the URL is a http or https or UDP one that Transmission understands */
965 bool
966 tr_urlIsValidTracker( const char * url )
968 bool valid;
969 const int len = url ? strlen(url) : 0;
971 valid = isValidURLChars( url, len )
972 && !tr_urlParse( url, len, NULL, NULL, NULL, NULL )
973 && ( !memcmp(url,"http://",7) || !memcmp(url,"https://",8) || !memcmp(url,"udp://",6) );
975 return valid;
978 /** @brief return true if the URL is a http or https or ftp or sftp one that Transmission understands */
979 bool
980 tr_urlIsValid( const char * url, int url_len )
982 bool valid;
983 if( ( url_len < 0 ) && ( url != NULL ) )
984 url_len = strlen( url );
986 valid = isValidURLChars( url, url_len )
987 && !tr_urlParse( url, url_len, NULL, NULL, NULL, NULL )
988 && ( !memcmp(url,"http://",7) || !memcmp(url,"https://",8) || !memcmp(url,"ftp://",6) || !memcmp(url,"sftp://",7) );
990 return valid;
993 bool
994 tr_addressIsIP( const char * str )
996 tr_address tmp;
997 return tr_address_from_string( &tmp, str );
1001 tr_urlParse( const char * url_in,
1002 int len,
1003 char ** setme_protocol,
1004 char ** setme_host,
1005 int * setme_port,
1006 char ** setme_path )
1008 int err;
1009 int port = 0;
1010 int n;
1011 char * tmp;
1012 char * pch;
1013 size_t host_len;
1014 size_t protocol_len;
1015 const char * host = NULL;
1016 const char * protocol = NULL;
1017 const char * path = NULL;
1019 tmp = tr_strndup( url_in, len );
1020 if( ( pch = strstr( tmp, "://" ) ) )
1022 *pch = '\0';
1023 protocol = tmp;
1024 protocol_len = pch - protocol;
1025 pch += 3;
1026 /*fprintf( stderr, "protocol is [%s]... what's left is [%s]\n", protocol, pch);*/
1027 if( ( n = strcspn( pch, ":/" ) ) )
1029 const int havePort = pch[n] == ':';
1030 host = pch;
1031 host_len = n;
1032 pch += n;
1033 if( pch && *pch )
1034 *pch++ = '\0';
1035 /*fprintf( stderr, "host is [%s]... what's left is [%s]\n", host, pch );*/
1036 if( havePort )
1038 char * end;
1039 port = strtol( pch, &end, 10 );
1040 pch = end;
1041 /*fprintf( stderr, "port is [%d]... what's left is [%s]\n", port, pch );*/
1043 path = pch;
1044 /*fprintf( stderr, "path is [%s]\n", path );*/
1048 err = !host || !path || !protocol;
1050 if( !err && !port )
1052 if( !strcmp( protocol, "udp" ) ) port = 80;
1053 else if( !strcmp( protocol, "ftp" ) ) port = 21;
1054 else if( !strcmp( protocol, "sftp" ) ) port = 22;
1055 else if( !strcmp( protocol, "http" ) ) port = 80;
1056 else if( !strcmp( protocol, "https" ) ) port = 443;
1059 if( !err )
1061 if( setme_protocol ) *setme_protocol = tr_strndup( protocol, protocol_len );
1063 if( setme_host ){ ( (char*)host )[-3] = ':'; *setme_host =
1064 tr_strndup( host, host_len ); }
1065 if( setme_path ){ if( !*path ) *setme_path = tr_strdup( "/" );
1066 else if( path[0] == '/' ) *setme_path = tr_strdup( path );
1067 else { ( (char*)path )[-1] = '/'; *setme_path = tr_strdup( path - 1 ); } }
1068 if( setme_port ) *setme_port = port;
1072 tr_free( tmp );
1073 return err;
1076 #include <string.h>
1077 #include <openssl/sha.h>
1078 #include <openssl/hmac.h>
1079 #include <openssl/evp.h>
1080 #include <openssl/bio.h>
1081 #include <openssl/buffer.h>
1083 char *
1084 tr_base64_encode( const void * input, int length, int * setme_len )
1086 int retlen = 0;
1087 char * ret = NULL;
1089 if( input != NULL )
1091 BIO * b64;
1092 BIO * bmem;
1093 BUF_MEM * bptr;
1095 if( length < 1 )
1096 length = (int)strlen( input );
1098 bmem = BIO_new( BIO_s_mem( ) );
1099 b64 = BIO_new( BIO_f_base64( ) );
1100 BIO_set_flags( b64, BIO_FLAGS_BASE64_NO_NL );
1101 b64 = BIO_push( b64, bmem );
1102 BIO_write( b64, input, length );
1103 (void) BIO_flush( b64 );
1104 BIO_get_mem_ptr( b64, &bptr );
1105 ret = tr_strndup( bptr->data, bptr->length );
1106 retlen = bptr->length;
1107 BIO_free_all( b64 );
1110 if( setme_len )
1111 *setme_len = retlen;
1113 return ret;
1116 char *
1117 tr_base64_decode( const void * input,
1118 int length,
1119 int * setme_len )
1121 char * ret;
1122 BIO * b64;
1123 BIO * bmem;
1124 int retlen;
1126 if( length < 1 )
1127 length = strlen( input );
1129 ret = tr_new0( char, length );
1130 b64 = BIO_new( BIO_f_base64( ) );
1131 bmem = BIO_new_mem_buf( (unsigned char*)input, length );
1132 bmem = BIO_push( b64, bmem );
1133 retlen = BIO_read( bmem, ret, length );
1134 if( !retlen )
1136 /* try again, but with the BIO_FLAGS_BASE64_NO_NL flag */
1137 BIO_free_all( bmem );
1138 b64 = BIO_new( BIO_f_base64( ) );
1139 BIO_set_flags( b64, BIO_FLAGS_BASE64_NO_NL );
1140 bmem = BIO_new_mem_buf( (unsigned char*)input, length );
1141 bmem = BIO_push( b64, bmem );
1142 retlen = BIO_read( bmem, ret, length );
1145 if( setme_len )
1146 *setme_len = retlen;
1148 BIO_free_all( bmem );
1149 return ret;
1152 /***
1153 ****
1154 ***/
1156 void
1157 tr_removeElementFromArray( void * array,
1158 unsigned int index_to_remove,
1159 size_t sizeof_element,
1160 size_t nmemb )
1162 char * a = array;
1164 memmove( a + sizeof_element * index_to_remove,
1165 a + sizeof_element * ( index_to_remove + 1 ),
1166 sizeof_element * ( --nmemb - index_to_remove ) );
1170 tr_lowerBound( const void * key,
1171 const void * base,
1172 size_t nmemb,
1173 size_t size,
1174 int (* compar)(const void* key, const void* arrayMember),
1175 bool * exact_match )
1177 size_t first = 0;
1178 const char * cbase = base;
1179 bool exact = false;
1181 while( nmemb != 0 )
1183 const size_t half = nmemb / 2;
1184 const size_t middle = first + half;
1185 const int c = compar( key, cbase + size*middle );
1187 if( c <= 0 ) {
1188 if( c == 0 )
1189 exact = true;
1190 nmemb = half;
1191 } else {
1192 first = middle + 1;
1193 nmemb = nmemb - half - 1;
1197 *exact_match = exact;
1199 return first;
1202 /***
1203 ****
1204 ***/
1206 static char*
1207 strip_non_utf8( const char * in, size_t inlen )
1209 const char * end;
1210 const char zero = '\0';
1211 struct evbuffer * buf = evbuffer_new( );
1213 while( !tr_utf8_validate( in, inlen, &end ) )
1215 const int good_len = end - in;
1217 evbuffer_add( buf, in, good_len );
1218 inlen -= ( good_len + 1 );
1219 in += ( good_len + 1 );
1220 evbuffer_add( buf, "?", 1 );
1223 evbuffer_add( buf, in, inlen );
1224 evbuffer_add( buf, &zero, 1 );
1225 return evbuffer_free_to_str( buf );
1228 static char*
1229 to_utf8( const char * in, size_t inlen )
1231 char * ret = NULL;
1233 #ifdef HAVE_ICONV_OPEN
1234 int i;
1235 const char * encodings[] = { "CURRENT", "ISO-8859-15" };
1236 const int encoding_count = sizeof(encodings) / sizeof(encodings[1]);
1237 const size_t buflen = inlen*4 + 10;
1238 char * out = tr_new( char, buflen );
1240 for( i=0; !ret && i<encoding_count; ++i )
1242 char * inbuf = (char*) in;
1243 char * outbuf = out;
1244 size_t inbytesleft = inlen;
1245 size_t outbytesleft = buflen;
1246 const char * test_encoding = encodings[i];
1248 iconv_t cd = iconv_open( "UTF-8", test_encoding );
1249 if( cd != (iconv_t)-1 ) {
1250 if( iconv( cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft ) != (size_t)-1 )
1251 ret = tr_strndup( out, buflen-outbytesleft );
1252 iconv_close( cd );
1256 tr_free( out );
1257 #endif
1259 if( ret == NULL )
1260 ret = strip_non_utf8( in, inlen );
1262 return ret;
1265 char*
1266 tr_utf8clean( const char * str, int max_len )
1268 char * ret;
1269 const char * end;
1271 if( max_len < 0 )
1272 max_len = (int) strlen( str );
1274 if( tr_utf8_validate( str, max_len, &end ) )
1275 ret = tr_strndup( str, max_len );
1276 else
1277 ret = to_utf8( str, max_len );
1279 assert( tr_utf8_validate( ret, -1, NULL ) );
1280 return ret;
1283 /***
1284 ****
1285 ***/
1287 struct number_range
1289 int low;
1290 int high;
1294 * This should be a single number (ex. "6") or a range (ex. "6-9").
1295 * Anything else is an error and will return failure.
1297 static bool
1298 parseNumberSection( const char * str, int len, struct number_range * setme )
1300 long a, b;
1301 bool success;
1302 char * end;
1303 const int error = errno;
1304 char * tmp = tr_strndup( str, len );
1306 errno = 0;
1307 a = b = strtol( tmp, &end, 10 );
1308 if( errno || ( end == tmp ) ) {
1309 success = false;
1310 } else if( *end != '-' ) {
1311 success = true;
1312 } else {
1313 const char * pch = end + 1;
1314 b = strtol( pch, &end, 10 );
1315 if( errno || ( pch == end ) )
1316 success = false;
1317 else if( *end ) /* trailing data */
1318 success = false;
1319 else
1320 success = true;
1322 tr_free( tmp );
1324 setme->low = MIN( a, b );
1325 setme->high = MAX( a, b );
1327 errno = error;
1328 return success;
1332 compareInt( const void * va, const void * vb )
1334 const int a = *(const int *)va;
1335 const int b = *(const int *)vb;
1336 return a - b;
1340 * Given a string like "1-4" or "1-4,6,9,14-51", this allocates and returns an
1341 * array of setmeCount ints of all the values in the array.
1342 * For example, "5-8" will return [ 5, 6, 7, 8 ] and setmeCount will be 4.
1343 * It's the caller's responsibility to call tr_free() on the returned array.
1344 * If a fragment of the string can't be parsed, NULL is returned.
1346 int*
1347 tr_parseNumberRange( const char * str_in, int len, int * setmeCount )
1349 int n = 0;
1350 int * uniq = NULL;
1351 char * str = tr_strndup( str_in, len );
1352 const char * walk;
1353 tr_list * ranges = NULL;
1354 bool success = true;
1356 walk = str;
1357 while( walk && *walk && success ) {
1358 struct number_range range;
1359 const char * pch = strchr( walk, ',' );
1360 if( pch ) {
1361 success = parseNumberSection( walk, pch-walk, &range );
1362 walk = pch + 1;
1363 } else {
1364 success = parseNumberSection( walk, strlen( walk ), &range );
1365 walk += strlen( walk );
1367 if( success )
1368 tr_list_append( &ranges, tr_memdup( &range, sizeof( struct number_range ) ) );
1371 if( !success )
1373 *setmeCount = 0;
1374 uniq = NULL;
1376 else
1378 int i;
1379 int n2;
1380 tr_list * l;
1381 int * sorted = NULL;
1383 /* build a sorted number array */
1384 n = n2 = 0;
1385 for( l=ranges; l!=NULL; l=l->next ) {
1386 const struct number_range * r = l->data;
1387 n += r->high + 1 - r->low;
1389 sorted = tr_new( int, n );
1390 for( l=ranges; l!=NULL; l=l->next ) {
1391 const struct number_range * r = l->data;
1392 int i;
1393 for( i=r->low; i<=r->high; ++i )
1394 sorted[n2++] = i;
1396 qsort( sorted, n, sizeof( int ), compareInt );
1397 assert( n == n2 );
1399 /* remove duplicates */
1400 uniq = tr_new( int, n );
1401 for( i=n=0; i<n2; ++i )
1402 if( !n || uniq[n-1] != sorted[i] )
1403 uniq[n++] = sorted[i];
1405 tr_free( sorted );
1408 /* cleanup */
1409 tr_list_free( &ranges, tr_free );
1410 tr_free( str );
1412 /* return the result */
1413 *setmeCount = n;
1414 return uniq;
1417 /***
1418 ****
1419 ***/
1421 double
1422 tr_truncd( double x, int precision )
1424 char * pt;
1425 char buf[128];
1426 const int max_precision = (int) log10( 1.0 / DBL_EPSILON ) - 1;
1427 tr_snprintf( buf, sizeof( buf ), "%.*f", max_precision, x );
1428 if(( pt = strstr( buf, localeconv()->decimal_point )))
1429 pt[precision ? precision+1 : 0] = '\0';
1430 return atof(buf);
1433 /* return a truncated double as a string */
1434 static char*
1435 tr_strtruncd( char * buf, double x, int precision, size_t buflen )
1437 tr_snprintf( buf, buflen, "%.*f", precision, tr_truncd( x, precision ) );
1438 return buf;
1441 char*
1442 tr_strpercent( char * buf, double x, size_t buflen )
1444 if( x < 10.0 )
1445 tr_strtruncd( buf, x, 2, buflen );
1446 else if( x < 100.0 )
1447 tr_strtruncd( buf, x, 1, buflen );
1448 else
1449 tr_strtruncd( buf, x, 0, buflen );
1450 return buf;
1453 char*
1454 tr_strratio( char * buf, size_t buflen, double ratio, const char * infinity )
1456 if( (int)ratio == TR_RATIO_NA )
1457 tr_strlcpy( buf, _( "None" ), buflen );
1458 else if( (int)ratio == TR_RATIO_INF )
1459 tr_strlcpy( buf, infinity, buflen );
1460 else
1461 tr_strpercent( buf, ratio, buflen );
1462 return buf;
1465 /***
1466 ****
1467 ***/
1470 tr_moveFile( const char * oldpath, const char * newpath, bool * renamed )
1472 int in;
1473 int out;
1474 char * buf;
1475 struct stat st;
1476 off_t bytesLeft;
1477 const size_t buflen = 1024 * 128; /* 128 KiB buffer */
1479 /* make sure the old file exists */
1480 if( stat( oldpath, &st ) ) {
1481 const int err = errno;
1482 errno = err;
1483 return -1;
1485 if( !S_ISREG( st.st_mode ) ) {
1486 errno = ENOENT;
1487 return -1;
1489 bytesLeft = st.st_size;
1491 /* make sure the target directory exists */
1493 char * newdir = tr_dirname( newpath );
1494 int i = tr_mkdirp( newdir, 0777 );
1495 tr_free( newdir );
1496 if( i )
1497 return i;
1500 /* they might be on the same filesystem... */
1502 const int i = rename( oldpath, newpath );
1503 if( renamed != NULL )
1504 *renamed = i == 0;
1505 if( !i )
1506 return 0;
1509 /* copy the file */
1510 in = tr_open_file_for_scanning( oldpath );
1511 out = tr_open_file_for_writing( newpath );
1512 buf = tr_valloc( buflen );
1513 while( bytesLeft > 0 )
1515 ssize_t bytesWritten;
1516 const off_t bytesThisPass = MIN( bytesLeft, (off_t)buflen );
1517 const int numRead = read( in, buf, bytesThisPass );
1518 if( numRead < 0 )
1519 break;
1520 bytesWritten = write( out, buf, numRead );
1521 if( bytesWritten < 0 )
1522 break;
1523 bytesLeft -= bytesWritten;
1526 /* cleanup */
1527 tr_free( buf );
1528 tr_close_file( out );
1529 tr_close_file( in );
1530 if( bytesLeft != 0 )
1531 return -1;
1533 unlink( oldpath );
1534 return 0;
1537 bool
1538 tr_is_same_file( const char * filename1, const char * filename2 )
1540 struct stat sb1, sb2;
1542 return !stat( filename1, &sb1 )
1543 && !stat( filename2, &sb2 )
1544 && ( sb1.st_dev == sb2.st_dev )
1545 && ( sb1.st_ino == sb2.st_ino );
1548 /***
1549 ****
1550 ***/
1552 void*
1553 tr_valloc( size_t bufLen )
1555 size_t allocLen;
1556 void * buf = NULL;
1557 static size_t pageSize = 0;
1559 if( !pageSize ) {
1560 #ifdef HAVE_GETPAGESIZE
1561 pageSize = (size_t) getpagesize();
1562 #else /* guess */
1563 pageSize = 4096;
1564 #endif
1567 allocLen = pageSize;
1568 while( allocLen < bufLen )
1569 allocLen += pageSize;
1571 #ifdef HAVE_POSIX_MEMALIGN
1572 if( !buf )
1573 if( posix_memalign( &buf, pageSize, allocLen ) )
1574 buf = NULL; /* just retry with valloc/malloc */
1575 #endif
1576 #ifdef HAVE_VALLOC
1577 if( !buf )
1578 buf = valloc( allocLen );
1579 #endif
1580 if( !buf )
1581 buf = tr_malloc( allocLen );
1583 return buf;
1586 char *
1587 tr_realpath( const char * path, char * resolved_path )
1589 #ifdef WIN32
1590 /* From a message to the Mingw-msys list, Jun 2, 2005 by Mark Junker. */
1591 if( GetFullPathNameA( path, TR_PATH_MAX, resolved_path, NULL ) == 0 )
1592 return NULL;
1593 return resolved_path;
1594 #else
1595 return realpath( path, resolved_path );
1596 #endif
1599 /***
1600 ****
1601 ***/
1603 uint64_t
1604 tr_htonll( uint64_t x )
1606 #ifdef HAVE_HTONLL
1607 return htonll( x );
1608 #else
1609 /* fallback code by Runner and Juan Carlos Cobas at
1610 * http://www.codeproject.com/KB/cpp/endianness.aspx */
1611 return (((uint64_t)(htonl((int)((x << 32) >> 32))) << 32) |
1612 (unsigned int)htonl(((int)(x >> 32))));
1613 #endif
1616 uint64_t
1617 tr_ntohll( uint64_t x )
1619 #ifdef HAVE_NTOHLL
1620 return ntohll( x );
1621 #else
1622 /* fallback code by Runner and Juan Carlos Cobas at
1623 * http://www.codeproject.com/KB/cpp/endianness.aspx */
1624 return (((uint64_t)(ntohl((int)((x << 32) >> 32))) << 32) |
1625 (unsigned int)ntohl(((int)(x >> 32))));
1626 #endif
1629 /***
1630 ****
1631 ****
1632 ****
1633 ***/
1635 struct formatter_unit
1637 char * name;
1638 int64_t value;
1641 struct formatter_units
1643 struct formatter_unit units[4];
1646 enum { TR_FMT_KB, TR_FMT_MB, TR_FMT_GB, TR_FMT_TB };
1648 static void
1649 formatter_init( struct formatter_units * units,
1650 unsigned int kilo,
1651 const char * kb, const char * mb,
1652 const char * gb, const char * tb )
1654 uint64_t value = kilo;
1655 units->units[TR_FMT_KB].name = tr_strdup( kb );
1656 units->units[TR_FMT_KB].value = value;
1658 value *= kilo;
1659 units->units[TR_FMT_MB].name = tr_strdup( mb );
1660 units->units[TR_FMT_MB].value = value;
1662 value *= kilo;
1663 units->units[TR_FMT_GB].name = tr_strdup( gb );
1664 units->units[TR_FMT_GB].value = value;
1666 value *= kilo;
1667 units->units[TR_FMT_TB].name = tr_strdup( tb );
1668 units->units[TR_FMT_TB].value = value;
1671 static char*
1672 formatter_get_size_str( const struct formatter_units * u,
1673 char * buf, int64_t bytes, size_t buflen )
1675 int precision;
1676 double value;
1677 const char * units;
1678 const struct formatter_unit * unit;
1680 if( bytes < u->units[1].value ) unit = &u->units[0];
1681 else if( bytes < u->units[2].value ) unit = &u->units[1];
1682 else if( bytes < u->units[3].value ) unit = &u->units[2];
1683 else unit = &u->units[3];
1685 value = (double)bytes / unit->value;
1686 units = unit->name;
1687 if( unit->value == 1 )
1688 precision = 0;
1689 else if( value < 100 )
1690 precision = 2;
1691 else
1692 precision = 1;
1693 tr_snprintf( buf, buflen, "%.*f %s", precision, value, units );
1694 return buf;
1697 static struct formatter_units size_units;
1699 void
1700 tr_formatter_size_init( unsigned int kilo,
1701 const char * kb, const char * mb,
1702 const char * gb, const char * tb )
1704 formatter_init( &size_units, kilo, kb, mb, gb, tb );
1707 char*
1708 tr_formatter_size_B( char * buf, int64_t bytes, size_t buflen )
1710 return formatter_get_size_str( &size_units, buf, bytes, buflen );
1713 static struct formatter_units speed_units;
1715 unsigned int tr_speed_K = 0u;
1717 void
1718 tr_formatter_speed_init( unsigned int kilo,
1719 const char * kb, const char * mb,
1720 const char * gb, const char * tb )
1722 tr_speed_K = kilo;
1723 formatter_init( &speed_units, kilo, kb, mb, gb, tb );
1726 char*
1727 tr_formatter_speed_KBps( char * buf, double KBps, size_t buflen )
1729 const double K = speed_units.units[TR_FMT_KB].value;
1730 double speed = KBps;
1732 if( speed <= 999.95 ) /* 0.0 KB to 999.9 KB */
1733 tr_snprintf( buf, buflen, "%d %s", (int)speed, speed_units.units[TR_FMT_KB].name );
1734 else {
1735 speed /= K;
1736 if( speed <= 99.995 ) /* 0.98 MB to 99.99 MB */
1737 tr_snprintf( buf, buflen, "%.2f %s", speed, speed_units.units[TR_FMT_MB].name );
1738 else if (speed <= 999.95) /* 100.0 MB to 999.9 MB */
1739 tr_snprintf( buf, buflen, "%.1f %s", speed, speed_units.units[TR_FMT_MB].name );
1740 else {
1741 speed /= K;
1742 tr_snprintf( buf, buflen, "%.1f %s", speed, speed_units.units[TR_FMT_GB].name );
1746 return buf;
1749 static struct formatter_units mem_units;
1751 unsigned int tr_mem_K = 0u;
1753 void
1754 tr_formatter_mem_init( unsigned int kilo,
1755 const char * kb, const char * mb,
1756 const char * gb, const char * tb )
1758 tr_mem_K = kilo;
1759 formatter_init( &mem_units, kilo, kb, mb, gb, tb );
1762 char*
1763 tr_formatter_mem_B( char * buf, int64_t bytes_per_second, size_t buflen )
1765 return formatter_get_size_str( &mem_units, buf, bytes_per_second, buflen );
1768 void
1769 tr_formatter_get_units( tr_benc * d )
1771 int i;
1772 tr_benc * l;
1774 tr_bencDictReserve( d, 6 );
1776 tr_bencDictAddInt( d, "memory-bytes", mem_units.units[TR_FMT_KB].value );
1777 l = tr_bencDictAddList( d, "memory-units", 4 );
1778 for( i=0; i<4; i++ ) tr_bencListAddStr( l, mem_units.units[i].name );
1780 tr_bencDictAddInt( d, "size-bytes", size_units.units[TR_FMT_KB].value );
1781 l = tr_bencDictAddList( d, "size-units", 4 );
1782 for( i=0; i<4; i++ ) tr_bencListAddStr( l, size_units.units[i].name );
1784 tr_bencDictAddInt( d, "speed-bytes", speed_units.units[TR_FMT_KB].value );
1785 l = tr_bencDictAddList( d, "speed-units", 4 );
1786 for( i=0; i<4; i++ ) tr_bencListAddStr( l, speed_units.units[i].name );