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.
48 "vcheck version " << VERSION <<
50 "vcheck [ options ] reference-server chk-vservers\n"
52 "--diffpkgs: Shows which package differ.\n"
53 " + means the package only exists in chk-server.\n"
54 " - means the package does not exist in chk-server.\n"
55 " ! means the servers have different version.\n"
57 "--verify: Execute an RPM verify on common packages.\n"
58 "--debug: Turn on some (useless) debugging messages.\n"
62 typedef list<Package> PACKAGES;
65 Delete a directory silently
67 static int vcheck_deldir (const string &path)
71 if (lstat(path.c_str(),&st)==-1){
74 if (!S_ISDIR(st.st_mode)){
75 fprintf (stderr,"%s already exist and is not a directory\n"
79 DIR *d = opendir (path.c_str());
83 while ((ent=readdir(d))!=NULL){
84 if (strcmp(ent->d_name,".")!=0
85 && strcmp(ent->d_name,"..")!=0){
86 string tmp = path + "/" + ent->d_name;
87 if (unlink(tmp.c_str())==-1){
88 fprintf (stderr,"Can't delete file %s (%s)\n",tmp.c_str()
104 static int vcheck_copydb (const string &refserv, const string &path)
107 string refpath = refserv + "/var/lib/rpm";
108 DIR *d = opendir (refpath.c_str());
110 fprintf (stderr,"Can't open directory %s (%s)\n",refpath.c_str()
115 while ((ent=readdir(d))!=NULL){
116 if (strcmp(ent->d_name,".")!=0
117 && strcmp(ent->d_name,"..")!=0){
118 string srcpath = refpath + "/" + ent->d_name;
119 const char *spath = srcpath.c_str();
121 if (stat(spath,&st)!=-1){
122 string dstpath = path + "/" + ent->d_name;
123 if (file_copy (spath,dstpath.c_str(),st) == -1){
129 fprintf (stderr,"Can't stat %s (%s)\n",spath,strerror(errno));
141 int operator()(const Package &p1, const Package &p2){
142 return strcmp(p1.name.c_str(),p2.name.c_str());
147 int main (int argc, char *argv[])
150 bool diffpkg = false;
153 for (i=1; i<argc; i++){
154 const char *arg = argv[i];
155 //const char *opt = argv[i+1];
156 if (strcmp(arg,"--diffpkg")==0){
158 }else if (strcmp(arg,"--verify")==0){
160 }else if (strcmp(arg,"--debug")==0){
169 string refserv = argv[i++];
170 string chkserv = argv[i];
171 PACKAGES refpkgs,chkpkgs;
172 // Load the package list from both vservers
173 vutil_loadallpkg (refserv,refpkgs);
174 vutil_loadallpkg (chkserv,chkpkgs);
175 PACKAGES common, differ, added, removed;
176 // Find which package are different, missing and added
178 for (PACKAGES::iterator it=refpkgs.begin(); it!=refpkgs.end(); it++){
179 PACKAGES::iterator f = find_if(chkpkgs.begin(),chkpkgs.end(),same_name(*it));
180 if (f == chkpkgs.end()){
181 removed.push_back (*it);
182 }else if (f->version != it->version){
183 differ.push_back (*it);
185 common.push_back (*it);
188 for (list<Package>::iterator it=chkpkgs.begin(); it!=chkpkgs.end(); it++){
189 list<Package>::iterator f = find_if(refpkgs.begin(),refpkgs.end(),same_name(*it));
190 if (f == refpkgs.end()){
191 added.push_back (*it);
198 bool something = false;
200 for (PACKAGES::iterator it=removed.begin(); it!=removed.end(); it++){
201 printf ("- %s\n",it->name.c_str());
203 for (PACKAGES::iterator it=added.begin(); it!=added.end(); it++){
204 printf ("+ %s\n",it->name.c_str());
206 for (PACKAGES::iterator it=differ.begin(); it!=differ.end(); it++){
207 printf ("! %s\n",it->name.c_str());
212 // We copy the rpm database from the reference vserver to
213 // the target vserver
214 string dbpath = chkserv + "/tmp/vcheck.db";
215 vcheck_deldir (dbpath);
216 if (mkdir (dbpath.c_str(),0)==-1){
217 fprintf (stderr,"Can't create directory %s (%s)\n"
218 ,dbpath.c_str(),strerror(errno));
219 }else if (vcheck_copydb (refserv,dbpath) != -1){
220 // We only compare the common package
221 string cmd = "rpm --dbpath /tmp/vcheck.db --root " + chkserv + " -V";
222 for (PACKAGES::iterator it=common.begin(); it!=common.end(); it++){
223 //printf ("compare %s\n",it->name.c_str());
224 cmd += " " + it->name;
226 if (debug) printf ("CMD: %s\n",cmd.c_str());
227 system (cmd.c_str());
229 vcheck_deldir (dbpath);
233 fprintf (stderr,"Nothing to do !!!\n\n");