⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 btcontent.cpp

📁 cTorrent advanced 3.3.2。是对 CTorrent 的一个改进版本。这是目前的最新版。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
  return 1;}int btContent::GetHashValue(size_t idx,unsigned char *md){  if( global_buffer_size < m_piece_length ){    delete []global_piece_buffer;    global_piece_buffer = new char[m_piece_length];    global_buffer_size = global_piece_buffer ? m_piece_length : 0;  }  if( ReadPiece(global_piece_buffer,idx) < 0 ) return -1;  Sha1(global_piece_buffer,GetPieceLength(idx),md);  return 0;}// This is btcontent's "IntervalCheck()"int btContent::SeedTimeout(){  uint64_t dl;  size_t oldrate = m_prevdlrate;  if( Seeding() && (!m_flush_failed || IsFull()) ){    if( !m_seed_timestamp ){      if( IsFull() ){        Tracker.Reset(15);        ReleaseHashTable();      }      Self.ResetDLTimer();  // set/report dl rate = 0      m_prevdlrate = 0;      m_seed_timestamp = now;      for( size_t n=1; n <= m_btfiles.GetNFiles(); n++ )        m_btfiles.CloseFile(n);  // files will reopen read-only      // Free global buffer prior to CompletionCommand fork (reallocate after).      delete []global_piece_buffer;      global_piece_buffer = (char *)0;      if( Self.TotalDL() > 0 ){        CONSOLE.Print("Download complete.");        CONSOLE.Print("Total time used: %ld minutes.",          (long)((now - m_start_timestamp) / 60));        if(arg_verbose) CONSOLE.cpu();        if( arg_completion_exit )          CompletionCommand();      }      // Reallocate global buffer for uploading.      global_piece_buffer = new char[DEFAULT_SLICE_SIZE];      global_buffer_size = global_piece_buffer ? DEFAULT_SLICE_SIZE : 0;      if(arg_ctcs) CTCS.Send_Status();      CONSOLE.Print_n("Seed for others %lu hours",        (unsigned long)cfg_seed_hours);      if( cfg_seed_ratio )        CONSOLE.Print_n(" or to ratio of %.2f", cfg_seed_ratio);      CONSOLE.Print("");    }else if( now < m_seed_timestamp ) m_seed_timestamp = now;    dl = (Self.TotalDL() > 0) ? Self.TotalDL() : GetTotalFilesLength();    if( (cfg_seed_ratio == 0 && cfg_seed_hours == 0) ||        (cfg_seed_hours > 0 &&          (now - m_seed_timestamp) >= (cfg_seed_hours * 60 * 60)) ||        (cfg_seed_ratio > 0 &&          cfg_seed_ratio <= (double) Self.TotalUL() / dl) ){      if( m_flush_failed ){        if( !WORLD.IsPaused() ){          CONSOLE.Warning(1,            "Seeding completed but cache flush failed; pausing...");          WORLD.Pause();        }      }else return 1;    }  }else{    m_prevdlrate = Self.RateDL();    if( m_prevdlrate == 0 && oldrate > 0 &&        global_buffer_size > DEFAULT_SLICE_SIZE ){      delete []global_piece_buffer;      global_piece_buffer = new char[DEFAULT_SLICE_SIZE];      global_buffer_size = global_piece_buffer ? DEFAULT_SLICE_SIZE : 0;    }  }  if( (cfg_cache_size && now >= m_cache_eval_time) ||      (oldrate == 0 && m_prevdlrate > 0) ){    CacheEval();  }  return 0;}void btContent::CompletionCommand(){  char *pt, *pd, *pw, *cmdstr;  int nt=0, nd=0, nw=0;  pt = pd = pw = arg_completion_exit;  while( pt = strstr(pt, "&t") ){ nt++; pt+=2; }  while( pd = strstr(pd, "&d") ){ nd++; pd+=2; }  while( pw = strstr(pw, "&w") ){ nw++; pw+=2; }  if( nt || nd || nw ){    char wd[MAXPATHLEN], *ptmp, *parg = arg_completion_exit;    if( nw && !getcwd(wd, MAXPATHLEN) ){      CONSOLE.Warning(2, "warn, couldn't get working directory:  %s",        strerror(errno));      return;    }    cmdstr = new char[1 + strlen(arg_completion_exit) +      nt * (strlen(arg_metainfo_file) - 2) +      nd * (strlen(m_btfiles.GetDataName()) - 2) +      nw * (strlen(wd) - 2)];    if( !cmdstr ){      CONSOLE.Warning(2,        "warn, failed to allocate memory for completion command");      return;    }    strcpy(cmdstr, arg_completion_exit);    pt = strstr(cmdstr, "&t");    pd = strstr(cmdstr, "&d");    pw = strstr(cmdstr, "&w");    while( pt || pd || pw ){      if( pt && (!pd || pt < pd) && (!pw || pt < pw) ){        strcpy(pt, arg_metainfo_file);        ptmp = cmdstr + strlen(cmdstr);        parg = strstr(parg, "&t") + 2;        strcat(pt, parg);        pt = strstr(ptmp, "&t");        if( pd ) pd = strstr(ptmp, "&d");        if( pw ) pw = strstr(ptmp, "&w");      }      if( pd && (!pt || pd < pt) && (!pw || pd < pw) ){        strcpy(pd, m_btfiles.GetDataName());        ptmp = cmdstr + strlen(cmdstr);        parg = strstr(parg, "&d") + 2;        strcat(pd, parg);        pd = strstr(ptmp, "&d");        if( pt ) pt = strstr(ptmp, "&t");        if( pw ) pw = strstr(ptmp, "&w");      }      if( pw && (!pt || pw < pt) && (!pd || pw < pd) ){        strcpy(pw, wd);        ptmp = cmdstr + strlen(cmdstr);        parg = strstr(parg, "&w") + 2;        strcat(pw, parg);        pw = strstr(ptmp, "&w");        if( pt ) pt = strstr(ptmp, "&t");        if( pd ) pd = strstr(ptmp, "&d");      }    }  }  else cmdstr = arg_completion_exit;  if(arg_verbose) CONSOLE.Debug("Executing: %s", cmdstr);#ifdef HAVE_WORKING_FORK  if( cfg_cache_size ){  // maybe free some cache before forking    CacheEval();    if( m_cache_size < m_cache_used && !m_flush_failed ) CacheClean(0);  }  pid_t r;  if( (r = fork()) < 0 ){    CONSOLE.Warning(2,"warn, fork failed running completion command:  %s",      strerror(errno));  }else if( r==0 ){    if( m_cache_used ){  // free the cache in the child process      BTCACHE *p, *pnext;      for( p=m_cache_oldest; p; p=pnext ){        pnext = p->age_next;        delete []p->bc_buf;        delete p;      }    }#endif    if( system(cmdstr) < 0 )      CONSOLE.Warning(2, "warn, failure running completion command:  %s",        strerror(errno));#ifdef HAVE_WORKING_FORK    exit(EXIT_SUCCESS);  }#endif  if( cmdstr != arg_completion_exit ) delete []cmdstr;}void btContent::CheckFilter(){  BitField tmpBitfield;  BFNODE *original = m_current_filter;  if( !m_filters ) return;  if( !m_current_filter ) m_current_filter = m_filters;  while( m_current_filter ){    tmpBitfield = *pBF;             // what I have...    tmpBitfield.Comb(GetFilter());  // ...plus what I don't want    if( !tmpBitfield.IsFull() ) break;    m_current_filter = m_current_filter->next;  }  if( !m_current_filter ){    if( !IsFull() ) CONSOLE.Print("End of download files list.");    for( BFNODE *goner=m_filters; goner; goner=m_current_filter ){      m_current_filter = goner->next;      delete goner;    }    m_filters = (BFNODE *)0;  }  if( m_current_filter != original ){    if( m_current_filter ){      size_t last;      tmpBitfield = *GetFilter();      tmpBitfield.Invert();      // what I want...      tmpBitfield.Except(*pBF);  // ...that I don't have      last = tmpBitfield.IsSet(m_npieces-1) ? 1 : 0;      if( GetFilter()->IsEmpty() )        CONSOLE.Print("Downloading remaining files");      else CONSOLE.Print("Downloading file(s): %s", m_current_filter->name);      CONSOLE.Print( "Pieces: %d (%llu bytes)", (int)(tmpBitfield.Count()),        (unsigned long long)          ((tmpBitfield.Count() - last) * (uint64_t)m_piece_length +           (last ? GetPieceLength(m_npieces-1) : 0)) );    }  }  if( m_seed_timestamp && m_current_filter ){    // was seeding, now downloading again    m_seed_timestamp = (time_t)0;  }}void btContent::SetFilter(){  // Set up filter list  char *list=(char *)0, *tok, *dash, *plus;  size_t start, end;  BitField tmpFilter, *pfilter;  BFNODE *node=m_filters, *pnode=(BFNODE *)0;  if( arg_file_to_download ){    pBMasterFilter->SetAll();    list = new char[strlen(arg_file_to_download) + 1];    if( !list ){      CONSOLE.Warning(1, "error, failed to allocate memory for filter");      return;    }    strcpy(list, arg_file_to_download);    tok = strtok(list, ", ");    while( tok ){      if( !node ){        node = new BFNODE;        if( !node ){          CONSOLE.Warning(1, "error, failed to allocate memory for filter");          return;        }        if( pnode ) pnode->next = node;        else m_filters = node;      }      if( node->name && strlen(node->name) < strlen(tok) ){        delete []node->name;        node->name = (char *)0;      }      if( !node->name ){        node->name = new char[strlen(tok)+1];        if( !node ){          CONSOLE.Warning(1, "error, failed to allocate memory for filter");          return;        }      }      strcpy(node->name, tok);      pfilter = &(node->bitfield);      if( strstr(tok, "...") || strchr(tok, '*') ){        pfilter->Clear();        pBMasterFilter->Clear();        pnode = node;        node = node->next;        break;      }      pfilter->SetAll();      do{        start = atoi(tok);        m_btfiles.SetFilter((int)start, &tmpFilter, m_piece_length);        pfilter->And(tmpFilter);        plus = strchr(tok, '+');        if( (dash = strchr(tok, '-')) && (!plus || dash < plus) ){          end = atoi(dash + 1);          while( ++start <= end ){            m_btfiles.SetFilter((int)start, &tmpFilter, m_piece_length);            pfilter->And(tmpFilter);          }        }        tok = plus ? plus+1 : plus;      }while( tok );      pBMasterFilter->And(*pfilter);      tok = strtok(NULL, ", ");      pnode = node;      node = node->next;    }    delete []list;  }else  // no arg_file_to_download    pBMasterFilter->Clear();  if( m_filters && m_filters->bitfield.IsEmpty() ){    delete []arg_file_to_download;    arg_file_to_download = (char *)0;    pBMasterFilter->Clear();    node = m_filters;    pnode = (BFNODE *)0;  }  if( node ){    if( m_filters == node ) m_filters = (BFNODE *)0;    if( pnode ) pnode->next = (BFNODE *)0;    for( BFNODE *goner=node; goner; goner=node ){      node = goner->next;      delete goner;    }  }  m_current_filter = (BFNODE *)0;  CheckFilter();  WORLD.CheckInterest();}BitField *btContent::GetNextFilter(BitField *pfilter) const{  static BFNODE *p = m_filters;  if( !pfilter ) p = m_filters;  else if( p && &(p->bitfield) == pfilter ){    p = p->next;  }else{    for( p=m_filters; p && (&(p->bitfield) != pfilter); p = p->next );    if(p) p = p->next;    else p = m_filters;  }  if(p) return &(p->bitfield);  else return (BitField *) 0;}int btContent::Seeding() const{  if( IsFull() || m_flush_failed ) return 1;  if( arg_file_to_download && !m_current_filter ) return 1;  return 0;}// Note, this functions assumes the program is exiting.void btContent::SaveBitfield(){  if( arg_bitfield_file ){    if( m_check_piece < m_npieces ){  // still checking      // Anything unchecked needs to be checked next time.      pBChecked->Invert();      pBF->Comb(*pBChecked);    }    if( !pBF->IsFull() ) pBF->WriteToFile(arg_bitfield_file);  }}void btContent::CountDupBlock(size_t len){  m_dup_blocks++;  Tracker.CountDL(len);}void btContent::DumpCache(){  BTCACHE *p = m_cache_oldest;  int count;  CONSOLE.Debug("CACHE CONTENTS:");  count = 0;  for( ; p; p = p->age_next ){    CONSOLE.Debug("  %p prev=%p %d/%d/%d %sflushed",      p, p->age_prev,      (int)(p->bc_off / m_piece_length), (int)(p->bc_off % m_piece_length),      (int)(p->bc_len),      p->bc_f_flush ? "un" : "");    count++;  }  CONSOLE.Debug("  count=%d", count);  CONSOLE.Debug("  newest=%p", m_cache_newest);  CONSOLE.Debug("BY PIECE:");  count = 0;  for( size_t idx=0; idx < m_npieces; idx++ ){    for( p=m_cache[idx]; p; p=p->bc_next ){      CONSOLE.Debug("  %p prev=%p %d/%d/%d %sflushed",        p, p->bc_prev,        (int)(p->bc_off / m_piece_length), (int)(p->bc_off % m_piece_length),        (int)(p->bc_len),        p->bc_f_flush ? "un" : "");      count++;    }  }  CONSOLE.Debug("  count=%d", count);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -