added vuname
[util-vserver.git] / util-vserver / src / vunify-matchlist.c
1 // $Id$    --*- c -*--
2
3 // Copyright (C) 2003 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
19 #ifdef HAVE_CONFIG_H
20 #  include <config.h>
21 #endif
22
23 #include "vunify-matchlist.h"
24 #include "wrappers.h"
25
26 #include <fnmatch.h>
27 #include <assert.h>
28
29 bool
30 MatchList_compare(struct MatchList const *list, char const *path)
31 {
32   bool                                  res = true;
33   struct MatchItem const *              ptr = list->data;
34   struct MatchItem const * const        end_ptr = list->data + list->count;
35   
36   //write(1, path, strlen(path));
37   //write(1, "\n", 1);
38   for (; ptr<end_ptr; ++ptr) {
39     if ((ptr->cmp==0 && strcmp(ptr->name, path)==0) ||
40         (ptr->cmp!=0 && (ptr->cmp)(ptr->name, path)==0)) {
41       switch (ptr->type) {
42         case stINCLUDE  :  res = true;  break;
43         case stEXCLUDE  :  res = false; break;
44         default         :  abort();
45       }
46       break;
47     }
48   }
49
50   return res;
51 }
52
53 void
54 MatchList_init(struct MatchList *list, char const *root, size_t count)
55 {
56   list->skip_depth = 0;
57   list->root.d     = root;
58   list->root.l     = strlen(root);
59   list->data       = Emalloc(sizeof(struct MatchItem) * count);
60   list->count      = count;
61   list->buf        = 0;
62   list->buf_count  = 0;
63
64   String_init(&list->id);
65 }
66
67 static int
68 fnmatchWrap(char const *a, char const *b)
69 {
70   return fnmatch(a, b, 0);
71 }
72
73
74 static MatchItemCompareFunc
75 determineCompareFunc(char const UNUSED *fname)
76 {
77   return fnmatchWrap;
78 }
79
80 void
81 MatchList_appendFiles(struct MatchList *list, size_t idx,
82                       char **files, size_t count,
83                       bool auto_type)
84 {
85   struct MatchItem      *ptr = list->data + idx;
86   size_t                i;
87   
88   assert(idx+count <= list->count);
89
90   if (auto_type) {
91     for (i=0; i<count; ++i) {
92       char      *file = files[i];
93       switch (file[0]) {
94         case '+'        :  ptr->type = stINCLUDE; ++file; break;
95         case '-'        :  ++file; /*@fallthrough@*/
96         default         :  ptr->type = stEXCLUDE; break;
97       }
98       ptr->cmp  = determineCompareFunc(file);
99       ptr->name = file;
100       ++ptr;
101     }
102   }
103   else {
104     for (i=0; i<count; ++i) {
105       ptr->type = stEXCLUDE;
106       ptr->name = files[i];
107       ptr->cmp  = 0;
108       ++ptr;
109     }
110   }
111 }
112
113
114 void
115 PathInfo_append(PathInfo       * restrict lhs,
116                 PathInfo const * restrict rhs,
117                 char *buf)
118 {
119   char *                ptr = buf;
120   char const *          rhs_ptr = rhs->d;
121   size_t                rhs_len = rhs->l;
122
123   while (lhs->l>1 && lhs->d[lhs->l-1]=='/') --lhs->l;
124
125   if (lhs->l>0) {
126     while (rhs->l>0 && *rhs_ptr=='/') {
127       ++rhs_ptr;
128       --rhs_len;
129     }
130     
131     ptr = Xmemcpy(ptr, lhs->d, lhs->l);
132     if (ptr[-1]!='/')
133       ptr = Xmemcpy(ptr, "/", 1);
134   }
135 //  else if (*rhs_ptr!='/')
136 //    ptr = Xmemcpy(ptr, "/", 1);
137
138   ptr = Xmemcpy(ptr, rhs_ptr, rhs_len+1);
139
140   lhs->d = buf;
141   lhs->l = ptr-buf-1;
142 }
143
144 void
145 String_init(String *str)
146 {
147   str->d = 0;
148   str->l = 0;
149 }
150
151 #ifdef ENSC_TESTSUITE
152 #define CHECK(LHS,RHS, EXP)                             \
153   do {                                                  \
154     PathInfo    lhs  = { LHS, sizeof(LHS)-1 };          \
155     PathInfo    rhs  = { RHS, sizeof(RHS)-1 };          \
156     char        *buf = malloc(ENSC_PI_APPSZ(lhs,rhs));  \
157     assert(ENSC_PI_APPSZ(lhs,rhs)>=sizeof(EXP));        \
158     PathInfo_append(&lhs, &rhs, buf);                   \
159     assert(memcmp(lhs.d, EXP, sizeof(EXP))==0);         \
160     assert(lhs.l == sizeof(EXP)-1);                     \
161     free(buf);                                          \
162   } while (0)
163
164
165 void
166 PathInfo_test()
167 {
168   CHECK("/var",  "/tmp", "/var/tmp");
169   CHECK("/var",   "tmp", "/var/tmp");
170   CHECK("/var/", "/tmp", "/var/tmp");
171   CHECK("/var/",  "tmp", "/var/tmp");
172   
173   CHECK("/",  "tmp",   "/tmp");
174   CHECK("/", "/tmp",   "/tmp");
175   
176   CHECK("", "/tmp",   "/tmp");
177   
178   CHECK("", "tmp",    "tmp");
179   CHECK("", "",       "");
180 }
181 #endif