void GMSyncTask::update() { GMTrackFilenameList tracklist; FXStringList pathlist; FXStat data; database->beginTask(); taskmanager->setStatus("Updating Files.."); for (FXint i=0;i<files.no() && processing;i++) { database->getPathList(files[i],pathlist); for (FXint p=0;p<pathlist.no() && processing;p++) { const FXString & path = pathlist[p]; if (!options.exclude_folder.empty() && filter_path(options.exclude_folder,path)) continue; const FXint path_index = dbtracks.hasPath(path); database->getFileList(path,tracklist); for (FXint t=0;t<tracklist.no() && processing;t++) { const FXString & name = tracklist[t].filename; if (options.exclude_file.empty() || !FXPath::match(name,options.exclude_file,matchflags)) { if (FXStat::statFile(path+PATHSEPSTRING+name,data)) { if (data.isReadable()) parse_update(path,name,options_sync.update_always ? forever : data.modified(),path_index); else parse_update(path,name,0,path_index); } else if (options_sync.remove_missing) { dbtracks.remove(tracklist[t].id); changed=true; } } } if (processing) update_tracks(path_index); } } if (changed) { database->sync_album_year(); database->sync_tracks_removed(); } database->commitTask(); }
/** * @brief Parse a dump file and pass info to a module * @param dmp The dump file * @return ID of last update */ unsigned int Parser::parse_dump(std::string dmp) { // Feed JSON parser with dump JSON j(dmp); std::string current = ""; unsigned int update = 0; // Parse, till information runs out while (!j.empty()) { // Check for an update if (current == "update_id") update = parse_update(j, current); else current = j.next_rec(); } return update; }
void GMSyncTask::traverse(const FXString & path,Seen * seen,FXlong index) { FXDir directory; FXStat data; FXString name; // Location Seen here={seen,index}; // First scan subfolders if (directory.open(path)) { while(directory.next(name) && processing) { if (FXStat::statLink(path+PATHSEPSTRING+name,data)) { if (data.isDirectory()) { if(!(name[0]=='.' && (name[1]==0 || (name[1]=='.' && name[2]==0)))){ for(Seen *s=seen; s; s=s->next){ if(data.index()==s->node) goto next_dir; } if (options.exclude_folder.empty() || !FXPath::match(name,options.exclude_folder,matchflags)) traverse(path+PATHSEPSTRING+name,&here,data.index()); } } } next_dir:; } directory.close(); } // Scan files in current folder if(directory.open(path) && processing) { FXint path_index = dbtracks.hasPath(path); while(directory.next(name) && processing) { if (FXStat::statFile(path+PATHSEPSTRING+name,data)) { if (!data.isDirectory() && data.isReadable()) { if (options.exclude_file.empty() || !FXPath::match(name,options.exclude_file,matchflags)) { if (FXPath::match(name,FILE_PATTERNS,matchflags)) { parse_update(path,name,options_sync.update_always ? forever : data.modified(),path_index); } } } } } if (processing) update_tracks(path_index); } }
void SetUpdater::update(deque<Record>::iterator record) { record_ = record; tokens_ = set_; return parse_update(); }
/* * Background thread to check for updates */ static DWORD WINAPI CheckForUpdatesThread(LPVOID param) { BOOL releases_only, found_new_version = FALSE; int status = 0; const char* server_url = RUFUS_URL "/"; int i, j, k, verbose = 0, verpos[4]; static const char* archname[] = {"win_x86", "win_x64"}; static const char* channel[] = {"release", "beta"}; // release channel const char* accept_types[] = {"*/*\0", NULL}; DWORD dwFlags, dwSize, dwDownloaded, dwTotalSize, dwStatus; char* buf = NULL; char agent[64], hostname[64], urlpath[128], mime[32]; OSVERSIONINFOA os_version = {sizeof(OSVERSIONINFOA), 0, 0, 0, 0, ""}; HINTERNET hSession = NULL, hConnection = NULL, hRequest = NULL; URL_COMPONENTSA UrlParts = {sizeof(URL_COMPONENTSA), NULL, 1, (INTERNET_SCHEME)0, hostname, sizeof(hostname), 0, NULL, 1, urlpath, sizeof(urlpath), NULL, 1}; SYSTEMTIME ServerTime, LocalTime; FILETIME FileTime; int64_t local_time = 0, reg_time, server_time, update_interval; update_check_in_progress = TRUE; verbose = ReadRegistryKey32(REGKEY_HKCU, REGKEY_VERBOSE_UPDATES); // Without this the FileDialog will produce error 0x8001010E when compiled for Vista or later IGNORE_RETVAL(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)); // Unless the update was forced, wait a while before performing the update check if (!force_update_check) { // It would of course be a lot nicer to use a timer and wake the thread, but my // development time is limited and this is FASTER to implement. do { for (i=0; (i<30) && (!force_update_check); i++) Sleep(500); } while ((!force_update_check) && ((iso_op_in_progress || format_op_in_progress || (dialog_showing>0)))); if (!force_update_check) { if ((ReadRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL) == -1)) { vuprintf("Check for updates disabled, as per registry settings.\n"); goto out; } reg_time = ReadRegistryKey64(REGKEY_HKCU, REGKEY_LAST_UPDATE); update_interval = (int64_t)ReadRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL); if (update_interval == 0) { WriteRegistryKey32(REGKEY_HKCU, REGKEY_UPDATE_INTERVAL, DEFAULT_UPDATE_INTERVAL); update_interval = DEFAULT_UPDATE_INTERVAL; } GetSystemTime(&LocalTime); if (!SystemTimeToFileTime(&LocalTime, &FileTime)) goto out; local_time = ((((int64_t)FileTime.dwHighDateTime)<<32) + FileTime.dwLowDateTime) / 10000000; vvuprintf("Local time: %" PRId64 "\n", local_time); if (local_time < reg_time + update_interval) { vuprintf("Next update check in %" PRId64 " seconds.\n", reg_time + update_interval - local_time); goto out; } } } PrintStatus(3000, TRUE, MSG_243); status++; // 1 if (!GetVersionExA(&os_version)) { uprintf("Could not read Windows version - Check for updates cancelled.\n"); goto out; } if ((!InternetCrackUrlA(server_url, (DWORD)safe_strlen(server_url), 0, &UrlParts)) || (!InternetGetConnectedState(&dwFlags, 0))) goto out; hostname[sizeof(hostname)-1] = 0; safe_sprintf(agent, ARRAYSIZE(agent), APPLICATION_NAME "/%d.%d.%d.%d", rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[3]); hSession = InternetOpenA(agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (hSession == NULL) goto out; hConnection = InternetConnectA(hSession, UrlParts.lpszHostName, UrlParts.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)NULL); if (hConnection == NULL) goto out; status++; // 2 releases_only = !GetRegistryKeyBool(REGKEY_HKCU, REGKEY_INCLUDE_BETAS); for (k=0; (k<(releases_only?1:(int)ARRAYSIZE(channel))) && (!found_new_version); k++) { uprintf("Checking %s channel...\n", channel[k]); // At this stage we can query the server for various update version files. // We first try to lookup for "<appname>_<os_arch>_<os_version_major>_<os_version_minor>.ver" // and then remove each each of the <os_> components until we find our match. For instance, we may first // look for rufus_win_x64_6.2.ver (Win8 x64) but only get a match for rufus_win_x64_6.ver (Vista x64 or later) // This allows sunsetting OS versions (eg XP) or providing different downloads for different archs/groups. safe_sprintf(urlpath, sizeof(urlpath), "%s%s%s_%s_%d.%d.ver", APPLICATION_NAME, (k==0)?"":"_", (k==0)?"":channel[k], archname[is_x64()?1:0], os_version.dwMajorVersion, os_version.dwMinorVersion); vuprintf("Base update check: %s\n", urlpath); for (i=0, j=(int)safe_strlen(urlpath)-5; (j>0)&&(i<ARRAYSIZE(verpos)); j--) { if ((urlpath[j] == '.') || (urlpath[j] == '_')) { verpos[i++] = j; } } if (i != ARRAYSIZE(verpos)) { uprintf("Broken code in CheckForUpdatesThread()!\n"); goto out; } UrlParts.lpszUrlPath = urlpath; UrlParts.dwUrlPathLength = sizeof(urlpath); for (i=0; i<ARRAYSIZE(verpos); i++) { vvuprintf("Trying %s\n", UrlParts.lpszUrlPath); hRequest = HttpOpenRequestA(hConnection, "GET", UrlParts.lpszUrlPath, NULL, NULL, accept_types, INTERNET_FLAG_HYPERLINK|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS|INTERNET_FLAG_NO_COOKIES| INTERNET_FLAG_NO_UI|INTERNET_FLAG_NO_CACHE_WRITE, (DWORD_PTR)NULL); if ((hRequest == NULL) || (!HttpSendRequestA(hRequest, NULL, 0, NULL, 0))) goto out; // Ensure that we get a text file dwSize = sizeof(dwStatus); dwStatus = 404; HttpQueryInfoA(hRequest, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwStatus, &dwSize, NULL); if (dwStatus == 200) break; InternetCloseHandle(hRequest); hRequest = NULL; safe_strcpy(&urlpath[verpos[i]], 5, ".ver"); } if (dwStatus != 200) { vuprintf("Could not find a %s version file on server %s", channel[k], server_url); if ((releases_only) || (k+1 >= ARRAYSIZE(channel))) goto out; continue; } vuprintf("Found match for %s on server %s", urlpath, server_url); dwSize = sizeof(mime); HttpQueryInfoA(hRequest, HTTP_QUERY_CONTENT_TYPE, (LPVOID)&mime, &dwSize, NULL); if (strcmp(mime, "text/plain") != 0) goto out; // We also get a date from Apache, which we'll use to avoid out of sync check, // in case some set their clock way into the future and back. // On the other hand, if local clock is set way back in the past, we will never check. dwSize = sizeof(ServerTime); // If we can't get a date we can trust, don't bother... if ( (!HttpQueryInfoA(hRequest, HTTP_QUERY_DATE|HTTP_QUERY_FLAG_SYSTEMTIME, (LPVOID)&ServerTime, &dwSize, NULL)) || (!SystemTimeToFileTime(&ServerTime, &FileTime)) ) goto out; server_time = ((((int64_t)FileTime.dwHighDateTime)<<32) + FileTime.dwLowDateTime) / 10000000; vvuprintf("Server time: %" PRId64 "\n", server_time); // Always store the server response time - the only clock we trust! WriteRegistryKey64(REGKEY_HKCU, REGKEY_LAST_UPDATE, server_time); // Might as well let the user know if (!force_update_check) { if ((local_time > server_time + 600) || (local_time < server_time - 600)) { uprintf("IMPORTANT: Your local clock is more than 10 minutes in the %s. Unless you fix this, " APPLICATION_NAME " may not be able to check for updates...", (local_time > server_time + 600)?"future":"past"); } } dwSize = sizeof(dwTotalSize); if (!HttpQueryInfoA(hRequest, HTTP_QUERY_CONTENT_LENGTH|HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwTotalSize, &dwSize, NULL)) goto out; safe_free(buf); // Make sure the file is NUL terminated buf = (char*)calloc(dwTotalSize+1, 1); if (buf == NULL) goto out; // This is a version file - we should be able to gulp it down in one go if (!InternetReadFile(hRequest, buf, dwTotalSize, &dwDownloaded) || (dwDownloaded != dwTotalSize)) goto out; status++; vuprintf("Successfully downloaded version file (%d bytes)\n", dwTotalSize); parse_update(buf, dwTotalSize+1); vuprintf("UPDATE DATA:\n"); vuprintf(" version: %d.%d.%d.%d (%s)\n", update.version[0], update.version[1], update.version[2], update.version[3], channel[k]); vuprintf(" platform_min: %d.%d\n", update.platform_min[0], update.platform_min[1]); vuprintf(" url: %s\n", update.download_url); found_new_version = ((to_uint64_t(update.version) > to_uint64_t(rufus_version)) || (force_update)) && ( (os_version.dwMajorVersion > update.platform_min[0]) || ( (os_version.dwMajorVersion == update.platform_min[0]) && (os_version.dwMinorVersion >= update.platform_min[1])) ); uprintf("N%sew %s version found%c\n", found_new_version?"":"o n", channel[k], found_new_version?'!':'.'); } out: safe_free(buf); if (hRequest) InternetCloseHandle(hRequest); if (hConnection) InternetCloseHandle(hConnection); if (hSession) InternetCloseHandle(hSession); switch(status) { case 1: PrintStatus(3000, TRUE, MSG_244); break; case 2: PrintStatus(3000, TRUE, MSG_245); break; case 3: case 4: PrintStatus(3000, FALSE, found_new_version?MSG_246:MSG_247); default: break; } // Start the new download after cleanup if (found_new_version) { // User may have started an operation while we were checking while ((!force_update_check) && (iso_op_in_progress || format_op_in_progress || (dialog_showing>0))) { Sleep(15000); } DownloadNewVersion(); } force_update_check = FALSE; update_check_in_progress = FALSE; ExitThread(0); }