bool cYTCache::download(MI_MOVIE_INFO *mi) { std::string file = getName(mi); std::string xml = getName(mi, "xml"); if (!access(file, R_OK) && !access(xml, R_OK)) { fprintf(stderr, "%s: %s already present and valid\n", __func__, file.c_str()); return true; } FILE * fp = fopen(file.c_str(), "wb"); if (!fp) { perror(file.c_str()); return false; } CURL *curl = curl_easy_init(); if (!curl) { fclose(fp); return false; } curl_easy_setopt(curl, CURLOPT_URL, mi->file.Url.c_str()); curl_easy_setopt(curl, CURLOPT_FILE, fp); curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1); curl_easy_setopt(curl, CURLOPT_TIMEOUT, URL_TIMEOUT); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, (long)1); curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, cYTCache::curlProgress); curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, this); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, (long)0); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); char cerror[CURL_ERROR_SIZE]; curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, cerror); if(!g_settings.softupdate_proxyserver.empty()) { curl_easy_setopt(curl, CURLOPT_PROXY, g_settings.softupdate_proxyserver.c_str()); if(!g_settings.softupdate_proxyusername.empty()) { std::string tmp = g_settings.softupdate_proxyusername + ":" + g_settings.softupdate_proxypassword; curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, tmp.c_str()); } } dltotal = 0; dlnow = 0; dlstart = time(NULL); fprintf (stderr, "downloading %s to %s\n", mi->file.Url.c_str(), file.c_str()); CURLcode res = curl_easy_perform(curl); curl_easy_cleanup(curl); fclose(fp); if (res) { fprintf (stderr, "downloading %s to %s failed: %s\n", mi->file.Url.c_str(), file.c_str(), cerror); unlink(file.c_str()); return false; } CMovieInfo cMovieInfo; CFile File; File.Name = xml; cMovieInfo.saveMovieInfo(*mi, &File); std::string thumbnail_dst = getName(mi, "jpg"); CFileHelpers fh; fh.copyFile(mi->tfile.c_str(), thumbnail_dst.c_str(), 0644); return true; }
bool COPKGManager::checkSize(const string& pkg_name) { string pkg_file = pkg_name; string plain_pkg = getBaseName(pkg_file); //exit check size if package already installed, because of auto remove of old stuff during installation if (isInstalled(plain_pkg)) return true; /* this is pretty broken right now for several reasons: * space in /tmp is limited (/tmp being ramfs usually, but wasted by unpacking the archive and then untaring it instead of using a pipe * the file is downloaded for this test, then discarded and later downloaded again for installation so until a better solution is found, simply disable it. */ #if 0 //get available root fs size //TODO: Check writability! struct statfs root_fs; statfs("/", &root_fs); u_int64_t free_size = root_fs.f_bfree*root_fs.f_bsize; /* * To calculate the required size for installation here we make a quasi-dry run, * it is a bit awkward, but relatively specific, other solutions are welcome. * We create a temporary test directory and fill it with downloaded or user uploaded package file. * Then we unpack the package and change into temporary testing directory. * The required size results from the size of generated folders and subfolders. * TODO: size of dependencies are not really considered */ CFileHelpers fh; //create test pkg dir string tmp_dest = OPKG_TEST_DIR; tmp_dest += "/package"; fh.createDir(tmp_dest); //change into test dir chdir(OPKG_TEST_DIR); //copy package into test dir string tmp_dest_file = OPKG_TEST_DIR; tmp_dest_file += "/" + plain_pkg; if(!access( pkg_file.c_str(), F_OK)) //use local package fh.copyFile(pkg_file.c_str(), tmp_dest_file.c_str(), 0644); else execCmd(pkg_types[OM_DOWNLOAD] + plain_pkg); //download package //unpack package into test dir string ar = "ar -x " + plain_pkg + char(0x2a); execCmd(ar); //untar package into test directory string untar_tar_cmd = "tar -xf "; untar_tar_cmd += OPKG_TEST_DIR; untar_tar_cmd += "/data.tar.gz -C " + tmp_dest; execCmd(untar_tar_cmd); //get new current required minimal size from dry run test dir u_int64_t req_size = fh.getDirSize(tmp_dest); //clean up fh.removeDir(OPKG_TEST_DIR); dprintf(DEBUG_INFO, "[COPKGManager] [%s - %d] Package: %s [required size=%" PRId64 " (free size: %" PRId64 ")]\n", __func__, __LINE__, pkg_name.c_str(), req_size, free_size); if (free_size < req_size){ //exit if required size too much dprintf(DEBUG_NORMAL, "[COPKGManager] [%s - %d] WARNING: size check freesize=%" PRId64 " (recommended: %" PRId64 ")\n", __func__, __LINE__, free_size, req_size); return false; } #endif return true; }
bool CFlashTool::program( const std::string & filename, int globalProgressEndErase, int globalProgressEndFlash ) { int fd1; ssize_t filesize; int globalProgressBegin = 0; if(g_settings.epg_save) CNeutrinoApp::getInstance()->saveEpg(true); if(statusViewer) statusViewer->showLocalStatus(0); if (mtdDevice.empty()) { ErrorMessage = "mtd-device not set"; return false; } char buf1[1024]; memset(buf1, 0, sizeof(buf1)); strncpy(buf1, filename.c_str(), sizeof(buf1)-1); char* dn = dirname(buf1); std::string flashfile; bool skipCopy = false; #ifdef BOXMODEL_APOLLO if (strcmp(dn, "/tmp") != 0) { uint64_t btotal = 0, bused = 0; long bsize = 0; if (get_fs_usage("/tmp", btotal, bused, &bsize)) { uint64_t fileSize = (uint64_t)file_size(filename.c_str()) / 1024ULL; uint64_t backupMaxSize = (int)((btotal - bused) * bsize); uint64_t res = 10; // Reserved 10% of available space backupMaxSize = (backupMaxSize - ((backupMaxSize * res) / 100ULL)) / 1024ULL; if (backupMaxSize < fileSize) skipCopy = true; } else skipCopy = true; } #endif if ((strcmp(dn, "/tmp") != 0) && !skipCopy) { memset(buf1, 0, sizeof(buf1)); strncpy(buf1, filename.c_str(), sizeof(buf1)-1); flashfile = (std::string)"/tmp/" + basename(buf1); CFileHelpers fh; printf("##### [CFlashTool::program] copy flashfile to %s\n", flashfile.c_str()); if(statusViewer) statusViewer->showStatusMessageUTF(g_Locale->getText(LOCALE_FLASHUPDATE_COPY_IMAGE)); fh.copyFile(filename.c_str(), flashfile.c_str(), 0644); sync(); if(statusViewer) statusViewer->showGlobalStatus(statusViewer->getGlobalStatus()+5); } else flashfile = filename; // Unmount all NFS & CIFS volumes if (!skipCopy) { nfs_mounted_once = false; CFSMounter::umount(); } if( (fd1 = open( flashfile.c_str(), O_RDONLY )) < 0 ) { ErrorMessage = g_Locale->getText(LOCALE_FLASHUPDATE_CANTOPENFILE); return false; } filesize = (ssize_t)lseek( fd1, 0, SEEK_END); lseek( fd1, 0, SEEK_SET); if(filesize==0) { ErrorMessage = g_Locale->getText(LOCALE_FLASHUPDATE_FILEIS0BYTES); close(fd1); return false; } if(statusViewer) { statusViewer->showLocalStatus(0); statusViewer->showStatusMessageUTF(g_Locale->getText(LOCALE_FLASHUPDATE_ERASING)); // UTF-8 } if(!erase(globalProgressEndErase)) { close(fd1); return false; } if(statusViewer) { if(globalProgressEndErase!=-1) statusViewer->showGlobalStatus(globalProgressEndErase); statusViewer->showLocalStatus(0); statusViewer->showStatusMessageUTF(g_Locale->getText(LOCALE_FLASHUPDATE_PROGRAMMINGFLASH)); // UTF-8 } #ifndef VFD_UPDATE CVFD::getInstance()->ShowText("Write Flash"); #endif if( (fd = open( mtdDevice.c_str(), O_WRONLY )) < 0 ) { ErrorMessage = g_Locale->getText(LOCALE_FLASHUPDATE_CANTOPENMTD); close(fd1); return false; } if(statusViewer) globalProgressBegin = statusViewer->getGlobalStatus(); unsigned char buf[meminfo.writesize]; unsigned mtdoffset = 0; unsigned fsize = filesize; printf("CFlashTool::program: file %s write size %d, erase size %d\n", flashfile.c_str(), meminfo.writesize, meminfo.erasesize); while(fsize > 0) { unsigned block = meminfo.writesize; if (block > fsize) block = fsize; unsigned res = read(fd1, buf, block); if (res != block) { printf("CFlashTool::program: read from %s failed: %d from %d\n", flashfile.c_str(), res, block); } if (isnand) { if (block < (unsigned) meminfo.writesize) { printf("CFlashTool::program: padding at %x\n", mtdoffset); memset(buf + res, 0, meminfo.writesize - res); } unsigned blockstart = mtdoffset & ~(meminfo.erasesize - 1); if (blockstart == mtdoffset) { while (mtdoffset < meminfo.size) { printf("CFlashTool::program: write block at %x\n", mtdoffset); loff_t offset = mtdoffset; int ret = ioctl(fd, MEMGETBADBLOCK, &offset); if (ret == 0) break; printf("CFlashTool::program: bad block at %x, skipping..\n", mtdoffset); mtdoffset += meminfo.erasesize; lseek(fd, mtdoffset, SEEK_SET); continue; } if (mtdoffset >= meminfo.size) { printf("CFlashTool::program: not enough space to write, left: %d\n", fsize); break; } } } write(fd, buf, meminfo.writesize); fsize -= block; mtdoffset += meminfo.writesize; int prog = int(100-(100./filesize*fsize)); if(statusViewer) { statusViewer->showLocalStatus(prog); if(globalProgressEndFlash!=-1) { int globalProg = globalProgressBegin + int((globalProgressEndFlash-globalProgressBegin) * prog/100. ); statusViewer->showGlobalStatus(globalProg); } } printf( "Writing %u Kbyte @ 0x%08X -- %2u %% complete.\n", block/1024, mtdoffset, prog); } if(statusViewer) statusViewer->showLocalStatus(100); close(fd1); close(fd); // FIXME error message if (fsize) return false; CVFD::getInstance()->ShowText("Flash OK."); return true; }