1
0
This repository has been archived on 2023-11-30. You can view files and clone it, but cannot push or open issues or pull requests.
dtux__mkauto_inst/main.cpp

590 lines
12 KiB
C++

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/utsname.h>
#include <errno.h>
#include <iostream>
#include <fstream>
#include <set>
#include <vector>
#include <array>
#include <memory>
#include <stdexcept>
#include <getopt.h>
#include <experimental/filesystem>
#include <cstdlib>
#include <functional>
using namespace std;
namespace fs = experimental::filesystem;
// Global variables
int verbose = false;
string tab = "\t\t\t\t\t";
bool verif = false;
bool list = false;
bool mountpoints = false;
bool partitions = false;
bool generateauto_inst = false;
void help(char * cmd)
{
printf("Usage: %s [-lavVf]\n", cmd);
printf("-a Execute all commands\n" );
printf("-f Verify the modified files and save them\n");
printf("-g Generate auto_inst.cfg.pl\n");
printf("-h Display this help\n");
printf("-l List of the first level packages installed\n");
printf("-m Keep mount points\n");
printf("-p Keep partitioning\n");
printf("-v Verbose\n");
printf("-V Display the version of this software\n");
exit(EXIT_FAILURE);
}
void whatprovides(string filepath)
{
string cmd = "urpmi_rpm-find-leaves";
cmd += " >" + filepath;
system(cmd.c_str());
}
string array2string(array<char, 256> buffer)
{
int i = 0;
string line;
while(buffer[i] != '\n' )
{
line.push_back(buffer[i]);
i++;
}
return line;
}
bool savenonemptydir(string filepath, string needle="*")
{
int rsyncErrors = 0;
int pos;
string rsyncdestination = "files/";
string rsynccmd = "rsync -aqP --relative ";
if (fs::is_directory(filepath))
{
pos = filepath.find(needle);
if (pos != string::npos and (pos == filepath.length() - 2) and !fs::is_empty(filepath) )
{
cout << filepath << endl;
}
}
return rsyncErrors;
}
bool fstabAnanlyze()
{
string fstabpath = "/etc/fstab";
string line;
bool returncode = EXIT_SUCCESS;
int pos = 0;
int posstart = 0;
int npos = 0;
vector<string> fstabarray;
ifstream file;
int nline = 0;
array<string, 15> mountpoints{"/", "/home /var, "};
file.open(fstabpath);
if(file.good())
{
while (getline(file, line))
{
while ((pos = line.find(" ") != string::npos))
{
fstabarray.push_back(line.substr(posstart, pos - posstart));
posstart = pos;
}
npos = 0;
if ()
}
}else
{
cout << "Error opening " + fstabpath << endl;
exit(EXIT_FAILURE);
}
return returncode;
}
bool savedirs()
{
bool returncode = false;
string filepath;
string line;
string rsyncdestination = "files/";
string rsynccmd = "rsync -aqP --relative -m ";
int rsyncErrors = 0;
ifstream confFile("config/savedir.conf");
if (confFile.is_open())
{
while (getline(confFile, line))
{
filepath = line;
//if (fs::exists(filepath))
//{
if (verbose) cout << "Directory to save: " + filepath << endl;
rsynccmd = "rsync -aqP --relative " + filepath + " " + rsyncdestination;
if (verbose) cout << "rsync command: " + rsynccmd << endl;
if (system(rsynccmd.c_str()) != 0)
{
rsyncErrors ++;
}
//}else cout << filepath << "not exists"<< endl;
}
}else
{
cout << "can't open config/savedir.conf" << endl;
exit(EXIT_FAILURE);
}
return returncode;
}
int recursedir(string dir, string needle, function<bool(string,string)> func)
{
int returncode = EXIT_SUCCESS;
string filepath;
for (const auto & file : fs::recursive_directory_iterator(dir))
{
filepath = (string ) file.path();
cout << filepath << endl;
returncode |= func(dir, needle);
}
return returncode;
}
/*
int saveOptLocal()
{
int result;
int rsyncErrors = EXIT_SUCCESS;
string cmd;
string rsynccmd = "rsync -aqP --relative -m ";
string rsyncdestination = "files/";
for(auto var : dirlist)
{
cout << "Saving" + var << endl;
cmd = rsynccmd + var + " " + rsyncdestination;
if (verbose) printf("rsync command: %s\n", cmd.c_str());
if ((result = system(cmd.c_str())) != 0)
{
rsyncErrors ++;
}
}
return rsyncErrors;
}
*/
void verification()
{
int result;
int i = 0;
int rsyncErrors = 0;
array<char, 256> buffer;
string cmd = "rpm -a --verify";
string line;
string filepath;
string rsyncdestination = "files/";
string rsynccmd = "rsync -aqP --relative ";
string etcdir = "/etc";
string dir;
int log;
if (verbose) cout << "save '.d' non empty directories";
recursedir(etcdir, ".d",&savenonemptydir);
savedirs();
printf("Verifying packages installed\n");
flush(cout);
unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
if (!pipe) {
throw std::runtime_error("popen() failed!");
}
while(fgets(buffer.data(), buffer.size(), pipe.get()) != NULL)
{
line = array2string(buffer);
log = line.find(".log");
//cout << "log = " << line.length() << " ---> ";
//printf("%s\n", line.c_str());
if (line.at(2) == '5' and log != (line.length() - 4))
{
line.erase(0, 13);
if (verbose) cout << "file to save: " + line<< endl;
cmd = rsynccmd + line + " " + rsyncdestination;
if (verbose) printf("rsync command: %s\n", cmd.c_str());
if ((result = system(cmd.c_str())) != 0)
{
printf("Rsync error: %i\n", result);
rsyncErrors ++;
}
}
buffer.fill(0);
}
// save all non empties directories finishing by ".d" in /etc
if (rsyncErrors != 0) printf("rsync returned %i errors", rsyncErrors);
}
bool enabledmedias(string filename)
{
bool returnCode = EXIT_SUCCESS;
bool start = false;
bool flag = false;
bool ignore = false;
string temp = "";
string medias = "\t\t'enabled_media' => [\n";
string line;
int i = 0;
printf("searching enabled medias\n");
ifstream file("/etc/urpmi/urpmi.cfg");
if (file.is_open())
{
while (getline(file, line))
{
//printf("%s\n", line.c_str());
//cout << "start =" << start;
if (start == false)
{
if (line.front() != '{' and line.front() != '\0' and line.front() != '}')
{
//cout << "passed";
start = true;
flag = false;
i = 0;
do
{
i = line.find(" ", i+1);
if (line[i-1] == '\\')
{
flag = true;
line.erase(i-1, 1);
}else
{
break;
}
}while(flag == true);
line.erase(i);
temp = line;
printf("%s", temp.c_str());
line.clear();
}else
{
continue;
}
}else
{ array <char, 2048> buffer;
if (line.front() == '}')
{
if (!temp.empty() and ignore != true)
{
cout << " ==> adding to medias list\n";
medias += tab + temp + ",\n";
}else
{
cout << endl;
}
start = false;
temp.clear();
ignore = false;
continue;
}
if (line.find("ignore") != string::npos)
{
//cout << "found 'ignore'\n";
ignore = true;
}
}
}
printf("Medias:\n%s\n", medias.c_str());
file.close();
medias += tab + "],\n";
ofstream file(filename, ofstream::app);
file << medias.c_str();
file.close();
}else return EXIT_FAILURE;
return returnCode;
}
bool keyboardlayout(string filename)
{
bool returncode = EXIT_SUCCESS;
int i;
string cmd = "setxkbmap -query";
string line;
string str;
array<char, 256> buffer;
printf("looking for keyboard layout\n");
flush(cout);
unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
if (!pipe) {
throw std::runtime_error("popen() failed!");
}
while(fgets(buffer.data(), buffer.size(), pipe.get()) != NULL)
{
line = array2string(buffer);
cout << line << endl;
i = line.find("layout:");
if (i != string::npos)
{
i = line.find_last_of(' ');
line.erase(0, i+1);
break;
}
cout << line << endl;
line.clear();
buffer.fill(0);
}
cout << "result =>" << line << endl;
ofstream file(filename, ofstream::app);
if(file.is_open())
{
str = "\t\t'keyboard' => {\n" + tab + "'GRP_TOGGLE' => '',\n" + tab + "'KEYBOARD' => '" + line + "'\n" + tab + "},\n";
file << str;
file.close();
}else return EXIT_FAILURE;
return returncode;
}
string getvalue( string line)
{
string value;
int i;
if ((i = line.find("=")) != string::npos)
{
value = line.substr(i+1, string::npos);
}
return value;
}
bool mklocale(string filename)
{
string localeconf = "/etc/locale.conf";
bool returncode = EXIT_SUCCESS;
int i;
int flag = 0;
int utf8 = 0;
string country;
string lang;
string line;
string str;
string value;
vector<string> languages;
ifstream ifile (localeconf);
ofstream ofile (filename, ofstream::app);
if (ifile.is_open() and ofile.is_open())
{
while (getline(ifile, line))
{
value = getvalue(line);
//cout << "Value ===>" + value << endl;
if((i = line.find("COUNTRY")) != string::npos)
{
country = value;
}else if((i = line.find("LANG=")) != string::npos)
{
lang = value.substr(0, 2);
if (value.find("UTF-8") != string::npos)
{
utf8 = 1;
}
}else if((i = line.find("LANGUAGE")) != string::npos)
{
i = value.find(":");
languages.push_back(value.substr(i+1,string::npos));
}
}
}
ofstream file(filename, ofstream::app);
str = "\t\t'locale' => {\n" + tab + "'IM' => undef,\n" + tab + "'country' => '" + country + "'\n" + tab + "'lang' => '" + lang + "'\n";
str += tab + "'langs' => {\n";
//for(auto & elem : languages)
flag = 0;
for(i=0; i< languages.size(); i++)
{
if (flag == 0)
{
str += tab + "\t\t'" + languages[i] + "' => 1";
}else
{
str += ",\n" + tab + "\t\t'" + languages[i] + "' => 1";
}
}
str += "\n" + tab + "\t\t},\n";
str += tab + "'utf8' => 1\n" + tab + "},\n";
file << str;
file.close();
return returncode;
}
bool miscellaneous(string filename)
{
bool returncode = EXIT_SUCCESS;
int r;
bool numlock = 0;
string str;
r = system("systemctl status numlock");
if (r == 0)
{
numlock = 1;
}
str = "\t\t'miscellaneous' => {\n" + tab + "'numlock' => " + to_string(numlock) + ",\n" + tab + "'HDPARM' => 1,\n\t\t},\n";
ofstream file(filename, ofstream::app);
file << str;
file.close();
return returncode;
}
int mkauto_inst(string pkgsfile)
{
bool returnCode = EXIT_SUCCESS;
bool flag =false;
string dirpath = "auto_inst.files";
string auto_inst_file = "auto_inst.cfg.pl";
string header = "auto_inst.cfg.pl.header";
string users = "auto_inst.cfg.pl.users";
string footer = "auto_inst.cfg.pl.footer";
string cmd = "cp " + dirpath + "/" + header + " ./" + auto_inst_file;
int i = 0;
string line;
cout << "\n\n" + cmd << endl;
returnCode |= system(cmd.c_str());
cout << "copying packages\n";
ifstream ifile(pkgsfile);
ofstream ofile("./" + auto_inst_file, ofstream::app);
if (ifile.is_open() and ofile.is_open())
{
while (getline(ifile, line))
{
if (flag == false)
{
flag = true;
line = tab + line;
ofile << line;
}else
{
line = ",\n" + tab + line;
ofile << line;
}
}
ofile << "\n" + tab + "],\n";
ifile.close();
ofile.close();
}else
{
cout << "error file not open";
return 1;
}
returnCode |= enabledmedias(auto_inst_file);
returnCode |= keyboardlayout(auto_inst_file);
returnCode |= mklocale(auto_inst_file);
returnCode |= miscellaneous(auto_inst_file);
return returnCode;
}
int main(int argc, char** argv)
{
//bool x64 = 0;
string pkgsfile = "pkgsfile.txt";
int opt = 0;
int exitcode = EXIT_SUCCESS;
// listing arguments
if(argc>1)
{
while((opt = getopt(argc, argv, "valmpVfg")) != -1)
{
switch (opt)
{
case 'f':
verif = true;
break;
case 'l':
list = true;
break;
case 'a':
list = true;
verif = true;
generateauto_inst = true;
break;
case 'v':
verbose = true;
break;
case 'g':
generateauto_inst = true;
list = true;
break;
case 'm':
mountpoints = true;
break;
case 'p':
partitions = true;
default:
help(argv[0]);
}
}
}else
{
cout << "no args\n";
help(argv[0]);
}
/*
// getting processeur architecture
if (uname(&buffer) < 0)
{
perror("uname");
exit(EXIT_FAILURE);
}
if ( strcmp(buffer.machine, "x86_64") == 0)
{
x64 = true;
}
if (verbose) printf("architecture is %s\n", buffer.machine);
*/
if (list == true)
{
whatprovides(pkgsfile);
}
if( verif == true)
{
verification();
}
if(generateauto_inst == true)
{
mkauto_inst(pkgsfile);
}
cout << "finished\n";
exit(exitcode);
}