this check really did more harm than good because:
1) It possible that the directory is removed just after the function was
called but before the returned string was used.
2) It's slow.
Instead of checking the existence here the game now tries to create
directories in ofstream when they don't exist yet. (commit will follow)
This replaces SDL 1.2's built-in stdout/stderr redirection, which writes
the log file to the process working directory (usually an
admin-restricted location) instead of a more accessible user-writable
location.
My approach combines stdout and stderr into a single log file which
includes the process id and timestamp in its filename in order to
accomodate multiple instances and (coming later) log rotation. The log
file is created in the user's temporary directory defined by Windows,
and then relocated to the game user data dir as soon as it is set-up the
first time, placed in the Windows-specific logs/ subdir.
The most pressing issues this solves are the lack of built-in
stdout/stderr redirection in SDL 2's SDL2main.lib entry point, and
Unicode path issues with SDL 1.2 (bug #22897). Additionally, it allows
us to not have to rely on UAC virtualization anymore; this is arguably
far more important because it has been known to break on occasion (e.g.
<http://r.wesnoth.org/t42970>), and starting with version 1.13.2 we want
to declare Windows Vista - 10 compatibility in our side-by-side manifest
(see commit e119f4071f).
Currently missing features coming later:
* Log rotation (otherwise the logs/ dir may grow forever)
* wesnothd support (although the code is already required to be linked
into wesnothd due to it being required by the FS API)
* Integration with the version info dialog
The former has been "unsupported" since Windows XP, while the latter is
still supported in Vista and later as a wrapper around a newer API.
Most importantly, used this as an excuse to rewrite the code to take
advantage of the fact that we already link to SHELL32.DLL at runtime
(it implements ShellExecute() and Shell_NotifyIcon(), used elsewhere in
our code), only run on versions of Windows guarantee to provide the
SHGetFolderPath symbol, and thus don't need all the LoadLibrary mumbo
jumbo that made the code considerably uglier and denser.
This allows asking Wesnoth to store user files in a directory relative
to the install dir if wanted on Windows (e.g. for portable installs to
removable media where the absolute path to the install dir is not
constant or under the user's control).
Use Documents\My Games\WesnothX.Y for user config data on Windows like
we currently do when using --config-dir there with a relative path. The
behavior of --config-dir when passed a relative path remains unchanged
with this commit, making the new out-of-the-box default equivalent to
passing --config-dir WesnothX.Y, except this is now enforced by Wesnoth
rather than a finicky installer option.
See bug #23753 for the rationale behind this change.
People who really can't live without the old CWD\userdata layout should
either use --config-dir with an absolute path to their existing userdata
dir, or wait for the next commit (which will help with "portable"
installs to removable devices, for example).
This function is implemented using case-insensitive pattern matching,
unlike filesystem::ends_with(). I missed this when writing my original
fix, so the vulnerability still applied to .pbl files on a
case-insensitive filesystem (e.g. NTFS and FAT* on Windows) by using
different case to bypass the check.
Some of these don't even exist in the legacy non-BFS implementation, but
it's possible they might prove useful for debugging later.
Fixes some spurious errors printed when browsing directories outside the
user's home dir on Linux/*BSD/etc., as well as a few recently introduced
in the GUI2 test suite by commit
db28dca52c.
that commit changed uintmax_t to be 4 bytes long instead of 8 bytes long in windows which makes us uncapable to read files >4GB.
boost::filesystem::file_size retrun type is boost::uintmax_t so we don't need to include files for this line.
This is essentially a port to the BFS implementation of the fs API of
commits 314425ab0e and
9f458d1bb2, which were authored separately
from the BFS branch.
Note that this introduces another disparity in behavior between the BFS
and legacy implementations of this API, in that the BFS
get_wml_location() function will now always start at <data dir>/data/
instead of starting at <data dir> in obscure border cases. This is
expected to have no impact on anything at all for reasons discussed on
IRC.
The non-BFS implementation already ignored this case without making
noise in stderr, and this function is used by delete_directory(), which
also accepts both regular files and directories. The add-ons management
code has always relied on this behavior.
This is intended to silently fail on Unix-like platforms where no procfs
is available, and indeed that's how it works in the non-BFS
implementation of get_exe_dir(). The caller (currently a single function
in game.cpp/wesnoth.cpp) must be able to deal with this situation
in a graceful fashion.
this fixes a bug which caused that _final.cfg wasn't included last
becasue we compared a string with "/_final.cfg". By using
generic_string() we make sure that the seperators are '/'.
http://gna.org/bugs/?22967
The non-BFS version of create_directory_if_missing_recursive() handles
relative path names (e.g. "foo") correctly and doesn't attempt to create
a parent that is left unspecified in the path (i.e. empty), but the BFS
version does, predictably failing the whole operation.
This fixes an issue where `./wesnoth -p data foo` from the source tree
would fail with `error filesystem: Could not create parents to foo` if
`foo` did not already exist, when using the Boost.filesystem-based
implementation. `./wesnoth -p data ./foo` would succeed because there is
a visible parent directory '.' that already exists and needs not be
created again.
The non-BFS version of normalize_path() returns an empty string when
passed an empty string, but the BFS version returns the normalized
version of the current working dir for the Wesnoth process.
Due to the way editor::start()'s arguments are built from the process
command line, the result of normalize_path("") gets passed to it when
starting with the --editor switch and no map path argument. If the
result describes a directory, the editor brings up the filechooser
dialog on that path; otherwise, it attempts to open it as a map file.
Making the BFS version of normalize_path() follow the non-BFS behavior
fixes the editor unexpectedly bringing up the filechooser when started
from the command line.
this codecvt gibes errormessages in LOG_FS if it meets an invalid utf8 char.
also the boost codecvt seems inconsistetn becasue it seems on msvc it acepts utf8 AND ansi while it only accpets ansi on mingw.
it seems like iostream from boost 1.44 is incompatible to filesystem
from boost 1.44.
Actualy i didnt veryfy this becasue i don't have boost < 1.50. I added
an adapter for boost filesystem that made it looks liek filesystem 1.43
which we can pass to boost iostreams 1.44.
code from 0e6a10a8c5ce8a48eb18c025547e3d30b5509349 and
e37f34b5cd.
I put it into #ifdefs becasue idk whether i chould/can raise the boost
dependency on linux to 1.48