📄 console.cpp
字号:
Interact("Peers: %d Min: %d Max: %d", (int)(WORLD.GetPeersCount()), (int)cfg_min_peers, (int)cfg_max_peers); Interact("Listening on: %s", WORLD.GetListen()); Interact(""); Interact("Ratio: %.2f Seed time: %luh Seed ratio: %.2f", (double)(Self.TotalUL()) / ( Self.TotalDL() ? Self.TotalDL() : BTCONTENT.GetTotalFilesLength() ), (unsigned long)cfg_seed_hours, cfg_seed_ratio); Interact("Cache in use: %dKB Wants: %dKB Max: %dMB", (int)(BTCONTENT.CacheUsed()/1024), (int)(BTCONTENT.CacheSize()/1024), (int)cfg_cache_size); if(arg_ctcs) Interact("CTCS Server: %s", arg_ctcs); oper_mode = 0; return 1; }else if( sel == 2 + O_NCHANNELS + STATUSLINES ){ // pause/resume if( WORLD.IsPaused() ) WORLD.Resume(); else WORLD.Pause(); oper_mode = 0; return 1; } } else if( 2==oper_mode ){ if( !*param ){ oper_mode = 0; return OperatorMenu(""); } ChangeChannel(channel, param); oper_mode = 0; return OperatorMenu(""); } Interact("Exiting menu"); return 1;}void Console::ChangeChannel(int channel, const char *param){ ConStream *dest = (ConStream *)0; if( !strcmp(param, m_stdout.GetName()) ) dest = &m_stdout; else if( !strcmp(param, m_stderr.GetName()) ) dest = &m_stderr; else{ for( int i=0; i <= O_NCHANNELS; i++ ){ if( channel != i && !strcmp(param, m_streams[i]->GetName()) ){ dest = m_streams[i]; break; } } if( !dest ){ FILE *stream; if( dest = new ConStream ){ if( !strcmp(param, m_streams[channel]->GetName()) ) delete m_streams[channel]; if( stream = fopen(param, "a") ) dest->Associate(stream, param); else{ Interact("Error opening file: %s", strerror(errno)); delete dest; dest = (ConStream *)0; } }else Interact("Failed to allocate memory."); } } if( dest ){ if( m_streams[channel] != &m_stdout && m_streams[channel] != &m_stderr ){ int in_use = 0; for( int i=0; i <= O_NCHANNELS; i++ ){ if( channel != i && m_streams[channel] == m_streams[i] ) in_use = 1; } if( !in_use) delete m_streams[channel]; } m_streams[channel] = dest; }}void Console::ShowFiles(){ BTFILE *file = 0; BitField tmpFilter; int n = 0; Interact("Files in this torrent:"); while( file = BTCONTENT.GetNextFile(file) ){ n++; BTCONTENT.SetTmpFilter(n, &tmpFilter); BitField tmpBitField = *BTCONTENT.pBF; tmpBitField.Except(tmpFilter); Interact("%d) %s [%llu] %d%%", n, file->bf_filename, (unsigned long long)(file->bf_length), (int)(100 * tmpBitField.Count() / BTCONTENT.getFilePieces(n))); }}void Console::Status(int immediate){ static char buffer[80]; if( immediate ) m_skip_status = 0; if( m_pre_dlrate.TimeUsed() || immediate ){ if( m_skip_status ) m_skip_status = 0; else{ (CONSOLE.*m_statusline[m_status_format])(buffer, sizeof(buffer)); if( !m_status_last ) Print_n(""); Update("%*s", -(int)sizeof(buffer)+1, buffer); m_status_last = 1; if(arg_verbose) Debug("Cache: %dK/%dM Hits: %d Miss: %d %d%%", (int)(BTCONTENT.CacheUsed()/1024), (int)cfg_cache_size, (int)(BTCONTENT.CacheHits()), (int)(BTCONTENT.CacheMiss()), BTCONTENT.CacheHits() ? (int)(100 * BTCONTENT.CacheHits() / (BTCONTENT.CacheHits()+BTCONTENT.CacheMiss())) : 0); } m_pre_dlrate = Self.GetDLRate(); m_pre_ulrate = Self.GetULRate(); }}void Console::StatusLine0(char buffer[], size_t length){ char partial[30] = ""; if(arg_file_to_download){ BitField tmpBitField = *BTCONTENT.pBF; tmpBitField.Except(*BTCONTENT.pBFilter); sprintf( partial, "P:%d/%d ", (int)(tmpBitField.Count()), (int)(BTCONTENT.getFilePieces(arg_file_to_download)) ); } char checked[14] = ""; if( BTCONTENT.CheckedPieces() < BTCONTENT.GetNPieces() ){ sprintf( checked, "Checking: %d%%", 100 * BTCONTENT.CheckedPieces() / BTCONTENT.GetNPieces() ); } snprintf(buffer, length, "%c %d/%d/%d [%d/%d/%d] %lluMB,%lluMB | %d,%dK/s | %d,%dK E:%d,%d %s%s", LIVE_CHAR[m_live_idx++], (int)(WORLD.GetSeedsCount()), (int)(WORLD.GetPeersCount()) - WORLD.GetSeedsCount(), (int)(Tracker.GetPeersCount()), (int)(BTCONTENT.pBF->Count()), (int)(BTCONTENT.GetNPieces()), (int)(WORLD.Pieces_I_Can_Get()), (unsigned long long)(Self.TotalDL()) >> 20, (unsigned long long)(Self.TotalUL()) >> 20, (int)(Self.RateDL() >> 10), (int)(Self.RateUL() >> 10), (int)(m_pre_dlrate.RateMeasure(Self.GetDLRate()) >> 10), (int)(m_pre_ulrate.RateMeasure(Self.GetULRate()) >> 10), (int)(Tracker.GetRefuseClick()), (int)(Tracker.GetOkClick()), partial, (Tracker.GetStatus()==T_CONNECTING) ? "Connecting" : ( (Tracker.GetStatus()==T_READY) ? "Connected" : (Tracker.IsQuitting() ? "Quitting" : (WORLD.IsPaused() ? "Paused" : checked)) ) );}void Console::StatusLine1(char buffer[], size_t length){ char partial[30] = ""; if(arg_file_to_download){ BitField tmpBitField = *BTCONTENT.pBF; tmpBitField.Except(*BTCONTENT.pBFilter); sprintf( partial, "P:%d/%d ", (int)(tmpBitField.Count()), (int)(BTCONTENT.getFilePieces(arg_file_to_download)) ); } char checked[14] = ""; if( BTCONTENT.CheckedPieces() < BTCONTENT.GetNPieces() ){ sprintf( checked, "Checking: %d%%", 100 * BTCONTENT.CheckedPieces() / BTCONTENT.GetNPieces() ); } char complete[8]; if( BTCONTENT.pBF->IsFull() ) sprintf(complete, "seeding"); else sprintf(complete, "%d/%d%%", 100 * BTCONTENT.pBF->Count() / BTCONTENT.GetNPieces(), 100 * WORLD.Pieces_I_Can_Get() / BTCONTENT.GetNPieces()); long remain = -1; char timeleft[20]; size_t rate; if( !BTCONTENT.pBF->IsFull() ){ // downloading if( rate = Self.RateDL() ){ // don't overflow remain if( BTCONTENT.GetLeftBytes() < (uint64_t)rate << 22 ) remain = BTCONTENT.GetLeftBytes() / rate / 60; else remain = 99999; } }else{ //seeding if( cfg_seed_hours ) remain = cfg_seed_hours * 60 - (now - BTCONTENT.GetSeedTime()) / 60; else if( rate = Self.RateUL() ){ // don't overflow remain if( cfg_seed_ratio * (Self.TotalDL() ? Self.TotalDL() : BTCONTENT.GetTotalFilesLength()) - Self.TotalUL() < (uint64_t)rate << 22 ) remain = (long)( cfg_seed_ratio * (Self.TotalDL() ? Self.TotalDL() : BTCONTENT.GetTotalFilesLength()) - Self.TotalUL() ) / rate / 60; else remain = 99999; } } if( remain >= 0 ){ if( remain < 60000 ) // 1000 hours snprintf(timeleft, sizeof(timeleft), "%d:%2.2d", (int)(remain / 60), (int)(remain % 60)); else strcpy(timeleft, ">999hr"); }else strcpy(timeleft, "stalled"); snprintf(buffer, length, "%c S:%d/%d L:%d/%d C:%d R=%.2f D=%d U=%d K/s %s %s %s%s", LIVE_CHAR[m_live_idx++], (int)(WORLD.GetSeedsCount()), (int)(Tracker.GetSeedsCount()) - ((BTCONTENT.pBF->IsFull() && Tracker.GetSeedsCount() > 0) ? 1 : 0), (int)(WORLD.GetPeersCount()) - WORLD.GetSeedsCount() - WORLD.GetConnCount(), (int)(Tracker.GetPeersCount()) - Tracker.GetSeedsCount() - ((!BTCONTENT.pBF->IsFull() && Tracker.GetPeersCount() > 0) ? 1 : 0), (int)(WORLD.GetConnCount()), (double)(Self.TotalUL()) / ( Self.TotalDL() ? Self.TotalDL() : BTCONTENT.GetTotalFilesLength() ), (int)(Self.RateDL() >> 10), (int)(Self.RateUL() >> 10), complete, timeleft, partial, (Tracker.GetStatus()==T_CONNECTING) ? "Connecting" : ( (Tracker.GetStatus()==T_READY) ? "Connected" : (Tracker.IsQuitting() ? "Quitting" : (WORLD.IsPaused() ? "Paused" : checked)) ) );}void Console::Print(const char *message, ...){ va_list ap; va_start(ap, message); if( K_LINES != m_streams[O_INPUT]->GetInputMode() || (!m_streams[O_NORMAL]->SameDev(m_streams[O_INTERACT]) && !m_streams[O_NORMAL]->SameDev(m_streams[O_INPUT])) ){ if( m_streams[O_NORMAL]->Output(message, ap) ) SyncNewlines(O_NORMAL); } if( arg_verbose && !m_streams[O_DEBUG]->SameDev(m_streams[O_NORMAL]) ){ if( m_streams[O_DEBUG]->Output(message, ap) ) SyncNewlines(O_DEBUG); } va_end(ap);}/* Print message without a terminating newline With a null message, start/insure a new line*/void Console::Print_n(const char *message, ...){ va_list ap; va_start(ap, message); if( m_status_last && *message ) Print_n(""); m_status_last = 0; if( K_LINES != m_streams[O_INPUT]->GetInputMode() || (!m_streams[O_NORMAL]->SameDev(m_streams[O_INTERACT]) && !m_streams[O_NORMAL]->SameDev(m_streams[O_INPUT])) ){ if( m_streams[O_NORMAL]->Output_n(message, ap) ) SyncNewlines(O_NORMAL); } if( arg_verbose && !m_streams[O_DEBUG]->SameDev(m_streams[O_NORMAL]) ){ if( m_streams[O_DEBUG]->Output_n(message, ap) ) SyncNewlines(O_DEBUG); } va_end(ap);}/* Update (replace) the current line (no terminating newline)*/void Console::Update(const char *message, ...){ va_list ap; va_start(ap, message); m_status_last = 0; if( K_LINES != m_streams[O_INPUT]->GetInputMode() || (!m_streams[O_NORMAL]->SameDev(m_streams[O_INTERACT]) && !m_streams[O_NORMAL]->SameDev(m_streams[O_INPUT])) ){ if( m_streams[O_NORMAL]->Update(message, ap) ) SyncNewlines(O_NORMAL); } if( arg_verbose && !m_streams[O_DEBUG]->SameDev(m_streams[O_NORMAL]) ){ if( m_streams[O_DEBUG]->Update(message, ap) ) SyncNewlines(O_DEBUG); } va_end(ap);}/* "sev" indicates the severity of the message. 0: will be printed but not sent to CTCS 1: extremely urgent/important 2: less important 3: no problem*/void Console::Warning(int sev, const char *message, ...){ va_list ap; va_start(ap, message); if( m_streams[O_WARNING]->Output(message, ap) ) SyncNewlines(O_WARNING); if( arg_verbose && !m_streams[O_DEBUG]->SameDev(m_streams[O_WARNING]) ){ if( m_streams[O_DEBUG]->Output(message, ap) ) SyncNewlines(O_DEBUG); } if(sev && arg_ctcs){ char cmsg[CTCS_BUFSIZE]; vsnprintf(cmsg, CTCS_BUFSIZE, message, ap); CTCS.Send_Info(sev, cmsg); } va_end(ap);}void Console::Debug(const char *message, ...){ static char buffer[80]; if( !arg_verbose ) return; char *format = (char *)0; size_t buflen; va_list ap; va_start(ap, message); if( K_LINES != m_streams[O_INPUT]->GetInputMode() || (!m_streams[O_DEBUG]->SameDev(m_streams[O_INTERACT]) && !m_streams[O_DEBUG]->SameDev(m_streams[O_INPUT])) ){ size_t need = strlen(message)+1 + 10*sizeof(unsigned long)/4; if( need > sizeof(buffer) && (format = new char[need]) ) buflen = need; else{ format = buffer; buflen = sizeof(buffer); } snprintf(format, buflen, "%lu %s", (unsigned long)now, message); if( m_streams[O_DEBUG]->Output(format, ap) ) SyncNewlines(O_DEBUG); if( format && format != buffer ) delete []format; } va_end(ap);}/* Print debug message without a terminating newline With a null message, start/insure a new line*/void Console::Debug_n(const char *message, ...){ static char buffer[80]; static int f_new_line = 1; if( !arg_verbose ) return; va_list ap; va_start(ap, message); if( K_LINES != m_streams[O_INPUT]->GetInputMode() || (!m_streams[O_DEBUG]->SameDev(m_streams[O_INTERACT]) && !m_streams[O_DEBUG]->SameDev(m_streams[O_INPUT])) ){ if( m_streams[O_DEBUG]->SameDev(m_streams[O_NORMAL]) ){ if( m_status_last && *message ) Debug_n(""); m_status_last = 0; } if( f_new_line && *message ){ char *format = (char *)0; size_t buflen; size_t need = strlen(message)+1 + 10*sizeof(unsigned long)/4; if( need > sizeof(buffer) && (format = new char[need]) ) buflen = need; else{ format = buffer; buflen = sizeof(buffer); } snprintf(format, buflen, "%lu %s", (unsigned long)now, message); if( m_streams[O_DEBUG]->Output_n(format, ap) ) SyncNewlines(O_DEBUG); if( format && format != buffer ) delete []format; } else if( m_streams[O_DEBUG]->Output_n(message, ap) ) SyncNewlines(O_DEBUG); if( *message ) f_new_line = 0; else f_new_line = 1; } va_end(ap);}void Console::Interact(const char *message, ...){ va_list ap; va_start(ap, message); if( m_streams[O_INTERACT]->Output(message, ap) ) SyncNewlines(O_INTERACT); va_end(ap);}/* Print interactive message without a terminating newline With a null message, start/insure a new line*/void Console::Interact_n(const char *message, ...){ va_list ap; va_start(ap, message); if( m_streams[O_INTERACT]->SameDev(m_streams[O_NORMAL]) ){ if( m_status_last && *message ) Interact_n(""); m_status_last = 0; } if( m_streams[O_INTERACT]->Output_n(message, ap) ) SyncNewlines(O_INTERACT); va_end(ap);}/* Update (replace) the current interactive line (no terminating newline)*/void Console::InteractU(const char *message, ...){ va_list ap; va_start(ap, message); if( m_streams[O_INTERACT]->SameDev(m_streams[O_NORMAL]) ){ if( m_status_last ) Interact_n(""); m_status_last = 0; } if( m_streams[O_INTERACT]->Update(message, ap) ) SyncNewlines(O_INTERACT); va_end(ap);}// Avoid using this during normal operation, as it blocks for input!char *Console::Input(const char *prompt, char *field, size_t length){ char *retval; m_streams[O_INPUT]->SetInputMode(K_LINES); Interact_n(0, ""); Interact_n(0, "%s", prompt); retval = m_streams[O_INPUT]->Input(field, length); m_streams[O_INPUT]->SetInputMode(K_CHARS); return retval;}void Console::SyncNewlines(int master){ for( int i=0; i < O_NCHANNELS; i++ ){ if( i != master && m_streams[i]->SameDev(m_streams[master]) ) m_streams[i]->SyncNewline(m_streams[master]); }}RETSIGTYPE Console::Signal(int sig_no){ switch( sig_no ){ case SIGTTOU: for( int i=0; i < O_NCHANNELS; i++ ) if( isatty(m_streams[i]->Fileno()) ) m_streams[i]->Suspend(); m_conmode = m_streams[O_INPUT]->GetInputMode(); break; case SIGTTIN: if( isatty(m_streams[O_INPUT]->Fileno()) ) m_streams[O_INPUT]->Suspend(); m_conmode = m_streams[O_INPUT]->GetInputMode(); break; case SIGCONT: for( int i=0; i <= O_NCHANNELS; i++ ) if( isatty(m_streams[i]->Fileno()) ) m_streams[i]->Resume(); m_streams[O_INPUT]->SetInputMode(m_conmode); // restore my handler signal(SIGTSTP, signals); break; case SIGTSTP: m_conmode = m_streams[O_INPUT]->GetInputMode(); m_streams[O_INPUT]->RestoreMode(); // let the system default action proceed signal(sig_no, SIG_DFL); raise(sig_no); break; default: break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -