#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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& pkgs) { string pkg; string command; string line; bool erased = false; array buffer; vector ::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 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 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 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 pkgs; vector ::iterator iter; set requires; set ::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); }