summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ui/qt5/CMakeLists.txt6
-rw-r--r--ui/qt5/horizonwizard.cc119
-rw-r--r--ui/qt5/horizonwizard.hh18
3 files changed, 142 insertions, 1 deletions
diff --git a/ui/qt5/CMakeLists.txt b/ui/qt5/CMakeLists.txt
index 9ac6372..7fd1ebf 100644
--- a/ui/qt5/CMakeLists.txt
+++ b/ui/qt5/CMakeLists.txt
@@ -31,7 +31,11 @@ ENDIF(UNSUPPORTED_NONFREE_FIRMWARE)
include_directories(${CMAKE_SOURCE_DIR}/3rdparty)
add_executable(horizon-qt5 ${UI_SOURCES})
-target_link_libraries(horizon-qt5 Qt5::Network Qt5::Widgets)
+target_link_libraries(horizon-qt5 Qt5::Network Qt5::Widgets crypto)
+
+IF("cxx_std_17" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
+ set_property(TARGET horizon-qt5 PROPERTY CXX_STANDARD 17)
+ENDIF()
install(TARGETS horizon-qt5 DESTINATION bin)
diff --git a/ui/qt5/horizonwizard.cc b/ui/qt5/horizonwizard.cc
index bde4232..75598cb 100644
--- a/ui/qt5/horizonwizard.cc
+++ b/ui/qt5/horizonwizard.cc
@@ -16,6 +16,9 @@
#include <QDebug>
#include <QFile>
#include <QMessageBox>
+#include <openssl/rand.h>
+
+#include <algorithm>
#include <map>
#include <string>
@@ -45,6 +48,8 @@ extern "C" {
#include "rootpwpage.hh"
#include "accountpage.hh"
+#include "util/keymaps.hh"
+
static std::map<int, std::string> help_id_map = {
{HorizonWizard::Page_Intro, "intro"},
{HorizonWizard::Page_Input, "input"},
@@ -278,3 +283,117 @@ HorizonWizard::HorizonWizard(QWidget *parent) : QWizard(parent) {
tain_now_set_stopwatch_g();
#endif /* HAS_INSTALL_ENV */
}
+
+
+extern "C" char *do_a_crypt(const char *key, const char *setting, char *output);
+
+/*! Make a shadow-compliant crypt string out of +the_pw+. */
+char *encrypt_pw(const char *the_pw) {
+ unsigned char rawsalt[8];
+ RAND_bytes(rawsalt, 8);
+ QByteArray salt_ba(reinterpret_cast<char *>(rawsalt), 8);
+
+ const char *salt = ("$6$" + salt_ba.toBase64(QByteArray::OmitTrailingEquals)
+ .toStdString() + "$").c_str();
+ char *result = new char[128];
+ if(do_a_crypt(the_pw, salt, result) == nullptr) {
+ delete[] result;
+ return nullptr;
+ }
+ return result;
+}
+
+
+QString HorizonWizard::toHScript() {
+ QStringList lines;
+
+ if(this->network) {
+ lines << "network true";
+
+ if(this->net_dhcp) {
+ lines << QString::fromStdString("netaddress " +
+ this->chosen_auto_iface + " dhcp");
+ } else {
+ /* XXX TODO no manual page implemented yet */
+ Q_ASSERT(false);
+ }
+ } else {
+ lines << "network false";
+ }
+
+ lines << ("hostname " + field("hostname").toString());
+
+ switch(this->pkgtype) {
+ case Mobile:
+ lines << "pkginstall powerdevil upower";
+#if __cplusplus >= 201703L
+ [[ fallthrough ]];
+#endif
+ case Standard:
+ lines << "pkginstall adelie-base-posix firefox-esr libreoffice "
+ "thunderbird vlc kde x11";
+ break;
+ case Compact:
+ lines << "pkginstall adelie-base netsurf featherpad lxqt-desktop "
+ "abiword gnumeric xorg-apps xorg-drivers xorg-server";
+ break;
+ case TextOnly:
+ lines << "pkginstall adelie-base links tmux";
+ break;
+ case Custom:
+ lines << ("pkginstall " + packages.join(" "));
+ break;
+ }
+
+ char *root = encrypt_pw(field("rootpw").toString().toStdString().c_str());
+ Q_ASSERT(root != nullptr);
+ lines << QString("rootpw ") + root;
+ delete[] root;
+
+ /* XXX TODO someday we'll have language support */
+ lines << "language en_GB.UTF-8";
+
+ auto iterator = valid_keymaps.begin();
+ std::advance(iterator, field("keymap").toInt());
+ lines << ("keymap " + QString::fromStdString(*iterator));
+
+#ifdef NON_LIBRE_FIRMWARE
+ if(this->firmware) {
+ lines << "firmware true";
+ } else {
+ lines << "firmware false";
+ }
+#endif /* NON_LIBRE_FIRWMARE */
+
+ lines << ("timezone " +
+ dynamic_cast<DateTimePage *>(page(Page_DateTime))->selectedTimeZone());
+
+ for(auto &acctWidget : dynamic_cast<AccountPage *>(page(Page_Accounts))->accountWidgets) {
+ if(acctWidget->accountText().isEmpty()) break;
+
+ char *userpw = encrypt_pw(acctWidget->passphraseText().toStdString().c_str());
+ Q_ASSERT(userpw != nullptr);
+
+ lines << ("username " + acctWidget->accountText());
+ lines << ("useralias " + acctWidget->accountText() + " " +
+ acctWidget->personalText());
+ lines << ("userpw " + acctWidget->accountText() + " " + userpw);
+ delete[] userpw;
+ if(acctWidget->isAdmin()) {
+ lines << ("usergroups " + acctWidget->accountText() + " " +
+ "users,lp,audio,cdrom,cdrw,scanner,camera,video,games,usb,kvm,wheel");
+ } else {
+ lines << ("usergroups " + acctWidget->accountText() + " " +
+ "users,lp,audio,cdrom,cdrw,scanner,camera,video,games");
+ }
+ }
+
+ return lines.join("\n");
+}
+
+
+#include <iostream>
+
+void HorizonWizard::accept() {
+ std::cout << toHScript().toStdString() << std::endl;
+}
diff --git a/ui/qt5/horizonwizard.hh b/ui/qt5/horizonwizard.hh
index 929c598..5be8c67 100644
--- a/ui/qt5/horizonwizard.hh
+++ b/ui/qt5/horizonwizard.hh
@@ -83,19 +83,37 @@ public:
};
HorizonWizard(QWidget *parent = nullptr);
+ void accept();
+ /*! Emit a HorizonScript file with the user's choices. */
+ QString toHScript();
QShortcut *esc, *f1, *f3, *f6, *f8;
+ /*! The domain to use for downloading packages.
+ * @example distfiles.adelielinux.org
+ */
std::string mirror_domain;
+ /*! The version of Adélie to install. Typically "1.0". */
std::string version;
#ifdef NON_LIBRE_FIRMWARE
+ /*! Determines whether firmware will be installed. */
bool firmware;
#endif /* NON_LIBRE_FIRMWARE */
+ /*! The currently probed network interfaces
+ * @note Only available in Installation Environment. */
std::map<std::string, NetworkInterface> interfaces;
+ /*! Determines whether networking will be enabled. */
bool network;
+ /*! Determines whether to use DHCP. */
bool net_dhcp;
+ /*! Determines the network interface to use. */
std::string chosen_auto_iface;
+ /*! Determines the packages to install. */
PackageType pkgtype;
+ /*! If pkgtype is Custom, a list of packages to install. */
+ QStringList packages;
+ /*! Determines whether to install GRUB. */
bool grub;
+ /*! Determines the kernel to install. */
std::string kernel;
};