📄 btfiles.cpp
字号:
if( stat(pathname, &sb) < 0 ){ CONSOLE.Warning(1, "error, stat file %s failed, %s", pathname, strerror(errno)); return -1; } if( S_IFREG & sb.st_mode ){ pbf = _new_bfnode();#ifndef WINDOWS if( !pbf ) return -1;#endif pbf->bf_length = m_total_files_length = sb.st_size; pbf->bf_filename = new char[strlen(pathname) + 1];#ifndef WINDOWS if( !pbf->bf_filename ) return -1;#endif strcpy(pbf->bf_filename, pathname); m_btfhead = pbf; }else if( S_IFDIR & sb.st_mode ){ char wd[MAXPATHLEN]; if( !getcwd(wd,MAXPATHLEN) ) return -1; m_directory = new char[strlen(pathname) + 1];#ifndef WINDOWS if( !m_directory ) return -1;#endif strcpy(m_directory, pathname); if(chdir(m_directory) < 0){ CONSOLE.Warning(1, "error, change work directory to %s failed, %s", m_directory, strerror(errno)); return -1; } if(_btf_recurses_directory((const char*)0, &lastnode) < 0) return -1; if( chdir(wd) < 0) return -1; }else{ CONSOLE.Warning(1, "error, %s is not a directory or regular file.", pathname); return -1; } return 0;}int btFiles::BuildFromMI(const char *metabuf, const size_t metabuf_len, const char *saveas){ char path[MAXPATHLEN]; const char *s, *p; size_t r,q,n; int64_t t; if( !decode_query(metabuf, metabuf_len, "info|name",&s,&q,(int64_t*) 0,QUERY_STR) || MAXPATHLEN <= q) return -1; memcpy(path, s, q); path[q] = '\0'; r = decode_query(metabuf,metabuf_len,"info|files",(const char**) 0, &q,(int64_t*) 0,QUERY_POS); if( r ){ BTFILE *pbf_last = (BTFILE*) 0; BTFILE *pbf = (BTFILE*) 0; size_t dl; if( decode_query(metabuf,metabuf_len,"info|length", (const char**) 0,(size_t*) 0,(int64_t*) 0,QUERY_LONG) ) return -1; if( saveas ){ m_directory = new char[strlen(saveas) + 1];#ifndef WINDOWS if(!m_directory) return -1;#endif strcpy(m_directory,saveas); }else{ m_directory = new char[strlen(path) + 1];#ifndef WINDOWS if( !m_directory) return -1;#endif strcpy(m_directory,path); } /* now r saved the pos of files list. q saved list length */ p = metabuf + r + 1; q--; for(; q && 'e' != *p; p += dl, q -= dl){ if(!(dl = decode_dict(p, q, (const char*) 0)) ) return -1; if( !decode_query(p, dl, "length", (const char**) 0, (size_t*) 0,&t,QUERY_LONG) ) return -1; pbf = _new_bfnode();#ifndef WINDOWS if( !pbf ) return -1;#endif pbf->bf_length = t; m_total_files_length += t; r = decode_query(p, dl, "path", (const char **) 0, &n,(int64_t*) 0,QUERY_POS); if( !r ) return -1; if(!decode_list2path(p + r, n, path)) return -1; pbf->bf_filename = new char[strlen(path) + 1];#ifndef WINDOWS if( !pbf->bf_filename ) return -1;#endif strcpy(pbf->bf_filename, path); if(pbf_last) pbf_last->bf_next = pbf; else m_btfhead = pbf; pbf_last = pbf; } }else{ if( !decode_query(metabuf,metabuf_len,"info|length", (const char**) 0,(size_t*) 0,&t,QUERY_LONG) ) return -1; m_btfhead = _new_bfnode();#ifndef WINDOWS if( !m_btfhead) return -1;#endif m_btfhead->bf_length = m_total_files_length = t; if( saveas ){ m_btfhead->bf_filename = new char[strlen(saveas) + 1];#ifndef WINDOWS if(!m_btfhead->bf_filename ) return -1;#endif strcpy(m_btfhead->bf_filename, saveas); }else{ m_btfhead->bf_filename = new char[strlen(path) + 1];#ifndef WINDOWS if(!m_btfhead->bf_filename ) return -1;#endif strcpy(m_btfhead->bf_filename, path); } } return 0;}int btFiles::CreateFiles(){ int check_exist = 0; char fn[MAXPATHLEN]; BTFILE *pbt = m_btfhead; struct stat sb; for(; pbt; pbt = pbt->bf_next){ if( m_directory ){ if( MAXPATHLEN <= snprintf(fn, MAXPATHLEN, "%s%c%s", m_directory, PATH_SP, pbt->bf_filename) ) return -1; }else{ strcpy(fn, pbt->bf_filename); } if(stat(fn ,&sb) < 0){ if(ENOENT == errno){ if( arg_allocate ){ CONSOLE.Interact_n(""); CONSOLE.Interact_n("Creating %s", fn); } if( !_btf_creat_by_path(fn,pbt->bf_length)){ CONSOLE.Warning(1, "error, create file %s failed.",fn); return -1; } }else{ CONSOLE.Warning(1, "error, couldn't create file %s", fn); return -1; } }else{ if( !check_exist) check_exist = 1; if( !(S_IFREG & sb.st_mode) ){ CONSOLE.Warning(1, "error, file %s is not a regular file.", fn); return -1; } if(sb.st_size != pbt->bf_length){ CONSOLE.Warning(1, "error, file %s size doesn't match. must be %llu", fn, (unsigned long long)(pbt->bf_length)); return -1; } } } //end for return check_exist;}void btFiles::PrintOut(){ BTFILE *p = m_btfhead; size_t id = 1; CONSOLE.Print(""); CONSOLE.Print("FILES INFO"); BitField tmpBitField, tmpFilter; if(m_directory) CONSOLE.Print("Directory: %s", m_directory); for( ; p ; p = p->bf_next ){ CONSOLE.Print_n(""); CONSOLE.Print_n("<%d> %s%s [%llu]", id, m_directory ? " " : "", p->bf_filename, (unsigned long long)(p->bf_length)); if( !arg_flg_exam_only ){ BTCONTENT.SetTmpFilter(id, &tmpFilter); tmpBitField = *BTCONTENT.pBF; tmpBitField.Except(tmpFilter); CONSOLE.Print_n(" %d/%d (%d%%)", (int)(tmpBitField.Count()), (int)(BTCONTENT.getFilePieces(id)), 100 * tmpBitField.Count() / BTCONTENT.getFilePieces(id)); } ++id; } CONSOLE.Print("Total: %lu MB", (unsigned long)(m_total_files_length/1024/1024));}size_t btFiles::FillMetaInfo(FILE* fp){ BTFILE *p; if( m_directory ){ // multi files if( bencode_str("files", fp) != 1 ) return 0; if( bencode_begin_list(fp) != 1) return 0; for( p = m_btfhead; p; p = p->bf_next){ if( bencode_begin_dict(fp) != 1) return 0; if( bencode_str("length", fp) != 1 ) return 0; if( bencode_int(p->bf_length, fp) != 1) return 0; if( bencode_str("path", fp) != 1) return 0; if( bencode_path2list(p->bf_filename, fp) != 1 ) return 0; if( bencode_end_dict_list(fp) != 1) return 0; } if(bencode_end_dict_list(fp) != 1 ) return 0; if(bencode_str("name", fp) != 1) return 0; return bencode_str(m_directory, fp); }else{ if( bencode_str("length", fp) != 1 ) return 0; if( bencode_int(m_btfhead->bf_length, fp) != 1) return 0; if( bencode_str("name", fp) != 1 ) return 0; return bencode_str(m_btfhead->bf_filename, fp); } return 1;}void btFiles::SetFilter(int nfile, BitField *pFilter, size_t pieceLength, int print){ //set the filter BTFILE *p = m_btfhead; size_t id = 1; uint64_t sizeBuffer=0; size_t index; pFilter->SetAll(); for( ; p ; p = p->bf_next ){ if(id++ == nfile){ size_t start, stop; start = sizeBuffer / pieceLength; stop = (sizeBuffer + p->bf_length) / pieceLength; // calculation is off if file ends on a piece boundary if(0 == (sizeBuffer + p->bf_length) % pieceLength) --stop; p->bf_npieces = stop-start+1; // This "if" cuts down on false prints with CTCS. if(arg_file_to_download == nfile && print){ CONSOLE.Print("Downloading file: <%d> %s", nfile, p->bf_filename); CONSOLE.Print("Pieces: %d - %d (%d)", start, stop, p->bf_npieces); } for(index = start; index <= stop; index++) { pFilter->UnSet(index); } } sizeBuffer+=(uint64_t) p->bf_length; } if(nfile>=id || nfile==0){ CONSOLE.Print("End of files list. Resuming normal behaviour"); pFilter->Invert(); arg_file_to_download = 0; }}size_t btFiles::getFilePieces(size_t nfile){ //returns the pieces of the file already gotten BTFILE *p = m_btfhead; size_t id = 1; for( ; p ; p = p->bf_next ){ if(id++ == nfile){ return p->bf_npieces; } } return 0;}BTFILE *btFiles::GetNextFile(BTFILE *file){ static BTFILE *p = m_btfhead; if( 0==file ) p = m_btfhead; else if( p==file ){ p = p->bf_next; }else{ for( p=m_btfhead; p && (p != file); p = p->bf_next); if( 0==p ){ p = m_btfhead; }else{ p = p->bf_next; } } return p;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -