/[public]/qemu-start/trunk/qemu-start.c
ViewVC logotype

Contents of /qemu-start/trunk/qemu-start.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 290 - (show annotations)
Sat Feb 11 16:27:15 2006 UTC (18 years, 1 month ago) by frodo
File MIME type: text/plain
File size: 3874 byte(s)
Imported sources

1 /*
2 qemu-start.c - Part of qemu-start, a package to start qemu nicely.
3 Copyright (c) 2006 Frodo Looijaard <frodo@frodo.looijaard.name>
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; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #define _GNU_SOURCE /* asprintf */
21 #include <stdio.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include <pwd.h>
25 #include <grp.h>
26 #include <sys/stat.h>
27 #include <sys/ioctl.h>
28 #include <fcntl.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <net/if.h>
32 #include <linux/if_tun.h>
33
34 #define QEMU "/usr/bin/qemu"
35 #define USER "qemu"
36
37 /* Tiny code to open tap/tun device, and hand the fd to qemu.
38 Run as root, drops to given user. */
39 int main(int argc, char *argv[])
40 {
41 struct ifreq ifr;
42 struct passwd *userdata;
43 char *newargs[argc + 2];
44 int i,fd,vlan,tapnr;
45 char *ptr;
46 char *command;
47 char *display;
48
49 /* Check parameters */
50 if (argc < 4) {
51 fprintf(stderr, "Usage: qemu-start TAPDEVNR VLAN SYSTEM <qemu options>...\n");
52 fprintf(stderr, " A device tapTAPDEVNR must have been configured.\n");
53 fprintf(stderr, " VLAN is the Virtual LAN number (just use 0 if unsure).\n");
54 fprintf(stderr, " SYSTEM is the system to emulate. Use \"\" for the current architecture\n");
55 fprintf(stderr, " (uses /usr/bin/qemm); else a binary /usr/bin/qemu-system-SYSTEM is used.\n");
56 exit(1);
57 }
58
59 /* First parameter: TAPDEVNR */
60 tapnr = strtol(argv[1],&ptr,0);
61 if (*ptr) {
62 fprintf(stderr, "Invalid value for TAPDEVNR parameter (use a number!)\n");
63 exit(1);
64 }
65
66 /* Second parameter: VLAN */
67 vlan = strtol(argv[2],&ptr,0);
68 if (*ptr) {
69 fprintf(stderr, "Invalid value for VLAN parameter (use a number!)\n");
70 exit(1);
71 }
72
73 /* Open /dev/net/tun */
74 fd = open("/dev/net/tun", O_RDWR);
75 if (fd < 0) {
76 perror("Could not open /dev/net/tun");
77 exit(1);
78 }
79
80 /* Bind to the right tap device */
81 memset(&ifr, 0, sizeof(ifr));
82 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
83 snprintf(ifr.ifr_name,IFNAMSIZ,"tap%d",tapnr);
84
85 if (ioctl(fd, TUNSETIFF, (void *) &ifr) != 0) {
86 perror("Could not get tap device");
87 exit(1);
88 }
89
90 /* Fix X-display */
91 userdata = getpwuid(getuid());
92 setuid(0);
93 setgid(0);
94 asprintf(&command,"xauth -f ~%s/.Xauthority extract - $(echo $DISPLAY|sed \"s,^localhost,$(hostname)/unix,\") | xauth -f ~%s/.Xauthority merge -; chown %s: ~%s/.Xauthority",userdata->pw_name,USER,USER,USER);
95 system(command);
96
97 /* Set correct userid. */
98 userdata = getpwnam(USER);
99 if (!userdata) {
100 fprintf(stderr, "No user '%s'\n", USER);
101 exit(1);
102 }
103 setgroups(0, NULL);
104 setgid(userdata->pw_gid);
105 if (setuid(userdata->pw_uid) != 0) {
106 perror("setting uid");
107 exit(1);
108 }
109
110 /* Clean the environment */
111 display=getenv("DISPLAY");
112 clearenv();
113 setenv("HOME",userdata->pw_dir,1);
114 setenv("DISPLAY",display,1);
115 setenv("PATH","/usr/bin:/bin:/usr/local/bin",1);
116 setenv("LOGNAME",userdata->pw_name,1);
117 setenv("USER",userdata->pw_name,1);
118
119 /* Create the right qemu invocation */
120 if (!strlen(argv[3]))
121 newargs[0] = QEMU;
122 else
123 asprintf(&newargs[0],"%s-system-%s",QEMU,argv[3]);
124 newargs[1] = "-net";
125 asprintf(&newargs[2],"nic,vlan=%d",vlan);
126 newargs[3] = "-net";
127 asprintf(&newargs[4],"tap,fd=%d,vlan=%d",fd,vlan);
128 for (i = 4; i <= argc; i++)
129 newargs[i+1] = argv[i];
130
131 execvp(newargs[0], newargs);
132 exit(1);
133 }

frodo@frodo.looijaard.name
ViewVC Help
Powered by ViewVC 1.1.26