/** Process commandline-arguments */ static int process_command_args(const commandline_options& cmdline_opts) { // Options that don't change behavior based on any others should be checked alphabetically below. if(cmdline_opts.userconfig_dir) { filesystem::set_user_config_dir(*cmdline_opts.userconfig_dir); } if(cmdline_opts.userconfig_path) { std::cout << filesystem::get_user_config_dir() << '\n'; return 0; } if(cmdline_opts.userdata_dir) { filesystem::set_user_data_dir(*cmdline_opts.userdata_dir); } if(cmdline_opts.userdata_path) { std::cout << filesystem::get_user_data_dir() << '\n'; return 0; } if(cmdline_opts.data_dir) { const std::string datadir = *cmdline_opts.data_dir; std::cerr << "Overriding data directory with " << datadir << std::endl; #ifdef _WIN32 // use c_str to ensure that index 1 points to valid element since c_str() returns null-terminated string if(datadir.c_str()[1] == ':') { #else if(datadir[0] == '/') { #endif game_config::path = datadir; } else { game_config::path = filesystem::get_cwd() + '/' + datadir; } if(!filesystem::is_directory(game_config::path)) { std::cerr << "Could not find directory '" << game_config::path << "'\n"; throw config::error("directory not found"); } // don't update font as we already updating it in game ctor //font_manager_.update_font_path(); } if(cmdline_opts.data_path) { std::cout << game_config::path << '\n'; return 0; } if(cmdline_opts.debug_lua) { game_config::debug_lua = true; } if(cmdline_opts.gunzip) { const std::string input_file(*cmdline_opts.gunzip); if(!filesystem::is_gzip_file(input_file)) { std::cerr << "file '" << input_file << "'isn't a .gz file\n"; return 2; } const std::string output_file( input_file, 0, input_file.length() - 3); gzip_decode(input_file, output_file); } if(cmdline_opts.bunzip2) { const std::string input_file(*cmdline_opts.bunzip2); if(!filesystem::is_bzip2_file(input_file)) { std::cerr << "file '" << input_file << "'isn't a .bz2 file\n"; return 2; } const std::string output_file( input_file, 0, input_file.length() - 4); bzip2_decode(input_file, output_file); } if(cmdline_opts.gzip) { const std::string input_file(*cmdline_opts.gzip); const std::string output_file(*cmdline_opts.gzip + ".gz"); gzip_encode(input_file, output_file); } if(cmdline_opts.bzip2) { const std::string input_file(*cmdline_opts.bzip2); const std::string output_file(*cmdline_opts.bzip2 + ".bz2"); bzip2_encode(input_file, output_file); } if(cmdline_opts.help) { std::cout << cmdline_opts; return 0; } if(cmdline_opts.log) { for(std::vector<boost::tuple<int, std::string> >::const_iterator it=cmdline_opts.log->begin(); it!=cmdline_opts.log->end(); ++it) { const std::string log_domain = it->get<1>(); const int severity = it->get<0>(); if (!lg::set_log_domain_severity(log_domain, severity)) { std::cerr << "unknown log domain: " << log_domain << '\n'; return 2; } } } if(cmdline_opts.logdomains) { std::cout << lg::list_logdomains(*cmdline_opts.logdomains); return 0; } if(cmdline_opts.path) { std::cout << game_config::path << "\n"; return 0; } if(cmdline_opts.log_precise_timestamps) { lg::precise_timestamps(true); } if(cmdline_opts.rng_seed) { srand(*cmdline_opts.rng_seed); } if(cmdline_opts.screenshot || cmdline_opts.render_image) { SDL_setenv("SDL_VIDEODRIVER", "dummy", 1); } if(cmdline_opts.strict_validation) { strict_validation_enabled = true; } if(cmdline_opts.version) { std::cout << "Battle for Wesnoth" << " " << game_config::version << "\n\n"; std::cout << "Library versions:\n" << game_config::library_versions_report() << '\n'; std::cout << "Optional features:\n" << game_config::optional_features_report(); return 0; } // Options changing their behavior dependent on some others should be checked below. if ( cmdline_opts.preprocess ) { handle_preprocess_command(cmdline_opts); return 0; } // Not the most intuitive solution, but I wanted to leave current semantics for now return -1; } /** * I would prefer to setup locale first so that early error * messages can get localized, but we need the game_launcher * initialized to have filesystem::get_intl_dir() to work. Note: setlocale() * does not take GUI language setting into account. */ static void init_locale() { #if defined _WIN32 || defined __APPLE__ setlocale(LC_ALL, "English"); #else std::setlocale(LC_ALL, "C"); translation::init(); #endif const std::string& intl_dir = filesystem::get_intl_dir(); translation::bind_textdomain(PACKAGE, intl_dir.c_str(), "UTF-8"); translation::bind_textdomain(PACKAGE "-lib", intl_dir.c_str(), "UTF-8"); translation::set_default_textdomain(PACKAGE); }
NETLIBHTTPREQUEST* NetlibHttpRecv(NetlibConnection *nlc, DWORD hflags, DWORD dflags, bool isConnect) { int dataLen = -1, i, chunkhdr = 0; bool chunked = false; int cenc = 0, cenctype = 0, close = 0; next: NETLIBHTTPREQUEST *nlhrReply = (NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)nlc, hflags); if (nlhrReply == NULL) return NULL; if (nlhrReply->resultCode == 100) { NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); goto next; } for (i = 0; i < nlhrReply->headersCount; i++) { NETLIBHTTPHEADER &p = nlhrReply->headers[i]; if (!mir_strcmpi(p.szName, "Content-Length")) dataLen = atoi(p.szValue); if (!mir_strcmpi(p.szName, "Content-Encoding")) { cenc = i; if (strstr(p.szValue, "gzip")) cenctype = 1; else if (strstr(p.szValue, "deflate")) cenctype = 2; } if (!mir_strcmpi(p.szName, "Connection")) close = !mir_strcmpi(p.szValue, "close"); if (!mir_strcmpi(p.szName, "Transfer-Encoding") && !mir_strcmpi(p.szValue, "chunked")) { chunked = true; chunkhdr = i; dataLen = -1; } } if (nlhrReply->resultCode >= 200 && (dataLen > 0 || (!isConnect && dataLen < 0))) { int recvResult, chunksz = -1; int dataBufferAlloced; if (chunked) { chunksz = NetlibHttpRecvChunkHeader(nlc, true, dflags); if (chunksz == SOCKET_ERROR) { NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); return NULL; } dataLen = chunksz; } dataBufferAlloced = dataLen < 0 ? 2048 : dataLen + 1; nlhrReply->pData = (char*)mir_realloc(nlhrReply->pData, dataBufferAlloced); while (chunksz != 0) { while (true) { recvResult = RecvWithTimeoutTime(nlc, GetTickCount() + HTTPRECVDATATIMEOUT, nlhrReply->pData + nlhrReply->dataLength, dataBufferAlloced - nlhrReply->dataLength - 1, dflags | (cenctype ? MSG_NODUMP : 0)); if (recvResult == 0) break; if (recvResult == SOCKET_ERROR) { NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); return NULL; } nlhrReply->dataLength += recvResult; if (dataLen >= 0) { if (nlhrReply->dataLength >= dataLen) break; } else if ((dataBufferAlloced - nlhrReply->dataLength) < 256) { dataBufferAlloced += 2048; nlhrReply->pData = (char*)mir_realloc(nlhrReply->pData, dataBufferAlloced); if (nlhrReply->pData == NULL) { SetLastError(ERROR_OUTOFMEMORY); NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); return NULL; } } Sleep(10); } if (!chunked) break; chunksz = NetlibHttpRecvChunkHeader(nlc, false, dflags); if (chunksz == SOCKET_ERROR) { NetlibHttpFreeRequestStruct(0, (LPARAM)nlhrReply); return NULL; } dataLen += chunksz; dataBufferAlloced += chunksz; nlhrReply->pData = (char*)mir_realloc(nlhrReply->pData, dataBufferAlloced); } nlhrReply->pData[nlhrReply->dataLength] = '\0'; } if (chunked) { nlhrReply->headers[chunkhdr].szName = (char*)mir_realloc(nlhrReply->headers[chunkhdr].szName, 16); mir_strcpy(nlhrReply->headers[chunkhdr].szName, "Content-Length"); nlhrReply->headers[chunkhdr].szValue = (char*)mir_realloc(nlhrReply->headers[chunkhdr].szValue, 16); mir_snprintf(nlhrReply->headers[chunkhdr].szValue, 16, "%u", nlhrReply->dataLength); } if (cenctype) { int bufsz = nlhrReply->dataLength; char* szData = NULL; switch (cenctype) { case 1: szData = gzip_decode(nlhrReply->pData, &bufsz, 0x10 | MAX_WBITS); break; case 2: szData = gzip_decode(nlhrReply->pData, &bufsz, -MAX_WBITS); if (bufsz < 0) { bufsz = nlhrReply->dataLength; szData = gzip_decode(nlhrReply->pData, &bufsz, MAX_WBITS); } break; } if (bufsz > 0) { NetlibDumpData(nlc, (PBYTE)szData, bufsz, 0, dflags); mir_free(nlhrReply->pData); nlhrReply->pData = szData; nlhrReply->dataLength = bufsz; mir_free(nlhrReply->headers[cenc].szName); mir_free(nlhrReply->headers[cenc].szValue); memmove(&nlhrReply->headers[cenc], &nlhrReply->headers[cenc+1], (--nlhrReply->headersCount-cenc)*sizeof(nlhrReply->headers[0])); } else if (bufsz == 0) { mir_free(nlhrReply->pData); nlhrReply->pData = NULL; nlhrReply->dataLength = 0; } } if (close && (nlc->proxyType != PROXYTYPE_HTTP || nlc->nloc.flags & NLOCF_SSL) && (!isConnect || nlhrReply->resultCode != 200)) NetlibDoClose(nlc); return nlhrReply; }