vshost-util-vserver

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

vsysctl.c (4537B)


      1 // $Id$    --*- c -*--
      2 
      3 // Copyright (C) 2007 Daniel Hokka Zakrisson
      4 //  
      5 // This program is free software; you can redistribute it and/or modify
      6 // it under the terms of the GNU General Public License as published by
      7 // the Free Software Foundation; version 2 of the License.
      8 //  
      9 // This program is distributed in the hope that it will be useful,
     10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 // GNU General Public License for more details.
     13 //  
     14 // You should have received a copy of the GNU General Public License
     15 // along with this program; if not, write to the Free Software
     16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     17 
     18 
     19 #ifdef HAVE_CONFIG_H
     20 #  include <config.h>
     21 #endif
     22 
     23 #include "util.h"
     24 #include <lib/internal.h>
     25 
     26 #include <vserver.h>
     27 
     28 #include <stdio.h>
     29 #include <getopt.h>
     30 #include <errno.h>
     31 #include <fcntl.h>
     32 #include <string.h>
     33 #include <dirent.h>
     34 
     35 #define ENSC_WRAPPERS_PREFIX	"vsysctl: "
     36 #define ENSC_WRAPPERS_UNISTD	1
     37 #define ENSC_WRAPPERS_FCNTL	1
     38 #define ENSC_WRAPPERS_DIRENT	1
     39 #define ENSC_WRAPPERS_VSERVER	1
     40 #define ENSC_WRAPPERS_IO	1
     41 #include <wrappers.h>
     42 
     43 
     44 #define PROC_SYS_DIRECTORY	"/proc/sys"
     45 
     46 
     47 #define CMD_HELP		0x1000
     48 #define CMD_VERSION		0x1001
     49 #define CMD_XID			0x4000
     50 #define CMD_DIR			0x4001
     51 #define CMD_MISSINGOK		0x4002
     52 
     53 int		wrapper_exit_code  =  1;
     54 
     55 struct option const
     56 CMDLINE_OPTIONS[] = {
     57   { "help",       no_argument,       0, CMD_HELP },
     58   { "version",    no_argument,       0, CMD_VERSION },
     59   { "xid",        required_argument, 0, CMD_XID },
     60   { "dir",        required_argument, 0, CMD_DIR },
     61   { "missingok",  no_argument,       0, CMD_MISSINGOK },
     62   {0,0,0,0}
     63 };
     64 
     65 static void
     66 showHelp(int fd, char const *cmd)
     67 {
     68   WRITE_MSG(fd, "Usage: ");
     69   WRITE_STR(fd, cmd);
     70   WRITE_MSG(fd,
     71 	    " --xid <xid> --dir <directory> [--missingok] -- <command> <args>*\n"
     72 	    "\n"
     73 	    "Please report bugs to " PACKAGE_BUGREPORT "\n");
     74 
     75   exit(0);
     76 }
     77 
     78 static void
     79 showVersion()
     80 {
     81   WRITE_MSG(1,
     82 	    "vsysctl " VERSION " -- sets sysctl values during guest boot\n"
     83 	    "This program is part of " PACKAGE_STRING "\n\n"
     84 	    "Copyright (C) 2007 Daniel Hokka Zakrisson\n"
     85 	    VERSION_COPYRIGHT_DISCLAIMER);
     86   exit(0);
     87 }
     88 
     89 void handle_setting(const char *dir, const char *name)
     90 {
     91   int	len_dir = strlen(dir), len_name = strlen(name);
     92   char	filename[len_dir+1+len_name+sizeof("/setting")];
     93   char	setting[128], value[128], *ptr;
     94   int	fd;
     95   size_t setting_len, value_len;
     96 
     97   strcpy(filename, dir);
     98   *(filename+len_dir) = '/';
     99   strcpy(filename+len_dir+1, name);
    100 
    101 #define READFILE(f) \
    102   strcpy(filename+len_dir+1+len_name, "/" #f); \
    103   fd = EopenD(filename, O_RDONLY, 0); \
    104   f##_len = Eread(fd, f, sizeof(f)); \
    105   if (f##_len == sizeof(f)) { \
    106     errno = EOVERFLOW; \
    107     perror(ENSC_WRAPPERS_PREFIX "read"); \
    108     exit(EXIT_FAILURE); \
    109   } \
    110   f[f##_len] = '\0'; \
    111   Eclose(fd);
    112 
    113   READFILE(setting);
    114   READFILE(value);
    115 
    116   /* replace all . with / in setting to get a filename */
    117   for (ptr = strchr(setting, '.'); ptr; ptr = strchr(ptr, '.'))
    118     *ptr = '/';
    119 
    120   /* we just want the first line, and not the linefeed */
    121   if ((ptr = strchr(setting, '\n')) != NULL)
    122     *ptr = '\0';
    123 
    124   fd = EopenD(setting, O_WRONLY, 0);
    125   EwriteAll(fd, value, value_len);
    126   Eclose(fd);
    127 }
    128 
    129 int main(int argc, char *argv[])
    130 {
    131   xid_t		xid	= VC_NOCTX;
    132   const char	*dir	= NULL;
    133   bool		missing	= false;
    134   
    135   while (1) {
    136     int		c = getopt_long(argc, argv, "+", CMDLINE_OPTIONS, 0);
    137     if (c==-1) break;
    138 
    139     switch (c) {
    140       case CMD_HELP	:  showHelp(1, argv[0]);
    141       case CMD_VERSION	:  showVersion();
    142       case CMD_XID	:  xid = Evc_xidopt2xid(optarg, true);	break;
    143       case CMD_DIR	:  dir = optarg;			break;
    144       case CMD_MISSINGOK:  missing = true;			break;
    145 
    146       default		:
    147 	WRITE_MSG(2, "Try '");
    148 	WRITE_STR(2, argv[0]);
    149 	WRITE_MSG(2, " --help' for more information.\n");
    150 	return EXIT_FAILURE;
    151 	break;
    152     }
    153   }
    154 
    155   if (dir != NULL) {
    156     int		  curdir = EopenD(".", O_RDONLY, 0);
    157     DIR		  *dp;
    158     struct dirent *de;
    159 
    160     if (chdir(PROC_SYS_DIRECTORY) == -1)
    161       goto exec;
    162 
    163     dp = opendir(dir);
    164     if (dp != NULL) {
    165       while ((de = Ereaddir(dp)) != NULL) {
    166 	if (*de->d_name == '.')
    167 	  continue;
    168 	handle_setting(dir, de->d_name);
    169       }
    170       Eclosedir(dp);
    171     }
    172     else if (!missing) {
    173       perror(ENSC_WRAPPERS_PREFIX "opendir");
    174       exit(wrapper_exit_code);
    175     }
    176 
    177     Efchdir(curdir);
    178     Eclose(curdir);
    179   }
    180 
    181 exec:
    182   Eexecvp(argv[optind], argv+optind);
    183   return EXIT_FAILURE;
    184 }