3 // Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 // based on vcheck.cc by Jacques Gelinas
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2, or (at your option)
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 This utility is used to compare two vservers. One is known to
22 be clean and the other is potentially corrupted (cracked). The
23 goal of this program is to run the rpm verify command, but using
24 the RPM database of the first vserver.
44 "vcheck version " << VERSION <<
46 "vcheck [ options ] reference-server chk-vservers\n"
48 "--diffpkgs: Shows which package differ.\n"
49 " + means the package only exists in chk-server.\n"
50 " - means the package does not exist in chk-server.\n"
51 " ! means the servers have different version.\n"
53 "--verify: Execute an RPM verify on common packages.\n"
54 "--debug: Turn on some (useless) debugging messages.\n"
58 typedef list<PACKAGE> PACKAGES;
61 Delete a directory silently
63 static int vcheck_deldir (const string &path)
67 if (lstat(path.c_str(),&st)==-1){
70 if (!S_ISDIR(st.st_mode)){
71 fprintf (stderr,"%s already exist and is not a directory\n"
75 DIR *d = opendir (path.c_str());
79 while ((ent=readdir(d))!=NULL){
80 if (strcmp(ent->d_name,".")!=0
81 && strcmp(ent->d_name,"..")!=0){
82 string tmp = path + "/" + ent->d_name;
83 if (unlink(tmp.c_str())==-1){
84 fprintf (stderr,"Can't delete file %s (%s)\n",tmp.c_str()
100 static int vcheck_copydb (const string &refserv, const string &path)
103 string refpath = refserv + "/var/lib/rpm";
104 DIR *d = opendir (refpath.c_str());
106 fprintf (stderr,"Can't open directory %s (%s)\n",refpath.c_str()
111 while ((ent=readdir(d))!=NULL){
112 if (strcmp(ent->d_name,".")!=0
113 && strcmp(ent->d_name,"..")!=0){
114 string srcpath = refpath + "/" + ent->d_name;
115 const char *spath = srcpath.c_str();
117 if (stat(spath,&st)!=-1){
118 string dstpath = path + "/" + ent->d_name;
119 if (file_copy (spath,dstpath.c_str(),st) == -1){
125 fprintf (stderr,"Can't stat %s (%s)\n",spath,strerror(errno));
137 int operator()(const PACKAGE &p1, const PACKAGE &p2){
138 return strcmp(p1.name.c_str(),p2.name.c_str());
143 int main (int argc, char *argv[])
146 bool diffpkg = false;
149 for (i=1; i<argc; i++){
150 const char *arg = argv[i];
151 //const char *opt = argv[i+1];
152 if (strcmp(arg,"--diffpkg")==0){
154 }else if (strcmp(arg,"--verify")==0){
156 }else if (strcmp(arg,"--debug")==0){
165 string refserv = argv[i++];
166 string chkserv = argv[i];
167 PACKAGES refpkgs,chkpkgs;
168 // Load the package list from both vservers
169 vutil_loadallpkg (refserv,refpkgs);
170 vutil_loadallpkg (chkserv,chkpkgs);
171 PACKAGES common, differ, added, removed;
172 // Find which package are different, missing and added
174 for (PACKAGES::iterator it=refpkgs.begin(); it!=refpkgs.end(); it++){
175 PACKAGES::iterator f = find_if(chkpkgs.begin(),chkpkgs.end(),same_name(*it));
176 if (f == chkpkgs.end()){
177 removed.push_back (*it);
178 }else if (f->version != it->version){
179 differ.push_back (*it);
181 common.push_back (*it);
184 for (list<PACKAGE>::iterator it=chkpkgs.begin(); it!=chkpkgs.end(); it++){
185 list<PACKAGE>::iterator f = find_if(refpkgs.begin(),refpkgs.end(),same_name(*it));
186 if (f == refpkgs.end()){
187 added.push_back (*it);
194 bool something = false;
196 for (PACKAGES::iterator it=removed.begin(); it!=removed.end(); it++){
197 printf ("- %s\n",it->name.c_str());
199 for (PACKAGES::iterator it=added.begin(); it!=added.end(); it++){
200 printf ("+ %s\n",it->name.c_str());
202 for (PACKAGES::iterator it=differ.begin(); it!=differ.end(); it++){
203 printf ("! %s\n",it->name.c_str());
208 // We copy the rpm database from the reference vserver to
209 // the target vserver
210 string dbpath = chkserv + "/tmp/vcheck.db";
211 vcheck_deldir (dbpath);
212 if (mkdir (dbpath.c_str(),0)==-1){
213 fprintf (stderr,"Can't create directory %s (%s)\n"
214 ,dbpath.c_str(),strerror(errno));
215 }else if (vcheck_copydb (refserv,dbpath) != -1){
216 // We only compare the common package
217 string cmd = "rpm --dbpath /tmp/vcheck.db --root " + chkserv + " -V";
218 for (PACKAGES::iterator it=common.begin(); it!=common.end(); it++){
219 //printf ("compare %s\n",it->name.c_str());
220 cmd += " " + it->name;
222 if (debug) printf ("CMD: %s\n",cmd.c_str());
223 system (cmd.c_str());
225 vcheck_deldir (dbpath);
229 fprintf (stderr,"Nothing to do !!!\n\n");