-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgemian_setup.cpp
154 lines (137 loc) · 5.65 KB
/
gemian_setup.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
* Copyright (c) 2021, Adam Boardman
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <iostream>
#include <filesystem>
#include "para_variables.h"
#include "locales_identification.h"
static const char *const devBlockPara = "/dev/disk/by-partlabel/para";
static const char *const defaultKeyboardFile = "/etc/default/keyboard";
static const std::string_view etcGemianDirectory("/etc/gemian");
static const char *const machineIdResetFile = "/etc/gemian/machine-id-reset";
static const char *const sshHostResetFile = "/etc/gemian/ssh-host-reset";
static const char *const timeZoneSetFile = "/etc/gemian/time-zone-set";
static const char *const localeSetFile = "/etc/gemian/locale-set";
static const std::string_view etcMachineIdFile("/etc/machine-id");
static const std::string_view dbusMachineIdFile("/var/lib/dbus/machine-id");
static const char *const operationPerformedContent = "done";
void createFile(const std::string &path, std::string_view content) {
std::ofstream stream(path);
stream << content;
stream.close();
}
int main() {
ParaVariables paraVariables;
std::ifstream paraStream(devBlockPara, std::ios::binary);
if (paraStream.is_open()) {
if (paraVariables.ReadFromStream(paraStream) != ParaVarErrorNone) {
std::cout << "Failed to read file: " << devBlockPara << std::endl;
}
paraStream.close();
} else {
std::cout << "Failed to open file: " << devBlockPara << std::endl;
}
std::string hwKeyboard(paraVariables["keyboard_layout"]);
std::cout << "HW Keyboard: " << hwKeyboard << "\n";
std::cout << "Time Zone: " << paraVariables["time_zone"] << "\n";
if (hwKeyboard.length() > 0) {
auto found = false;
auto foundModel = false;
std::ifstream keyboardDefault(defaultKeyboardFile);
if (keyboardDefault.is_open()) {
while (!keyboardDefault.eof()) {
std::string toCheck;
keyboardDefault >> toCheck;
if (toCheck.find("XKBLAYOUT=") != std::string::npos && toCheck.find(hwKeyboard) != std::string::npos) {
found = true;
}
if (toCheck.find("XKBMODEL=") != std::string::npos) {
foundModel = true;
}
}
} else {
std::cout << "Failed to open file: " << defaultKeyboardFile << std::endl;
}
if (!found || foundModel) {
auto setKeymap = "localectl set-x11-keymap " + hwKeyboard;
auto err = system(setKeymap.c_str());
std::cout << setKeymap << " : " << err << "\n";
}
}
if (!std::filesystem::exists(localeSetFile) && (paraVariables["keyboard_layout"].length() > 0)) {
int layoutIndex = LocalesIdentification::indexForKeyboardLayout(paraVariables["keyboard_layout"]);
if (layoutIndex >= 0 && (layoutIndex < LocalesIdentification::getLayoutCodesCount())) {
std::string locale(LocalesIdentification::getDefaultLocale(layoutIndex));
if (locale.find('*') != std::string::npos && paraVariables["time_zone"].length() > 0) {
auto index = LocalesIdentification::indexForArabicCountryTz(paraVariables["time_zone"]);
locale = LocalesIdentification::getArabicLocales(index);
}
if (paraVariables["language"].length() > 0 && paraVariables["language"] != "auto") {
locale = paraVariables["language"]+".UTF-8";
}
auto sedLocalGenCmd = "sed -i /etc/locale.gen -e 's/# " + locale + "/" + locale + "/'";
auto err = system(sedLocalGenCmd.c_str());
std::cout << sedLocalGenCmd << " : " << err << "\n";
auto localeGenCmd = "locale-gen";
err = system(localeGenCmd);
std::cout << localeGenCmd << " : " << err << "\n";
char buffer[128];
std::string result;
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen("localectl list-locales", "r"), pclose);
if (!pipe) {
std::cout << "localectl list-locales" << " : " << "popen() failed!" << "\n";
}
auto localeDotPos = locale.find('.');
if (localeDotPos == std::string::npos) {
localeDotPos = locale.find(' ');
}
while (fgets(buffer, sizeof(buffer), pipe.get()) != nullptr) {
result = buffer;
auto resultDotPos = result.find('.');
if (resultDotPos == std::string::npos) {
resultDotPos = result.find(' ');
}
if (result.substr(0, resultDotPos) == locale.substr(0, localeDotPos)) {
locale = result;
}
}
auto localeSetCmd = "localectl set-locale " + locale + "";
err = system(localeSetCmd.c_str());
std::cout << localeSetCmd << " : " << err << "\n";
createFile(localeSetFile, operationPerformedContent);
}
}
if (!std::filesystem::exists(machineIdResetFile)) {
std::filesystem::remove(etcMachineIdFile);
std::filesystem::remove(dbusMachineIdFile);
const char *idGen1Cmd = "dbus-uuidgen --ensure=/etc/machine-id";
auto err = system(idGen1Cmd);
std::cout << idGen1Cmd << " : " << err << "\n";
const char *idGen2Cmd = "dbus-uuidgen --ensure";
err = system(idGen2Cmd);
std::cout << idGen2Cmd << " : " << err << "\n";
std::filesystem::create_directory(etcGemianDirectory);
createFile(machineIdResetFile, operationPerformedContent);
}
if (!std::filesystem::exists(sshHostResetFile)) {
for (auto &p: std::filesystem::directory_iterator("/etc/ssh")) {
if (p.path().string().find("ssh_host_") != std::string::npos) {
std::filesystem::remove(p);
}
}
const char *reConfigCmd = "dpkg-reconfigure openssh-server";
auto err = system(reConfigCmd);
std::cout << reConfigCmd << " : " << err << "\n";
std::filesystem::create_directory(etcGemianDirectory);
createFile(sshHostResetFile, operationPerformedContent);
}
if (!std::filesystem::exists(timeZoneSetFile) && (paraVariables["time_zone"].length() > 0)) {
auto setTimeZone = "timedatectl set-timezone " + paraVariables["time_zone"];
auto err = system(setTimeZone.c_str());
std::cout << setTimeZone << " : " << err << "\n";
createFile(timeZoneSetFile, operationPerformedContent);
}
return 0;
}