create_engine::create_engine(game_display& disp, saved_game& state) : current_level_type_(), current_level_index_(0), current_era_index_(0), current_mod_index_(0), level_name_filter_(), player_count_filter_(1), scenarios_(), user_maps_(), user_scenarios_(), campaigns_(), sp_campaigns_(), random_maps_(), user_map_names_(), user_scenario_names_(), eras_(), mods_(), state_(state), dependency_manager_(resources::config_manager->game_config(), disp.video()), generator_(NULL) { DBG_MP << "restoring game config\n"; // Restore game config for multiplayer. state_ = saved_game(); state_.classification().campaign_type = game_classification::MULTIPLAYER; resources::config_manager-> load_game_config_for_game(state_.classification()); //TODO the editor dir is already configurable, is the preferences value get_files_in_dir(get_user_data_dir() + "/editor/maps", &user_map_names_, NULL, FILE_NAME_ONLY); get_files_in_dir(get_user_data_dir() + "/editor/scenarios", &user_scenario_names_, NULL, FILE_NAME_ONLY); DBG_MP << "initializing all levels, eras and mods\n"; init_all_levels(); init_extras(ERA); init_extras(MOD); state_.mp_settings().saved_game = false; BOOST_FOREACH (const std::string& str, preferences::modifications()) { if (resources::config_manager-> game_config().find_child("modification", "id", str)) state_.mp_settings().active_mods.push_back(str); } if (current_level_type_ != level::CAMPAIGN && current_level_type_ != level::SP_CAMPAIGN) { dependency_manager_.try_modifications(state_.mp_settings().active_mods, true); } reset_level_filters(); }
static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { (void) offset; (void) fi; if (strcmp(path, "/") != 0) return -ENOENT; filler(buf, ".", NULL, 0); filler(buf, "..", NULL, 0); filler(buf, hello_path + 1, NULL, 0); unsigned long n_files = 0; char ** files = NULL; darfs_dir_listing_flush(); get_files_in_dir("", &files, &n_files); unsigned int i; for (i=0; i<n_files; i++) { filler(buf, files[i], NULL, 0); printf("fuse.c: %s\n", files[i]); } return 0; }
static void archive_dir(const std::string& path, const std::string& dirname, config& cfg, std::pair<std::vector<std::string>, std::vector<std::string> >& ignore_patterns) { cfg["name"] = dirname; const std::string dir = path + '/' + dirname; std::vector<std::string> files, dirs; get_files_in_dir(dir,&files,&dirs); for(std::vector<std::string>::const_iterator i = files.begin(); i != files.end(); ++i) { bool valid = !looks_like_pbl(*i); for(std::vector<std::string>::const_iterator p = ignore_patterns.first.begin(); p != ignore_patterns.first.end(); ++p) { if (utils::wildcard_string_match(*i, *p)) { valid = false; break; } } if (valid) { archive_file(dir,*i,cfg.add_child("file")); } } for(std::vector<std::string>::const_iterator j = dirs.begin(); j != dirs.end(); ++j) { bool valid = true; for(std::vector<std::string>::const_iterator p = ignore_patterns.second.begin(); p != ignore_patterns.second.end(); ++p) { if (utils::wildcard_string_match(*j, *p)) { valid = false; break; } } if (valid) { archive_dir(dir,*j,cfg.add_child("dir"),ignore_patterns); } } }
void tbrowse::update_file_lists(twindow& window) { files_in_current_dir_.clear(); dirs_in_current_dir_.clear(); std::vector<std::string> files, dirs; std::string adjust_current_dir; #ifdef _WIN32 adjust_current_dir = conv_ansi_utf8_2(current_dir_, false); #else adjust_current_dir = current_dir_; #endif get_files_in_dir(adjust_current_dir, &files, &dirs, FILE_NAME_ONLY); // files and dirs of get_files_in_dir returned are unicode16 format for (std::vector<std::string>::const_iterator it = files.begin(); it != files.end(); ++ it) { const std::string& str = *it; #ifdef _WIN32 files_in_current_dir_.insert(tfile(conv_ansi_utf8_2(str, true))); #else files_in_current_dir_.insert(str); #endif } for (std::vector<std::string>::const_iterator it = dirs.begin(); it != dirs.end(); ++ it) { const std::string& str = *it; #ifdef _WIN32 dirs_in_current_dir_.insert(tfile(conv_ansi_utf8_2(str, true))); #else dirs_in_current_dir_.insert(str); #endif } reload_file_table(window, 0); }
std::vector<std::string> available_addons() { std::vector<std::string> res; std::vector<std::string> files, dirs; const std::string parentd = get_addon_campaigns_dir(); get_files_in_dir(parentd,&files,&dirs); for(std::vector<std::string>::const_iterator i = dirs.begin(); i != dirs.end(); ++i) { const std::string external_cfg_file = *i + ".cfg"; const std::string internal_cfg_file = *i + "/_main.cfg"; const std::string external_pbl_file = *i + ".pbl"; const std::string internal_pbl_file = *i + "/_server.pbl"; if((std::find(files.begin(),files.end(),external_cfg_file) != files.end() || file_exists(parentd + "/" + internal_cfg_file)) && (std::find(files.begin(),files.end(),external_pbl_file) != files.end() || (file_exists(parentd + "/" + internal_pbl_file)))) { res.push_back(*i); } } for(std::vector<std::string>::const_iterator i = files.begin(); i != files.end(); ++i) { const size_t length = i->size() - 4; if (i->rfind(".cfg", length) != length) continue; const std::string name = i->substr(0, length); // Continue if there is a dir (which we already processed). if (std::find(dirs.begin(), dirs.end(), name) != dirs.end()) continue; if (std::find(files.begin(), files.end(), name + ".pbl") != files.end()) { res.push_back(name); } } return res; }
void file_menu::update_file_lists() { files_in_current_dir_.clear(); dirs_in_current_dir_.clear(); get_files_in_dir(current_dir_, &files_in_current_dir_, &dirs_in_current_dir_, FILE_NAME_ONLY); display_current_files(); }
void get_unique_filenames_under_dir(const std::string& sdir, std::map<std::string, std::string>* file_map, const std::string& prefix) { if(sdir.size() > 1024) { return; } std::string dir(sdir); if(dir[dir.length()-1] == '/') { dir = dir.substr(0,dir.length()-1); } std::vector<std::string> files; std::vector<std::string> dirs; get_files_in_dir(dir, &files, &dirs); //LOG("get_unique_filenames_under_dir(): " << dir); for(std::vector<std::string>::const_iterator i = files.begin(); i != files.end(); ++i) { (*file_map)[prefix + *i] = dir + "/" + *i; //LOG("unique: " << *i << " : " << (*file_map)[*i]); } for(std::vector<std::string>::const_iterator i = dirs.begin(); i != dirs.end(); ++i) { //LOG("get_unique_filenames_under_dir(): " << (dir + "/" + *i) << " : " << *i); get_unique_filenames_under_dir(dir + "/" + *i, file_map, prefix); } }
std::vector<save_info> manager::get_saves_list(const std::string *dir, const std::string* filter) { // Don't use a reference, it seems to break on arklinux with GCC-4.3. std::string saves_dir = (dir) ? *dir : get_saves_dir(); #ifdef _WIN32 conv_ansi_utf8(saves_dir, false); #endif std::vector<std::string> saves; get_files_in_dir(saves_dir,&saves); std::vector<save_info> res; for(std::vector<std::string>::iterator i = saves.begin(); i != saves.end(); ++i) { if(filter && std::search(i->begin(), i->end(), filter->begin(), filter->end()) == i->end()) { continue; } const time_t modified = file_create_time(saves_dir + "/" + *i); // replace_underbar2space(*i); #ifdef _WIN32 res.push_back(save_info(conv_ansi_utf8_2(*i, true), modified)); #else res.push_back(save_info(*i, modified)); #endif } std::sort(res.begin(),res.end(),save_info_less_time()); return res; }
static void get_file_tree_checksum_internal(const std::string& path, file_tree_checksum& res) { std::vector<std::string> dirs; get_files_in_dir(path,NULL,&dirs, ENTIRE_FILE_PATH, SKIP_MEDIA_DIR, DONT_REORDER, &res); loadscreen::increment_progress(); for(std::vector<std::string>::const_iterator j = dirs.begin(); j != dirs.end(); ++j) { get_file_tree_checksum_internal(*j,res); } }
int dir_size(const std::string& path) { std::vector<std::string> files, dirs; get_files_in_dir(path, &files, &dirs, ENTIRE_FILE_PATH); int res = 0; BOOST_FOREACH(const std::string& file_path, files) { res += file_size(file_path); }
size_t get_files_in_dir_with_ext(const char * name, char ** files[], const char * ext) { char ** localFiles = NULL; size_t amt = get_files_in_dir(name, &localFiles); if(amt == 0) return amt; // create a new list of files matching what we want char ** newFiles = calloc(amt, sizeof(char*)); size_t i = 0, j = 0; for(i = 0; i < amt; i++) { if(strlen(localFiles[i]) <= strlen(ext)) { free(localFiles[i]); continue; } // find last . char * newPtr = strstr(localFiles[i], "."); char * ptr = NULL; // find the last . while(newPtr) { ptr = newPtr; newPtr = strstr(newPtr+1, "."); } if(!ptr) { free(localFiles[i]); continue; } // +1 to skip dot if(strcmp(ptr+1, ext) == 0) { newFiles[j++] = localFiles[i]; } else { free(localFiles[i]); } } free(localFiles); *files = newFiles; return j; }
void manager::deinit() const { #ifdef CAIRO_HAS_FT_FONT FcConfigAppFontClear(FcConfigGetCurrent()); #endif #if CAIRO_HAS_WIN32_FONT foreach(const std::string& path, get_binary_paths("fonts")) { std::vector<std::string> files; get_files_in_dir(path, &files, NULL, ENTIRE_FILE_PATH); foreach(const std::string& file, files) if(file.substr(file.length() - 4) == ".ttf" || file.substr(file.length() - 4) == ".ttc") RemoveFontResource(file.c_str()); } #endif }
std::vector<std::string> installed_addons() { std::vector<std::string> res; const std::string parentd = get_addon_campaigns_dir(); std::vector<std::string> files, dirs; get_files_in_dir(parentd,&files,&dirs); for(std::vector<std::string>::const_iterator i = dirs.begin(); i != dirs.end(); ++i) { const std::string external_cfg_file = *i + ".cfg"; const std::string internal_cfg_file = *i + "/_main.cfg"; if(std::find(files.begin(),files.end(),external_cfg_file) != files.end() || file_exists(parentd + "/" + internal_cfg_file)) { res.push_back(*i); } } return res; }
void manager::init() const { #ifdef CAIRO_HAS_FT_FONT if (!FcConfigAppFontAddDir(FcConfigGetCurrent(), reinterpret_cast<const FcChar8 *>((game_config::path + "/fonts").c_str()))) { ERR_FT << "Could not load the true type fonts\n"; throw error(); } #endif #if CAIRO_HAS_WIN32_FONT foreach(const std::string& path, get_binary_paths("fonts")) { std::vector<std::string> files; get_files_in_dir(path, &files, NULL, ENTIRE_FILE_PATH); foreach(const std::string& file, files) if(file.substr(file.length() - 4) == ".ttf" || file.substr(file.length() - 4) == ".ttc") AddFontResource(file.c_str()); } #endif }
void get_unique_filenames_under_dir(const std::string& dir, std::map<std::string, std::string>* file_map, const std::string& prefix) { if(dir.size() > 1024) { return; } std::vector<std::string> files; std::vector<std::string> dirs; get_files_in_dir(dir, &files, &dirs); for(std::vector<std::string>::const_iterator i = files.begin(); i != files.end(); ++i) { (*file_map)[prefix + *i] = dir + "/" + *i; } for(std::vector<std::string>::const_iterator i = dirs.begin(); i != dirs.end(); ++i) { get_unique_filenames_under_dir(dir + "/" + *i, file_map, prefix); } }
// This deletes a directory with no hidden files and subdirectories. // Also deletes a single file. bool delete_directory(const std::string& path, const bool keep_pbl) { bool ret = true; std::vector<std::string> files; std::vector<std::string> dirs; get_files_in_dir(path, &files, &dirs, ENTIRE_FILE_PATH, keep_pbl ? SKIP_PBL_FILES : NO_FILTER); if(!files.empty()) { for(std::vector<std::string>::const_iterator i = files.begin(); i != files.end(); ++i) { errno = 0; if(remove((*i).c_str()) != 0) { LOG_FS << "remove(" << (*i) << "): " << strerror(errno) << "\n"; ret = false; } } } if(!dirs.empty()) { for(std::vector<std::string>::const_iterator j = dirs.begin(); j != dirs.end(); ++j) { if(!delete_directory(*j)) ret = false; } } errno = 0; #ifdef _WIN32 // remove() doesn't delete directories on windows. int (*remove)(const char*); if(is_directory(path)) remove = rmdir; else remove = ::remove; #endif if(remove(path.c_str()) != 0) { LOG_FS << "remove(" << path << "): " << strerror(errno) << "\n"; ret = false; } return ret; }
void get_files_in_dir(const std::string &directory, std::vector<std::string>* files, std::vector<std::string>* dirs, file_name_option mode, file_filter_option filter, file_reorder_option reorder, file_tree_checksum* checksum) { // If we have a path to find directories in, // then convert relative pathnames to be rooted // on the wesnoth path if(!directory.empty() && directory[0] != '/' && !game_config::path.empty()){ std::string dir = game_config::path + "/" + directory; if(is_directory(dir)) { get_files_in_dir(dir,files,dirs,mode,filter,reorder,checksum); return; } } struct stat st; if (reorder == DO_REORDER) { LOG_FS << "searching for _main.cfg in directory " << directory << '\n'; std::string maincfg; if (directory.empty() || directory[directory.size()-1] == '/') maincfg = directory + maincfg_filename; else maincfg = (directory + "/") + maincfg_filename; if (::stat(maincfg.c_str(), &st) != -1) { LOG_FS << "_main.cfg found : " << maincfg << '\n'; if (files != NULL) { if (mode == ENTIRE_FILE_PATH) files->push_back(maincfg); else files->push_back(maincfg_filename); } return; } } DIR* dir = opendir(directory.c_str()); if(dir == NULL) { return; } struct dirent* entry; while((entry = readdir(dir)) != NULL) { if(entry->d_name[0] == '.') continue; #ifdef __APPLE__ // HFS Mac OS X decomposes filenames using combining unicode characters. // Try to get the precomposed form. char macname[MAXNAMLEN+1]; CFStringRef cstr = CFStringCreateWithCString(NULL, entry->d_name, kCFStringEncodingUTF8); CFMutableStringRef mut_str = CFStringCreateMutableCopy(NULL, 0, cstr); CFStringNormalize(mut_str, kCFStringNormalizationFormC); CFStringGetCString(mut_str, macname,sizeof(macname)-1, kCFStringEncodingUTF8); CFRelease(cstr); CFRelease(mut_str); const std::string basename = macname; #else // generic Unix const std::string basename = entry->d_name; #endif /* !APPLE */ std::string fullname; if (directory.empty() || directory[directory.size()-1] == '/') fullname = directory + basename; else fullname = directory + "/" + basename; if (::stat(fullname.c_str(), &st) != -1) { if (S_ISREG(st.st_mode)) { if(filter == SKIP_PBL_FILES && looks_like_pbl(basename)) { continue; } if (files != NULL) { if (mode == ENTIRE_FILE_PATH) files->push_back(fullname); else files->push_back(basename); } if (checksum != NULL) { if(st.st_mtime > checksum->modified) { checksum->modified = st.st_mtime; } checksum->sum_size += st.st_size; checksum->nfiles++; } } else if (S_ISDIR(st.st_mode)) { if (filter == SKIP_MEDIA_DIR && (basename == "images"|| basename == "sounds")) continue; if (reorder == DO_REORDER && ::stat((fullname+"/"+maincfg_filename).c_str(), &st)!=-1 && S_ISREG(st.st_mode)) { LOG_FS << "_main.cfg found : "; if (files != NULL) { if (mode == ENTIRE_FILE_PATH) { files->push_back(fullname + "/" + maincfg_filename); LOG_FS << fullname << "/" << maincfg_filename << '\n'; } else { files->push_back(basename + "/" + maincfg_filename); LOG_FS << basename << "/" << maincfg_filename << '\n'; } } else { // Show what I consider strange LOG_FS << fullname << "/" << maincfg_filename << " not used now but skip the directory \n"; } } else if (dirs != NULL) { if (mode == ENTIRE_FILE_PATH) dirs->push_back(fullname); else dirs->push_back(basename); } } } } closedir(dir); if(files != NULL) std::sort(files->begin(),files->end()); if (dirs != NULL) std::sort(dirs->begin(),dirs->end()); if (files != NULL && reorder == DO_REORDER) { // move finalcfg_filename, if present, to the end of the vector for (unsigned int i = 0; i < files->size(); i++) { if (ends_with((*files)[i], "/" + finalcfg_filename)) { files->push_back((*files)[i]); files->erase(files->begin()+i); break; } } // move initialcfg_filename, if present, to the beginning of the vector unsigned int foundit = 0; for (unsigned int i = 0; i < files->size(); i++) if (ends_with((*files)[i], "/" + initialcfg_filename)) { foundit = i; break; } // If _initial.cfg needs to be moved (it was found, but not at index 0). if (foundit > 0) { std::string initialcfg = (*files)[foundit]; for (unsigned int i = foundit; i > 0; --i) (*files)[i] = (*files)[i-1]; (*files)[0] = initialcfg; } } }
void game_config_manager::load_addons_cfg() { const std::string user_campaign_dir = get_addon_campaigns_dir(); std::vector<std::string> error_addons; std::vector<std::string> user_dirs; std::vector<std::string> user_files; std::vector<std::string> addons_to_load; get_files_in_dir(user_campaign_dir, &user_files, &user_dirs, ENTIRE_FILE_PATH); std::stringstream user_error_log; // Append the $user_campaign_dir/*.cfg files to addons_to_load. BOOST_FOREACH(const std::string& uc, user_files) { const std::string file = uc; const int size_minus_extension = file.size() - 4; if(file.substr(size_minus_extension, file.size()) == ".cfg") { bool ok = true; // Allowing it if the dir doesn't exist, // for the single-file add-on. if(file_exists(file.substr(0, size_minus_extension))) { // Unfortunately, we create the dir plus // _info.cfg ourselves on download. std::vector<std::string> dirs, files; get_files_in_dir(file.substr(0, size_minus_extension), &files, &dirs); if(dirs.size() > 0) { ok = false; } if(files.size() > 1) { ok = false; } if(files.size() == 1 && files[0] != "_info.cfg") { ok = false; } } if(!ok) { const int userdata_loc = file.find("data/add-ons") + 5; ERR_CONFIG << "error reading usermade add-on '" << file << "'\n"; error_addons.push_back(file); user_error_log << "The format '~" << file.substr(userdata_loc) << "' is only for single-file add-ons, use '~" << file.substr(userdata_loc, size_minus_extension - userdata_loc) << "/_main.cfg' instead.\n"; } else { addons_to_load.push_back(file); } } } // Append the $user_campaign_dir/*/_main.cfg files to addons_to_load. BOOST_FOREACH(const std::string& uc, user_dirs) { const std::string main_cfg = uc + "/_main.cfg"; if(file_exists(main_cfg)) { addons_to_load.push_back(main_cfg); } } // Load the addons. BOOST_FOREACH(const std::string& uc, addons_to_load) { const std::string toplevel = uc; try { config umc_cfg; cache_.get_config(toplevel, umc_cfg); game_config_.append(umc_cfg); } catch(config::error& err) { ERR_CONFIG << "error reading usermade add-on '" << uc << "'\n"; error_addons.push_back(uc); user_error_log << err.message << "\n"; } catch(preproc_config::error& err) { ERR_CONFIG << "error reading usermade add-on '" << uc << "'\n"; error_addons.push_back(uc); user_error_log << err.message << "\n"; } catch(io_exception&) { ERR_CONFIG << "error reading usermade add-on '" << uc << "'\n"; error_addons.push_back(uc); } } if(error_addons.empty() == false) { std::stringstream msg; msg << _n("The following add-on had errors and could not be loaded:", "The following add-ons had errors and could not be loaded:", error_addons.size()); BOOST_FOREACH(const std::string& error_addon, error_addons) { msg << "\n" << error_addon; } msg << '\n' << _("ERROR DETAILS:") << '\n' << user_error_log.str(); gui2::show_error_message(disp_.video(),msg.str()); }
void Verifier::prepare_answers(int beta) { #if NONINTERACTIVE == 1 prepare_noninteractive_answers(beta); #else #if VERBOSE == 1 cout << endl << "LOG: Batch " << beta << endl; #endif FILE *fp = NULL; if (optimize_answers) { char f_name[BUFLEN]; snprintf(f_name, BUFLEN - 1, "answers_%d", beta + 1); snprintf(f_name, BUFLEN - 1, "%s/answers_%d", FOLDER_STATE, beta + 1); fp = fopen(f_name, "rb"); if (fp == NULL) { printf("Failed to open %s file for reading.", f_name); exit(1); } } // only one commitment answer and one consistency answer string commitment_answer_str = "f_commitment_answer_b_%d"; snprintf(scratch_str, BUFLEN - 1, commitment_answer_str.c_str(), beta); load_vector(expansion_factor, temp_arr_ptrs[0], scratch_str); if (!optimize_answers) { string consistency_answer_str = "f_consistency_answer_b_%d"; snprintf(scratch_str, BUFLEN - 1, consistency_answer_str.c_str(), beta); load_scalar(a, scratch_str); } else { size_t bytes = mpz_inp_raw(a, fp); fseek(fp, bytes, SEEK_CUR); } for (uint32_t j=0; j<num_repetitions*num_lin_pcp_queries; j++) mpz_set_ui(f_answers[j], 0); std::list<string> files = get_files_in_dir((char *)FOLDER_STATE); for (int rho = 0; rho < num_repetitions; rho++) { if (!optimize_answers) { char *file_exp = (char *)"_qquery_answer_b_%d_r_%d"; snprintf(scratch_str, BUFLEN-1, file_exp, beta, rho); std::list<string>::const_iterator it = files.begin(); for (; it != files.end(); it++) { string file_name = *it; size_t b_index = file_name.find(scratch_str); if (b_index != string::npos) { int q_num = atoi(file_name.substr(file_name.find("q") + 1, b_index).c_str()); load_scalar(f_answers[rho * num_lin_pcp_queries + Q_list[q_num - 1]], (char*)file_name.c_str()); } } } else { for (uint32_t q = 0; q < Q_list.size(); q++) { size_t bytes = mpz_inp_raw(f_answers[rho * num_lin_pcp_queries + Q_list[q]], fp); fseek(fp, bytes, SEEK_CUR); } } //populate_answers(f_answers, rho, num_repetitions, beta); } snprintf(scratch_str, BUFLEN-1, "input_b_%d", beta); load_vector(size_input, input, scratch_str); snprintf(scratch_str, BUFLEN-1, "output_b_%d", beta); load_vector(size_output, output, scratch_str); if (output_q != NULL) { snprintf(scratch_str, BUFLEN-1, "output_q_b_%d", beta); load_vector(size_output, output_q, scratch_str); if (verify_conversion_to_z(size_output, output, output_q, prime) == false) { cout<<"LOG: Prover presented two different versions of output"<<endl; exit(1); } } if (fp != NULL) fclose(fp); #endif }
// Function which runs in a background thread to upload logs to server. // Uses http POST to port 80 for maximum firewall penetration & other-end // compatibility. static int upload_logs(void *_ti) { DBG_UPLD << "attempting to upload game logs\n"; TCPsocket sock = NULL; upload_log::thread_info *ti = static_cast<upload_log::thread_info*>(_ti); int numfiles = 0; const std::string header = "POST " + TARGET_URL + " HTTP/1.1\n" "Host: " + TARGET_HOST + "\n" "User-Agent: Wesnoth " VERSION "\n" "Content-Type: text/plain\n"; try { std::vector<std::string> files; // These are sorted: send them one at a time until we get to lastfile. get_files_in_dir(get_upload_dir(), &files, NULL, ENTIRE_FILE_PATH); IPaddress ip; network::manager ensure_net_initialized; if (SDLNet_ResolveHost(&ip, TARGET_HOST.c_str(), TARGET_PORT) == 0) { std::vector<std::string>::iterator i; for (i = files.begin(); i!=files.end() && *i!=ti->lastfile; i++) { std::string contents; char response[10]; //This needs to be strlen("HTTP/1.1 2"); contents = read_file(*i); sock = SDLNet_TCP_Open(&ip); if (!sock) { ERR_UPLD << "error connecting to log server\n"; break; } else { DBG_UPLD << "successfully connected to log server\n"; } send_string(sock, header.c_str()); send_string(sock, "Content-length: "); send_string(sock, lexical_cast<std::string>(contents.length())); send_string(sock, "\n\n"); send_string(sock, contents); // As long as we can actually send the data, delete the file. // Even if the server gives a bad response, we don't want to // be sending the same bad data over and over to the server. delete_directory(*i); numfiles++; if (SDLNet_TCP_Recv(sock, response, sizeof(response)) != sizeof(response)) break; // Must be version 1.x, must start with 2 (eg. 200) for success if (memcmp(response, "HTTP/1.", strlen("HTTP/1.")) != 0) break; if (memcmp(response+8, " 2", strlen(" 2")) != 0) break; SDLNet_TCP_Close(sock); sock = NULL; } } } catch(...) { } if (sock) SDLNet_TCP_Close(sock); ti->shutdown = true; DBG_UPLD << numfiles << " game logs successfully sent to server\n"; return 0; }