312 lines
6.4 KiB
C++
312 lines
6.4 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 <filesystem>
|
|
#include <cstdlib>
|
|
|
|
//#include <pstreams/pstream.h>
|
|
|
|
#include <rpm/rpmlib.h>
|
|
#include <rpm/header.h>
|
|
#include <rpm/rpmdb.h>
|
|
#include <rpm/rpmtypes.h>
|
|
#include <rpm/rpmts.h>
|
|
#include <rpm/rpmtd.h>
|
|
#include <rpm/rpmds.h>
|
|
#include <rpm/rpmtag.h>
|
|
#include <rpm/rpmfi.h>
|
|
#include <rpm/header.h>
|
|
#include <rpm/rpmlog.h>
|
|
#include <rpm/rpmps.h>
|
|
#include <rpm/rpmcli.h>
|
|
#include <rpm/rpmio.h>
|
|
|
|
namespace fs = std::filesystem;
|
|
|
|
using namespace std;
|
|
|
|
// Global variables
|
|
int verbose = false;
|
|
|
|
void help(char * cmd)
|
|
{
|
|
printf("Usage: %s [-lavVf]\n", cmd);
|
|
printf("-l List of the first level packages installed\n");
|
|
printf("-f Verify the modified files and save them\n");
|
|
printf("-a Execute all commands\n" );
|
|
printf("-V Display the version of this software\n");
|
|
printf("-h Display this help\n");
|
|
printf("-v verbose\n");
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
void whatprovides(string cmd, vector<string>& pkgs)
|
|
{
|
|
string pkg;
|
|
string command;
|
|
string line;
|
|
bool erased = false;
|
|
array<char, 128> buffer;
|
|
vector <string>::iterator iter;
|
|
|
|
for ( iter = pkgs.begin(); iter < pkgs.end();)
|
|
{
|
|
pkg = string(*iter);
|
|
command = cmd + pkg;
|
|
printf("Searching whatprovides for %s\n", pkg.c_str());
|
|
unique_ptr<FILE, decltype(&pclose)> pipe(popen(command.c_str(), "r"), pclose);
|
|
if (!pipe) {
|
|
throw std::runtime_error("popen() failed!");
|
|
}
|
|
while (fgets(buffer.data(), buffer.size(), pipe.get()) != NULL)
|
|
{
|
|
printf("=> %s\n", buffer.data());
|
|
line = string(buffer.cbegin(), buffer.cend());
|
|
if(line.find(pkg) == std::string::npos)
|
|
{
|
|
printf("erasing %s\n", pkg.c_str() );
|
|
pkgs.erase(iter);
|
|
erased = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!erased)
|
|
{
|
|
iter++;
|
|
}else
|
|
{
|
|
erased = false;
|
|
buffer.fill(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void verification()
|
|
{
|
|
int result;
|
|
int i = 0;
|
|
int rsyncErrors = 0;
|
|
array<char, 128> buffer;
|
|
string cmd = "rpm -a --verify";
|
|
string line;
|
|
string filepath;
|
|
string rsyncdestination = "files/";
|
|
string rsynccmd = "rsync -aqP";
|
|
|
|
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)
|
|
{
|
|
i = 0;
|
|
while(buffer[i] != '\n' )
|
|
{
|
|
line.push_back(buffer[i]);
|
|
i++;
|
|
}
|
|
|
|
printf("line: %s<=====\n", line.c_str());
|
|
if (line.at(2) == '5')
|
|
{
|
|
line.erase(0, 13);
|
|
if (verbose) cout << "===>>>>" << line.c_str() << "\n";
|
|
rsynccmd = "rsync -aqP --relative " + line + " " + rsyncdestination;
|
|
/*rsynccmd.append("rsync -aqP");
|
|
rsynccmd.append(line);
|
|
rsynccmd.append(" ");
|
|
rsynccmd.append(rsyncdestination);*/
|
|
if (verbose) printf("%s<====\n", rsynccmd.c_str());
|
|
if ((result = system(rsynccmd.c_str())) != 0)
|
|
{
|
|
rsyncErrors ++;
|
|
}
|
|
}
|
|
buffer.fill(0);
|
|
line.clear();
|
|
rsynccmd.clear();
|
|
}
|
|
if (rsyncErrors != 0) printf("rsync returned %i errors", rsyncErrors);
|
|
}
|
|
|
|
int mkauto_inst()
|
|
{
|
|
bool returnCode = 0;
|
|
string dirpath = "auto_inst.files";
|
|
|
|
|
|
return returnCode;
|
|
}
|
|
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
|
|
|
|
/*rpmdbMatchIterator mi;
|
|
//int type, count;
|
|
//char *name;
|
|
rpmdb db;
|
|
Header h;
|
|
rpmtd td;
|
|
rpmTagVal result;
|
|
rpmts ts = NULL;
|
|
rpmds ds = NULL;
|
|
const char *DNEVR;
|
|
*/
|
|
|
|
struct utsname buffer;
|
|
int i = 0;
|
|
errno = 0;
|
|
bool x64 = 0;
|
|
string line;
|
|
string tmpfile = "/tmp/installedrpmlist.txt";
|
|
string pkgsfile = "pkgsfile.txt";
|
|
string rpmcmd = "/usr/bin/rpm -q";
|
|
string rpmfullcmd;
|
|
string whatrequirescmd;
|
|
size_t found;
|
|
string pkg;
|
|
vector <string> pkgs;
|
|
vector <string>::iterator iter;
|
|
set <string> requires;
|
|
set <string>::iterator reqiter;
|
|
ofstream fh;
|
|
int verif = false;
|
|
int opt = 0;
|
|
int list = false;
|
|
|
|
rpmfullcmd = rpmcmd + "a >" + tmpfile;
|
|
whatrequirescmd = "urpmq --whatrequires ";
|
|
|
|
// listing arguments
|
|
if(argc>1)
|
|
{
|
|
while((opt = getopt(argc, argv, "valVf")) != -1)
|
|
{
|
|
switch (opt)
|
|
{
|
|
case 'f':
|
|
verif = true;
|
|
break;
|
|
case 'l':
|
|
list = true;
|
|
break;
|
|
case 'a':
|
|
list = true;
|
|
verif = true;
|
|
break;
|
|
case 'v':
|
|
verbose = true;
|
|
break;
|
|
default:
|
|
help(argv[0]);
|
|
}
|
|
}
|
|
}else
|
|
{
|
|
cout << "no args\n";
|
|
help(argv[0]);
|
|
}
|
|
if (verbose == true)
|
|
{
|
|
printf("%s\n", rpmfullcmd.c_str());
|
|
printf("%s\n", whatrequirescmd.c_str());
|
|
}
|
|
|
|
// 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)
|
|
{
|
|
// launching rpm -qa ...
|
|
if (system(rpmfullcmd.c_str()) != 0)
|
|
{
|
|
cout << "system return an error\n";
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
// opening file generated by rpm -qa
|
|
cout << "Opening file generated by rpm -qa\n";
|
|
ifstream myfile (tmpfile);
|
|
if (myfile.is_open())
|
|
{
|
|
while ( getline (myfile,line) )
|
|
{
|
|
found = line.find_last_of("-"); // searching first "." delimiting version string
|
|
found = line.find_last_of("-", found - 1);
|
|
if (found != std::string::npos)
|
|
{
|
|
line.erase(found, string::npos); // erasing version string
|
|
}
|
|
/*found = line.find_last_of("-");
|
|
if (found != std::string::npos)
|
|
{
|
|
line.erase(found, string::npos); // erasing version string
|
|
}*/
|
|
pkgs.push_back(line); // inserting line in array (set)
|
|
}
|
|
myfile.close();
|
|
}else
|
|
{
|
|
cout << "Unable to open file\n";
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
/*
|
|
for ( iter = pkgs.begin(); iter < pkgs.end();)
|
|
{
|
|
found = string(*iter).find("lib");
|
|
if (found != string::npos and found == 0)
|
|
{
|
|
printf("erasing %s\n", string(*iter).c_str() );printf("\n");
|
|
pkgs.erase(iter);
|
|
}else
|
|
{
|
|
iter++;
|
|
}
|
|
}
|
|
*/
|
|
// searching whatrequires for every pkg
|
|
|
|
whatprovides(whatrequirescmd, pkgs);
|
|
// saving to file
|
|
if (verbose) cout << "Saving result to file" << pkgsfile << "\n";
|
|
fh.open(pkgsfile);
|
|
for( iter = pkgs.begin(); iter < pkgs.end(); ++iter)
|
|
{
|
|
fh << *iter << " ";
|
|
}
|
|
fh.close();
|
|
}
|
|
if( verif == true)
|
|
{
|
|
verification();
|
|
}
|
|
|
|
cout << "finished\n";
|
|
exit(EXIT_SUCCESS);
|
|
}
|