X-Git-Url: http://git.onelab.eu/?p=util-vserver.git;a=blobdiff_plain;f=vserver-start%2Fscriptlets.c;fp=vserver-start%2Fscriptlets.c;h=9c0df652e287100ed7e1f5bc14505fcdd1b152e3;hp=0000000000000000000000000000000000000000;hb=8cf13bb177d92c93eb73dc8939777150536c2d00;hpb=6bf3f95de36c804c97716b2d0bdf10680c559044 diff --git a/vserver-start/scriptlets.c b/vserver-start/scriptlets.c new file mode 100644 index 0000000..9c0df65 --- /dev/null +++ b/vserver-start/scriptlets.c @@ -0,0 +1,171 @@ +// $Id: scriptlets.c,v 1.3 2004/10/19 21:11:10 ensc Exp $ --*- 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-start.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#define HAS_SUFFIX(STR, LEN, SUF) \ + (LEN>sizeof(SUF) && strcmp(STR+LEN-sizeof(SUF), SUF)==0) + +static bool +visitFile(char const *fname, char const *vname, char const *style) +{ + struct stat st; + struct Command cmd; + + if (stat(fname, &st)==-1 || + !S_ISREG(st.st_mode)) + return false; + + if ((st.st_mode & 0111)==0) { + WRITE_MSG(2, + "!!!LEGACY ALERT!!!\n" + "The special handling of non-executable scriptlets which allows to\n" + "override environment variables is not supported anymore. This change\n" + "was needed as 'vserver ... start' is done by a native C program now.\n" + "If you need the old functionality please fill a bugreport so that\n" + "workarounds can be found/implemented.\n" + "The file triggering this message was\n" + " '"); + WRITE_STR(2, fname); + WRITE_MSG(2, "'\n"); + + return false; + } + + char const *par[] = { fname, style, vname, 0 }; + Command_setParams(&cmd, par); + + if (!Command_exec(&cmd, true) || + !Command_wait(&cmd, true)) { + WRITE_MSG(2, "vserver-start: exec('"); + WRITE_STR(2, fname); + WRITE_MSG(2, "'): "); + WRITE_STR(2, strerror(cmd.err)); + WRITE_MSG(2, "; aborting...\n"); + + exit(1); + } + + if (cmd.rc!=0) { + WRITE_MSG(2, "vserver-start: scriptlet '"); + WRITE_STR(2, fname); + WRITE_MSG(2, "' failed; aborting...\n"); + + exit (1); + } + + Command_free(&cmd); + + return true; +} + +static bool +visitDirentry(PathInfo const *basepath, char const *d_name, + char const *vname, + char const *style) +{ + size_t l = strlen(d_name); + char path[basepath->l + l + 1]; + char * ptr; + + if (isDotfile(d_name) || + HAS_SUFFIX(d_name, l, ".rpmnew") || + HAS_SUFFIX(d_name, l, ".rpmsave") || + HAS_SUFFIX(d_name, l, ".rpmorig") || + HAS_SUFFIX(d_name, l, ".cfsaved")) + return false; + + ptr = Xmemcpy(path, basepath->d, basepath->l); + ptr = Xmemcpy(ptr, d_name, l); + *ptr = '\0'; + + return visitFile(path, vname, style); +} + +static bool +visitPath(PathInfo const *basepath, + char const *vname, + PathInfo const *style) +{ + char tmp[basepath->l + style->l + sizeof(".d/")]; + PathInfo path = { .d = tmp }; + char * ptr; + DIR * dir; + bool did_something = false; + + ptr = Xmemcpy(tmp, basepath->d, basepath->l); + ptr = Xmemcpy(ptr, style->d, style->l); + *ptr = '\0'; + path.l = ptr-tmp; + + did_something = visitFile(path.d, vname, style->d) || did_something; + + ptr = Xmemcpy(ptr, ".d/", sizeof(".d/")); + path.l = ptr-tmp; + + dir = opendir(tmp); + while (dir) { + struct dirent *ent = readdir(dir); + if (ent==0) break; + + did_something = visitDirentry(&path, ent->d_name, vname, style->d) || did_something; + } + if (dir!=0) closedir(dir); + + return did_something; +} + +void +execScriptlets(PathInfo const *cfgdir, char const *vname, char const *style) +{ + char path_buf[MAX(cfgdir->l, sizeof(CONFDIR "/.defaults")) + + sizeof("/scripts/")]; + PathInfo basepath = { .d = path_buf }; + PathInfo styledir = { + .d = style, + .l = strlen(style) + }; + char * ptr; + bool doit = true; + + ptr = Xmemcpy(path_buf, cfgdir->d, cfgdir->l); + ptr = Xmemcpy(ptr, "/scripts/", sizeof("/scripts/")); + basepath.l = ptr-path_buf-1; + doit = !visitPath(&basepath, vname, &styledir); + + if (doit) { + ptr = Xmemcpy(path_buf, CONFDIR "/.defaults/scripts/", + sizeof(CONFDIR "/.defaults/scripts/")); + basepath.l = ptr-path_buf-1; + doit = !visitPath(&basepath, vname, &styledir); + } +}