X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Ffakerunlevel.c;h=55ee5c24bb14c016ffab256050c0ace232f97ec4;hb=a741f6faf2baae1e823d334012f6a09e6a1bda51;hp=3ddcfe95840d5a68183b4ee3c949c999d88b4a4c;hpb=06e1018272502e1d15d6d8f32b80fa96420785b8;p=util-vserver.git diff --git a/src/fakerunlevel.c b/src/fakerunlevel.c index 3ddcfe9..55ee5c2 100644 --- a/src/fakerunlevel.c +++ b/src/fakerunlevel.c @@ -1,4 +1,4 @@ -// $Id: fakerunlevel.c,v 1.1 2003/09/29 22:01:57 ensc Exp $ +// $Id: fakerunlevel.c 2562 2007-07-12 21:59:06Z dhozac $ // Copyright (C) 2003 Enrico Scholz // based on fakerunlevel.cc by Jacques Gelinas @@ -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>9) 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; +}