/** * draw a nice download status-bar */ static int progress_func(CSdp& csdp, double TotalToDownload, double NowDownloaded, double TotalToUpload, double NowUploaded) { (void)csdp; (void)TotalToUpload; (void)NowUploaded; //remove unused warning if (TotalToDownload == NowDownloaded) //force output when download is finished LOG_PROGRESS(NowDownloaded,TotalToDownload, true); else LOG_PROGRESS(NowDownloaded,TotalToDownload); return 0; }
/** * draw a nice download status-bar */ static int progress_func(CSdp& csdp, double TotalToDownload, double NowDownloaded, double TotalToUpload, double NowUploaded) { (void)csdp; (void)TotalToUpload; (void)NowUploaded; //remove unused warning LOG_PROGRESS(NowDownloaded,TotalToDownload); return 0; }
int CFileSystem::validatePool(const std::string& path) { if(!directoryExists(path)) { LOG_ERROR("Pool directory doesn't exist: %s", path.c_str()); return 0; } int res=0; std::list <std::string>dirs; dirs.push_back(path); int maxdirs=257; //FIXME: unknown dirs in pool will break bar int finished=0; IHash* md5=new HashMD5(); while(!dirs.empty()) { struct dirent* dentry; DIR* d; const std::string dir=dirs.front(); dirs.pop_front(); d=opendir(dir.c_str()); while ( (dentry=readdir(d))!=NULL) { LOG_PROGRESS(finished, maxdirs); std::string absname=dir; absname += PATH_DELIMITER; absname += dentry->d_name; if (dentry->d_name[0]!='.') { //don't check hidden files / . / .. #ifndef WIN32 if ((dentry->d_type & DT_DIR)!=0) { //directory #else struct stat sb; stat(absname.c_str(), &sb); if((sb.st_mode & S_IFDIR)!=0) { #endif dirs.push_back(absname); } else { FileData filedata=FileData(); int len=absname.length(); if (len<36) { //file length has at least to be <md5[0]><md5[1]>/<md5[2-30]>.gz LOG_ERROR("Invalid file: %s", absname.c_str()); } else { std::string md5str=""; md5str.push_back(absname.at(len-36)); //get md5 from path + filename md5str.push_back(absname.at(len-35)); md5str.append(absname.substr(len-33, 30)); md5->Set(md5str); for(unsigned i=0; i<16; i++) { filedata.md5[i]=md5->get(i); } if (!fileIsValid(&filedata, absname)) { //check if md5 in filename is the same as in filename LOG_ERROR("Invalid File in pool: %s",absname.c_str()); } else { res++; } } } } } finished++; closedir(d); } delete md5; LOG_PROGRESS(finished, maxdirs, true); LOG(""); return res; } bool CFileSystem::isOlder(const std::string& filename, int secs) { struct stat sb; if (stat(filename.c_str(),&sb)<0) { return true; } time_t t; #ifdef WIN32 SYSTEMTIME pTime; FILETIME pFTime; GetSystemTime(&pTime); SystemTimeToFileTime(&pTime, &pFTime); t = FiletimeToTimestamp(pFTime); #else time(&t); #endif LOG_DEBUG("%s is %d seconds old, redownloading at %d",filename.c_str(), (int)(t - sb.st_ctime), secs); return (t<sb.st_ctime+secs); } bool CFileSystem::fileExists(const std::string& filename) { struct stat buffer; return stat(filename.c_str(), &buffer) == 0; } bool CFileSystem::parseTorrent(const char* data, int size, IDownload* dl) { struct be_node* node=be_decoden(data, size); //#ifdef DEBUG // be_dump(node); //#endif if(node==NULL) { LOG_ERROR("couldn't parse torrent"); return false; } if (node->type!=BE_DICT) { LOG_ERROR("Error in torrent data"); be_free(node); return false; } int i; struct be_node* infonode=NULL; for (i = 0; node->val.d[i].val; ++i) { //search for a dict with name info if ((node->type==BE_DICT) && (strcmp(node->val.d[i].key,"info")==0)) { infonode=node->val.d[i].val; break; } } if (infonode==NULL) { LOG_ERROR("couldn't find info node in be dict"); be_free(node); return false; } for (i = 0; infonode->val.d[i].val; ++i) { //fetch needed data from dict and fill into dl struct be_node*datanode; datanode=infonode->val.d[i].val; switch(datanode->type) { case BE_STR: //current value is a string if ((strcmp("name",infonode->val.d[i].key)==0) && (dl->name.empty())) { //set filename if not already set dl->name=datanode->val.s; } else if (!strcmp("pieces", infonode->val.d[i].key)) { //hash sum of a piece const int count = be_str_len(datanode)/20; //one sha1 sum is 5 * 4 bytes long for (int i=0; i<count; i++) { struct IDownload::piece piece; const unsigned char* data=(unsigned char*)&datanode->val.s[i*20]; piece.sha=new HashSHA1(); if (!piece.sha->Set(data, 20)) { LOG_ERROR("Error setting sha1"); } piece.state=IDownload::STATE_NONE; dl->pieces.push_back(piece); } } break; case BE_INT: //current value is a int if (strcmp("length",infonode->val.d[i].key)==0) { //filesize dl->size=datanode->val.i; } else if (!strcmp("piece length",infonode->val.d[i].key)) { //length of a piece dl->piecesize=datanode->val.i; LOG_DEBUG("dl->piecesize: %d", dl->piecesize); } break; default: break; } } LOG_DEBUG("Parsed torrent data: %s %d", dl->name.c_str(), dl->piecesize); be_free(node); return true; } bool CFileSystem::dumpSDP(const std::string& filename) { std::list<FileData*> files; files.clear(); if (!parseSdp(filename, files)) return false; LOG_INFO("md5 (filename in pool) crc32 size filename"); std::list<FileData*>::iterator it; HashMD5 md5; for(it=files.begin(); it!=files.end(); ++it) { md5.Set((*it)->md5, sizeof((*it)->md5)); LOG_INFO("%s %.8X %8d %s",md5.toString().c_str(), (*it)->crc32, (*it)->size, (*it)->name.c_str()); } return true; }
void CHttpDownloader::showProcess(IDownload* download, bool force) { int done = download->getProgress(); int size = download->size; LOG_PROGRESS(done, size, force); }