vshost-util-vserver

Build script and sources for util-vserver.
git clone https://ccx.te2000.cz/git/vshost-util-vserver
Log | Files | Refs

fakerunlevel.c (3041B)


      1 // $Id$
      2 
      3 // Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
      4 // based on fakerunlevel.cc by Jacques Gelinas
      5 //  
      6 // This program is free software; you can redistribute it and/or modify
      7 // it under the terms of the GNU General Public License as published by
      8 // the Free Software Foundation; either version 2, or (at your option)
      9 // any later version.
     10 //  
     11 // This program is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 //  
     16 // You should have received a copy of the GNU General Public License
     17 // along with this program; if not, write to the Free Software
     18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     19 
     20 /*
     21 	This program add a RUNLEVEL record in a utmp file.
     22 	This is used when a vserver lack a private init process
     23 	so runlevel properly report the fake runlevel.
     24 */
     25 #ifdef HAVE_CONFIG_H
     26 #  include <config.h>
     27 #endif
     28 
     29 #include "util.h"
     30 
     31 #include <utmp.h>
     32 #include <stdio.h>
     33 #include <string.h>
     34 #include <stdlib.h>
     35 #include <errno.h>
     36 #include <fcntl.h>
     37 #include <grp.h>
     38 #include <sys/types.h>
     39 #include <sys/stat.h>
     40 
     41 #define ENSC_WRAPPERS_PREFIX	"fakerunlevel: "
     42 #define ENSC_WRAPPERS_UNISTD	1
     43 #define ENSC_WRAPPERS_FCNTL	1
     44 #include <wrappers.h>
     45 
     46 int	wrapper_exit_code = 1;
     47 
     48 static void
     49 showHelp(int fd, int exit_code)
     50 {
     51   WRITE_MSG(fd,
     52 	    "Usage: fakerunlevel <runlevel> <utmp_file>\n\n"
     53 	    "Put a runlevel record in file <utmp_file>\n\n"
     54 	    "Please report bugs to " PACKAGE_BUGREPORT "\n");
     55 
     56   exit(exit_code);
     57 }
     58 
     59 static void
     60 showVersion()
     61 {
     62   WRITE_MSG(1,
     63 	    "fakerunlevel " VERSION "\n"
     64 	    "This program is part of " PACKAGE_STRING "\n\n"
     65 	    "Copyright (C) 2003 Enrico Scholz\n"
     66 	    VERSION_COPYRIGHT_DISCLAIMER);
     67   exit(0);
     68 }
     69 
     70 int main (int argc, char *argv[])
     71 {
     72   if (argc==1) showHelp(2,1);
     73   if (strcmp(argv[1], "--help")==0)    showHelp(1,0);
     74   if (strcmp(argv[1], "--version")==0) showVersion();
     75   if (argc!=3) showHelp(2,1);
     76 
     77   {
     78     int  const 		runlevel = atoi(argv[1]);
     79     char const * const	fname    = argv[2];
     80     int			fd;
     81     struct utmp 	ut;
     82     
     83     gid_t		gid;
     84     char		*gid_str = getenv("UTMP_GID");
     85     
     86     if (runlevel<0 || runlevel>9) showHelp(2,1);
     87 
     88     Echroot(".");
     89     Echdir("/");
     90 
     91       // Real NSS is too expensive/insecure in this state; therefore, use the
     92       // value detected at ./configure stage or overridden by $UTMP_GID
     93       // env-variable
     94     gid = gid_str ? atoi(gid_str) : UTMP_GID;
     95     Esetgroups(1, &gid);
     96     Esetgid(gid);
     97 
     98     if (getgid()!=gid) {
     99       WRITE_MSG(2, "fakerunlevel: Failed to set group\n");
    100       return EXIT_FAILURE;
    101     }
    102 
    103     umask(002);
    104     fd = EopenD(fname, O_WRONLY|O_CREAT|O_APPEND, 0664);
    105     Eclose(fd);
    106 
    107     utmpname (fname);
    108     setutent();
    109     memset (&ut,0,sizeof(ut));
    110     ut.ut_type = RUN_LVL;
    111     ut.ut_pid  = ('#' << 8) + runlevel+'0';
    112     pututline (&ut);
    113     endutent();
    114   }
    115 
    116   return EXIT_SUCCESS;
    117 }