| … |  | 
… |  | 
| 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; | 
 | 
 | 
374 |   | 
 | 
 | 
375 | 	for (i = 0; newargs[i]; i++) | 
 | 
 | 
376 | 	  fprintf(stderr, "%d: %s\n", i, newargs[i]); | 
| 345 |  | 
377 |  | 
| 346 | 	execvp(newargs[0], newargs); | 
378 | 	execvp(newargs[0], newargs); | 
| 347 | 	perror("Execution of qemu failed"); | 
379 | 	perror("Execution of qemu failed"); | 
| 348 | 	exit(1); | 
380 | 	exit(1); | 
| 349 | } | 
381 | } | 
| 350 |   | 
 | 
 |