util-vserver-0.29
[util-vserver.git] / src / vutil.cc
1 // $Id: vutil.cc,v 1.1.4.2 2003/11/18 22:30:44 ensc Exp $
2
3 // Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 // based on vutil.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 #pragma implementation
21
22 #ifdef HAVE_CONFIG_H
23 #  include <config.h>
24 #endif
25 #include "compat.h"
26
27 #undef PACKAGE
28
29 #include <stdio.h>
30 #include <errno.h>
31 #include <string.h>
32 #include <sys/stat.h>
33 #include <sys/wait.h>
34 #include <fcntl.h>
35 #include <unistd.h>
36 #include <utime.h>
37 #include "vutil.h"
38 #include <sys/ioctl.h>
39
40 #include "ext2fs.h"
41
42
43 bool testmode;
44 int debug;
45
46 int file_copy (const char *src, const char *dst, struct stat &st)
47 {
48         int ret = -1;
49         FILE *fin = fopen (src,"r");
50         if (fin == NULL){
51                 fprintf (stderr,"Can't open file %s (%s)\n",src,strerror(errno));
52         }else{
53                 FILE *fout = fopen (dst,"w");
54                 if (fout == NULL){
55                         fprintf (stderr,"Can't open file %s (%s)\n",dst,strerror(errno));
56                 }else{
57                         char buf[8192];
58                         int len;
59                         while ((len=fread(buf,1,sizeof(buf),fin))>0){
60                                 fwrite (buf,1,len,fout);
61                         }
62                         fflush (fout);
63                         ret = 0;
64                         if (fchown (fileno(fout),st.st_uid,st.st_gid)==-1){
65                                 fprintf (stderr,"Can't chown file %s (%s)\n"
66                                         ,dst,strerror(errno));
67                                 ret = -1;
68                         }else if (fchmod (fileno(fout),st.st_mode)==-1){
69                                 fprintf (stderr,"Can't chmod file %s (%s)\n"
70                                         ,dst,strerror(errno));
71                                 ret = -1;
72                         }
73                         fclose(fout);
74                         struct utimbuf timbuf;
75                         timbuf.modtime = st.st_mtime;
76                         timbuf.actime = st.st_atime;
77                         if (utime (dst,&timbuf)==-1){
78                                 fprintf (stderr,"Can't set time stamp on file %s (%s)\n"
79                                         ,dst,strerror(errno));
80                         }
81                 }
82                 fclose (fin);
83         }
84         return ret;
85 }
86
87 /*
88         Set the immutable flag on a file
89 */
90 int setext2flag (const char *fname, bool set, int ext2flags)
91 {
92         int ret = -1;
93         if (testmode){
94                 ret = 0;
95         }else{
96                 int fd = open (fname,O_RDONLY);
97                 if (fd == -1){
98                         fprintf (stderr,"Can't open file %s (%s)\n",fname 
99                                 ,strerror(errno));
100                 }else{
101                         int flags = set ? ext2flags : 0;
102                         ret = ioctl (fd,EXT2_IOC_SETFLAGS,&flags);
103                         close (fd);
104                         if (ret == -1){
105                                 fprintf (stderr,"Can't %s immutable flag on file %s (%s)\n"
106                                         ,(set ? "set" : "unset")
107                                         ,fname
108                                         ,strerror(errno));
109                         }
110                 }
111         }
112         return ret;
113 }
114
115 int vbuild_mkdir (const char *path, mode_t mode)
116 {
117         int ret = -1;
118         if (testmode){
119                 printf ("mkdir %s; chmod %o %s\n",path,mode,path);
120                 ret = 0;
121         }else{
122                 ret = mkdir (path,mode);
123                 if (ret == -1 && errno == EEXIST){
124                         struct stat st;
125                         if (lstat(path,&st)!=-1 && S_ISDIR(st.st_mode)){
126                                 ret = chmod (path,mode);
127                         }
128                 }
129         }
130         return ret;
131 }
132
133 int vbuild_mknod(const char *path, mode_t mode, dev_t dev)
134 {
135         int ret = -1;
136         if (testmode){
137                 printf ("mknod %s %o %02x:%02x\n",path,mode,major(dev),minor(dev));
138                 ret = 0;
139         }else{
140                 ret = mknod (path,mode,dev);
141                 if (ret == -1 && errno == EEXIST){
142                         struct stat st;
143                         lstat(path,&st);
144                         if (lstat(path,&st)!=-1
145                                 && (st.st_mode & S_IFMT) == (mode & S_IFMT)
146                                 && st.st_rdev == dev){
147                                 ret = chmod (path,mode);
148                         }
149                 }
150         }
151         return ret;
152 }
153 int vbuild_symlink(const char *src, const char *dst)
154 {
155         int ret = -1;
156         if (testmode){
157                 printf ("ln -s %s %s\n",src,dst);
158                 ret = 0;
159         }else{
160                 ret = symlink (src,dst);
161         }
162         return ret;
163 }
164
165 int vbuild_link(const char *src, const char *dst)
166 {
167         int ret = -1;
168         if (testmode){
169                 printf ("ln %s %s\n",src,dst);
170                 ret = 0;
171         }else{
172                 ret = link (src,dst);
173         }
174         return ret;
175 }
176
177 int vbuild_unlink(const char *path)
178 {
179         int ret = -1;
180         if (testmode){
181                 printf ("unlink %s\n",path);
182                 ret = 0;
183         }else{
184                 ret = unlink (path);
185         }
186         return ret;
187 }
188
189 int vbuild_chown(const char *path, uid_t uid, gid_t gid)
190 {
191         int ret = -1;
192         if (testmode){
193                 printf ("chown %d.%d %s\n",uid,gid,path);
194                 ret = 0;
195         }else{
196                 ret = chown (path,uid,gid);
197         }
198         return ret;
199 }
200
201 int vbuild_file_copy(
202         const char *src,
203         const char *dst,
204         struct stat &st)
205 {
206         int ret = -1;
207         if (testmode){
208                 printf ("cp -a %s %s\n",src,dst);
209                 ret = 0;
210         }else{
211                 ret = file_copy (src,dst,st);
212         }
213         return ret;
214 }
215
216 /*
217         Load the list of all packages in a vserver
218 */
219 void vutil_loadallpkg (string &refserver, list<PACKAGE> &packages)
220 {
221         FILE *fin = vutil_execdistcmd (K_PKGVERSION,refserver,NULL);
222         if (fin != NULL){
223                 char line[1000];
224                 while (fgets(line,sizeof(line)-1,fin)!=NULL){
225                         int last = strlen(line)-1;
226                         if (last >= 0 && line[last] == '\n') line[last] = '\0';
227                         packages.push_back (PACKAGE(line));
228                 }
229                 pclose (fin);
230         }
231 }
232
233 int vutil_lstat (string path, struct stat &st)
234 {
235         int ret = 0;
236         if (lstat(path.c_str(),&st) == -1){
237                 fprintf (stderr,"Can't lstat file %s (%s)\n"
238                         ,path.c_str(),strerror(errno));
239                 ret = -1;
240         }
241         return ret;
242 }
243
244 const char K_PKGVERSION[]="pkgversion";
245 const char K_DUMPFILES[]="dumpfiles";
246 const char K_UNIFILES[]="unifiles";
247
248 FILE *vutil_execdistcmd (const char *key, const string &vserver, const char *args)
249 {
250         string cmd = PKGLIBDIR "/distrib-info ";
251         cmd += vserver;
252         cmd += " ";
253         cmd += key;
254         if (args != NULL){
255                 cmd += " ";
256                 cmd += args;
257         }
258         FILE *ret = popen (cmd.c_str(),"r");
259         if (ret == NULL){
260                 fprintf (stderr,"Can't execute command %s\n",cmd.c_str());
261         }else{
262                 #if 0
263                 char buf[1000];
264                 while (fgets(buf,sizeof(buf)-1,fin)!=NULL){
265                         int last = strlen(buf)-1;
266                         if (last >= 0) buf[last] = '\0';
267                         ret = buf;
268                         break;
269                 }
270                 pclose (fin);
271                 #endif
272         }
273         return ret;
274 }
275