Use the host's /etc/resolv.conf by default.
[util-vserver.git] / src / vattribute.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 "util.h"
24 #include "attribute-util.h"
25 #include <lib/vserver.h>
26
27 #include <getopt.h>
28 #include <stdint.h>
29 #include <errno.h>
30
31 #define ENSC_WRAPPERS_PREFIX    "vattribute: "
32 #define ENSC_WRAPPERS_VSERVER   1
33 #define ENSC_WRAPPERS_UNISTD    1
34 #include <wrappers.h>
35
36 #define CMD_HELP                0x1000
37 #define CMD_VERSION             0x1001
38 #define CMD_XID                 0x2000
39 #define CMD_SET                 0x2001
40 #define CMD_CCAP                0x2002
41 #define CMD_FLAG                0x2003
42 #define CMD_SECURE              0x2004
43 #define CMD_BCAP                0x2005
44 #define CMD_GET                 0x2006
45
46 int                     wrapper_exit_code = 1;
47
48 struct option const
49 CMDLINE_OPTIONS[] = {
50   { "help",       no_argument,       0, CMD_HELP },
51   { "version",    no_argument,       0, CMD_VERSION },
52   { "xid",        required_argument, 0, CMD_XID },
53   { "set",        no_argument,       0, CMD_SET },
54   { "get",        no_argument,       0, CMD_GET },
55   { "ccap",       required_argument, 0, CMD_CCAP },
56   { "bcap",       required_argument, 0, CMD_BCAP },
57   { "flag",       required_argument, 0, CMD_FLAG },
58   { "secure",     no_argument,       0, CMD_SECURE },
59   {0,0,0,0}
60 };
61
62 struct Arguments {
63     xid_t               xid;
64     struct vc_ctx_flags flags;
65     struct vc_ctx_caps  caps;
66     int                 mode;
67 };
68
69 static void
70 showHelp(int fd, char const *cmd, int res)
71 {
72   WRITE_MSG(fd, "Usage:\n    ");
73   WRITE_STR(fd, cmd);
74   WRITE_MSG(fd,
75             " [--xid <xid>] {--get|--set [--bcap [~!]<cap>] [--ccap [~!]<cap>]\n"
76             "    [--flag [~!]<flag>] [--secure]} -- [<program> <args>*]\n"
77             "\n"
78             " --bcap <cap>   ...  system  capability to be set\n"
79             " --ccap <cap>   ...  context capability to be set\n"
80             " --flag <flag>  ...  context flag to be set\n"
81             "\n"
82             "Please report bugs to " PACKAGE_BUGREPORT "\n");
83
84   exit(res);
85 }
86
87 static void
88 showVersion()
89 {
90   WRITE_MSG(1,
91             "vattribute " VERSION " -- sets/gets attributes of vservers\n"
92             "This program is part of " PACKAGE_STRING "\n\n"
93             "Copyright (C) 2004 Enrico Scholz\n"
94             VERSION_COPYRIGHT_DISCLAIMER);
95   exit(0);
96 }
97
98 static void
99 parseFlags(char const *str, struct vc_ctx_flags *flags)
100 {
101   struct vc_err_listparser      err;
102   int                           rc;
103
104   rc = vc_list2cflag(str,0, &err, flags);
105   
106   if (rc==-1) {
107     WRITE_MSG(2, "Unknown flag '");
108     Vwrite(2, err.ptr, err.len);
109     WRITE_MSG(2, "'\n");
110     exit(wrapper_exit_code);
111   }
112 }
113
114 static void
115 parseBCaps(char const *str, struct vc_ctx_caps *caps)
116 {
117   struct vc_err_listparser      err;
118   int                           rc;
119
120   rc = vc_list2bcap(str,0, &err, caps);
121   
122   if (rc==-1) {
123     WRITE_MSG(2, "Unknown bcap '");
124     Vwrite(2, err.ptr, err.len);
125     WRITE_MSG(2, "'\n");
126     exit(wrapper_exit_code);
127   }
128 }
129
130 static void
131 parseCCaps(char const *str, struct vc_ctx_caps *caps)
132 {
133   struct vc_err_listparser      err;
134   int                           rc;
135
136   rc = vc_list2ccap(str,0, &err, caps);
137   
138   if (rc==-1) {
139     WRITE_MSG(2, "Unknown ccap '");
140     Vwrite(2, err.ptr, err.len);
141     WRITE_MSG(2, "'\n");
142     exit(wrapper_exit_code);
143   }
144 }
145
146 static void
147 parseSecure(struct vc_ctx_flags UNUSED * flags,
148             struct vc_ctx_caps  UNUSED * caps)
149 {
150   caps->ccaps = ~vc_get_insecureccaps();
151   caps->cmask = ~0ull;
152   caps->bcaps = ~vc_get_insecurebcaps();
153   caps->bmask = ~0ull;
154
155     // TODO: generalize this
156   flags->flagword = VC_VXF_HIDE_NETIF;
157   flags->mask     = VC_VXF_HIDE_NETIF;
158 }
159
160 static int
161 printAttrs(struct Arguments *args)
162 {
163   struct vc_ctx_flags flags;
164   struct vc_ctx_caps caps;
165
166   Evc_get_cflags(args->xid, &flags);
167   Evc_get_ccaps(args->xid, &caps);
168
169   print_bitfield(1, bcap, "bcapabilities", &caps.bcaps);
170   print_bitfield(1, ccap, "ccapabilities", &caps.ccaps);
171   print_bitfield(1, cflag, "flags", &flags.flagword);
172
173   return 0;
174 }
175
176 int main(int argc, char *argv[])
177 {
178   struct Arguments              args = {
179     .xid   = VC_NOCTX,
180     .flags = { .flagword = 0, .mask = 0 },
181     .caps  = { .bcaps = 0, .bmask = 0,.ccaps = 0, .cmask = 0 },
182     .mode  = CMD_SET,
183   };
184
185   while (1) {
186     int         c = getopt_long(argc, argv, "+", CMDLINE_OPTIONS, 0);
187     if (c==-1) break;
188
189     switch (c) {
190       case CMD_HELP     :  showHelp(1, argv[0], 0);
191       case CMD_VERSION  :  showVersion();
192       case CMD_SET      :  args.mode = CMD_SET;                    break;
193       case CMD_GET      :  args.mode = CMD_GET;                    break;
194       case CMD_XID      :  args.xid = Evc_xidopt2xid(optarg,true); break;
195       case CMD_FLAG     :  parseFlags(optarg, &args.flags);        break;
196       case CMD_CCAP     :  parseCCaps(optarg, &args.caps);         break;
197       case CMD_BCAP     :  parseBCaps(optarg, &args.caps);         break;
198       case CMD_SECURE   :  parseSecure(&args.flags, &args.caps);   break;
199       default           :
200         WRITE_MSG(2, "Try '");
201         WRITE_STR(2, argv[0]);
202         WRITE_MSG(2, " --help' for more information.\n");
203         return 255;
204         break;
205     }
206   }
207
208   if (args.xid==VC_NOCTX) args.xid = Evc_get_task_xid(0);
209
210   if (args.mode == CMD_SET) {
211     if ((args.caps.cmask || args.caps.bmask) &&
212         vc_set_ccaps(args.xid, &args.caps)==-1)
213       perror(ENSC_WRAPPERS_PREFIX "vc_set_ccaps()");
214     else if (args.flags.mask &&
215              vc_set_cflags(args.xid, &args.flags)==-1)
216       perror(ENSC_WRAPPERS_PREFIX "vc_set_flags()");
217     else if (optind<argc)
218       EexecvpD(argv[optind], argv+optind);
219     else
220       return EXIT_SUCCESS;
221   }
222   else if (args.mode == CMD_GET) {
223     printAttrs(&args);
224     if (optind<argc)
225       EexecvpD(argv[optind], argv+optind);
226     else
227       return EXIT_SUCCESS;
228   }
229
230   return EXIT_FAILURE;
231 }