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