fixed do-display-dir behavior
[util-vserver.git] / util-vserver / src / vuname.c
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
32 #define CMD_HELP                0x1000
33 #define CMD_VERSION             0x1001
34 #define CMD_UTSCONTEXT          0x4000
35 #define CMD_UTSSYSNAME          0x4001
36 #define CMD_UTSNODENAME         0x4002
37 #define CMD_UTSRELEASE          0x4003
38 #define CMD_UTSVERSION          0x4004
39 #define CMD_UTSMACHINE          0x4005
40 #define CMD_UTSDOMAINNAME       0x4006
41
42
43 static vc_uts_type const        UTS_MAPPING[7] = {
44   vcVHI_CONTEXT, vcVHI_SYSNAME, vcVHI_NODENAME,
45   vcVHI_RELEASE, vcVHI_VERSION, vcVHI_MACHINE,
46   vcVHI_DOMAINNAME };
47
48 struct Arguments {
49     bool                handle_opts[DIM_OF(UTS_MAPPING)];
50     xid_t               xid;
51     bool                do_set;
52     char const *        value;
53 };
54
55 static 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, 'x' },
60   { "set",      no_argument,       0, 's' },
61   { "get",      no_argument,       0, 'g' },
62   { "context",     no_argument, 0, CMD_UTSCONTEXT },
63   { "sysname",     no_argument, 0, CMD_UTSSYSNAME },
64   { "nodename",    no_argument, 0, CMD_UTSNODENAME },
65   { "release",     no_argument, 0, CMD_UTSRELEASE },
66   { "version",     no_argument, 0, CMD_UTSVERSION },
67   { "machine",     no_argument, 0, CMD_UTSMACHINE },
68   { "domainname" , no_argument, 0, CMD_UTSDOMAINNAME },
69   { 0,0,0,0 }
70 };
71
72 static void
73 showHelp(int fd, char const *cmd, int res)
74 {
75   VSERVER_DECLARE_CMD(cmd);
76   
77   WRITE_MSG(fd, "Usage:  ");
78   WRITE_STR(fd, cmd);
79   WRITE_MSG(fd,
80             " [-g] [--xid|x <xid>] [--<TAG>]*\n"
81             "    or  ");
82   WRITE_STR(fd, cmd);
83   WRITE_MSG(fd,     
84             "  -s  [--xid|x <xid>]  --<TAG> [--] <value>\n\n"
85             " Options:\n"
86             "   -x <xid>  ...  operate on this context (default: current one)\n"
87             "   -g        ...  get and print the value\n"
88             "   -s        ...  set the value\n\n"
89             " Valid TAGs are:\n"
90             "   context, sysname, nodename, release, version, machine, domainname\n\n"
91             "Please report bugs to " PACKAGE_BUGREPORT "\n");
92   exit(res);
93 }
94
95 static void
96 showVersion()
97 {
98   WRITE_MSG(1,
99             "vuname " VERSION " -- modifies and shows uname entries of vserver contexts\n"
100             "This program is part of " PACKAGE_STRING "\n\n"
101             "Copyright (C) 2004 Enrico Scholz\n"
102             VERSION_COPYRIGHT_DISCLAIMER);
103   exit(0);
104 }
105
106 static unsigned int
107 getTrueCount(bool const *field, size_t cnt)
108 {
109   unsigned int  res = 0;
110   while (cnt>0) {
111     --cnt;
112     if (field[cnt]) ++res;
113   }
114
115   return res;
116 }
117
118 int main(int argc, char *argv[])
119 {
120   struct Arguments      args = {
121     .handle_opts = { 0,0,0,0,0,0,0 },
122     .do_set      = false,
123     .xid         = VC_SAMECTX,
124   };
125   unsigned int          opt_cnt;
126   size_t                i;
127   bool                  failed = false;
128   bool                  passed = false;
129   char const *          delim  = "";
130   char                  result_buf[1024] = { [0] = '\0' };
131
132   assert(DIM_OF(UTS_MAPPING) == DIM_OF(args.handle_opts));
133   
134   while (1) {
135     int         c = getopt_long(argc, argv, "gsx:", CMDLINE_OPTIONS, 0);
136     if (c==-1) break;
137
138     if (c>=CMD_UTSCONTEXT && c<=CMD_UTSDOMAINNAME)
139       args.handle_opts[c-CMD_UTSCONTEXT] = true;
140     else switch (c) {
141       case CMD_HELP     :  showHelp(1, argv[0], 0);
142       case CMD_VERSION  :  showVersion();
143       case 'g'          :  args.do_set  = true; break;
144       case 's'          :  args.do_set  = true; break;
145       case 'x'          :  args.xid     = atoi(optarg); break;
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   opt_cnt = getTrueCount(args.handle_opts, DIM_OF(args.handle_opts));
156   
157   if (args.do_set && optind==argc) {
158     WRITE_MSG(2, "No value given; use '--help' for more information\n");
159     return EXIT_FAILURE;
160   }
161
162   if (args.do_set && optind+1>argc) {
163     WRITE_MSG(2, "Too much values given; use '--help' for more information\n");
164     return EXIT_FAILURE;
165   }
166
167   if (args.do_set && opt_cnt<=0) {
168     WRITE_MSG(2, "No field given which shall be set; use '--help' for more information\n");
169     return EXIT_FAILURE;
170   }
171
172   if (args.do_set && opt_cnt>1) {
173     WRITE_MSG(2, "Can not set multiple fields; use '--help' for more information\n");
174     return EXIT_FAILURE;
175   }
176
177   if (!args.do_set && optind!=argc) {
178     WRITE_MSG(2, "Can not specifiy a value with '-g'; use '--help' for more information\n");
179     return EXIT_FAILURE;
180   }
181
182   if (args.do_set) args.value = argv[optind];
183
184   if (!args.do_set && opt_cnt==0)
185     for (i=0; i<DIM_OF(args.handle_opts); ++i) args.handle_opts[i]=true;
186     
187   for (i=0; i<DIM_OF(args.handle_opts); ++i) {
188     if (!args.handle_opts[i]) continue;
189
190     if (args.do_set) {
191       if (vc_set_vhi_name(args.xid, UTS_MAPPING[i], args.value, strlen(args.value))==-1) {
192         perror("vc_set_vhi_name()");
193         return EXIT_FAILURE;
194       }
195     }
196     else {
197       char              buf[128];
198       if (vc_get_vhi_name(args.xid, UTS_MAPPING[i], buf, sizeof(buf)-1)==-1) {
199         perror("vc_get_vhi_name()");
200         failed = true;
201         strcpy(buf, "???");
202       }
203       else
204         passed = true;
205       strcat(result_buf, delim);
206       strcat(result_buf, buf);
207       delim = " ";
208     }
209   }
210
211   if (!args.do_set && passed) {
212     strcat(result_buf, "\n");
213     WRITE_STR(1, result_buf);
214   }
215
216   return failed ? passed ? 2 : EXIT_FAILURE : EXIT_SUCCESS;
217 }