X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FMain%2Ffg_commands.cxx;h=cf5efb8a5df4dc4e0a9d3fe3c3ee6edf99b414c3;hb=18d1593c42c2df60d7fb44ace722ca3e8a7fd82c;hp=56eb29fcfe44cb96bc56e6caed1d641d49704d6d;hpb=60dc921a80643c9f4b54e4953d50373e861f6c19;p=flightgear.git diff --git a/src/Main/fg_commands.cxx b/src/Main/fg_commands.cxx index 56eb29fcf..cf5efb8a5 100644 --- a/src/Main/fg_commands.cxx +++ b/src/Main/fg_commands.cxx @@ -8,8 +8,8 @@ #include -#include STL_STRING -#include STL_FSTREAM +#include +#include #include #include @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -45,9 +46,9 @@ #include "viewmgr.hxx" #include "main.hxx" -SG_USING_STD(string); -SG_USING_STD(ifstream); -SG_USING_STD(ofstream); +using std::string; +using std::ifstream; +using std::ofstream; @@ -211,6 +212,17 @@ do_exit (const SGPropertyNode * arg) } +/** + * Reset FlightGear (Shift-Escape or Menu->File->Reset) + */ +static bool +do_reset (const SGPropertyNode * arg) +{ + reInit(); + return true; +} + + /** * Built-in command: reinitialize one or more subsystems. * @@ -309,16 +321,25 @@ do_resume (const SGPropertyNode * arg) static bool do_load (const SGPropertyNode * arg) { - const string &file = arg->getStringValue("file", "fgfs.sav"); - ifstream input(file.c_str()); - if (input.good() && fgLoadFlight(input)) { - input.close(); - SG_LOG(SG_INPUT, SG_INFO, "Restored flight from " << file); - return true; - } else { - SG_LOG(SG_INPUT, SG_WARN, "Cannot load flight from " << file); - return false; - } + string file = arg->getStringValue("file", "fgfs.sav"); + if (file.size() < 4 || file.substr(file.size() - 4) != ".sav") + file += ".sav"; + + if (!fgValidatePath(file.c_str(), false)) { + SG_LOG(SG_IO, SG_ALERT, "load: reading '" << file << "' denied " + "(unauthorized access)"); + return false; + } + + ifstream input(file.c_str()); + if (input.good() && fgLoadFlight(input)) { + input.close(); + SG_LOG(SG_INPUT, SG_INFO, "Restored flight from " << file); + return true; + } else { + SG_LOG(SG_INPUT, SG_WARN, "Cannot load flight from " << file); + return false; + } } @@ -331,18 +352,27 @@ do_load (const SGPropertyNode * arg) static bool do_save (const SGPropertyNode * arg) { - const string &file = arg->getStringValue("file", "fgfs.sav"); - bool write_all = arg->getBoolValue("write-all", false); - SG_LOG(SG_INPUT, SG_INFO, "Saving flight"); - ofstream output(file.c_str()); - if (output.good() && fgSaveFlight(output, write_all)) { - output.close(); - SG_LOG(SG_INPUT, SG_INFO, "Saved flight to " << file); - return true; - } else { - SG_LOG(SG_INPUT, SG_ALERT, "Cannot save flight to " << file); - return false; - } + string file = arg->getStringValue("file", "fgfs.sav"); + if (file.size() < 4 || file.substr(file.size() - 4) != ".sav") + file += ".sav"; + + if (!fgValidatePath(file.c_str(), false)) { + SG_LOG(SG_IO, SG_ALERT, "save: reading '" << file << "' denied " + "(unauthorized access)"); + return false; + } + + bool write_all = arg->getBoolValue("write-all", false); + SG_LOG(SG_INPUT, SG_INFO, "Saving flight"); + ofstream output(file.c_str()); + if (output.good() && fgSaveFlight(output, write_all)) { + output.close(); + SG_LOG(SG_INPUT, SG_INFO, "Saved flight to " << file); + return true; + } else { + SG_LOG(SG_INPUT, SG_ALERT, "Cannot save flight to " << file); + return false; + } } @@ -1151,15 +1181,46 @@ do_gui_redraw (const SGPropertyNode * arg) /** - * Set mouse coordinates and cursor. + * Adds model to the scenery. The path to the added branch (/models/model[*]) + * is returned in property "property". + */ +static bool +do_add_model (const SGPropertyNode * arg) +{ + SGPropertyNode * model = fgGetNode("models", true); + for (int i = 0;; i++) { + if (i < 0) + return false; + if (!model->getChild("model", i, false)) { + model = model->getChild("model", i, true); + break; + } + } + copyProperties(arg, model); + if (model->hasValue("elevation-m")) + model->setDoubleValue("elevation-ft", model->getDoubleValue("elevation-m") + * SG_METER_TO_FEET); + model->getNode("load", true); + model->removeChildren("load"); + const_cast(arg)->setStringValue("property", model->getPath()); + return true; +} + + +/** + * Set mouse cursor coordinates and cursor shape. */ static bool -do_set_mouse (const SGPropertyNode * arg) +do_set_cursor (const SGPropertyNode * arg) { if (arg->hasValue("x") || arg->hasValue("y")) { - int x = arg->getIntValue("x", fgGetInt("/devices/status/mice/mouse/x")); - int y = arg->getIntValue("y", fgGetInt("/devices/status/mice/mouse/y")); + SGPropertyNode *mx = fgGetNode("/devices/status/mice/mouse/x", true); + SGPropertyNode *my = fgGetNode("/devices/status/mice/mouse/y", true); + int x = arg->getIntValue("x", mx->getIntValue()); + int y = arg->getIntValue("y", my->getIntValue()); fgWarpMouse(x, y); + mx->setIntValue(x); + my->setIntValue(y); } SGPropertyNode *cursor = const_cast(arg)->getNode("cursor", true); @@ -1321,6 +1382,12 @@ do_load_xml_to_proptree(const SGPropertyNode * arg) if (file.extension() != "xml") file.concat(".xml"); + if (!fgValidatePath(file.c_str(), false)) { + SG_LOG(SG_IO, SG_ALERT, "loadxml: reading '" << file.str() << "' denied " + "(unauthorized access)"); + return false; + } + SGPropertyNode *targetnode; if (arg->hasValue("targetnode")) targetnode = fgGetNode(arg->getStringValue("targetnode"), true); @@ -1334,7 +1401,7 @@ do_load_xml_to_proptree(const SGPropertyNode * arg) return false; } - return true; + return true; } @@ -1361,6 +1428,12 @@ do_save_xml_from_proptree(const SGPropertyNode * arg) if (file.extension() != "xml") file.concat(".xml"); + if (!fgValidatePath(file.c_str(), true)) { + SG_LOG(SG_IO, SG_ALERT, "savexml: writing to '" << file.str() << "' denied " + "(unauthorized access)"); + return false; + } + SGPropertyNode *sourcenode; if (arg->hasValue("sourcenode")) sourcenode = fgGetNode(arg->getStringValue("sourcenode"), true); @@ -1441,6 +1514,7 @@ static struct { { "null", do_null }, { "nasal", do_nasal }, { "exit", do_exit }, + { "reset", do_reset }, { "reinit", do_reinit }, { "suspend", do_reinit }, { "resume", do_reinit }, @@ -1473,7 +1547,8 @@ static struct { { "dialog-update", do_dialog_update }, { "dialog-apply", do_dialog_apply }, { "gui-redraw", do_gui_redraw }, - { "set-mouse", do_set_mouse }, + { "add-model", do_add_model }, + { "set-cursor", do_set_cursor }, { "play-audio-sample", do_play_audio_sample }, { "presets-commit", do_presets_commit }, { "log-level", do_log_level },