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