vtag.c (5340B)
1 // $Id$ --*- c -*-- 2 3 // Copyright (C) 2007 Daniel Hokka Zakrisson 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 25 #include <vserver.h> 26 #include <getopt.h> 27 #include <errno.h> 28 #include <sys/types.h> 29 30 31 #define ENSC_WRAPPERS_PREFIX "vtag: " 32 #define ENSC_WRAPPERS_VSERVER 1 33 #include <wrappers.h> 34 35 #define CMD_HELP 0x1000 36 #define CMD_VERSION 0x1001 37 #define CMD_TAG 0x4000 38 #define CMD_CREATE 0x4001 39 #define CMD_MIGRATE 0x4002 40 #define CMD_SILENTEXIST 0x4003 41 #define CMD_SILENT 0x4004 42 43 44 struct option const 45 CMDLINE_OPTIONS[] = { 46 { "help", no_argument, 0, CMD_HELP }, 47 { "version", no_argument, 0, CMD_VERSION }, 48 { "tag", required_argument, 0, CMD_TAG }, 49 { "create", no_argument, 0, CMD_CREATE }, 50 { "migrate", no_argument, 0, CMD_MIGRATE }, 51 { "silent", no_argument, 0, CMD_SILENT }, 52 { "silentexist", no_argument, 0, CMD_SILENTEXIST }, 53 { 0,0,0,0 }, 54 }; 55 56 struct Arguments { 57 bool do_create; 58 bool do_migrate; 59 bool is_silentexist; 60 int verbosity; 61 tag_t tag; 62 }; 63 64 int wrapper_exit_code = 255; 65 66 static void 67 showHelp(int fd, char const *cmd, int res) 68 { 69 WRITE_MSG(fd, "Usage:\n "); 70 WRITE_STR(fd, cmd); 71 WRITE_MSG(fd, 72 " (--create|--migrate) --tag <tag> <opts>* [--] <program> <args>*\n " 73 "\n" 74 "<opts> can be:\n" 75 " --silentexist ... be silent when context exists already; useful\n" 76 " for '--create' only\n" 77 " --silent ... if the feature is not supported, just execute\n" 78 " <program>\n" 79 "\n" 80 "'vtag --create' exits with code 254 iff the context exists already.\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 "vtag " VERSION " -- sets the process's filesystem tag\n" 92 "This program is part of " PACKAGE_STRING "\n\n" 93 "Copyright (C) 2007 Daniel Hokka Zakrisson\n" 94 VERSION_COPYRIGHT_DISCLAIMER); 95 exit(0); 96 } 97 98 static inline ALWAYSINLINE int 99 doit(struct Arguments const *args, char *argv[]) 100 { 101 tag_t tag; 102 103 if (!vc_isSupported(vcFEATURE_PPTAG)) { 104 if (args->verbosity >= 1) { 105 errno = ENOSYS; 106 perror(ENSC_WRAPPERS_PREFIX); 107 return wrapper_exit_code; 108 } 109 else 110 goto exec; 111 } 112 if (args->tag == VC_DYNAMIC_XID) { 113 if (args->verbosity >= 1) { 114 WRITE_MSG(2, "You must specify the tag with '--tag'; try '--help' for more information\n"); 115 return wrapper_exit_code; 116 } 117 else { 118 WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "WARNING: A dynamic tag has been specified, this is not supported\n"); 119 goto exec; 120 } 121 } 122 123 if (args->do_create) { 124 tag = vc_tag_create(args->tag); 125 if (tag==VC_NOCTX) { 126 switch (errno) { 127 case EEXIST : 128 if (!args->is_silentexist) 129 perror(ENSC_WRAPPERS_PREFIX "vc_tag_create()"); 130 return 254; 131 default : 132 perror(ENSC_WRAPPERS_PREFIX "vc_tag_create()"); 133 return wrapper_exit_code; 134 } 135 } 136 } 137 else 138 tag = args->tag; 139 140 if (args->do_migrate) 141 Evc_tag_migrate(tag); 142 143 exec: 144 execvp(argv[optind], argv+optind); 145 146 PERROR_Q(ENSC_WRAPPERS_PREFIX "execvp", argv[optind]); 147 return wrapper_exit_code; 148 } 149 150 int main (int argc, char *argv[]) 151 { 152 struct Arguments args = { 153 .tag = VC_DYNAMIC_XID, 154 .do_create = false, 155 .do_migrate = false, 156 .is_silentexist = false, 157 .verbosity = 1, 158 }; 159 160 while (1) { 161 int c = getopt_long(argc, argv, "+", CMDLINE_OPTIONS, 0); 162 if (c==-1) break; 163 164 switch (c) { 165 case CMD_HELP : showHelp(1, argv[0], 0); 166 case CMD_VERSION : showVersion(); 167 case CMD_CREATE : args.do_create = true; break; 168 case CMD_MIGRATE : args.do_migrate = true; break; 169 case CMD_SILENTEXIST : args.is_silentexist = true; break; 170 case CMD_TAG : args.tag = Evc_tagopt2tag(optarg,true); break; 171 case CMD_SILENT : args.verbosity--; break; 172 173 default : 174 WRITE_MSG(2, "Try '"); 175 WRITE_STR(2, argv[0]); 176 WRITE_MSG(2, " --help' for more information.\n"); 177 return wrapper_exit_code; 178 break; 179 } 180 } 181 182 if (!args.do_create && !args.do_migrate) 183 WRITE_MSG(2, "Neither '--create' nor '--migrate' specified; try '--help' for more information\n"); 184 else if (args.do_create && args.do_migrate) 185 WRITE_MSG(2, "Can not specify '--create' and '--migrate' at the same time; try '--help' for more information\n"); 186 else if (optind>=argc) 187 WRITE_MSG(2, "No command given; use '--help' for more information.\n"); 188 else 189 return doit(&args, argv); 190 191 return wrapper_exit_code; 192 }