static int custom_update_thread(void* thread_data) { SDL_Event event; UpdateThreaData_t* data; Uint32 result; result = 0; data = (UpdateThreaData_t*)thread_data; init_thread_log("custom_update"); while (1) { CHECK_AND_LOCK_MUTEX(data->mutex); data->error = result; while (data->running == 1) { SDL_CondWait(data->condition, data->mutex); } if (data->running == 0) { CHECK_AND_UNLOCK_MUTEX(data->mutex); return 1; } data->error = 0; safe_snprintf(data->str, sizeof(data->str), "%s custom updates: %s", data->name, "started"); CHECK_AND_UNLOCK_MUTEX(data->mutex); result = custom_update_threaded(data->dir, data->zip, data); CHECK_AND_LOCK_MUTEX(data->mutex); if (data->running == 2) { data->running = 1; } LOG_INFO("%s", data->str); CHECK_AND_UNLOCK_MUTEX(data->mutex); // signal we are done event.type = SDL_USEREVENT; event.user.code = EVENT_CUSTOM_UPDATE_COMPLETE; event.user.data1 = 0; SDL_PushEvent(&event); } return 0; }
static int only_call_from_open_web_link__go_to_url(void * url) { char browser_command[400]; init_thread_log("web_link"); // build the command line and execute it safe_snprintf (browser_command, sizeof (browser_command), "%s \"%s\"", browser_name, url), system(browser_command); // Do not use this command on UNIX. // free the memory allocated in open_web_link() free(url); return 0; }
// the actual background downloader int http_get_file_thread_handler(void *specs){ struct http_get_struct *spec= (struct http_get_struct *) specs; SDL_Event event; init_thread_log("get_file"); // load the file spec->status= http_get_file(spec->server, spec->path, spec->fp); fclose(spec->fp); spec->fp= NULL; // check to see if the file is correct if (spec->md5 && *spec->md5) { // get the MD5 for the file if (file_temp_check(download_temp_file, spec->md5) != 0) { LOG_ERROR("Download of %s does not match the MD5 sum in the update file!", spec->path); spec->status= 404; // remove the temp-file file_remove_config(download_temp_file); // and make sure we can't restart allow_restart= 0; restart_required= 0; } } LOG_DEBUG("Finished downloading %s\n", spec->path); // signal we are done event.type= SDL_USEREVENT; event.user.code= spec->event; event.user.data1= spec; SDL_Delay(500); // FIXME: This should _not_ be necessary, but appears to be so recently under Windows SDL_PushEvent(&event); // NOTE: it is up to the EVENT handler to close the handle & free the spec pointer in data1 return(0); }
static int download_files_thread(void* _data) { char file_name[256]; char comment[64]; download_files_thread_data_t *data = NULL; update_info_t* info = NULL; char* download_buffer = NULL; void* file_buffer = NULL; FILE *file = NULL; Uint64 file_size, size; Uint32 i, len, result, error, count, index, running; Uint32 download_buffer_size; data = (download_files_thread_data_t*)_data; init_thread_log("download_files"); #ifdef WINDOWS file = my_tmpfile(); #else file = tmpfile(); #endif if (file == 0) { return 1; } error = 0; file_buffer = 0; download_buffer_size = 4096; download_buffer = calloc(download_buffer_size, sizeof(char)); count = data->count; while (1) { CHECK_AND_LOCK_MUTEX(data->mutex); do { info = queue_pop(data->files); running = data->running; if ((running == 1) && (info == 0)) { SDL_CondWait(data->condition, data->mutex); } } while ((data->running == 1) && (info == 0)); index = data->index; CHECK_AND_UNLOCK_MUTEX(data->mutex); if (info == 0) { break; } if (data->update_progress_function("Downloading files", count, index, data->user_data) != 1) { CHECK_AND_LOCK_MUTEX(data->mutex); data->running = 0; CHECK_AND_UNLOCK_MUTEX(data->mutex); error = 2; break; } for (i = 0; i < 5; i++) { fseek(file, 0, SEEK_SET); result = download_file(info->file_name, file, data->server, data->path, &size, download_buffer_size, download_buffer, 0, 0); if (result != 0) { LOG_ERROR("Download error %d while updating " "file '%s' from server '%s', retrying" " it", result, info->file_name, data->server); error = 3; continue; } if (file_read(file, size, &file_buffer, &file_size) != 0) { LOG_ERROR("Read error while updating file '%s' " "from server '%s', retrying it", info->file_name, data->server); error = 3; continue; } convert_md5_digest_to_comment_string(info->digest, sizeof(comment), comment); len = strlen(info->file_name); safe_snprintf(file_name, sizeof(file_name), "%s", info->file_name); if (has_suffix(file_name, len, ".xz", 3)) { file_name[len - 3] = 0; } CHECK_AND_LOCK_MUTEX(data->mutex); add_to_zip(file_name, file_size, file_buffer, data->dest, comment); data->index++; CHECK_AND_UNLOCK_MUTEX(data->mutex); free(file_buffer); error = 0; break; } if (error != 0) { break; } } free(download_buffer); fclose(file); return error; }
int do_threaded_update(void *ptr) { char buffer[1024]; char *buf; int num_files= 0; gzFile fp= NULL; char filename[1024]; init_thread_log("update"); // open the update file safe_snprintf(filename, sizeof(filename), "%s%s", doing_custom ? get_path_custom() : get_path_updates(), files_lst); fp = my_gzopen(filename, "rb"); if(fp == NULL){ // error, we stop processing now update_busy= 0; return(0); } ENTER_DEBUG_MARK("update"); buf= gzgets(fp, buffer, 1024); while(buf && buf != Z_NULL){ char filename[1024]; char asc_md5[256]; Uint8 md5[16]; // parse the line filename[0]= '\0'; asc_md5[0]= '\0'; sscanf(buffer, "%*[^(](%250[^)])%*[^0-9a-zA-Z]%32s", filename, asc_md5); // check for something to process if(*filename && *asc_md5 && !strstr(filename, "..") && filename[0] != '/' && filename[0] != '\\' && filename[1] != ':'){ // check for one special case if(!strcasecmp(asc_md5, "none")){ // this file is to be removed remove_file_updates(filename, doing_custom); } else { int i; // convert the md5 to binary for(i=0; i<16; i++){ int val; strncpy(buffer, asc_md5+i*2, 2); buffer[2]= '\0'; sscanf(buffer, "%x", &val); md5[i]= val; } if (file_update_check(filename, md5, doing_custom) != 0) { add_to_download(filename, md5); num_files++; } } } // read the next line, if any buf= gzgets(fp, buffer, 1024); } // close the file, clear that we are busy if(fp){ gzclose(fp); } update_busy= 0; LEAVE_DEBUG_MARK("update"); // all done return(0); }