added Vector_zeroEnd() function
[util-vserver.git] / util-vserver / src / vfiles.cc
1 // $Id$
2
3 // Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 // based on vfiles.cc by Jacques Gelinas
5 //  
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)
9 // any later version.
10 //  
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.
15 //  
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.
19
20 /*
21         This utility is used to extract the list of non unified files in
22         a vserver.
23 */
24 #ifdef HAVE_CONFIG_H
25 #  include <config.h>
26 #endif
27
28 #include <stdio.h>
29 #include <fcntl.h>
30 #include <sys/ioctl.h>
31 #include <sys/stat.h>
32 #include <unistd.h>
33 #include <errno.h>
34 #include <dirent.h>
35
36 #include <string>
37 #include <list>
38 #include <set>
39 #include "vutil.h"
40
41 using namespace std;
42
43 static bool ignorelink = false;
44
45
46 static void usage()
47 {
48         cerr <<
49                 "vfiles version " << VERSION <<
50                 "\n\n"
51                 "vfiles [ options ] reference-server vserver\n"
52                 "\n"
53                 "--debug: Prints some debugging messages.\n"
54                 "--ignorelink: Do not print symbolic links (they are never unified)\n"
55                 "\n"
56                 ;
57 }
58
59
60 static int vfiles_walk (
61         string absdir,
62         dev_t dev,                      // We stay on the same volume
63         string logical_dir,
64         set<string> &files)
65 {
66         int ret = -1;
67         if (debug > 0) printf ("Entering directory %s\n",logical_dir.c_str());
68         DIR *dir = opendir (absdir.c_str());
69         if (dir == NULL){
70                 fprintf (stderr,"Can't open directory %s (%s)\n",absdir.c_str()
71                         ,strerror(errno));
72         }else{
73                 struct dirent *ent;
74                 ret = 0;
75                 while (ret == 0 && (ent=readdir(dir))!=NULL){
76                         if (strcmp(ent->d_name,".")==0 || strcmp(ent->d_name,"..")==0){
77                                 continue;
78                         }
79                         string file = absdir + "/" + ent->d_name;
80                         struct stat st;
81                         if (vutil_lstat(file,st) == -1){
82                                 ret = -1;
83                         }else if (st.st_dev != dev){
84                                 if (debug > 0) printf ("Ignore sub-directory %s\n",file.c_str());
85                         }else{
86                                 if (S_ISDIR(st.st_mode)){
87                                         ret |= vfiles_walk (file,dev
88                                                         ,logical_dir + "/" + ent->d_name,files);
89                                 }else if (S_ISLNK(st.st_mode)){
90                                         if (!ignorelink) printf ("%s\n",file.c_str());  
91                                 }else if (S_ISBLK(st.st_mode)
92                                         || S_ISCHR(st.st_mode)
93                                         || S_ISFIFO(st.st_mode)){
94                                         printf ("%s\n",file.c_str());   
95                                 }else if (S_ISSOCK(st.st_mode)){
96                                         // Do nothing
97                                 }else{
98                                         // Ok, this is a file. We either copy it or do a link
99                                         string logical_file = logical_dir + "/" + ent->d_name;
100                                         if (files.find (logical_file)==files.end()){
101                                                 printf ("%s\n",file.c_str());   
102                                         }
103                                 }
104                         }
105                 }
106                 closedir(dir);
107         }
108         return ret;
109 }
110
111 int main (int argc, char *argv[])
112 {
113         int ret = -1;
114         int i;
115         for (i=1; i<argc; i++){
116                 const char *arg = argv[i];
117                 //const char *opt = argv[i+1];
118                 if (strcmp(arg,"--debug")==0){
119                         debug++;
120                 }else if (strcmp(arg,"--ignorelink")==0){
121                         ignorelink=true;
122                 }else{
123                         break;
124                 }
125         }
126         if (i!=argc-2){
127                 usage();
128         }else{
129                 string refserv = argv[i++];
130                 string newserv = argv[i];
131                 list<Package> packages;
132                 // Load the files which are not configuration files from
133                 // the packages
134                 vutil_loadallpkg (refserv,packages);
135                 set<string> files;
136                 for (list<Package>::iterator it=packages.begin(); it!=packages.end(); it++){
137                         (*it).loadfiles(refserv,files);
138                 }
139                 struct stat st;
140                 if (vutil_lstat(newserv,st)!=-1){
141                         // Now, we do a recursive walk of newserv and prints
142                         // all files not unifiable
143                         ret = vfiles_walk (newserv,st.st_dev,"",files);
144                 }
145         }
146         return ret;
147 }
148
149
150