initial checkin
[util-vserver.git] / util-vserver / lib / createskeleton-full.hc
1 // $Id$    --*- c -*--
2
3 // Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 //  
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; version 2 of the License.
8 //  
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //  
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23
24 #define CONCAT_TWO_ARGS(BUF, LHS,RHS)                   \
25   size_t                BUF ## l1 = strlen(LHS);        \
26   size_t                BUF ## l2 = strlen(RHS);        \
27   char                  BUF[BUF ## l1 + BUF ## l2 + 2]; \
28                                                         \
29   memcpy(BUF,      LHS, BUF ## l1 + 1);                 \
30   if (BUF ## l2>0) {                                    \
31     memcpy(BUF+BUF ## l1,   "/", BUF ## l1);            \
32     memcpy(BUF+BUF ## l1+1, RHS, BUF ## l2+1);          \
33   }
34
35 static inline int
36 mkdir2(char const *lhs, char const *rhs, int mode)
37 {
38   CONCAT_TWO_ARGS(buf, lhs, rhs);
39   return mkdir(buf, mode);
40 }
41
42 static inline int
43 setIAttr2(char const *lhs, char const *rhs, int flags)
44 {
45   struct stat           st;
46   CONCAT_TWO_ARGS(buf, lhs, rhs);
47
48   if (stat(buf, &st)==-1) return -1;
49   return vc_set_iattr_compat(buf, st.st_dev, st.st_ino,
50                              0, flags, VC_IMMUTABLE_ALL, 0);
51 }
52
53 static inline int
54 symlink2(char const *old_lhs, char const *old_rhs,
55          char const *new_lhs, char const *new_rhs)
56 {
57   CONCAT_TWO_ARGS(old_buf, old_lhs, old_rhs);
58
59   {
60     CONCAT_TWO_ARGS(new_buf, new_lhs, new_rhs);
61     return symlink(old_buf, new_buf);
62   }
63 }
64
65 #undef CONCAT_TWO_ARGS
66
67 static inline int
68 vc_createSkeleton_full(char const *id, char const *name, int flags)
69 {
70   if (mkdir(id, 0755)==-1) return -1;
71
72   if (mkdir2(id, "apps", 0755)==-1 ||
73       ((flags&vcSKEL_INTERFACES) && mkdir2(id, "interfaces", 755)==-1) ||
74       ((flags&vcSKEL_PKGMGMT) && (
75         mkdir2(id, "apps/pkgmgmt", 0755)==-1)))
76     return -1;
77
78   for (;;) {
79     char const  *basedir = CONFDIR "/.defaults/run.rev";
80
81     if (!utilvserver_isDirectory(basedir, true)) basedir = DEFAULT_PKGSTATEREVDIR;
82     if (!utilvserver_isDirectory(basedir, true)) break;
83
84     if (symlink2(basedir, "", id, "run.rev")==-1)
85       return -1;
86
87     break;
88   }
89
90   for (;;) {
91     char const  *basedir = CONFDIR "/.defaults/run";
92
93     if (!utilvserver_isDirectory(basedir, true)) basedir = DEFAULT_PKGSTATEDIR;
94     if (!utilvserver_isDirectory(basedir, true)) break;
95
96     if (symlink2(basedir, name, id, "run")==-1)
97       return -1;
98
99     break;
100   }
101   
102   while (flags&vcSKEL_PKGMGMT) {
103     char const  *basedir = CONFDIR "/.defaults/apps/pkgmgmt/base";
104
105     if (!utilvserver_isDirectory(basedir, true)) basedir = DEFAULT_VSERVERPKGDIR;
106     if (!utilvserver_isDirectory(basedir, true)) break;
107
108     if (mkdir2(basedir, name, 0755)==-1 ||
109         symlink2(basedir, name, id, "apps/pkgmgmt/base")==-1)
110       return -1;
111
112     break;
113   }
114
115   while (flags&vcSKEL_FILESYSTEM) {
116     char const  *basedir = CONFDIR "/.defaults/vdirbase";
117
118     if (!utilvserver_isDirectory(basedir, true)) basedir = DEFAULT_VSERVERDIR;
119     if (!utilvserver_isDirectory(basedir, true)) break;
120
121     if (mkdir2(basedir, name, 0755)==-1 ||
122         setIAttr2(basedir, name, 0)==-1 ||
123         symlink2(basedir, name, id, "vdir")==-1)
124       return -1;
125
126     break;
127   }
128
129   return 0;
130 }