initial checkin
authorEnrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
Tue, 17 Feb 2004 02:33:20 +0000 (02:33 +0000)
committerEnrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
Tue, 17 Feb 2004 02:33:20 +0000 (02:33 +0000)
git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@910 94cd875c-1c1d-0410-91d2-eb244daf1a30

20 files changed:
util-vserver/lib_internal/Makefile-files [new file with mode: 0644]
util-vserver/lib_internal/matchlist-appendfiles.c [new file with mode: 0644]
util-vserver/lib_internal/matchlist-compare.c [new file with mode: 0644]
util-vserver/lib_internal/matchlist-destroy.c [new file with mode: 0644]
util-vserver/lib_internal/matchlist-init.c [new file with mode: 0644]
util-vserver/lib_internal/matchlist-initbyvserver.c [new file with mode: 0644]
util-vserver/lib_internal/matchlist-initmanually.c [new file with mode: 0644]
util-vserver/lib_internal/matchlist-initrefserverlist.c [new file with mode: 0644]
util-vserver/lib_internal/matchlist.h [new file with mode: 0644]
util-vserver/lib_internal/pathinfo-append.c [new file with mode: 0644]
util-vserver/lib_internal/pathinfo-test.c [new file with mode: 0644]
util-vserver/lib_internal/pathinfo.h [new file with mode: 0644]
util-vserver/lib_internal/string-destroy.c [new file with mode: 0644]
util-vserver/lib_internal/string.h [new file with mode: 0644]
util-vserver/lib_internal/string.hc [new file with mode: 0644]
util-vserver/lib_internal/unify-deunify.c [new file with mode: 0644]
util-vserver/lib_internal/unify-unify.c [new file with mode: 0644]
util-vserver/lib_internal/unify.h [new file with mode: 0644]
util-vserver/lib_internal/util-io.h [new file with mode: 0644]
util-vserver/lib_internal/util-mem.h [new file with mode: 0644]

diff --git a/util-vserver/lib_internal/Makefile-files b/util-vserver/lib_internal/Makefile-files
new file mode 100644 (file)
index 0000000..3399c2a
--- /dev/null
@@ -0,0 +1,43 @@
+## $Id$  -*- makefile -*-
+
+## Copyright (C) 2003,2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+##  
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2, or (at your option)
+## any later version.
+##  
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##  
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+##  
+
+lib_internal_LIBS =                    lib_internal/libinternal.a
+
+lib_internal_libinternal_a_XHDRS =     lib_internal/matchlist.h \
+                                       lib_internal/pathinfo.h \
+                                       lib_internal/string.h \
+                                       lib_internal/util-io.h \
+                                       lib_internal/util-mem.h \
+                                       lib_internal/unify.h \
+                                       lib_internal/string.hc
+
+lib_internal_libinternal_a_SOURCES =   lib_internal/matchlist-appendfiles.c \
+                                       lib_internal/matchlist-compare.c \
+                                       lib_internal/matchlist-destroy.c \
+                                       lib_internal/matchlist-init.c \
+                                       lib_internal/matchlist-initbyvserver.c \
+                                       lib_internal/matchlist-initmanually.c \
+                                       lib_internal/matchlist-initrefserverlist.c \
+                                       lib_internal/pathinfo-append.c \
+                                       lib_internal/pathinfo-test.c \
+                                       lib_internal/string-destroy.c \
+                                       lib_internal/unify-unify.c \
+                                       lib_internal/unify-deunify.c
+
+lib_internal_DIETPROGS =               $(lib_internal_LIBS)
diff --git a/util-vserver/lib_internal/matchlist-appendfiles.c b/util-vserver/lib_internal/matchlist-appendfiles.c
new file mode 100644 (file)
index 0000000..de2393a
--- /dev/null
@@ -0,0 +1,70 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//  
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//  
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include "matchlist.h"
+#include <fnmatch.h>
+#include <assert.h>
+
+static int
+fnmatchWrap(char const *a, char const *b)
+{
+  return fnmatch(a, b, 0);
+}
+
+static MatchItemCompareFunc
+determineCompareFunc(char const UNUSED *fname)
+{
+  return fnmatchWrap;
+}
+
+void
+MatchList_appendFiles(struct MatchList *list, size_t idx,
+                     char **files, size_t count,
+                     bool auto_type)
+{
+  struct MatchItem     *ptr = list->data + idx;
+  size_t               i;
+  
+  assert(idx+count <= list->count);
+
+  if (auto_type) {
+    for (i=0; i<count; ++i) {
+      char     *file = files[i];
+      switch (file[0]) {
+       case '+'        :  ptr->type = stINCLUDE; ++file; break;
+       case '-'        :  ++file; /*@fallthrough@*/
+       default         :  ptr->type = stEXCLUDE; break;
+      }
+      ptr->cmp  = determineCompareFunc(file);
+      ptr->name = file;
+      ++ptr;
+    }
+  }
+  else {
+    for (i=0; i<count; ++i) {
+      ptr->type = stEXCLUDE;
+      ptr->name = files[i];
+      ptr->cmp  = 0;
+      ++ptr;
+    }
+  }
+}
diff --git a/util-vserver/lib_internal/matchlist-compare.c b/util-vserver/lib_internal/matchlist-compare.c
new file mode 100644 (file)
index 0000000..7f15ec5
--- /dev/null
@@ -0,0 +1,48 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//  
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//  
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include "matchlist.h"
+#include <string.h>
+
+bool
+MatchList_compare(struct MatchList const *list, char const *path)
+{
+  bool                                 res = true;
+  struct MatchItem const *             ptr = list->data;
+  struct MatchItem const * const       end_ptr = list->data + list->count;
+  
+  //write(1, path, strlen(path));
+  //write(1, "\n", 1);
+  for (; ptr<end_ptr; ++ptr) {
+    if ((ptr->cmp==0 && strcmp(ptr->name, path)==0) ||
+       (ptr->cmp!=0 && (ptr->cmp)(ptr->name, path)==0)) {
+      switch (ptr->type) {
+       case stINCLUDE  :  res = true;  break;
+       case stEXCLUDE  :  res = false; break;
+       default         :  abort();
+      }
+      break;
+    }
+  }
+
+  return res;
+}
diff --git a/util-vserver/lib_internal/matchlist-destroy.c b/util-vserver/lib_internal/matchlist-destroy.c
new file mode 100644 (file)
index 0000000..626cac2
--- /dev/null
@@ -0,0 +1,37 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//  
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//  
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include "matchlist.h"
+
+void
+MatchList_destroy(struct MatchList *list)
+{
+  size_t               i;
+
+  String_destroy(&list->id);
+  free(list->data);
+
+  for (i=0; i<list->buf_count; ++i)
+    free((void *)(list->buf[i]));
+
+  free(list->buf);
+}
diff --git a/util-vserver/lib_internal/matchlist-init.c b/util-vserver/lib_internal/matchlist-init.c
new file mode 100644 (file)
index 0000000..6fe2455
--- /dev/null
@@ -0,0 +1,41 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//  
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//  
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include "matchlist.h"
+#include <string.h>
+#include <stdlib.h>
+
+#define ENSC_WRAPPERS_STDLIB   1
+#include <wrappers.h>
+void
+MatchList_init(struct MatchList *list, char const *root, size_t count)
+{
+  list->skip_depth = 0;
+  list->root.d     = root;
+  list->root.l     = strlen(root);
+  list->data       = Emalloc(sizeof(struct MatchItem) * count);
+  list->count      = count;
+  list->buf        = 0;
+  list->buf_count  = 0;
+
+  String_init(&list->id);
+}
diff --git a/util-vserver/lib_internal/matchlist-initbyvserver.c b/util-vserver/lib_internal/matchlist-initbyvserver.c
new file mode 100644 (file)
index 0000000..13b2828
--- /dev/null
@@ -0,0 +1,72 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//  
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//  
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+#include "pathconfig.h"
+
+#include "matchlist.h"
+#include "util-io.h"
+
+#include "vserver.h"
+
+
+
+bool
+MatchList_initByVserver(struct MatchList *list, char const *vserver,
+                       char const **res_appdir)
+{
+  vcCfgStyle   style;
+  char const   *vdir;
+  char const   *appdir;
+
+  style  = vc_getVserverCfgStyle(vserver);
+  vdir   = vc_getVserverVdir(  vserver, style, true);
+  appdir = vc_getVserverAppDir(vserver, style, "vunify");
+
+  if (vdir==0 || appdir==0) {
+    free((char *)appdir);
+    free((char *)vdir);
+    return false;
+  }
+
+  {
+    size_t             l1 = strlen(appdir);
+    char               tmp[l1 + sizeof("/exclude")];
+    char const *       excl_list;
+
+    memcpy(tmp,    appdir, l1);
+    memcpy(tmp+l1, "/exclude", 9);
+
+    excl_list = tmp;
+    if (access(excl_list, R_OK)==-1) excl_list = CONFDIR   "/.defaults/apps/vunify/exclude";
+    if (access(excl_list, R_OK)==-1) excl_list = PKGLIBDIR "/defaults/vunify-exclude";
+
+      // 'vdir' is transferred to matchlist and must not be free'ed here
+    MatchList_initManually(list, vserver, vdir, excl_list);
+  }
+
+  if (res_appdir!=0)
+    *res_appdir = appdir;
+  else
+    free((char *)appdir);
+  
+  return true;
+}
+
diff --git a/util-vserver/lib_internal/matchlist-initmanually.c b/util-vserver/lib_internal/matchlist-initmanually.c
new file mode 100644 (file)
index 0000000..111ab42
--- /dev/null
@@ -0,0 +1,196 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//  
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//  
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+#include "pathconfig.h"
+
+#include "matchlist.h"
+#include "util-io.h"
+
+#include <wait.h>
+#include <errno.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+#define ENSC_WRAPPERS_UNISTD   1
+#define ENSC_WRAPPERS_STDLIB   1
+#define ENSC_WRAPPERS_IO       1
+#include <wrappers.h>
+
+
+extern int     Global_getVerbosity();
+extern bool    Global_doRenew();
+
+static void
+readExcludeListFD(int fd,
+                 char ***files,  size_t *size,
+                 char **buf)
+{
+  off_t                len;
+  size_t       lines = 0;
+  char         *ptr;
+  
+  if (fd==-1) return; // todo: message on verbose?
+
+  len = Elseek(fd, 0, SEEK_END);
+  Elseek(fd, 0, SEEK_SET);
+
+  *buf = Emalloc(sizeof(*buf) * (len+1));
+  EreadAll(fd, *buf, len);
+  (*buf)[len] = '\0';
+
+  ptr = *buf;
+  while ((ptr=strchr(ptr, '\n'))) {
+    ++lines;
+    ++ptr;
+  }
+
+  ++lines;
+  *files = Emalloc(sizeof(**files) * lines);
+
+  *size = 0;
+  ptr   = *buf;
+  while (*ptr) {
+    char       *end_ptr = strchr(ptr, '\n');
+
+    assert(*size<lines);
+    if (end_ptr==0) break;
+
+    if (*ptr!='#') {
+      char     *tmp = end_ptr;
+      do {
+       *tmp-- = '\0';
+      } while (tmp>ptr && *tmp==' ');
+      
+      if (tmp>ptr) (*files)[(*size)++] = ptr;
+    }
+
+    ptr = end_ptr+1;
+  }
+}
+
+static void
+readExcludeList(char const *filename,
+               char ***files,  size_t *size,
+               char **buf)
+{
+  int          fd = open(filename, O_RDONLY);
+  if (fd==-1) return; // todo: message on verbose?
+
+  readExcludeListFD(fd, files, size, buf);
+  Eclose(fd);
+}
+
+static void
+getConfigfileList(char const *vserver,
+                 char ***files, size_t *size,
+                 char **buf)
+{
+  char                 tmpname[] = "/tmp/vunify.XXXXXX";
+  pid_t                pid;
+  int          fd = Emkstemp(tmpname);
+
+  Eunlink(tmpname);
+  pid = Efork();
+
+  if (pid==0) {
+    char       *args[10];
+    char const **ptr = (char const **)(args)+0;
+    
+    Edup2(fd, 1);
+    //Eclose(0);
+    if (fd!=1) Eclose(fd);
+
+    *ptr++  = VPKG_PROG;
+    *ptr++  = vserver;
+    *ptr++  = "get-conffiles";
+    *ptr    = 0;
+
+    Eexecv(args[0], args);
+  }
+  else {
+    int                status;
+    
+    if (TEMP_FAILURE_RETRY(wait4(pid, &status, 0,0))==-1) {
+      perror("wait4()");
+      exit(1);
+    }
+
+    if (!WIFEXITED(status) || WEXITSTATUS(status)!=0) {
+      WRITE_MSG(2, "failed to determine configfiles\n");
+      exit(1);
+    }
+
+    readExcludeListFD(fd, files, size, buf);
+    Eclose(fd);
+  }
+}
+
+void
+MatchList_initManually(struct MatchList *list, char const *vserver,
+                      char const *vdir, char const *exclude_file)
+{
+  char                 *buf[2] = { 0,0 };
+  
+  char                 **fixed_files = 0;
+  size_t               fixed_count   = 0;
+
+  char                 **expr_files  = 0;
+  size_t               expr_count    = 0;
+
+  if (Global_getVerbosity()>3) {
+    WRITE_MSG(1, "Initializing exclude-list for ");
+    WRITE_STR(1, vdir);
+    if (vserver!=0) {
+      WRITE_MSG(1, " (");
+      WRITE_STR(1, vserver);
+      WRITE_MSG(1, ")");
+    }
+    WRITE_MSG(1, "\n");
+  }
+  if (vserver && Global_doRenew()) {
+    if (Global_getVerbosity()>4)
+      WRITE_MSG(1, "  Fetching configuration-file list from packagemanagement\n");
+    getConfigfileList(vserver, &fixed_files, &fixed_count, buf+0);
+  }
+
+  // abuse special values (NULL, empty string) to skip the next step
+  if (exclude_file && *exclude_file) {
+    if (Global_getVerbosity()>4) WRITE_MSG(1, "  Reading exclude file\n");
+    readExcludeList(exclude_file,
+                   &expr_files,  &expr_count,
+                   buf+1);
+  }
+
+  MatchList_init(list, vdir, fixed_count + expr_count);
+  list->buf       = Emalloc(sizeof(void *) * 3);
+  list->buf[0]    = buf[0];
+  list->buf[1]    = buf[1];
+  list->buf[2]    = vdir;
+  list->buf_count = 3;
+
+  MatchList_appendFiles(list, 0,           fixed_files, fixed_count, false);
+  MatchList_appendFiles(list, fixed_count, expr_files,  expr_count,  true);
+
+  free(expr_files);
+  free(fixed_files);
+}
diff --git a/util-vserver/lib_internal/matchlist-initrefserverlist.c b/util-vserver/lib_internal/matchlist-initrefserverlist.c
new file mode 100644 (file)
index 0000000..f39a98b
--- /dev/null
@@ -0,0 +1,82 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//  
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//  
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include "matchlist.h"
+#include "util-io.h"
+
+#include <dirent.h>
+#include <string.h>
+#include <fcntl.h>
+
+#define ENSC_WRAPPERS_FCNTL    1
+#define ENSC_WRAPPERS_UNISTD   1
+#define ENSC_WRAPPERS_STDLIB   1
+#include <wrappers.h>
+
+static int
+selectRefserver(struct dirent const *ent)
+{
+  return strncmp(ent->d_name, "refserver.", 10)==0;
+}
+
+void
+MatchList_initRefserverList(struct MatchList **lst, size_t *cnt,
+                           char const *dir)
+{
+  int                  cur_dir = Eopen(".", O_RDONLY, 0);
+  struct dirent                **entries;
+  int                  count,i;
+  
+  Echdir(dir);
+  count = scandir(".", &entries, selectRefserver, alphasort);
+  if (count==-1) {
+    perror("scandir()");
+    exit(1);
+  }
+
+  if (count==0) {
+    WRITE_MSG(2, "no reference vserver configured\n");
+    exit(1);
+  }
+
+  *lst = Emalloc(sizeof(struct MatchList) * count);
+  *cnt = count;
+  for (i=0; i<count; ++i) {
+    char const                 *tmp   = entries[i]->d_name;
+    size_t             l      = strlen(tmp);
+    char               vname[sizeof("./") + l];
+
+    memcpy(vname,   "./", 2);
+    memcpy(vname+2, tmp,  l+1);
+    
+    if (!MatchList_initByVserver((*lst)+i, vname, 0)) {
+      WRITE_MSG(2, "unification for reference vserver not configured\n");
+      exit(1);
+    }
+
+    free(entries[i]);
+  }
+  free(entries);
+
+  Efchdir(cur_dir);
+  Eclose(cur_dir);
+}
diff --git a/util-vserver/lib_internal/matchlist.h b/util-vserver/lib_internal/matchlist.h
new file mode 100644 (file)
index 0000000..0cbf907
--- /dev/null
@@ -0,0 +1,71 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//  
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//  
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#ifndef H_UTIL_VSERVER_LIB_INTERNAL_MATCHLIST_H
+#define H_UTIL_VSERVER_LIB_INTERNAL_MATCHLIST_H
+
+#include "pathinfo.h"
+#include "string.h"
+
+#include <stdlib.h>
+#include <stdbool.h>
+
+typedef int    (*MatchItemCompareFunc)(char const *, char const *);
+
+struct MatchItem
+{
+    enum { stINCLUDE, stEXCLUDE }      type;
+    char const *                       name;
+    MatchItemCompareFunc               cmp;
+};
+
+struct MatchList
+{
+    size_t             skip_depth;
+    PathInfo           root;
+    String             id;
+    struct MatchItem   *data;
+    size_t             count;
+
+    void const         **buf;
+    size_t             buf_count;
+};
+
+void           MatchList_init(struct MatchList *, char const *root,
+                              size_t count) NONNULL((1,2));
+bool           MatchList_initByVserver(struct MatchList *,
+                                       char const *vserver,
+                                       char const **res_appdir) NONNULL((1,2));
+void           MatchList_initManually(struct MatchList *list,
+                                      char const *vserver,
+                                      char const *vdir,
+                                      char const *exclude_file) NONNULL((1,3,4));
+void           MatchList_initRefserverList(struct MatchList **, size_t *cnt,
+                                           char const *dir) NONNULL((1,2,3));
+void           MatchList_destroy(struct MatchList *) NONNULL((1));
+void           MatchList_appendFiles(struct MatchList *, size_t idx,
+                                     char **files, size_t count,
+                                     bool auto_type) NONNULL((1,3));
+
+bool           MatchList_compare(struct MatchList const *,
+                                 char const *path) NONNULL((1,2));
+struct MatchItem
+const *                MatchList_find(struct MatchList const *,
+                              char const *path) NONNULL((1,2));
+
+#endif //  H_UTIL_VSERVER_LIB_INTERNAL_MATCHLIST_H
diff --git a/util-vserver/lib_internal/pathinfo-append.c b/util-vserver/lib_internal/pathinfo-append.c
new file mode 100644 (file)
index 0000000..c4cf941
--- /dev/null
@@ -0,0 +1,54 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//  
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//  
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include "pathinfo.h"
+#include "util-mem.h"
+
+void
+PathInfo_append(PathInfo       * restrict lhs,
+               PathInfo const * restrict rhs,
+               char *buf)
+{
+  char *               ptr = buf;
+  char const *         rhs_ptr = rhs->d;
+  size_t               rhs_len = rhs->l;
+
+  while (lhs->l>1 && lhs->d[lhs->l-1]=='/') --lhs->l;
+
+  if (lhs->l>0) {
+    while (rhs->l>0 && *rhs_ptr=='/') {
+      ++rhs_ptr;
+      --rhs_len;
+    }
+    
+    ptr = Xmemcpy(ptr, lhs->d, lhs->l);
+    if (ptr[-1]!='/')
+      ptr = Xmemcpy(ptr, "/", 1);
+  }
+//  else if (*rhs_ptr!='/')
+//    ptr = Xmemcpy(ptr, "/", 1);
+
+  ptr = Xmemcpy(ptr, rhs_ptr, rhs_len+1);
+
+  lhs->d = buf;
+  lhs->l = ptr-buf-1;
+}
diff --git a/util-vserver/lib_internal/pathinfo-test.c b/util-vserver/lib_internal/pathinfo-test.c
new file mode 100644 (file)
index 0000000..122d4f6
--- /dev/null
@@ -0,0 +1,55 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//  
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//  
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include "pathinfo.h"
+#include <string.h>
+#include <assert.h>
+
+#define CHECK(LHS,RHS, EXP)                            \
+  do {                                                 \
+    PathInfo   lhs  = { LHS, sizeof(LHS)-1 };          \
+    PathInfo   rhs  = { RHS, sizeof(RHS)-1 };          \
+    char       *buf = malloc(ENSC_PI_APPSZ(lhs,rhs));  \
+    assert(ENSC_PI_APPSZ(lhs,rhs)>=sizeof(EXP));       \
+    PathInfo_append(&lhs, &rhs, buf);                  \
+    assert(memcmp(lhs.d, EXP, sizeof(EXP))==0);                \
+    assert(lhs.l == sizeof(EXP)-1);                    \
+    free(buf);                                         \
+  } while (0)
+
+
+void
+PathInfo_test()
+{
+  CHECK("/var",  "/tmp", "/var/tmp");
+  CHECK("/var",   "tmp", "/var/tmp");
+  CHECK("/var/", "/tmp", "/var/tmp");
+  CHECK("/var/",  "tmp", "/var/tmp");
+  
+  CHECK("/",  "tmp",   "/tmp");
+  CHECK("/", "/tmp",   "/tmp");
+  
+  CHECK("", "/tmp",   "/tmp");
+  
+  CHECK("", "tmp",    "tmp");
+  CHECK("", "",       "");
+}
diff --git a/util-vserver/lib_internal/pathinfo.h b/util-vserver/lib_internal/pathinfo.h
new file mode 100644 (file)
index 0000000..7ddaba5
--- /dev/null
@@ -0,0 +1,32 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//  
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//  
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#ifndef H_UTIL_VSERVER_LIB_INTERNAL_PATHINFO_H
+#define H_UTIL_VSERVER_LIB_INTERNAL_PATHINFO_H
+
+#include "string.h"
+
+#define ENSC_PI_APPSZ(P1,P2)   ((P1).l + sizeof("/") + (P2).l)
+
+typedef String         PathInfo;
+
+void           PathInfo_append(PathInfo * restrict,
+                               PathInfo const * restrict,
+                               char *buf) NONNULL((1,2,3));
+
+#endif //  H_UTIL_VSERVER_LIB_INTERNAL_PATHINFO_H
diff --git a/util-vserver/lib_internal/string-destroy.c b/util-vserver/lib_internal/string-destroy.c
new file mode 100644 (file)
index 0000000..517056f
--- /dev/null
@@ -0,0 +1,29 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//  
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//  
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include "string.h"
+
+void
+String_destroy(String *str)
+{
+  free((char *)(str->d));
+}
diff --git a/util-vserver/lib_internal/string.h b/util-vserver/lib_internal/string.h
new file mode 100644 (file)
index 0000000..81b3e73
--- /dev/null
@@ -0,0 +1,35 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//  
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//  
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#ifndef H_UTIL_VSERVER_LIB_INTERNAL_STRING_H
+#define H_UTIL_VSERVER_LIB_INTERNAL_STRING_H
+
+#include <stdlib.h>
+
+typedef struct
+{
+    char const *       d;
+    size_t             l;
+} String;
+
+static void    String_init(String *);
+void           String_destroy(String *);
+
+#include "string.hc"
+
+#endif //  H_UTIL_VSERVER_LIB_INTERNAL_STRING_H
diff --git a/util-vserver/lib_internal/string.hc b/util-vserver/lib_internal/string.hc
new file mode 100644 (file)
index 0000000..251d597
--- /dev/null
@@ -0,0 +1,23 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//  
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//  
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+static inline UNUSED void
+String_init(String *str)
+{
+  str->d = 0;
+  str->l = 0;
+}
diff --git a/util-vserver/lib_internal/unify-deunify.c b/util-vserver/lib_internal/unify-deunify.c
new file mode 100644 (file)
index 0000000..a942aab
--- /dev/null
@@ -0,0 +1,126 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//  
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//  
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include "unify.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <utime.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#define ENSC_WRAPPERS_IO       1
+#include <wrappers.h>
+
+bool
+Unify_deUnify(char const UNUSED *src, struct stat const UNUSED *src_stat,
+             char const *dst,        struct stat const UNUSED *dst_stat)
+{
+  size_t               l = strlen(dst);
+  char                 tmpfile[l + sizeof(";XXXXXX")];
+  int                  fd_src, fd_tmp;
+  struct stat          st;
+  struct utimbuf       utm;
+
+  fd_src = open(dst, O_RDONLY);
+  if (fd_src==-1) {
+    perror("open()");
+    return false;
+  }
+
+  if (fstat(fd_src, &st)==-1) {
+    perror("fstat()");
+    close(fd_src);
+    return false;
+  }
+  
+  memcpy(tmpfile,   dst, l);
+  memcpy(tmpfile+l, ";XXXXXX", 8);
+  fd_tmp = mkstemp(tmpfile);
+
+  if (fd_tmp==-1) {
+    perror("mkstemp()");
+    tmpfile[0] = '\0';
+    goto err;
+  }
+
+  if (fchown(fd_tmp, st.st_uid, st.st_gid)==-1 ||
+      fchmod(fd_tmp, st.st_mode)==-1) {
+    perror("fchown()/fchmod()");
+    goto err;
+  }
+
+  // todo: acl?
+
+  for (;;) {
+    char       buf[0x4000];
+    ssize_t    len = read(fd_src, buf, sizeof buf);
+    if (len==-1) {
+      perror("read()");
+      goto err;
+    }
+    if (len==0) break;
+
+    if (!WwriteAll(fd_tmp, buf, len)) goto err;
+  }
+
+  if (close(fd_src)==-1) {
+    perror("close()");
+    goto err;
+  }
+  if (close(fd_tmp)==-1) {
+    perror("close()");
+    goto err;
+  }
+  
+  utm.actime  = st.st_atime;
+  utm.modtime = st.st_mtime;
+
+  // ALERT: race !!!
+  if (utime(tmpfile, &utm)==-1) {
+    perror("utime()");
+    goto err1;
+  }
+
+  if (unlink(dst)==-1) {
+    perror("unlink()");
+    goto err1;
+  }
+  
+  // ALERT: race !!!
+  if (rename(tmpfile, dst)==-1) {
+    perror("FATAL error in rename()");
+    _exit(1);
+  }
+
+  return true;
+  
+  err:
+  close(fd_src);
+  close(fd_tmp);
+  err1:
+  if (tmpfile[0]) unlink(tmpfile);
+
+  return false;
+}
diff --git a/util-vserver/lib_internal/unify-unify.c b/util-vserver/lib_internal/unify-unify.c
new file mode 100644 (file)
index 0000000..6423f58
--- /dev/null
@@ -0,0 +1,82 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//  
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//  
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include "unify.h"
+#include "vserver.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+bool
+Unify_unify(char const *src, struct stat const *src_stat,
+           char const *dst, struct stat const UNUSED *dst_stat)
+{
+  size_t       l = strlen(dst);
+  char         tmpfile[l + sizeof(";XXXXXX")];
+  int          fd;
+  bool         res = false;
+
+  // at first, set the ILI flags on 'src'
+  if (vc_set_iattr_compat(src, src_stat->st_dev, src_stat->st_ino,
+                         0, VC_IATTR_IUNLINK, VC_IATTR_IUNLINK,
+                         &src_stat->st_mode)==-1)
+    return false;
+
+  // now, create a temporary filename
+  memcpy(tmpfile,   dst, l);
+  memcpy(tmpfile+l, ";XXXXXX", 8);
+  fd = mkstemp(tmpfile);
+  close(fd);
+
+  if (fd==-1) {
+    perror("mkstemp()");
+    return false;
+  }
+
+  // and rename the old file to this name
+  if (rename(dst, tmpfile)==-1) {
+    perror("rename()");
+    goto err;
+  }
+
+  // now, link the src-file to dst
+  if (link(src, dst)==-1) {
+    perror("link()");
+
+    unlink(dst);
+    if (rename(tmpfile, dst)==-1) {
+      perror("FATAL error in rename()");
+      _exit(1);
+    }
+    goto err;
+  }
+
+  res = true;
+
+  err:
+  unlink(tmpfile);
+
+  return res;
+}
diff --git a/util-vserver/lib_internal/unify.h b/util-vserver/lib_internal/unify.h
new file mode 100644 (file)
index 0000000..6498d3f
--- /dev/null
@@ -0,0 +1,49 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//  
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//  
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#ifndef H_UTIL_VSERVER_LIB_INTERNAL_UNIFY_H
+#define H_UTIL_VSERVER_LIB_INTERNAL_UNIFY_H
+
+#include <stdbool.h>
+
+struct stat;
+
+bool
+Unify_unify(char const *src, struct stat const *src_stat,
+           char const *dst, struct stat const *dst_stat) NONNULL((1,2,3,4));
+
+bool
+Unify_deUnify(char const *src, struct stat const *src_stat,
+             char const *dst, struct stat const *dst_stat) NONNULL((1,2,3,4));
+
+
+#define        Unify_isUnified(LHS, RHS)               \
+  ((bool)((LHS)->st_dev ==(RHS)->st_dev  &&    \
+         (LHS)->st_ino ==(RHS)->st_ino))
+
+#define Unify_isUnifyable(LHS, RHS)            \
+  ((bool)((LHS)->st_dev  ==(RHS)->st_dev  &&   \
+         (LHS)->st_ino  !=(RHS)->st_ino  &&    \
+         (LHS)->st_mode ==(RHS)->st_mode &&    \
+         (LHS)->st_uid  ==(RHS)->st_uid  &&    \
+         (LHS)->st_gid  ==(RHS)->st_gid  &&    \
+         (LHS)->st_size ==(RHS)->st_size &&    \
+         (LHS)->st_mtime==(RHS)->st_mtime))
+  
+
+#endif //  H_UTIL_VSERVER_LIB_INTERNAL_UNIFY_H
diff --git a/util-vserver/lib_internal/util-io.h b/util-vserver/lib_internal/util-io.h
new file mode 100644 (file)
index 0000000..d4519e7
--- /dev/null
@@ -0,0 +1,35 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//  
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//  
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#ifndef H_UTIL_VSERVER_LIB_INTERNAL_UTIL_IO_H
+#define H_UTIL_VSERVER_LIB_INTERNAL_UTIL_IO_H
+
+#include <unistd.h>
+#include <string.h>
+
+inline static void UNUSED
+writeStr(int fd, char const *cmd)
+{
+  (void)write(fd, cmd, strlen(cmd));
+}
+
+#define WRITE_MSG(FD,X)                (void)(write(FD,X,sizeof(X)-1))
+#define WRITE_STR(FD,X)                writeStr(FD,X)
+
+
+#endif //  H_UTIL_VSERVER_LIB_INTERNAL_UTIL_IO_H
diff --git a/util-vserver/lib_internal/util-mem.h b/util-vserver/lib_internal/util-mem.h
new file mode 100644 (file)
index 0000000..6ed98a0
--- /dev/null
@@ -0,0 +1,31 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+//  
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//  
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//  
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#ifndef H_UTIL_VSERVER_LIB_INTERNAL_UTIL_MEM_H
+#define H_UTIL_VSERVER_LIB_INTERNAL_UTIL_MEM_H
+
+#include <string.h>
+
+inline static void *
+Xmemcpy(void * restrict dst, void const * restrict src, size_t len)
+{
+  memcpy(dst, src, len);
+  return (char *)(dst)+len;
+}
+
+#endif //  H_UTIL_VSERVER_LIB_INTERNAL_UTIL_MEM_H