From e3d4565bc764db8eba3be02f85f24d6f2f5ad6e9 Mon Sep 17 00:00:00 2001 From: Enrico Scholz Date: Fri, 16 Jan 2004 18:00:11 +0000 Subject: [PATCH] initial checkin git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@611 94cd875c-1c1d-0410-91d2-eb244daf1a30 --- util-vserver/lib/getvserverappdir.c | 73 ++++++++++++ util-vserver/lib/getvservercfgdir.c | 61 ++++++++++ util-vserver/lib/isdirectory.c | 37 +++++++ util-vserver/scripts/legacy/.cvsignore | 2 + util-vserver/src/vunify-debug.c | 43 ++++++++ util-vserver/src/vunify-init.ic | 196 +++++++++++++++++++++++++++++++++ util-vserver/src/vunify.h | 53 +++++++++ util-vserver/src/wrappers-io.h | 172 +++++++++++++++++++++++++++++ 8 files changed, 637 insertions(+) create mode 100644 util-vserver/lib/getvserverappdir.c create mode 100644 util-vserver/lib/getvservercfgdir.c create mode 100644 util-vserver/lib/isdirectory.c create mode 100644 util-vserver/scripts/legacy/.cvsignore create mode 100644 util-vserver/src/vunify-debug.c create mode 100644 util-vserver/src/vunify-init.ic create mode 100644 util-vserver/src/vunify.h create mode 100644 util-vserver/src/wrappers-io.h diff --git a/util-vserver/lib/getvserverappdir.c b/util-vserver/lib/getvserverappdir.c new file mode 100644 index 0000000..71e2c07 --- /dev/null +++ b/util-vserver/lib/getvserverappdir.c @@ -0,0 +1,73 @@ +// $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 "vserver.h" +#include "internal.h" +#include "pathconfig.h" + +#include + +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 index 0000000..b846d73 --- /dev/null +++ b/util-vserver/lib/getvservercfgdir.c @@ -0,0 +1,61 @@ +// $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 "vserver.h" +#include "internal.h" +#include "pathconfig.h" + +#include + +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 index 0000000..bfe0f35 --- /dev/null +++ b/util-vserver/lib/isdirectory.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 "internal.h" + +#include +#include +#include + +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 index 0000000..9acb2e2 --- /dev/null +++ b/util-vserver/scripts/legacy/.cvsignore @@ -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 index 0000000..f84704c --- /dev/null +++ b/util-vserver/src/vunify-debug.c @@ -0,0 +1,43 @@ +// $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 "vunify-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(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 index 0000000..9757e14 --- /dev/null +++ b/util-vserver/src/vunify-init.ic @@ -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. + +#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(*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); +} + +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 index 0000000..3a404df --- /dev/null +++ b/util-vserver/src/vunify.h @@ -0,0 +1,53 @@ +// $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_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 index 0000000..b82a806 --- /dev/null +++ b/util-vserver/src/wrappers-io.h @@ -0,0 +1,172 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2003 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_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 -- 1.8.1.5