Ejemplo n.º 1
0
tr_lock*
tr_lockNew( void )
{
    tr_lock *           l = tr_new0( tr_lock, 1 );

#ifdef WIN32
    InitializeCriticalSection( &l->lock ); /* supports recursion */
#else
    pthread_mutexattr_t attr;
    pthread_mutexattr_init( &attr );
    pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE );
    pthread_mutex_init( &l->lock, &attr );
#endif

    return l;
}
Ejemplo n.º 2
0
void
tr_eventInit( tr_session * session )
{
    tr_event_handle * eh;

    session->events = NULL;

    eh = tr_new0( tr_event_handle, 1 );
    eh->lock = tr_lockNew( );
    pipe( eh->fds );
    eh->session = session;
    eh->thread = tr_threadNew( libeventThreadFunc, eh );

    /* wait until the libevent thread is running */
    while( session->events == NULL )
        tr_wait( 100 );
}
Ejemplo n.º 3
0
tr_webseed*
tr_webseedNew( struct tr_torrent * torrent,
               const char        * url,
               tr_peer_callback  * callback,
               void              * callback_data )
{
    tr_webseed * w = tr_new0( tr_webseed, 1 );

    memcpy( w->hash, torrent->info.hash, SHA_DIGEST_LENGTH );
    w->session = torrent->session;
    w->content = evbuffer_new( );
    w->url = tr_strdup( url );
    w->callback = callback;
    w->callback_data = callback_data;
    tr_rcConstruct( &w->rateDown );
    return w;
}
Ejemplo n.º 4
0
static tr_peerIo*
tr_peerIoNew( tr_session       * session,
              tr_bandwidth     * parent,
              const tr_address * addr,
              tr_port            port,
              const uint8_t    * torrentHash,
              tr_bool            isIncoming,
              tr_bool            isSeed,
              int                socket )
{
    tr_peerIo * io;

    assert( session != NULL );
    assert( session->events != NULL );
    assert( tr_isBool( isIncoming ) );
    assert( tr_isBool( isSeed ) );
    assert( tr_amInEventThread( session ) );

    if( socket >= 0 ) {
        tr_netSetTOS( socket, session->peerSocketTOS );
        maybeSetCongestionAlgorithm( socket, session->peer_congestion_algorithm );
    }

    io = tr_new0( tr_peerIo, 1 );
    io->magicNumber = MAGIC_NUMBER;
    io->refCount = 1;
    io->crypto = tr_cryptoNew( torrentHash, isIncoming );
    io->session = session;
    io->addr = *addr;
    io->isSeed = isSeed;
    io->port = port;
    io->socket = socket;
    io->isIncoming = isIncoming != 0;
    io->hasFinishedConnecting = FALSE;
    io->timeCreated = tr_time( );
    io->inbuf = evbuffer_new( );
    io->outbuf = evbuffer_new( );
    tr_bandwidthConstruct( &io->bandwidth, session, parent );
    tr_bandwidthSetPeer( &io->bandwidth, io );
    dbgmsg( io, "bandwidth is %p; its parent is %p", &io->bandwidth, parent );

    event_set( &io->event_read, io->socket, EV_READ, event_read_cb, io );
    event_set( &io->event_write, io->socket, EV_WRITE, event_write_cb, io );

    return io;
}
Ejemplo n.º 5
0
void
tr_eventInit (tr_session * session)
{
    tr_event_handle * eh;

    session->events = NULL;

    eh = tr_new0 (tr_event_handle, 1);
    eh->lock = tr_lockNew ();
    if (pipe (eh->fds) == -1)
      tr_logAddError ("Unable to write to pipe() in libtransmission: %s", tr_strerror(errno));
    eh->session = session;
    eh->thread = tr_threadNew (libeventThreadFunc, eh);

    /* wait until the libevent thread is running */
    while (session->events == NULL)
        tr_wait_msec (100);
}
Ejemplo n.º 6
0
// Recebe uma função e um ponteiro para seus argumentos, e executa a função dada em...
// ...uma nova thread.
tr_thread * tr_threadNew(void (*func)(void *), void * arg) {
    tr_thread * t = tr_new0(tr_thread, 1);  // aloca espaço para uma estrutura 'tr_thread'

    t->func = func;
    t->arg = arg;

#ifdef WIN32   // Se o Transmission for utilizado em um sistema operacional Windows...
{              // ...usa os comandos de thread específicos para ele.
    unsigned int id;
    t->thread_handle = (HANDLE) _beginthreadex (NULL, 0, &ThreadFunc, t, 0, &id);
    t->thread = (DWORD) id;
}
#else          // ...caso contrário, use pthread, que é padrão do Mac OS e Linux
    pthread_create(&t->thread, NULL, (void* (*)(void*)) ThreadFunc, t);
    pthread_detach(t->thread);
#endif
    return t;
}
Ejemplo n.º 7
0
tr_webseed*
tr_webseedNew( struct tr_torrent * torrent,
               const char *        url,
               tr_delivery_func    callback,
               void *              callback_userdata )
{
    tr_webseed * w = tr_new0( tr_webseed, 1 );

    memcpy( w->hash, torrent->info.hash, SHA_DIGEST_LENGTH );
    w->session = torrent->session;
    w->content = evbuffer_new( );
    w->url = tr_strdup( url );
    w->callback = callback;
    w->callback_userdata = callback_userdata;
    tr_rcConstruct( &w->rateDown );
/*fprintf( stderr, "w->callback_userdata is %p\n", w->callback_userdata );*/
    return w;
}
Ejemplo n.º 8
0
tr_handshake*
tr_handshakeNew (tr_peerIo           * io,
                 tr_encryption_mode    encryptionMode,
                 handshakeDoneCB       doneCB,
                 void                * doneUserData)
{
  tr_handshake * handshake;
  tr_session * session = tr_peerIoGetSession (io);

  handshake = tr_new0 (tr_handshake, 1);
  handshake->io = io;
  handshake->crypto = tr_peerIoGetCrypto (io);
  handshake->encryptionMode = encryptionMode;
  handshake->doneCB = doneCB;
  handshake->doneUserData = doneUserData;
  handshake->session = session;
  handshake->timeout_timer = evtimer_new (session->event_base, handshakeTimeout, handshake);
  tr_timerAdd (handshake->timeout_timer, HANDSHAKE_TIMEOUT_SEC, 0);

  tr_peerIoRef (io); /* balanced by the unref in tr_handshakeFree */
  tr_peerIoSetIOFuncs (handshake->io, canRead, NULL, gotError, handshake);
  tr_peerIoSetEncryption (io, PEER_ENCRYPTION_NONE);

  if (tr_peerIoIsIncoming (handshake->io))
    {
      setReadState (handshake, AWAITING_HANDSHAKE);
    }
  else if (encryptionMode != TR_CLEAR_PREFERRED)
    {
      sendYa (handshake);
    }
  else
    {
      uint8_t msg[HANDSHAKE_SIZE];
      buildHandshakeMessage (handshake, msg);

      handshake->haveSentBitTorrentHandshake = 1;
      setReadState (handshake, AWAITING_HANDSHAKE);
      tr_peerIoWriteBytes (handshake->io, msg, sizeof (msg), false);
    }

  return handshake;
}
Ejemplo n.º 9
0
static int
test_single_directory_random_payload_impl (const tr_tracker_info * trackers,
                                           const size_t            trackerCount,
                                           const size_t            maxFileCount,
                                           const size_t            maxFileSize,
                                           const char            * comment,
                                           const bool              isPrivate)
{
  size_t i;
  void ** payloads;
  size_t * payloadSizes;
  size_t payloadCount;

  /* build random payloads */
  payloadCount = 1 + tr_rand_int_weak (maxFileCount);
  payloads = tr_new0 (void*, payloadCount);
  payloadSizes = tr_new0 (size_t, payloadCount);
  for (i=0; i<payloadCount; i++)
    {
      const size_t n = 1 + tr_rand_int_weak (maxFileSize);
      payloads[i] = tr_new (char, n);
      tr_rand_buffer (payloads[i], n);
      payloadSizes[i] = n;
    }

  /* run the test */
  test_single_directory_impl (trackers,
                              trackerCount,
                              (const void**) payloads,
                              payloadSizes,
                              payloadCount,
                              comment,
                              isPrivate);

  /* cleanup */
  for (i=0; i<payloadCount; i++)
    tr_free (payloads[i]);
  tr_free (payloads);
  tr_free (payloadSizes);

  return 0;
}
Ejemplo n.º 10
0
tr_thread *
tr_threadNew (void (*func)(void *), void * arg)
{
    tr_thread * t = tr_new0 (tr_thread, 1);

    t->func = func;
    t->arg  = arg;

#ifdef WIN32
    {
        unsigned int id;
        t->thread_handle = (HANDLE) _beginthreadex (NULL, 0, &ThreadFunc, t, 0, &id);
        t->thread = (DWORD) id;
    }
#else
    pthread_create (&t->thread, NULL, (void* (*)(void*))ThreadFunc, t);
    pthread_detach (t->thread);
#endif

    return t;
}
Ejemplo n.º 11
0
tr_timer*
tr_timerNew( tr_session  * session,
             timer_func    func,
             void        * user_data,
             uint64_t      interval_milliseconds )
{
    tr_timer * timer;

    assert( tr_amInEventThread( session ) );

    timer = tr_new0( tr_timer, 1 );
    timer->func = func;
    timer->user_data = user_data;
    timer->eh = session->events;

    tr_timevalMsec( interval_milliseconds, &timer->tv );
    evtimer_set( &timer->event, timerCallback, timer );
    evtimer_add( &timer->event,  &timer->tv );

    return timer;
}
Ejemplo n.º 12
0
tr_shared *
tr_sharedInit( tr_session  * session )
{
    tr_shared * s = tr_new0( tr_shared, 1 );

    s->session      = session;
    s->isEnabled    = FALSE;
    s->upnpStatus   = TR_PORT_UNMAPPED;
    s->natpmpStatus = TR_PORT_UNMAPPED;

#if 0
    if( isEnabled )
    {
        s->timer = tr_new0( struct event, 1 );
        evtimer_set( s->timer, onTimer, s );
        tr_timerAdd( s->timer, 0, 333000 );
    }
#endif

    return s;
}
Ejemplo n.º 13
0
tr_timer*
tr_timerNew( struct tr_handle * handle,
             timer_func         func,
             void *             user_data,
             uint64_t           interval_milliseconds )
{
    tr_timer * timer;

    assert( handle );
    assert( handle->events );

    timer = tr_new0( tr_timer, 1 );
    tr_timevalMsec( interval_milliseconds, &timer->tv );
    timer->func = func;
    timer->user_data = user_data;
    timer->eh = handle->events;
    evtimer_set( &timer->event, timerCallback, timer );

    if( tr_amInThread( handle->events->thread ) )
    {
        evtimer_add( &timer->event,  &timer->tv );
    }
    else
    {
        const char ch = 't';
        int        fd = handle->events->fds[1];
        tr_lock *  lock = handle->events->lock;

        tr_lockLock( lock );
        pipewrite( fd, &ch, 1 );
        pipewrite( fd, &timer, sizeof( timer ) );
        tr_lockUnlock( lock );
    }

    return timer;
}
Ejemplo n.º 14
0
static tr_pex*
listToPex (tr_variant * peerList, size_t * setme_len)
{
    size_t i;
    size_t n;
    const size_t len = tr_variantListSize (peerList);
    tr_pex * pex = tr_new0 (tr_pex, len);

    for (i=n=0; i<len; ++i)
    {
        int64_t port;
        const char * ip;
        tr_address addr;
        tr_variant * peer = tr_variantListChild (peerList, i);

        if (peer == NULL)
            continue;
        if (!tr_variantDictFindStr (peer, TR_KEY_ip, &ip, NULL))
            continue;
        if (!tr_address_from_string (&addr, ip))
            continue;
        if (!tr_variantDictFindInt (peer, TR_KEY_port, &port))
            continue;
        if ((port < 0) || (port > USHRT_MAX))
            continue;
        if (!tr_address_is_valid_for_peers (&addr, port))
            continue;

        pex[n].addr = addr;
        pex[n].port = htons ((uint16_t)port);
        ++n;
    }

    *setme_len = n;
    return pex;
}
Ejemplo n.º 15
0
void
tr_logAddMessage (const char * file,
                  int line,
                  tr_log_level level,
                  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 ());

  /* build the text message */
  *buf = '\0';
  va_start (ap, fmt);
  evutil_vsnprintf (buf, sizeof (buf), fmt, ap);
  va_end (ap);

  OutputDebugStringA (buf);

  if (*buf)
    {
      if (tr_logGetQueueEnabled ())
        {
          tr_log_message * newmsg;
          newmsg = tr_new0 (tr_log_message, 1);
          newmsg->level = level;
          newmsg->when = tr_time ();
          newmsg->message = tr_strdup (buf);
          newmsg->file = file;
          newmsg->line = line;
          newmsg->name = tr_strdup (name);

          *myQueueTail = newmsg;
          myQueueTail = &newmsg->next;
          ++myQueueLength;

          if (myQueueLength > TR_LOG_MAX_QUEUE_LENGTH)
            {
              tr_log_message * old = myQueue;
              myQueue = old->next;
              old->next = NULL;
              tr_logFreeQueue (old);
              --myQueueLength;
              assert (myQueueLength == TR_LOG_MAX_QUEUE_LENGTH);
            }
        }
      else
        {
          FILE * fp;
          char timestr[64];

          fp = tr_logGetFile ();
          if (fp == NULL)
            fp = stderr;

          tr_logGetTimeStr (timestr, sizeof (timestr));

          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;
}
Ejemplo n.º 16
0
tr_publisher_t*
tr_publisherNew( void )
{
    return tr_new0( tr_publisher_t, 1 );
}
Ejemplo n.º 17
0
tr_magnet_info *
tr_magnetParse( const char * uri )
{
    bool got_checksum = false;
    int trCount = 0;
    int wsCount = 0;
    char * tr[MAX_TRACKERS];
    char * ws[MAX_WEBSEEDS];
    char * displayName = NULL;
    uint8_t sha1[SHA_DIGEST_LENGTH];
    tr_magnet_info * info = NULL;

    if( ( uri != NULL ) && !memcmp( uri, "magnet:?", 8 ) )
    {
        const char * walk;

        for( walk=uri+8; walk && *walk; )
        {
            const char * key = walk;
            const char * delim = strchr( key, '=' );
            const char * val = delim == NULL ? NULL : delim + 1;
            const char * next = strchr( delim == NULL ? key : val, '&' );
            int keylen, vallen;

            if( delim != NULL )
                keylen = delim - key;
            else if( next != NULL )
                keylen = next - key;
            else
                keylen = strlen( key );

            if( val == NULL )
                vallen = 0;
            else if( next != NULL )
                vallen = next - val;
            else
                vallen = strlen( val );

            if( ( keylen==2 ) && !memcmp( key, "xt", 2 ) && val && !memcmp( val, "urn:btih:", 9 ) )
            {
                const char * hash = val + 9;
                const int hashlen = vallen - 9;

                if( hashlen == 40 ) {
                    tr_hex_to_sha1( sha1, hash );
                    got_checksum = true;
                }
                else if( hashlen == 32 ) {
                    base32_to_sha1( sha1, hash, hashlen );
                    got_checksum = true;
                }
            }

            if( ( vallen > 0 ) && ( keylen==2 ) && !memcmp( key, "dn", 2 ) )
                displayName = tr_http_unescape( val, vallen );

            if( ( vallen > 0 ) && ( trCount < MAX_TRACKERS ) ) {
                int i;
                if( ( keylen==2 ) && !memcmp( key, "tr", 2 ) )
                    tr[trCount++] = tr_http_unescape( val, vallen );
                else if( ( sscanf( key, "tr.%d=", &i ) == 1 ) && ( i > 0 ) ) /* ticket #3341 */
                    tr[trCount++] = tr_http_unescape( val, vallen );
            }

            if( ( vallen > 0 ) && ( keylen==2 ) && !memcmp( key, "ws", 2 ) && ( wsCount < MAX_WEBSEEDS ) )
                ws[wsCount++] = tr_http_unescape( val, vallen );

            walk = next != NULL ? next + 1 : NULL;
        }
    }

    if( got_checksum )
    {
        info = tr_new0( tr_magnet_info, 1 );
        info->displayName = displayName;
        info->trackerCount = trCount;
        info->trackers = tr_memdup( tr, sizeof(char*) * trCount );
        info->webseedCount = wsCount;
        info->webseeds = tr_memdup( ws, sizeof(char*) * wsCount );
        memcpy( info->hash, sha1, sizeof(uint8_t) * SHA_DIGEST_LENGTH );
    }

    return info;
}
Ejemplo n.º 18
0
void
tr_logAddMessage (const char * file,
                  int line,
                  tr_log_level level,
                  const char * name,
                  const char * fmt,
                  ...)
{
  const int err = errno; /* message logging shouldn't affect errno */
  char buf[1024];
  int buf_len;
  va_list ap;
  tr_lockLock (getMessageLock ());

  /* build the text message */
  *buf = '\0';
  va_start (ap, fmt);
  buf_len = evutil_vsnprintf (buf, sizeof (buf), fmt, ap);
  va_end (ap);

  if (buf_len < 0)
    return;

#ifdef _WIN32
  if ((size_t) buf_len < sizeof (buf) - 3)
    {
      buf[buf_len + 0] = '\r';
      buf[buf_len + 1] = '\n';
      buf[buf_len + 2] = '\0';
      OutputDebugStringA (buf);
      buf[buf_len + 0] = '\0';
    }
  else
    {
      OutputDebugStringA (buf);
    }
#endif

  if (*buf)
    {
      if (tr_logGetQueueEnabled ())
        {
          tr_log_message * newmsg;
          newmsg = tr_new0 (tr_log_message, 1);
          newmsg->level = level;
          newmsg->when = tr_time ();
          newmsg->message = tr_strdup (buf);
          newmsg->file = file;
          newmsg->line = line;
          newmsg->name = tr_strdup (name);

          *myQueueTail = newmsg;
          myQueueTail = &newmsg->next;
          ++myQueueLength;

          if (myQueueLength > TR_LOG_MAX_QUEUE_LENGTH)
            {
              tr_log_message * old = myQueue;
              myQueue = old->next;
              old->next = NULL;
              tr_logFreeQueue (old);
              --myQueueLength;
              assert (myQueueLength == TR_LOG_MAX_QUEUE_LENGTH);
            }
        }
      else
        {
          tr_sys_file_t fp;
          char timestr[64];

          fp = tr_logGetFile ();
          if (fp == TR_BAD_SYS_FILE)
            fp = tr_sys_file_get_std (TR_STD_SYS_FILE_ERR, NULL);

          tr_logGetTimeStr (timestr, sizeof (timestr));

          if (name)
            tr_sys_file_write_fmt (fp, "[%s] %s: %s" TR_NATIVE_EOL_STR, NULL, timestr, name, buf);
          else
            tr_sys_file_write_fmt (fp, "[%s] %s" TR_NATIVE_EOL_STR, NULL, timestr, buf);
          tr_sys_file_flush (fp, NULL);
        }
    }

  tr_lockUnlock (getMessageLock ());
  errno = err;
}
Ejemplo n.º 19
0
tr_watchdir_backend *
tr_watchdir_win32_new (tr_watchdir_t handle)
{
  const char * const path = tr_watchdir_get_path (handle);
  wchar_t * wide_path;
  tr_watchdir_win32 * backend;

  backend = tr_new0 (tr_watchdir_win32, 1);
  backend->base.free_func = &tr_watchdir_win32_free;
  backend->fd = INVALID_HANDLE_VALUE;
  backend->notify_pipe[0] = backend->notify_pipe[1] = TR_BAD_SOCKET;

  if ((wide_path = tr_win32_utf8_to_native (path, -1)) == NULL)
    {
      log_error ("Failed to convert \"%s\" to native path", path);
      goto fail;
    }

  if ((backend->fd = CreateFileW (wide_path, FILE_LIST_DIRECTORY,
                                  FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                                  NULL, OPEN_EXISTING,
                                  FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
                                  NULL)) == INVALID_HANDLE_VALUE)
    {
      log_error ("Failed to open directory \"%s\"", path);
      goto fail;
    }

  tr_free (wide_path);
  wide_path = NULL;

  backend->overlapped.Pointer = handle;

  if (!ReadDirectoryChangesW (backend->fd, backend->buffer, sizeof (backend->buffer), FALSE,
                              WIN32_WATCH_MASK, NULL, &backend->overlapped, NULL))
    {
      log_error ("Failed to read directory changes");
      goto fail;
    }

  if (evutil_socketpair (AF_INET, SOCK_STREAM, 0, backend->notify_pipe) == -1)
    {
      log_error ("Failed to create notify pipe: %s", tr_strerror (errno));
      goto fail;
    }

  if ((backend->event = bufferevent_socket_new (tr_watchdir_get_event_base (handle),
                                                backend->notify_pipe[0], 0)) == NULL)
    {
      log_error ("Failed to create event buffer: %s", tr_strerror (errno));
      goto fail;
    }

  bufferevent_setwatermark (backend->event, EV_READ, sizeof (FILE_NOTIFY_INFORMATION), 0);
  bufferevent_setcb (backend->event, &tr_watchdir_win32_on_event, NULL, NULL, handle);
  bufferevent_enable (backend->event, EV_READ);

  if ((backend->thread = (HANDLE) _beginthreadex (NULL, 0, &tr_watchdir_win32_thread,
                                                  handle, 0, NULL)) == NULL)
    {
      log_error ("Failed to create thread");
      goto fail;
    }

  /* Perform an initial scan on the directory */
  if (event_base_once (tr_watchdir_get_event_base (handle), -1, EV_TIMEOUT,
                       &tr_watchdir_win32_on_first_scan, handle, NULL) == -1)
    log_error ("Failed to perform initial scan: %s", tr_strerror (errno));

  return BACKEND_DOWNCAST (backend);

fail:
  tr_watchdir_win32_free (BACKEND_DOWNCAST (backend));
  tr_free (wide_path);
  return NULL;
}
Ejemplo n.º 20
0
static char const* parseFiles(tr_info* inf, tr_variant* files, tr_variant const* length)
{
    int64_t len;

    inf->totalSize = 0;

    if (tr_variantIsList(files)) /* multi-file mode */
    {
        struct evbuffer* buf;
        char const* result;

        if (path_component_is_suspicious(inf->name))
        {
            return "path";
        }

        buf = evbuffer_new();
        result = NULL;

        inf->isFolder = true;
        inf->fileCount = tr_variantListSize(files);
        inf->files = tr_new0(tr_file, inf->fileCount);

        for (tr_file_index_t i = 0; i < inf->fileCount; i++)
        {
            tr_variant* file;
            tr_variant* path;

            file = tr_variantListChild(files, i);

            if (!tr_variantIsDict(file))
            {
                result = "files";
                break;
            }

            if (!tr_variantDictFindList(file, TR_KEY_path_utf_8, &path))
            {
                if (!tr_variantDictFindList(file, TR_KEY_path, &path))
                {
                    result = "path";
                    break;
                }
            }

            if (!getfile(&inf->files[i].name, inf->name, path, buf))
            {
                result = "path";
                break;
            }

            if (!tr_variantDictFindInt(file, TR_KEY_length, &len))
            {
                result = "length";
                break;
            }

            inf->files[i].length = len;
            inf->totalSize += len;
        }

        evbuffer_free(buf);
        return result;
    }
    else if (tr_variantGetInt(length, &len)) /* single-file mode */
    {
        if (path_component_is_suspicious(inf->name))
        {
            return "path";
        }

        inf->isFolder = false;
        inf->fileCount = 1;
        inf->files = tr_new0(tr_file, 1);
        inf->files[0].name = tr_strdup(inf->name);
        inf->files[0].length = len;
        inf->totalSize += len;
    }
    else
    {
        return "length";
    }

    return NULL;
}
Ejemplo n.º 21
0
tr_ratecontrol*
tr_rcInit( void )
{
    return tr_new0( tr_ratecontrol, 1 );
}
Ejemplo n.º 22
0
tr_rc4_ctx_t
tr_rc4_new (void)
{
  return tr_new0 (Arc4, 1);
}
Ejemplo n.º 23
0
static const char*
getannounce( tr_info * inf,
             tr_benc * meta )
{
    const char *      str;
    tr_tracker_info * trackers = NULL;
    int               trackerCount = 0;
    tr_benc *         tiers;

    /* Announce-list */
    if( tr_bencDictFindList( meta, "announce-list", &tiers ) )
    {
        int       n;
        int       i, j;
        const int numTiers = tr_bencListSize( tiers );

        n = 0;
        for( i = 0; i < numTiers; ++i )
            n += tr_bencListSize( tr_bencListChild( tiers, i ) );

        trackers = tr_new0( tr_tracker_info, n );
        trackerCount = 0;

        for( i = 0; i < numTiers; ++i )
        {
            tr_benc * tier = tr_bencListChild( tiers, i );
            const int tierSize = tr_bencListSize( tier );
            for( j = 0; j < tierSize; ++j )
            {
                if( tr_bencGetStr( tr_bencListChild( tier, j ), &str ) )
                {
                    char * url = tr_strstrip( tr_strdup( str ) );
                    if( tr_httpIsValidURL( url ) )
                    {
                        tr_tracker_info * t = trackers + trackerCount++;
                        t->tier = i;
                        t->announce = tr_strdup( url );
                        t->scrape = announceToScrape( url );
                    }
                    tr_free( url );
                }
            }
        }

        /* did we use any of the tiers? */
        if( !trackerCount )
        {
            tr_free( trackers );
            trackers = NULL;
        }
    }

    /* Regular announce value */
    if( !trackerCount
      && tr_bencDictFindStr( meta, "announce", &str ) )
    {
        char * url = tr_strstrip( tr_strdup( str ) );
        if( tr_httpIsValidURL( url ) )
        {
            trackers = tr_new0( tr_tracker_info, 1 );
            trackers[trackerCount].tier = 0;
            trackers[trackerCount].announce = tr_strdup( url );
            trackers[trackerCount++].scrape = announceToScrape( url );
            /*fprintf( stderr, "single announce: [%s]\n", url );*/
        }
        tr_free( url );
    }

    inf->trackers = trackers;
    inf->trackerCount = trackerCount;

    return inf->trackerCount ? NULL : "announce";
}
Ejemplo n.º 24
0
void
tr_msg( const char * file, int line,
        tr_msg_level level,
        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( ) );

    /* build the text message */
    *buf = '\0';
    va_start( ap, fmt );
    evutil_vsnprintf( buf, sizeof( buf ), fmt, ap );
    va_end( ap );

    OutputDebugString( buf );

    if( *buf )
    {
        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 );

            *messageQueueTail = newmsg;
            messageQueueTail = &newmsg->next;
            ++messageQueueCount;

            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 );
            }
        }
        else
        {
            char timestr[64];
            FILE * fp;

            fp = tr_getLog( );
            if( fp == NULL )
                fp = stderr;

            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 );
        }
    }

    tr_lockUnlock( getMessageLock( ) );
    errno = err;
}
Ejemplo n.º 25
0
static tr_list*
node_alloc( void )
{
    return tr_new0( tr_list, 1 );
}
Ejemplo n.º 26
0
static const char*
getannounce( tr_info * inf, tr_benc * meta )
{
    const char *      str;
    tr_tracker_info * trackers = NULL;
    int               trackerCount = 0;
    tr_benc *         tiers;

    /* Announce-list */
    if( tr_bencDictFindList( meta, "announce-list", &tiers ) )
    {
        int       n;
        int       i, j, validTiers;
        const int numTiers = tr_bencListSize( tiers );

        n = 0;
        for( i = 0; i < numTiers; ++i )
            n += tr_bencListSize( tr_bencListChild( tiers, i ) );

        trackers = tr_new0( tr_tracker_info, n );

        for( i = 0, validTiers = 0; i < numTiers; ++i )
        {
            tr_benc * tier = tr_bencListChild( tiers, i );
            const int tierSize = tr_bencListSize( tier );
            tr_bool anyAdded = FALSE;
            for( j = 0; j < tierSize; ++j )
            {
                if( tr_bencGetStr( tr_bencListChild( tier, j ), &str ) )
                {
                    char * url = tr_strstrip( tr_strdup( str ) );
                    if( tr_urlIsValidTracker( url ) )
                    {
                        tr_tracker_info * t = trackers + trackerCount;
                        t->tier = validTiers;
                        t->announce = tr_strdup( url );
                        t->scrape = tr_convertAnnounceToScrape( url );
                        t->id = trackerCount;

                        anyAdded = TRUE;
                        ++trackerCount;
                    }
                    tr_free( url );
                }
            }

            if( anyAdded )
                ++validTiers;
        }

        /* did we use any of the tiers? */
        if( !trackerCount )
        {
            tr_free( trackers );
            trackers = NULL;
        }
    }

    /* Regular announce value */
    if( !trackerCount
      && tr_bencDictFindStr( meta, "announce", &str ) )
    {
        char * url = tr_strstrip( tr_strdup( str ) );
        if( tr_urlIsValidTracker( url ) )
        {
            trackers = tr_new0( tr_tracker_info, 1 );
            trackers[trackerCount].tier = 0;
            trackers[trackerCount].announce = tr_strdup( url );
            trackers[trackerCount].scrape = tr_convertAnnounceToScrape( url );
            trackers[trackerCount].id = 0;
            trackerCount++;
            /*fprintf( stderr, "single announce: [%s]\n", url );*/
        }
        tr_free( url );
    }

    inf->trackers = trackers;
    inf->trackerCount = trackerCount;

    return NULL;
}