1<?php 2 3/* 4 * haiku.php - an online Haiku demo using qemu and vnc. 5 * Copyright 2007, Francois Revol, revol@free.fr. 6 */ 7 8// relative path to the vnc java applet jar 9// you must *copy* (apache doesn't seem to like symlinks) it there. 10 11// on debian, apt-get install vnc-java will put them in 12// /usr/share/vnc-java 13//define("VNCJAVA_PATH", "vnc-java"); 14//define("VNCJAR", "vncviewer.jar"); 15//define("VNCCLASS", "vncviewer.class"); 16 17// to use the tightvnc applet instead (supports > 8bpp): 18// on debian, apt-get install tightvnc-java will put them in 19// /usr/share/tightvnc-java 20define("VNCJAVA_PATH", "tightvnc-java"); 21define("VNCJAR", "VncViewer.jar"); 22define("VNCCLASS", "VncViewer.class"); 23 24// maximum count of qemu instances. 25define("MAX_QEMUS", 8); 26 27// size of the java applet, must match the default resolution of the image. 28define("APPLET_WIDTH", "800"); 29define("APPLET_HEIGHT", "600"); 30// vnc protocol base port. 31define("VNCPORTBASE", 5900); 32 33// timeout before the demo session is killed, as argument to /bin/sleep 34define("SESSION_TIMEOUT", "10m"); 35 36// path to qemu binary 37//define("QEMU_BIN", "/usr/bin/qemu"); 38define("QEMU_BIN", "/usr/local/bin/qemu"); 39// default arguments: no network, emulate tablet, readonly image file. 40define("QEMU_ARGS","-net none -usbdevice wacom-tablet -k en-us -snapshot"); 41//define("QEMU_ARGS","-net none -usbdevice wacom-tablet -k fr -snapshot"); 42// absolute path to the image. 43define("QEMU_IMAGE_PATH","/home/revol/haiku/trunk/generated.x86/haiku.image"); 44// qemu 0.8.2 needs "", qemu 0.9.1 needs ":" 45define("QEMU_VNC_PREFIX", ":"); 46 47// name of session and pid files in /tmp 48define("QEMU_SESSFILE_TMPL", "qemu-haiku-session-"); 49define("QEMU_PIDFILE_TMPL", "qemu-haiku-pid-"); 50// name of session variable holding the qemu slot; not yet used correctly 51define("QEMU_IDX_VAR", "QEMU_HAIKU_SESSION_VAR"); 52 53session_start(); 54 55if (isset($_GET['frame'])) { 56} 57 58?> 59<html> 60<head> 61<title>Haiku Test</title> 62</head> 63<script> 64function onPageUnload() { 65 //window.open("<?php echo $_SERVER["SCRIPT_NAME"] . "?close"; ?>", "closing", "width=100,height=30,location=no,menubar=no,toolbar=no,scrollbars=no"); 66} 67</script> 68<?php 69 70 71// statics 72 73$count = $_SESSION['compteur']; 74//$count = $GLOBALS['compteur']; 75$closing = 0; 76if (isset($_GET['close'])) { 77 $closing = 1; 78 echo "<body>"; 79} else 80 echo "<body onunload=\"onPageUnload();\">"; 81 82function dbg($str) 83{ 84 echo "<div class=\"debug\">$str</div>\n"; 85} 86 87function err($str) 88{ 89 echo "<div class=\"error\">$str</div>\n"; 90} 91 92function make_qemu_sessionfile_name($idx) 93{ 94 return "/tmp/" . QEMU_SESSFILE_TMPL . $idx; 95} 96 97function make_qemu_pidfile_name($idx) 98{ 99 return "/tmp/" . QEMU_PIDFILE_TMPL . $idx; 100} 101 102function find_qemu_slot() 103{ 104 for ($idx = 0; $idx < MAX_QEMUS; $idx++) { 105 $pidfile = make_qemu_pidfile_name($idx); 106 $sessfile = make_qemu_sessionfile_name($idx); 107 dbg("checking \"$pidfile\", \"$sessfile\"..."); 108 if (!file_exists($pidfile) && !file_exists($sessfile)) { 109 file_put_contents($sessfile, session_id()); 110 $sid = file_get_contents($sessfile); 111 if ($sid != session_id()) 112 continue; 113 $_SESSION[QEMU_IDX_VAR] = $idx; 114 return $idx; 115 } 116 } 117 return -1; 118} 119 120function qemu_slot() 121{ 122 return $_SESSION[QEMU_IDX_VAR]; 123} 124 125function vnc_display() 126{ 127 return qemu_slot(); 128} 129 130function vnc_port() 131{ 132 return VNCPORTBASE + vnc_display(); 133} 134 135function is_my_session_valid() 136{ 137 if (!isset($_SESSION[QEMU_IDX_VAR])) 138 return 0; 139 $idx = $_SESSION[QEMU_IDX_VAR]; 140 $sessfile = make_qemu_sessionfile_name($idx); 141 if (!file_exists($sessfile)) 142 return 0; 143 $qemusession=file_get_contents($sessfile); 144 // has expired 145 if ($qemusession != session_id()) { 146 return 0; 147 } 148 return 1; 149} 150 151 152function start_qemu() 153{ 154 $idx = find_qemu_slot(); 155 if ($idx < 0) { 156 err("No available qemu slot, please try later."); 157 return $idx; 158 } 159 $pidfile = make_qemu_pidfile_name($idx); 160 $cmd = QEMU_BIN . " " . QEMU_ARGS . " -vnc " . QEMU_VNC_PREFIX . vnc_display() . " -pidfile " . $pidfile . " " . QEMU_IMAGE_PATH; 161 162 if (file_exists($pidfile)) 163 unlink($pidfile); 164 dbg("Starting <tt>" . $cmd . "</tt>..."); 165 166 $descriptorspec = array( 167 // 0 => array("pipe", "r"), // stdin 168 // 1 => array("pipe", "w"), // stdout 169 // 2 => array("pipe", "w") // stderr 170 ); 171 //$cmd="/bin/ls"; 172 //passthru($cmd, $ret); 173 //dbg("ret=$ret"); 174 $cmd .= " &"; 175 $process = proc_open($cmd, $descriptorspec, $pipes); 176 sleep(1); 177 proc_close($process); 178 179 dbg("Started QEMU."); 180 $sessfile = make_qemu_sessionfile_name($idx); 181 $cmd = "(sleep " . SESSION_TIMEOUT . "; kill -9 `cat " . $pidfile . "`; rm " . $pidfile . " " . $sessfile . ") &"; 182 183 $process = proc_open($cmd, $descriptorspec, $wkpipes); 184 sleep(1); 185 proc_close($process); 186 187 dbg("Started timed kill."); 188 dbg("Ready for a " . SESSION_TIMEOUT . " session."); 189} 190 191 192function output_applet_code() 193{ 194 $w = APPLET_WIDTH; 195 $h = APPLET_HEIGHT; 196 $port = vnc_port(); 197 $vncjpath = VNCJAVA_PATH; 198 $jar = VNCJAR; 199 $class = VNCCLASS; 200 echo "<applet code=$class codebase=\"$vncjpath/\" archive=\"$vncjpath/$jar\" width=$w height=$h> 201 <param name=\"PORT\" value=\"$port\"> 202 <!param name=\"HOST\" value=\"$HTTP_HOST\"><!-- no need --> 203 <param name=\"PORT\" value=\"$port\"> 204 <param name=\"PASSWORD\" value=\"\"> 205 There should be a java applet here... make sure you have a JVM and it's enabled! 206 </applet>"; 207} 208 209dbg("Checking if session is running..."); 210 211if (is_my_session_valid()) { 212 dbg("Session running"); 213 $qemuidx = qemu_slot(); 214} else if ($closing != 1) { 215 dbg("Need to start qemu"); 216 217 $qemuidx = start_qemu(); 218} 219 220if ($qemuidx >= 0) { 221 if ($closing) { 222 dbg("closing..."); 223 unlink(make_qemu_sessionfile_name($qemuidx)); 224 //unlink(make_qemu_sessionfile_name($qemuidx)); 225 sleep(1); 226 //echo "<script> self.close(\"closing\"); </script>"; 227 } else { 228 dbg("Waiting for vnc server..."); 229 sleep(5); 230 output_applet_code(); 231 } 232} 233 234 235 236?> 237 238</body> 239</html> 240