… | |
… | |
31 | #include <net/if.h> |
31 | #include <net/if.h> |
32 | #include <linux/if_tun.h> |
32 | #include <linux/if_tun.h> |
33 | #include <sys/wait.h> |
33 | #include <sys/wait.h> |
34 | #include <errno.h> |
34 | #include <errno.h> |
35 | |
35 | |
|
|
36 | /* Autogenerated by gengetopt */ |
|
|
37 | #include "cmdline.h" |
|
|
38 | |
36 | /* This define is present in recent glibc, it is not available on sarge */ |
39 | /* This define is present in recent glibc, it is not available on sarge */ |
37 | #ifndef HOST_NAME_MAX |
40 | #ifndef HOST_NAME_MAX |
38 | #define HOST_NAME_MAX 64 |
41 | #define HOST_NAME_MAX 64 |
39 | #endif |
42 | #endif |
40 | |
43 | |
… | |
… | |
187 | perror("close of pfd[1] failed"); |
190 | perror("close of pfd[1] failed"); |
188 | exit(1); |
191 | exit(1); |
189 | } |
192 | } |
190 | |
193 | |
191 | if (asprintf(&xauthfile,"%s/.Xauthority",userdata->pw_dir) < 1) { |
194 | if (asprintf(&xauthfile,"%s/.Xauthority",userdata->pw_dir) < 1) { |
192 | perror("Constructing xauthority filename failed"); |
195 | perror("Constructing xauthority filename failed"); |
193 | exit(1); |
196 | exit(1); |
194 | } |
197 | } |
195 | |
198 | |
196 | execl("/usr/bin/X11/xauth","/usr/bin/X11/xauth","-f",xauthfile,"merge","-",NULL); |
199 | execl("/usr/bin/X11/xauth","/usr/bin/X11/xauth","-f",xauthfile,"merge","-",NULL); |
197 | exit(1); |
200 | exit(1); |
… | |
… | |
214 | if (pid < 1) { |
217 | if (pid < 1) { |
215 | perror("wait failed"); |
218 | perror("wait failed"); |
216 | exit(1); |
219 | exit(1); |
217 | } |
220 | } |
218 | if (! WIFEXITED(status) || WEXITSTATUS(status)) { |
221 | if (! WIFEXITED(status) || WEXITSTATUS(status)) { |
219 | fprintf(stderr,"Child returned error"); |
222 | fprintf(stderr,"Child returned error\n"); |
220 | exit(1); |
223 | exit(1); |
221 | } |
224 | } |
222 | } |
225 | } |
223 | } |
226 | } |
224 | |
227 | |
… | |
… | |
228 | int main(int argc, char *argv[]) |
231 | int main(int argc, char *argv[]) |
229 | { |
232 | { |
230 | struct ifreq ifr; |
233 | struct ifreq ifr; |
231 | struct passwd *userdata; |
234 | struct passwd *userdata; |
232 | char *newargs[argc + 2]; |
235 | char *newargs[argc + 2]; |
233 | int i,fd,vlan,tapnr; |
236 | int fd,vlan,tapnr; |
234 | char *ptr; |
237 | unsigned int i; |
|
|
238 | unsigned new_arg_count = 5; |
|
|
239 | struct gengetopt_args_info args_info; |
235 | char *display; |
240 | char *display; |
|
|
241 | char *system; |
|
|
242 | char *topleft; |
236 | |
243 | |
237 | /* Check parameters */ |
244 | /* Ugly fix because gengetopt 2.18 does not have the `usage' option */ |
238 | if (argc < 4) { |
245 | gengetopt_args_info_usage = "qemu-start [OPTIONS] -- [OPTIONS for QEMU]"; |
239 | fprintf(stderr, "Usage: qemu-start TAPDEVNR VLAN SYSTEM <qemu options>...\n"); |
246 | |
240 | fprintf(stderr, " A device tapTAPDEVNR must have been configured.\n"); |
247 | if (cmdline_parser(argc, argv, &args_info)) |
241 | fprintf(stderr, " VLAN is the Virtual LAN number (just use 0 if unsure).\n"); |
248 | exit(1); |
242 | fprintf(stderr, " SYSTEM is the system to emulate. Use \"\" for the current architecture\n"); |
249 | |
243 | fprintf(stderr, " (uses /usr/bin/qemm); else a binary /usr/bin/qemu-system-SYSTEM is used.\n"); |
250 | /* parameter: TAPDEVNR */ |
|
|
251 | tapnr = args_info.tapnr_arg; |
|
|
252 | |
|
|
253 | /* parameter: VLAN */ |
|
|
254 | vlan = args_info.vlan_arg; |
|
|
255 | |
|
|
256 | /* parameter: System type */ |
|
|
257 | if (args_info.system_given) { |
|
|
258 | if (index(args_info.system_arg,'/')) { |
|
|
259 | fprintf(stderr, "Invalid value `%s' for system (may not contain a slash character)\n", args_info.system_arg); |
244 | exit(1); |
260 | exit(1); |
245 | } |
261 | } |
|
|
262 | asprintf(&system, "%s", args_info.system_arg); |
|
|
263 | } |
246 | |
264 | |
247 | /* First parameter: TAPDEVNR */ |
265 | /* parameters: Window location */ |
248 | tapnr = strtol(argv[1],&ptr,0); |
266 | if (args_info.window_left_given || args_info.window_top_given) { |
249 | if (*ptr) { |
267 | if (!(args_info.window_left_given && args_info.window_top_given)) { |
250 | fprintf(stderr, "Invalid value `%s' for TAPDEVNR parameter (use a number!)\n",argv[1]); |
268 | fprintf(stderr,("If either window-left (x) or window-top (y) are given, then both must be given\n")); |
251 | exit(1); |
269 | exit(1); |
252 | } |
270 | } |
253 | |
271 | if (asprintf(&topleft, "%d,%d",args_info.window_left_arg,args_info.window_top_arg) < 0) { |
254 | /* Second parameter: VLAN */ |
272 | perror("Preparing top-left environment value string failed"); |
255 | vlan = strtol(argv[2],&ptr,0); |
|
|
256 | if (*ptr) { |
|
|
257 | fprintf(stderr, "Invalid value `%s' for VLAN parameter (use a number!)\n", argv[2]); |
|
|
258 | exit(1); |
273 | exit(1); |
259 | } |
274 | } |
260 | |
|
|
261 | /* Third parameter: System type */ |
|
|
262 | if (index(argv[3],'/')) { |
|
|
263 | fprintf(stderr, "Invalid value `%s' for system (may not contain a slash character)\n", argv[3]); |
|
|
264 | exit(1); |
|
|
265 | } |
275 | } |
266 | |
276 | |
267 | /* Export the xauth data */ |
277 | /* Export the xauth data */ |
268 | fix_xauthority(); |
278 | fix_xauthority(); |
269 | |
279 | |
… | |
… | |
320 | setenv("LOGNAME",userdata->pw_name,1) || |
330 | setenv("LOGNAME",userdata->pw_name,1) || |
321 | setenv("USER",userdata->pw_name,1)) { |
331 | setenv("USER",userdata->pw_name,1)) { |
322 | perror("Setting environment failed"); |
332 | perror("Setting environment failed"); |
323 | exit(1); |
333 | exit(1); |
324 | } |
334 | } |
|
|
335 | if (args_info.window_left_given || args_info.window_top_given) { |
|
|
336 | if (setenv("SDL_VIDEO_WINDOW_POS", topleft, 1)) { |
|
|
337 | perror("Setting top-left environment value failed"); |
|
|
338 | exit(1); |
|
|
339 | } |
|
|
340 | } |
325 | |
341 | |
326 | /* Create the right qemu invocation */ |
342 | /* Create the right qemu invocation */ |
327 | if (!strlen(argv[3])) |
343 | if (!args_info.system_given) |
328 | newargs[0] = QEMU; |
344 | newargs[0] = QEMU; |
329 | else if (asprintf(&newargs[0],"%s-system-%s",QEMU,argv[3]) < 0) { |
345 | else if (asprintf(&newargs[0],"%s-system-%s",QEMU,args_info.system_arg) < 0) { |
330 | perror("Preparing qemu executable filename failed"); |
346 | perror("Preparing qemu executable filename failed"); |
331 | exit(1); |
347 | exit(1); |
332 | } |
348 | } |
333 | newargs[1] = "-net"; |
349 | newargs[1] = "-net"; |
334 | if (asprintf(&newargs[2],"nic,vlan=%d",vlan) < 0) { |
350 | if (asprintf(&newargs[2],"nic,vlan=%d",vlan) < 0) { |
335 | perror("Preparing nic argument failed"); |
351 | perror("Preparing nic argument failed"); |
336 | exit(1); |
352 | exit(1); |
337 | } |
353 | } |
|
|
354 | if (args_info.macaddr_given) { |
|
|
355 | if (asprintf(&newargs[2], "%s,mac=%s", newargs[2], args_info.macaddr_arg) < 0) { |
|
|
356 | perror("Adding macaddress to nic argument failed"); |
|
|
357 | } |
|
|
358 | } |
|
|
359 | if (args_info.nic_model_given) { |
|
|
360 | if (asprintf(&newargs[2], "%s,model=%s", newargs[2], args_info.nic_model_arg) < 0) { |
|
|
361 | perror("Adding nic model to nic argument failed"); |
|
|
362 | } |
|
|
363 | } |
338 | newargs[3] = "-net"; |
364 | newargs[3] = "-net"; |
339 | if (asprintf(&newargs[4],"tap,fd=%d,vlan=%d",fd,vlan) < 0) { |
365 | if (asprintf(&newargs[4],"tap,fd=%d,vlan=%d",fd,vlan) < 0) { |
340 | perror("Preparing tap argument failed"); |
366 | perror("Preparing tap argument failed"); |
341 | exit(1); |
367 | exit(1); |
342 | } |
368 | } |
343 | for (i = 4; i <= argc; i++) |
369 | for (i = 0; i < args_info.inputs_num; i++) { |
344 | newargs[i+1] = argv[i]; |
370 | newargs[i+5] = args_info.inputs[i]; |
|
|
371 | new_arg_count++; |
|
|
372 | } |
|
|
373 | newargs[new_arg_count] = NULL; |
345 | |
374 | |
346 | execvp(newargs[0], newargs); |
375 | execvp(newargs[0], newargs); |
347 | perror("Execution of qemu failed"); |
376 | perror("Execution of qemu failed"); |
348 | exit(1); |
377 | exit(1); |
349 | } |
378 | } |
350 | |
|
|