initial checkin
[util-vserver.git] / util-vserver / src / vhashify-init.hc
1 // $Id$    --*- c -*--
2
3 // Copyright (C) 2005 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 "pathconfig.h"
19 #include "lib_internal/util-dotfile.h"
20
21 #include <sys/param.h>
22
23 static size_t
24 initHashList(HashDirCollection *hash_vec, char const *hashdir)
25 {
26   int           cur_dir = Eopen(".", O_RDONLY|O_DIRECTORY, 0);
27   Echdir(hashdir);
28   
29   DIR           *d      = Eopendir(".");
30   struct dirent *ep;
31   size_t        l   = strlen(hashdir);
32   size_t        res = 0;
33
34   while ((ep=readdir(d)) != 0) {
35     struct stat         st;
36
37     if (isDotfile(ep->d_name) ||
38         stat(ep->d_name, &st)==-1 || !S_ISDIR(st.st_mode))
39       continue;
40
41     if (HashDirInfo_findDevice(hash_vec, st.st_dev)!=0) {
42       WRITE_MSG(2, "Duplicate hash-dir entry '");
43       WRITE_STR(2, ep->d_name);
44       WRITE_MSG(2, "' found\n");
45       continue;
46     }
47
48     char                *full_path = Emalloc(l + strlen(ep->d_name) + 3);
49     char                *ptr       = full_path + l;
50
51     memcpy(full_path, hashdir, l);
52     while (ptr>full_path && ptr[-1]=='/') --ptr;
53     *ptr++ = '/';
54     strcpy(ptr, ep->d_name);
55     strcat(ptr, "/");   // append a trailing '/'
56
57
58     struct HashDirInfo  tmp = {
59       .device  = st.st_dev,
60       .path    = { full_path, strlen(full_path) },
61     };
62
63     res = MAX(res, tmp.path.l);
64     
65     memcpy(Vector_pushback(hash_vec), &tmp, sizeof tmp);
66   }
67
68   if (Vector_count(hash_vec)==0) {
69     WRITE_MSG(2, "Could not find a place for the hashified files at '");
70     WRITE_STR(2, hashdir);
71     WRITE_MSG(2, "'.\n");
72     exit(wrapper_exit_code);
73   }
74
75   Eclosedir(d);
76   Efchdir(cur_dir);
77   Eclose(cur_dir);
78
79   return res;
80 }
81
82 static char *
83 searchHashdir(char const *lhs, char const *rhs)
84 {
85   size_t        l1  = strlen(lhs);
86   size_t        l2  = rhs ? strlen(rhs) : 0;
87   char *        res = Emalloc(l1 + l2);
88   struct stat   st;
89
90   strcpy(res, lhs);
91   if (rhs) strcat(res, rhs);
92
93   if (stat(res, &st)==-1 || !S_ISDIR(st.st_mode)) {
94     free(res);
95     res = 0;
96   }
97
98   return res;
99 }
100
101 static void
102 initModeManually(struct Arguments const UNUSED *args, int argc, char *argv[])
103 {
104   assert(args->hash_dir!=0);
105   
106   if (argc<2) {
107     WRITE_MSG(2, "No exclude list specified\n");
108     exit(1);
109   }
110
111   global_info.hash_dirs_max_size = initHashList(&global_info.hash_dirs,
112                                                 args->hash_dir);
113   MatchList_initManually(&global_info.dst_list, 0, strdup(argv[0]), argv[1]);
114 }
115
116 static void
117 initModeVserver(struct Arguments const UNUSED *args, int argc, char *argv[])
118 {
119   char const                            *appdir;
120   char const                            *hashdir   = args->hash_dir;
121   struct MatchVserverInfo const         dst_vserver = { argv[0], true };
122
123   if (argc!=1) {
124     WRITE_MSG(2, "More than one vserver is not supported\n");
125     exit(1);
126   }
127
128   if (!MatchList_initByVserver(&global_info.dst_list, &dst_vserver, &appdir)) {
129     WRITE_MSG(2, "unification not configured for this vserver\n");
130     exit(1);
131   }
132
133   if (hashdir==0) hashdir = searchHashdir(appdir, "/hash");
134   if (hashdir==0) hashdir = searchHashdir(CONFDIR "/.defaults/apps/vunify/hash", 0);
135
136   if (hashdir==0) {
137     WRITE_MSG(2, "no hash-directory configured for this vserver.\n");
138     exit(1);
139   }
140
141   global_info.hash_dirs_max_size = initHashList(&global_info.hash_dirs, hashdir);
142
143   free(const_cast(char *)(hashdir));
144   free(const_cast(char *)(appdir));
145 }
146