3 // Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
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.
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.
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.
36 #define ENSC_WRAPPERS_PREFIX "vuname: "
37 #define ENSC_WRAPPERS_UNISTD 1
38 #define ENSC_WRAPPERS_IO 1
39 #define ENSC_WRAPPERS_VSERVER 1
42 #define CMD_HELP 0x1000
43 #define CMD_VERSION 0x1001
44 #define CMD_DIR 0x4007
45 #define CMD_MISSINGOK 0x4008
47 int wrapper_exit_code = 255;
49 static vc_uts_type const UTS_MAPPING[7] = {
50 vcVHI_CONTEXT, vcVHI_SYSNAME, vcVHI_NODENAME,
51 vcVHI_RELEASE, vcVHI_VERSION, vcVHI_MACHINE,
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),
67 struct Tag tags[DIM_OF(UTS_MAPPING)];
74 static struct option const
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 },
87 showHelp(int fd, char const *cmd, int res)
89 VSERVER_DECLARE_CMD(cmd);
91 WRITE_MSG(fd, "Usage: ");
94 " [-g] --xid <xid> <TAG>*\n"
98 " -s --xid <xid> -t <TAG>=<VALUE> [--] [<command> <args>*]\n"
102 " --dir <dir> --xid <xid> [--missingok] [--] [<command> <args>*]\n\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"
113 " Possible values for TAG are:\n"
114 " context, sysname, nodename, release, version, machine, domainname\n"
116 "Please report bugs to " PACKAGE_BUGREPORT "\n");
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);
132 setFromDir(char const *pathname, bool is_missingok, xid_t xid)
136 size_t l_pathname = strlen(pathname);
137 char buf[l_pathname + sizeof("/domainname") + 32];
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);
145 memcpy(buf, pathname, l_pathname);
146 if (l_pathname>0 && pathname[l_pathname-1]!='/')
147 buf[l_pathname++] = '/';
149 for (i=0; i<DIM_OF(UTS_STRINGS); ++i) {
150 char * ptr = buf+l_pathname;
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);
159 size_t l = Elseek(fd, 0, SEEK_END);
161 Elseek(fd,0,SEEK_SET);
162 EreadAll(fd, name, l);
163 while (l>0 && name[l-1]=='\n') --l;
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);
176 findUtsIdx(char const *str, size_t len)
179 for (i=0; i<DIM_OF(UTS_STRINGS); ++i)
180 if (UTS_STRINGS[i]!=0 && strncasecmp(UTS_STRINGS[i], str, len)==0)
183 WRITE_MSG(2, "Tag '");
184 Vwrite (2, str, len);
185 WRITE_STR(2, "' not recognized\n");
186 exit(wrapper_exit_code);
190 registerValue(char const *str, struct Tag tags[DIM_OF(UTS_MAPPING)])
192 char const * ptr = strchr(str, '=');
195 if (ptr==0) ptr = str + strlen(str);
196 assert(*ptr=='=' || *ptr=='\0');
198 idx = findUtsIdx(str, ptr-str);
200 if (*ptr=='=') ++ptr;
201 tags[idx].is_set = true;
202 tags[idx].value = ptr;
206 printUtsValue(xid_t xid, int val)
209 if (vc_get_vhi_name(xid, val, buf, sizeof(buf)-1)==-1)
216 int main(int argc, char *argv[])
218 struct Arguments args = {
219 .tags = { [0] = {false,0} },
222 .is_missingok= false,
227 assert(DIM_OF(UTS_MAPPING) == DIM_OF(args.tags));
230 int c = getopt_long(argc, argv, "+gst:", CMDLINE_OPTIONS, 0);
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;
243 WRITE_MSG(2, "Try '");
244 WRITE_STR(2, argv[0]);
245 WRITE_MSG(2, " --help' for more information.\n");
251 if (args.xid==VC_NOCTX) {
252 WRITE_MSG(2, "No context specified; try '--help' for more information\n");
253 exit(wrapper_exit_code);
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));
264 else if (optind==argc) {
265 char const * delim = "";
266 for (i=0; i<DIM_OF(UTS_MAPPING); ++i) {
268 printUtsValue(args.xid, i);
276 char const * delim = "";
277 while (optind <argc) {
278 int idx = findUtsIdx(argv[optind], strlen(argv[optind]));
280 printUtsValue(args.xid, idx);
291 EexecvpD(argv[optind], argv+optind);
293 return wrapper_exit_code;