bool Upgrader::unzipper(int targetfile) { bfs::path target = path(DATA) / "upgrade"; if (!verifyPath(target.c_str(), true)) {return false;} const char *targetzip = (target / targetswitch(targetfile)).string().c_str(); struct zip *archive; struct zip_file *zipfile; struct zip_stat filestat; char buffer[1024*1024]; FILE *file; int bufferlength, err; unsigned long long sum; printf("Extracting %s\n", targetzip); if ((archive = zip_open(targetzip, 0, &err)) == NULL) { printf("Failed to open archive %s\n", targetzip); return false; } for (unsigned int i = 0; i < zip_get_num_entries(archive, 0); i++) { if (zip_stat_index(archive, i, 0, &filestat) == 0) { verifyPath((target / filestat.name).parent_path(), true); if (!is_directory(target / filestat.name)) { zipfile = zip_fopen_index(archive, i, 0); if (!zipfile) { printf("Could not open %s in archive\n", filestat.name); continue; } file = fopen((target / filestat.name).string().c_str(), "w"); sum = 0; while (sum != filestat.size) { bufferlength = zip_fread(zipfile, buffer, 1024*1024); fwrite(buffer, sizeof(char), bufferlength, file); sum += bufferlength; } printf("Finished extracting %s\n", filestat.name); fclose(file); zip_fclose(zipfile); } } } if (zip_close(archive) == -1) { printf("Can't close zip archive %s\n", targetzip); return false; } bfs::remove(target / targetswitch(targetfile)); return true; }
bool Upgrader::copyDir(bfs::path source, bfs::path target, bool recursive) { if (!verifyPath(source, false) || !verifyPath(target, true)) {return false;} pathvec iteraton = this->fvector(source); for (pathvec::const_iterator mongo (iteraton.begin()); mongo != iteraton.end(); ++mongo) { bfs::path fongo = *mongo; if (!bfs::exists(source / fongo)) { printf("Error, file/directory does not exist\n"); return false; } if (bfs::is_directory(source / fongo)) { if ((fongo == "upgrade") || (fongo == "backup") || (!recursive)) { continue; } verifyPath(target / fongo, true); copyDir(source / fongo, target / fongo, recursive); } else { if (bfs::exists(target / fongo)) { bfs::remove(target / fongo); } // avoid overwriting bfs::copy_file(source / fongo, target / fongo); // the actual upgrade/recovery } } return true; }
void *displayFolder(void *params) { char *tmp=params; char folder_name[FOLDER_NAME_MAX]; strcpy(folder_name,tmp); if(!verifyPath(folder_name,False)) { return; } char data[strlen(LIST_DIR)+1+strlen(folder_name)]; strcpy(data,LIST_DIR); strcat(data,":"); strcat(data,folder_name); send_packet_to(server_address.sin_addr,user_login,SERVER_ADMIN_NAME,CMD_TYPE,data); }
bool Upgrader::juggler(int pf, bool recovery) // for upgrade, backs up target and copies over upgraded file { // for recovery, copies over backup static std::locale loc(std::cout.getloc(), new bpt::time_facet("%Y-%b-%d %H%M%S")); std::stringstream datestream; datestream.imbue(loc); datestream << bpt::second_clock::local_time(); std::string subdir = (pf == BLOCKS)? "Blockchain " : "Client " + datestream.str(); bfs::path backupdir(path(DATA) / "backup" / subdir); bfs::path sourcedir(path(DATA)); if (recovery) sourcedir = backupdir; else sourcedir /= "upgrade"; if (!verifyPath(sourcedir, true)) {return false;} if ((pf == PROGRAM) && (path(pf) == "")) { return false; } //printf("Copying %s into %s\n", path(pf).c_str(), backupdir.c_str()); if ((pf == PROGRAM) && (safeProgramDir())) { pathvec iteraton = this->fvector(sourcedir); for (pathvec::const_iterator mongo (iteraton.begin()); mongo != iteraton.end(); ++mongo) { bfs::path fongo = *mongo; if (!bfs::exists(sourcedir / fongo) || bfs::is_directory(sourcedir / fongo)) { continue; } if (bfs::exists(path(pf) / fongo) && !recovery) // i.e. backup files before upgrading { if (!verifyPath(backupdir, true)) {return false;} bfs::copy_file(path(pf) / fongo, backupdir / fongo, bfs::copy_option::overwrite_if_exists); } if (bfs::exists(path(pf) / fongo)) // avoid overwriting {bfs::remove(path(pf) / fongo);} bfs::copy_file(sourcedir / fongo, path(pf) / fongo); // the actual upgrade/recovery } } else { copyDir(path(pf), backupdir, true); copyDir(sourcedir, path(pf), true); } if (!recovery) { bfs::remove_all(sourcedir); // include removing directory to avoid having users tempted to store files here } return true; }
bool Upgrader::downloader(int targetfile) { curlhandle.downloading = true; curlhandle.handle = curl_easy_init(); curlhandle.success = false; std::string urlstring = geturl() + targetswitch(targetfile); const char *url = urlstring.c_str(); bfs::path target = path(DATA) / "upgrade"; // if user switches between upgrading client and bootstrapping blockchain, we don't want to pass around garbage if (bfs::exists(target)) {bfs::remove_all(target);} if (!verifyPath(target, true)) {return false;} target /= targetswitch(targetfile); cancelDownload(false); if (bfs::exists(target)) {bfs::remove(target);} file = fopen(target.string().c_str(), "wb"); fileInitialized=true; curl_easy_setopt(curlhandle.handle, CURLOPT_URL, url); curl_easy_setopt(curlhandle.handle, CURLOPT_WRITEFUNCTION, fwrite); curl_easy_setopt(curlhandle.handle, CURLOPT_WRITEDATA, file); curl_easy_setopt(curlhandle.handle, CURLOPT_WRITEDATA, file); //curl_easy_setopt(curlhandle.handle, CURLOPT_XFERINFOFUNCTION, cancelDownloader); curl_easy_setopt(curlhandle.handle, CURLOPT_NOPROGRESS, 0L); downloadThread = boost::thread(download, (void *)&curlhandle); printf("downloading file...\n"); filesize = -1; filesizeRetrieved = false; while (curlhandle.downloading && !CANCEL_DOWNLOAD) { #ifdef WIN32 Sleep(1000); #else usleep(1000*500); #endif #if defined(UPGRADERFLAG) int sz = getFileDone(); printf("\r%i\tKB \t%i%%", sz/1024, getFilePerc(sz)); fflush( stdout ); #endif } curl_easy_cleanup(curlhandle.handle); fclose(file); fileInitialized=false; if(!curlhandle.success) { printf((CANCEL_DOWNLOAD)? "\ndownload interrupted\n" : "\ndownload failed\n"); if (bfs::exists(target)) bfs::remove(target); cancelDownload(false); return false; } else { printf("\nfile downloaded successfully\n"); return true; } }