From 5269e9607d89ac4dbd34f9adb5b14fb5dfc9b1a5 Mon Sep 17 00:00:00 2001 From: Enrico Scholz Date: Tue, 17 Feb 2004 02:33:20 +0000 Subject: [PATCH] initial checkin git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@910 94cd875c-1c1d-0410-91d2-eb244daf1a30 --- util-vserver/lib_internal/Makefile-files | 43 +++++ util-vserver/lib_internal/matchlist-appendfiles.c | 70 ++++++++ util-vserver/lib_internal/matchlist-compare.c | 48 +++++ util-vserver/lib_internal/matchlist-destroy.c | 37 ++++ util-vserver/lib_internal/matchlist-init.c | 41 +++++ .../lib_internal/matchlist-initbyvserver.c | 72 ++++++++ util-vserver/lib_internal/matchlist-initmanually.c | 196 +++++++++++++++++++++ .../lib_internal/matchlist-initrefserverlist.c | 82 +++++++++ util-vserver/lib_internal/matchlist.h | 71 ++++++++ util-vserver/lib_internal/pathinfo-append.c | 54 ++++++ util-vserver/lib_internal/pathinfo-test.c | 55 ++++++ util-vserver/lib_internal/pathinfo.h | 32 ++++ util-vserver/lib_internal/string-destroy.c | 29 +++ util-vserver/lib_internal/string.h | 35 ++++ util-vserver/lib_internal/string.hc | 23 +++ util-vserver/lib_internal/unify-deunify.c | 126 +++++++++++++ util-vserver/lib_internal/unify-unify.c | 82 +++++++++ util-vserver/lib_internal/unify.h | 49 ++++++ util-vserver/lib_internal/util-io.h | 35 ++++ util-vserver/lib_internal/util-mem.h | 31 ++++ 20 files changed, 1211 insertions(+) create mode 100644 util-vserver/lib_internal/Makefile-files create mode 100644 util-vserver/lib_internal/matchlist-appendfiles.c create mode 100644 util-vserver/lib_internal/matchlist-compare.c create mode 100644 util-vserver/lib_internal/matchlist-destroy.c create mode 100644 util-vserver/lib_internal/matchlist-init.c create mode 100644 util-vserver/lib_internal/matchlist-initbyvserver.c create mode 100644 util-vserver/lib_internal/matchlist-initmanually.c create mode 100644 util-vserver/lib_internal/matchlist-initrefserverlist.c create mode 100644 util-vserver/lib_internal/matchlist.h create mode 100644 util-vserver/lib_internal/pathinfo-append.c create mode 100644 util-vserver/lib_internal/pathinfo-test.c create mode 100644 util-vserver/lib_internal/pathinfo.h create mode 100644 util-vserver/lib_internal/string-destroy.c create mode 100644 util-vserver/lib_internal/string.h create mode 100644 util-vserver/lib_internal/string.hc create mode 100644 util-vserver/lib_internal/unify-deunify.c create mode 100644 util-vserver/lib_internal/unify-unify.c create mode 100644 util-vserver/lib_internal/unify.h create mode 100644 util-vserver/lib_internal/util-io.h create mode 100644 util-vserver/lib_internal/util-mem.h diff --git a/util-vserver/lib_internal/Makefile-files b/util-vserver/lib_internal/Makefile-files new file mode 100644 index 0000000..3399c2a --- /dev/null +++ b/util-vserver/lib_internal/Makefile-files @@ -0,0 +1,43 @@ +## $Id$ -*- makefile -*- + +## Copyright (C) 2003,2004 Enrico Scholz +## +## 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 index 0000000..de2393a --- /dev/null +++ b/util-vserver/lib_internal/matchlist-appendfiles.c @@ -0,0 +1,70 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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 +#endif + +#include "matchlist.h" +#include +#include + +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; itype = stINCLUDE; ++file; break; + case '-' : ++file; /*@fallthrough@*/ + default : ptr->type = stEXCLUDE; break; + } + ptr->cmp = determineCompareFunc(file); + ptr->name = file; + ++ptr; + } + } + else { + for (i=0; itype = 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 index 0000000..7f15ec5 --- /dev/null +++ b/util-vserver/lib_internal/matchlist-compare.c @@ -0,0 +1,48 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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 +#endif + +#include "matchlist.h" +#include + +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 (; ptrcmp==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 index 0000000..626cac2 --- /dev/null +++ b/util-vserver/lib_internal/matchlist-destroy.c @@ -0,0 +1,37 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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 +#endif + +#include "matchlist.h" + +void +MatchList_destroy(struct MatchList *list) +{ + size_t i; + + String_destroy(&list->id); + free(list->data); + + for (i=0; ibuf_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 index 0000000..6fe2455 --- /dev/null +++ b/util-vserver/lib_internal/matchlist-init.c @@ -0,0 +1,41 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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 +#endif + +#include "matchlist.h" +#include +#include + +#define ENSC_WRAPPERS_STDLIB 1 +#include +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 index 0000000..13b2828 --- /dev/null +++ b/util-vserver/lib_internal/matchlist-initbyvserver.c @@ -0,0 +1,72 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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 +#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 index 0000000..111ab42 --- /dev/null +++ b/util-vserver/lib_internal/matchlist-initmanually.c @@ -0,0 +1,196 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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 +#endif +#include "pathconfig.h" + +#include "matchlist.h" +#include "util-io.h" + +#include +#include +#include +#include +#include +#include + +#define ENSC_WRAPPERS_UNISTD 1 +#define ENSC_WRAPPERS_STDLIB 1 +#define ENSC_WRAPPERS_IO 1 +#include + + +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(*sizeptr && *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 index 0000000..f39a98b --- /dev/null +++ b/util-vserver/lib_internal/matchlist-initrefserverlist.c @@ -0,0 +1,82 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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 +#endif + +#include "matchlist.h" +#include "util-io.h" + +#include +#include +#include + +#define ENSC_WRAPPERS_FCNTL 1 +#define ENSC_WRAPPERS_UNISTD 1 +#define ENSC_WRAPPERS_STDLIB 1 +#include + +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; id_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 index 0000000..0cbf907 --- /dev/null +++ b/util-vserver/lib_internal/matchlist.h @@ -0,0 +1,71 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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 +#include + +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 index 0000000..c4cf941 --- /dev/null +++ b/util-vserver/lib_internal/pathinfo-append.c @@ -0,0 +1,54 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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 +#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 index 0000000..122d4f6 --- /dev/null +++ b/util-vserver/lib_internal/pathinfo-test.c @@ -0,0 +1,55 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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 +#endif + +#include "pathinfo.h" +#include +#include + +#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 index 0000000..7ddaba5 --- /dev/null +++ b/util-vserver/lib_internal/pathinfo.h @@ -0,0 +1,32 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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 index 0000000..517056f --- /dev/null +++ b/util-vserver/lib_internal/string-destroy.c @@ -0,0 +1,29 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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 +#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 index 0000000..81b3e73 --- /dev/null +++ b/util-vserver/lib_internal/string.h @@ -0,0 +1,35 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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 + +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 index 0000000..251d597 --- /dev/null +++ b/util-vserver/lib_internal/string.hc @@ -0,0 +1,23 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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 index 0000000..a942aab --- /dev/null +++ b/util-vserver/lib_internal/unify-deunify.c @@ -0,0 +1,126 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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 +#endif + +#include "unify.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#define ENSC_WRAPPERS_IO 1 +#include + +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 index 0000000..6423f58 --- /dev/null +++ b/util-vserver/lib_internal/unify-unify.c @@ -0,0 +1,82 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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 +#endif + +#include "unify.h" +#include "vserver.h" + +#include +#include +#include +#include +#include + +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 index 0000000..6498d3f --- /dev/null +++ b/util-vserver/lib_internal/unify.h @@ -0,0 +1,49 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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 + +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 index 0000000..d4519e7 --- /dev/null +++ b/util-vserver/lib_internal/util-io.h @@ -0,0 +1,35 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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 +#include + +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 index 0000000..6ed98a0 --- /dev/null +++ b/util-vserver/lib_internal/util-mem.h @@ -0,0 +1,31 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2004 Enrico Scholz +// +// 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 + +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 -- 1.8.1.5