main.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*
  2. * Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org>
  3. * Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
  4. * Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
  5. *
  6. * SPDX-License-Identifier: BSD-2-Clause
  7. */
  8. #include "MainWidget.h"
  9. #include <AK/URL.h>
  10. #include <LibCore/ArgsParser.h>
  11. #include <LibCore/System.h>
  12. #include <LibGUI/Application.h>
  13. #include <LibGUI/Icon.h>
  14. #include <LibGUI/Window.h>
  15. #include <LibMain/Main.h>
  16. using namespace Help;
  17. static DeprecatedString parse_input(StringView input)
  18. {
  19. AK::URL url(input);
  20. if (url.is_valid())
  21. return url.basename();
  22. return input;
  23. }
  24. ErrorOr<int> serenity_main(Main::Arguments arguments)
  25. {
  26. TRY(Core::System::pledge("stdio recvfd sendfd rpath unix"));
  27. auto app = TRY(GUI::Application::try_create(arguments));
  28. TRY(Core::System::unveil("/sys/kernel/processes", "r"));
  29. TRY(Core::System::unveil("/res", "r"));
  30. // We specifically don't want to load this path from a library, as that can be hijacked with LD_PRELOAD.
  31. TRY(Core::System::unveil("/usr/share/man", "r"));
  32. TRY(Core::System::unveil("/tmp/session/%sid/portal/filesystemaccess", "rw"));
  33. TRY(Core::System::unveil("/tmp/session/%sid/portal/launch", "rw"));
  34. TRY(Core::System::unveil("/tmp/session/%sid/portal/webcontent", "rw"));
  35. TRY(Core::System::unveil(nullptr, nullptr));
  36. DeprecatedString start_page;
  37. u32 section = 0;
  38. Core::ArgsParser args_parser;
  39. // FIXME: These custom Args are a hack. What we want to do is have an optional int arg, then an optional string.
  40. // However, when only a string is provided, it gets forwarded to the int argument since that is first, and
  41. // parsing fails. This hack instead forwards it to the start_page in that case.
  42. args_parser.add_positional_argument(Core::ArgsParser::Arg {
  43. .help_string = "Section of the man page",
  44. .name = "section",
  45. .min_values = 0,
  46. .max_values = 1,
  47. .accept_value = [&](char const* input_ptr) {
  48. StringView input { input_ptr, strlen(input_ptr) };
  49. // If it's a number, use it as the section
  50. if (auto number = input.to_int(); number.has_value()) {
  51. section = number.value();
  52. return true;
  53. }
  54. // Otherwise, use it as the start_page
  55. start_page = parse_input(input);
  56. return true;
  57. } });
  58. args_parser.add_positional_argument(Core::ArgsParser::Arg {
  59. .help_string = "Help page to open. Either an absolute path to the markdown file, or a search query",
  60. .name = "page",
  61. .min_values = 0,
  62. .max_values = 1,
  63. .accept_value = [&](char const* input_ptr) {
  64. StringView input { input_ptr, strlen(input_ptr) };
  65. // If start_page was already set by our section arg, then it can't be set again
  66. if (start_page.is_empty())
  67. return false;
  68. start_page = parse_input(input);
  69. return true;
  70. } });
  71. args_parser.parse(arguments);
  72. auto app_icon = GUI::Icon::default_icon("app-help"sv);
  73. auto window = TRY(GUI::Window::try_create());
  74. window->set_icon(app_icon.bitmap_for_size(16));
  75. window->set_title("Help");
  76. window->resize(570, 500);
  77. auto main_widget = TRY(window->try_set_main_widget<MainWidget>());
  78. TRY(main_widget->initialize_fallibles(window));
  79. TRY(main_widget->set_start_page(start_page, section));
  80. window->show();
  81. return app->exec();
  82. }