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;
}
示例#3
0
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;
    }
}