vshost-util-vserver

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

vuname.c (7868B)


      1 // $Id$    --*- c -*--
      2 
      3 // Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
      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 "vserver.h"
     24 #include "util.h"
     25 
     26 #include <getopt.h>
     27 #include <stdlib.h>
     28 #include <assert.h>
     29 #include <stdio.h>
     30 #include <libgen.h>
     31 #include <errno.h>
     32 #include <fcntl.h>
     33 #include <ctype.h>
     34 #include <strings.h>
     35 
     36 #define ENSC_WRAPPERS_PREFIX	"vuname: "
     37 #define ENSC_WRAPPERS_UNISTD	1
     38 #define ENSC_WRAPPERS_IO	1
     39 #define ENSC_WRAPPERS_VSERVER	1
     40 #include <wrappers.h>
     41 
     42 #define CMD_HELP		0x1000
     43 #define CMD_VERSION		0x1001
     44 #define CMD_DIR			0x4007
     45 #define CMD_MISSINGOK		0x4008
     46 
     47 int			wrapper_exit_code = 255;
     48 
     49 static vc_uts_type const	UTS_MAPPING[7] = {
     50   vcVHI_CONTEXT, vcVHI_SYSNAME, vcVHI_NODENAME,
     51   vcVHI_RELEASE, vcVHI_VERSION, vcVHI_MACHINE,
     52   vcVHI_DOMAINNAME };
     53 
     54 #define DECL(UTS) [vcVHI_ ## UTS] = #UTS
     55 static char const * const	UTS_STRINGS[] = {
     56   DECL(CONTEXT), DECL(SYSNAME), DECL(NODENAME),
     57   DECL(RELEASE), DECL(VERSION), DECL(MACHINE),
     58   DECL(DOMAINNAME)
     59 };
     60 
     61 struct Tag {
     62     bool		is_set;
     63     char const *	value;
     64 };
     65 
     66 struct Arguments {
     67     struct Tag		tags[DIM_OF(UTS_MAPPING)];
     68     xid_t		xid;
     69     bool		do_set;
     70     char const *	dir;
     71     bool		is_missingok;
     72 };
     73 
     74 static struct option const
     75 CMDLINE_OPTIONS[] = {
     76   { "help",        no_argument,       0, CMD_HELP },
     77   { "version",     no_argument,       0, CMD_VERSION },
     78   { "xid",         required_argument, 0, 'x' },
     79   { "set",         no_argument,       0, 's' },
     80   { "get",         no_argument,       0, 'g' },
     81   { "dir",         required_argument, 0, CMD_DIR },
     82   { "missingok",   no_argument,       0, CMD_MISSINGOK },
     83   { 0,0,0,0 }
     84 };
     85 
     86 static void
     87 showHelp(int fd, char const *cmd, int res)
     88 {
     89   VSERVER_DECLARE_CMD(cmd);
     90   
     91   WRITE_MSG(fd, "Usage:  ");
     92   WRITE_STR(fd, cmd);
     93   WRITE_MSG(fd,
     94 	    "  [-g] --xid <xid> <TAG>*\n"
     95 	    "    or  ");
     96   WRITE_STR(fd, cmd);
     97   WRITE_MSG(fd,
     98 	    "  -s --xid <xid> -t <TAG>=<VALUE> [--] [<command> <args>*]\n"
     99 	    "    or  ");
    100   WRITE_STR(fd, cmd);
    101   WRITE_MSG(fd,	    
    102 	    "  --dir <dir> --xid <xid> [--missingok] [--] [<command> <args>*]\n\n"
    103 	    " Options:\n"
    104 	    "   -g           ...  get and print the value\n"
    105 	    "   -s           ...  set the value\n\n"
    106 	    "   --xid <xid>  ...  operate on this context; 'self' means the current one\n"
    107 	    "   -t <TAG>=<VALUE>\n"
    108 	    "                ...  set <TAG> to <VALUE>; this option can be repeated multiple time\n"
    109 	    "   --dir <dir>  ...  read values from files in <dir>. These files must\n"
    110 	    "                     have a valid TAG as their name\n"
    111 	    "   --missingok  ...  do not fail when the <DIR> from '--dir' does not exist.\n"
    112 	    "\n"
    113 	    " Possible values for TAG are:\n"
    114 	    "   context, sysname, nodename, release, version, machine, domainname\n"
    115 	    "\n"
    116 	    "Please report bugs to " PACKAGE_BUGREPORT "\n");
    117   exit(res);
    118 }
    119 
    120 static void
    121 showVersion()
    122 {
    123   WRITE_MSG(1,
    124 	    "vuname " VERSION " -- modifies and shows uname entries of vserver contexts\n"
    125 	    "This program is part of " PACKAGE_STRING "\n\n"
    126 	    "Copyright (C) 2004 Enrico Scholz\n"
    127 	    VERSION_COPYRIGHT_DISCLAIMER);
    128   exit(0);
    129 }
    130 
    131 static void
    132 setFromDir(char const *pathname, bool is_missingok, xid_t xid)
    133 {
    134   struct stat		st;
    135   size_t		i;
    136   size_t		l_pathname = strlen(pathname);
    137   char			buf[l_pathname + sizeof("/domainname") + 32];
    138   
    139   if (stat(pathname, &st)==-1) {
    140     if (errno==ENOENT && is_missingok) return;
    141     PERROR_Q(ENSC_WRAPPERS_PREFIX "fstat", pathname);
    142     exit(wrapper_exit_code);
    143   }
    144 
    145   memcpy(buf, pathname, l_pathname);
    146   if (l_pathname>0 && pathname[l_pathname-1]!='/')
    147     buf[l_pathname++] = '/';
    148   
    149   for (i=0; i<DIM_OF(UTS_STRINGS); ++i) {
    150     char *	ptr   = buf+l_pathname;
    151     int		fd;
    152 
    153     // ignore unimplemented uts-names
    154     if (UTS_STRINGS[i]==0) continue;
    155     strcpy(ptr, UTS_STRINGS[i]);
    156     for (;*ptr;++ptr) *ptr = tolower(*ptr);
    157     fd = open(buf, O_RDONLY);
    158     if (fd!=-1) {
    159       size_t	l = Elseek(fd, 0, SEEK_END);
    160       char	name[l+1];
    161       Elseek(fd,0,SEEK_SET);
    162       EreadAll(fd, name, l);
    163       while (l>0 && name[l-1]=='\n') --l;
    164       name[l] = '\0';
    165       Eclose(fd);
    166 
    167       if (vc_set_vhi_name(xid, (vc_uts_type)(i), name, l)==-1) {
    168 	PERROR_U(ENSC_WRAPPERS_PREFIX "vc_set_vhi_name", UTS_STRINGS[i]);
    169 	exit(wrapper_exit_code);
    170       }
    171     }
    172   }
    173 }
    174 
    175 static size_t
    176 findUtsIdx(char const *str, size_t len)
    177 {
    178   size_t		i;
    179   for (i=0; i<DIM_OF(UTS_STRINGS); ++i)
    180     if (UTS_STRINGS[i]!=0 && strncasecmp(UTS_STRINGS[i], str, len)==0)
    181       return i;
    182 
    183   WRITE_MSG(2, "Tag '");
    184   Vwrite   (2, str, len);
    185   WRITE_STR(2, "' not recognized\n");
    186   exit(wrapper_exit_code);
    187 }
    188 
    189 static void
    190 registerValue(char const *str, struct Tag tags[DIM_OF(UTS_MAPPING)])
    191 {
    192   char const *	ptr = strchr(str, '=');
    193   size_t	idx;
    194   
    195   if (ptr==0) ptr = str + strlen(str);
    196   assert(*ptr=='=' || *ptr=='\0');
    197 
    198   idx = findUtsIdx(str, ptr-str);
    199 
    200   if (*ptr=='=') ++ptr;
    201   tags[idx].is_set = true;
    202   tags[idx].value  = ptr;
    203 }
    204 
    205 static void
    206 printUtsValue(xid_t xid, int val)
    207 {
    208   char	buf[128];
    209   if (vc_get_vhi_name(xid, val, buf, sizeof(buf)-1)==-1)
    210     WRITE_MSG(1, "???");
    211   else
    212     WRITE_STR(1, buf);
    213   
    214 }
    215 
    216 int main(int argc, char *argv[])
    217 {
    218   struct Arguments	args = {
    219     .tags        = { [0] = {false,0} },
    220     .do_set      = false,
    221     .dir         = 0,
    222     .is_missingok= false,
    223     .xid         = VC_NOCTX,
    224   };
    225   size_t		i;
    226 
    227   assert(DIM_OF(UTS_MAPPING) == DIM_OF(args.tags));
    228   
    229   while (1) {
    230     int		c = getopt_long(argc, argv, "+gst:", CMDLINE_OPTIONS, 0);
    231     if (c==-1) break;
    232 
    233     switch (c) {
    234       case CMD_HELP	:  showHelp(1, argv[0], 0);
    235       case CMD_VERSION	:  showVersion();
    236       case CMD_DIR	:  args.dir          = optarg; break;
    237       case CMD_MISSINGOK:  args.is_missingok = true;   break;
    238       case 'g'		:  args.do_set       = false;  break;
    239       case 's'		:  args.do_set       = true;   break;
    240       case 'x'		:  args.xid = Evc_xidopt2xid(optarg,true); break;
    241       case 't'		:  registerValue(optarg, args.tags);       break;
    242       default		:
    243 	WRITE_MSG(2, "Try '");
    244 	WRITE_STR(2, argv[0]);
    245 	WRITE_MSG(2, " --help' for more information.\n");
    246 	return EXIT_FAILURE;
    247 	break;
    248     }
    249   }
    250 
    251   if (args.xid==VC_NOCTX) {
    252     WRITE_MSG(2, "No context specified; try '--help' for more information\n");
    253     exit(wrapper_exit_code);
    254   }
    255 
    256   if (args.dir)
    257     setFromDir(args.dir, args.is_missingok, args.xid);
    258   else if (args.do_set) {
    259     for (i=0; i<DIM_OF(args.tags); ++i) {
    260       if (!args.tags[i].is_set) continue;
    261       Evc_set_vhi_name(args.xid, i, args.tags[i].value, strlen(args.tags[i].value));
    262     }
    263   }
    264   else if (optind==argc) {
    265     char const *	delim = "";
    266     for (i=0; i<DIM_OF(UTS_MAPPING); ++i) {
    267       WRITE_STR(1, delim);
    268       printUtsValue(args.xid, i);
    269       delim = " ";
    270     }
    271     WRITE_MSG(1, "\n");
    272 
    273     return EXIT_SUCCESS;
    274   }
    275   else {
    276     char const *	delim = "";
    277     while (optind <argc) {
    278       int		idx = findUtsIdx(argv[optind], strlen(argv[optind]));
    279       WRITE_STR(1, delim);
    280       printUtsValue(args.xid, idx);
    281       delim = " ";
    282 
    283       ++optind;
    284     }
    285     WRITE_MSG(1, "\n");
    286     
    287     return EXIT_SUCCESS;
    288   }
    289 
    290   if (optind<argc)
    291     EexecvpD(argv[optind], argv+optind);
    292 
    293   return EXIT_SUCCESS;
    294 }