X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Fsrc%2Fvuname.c;h=83432f79017f4d7915dca69d22cbc7ed3eb02a91;hb=a917f24ef7b003dcef54a3db2644cf9cb4bc2db2;hp=2f0162b9b5560d405fe97bebd01314e237115ebf;hpb=b7ff750467e0bd998b0ccfa7077c7ec1367b84e8;p=util-vserver.git diff --git a/util-vserver/src/vuname.c b/util-vserver/src/vuname.c index 2f0162b..83432f7 100644 --- a/util-vserver/src/vuname.c +++ b/util-vserver/src/vuname.c @@ -28,44 +28,58 @@ #include #include #include +#include +#include +#include +#include + +#define ENSC_WRAPPERS_PREFIX "vuname: " +#define ENSC_WRAPPERS_UNISTD 1 +#define ENSC_WRAPPERS_IO 1 +#define ENSC_WRAPPERS_VSERVER 1 +#include #define CMD_HELP 0x1000 #define CMD_VERSION 0x1001 -#define CMD_UTSCONTEXT 0x4000 -#define CMD_UTSSYSNAME 0x4001 -#define CMD_UTSNODENAME 0x4002 -#define CMD_UTSRELEASE 0x4003 -#define CMD_UTSVERSION 0x4004 -#define CMD_UTSMACHINE 0x4005 -#define CMD_UTSDOMAINNAME 0x4006 +#define CMD_DIR 0x4007 +#define CMD_MISSINGOK 0x4008 +int wrapper_exit_code = 255; static vc_uts_type const UTS_MAPPING[7] = { vcVHI_CONTEXT, vcVHI_SYSNAME, vcVHI_NODENAME, vcVHI_RELEASE, vcVHI_VERSION, vcVHI_MACHINE, vcVHI_DOMAINNAME }; +#define DECL(UTS) [vcVHI_ ## UTS] = #UTS +static char const * const UTS_STRINGS[] = { + DECL(CONTEXT), DECL(SYSNAME), DECL(NODENAME), + DECL(RELEASE), DECL(VERSION), DECL(MACHINE), + DECL(DOMAINNAME) +}; + +struct Tag { + bool is_set; + char const * value; +}; + struct Arguments { - bool handle_opts[DIM_OF(UTS_MAPPING)]; + struct Tag tags[DIM_OF(UTS_MAPPING)]; xid_t xid; bool do_set; - char const * value; + char const * dir; + bool is_missingok; }; static struct option const CMDLINE_OPTIONS[] = { - { "help", no_argument, 0, CMD_HELP }, - { "version", no_argument, 0, CMD_VERSION }, - { "xid", required_argument, 0, 'x' }, - { "set", no_argument, 0, 's' }, - { "get", no_argument, 0, 'g' }, - { "context", no_argument, 0, CMD_UTSCONTEXT }, - { "sysname", no_argument, 0, CMD_UTSSYSNAME }, - { "nodename", no_argument, 0, CMD_UTSNODENAME }, - { "release", no_argument, 0, CMD_UTSRELEASE }, - { "version", no_argument, 0, CMD_UTSVERSION }, - { "machine", no_argument, 0, CMD_UTSMACHINE }, - { "domainname" , no_argument, 0, CMD_UTSDOMAINNAME }, + { "help", no_argument, 0, CMD_HELP }, + { "version", no_argument, 0, CMD_VERSION }, + { "xid", required_argument, 0, 'x' }, + { "set", no_argument, 0, 's' }, + { "get", no_argument, 0, 'g' }, + { "dir", required_argument, 0, CMD_DIR }, + { "missingok", no_argument, 0, CMD_MISSINGOK }, { 0,0,0,0 } }; @@ -77,17 +91,28 @@ showHelp(int fd, char const *cmd, int res) WRITE_MSG(fd, "Usage: "); WRITE_STR(fd, cmd); WRITE_MSG(fd, - " [-g] [--xid|x ] [--]*\n" + " [-g] --xid *\n" + " or "); + WRITE_STR(fd, cmd); + WRITE_MSG(fd, + " -s --xid -t = [--] [ *]\n" " or "); WRITE_STR(fd, cmd); WRITE_MSG(fd, - " -s [--xid|x ] -- [--] \n\n" + " --dir --xid [--missingok] [--] [ *]\n\n" " Options:\n" - " -x ... operate on this context (default: current one)\n" - " -g ... get and print the value\n" - " -s ... set the value\n\n" - " Valid TAGs are:\n" - " context, sysname, nodename, release, version, machine, domainname\n\n" + " -g ... get and print the value\n" + " -s ... set the value\n\n" + " --xid ... operate on this context; 'self' means the current one\n" + " -t =\n" + " ... set to ; this option can be repeated multiple time\n" + " --dir ... read values from files in . These files must\n" + " have a valid TAG as their name\n" + " --missingok ... do not fail when the from '--dir' does not exist.\n" + "\n" + " Possible values for TAG are:\n" + " context, sysname, nodename, release, version, machine, domainname\n" + "\n" "Please report bugs to " PACKAGE_BUGREPORT "\n"); exit(res); } @@ -103,46 +128,117 @@ showVersion() exit(0); } -static unsigned int -getTrueCount(bool const *field, size_t cnt) +static void +setFromDir(char const *pathname, bool is_missingok, xid_t xid) { - unsigned int res = 0; - while (cnt>0) { - --cnt; - if (field[cnt]) ++res; + struct stat st; + size_t i; + size_t l_pathname = strlen(pathname); + char buf[l_pathname + sizeof("/domainname") + 32]; + + if (stat(pathname, &st)==-1) { + if (errno==ENOENT && is_missingok) return; + PERROR_Q(ENSC_WRAPPERS_PREFIX "fstat", pathname); + exit(wrapper_exit_code); + } + + memcpy(buf, pathname, l_pathname); + if (l_pathname>0 && pathname[l_pathname-1]!='/') + buf[l_pathname++] = '/'; + + for (i=0; i0 && name[l-1]=='\n') --l; + name[l] = '\0'; + Eclose(fd); + + if (vc_set_vhi_name(xid, (vc_uts_type)(i), name, l)==-1) { + PERROR_U(ENSC_WRAPPERS_PREFIX "vc_set_vhi_name", UTS_STRINGS[i]); + exit(wrapper_exit_code); + } + } } +} - return res; +static size_t +findUtsIdx(char const *str, size_t len) +{ + size_t i; + for (i=0; i=CMD_UTSCONTEXT && c<=CMD_UTSDOMAINNAME) - args.handle_opts[c-CMD_UTSCONTEXT] = true; - else switch (c) { + switch (c) { case CMD_HELP : showHelp(1, argv[0], 0); case CMD_VERSION : showVersion(); - case 'g' : args.do_set = true; break; - case 's' : args.do_set = true; break; - case 'x' : args.xid = atoi(optarg); break; + case CMD_DIR : args.dir = optarg; break; + case CMD_MISSINGOK: args.is_missingok = true; break; + case 'g' : args.do_set = false; break; + case 's' : args.do_set = true; break; + case 'x' : args.xid = Evc_xidopt2xid(optarg,true); break; + case 't' : registerValue(optarg, args.tags); break; default : WRITE_MSG(2, "Try '"); WRITE_STR(2, argv[0]); @@ -152,66 +248,47 @@ int main(int argc, char *argv[]) } } - opt_cnt = getTrueCount(args.handle_opts, DIM_OF(args.handle_opts)); - - if (args.do_set && optind==argc) { - WRITE_MSG(2, "No value given; use '--help' for more information\n"); - return EXIT_FAILURE; - } - - if (args.do_set && optind+1>argc) { - WRITE_MSG(2, "Too much values given; use '--help' for more information\n"); - return EXIT_FAILURE; + if (args.xid==VC_NOCTX) { + WRITE_MSG(2, "No context specified; try '--help' for more information\n"); + exit(wrapper_exit_code); } - if (args.do_set && opt_cnt<=0) { - WRITE_MSG(2, "No field given which shall be set; use '--help' for more information\n"); - return EXIT_FAILURE; - } - - if (args.do_set && opt_cnt>1) { - WRITE_MSG(2, "Can not set multiple fields; use '--help' for more information\n"); - return EXIT_FAILURE; + if (args.dir) + setFromDir(args.dir, args.is_missingok, args.xid); + else if (args.do_set) { + for (i=0; i