X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Fsrc%2Ffakerunlevel.c;h=d532d693896be53d26b18be9d63786cabe55ac28;hb=faa778968d1a7dfeaebc9fe4b847e691dc62fd15;hp=b4f58986a6ba7a22585bac7de750a7d7ec2c0c9a;hpb=da691fd4bad5e187b307b7fd86bf5fd61e47c3fc;p=util-vserver.git diff --git a/util-vserver/src/fakerunlevel.c b/util-vserver/src/fakerunlevel.c index b4f5898..d532d69 100644 --- a/util-vserver/src/fakerunlevel.c +++ b/util-vserver/src/fakerunlevel.c @@ -22,52 +22,96 @@ This is used when a vserver lack a private init process so runlevel properly report the fake runlevel. */ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "util.h" + #include #include #include #include #include +#include +#include +#include +#include + +#define ENSC_WRAPPERS_PREFIX "fakerunlevel: " +#define ENSC_WRAPPERS_UNISTD 1 +#define ENSC_WRAPPERS_FCNTL 1 +#include + +int wrapper_exit_code = 1; -static void usage() +static void +showHelp(int fd, int exit_code) { - fprintf (stderr,"fakerunlevel version %s\n",VERSION); - fprintf (stderr - ,"\n" - "fakerunlevel runlevel utmp_file\n" - "\n" - "Put a runlevel record in file utmp_file\n"); + WRITE_MSG(fd, + "Usage: fakerunlevel \n\n" + "Put a runlevel record in file \n\n" + "Please report bugs to " PACKAGE_BUGREPORT "\n"); + + exit(exit_code); } -int main (int argc, char *argv[]) +static void +showVersion() { - if (argc != 3){ - usage(); - }else{ - int runlevel = atoi(argv[1]); - const char *fname = argv[2]; - if (runlevel < 1 || runlevel > 5){ - usage(); - }else{ - // Make sure the file exist - FILE *fout = fopen (fname,"a"); - if (fout == NULL){ - fprintf (stderr,"Can't open file %s (%s)\n",fname - ,strerror(errno)); - }else{ - struct utmp ut; - - fclose (fout); - utmpname (fname); - setutent(); - memset (&ut,0,sizeof(ut)); - ut.ut_type = RUN_LVL; - ut.ut_pid = ('#' << 8) + runlevel+'0'; - pututline (&ut); - endutent(); - } - } - } - - return 0; + WRITE_MSG(1, + "fakerunlevel " VERSION "\n" + "This program is part of " PACKAGE_STRING "\n\n" + "Copyright (C) 2003 Enrico Scholz\n" + VERSION_COPYRIGHT_DISCLAIMER); + exit(0); } +int main (int argc, char *argv[]) +{ + if (argc==1) showHelp(2,1); + if (strcmp(argv[1], "--help")==0) showHelp(1,0); + if (strcmp(argv[1], "--version")==0) showVersion(); + if (argc!=3) showHelp(2,1); + + { + int const runlevel = atoi(argv[1]); + char const * const fname = argv[2]; + int fd; + struct utmp ut; + + gid_t gid; + char *gid_str = getenv("UTMP_GID"); + + if (runlevel<0 || runlevel>6) showHelp(2,1); + + Echroot("."); + Echdir("/"); + + // Real NSS is too expensive/insecure in this state; therefore, use the + // value detected at ./configure stage or overridden by $UTMP_GID + // env-variable + gid = gid_str ? atoi(gid_str) : UTMP_GID; + Esetgroups(1, &gid); + Esetgid(gid); + + if (getgid()!=gid) { + WRITE_MSG(2, "fakerunlevel: Failed to set group\n"); + return EXIT_FAILURE; + } + + umask(002); + fd = EopenD(fname, O_WRONLY|O_CREAT|O_APPEND, 0664); + Eclose(fd); + + utmpname (fname); + setutent(); + memset (&ut,0,sizeof(ut)); + ut.ut_type = RUN_LVL; + ut.ut_pid = ('#' << 8) + runlevel+'0'; + pututline (&ut); + endutent(); + } + + return EXIT_SUCCESS; +}