initial checkin
authorEnrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
Fri, 16 Jan 2004 18:00:11 +0000 (18:00 +0000)
committerEnrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
Fri, 16 Jan 2004 18:00:11 +0000 (18:00 +0000)
git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@611 94cd875c-1c1d-0410-91d2-eb244daf1a30

util-vserver/lib/getvserverappdir.c [new file with mode: 0644]
util-vserver/lib/getvservercfgdir.c [new file with mode: 0644]
util-vserver/lib/isdirectory.c [new file with mode: 0644]
util-vserver/scripts/legacy/.cvsignore [new file with mode: 0644]
util-vserver/src/vunify-debug.c [new file with mode: 0644]
util-vserver/src/vunify-init.ic [new file with mode: 0644]
util-vserver/src/vunify.h [new file with mode: 0644]
util-vserver/src/wrappers-io.h [new file with mode: 0644]

diff --git a/util-vserver/lib/getvserverappdir.c b/util-vserver/lib/getvserverappdir.c
new file mode 100644 (file)
index 0000000..71e2c07
--- /dev/null
@@ -0,0 +1,73 @@
+// $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 "vserver.h"
+#include "internal.h"
+#include "pathconfig.h"
+
+#include <string.h>
+
+char *
+vc_getVserverAppDir(char const *id, vcCfgStyle style, char const *app)
+{
+  size_t               l1   = strlen(id);
+  size_t               l2   = strlen(app);
+  char                 *res = 0;
+
+  if (style==vcCFG_NONE || style==vcCFG_AUTO)
+    style = vc_getVserverCfgStyle(id);
+
+  switch (style) {
+    case vcCFG_NONE            :  return 0;
+    case vcCFG_LEGACY          :  return 0;
+    case vcCFG_RECENT_FULL     :
+    case vcCFG_RECENT_SHORT    :
+    {
+      char             buf[sizeof(CONFDIR) + l1 + l2 + sizeof("//apps/") - 1];
+      char *           ptr = buf;
+
+      if (style==vcCFG_RECENT_FULL)
+       memcpy(ptr, id, l1);
+      else {
+       memcpy(ptr, CONFDIR "/", sizeof(CONFDIR "/")-1);
+       ptr += sizeof(CONFDIR "/")-1;
+       memcpy(ptr, id, l1);      
+      }
+      
+      ptr += l1;
+      memcpy(ptr, "/apps/", 6); ptr += 6;
+      memcpy(ptr, app,     l2); ptr += l2;
+      *ptr = '\0';
+      
+      res = strdup(buf);
+      break;
+    }
+    default                    :  return 0;
+  }
+
+  if (!utilvserver_isDirectory(res, true)) {
+    free(res);
+    res = 0;
+  }
+
+  return res;
+}
diff --git a/util-vserver/lib/getvservercfgdir.c b/util-vserver/lib/getvservercfgdir.c
new file mode 100644 (file)
index 0000000..b846d73
--- /dev/null
@@ -0,0 +1,61 @@
+// $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 "vserver.h"
+#include "internal.h"
+#include "pathconfig.h"
+
+#include <string.h>
+
+char *
+vc_getVserverCfgDir(char const *id, vcCfgStyle style)
+{
+  size_t               l1   = strlen(id);
+  char                 *res = 0;
+
+  if (style==vcCFG_NONE || style==vcCFG_AUTO)
+    style = vc_getVserverCfgStyle(id);
+
+  switch (style) {
+    case vcCFG_NONE            :  return 0;
+    case vcCFG_LEGACY          :  return 0;
+    case vcCFG_RECENT_FULL     :  res = strdup(id); break;
+    case vcCFG_RECENT_SHORT    :
+    {
+      char             buf[sizeof(CONFDIR) + l1 + sizeof("/") - 1];
+
+      strcpy(buf,                            CONFDIR "/");
+      strcpy(buf+sizeof(CONFDIR "/")    - 1, id);
+      
+      res = strdup(buf);
+      break;
+    }
+    default                    :  return 0;
+  }
+
+  if (!utilvserver_isDirectory(res, true)) {
+    free(res);
+    res = 0;
+  }
+
+  return res;
+}
diff --git a/util-vserver/lib/isdirectory.c b/util-vserver/lib/isdirectory.c
new file mode 100644 (file)
index 0000000..bfe0f35
--- /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 "internal.h"
+
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+bool
+utilvserver_isDirectory(char const *path, bool follow_link)
+{
+  struct stat          st;
+  if ( ( follow_link &&  stat(path, &st)==-1) ||
+       (!follow_link && lstat(path, &st)==-1) ) return false;
+
+  return S_ISDIR(st.st_mode);
+}
diff --git a/util-vserver/scripts/legacy/.cvsignore b/util-vserver/scripts/legacy/.cvsignore
new file mode 100644 (file)
index 0000000..9acb2e2
--- /dev/null
@@ -0,0 +1,2 @@
+.vps.pathsubst.stamp
+vps
diff --git a/util-vserver/src/vunify-debug.c b/util-vserver/src/vunify-debug.c
new file mode 100644 (file)
index 0000000..f84704c
--- /dev/null
@@ -0,0 +1,43 @@
+// $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 "vunify-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(list->buf[i]);
+
+  free(list->buf);
+}
+
+void
+String_destroy(String *str)
+{
+  free(const_cast(char *)(str->d));
+}
diff --git a/util-vserver/src/vunify-init.ic b/util-vserver/src/vunify-init.ic
new file mode 100644 (file)
index 0000000..9757e14
--- /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.
+
+#include "wrappers-io.h"
+#include "pathconfig.h"
+
+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);
+}
+
+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++  = PKGMGMT_INFO_PROG;
+    *ptr++  = vserver;
+    *ptr++  = "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);
+  }
+}
+
+static void
+initMatchList(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 (vserver && global_args->do_renew) {
+    getConfigfileList(vserver, &fixed_files, &fixed_count, buf+0);
+  }
+
+  // abuse special values (NULL, empty string) to skip the next step
+  if (exclude_file && *exclude_file) {
+    readExcludeList(exclude_file,
+                   &expr_files,  &expr_count,
+                   buf+1);
+  }
+
+  MatchList_init(list, vdir, fixed_count + expr_count);
+  list->buf       = Emalloc(sizeof(void *) * 2);
+  list->buf[0]    = buf[0];
+  list->buf[1]    = buf[1];
+  list->buf_count = 2;
+
+  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);
+}
+
+static bool
+initMatchListByVserver(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);
+  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               excl_list[l1 + sizeof("/exclude")];
+
+    memcpy(excl_list,    appdir, l1);
+    memcpy(excl_list+l1, "/exclude", 9);
+    
+      // 'vdir' is transferred to matchlist and must not be free'ed here
+    initMatchList(list, vserver, vdir, excl_list);
+  }
+
+  if (res_appdir!=0)
+    *res_appdir = appdir;
+  else
+    free((char *)appdir);
+  
+  return true;
+}
diff --git a/util-vserver/src/vunify.h b/util-vserver/src/vunify.h
new file mode 100644 (file)
index 0000000..3a404df
--- /dev/null
@@ -0,0 +1,53 @@
+// $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_SRC_VUNIFY_H
+#define H_UTIL_VSERVER_SRC_VUNIFY_H
+
+#include "vunify-matchlist.h"
+
+struct dirent;
+struct WalkdownInfo
+{
+    PathInfo                   state;
+    struct MatchList           dst_list;
+    struct {
+       struct MatchList *      v;
+       size_t                  l;
+    }                          src_lists;
+};
+
+static void    visitDirEntry(struct dirent const *) NONNULL((1));
+static void    visitDir(char const *, struct stat const *) NONNULL((1));
+static bool    checkFstat(struct MatchList const * const,
+                          PathInfo const * const,
+                          PathInfo const * const,
+                          struct stat const ** const,
+                          struct stat * const) NONNULL((1,2,3,4,5));
+
+static struct MatchList const *
+checkDirEntry(PathInfo const *,
+             PathInfo const *,
+             bool *, struct stat *) NONNULL((1,2,3,4));
+
+static bool    updateSkipDepth(PathInfo const *, bool) NONNULL((1));
+static void    EsafeChdir(char const *, struct stat const *)  NONNULL((1,2));
+static bool    doit(struct MatchList const *, PathInfo const *,
+                    char const *dst_path) NONNULL((1,2,3));
+
+#endif //  H_UTIL_VSERVER_SRC_VUNIFY_H
diff --git a/util-vserver/src/wrappers-io.h b/util-vserver/src/wrappers-io.h
new file mode 100644 (file)
index 0000000..b82a806
--- /dev/null
@@ -0,0 +1,172 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2003 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_VSERVER_DJINNI_SRC_WRAPPERS_IO_H
+#define H_VSERVER_DJINNI_SRC_WRAPPERS_IO_H
+
+#include "wrappers.h"
+
+#ifdef UTILVSERVER_ENABLE_SOCKET_WRAPPERS
+inline static UNUSED bool
+WsendAll(int fd, void const *ptr_v, size_t len)
+{
+  register char const  *ptr = ptr_v;
+
+  while (len>0) {
+    size_t     res = TEMP_FAILURE_RETRY(send(fd, ptr, len, MSG_NOSIGNAL));
+    if (res==(size_t)-1) {
+      perror("send()");
+      return false;
+    }
+
+    if (res==0) return false;
+
+    ptr += res;
+    len -= res;
+  }
+  return true;
+}
+
+inline static UNUSED void
+EsendAll(int fd, void const *ptr_v, size_t len)
+{
+  register char const  *ptr = ptr_v;
+
+  while (len>0) {
+    size_t     res = TEMP_FAILURE_RETRY(send(fd, ptr, len, MSG_NOSIGNAL));
+    FatalErrnoError(res==(size_t)-1, "send()");
+
+    ptr += res;
+    len -= res;
+  }
+}
+
+
+inline static UNUSED bool
+WrecvAll(int fd, void *ptr_v, size_t len)
+{
+  register char        *ptr = ptr_v;
+  
+  while (len>0) {
+    size_t     res = TEMP_FAILURE_RETRY(recv(fd, ptr, len, MSG_NOSIGNAL));
+    if (res==(size_t)-1) {
+      perror("recv()");
+      return false;
+    }
+
+    if (res==0) return false;
+
+    ptr += res;
+    len -= res;
+  }
+  return true;
+}
+
+inline static UNUSED bool
+ErecvAll(int fd, void *ptr_v, size_t len)
+{
+  register char        *ptr = ptr_v;
+  
+  while (len>0) {
+    size_t     res = TEMP_FAILURE_RETRY(recv(fd, ptr, len, MSG_NOSIGNAL));
+    FatalErrnoError(res==(size_t)-1, "recv()");
+
+    if (res==0) return false;
+
+    ptr += res;
+    len -= res;
+  }
+
+  return true;
+}
+#endif
+
+inline static UNUSED bool
+WwriteAll(int fd, void const *ptr_v, size_t len)
+{
+  register char const  *ptr = ptr_v;
+
+  while (len>0) {
+    size_t     res = TEMP_FAILURE_RETRY(write(fd, ptr, len));
+    if (res==(size_t)-1) {
+      perror("write()");
+      return false;
+    }
+
+    if (res==0) return false;
+
+    ptr += res;
+    len -= res;
+  }
+  return true;
+}
+
+inline static UNUSED void
+EwriteAll(int fd, void const *ptr_v, size_t len)
+{
+  register char const  *ptr = ptr_v;
+
+  while (len>0) {
+    size_t     res = TEMP_FAILURE_RETRY(write(fd, ptr, len));
+    FatalErrnoError(res==(size_t)-1, "write()");
+
+    ptr += res;
+    len -= res;
+  }
+}
+
+
+inline static UNUSED bool
+WreadAll(int fd, void *ptr_v, size_t len)
+{
+  register char        *ptr = ptr_v;
+  
+  while (len>0) {
+    size_t     res = TEMP_FAILURE_RETRY(read(fd, ptr, len));
+    if (res==(size_t)-1) {
+      perror("read()");
+      return false;
+    }
+
+    if (res==0) return false;
+
+    ptr += res;
+    len -= res;
+  }
+  return true;
+}
+
+inline static UNUSED bool
+EreadAll(int fd, void *ptr_v, size_t len)
+{
+  register char        *ptr = ptr_v;
+  
+  while (len>0) {
+    size_t     res = TEMP_FAILURE_RETRY(read(fd, ptr, len));
+    FatalErrnoError(res==(size_t)-1, "read()");
+
+    if (res==0) return false;
+
+    ptr += res;
+    len -= res;
+  }
+
+  return true;
+}
+
+#endif //  H_VSERVER_DJINNI_SRC_WRAPPERS_IO_H