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