You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by we...@apache.org on 2013/06/26 11:30:27 UTC

[17/25] add patches for leaseweb

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/tests/cursor.html
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/tests/cursor.html b/patches/systemvm/debian/config/root/lswcp/tests/cursor.html
new file mode 100644
index 0000000..91e621b
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/tests/cursor.html
@@ -0,0 +1,135 @@
+<!DOCTYPE html> 
+<html xmlns="http://www.w3.org/1999/xhtml"> 
+  <head> 
+    <title>Cursor Change test</title> 
+    <meta charset="UTF-8"> 
+    <!--
+    <script type='text/javascript' 
+                    src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
+    -->
+    <script src="../include/util.js"></script> 
+    <script src="../include/webutil.js"></script> 
+    <script src="../include/base64.js"></script> 
+    <script src="../include/canvas.js"></script> 
+  </head> 
+  <body> 
+        <h1>Roll over the buttons to test cursors</h1>
+        <br>
+        <input id=button1 type="button" value="Cursor from file (smiley face)">
+        <input id=button2 type="button" value="Data URI cursor (crosshair)">
+    
+        <br> 
+        <br> 
+        <br> 
+        Debug:<br> 
+        <textarea id="debug" style="font-size: 9px;" cols=80 rows=25></textarea> 
+        <br>
+        <br>
+        <canvas id="testcanvas" width="100px" height="20px">
+            Canvas not supported.
+        </canvas>
+    
+  </body> 
+ 
+  <script> 
+    function debug(str) {
+        console.log(str);
+        cell = $D('debug');
+        cell.innerHTML += str + "\n";
+        cell.scrollTop = cell.scrollHeight;
+    }
+
+    function makeCursor() {
+        var arr = [], x, y, w = 32, h = 32, hx = 16, hy = 16;
+
+        var IHDRsz = 40;
+        var ANDsz = w * h * 4;
+        var XORsz = Math.ceil( (w * h) / 8.0 );
+
+        // Push multi-byte little-endian values
+        arr.push16le = function (num) {
+            this.push((num     ) & 0xFF,
+                      (num >> 8) & 0xFF  );
+        };
+        arr.push32le = function (num) {
+            this.push((num      ) & 0xFF,
+                      (num >>  8) & 0xFF,
+                      (num >> 16) & 0xFF,
+                      (num >> 24) & 0xFF  );
+        };
+
+        // Main header
+        arr.push16le(0);      // Reserved
+        arr.push16le(2);      // .CUR type
+        arr.push16le(1);      // Number of images, 1 for non-animated arr
+
+        // Cursor #1
+        arr.push(w);          // width
+        arr.push(h);          // height
+        arr.push(0);          // colors, 0 -> true-color
+        arr.push(0);          // reserved
+        arr.push16le(hx);     // hotspot x coordinate
+        arr.push16le(hy);     // hotspot y coordinate
+        arr.push32le(IHDRsz + XORsz + ANDsz); // cursor data byte size
+        arr.push32le(22);     // offset of cursor data in the file
+
+        // Infoheader for Cursor #1
+        arr.push32le(IHDRsz); // Infoheader size
+        arr.push32le(w);      // Cursor width
+        arr.push32le(h*2);    // XOR+AND height
+        arr.push16le(1);      // number of planes
+        arr.push16le(32);     // bits per pixel
+        arr.push32le(0);      // type of compression
+        arr.push32le(XORsz + ANDsz); // Size of Image
+        arr.push32le(0);
+        arr.push32le(0);
+        arr.push32le(0);
+        arr.push32le(0);
+
+        // XOR/color data
+        for (y = h-1; y >= 0; y--) {
+            for (x = 0; x < w; x++) {
+                //if ((x === hx) || (y === (h-hy-1))) {
+                if ((x === hx) || (y === hy)) {
+                    arr.push(0xe0);  // blue
+                    arr.push(0x00);  // green
+                    arr.push(0x00);  // red
+                    arr.push(0xff);  // alpha
+                } else {
+                    arr.push(0x05);  // blue
+                    arr.push(0xe6);  // green
+                    arr.push(0x00);  // red
+                    arr.push(0x80);  // alpha
+                }
+            }
+        }
+
+        // AND/bitmask data (seems to be ignored)
+        for (y = 0; y < h; y++) {
+            for (x = 0; x < Math.ceil(w / 8); x++) {
+                arr.push(0x00);
+            }
+        }
+
+        debug("cursor generated");
+        return arr;
+    }
+ 
+    window.onload = function() {
+        debug("onload");
+        var canvas, cross, cursor, cursor64;
+
+        canvas = new Canvas({'target' : $D("testcanvas")});
+        debug("canvas indicates Data URI cursor support is: " + canvas.get_cursor_uri());
+
+        $D('button1').style.cursor="url(face.png), default";
+
+        cursor = makeCursor();
+        cursor64 = Base64.encode(cursor);
+        //debug("cursor: " + cursor.slice(0,100) + " (" + cursor.length + ")");
+        //debug("cursor64: " + cursor64.slice(0,100) + " (" + cursor64.length + ")");
+        $D('button2').style.cursor="url(data:image/x-icon;base64," + cursor64 + "), default";
+
+        debug("onload complete");
+    }
+  </script> 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/tests/face.png.js
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/tests/face.png.js b/patches/systemvm/debian/config/root/lswcp/tests/face.png.js
new file mode 100644
index 0000000..e0b5d6c
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/tests/face.png.js
@@ -0,0 +1 @@
+var face64 = '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';

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/tests/input.html
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/tests/input.html b/patches/systemvm/debian/config/root/lswcp/tests/input.html
new file mode 100644
index 0000000..248d24e
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/tests/input.html
@@ -0,0 +1,118 @@
+<!DOCTYPE html>
+<html>
+    <head><title>Input Test</title></head>
+    <body>
+        <br><br>
+
+        Canvas:
+        <span id="button-selection" style="display: none;">
+            <input id="button1" type="button" value="L"><input id="button2" type="button" value="M"><input id="button4" type="button" value="R">
+        </span>
+        <br>
+        <canvas id="canvas" width="640" height="20"
+                style="border-style: dotted; border-width: 1px;">
+            Canvas not supported.
+        </canvas>
+
+        <br>
+        Results:<br>
+        <textarea id="messages" style="font-size: 9;" cols=80 rows=25></textarea>
+    </body>
+
+    <!--
+    <script type='text/javascript' 
+        src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
+    -->
+    <script src="../include/util.js"></script>
+    <script src="../include/webutil.js"></script> 
+    <script src="../include/base64.js"></script>
+    <script src="../include/input.js"></script> 
+    <script src="../include/display.js"></script>
+    <script>
+        var msg_cnt = 0, iterations,
+            width = 400, height = 200,
+            canvas, keyboard, mouse;
+
+        var newline = "\n";
+        if (Util.Engine.trident) {
+            var newline = "<br>\n";
+        }
+
+        function message(str) {
+            console.log(str);
+            cell = $D('messages');
+            cell.innerHTML += msg_cnt + ": " + str + newline;
+            cell.scrollTop = cell.scrollHeight;
+            msg_cnt++;
+        }
+
+        function mouseButton(x, y, down, bmask) {
+            msg = 'mouse x,y: ' + x + ',' + y + '  down: ' + down;
+            msg += ' bmask: ' + bmask;
+            message(msg);
+        }
+
+        function mouseMove(x, y) {
+            msg = 'mouse x,y: ' + x + ',' + y;
+            //console.log(msg);
+        }
+
+        function keyPress(keysym, down, e) {
+            var d = down ? "down" : " up ";
+            msg = "keyPress " + d + " keysym: " + keysym +
+                  " (key: " + e.keyCode + ", char: " + e.charCode +
+                  ", which: " + e.which +")";
+            message(msg);
+        }
+
+        function selectButton(num) {
+            var b, blist = [1,2,4];
+
+            if (typeof num === 'undefined') {
+                // Show the default
+                num = mouse.get_touchButton();
+            } else if (num === mouse.get_touchButton()) {
+                // Set all buttons off (no clicks)
+                mouse.set_touchButton(0);
+                num = 0;
+            } else {
+                // Turn on one button
+                mouse.set_touchButton(num);
+            }
+
+            for (b = 0; b < blist.length; b++) {
+                if (blist[b] === num) {
+                    $D('button' + blist[b]).style.backgroundColor = "black";
+                    $D('button' + blist[b]).style.color = "lightgray";
+                } else {
+                    $D('button' + blist[b]).style.backgroundColor = "";
+                    $D('button' + blist[b]).style.color = "";
+                }
+            }
+        }
+
+        window.onload = function() {
+            canvas = new Display({'target' : $D('canvas')});
+            keyboard = new Keyboard({'target': document,
+                                    'onKeyPress': keyPress});
+            mouse    = new Mouse({'target': $D('canvas'),
+                                'onMouseButton': mouseButton,
+                                'onMouseMove': mouseMove});
+
+            canvas.resize(width, height, true);
+            keyboard.grab();
+            mouse.grab();
+            message("Display initialized");
+
+            if ('ontouchstart' in document.documentElement) {
+                message("Touch device detected");
+                $D('button-selection').style.display = "inline";
+                $D('button1').onclick = function(){ selectButton(1) };
+                $D('button2').onclick = function(){ selectButton(2) };
+                $D('button4').onclick = function(){ selectButton(4) };
+                selectButton();
+            }
+
+        }
+    </script>
+</html>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/tests/stats.js
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/tests/stats.js b/patches/systemvm/debian/config/root/lswcp/tests/stats.js
new file mode 100644
index 0000000..cd3011c
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/tests/stats.js
@@ -0,0 +1,53 @@
+/*
+ * Define some useful statistical functions on arrays of numbers
+ */
+
+Array.prototype.sum = function() {
+    var i, sum = 0;
+    for (i = 0; i < this.length; i++) {
+        sum += this[i];
+    }
+    return sum;
+}
+
+Array.prototype.max = function() {
+    return Math.max.apply(null, this);
+}
+
+Array.prototype.min = function() {
+    return Math.min.apply(null, this);
+}
+
+Array.prototype.mean = function() {
+    return this.sum() / this.length;
+}
+Array.prototype.average = Array.prototype.mean;
+
+Array.prototype.median = function() {
+    var sorted = this.sort( function(a,b) { return a-b; }),
+        len = sorted.length;
+    if (len % 2) {
+        return sorted[Math.floor(len / 2)]; // Odd
+    } else {
+        return (sorted[len/2 - 1] + sorted[len/2]) / 2; // Even
+    }
+}
+
+Array.prototype.stdDev = function(sample) {
+    var i, sumSqr = 0, mean = this.mean(), N;
+
+    if (sample) {
+        // Population correction if this is a sample
+        N = this.length - 1;
+    } else {
+        // Standard deviation of just the array
+        N = this.length;
+    }
+
+    for (i = 0; i < this.length; i++) {
+        sumSqr += Math.pow(this[i] - mean, 2);
+    }
+
+    return Math.sqrt(sumSqr / N);
+}
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/tests/viewport.css
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/tests/viewport.css b/patches/systemvm/debian/config/root/lswcp/tests/viewport.css
new file mode 100644
index 0000000..86f65ff
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/tests/viewport.css
@@ -0,0 +1,43 @@
+html,body {
+    margin: 0px;
+    padding: 0px;
+    width: 100%;
+    height: 100%;
+}
+
+.flex-layout {
+    width: 100%;
+    height: 100%;
+
+    display: box;
+    display: -webkit-box;
+    display: -moz-box;
+    display: -ms-box;
+
+    box-orient: vertical;
+    -webkit-box-orient: vertical;
+    -moz-box-orient: vertical;
+    -ms-box-orient: vertical;
+
+    box-align: stretch;
+    -webkit-box-align: stretch;
+    -moz-box-align: stretch;
+    -ms-box-align: stretch;
+}
+.flex-box {
+    box-flex: 1;
+    -webkit-box-flex: 1;
+    -moz-box-flex: 1;
+    -ms-box-flex: 1;
+}
+
+.container {
+    margin: 0px;
+    padding: 0px;
+}
+
+.canvas {
+    position: absolute;
+    border-style: dotted;
+    border-width: 1px;
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/tests/viewport.html
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/tests/viewport.html b/patches/systemvm/debian/config/root/lswcp/tests/viewport.html
new file mode 100644
index 0000000..1fb0a79
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/tests/viewport.html
@@ -0,0 +1,202 @@
+<!DOCTYPE html>
+<html>
+    <head><title>Viewport Test</title>
+        <link rel="stylesheet" href="viewport.css">
+        <!--
+        <meta name="apple-mobile-web-app-capable" content="yes" />
+        <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
+        -->
+        <meta name=viewport content="width=device-width, initial-scale=1.0, user-scalable=no">
+    </head>
+    <body>
+        <div class="flex-layout">
+            <div>
+                Canvas:
+                    <input id="move-selector" type="button" value="Move"
+                        onclick="toggleMove();">
+                <br>
+            </div>
+            <div class="container flex-box">
+                <canvas id="canvas" class="canvas">
+                    Canvas not supported.
+                </canvas>
+                <br>
+            </div>
+            <div>
+                <br>
+                Results:<br>
+                <textarea id="messages" style="font-size: 9;" cols=80 rows=8></textarea>
+            </div>
+        </div>
+    </body>
+
+    <!--
+    <script type='text/javascript' 
+        src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
+    -->
+    <script src="../include/util.js"></script>
+    <script src="../include/webutil.js"></script> 
+    <script src="../include/base64.js"></script>
+    <script src="../include/input.js"></script> 
+    <script src="../include/display.js"></script>
+    <script>
+        var msg_cnt = 0, iterations,
+            penDown = false, doMove = false,
+            inMove = false, lastPos = {},
+            padW = 0, padH = 0,
+            display, ctx, keyboard, mouse;
+
+        var newline = "\n";
+        if (Util.Engine.trident) {
+            var newline = "<br>\n";
+        }
+
+        function message(str) {
+            console.log(str);
+            cell = $D('messages');
+            cell.innerHTML += msg_cnt + ": " + str + newline;
+            cell.scrollTop = cell.scrollHeight;
+            msg_cnt++;
+        }
+
+        function mouseButton(x, y, down, bmask) {
+            //msg = 'mouse x,y: ' + x + ',' + y + '  down: ' + down;
+            //msg += ' bmask: ' + bmask;
+            //message(msg);
+
+            if (doMove) {
+                if (down && !inMove) {
+                    inMove = true;
+                    lastPos = {'x': x, 'y': y};
+                } else if (!down && inMove) {
+                    inMove = false;
+                    //dirtyRedraw();
+                }
+                return;
+            }
+
+            if (down && ! penDown) {
+                penDown = true;
+                ctx.beginPath();
+                ctx.moveTo(x, y);
+            } else if (!down && penDown) {
+                penDown = false;
+                ctx.closePath();
+            }
+        }
+
+        function mouseMove(x, y) {
+            var deltaX, deltaY;
+
+            if (inMove) {
+                //deltaX = x - lastPos.x; // drag viewport
+                deltaX = lastPos.x - x; // drag frame buffer
+                //deltaY = y - lastPos.y; // drag viewport
+                deltaY = lastPos.y - y; // drag frame buffer
+                lastPos = {'x': x, 'y': y};
+
+                display.viewportChange(deltaX, deltaY);
+                return;
+            }
+
+            if (penDown) {
+                ctx.lineTo(x, y);
+                ctx.stroke();
+            }
+        }
+
+        function dirtyRedraw() {
+            if (inMove) {
+                // Wait for user to stop moving viewport
+                return;
+            }
+
+            var d = display.getCleanDirtyReset();
+
+            for (i = 0; i < d.dirtyBoxes.length; i++) {
+                //showBox(d.dirtyBoxes[i], "dirty[" + i + "]: ");
+                drawArea(d.dirtyBoxes[i]);
+            }
+        }
+
+        function drawArea(b) {
+            var data = [], pixel, x, y;
+
+            //message("draw "+b.x+","+b.y+" ("+b.w+","+b.h+")");
+
+            for (var i = 0; i < b.w; i++) {
+                x = b.x + i;
+                for (var j = 0; j < b.h; j++) {
+                    y = b.y + j;
+                    pixel = (j * b.w * 4 + i * 4);
+                    data[pixel + 0] = ((x * y) / 13) % 256;
+                    data[pixel + 1] = ((x * y) + 392) % 256;
+                    data[pixel + 2] = ((x + y) + 256) % 256;
+                    data[pixel + 3] = 255;
+                }
+            }
+            //message("i: " + i + ", j: " + j + ", pixel: " + pixel);
+            display.blitImage(b.x, b.y, b.w, b.h, data, 0);
+        }
+
+        function toggleMove() {
+            if (doMove) {
+                doMove = false;
+                $D('move-selector').style.backgroundColor = "";
+                $D('move-selector').style.color = "";
+            } else {
+                doMove = true;
+                $D('move-selector').style.backgroundColor = "black";
+                $D('move-selector').style.color = "lightgray";
+            }
+        }
+
+        function detectPad() {
+            var c = $D('canvas'), p = c.parentNode;
+            c.width = 10;
+            c.height = 10;
+            padW = c.offsetWidth - 10;
+            padH = c.offsetHeight - 10;
+            message("padW: " + padW + ", padH: " + padH);
+        }
+
+        function doResize() {
+            var p = $D('canvas').parentNode;
+            message("doResize1: [" + (p.offsetWidth - padW) +
+                    "," + (p.offsetHeight - padH) + "]");
+            display.viewportChange(0, 0,
+                p.offsetWidth - padW, p.offsetHeight - padH);
+            /*
+            var pos, new_w, new_h;pos
+            pos = Util.getPosition($D('canvas').parentNode);
+            new_w = window.innerWidth - pos.x;
+            new_h = window.innerHeight - pos.y;
+            display.viewportChange(0, 0, new_w, new_h);
+            */
+        }
+
+        window.onload = function() {
+            detectPad();
+
+            display = new Display({'target': $D('canvas')});
+            display.resize(1600, 1024);
+            display.set_viewport(true);
+            ctx = display.get_context();
+
+            mouse    = new Mouse({'target': $D('canvas'),
+                                'onMouseButton': mouseButton,
+                                'onMouseMove': mouseMove});
+            mouse.grab();
+
+
+            Util.addEvent(window, 'resize', doResize);
+            // Shrink viewport for first resize call so that the
+            // scrollbars are disabled
+            display.viewportChange(0, 0, 10, 10);
+            setTimeout(doResize, 1);
+            setInterval(dirtyRedraw, 50);
+
+            message("Display initialized");
+        };
+    </script>
+</html>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/tests/vnc_perf.html
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/tests/vnc_perf.html b/patches/systemvm/debian/config/root/lswcp/tests/vnc_perf.html
new file mode 100644
index 0000000..eda6fd0
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/tests/vnc_perf.html
@@ -0,0 +1,203 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>VNC Performance Benchmark</title>
+        <link rel="stylesheet" href="../include/base.css">
+    </head>
+    <body>
+
+        Passes: <input id='passes' style='width:50' value=3>&nbsp;
+
+        <input id='startButton' type='button' value='Start' style='width:100px'
+            onclick="do_test();" disabled>&nbsp;
+
+        <br><br>
+
+        Results:<br>
+        <textarea id="messages" style="font-size: 9;" cols=80 rows=15></textarea>
+
+        <br><br>
+
+        <div id="VNC_screen">
+            <div id="VNC_status_bar" class="VNC_status_bar" style="margin-top: 0px;">
+                <table border=0 width=100%><tr>
+                    <td><div id="VNC_status">Loading</div></td>
+                </tr></table>
+            </div>
+            <canvas id="VNC_canvas" width="640px" height="20px">
+                Canvas not supported.
+            </canvas>
+        </div>
+
+    </body>
+
+    <!--
+    <script type='text/javascript' 
+        src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
+    -->
+
+    <script type="text/javascript">
+        var INCLUDE_URI= "../include/";
+    </script>
+    <script src="../include/vnc.js"></script>
+    <script src="../include/playback.js"></script>
+    <script src="../data/multi.js"></script>
+
+    <script>
+        var start_time, VNC_frame_data, pass, passes, encIdx,
+            encOrder = ['raw', 'rre', 'hextile', 'tightpng', 'copyrect'],
+            encTot = {}, encMin = {}, encMax = {},
+            passCur, passTot, passMin, passMax;
+
+        function msg(str) {
+            console.log(str);
+            var cell = $D('messages');
+            cell.innerHTML += str + "\n";
+            cell.scrollTop = cell.scrollHeight;
+        }
+        function dbgmsg(str) {
+            if (Util.get_logging() === 'debug') {
+                msg(str);
+            }
+        }
+
+        updateState = function (rfb, state, oldstate, mesg) {
+            switch (state) {
+                case 'failed':
+                case 'fatal':
+                    msg("noVNC sent '" + state +
+                        "' state during pass " + pass +
+                        ", iteration " + iteration +
+                        " frame " + frame_idx);
+                    test_state = 'failed';
+                    break;
+                case 'loaded':
+                    $D('startButton').disabled = false;
+                    break;
+            }
+            if (typeof mesg !== 'undefined') {
+                $D('VNC_status').innerHTML = mesg;
+            }
+        }
+
+        function do_test() {
+            $D('startButton').value = "Running";
+            $D('startButton').disabled = true;
+
+            mode = 'perftest'; // full-speed
+            passes = $D('passes').value;
+            pass = 1;
+            encIdx = 0;
+
+            // Render each encoding once for each pass
+            iterations = 1;
+
+            // Initialize stats counters
+            for (i = 0; i < encOrder.length; i++) {
+                enc = encOrder[i];
+                encTot[i] = 0;
+                encMin[i] = 2<<23; // Something sufficiently large
+                encMax[i] = 0;
+            }
+            passCur = 0;
+            passTot = 0;
+            passMin = 2<<23;
+            passMax = 0;
+
+            // Fire away
+            next_encoding();
+        }
+
+        function next_encoding() {
+            var encName;
+
+            if (encIdx >= encOrder.length) {
+                // Accumulate pass stats
+                if (passCur < passMin) {
+                    passMin = passCur;
+                }
+                if (passCur > passMax) {
+                    passMax = passCur;
+                }
+                msg("Pass " + pass + " took " + passCur + " ms");
+
+                passCur = 0;
+                encIdx = 0;
+                pass += 1;
+                if (pass > passes) {
+                    // We are finished
+                    // Shut-off event interception
+                    rfb.get_mouse().ungrab();
+                    rfb.get_keyboard().ungrab();
+                    $D('startButton').disabled = false;
+                    $D('startButton').value = "Start";
+                    finish_passes();
+                    return; // We are finished, terminate
+                }
+            }
+
+            encName = encOrder[encIdx];
+            dbgmsg("Rendering pass " + pass + " encoding '" + encName + "'");
+
+            VNC_frame_data = VNC_frame_data_multi[encName];
+            iteration = 0;
+            start_time = (new Date()).getTime();
+
+            next_iteration();
+        }
+
+        // Finished rendering current encoding
+        function finish() {
+            var total_time, end_time = (new Date()).getTime();
+            total_time = end_time - start_time;
+
+            dbgmsg("Encoding " + encOrder[encIdx] + " took " + total_time + "ms");
+
+            passCur += total_time;
+            passTot += total_time;
+
+            // Accumulate stats
+            encTot[encIdx] += total_time;
+            if (total_time < encMin[encIdx]) {
+                encMin[encIdx] = total_time;
+            }
+            if (total_time > encMax[encIdx]) {
+                encMax[encIdx] = total_time;
+            }
+
+            encIdx += 1;
+            next_encoding();
+        }
+
+        function finish_passes() {
+            var i, enc, avg, passAvg;
+            msg("STATS (for " + passes + " passes)");
+            // Encoding stats
+            for (i = 0; i < encOrder.length; i++) {
+                enc = encOrder[i];
+                avg = (encTot[i] / passes).toFixed(1);
+                msg("  " + enc + ": " + encTot[i] + " ms, " +
+                    encMin[i] + "/" + avg + "/" + encMax[i] + 
+                    " (min/avg/max)");
+
+            }
+            // Print pass stats
+            passAvg = (passTot / passes).toFixed(1);
+            msg("\n  All passes: " + passTot + " ms, " +
+                passMin + "/" + passAvg + "/" + passMax +
+                " (min/avg/max)");
+        }
+
+        window.onload = function() {
+            var i, enc;
+            dbgmsg("Frame lengths:");
+            for (i = 0; i < encOrder.length; i++) {
+                enc = encOrder[i];
+                dbgmsg("  " + enc + ": " + VNC_frame_data_multi[enc].length);
+            }
+            rfb = new RFB({'target': $D('VNC_canvas'),
+                           'updateState': updateState});
+            rfb.testMode(send_array);
+        }
+    </script>
+</html>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/tests/vnc_playback.html
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/tests/vnc_playback.html b/patches/systemvm/debian/config/root/lswcp/tests/vnc_playback.html
new file mode 100644
index 0000000..a258a47
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/tests/vnc_playback.html
@@ -0,0 +1,134 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>VNC Playback</title>
+        <link rel="stylesheet" href="../include/plain.css">
+    </head>
+    <body>
+
+        Iterations: <input id='iterations' style='width:50'>&nbsp;
+        Perftest:<input type='radio' id='mode1' name='mode' checked>&nbsp;
+        Realtime:<input type='radio' id='mode2' name='mode'>&nbsp;&nbsp;
+
+        <input id='startButton' type='button' value='Start' style='width:100px'
+            onclick="start();" disabled>&nbsp;
+
+        <br><br>
+
+        Results:<br>
+        <textarea id="messages" style="font-size: 9;" cols=80 rows=25></textarea>
+
+        <br><br>
+
+        <div id="VNC_screen">
+            <div id="VNC_status_bar" class="VNC_status_bar" style="margin-top: 0px;">
+                <table border=0 width=100%><tr>
+                    <td><div id="VNC_status">Loading</div></td>
+                </tr></table>
+            </div>
+            <canvas id="VNC_canvas" width="640px" height="20px">
+                Canvas not supported.
+            </canvas>
+        </div>
+
+    </body>
+
+    <!--
+    <script type='text/javascript' 
+        src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
+    -->
+
+    <script type="text/javascript">
+        var INCLUDE_URI= "../include/";
+    </script>
+    <script src="../include/vnc.js"></script>
+    <script src="../include/playback.js"></script>
+
+    <script>
+        var fname, start_time;
+
+        function message(str) {
+            console.log(str);
+            var cell = $D('messages');
+            cell.innerHTML += str + "\n";
+            cell.scrollTop = cell.scrollHeight;
+        }
+
+        fname = WebUtil.getQueryVar('data', null);
+
+        if (fname) {
+            message("Loading " + fname);
+            document.write('<script src="' + fname + '"><\/script>');
+        } else {
+            message("Must specify data=FOO in query string.");
+        }
+
+        updateState = function (rfb, state, oldstate, msg) {
+            switch (state) {
+                case 'failed':
+                case 'fatal':
+                    message("noVNC sent '" + state + "' state during iteration " + iteration + " frame " + frame_idx);
+                    test_state = 'failed';
+                    break;
+                case 'loaded':
+                    $D('startButton').disabled = false;
+                    break;
+            }
+            if (typeof msg !== 'undefined') {
+                $D('VNC_status').innerHTML = msg;
+            }
+        }
+
+        function start() {
+            $D('startButton').value = "Running";
+            $D('startButton').disabled = true;
+
+            iterations = $D('iterations').value;
+            iteration = 0;
+            start_time = (new Date()).getTime();
+
+            if ($D('mode1').checked) {
+                message("Starting performance playback (fullspeed) [" + iterations + " iteration(s)]");
+                mode = 'perftest';
+            } else {
+                message("Starting realtime playback [" + iterations + " iteration(s)]");
+                mode = 'realtime';
+            }
+
+            recv_message = rfb.testMode(send_array);
+            next_iteration();
+        }
+
+        function finish() {
+            // Finished with all iterations
+            var total_time, end_time = (new Date()).getTime();
+            total_time = end_time - start_time;
+
+            iter_time = parseInt(total_time / iterations, 10);
+            message(iterations + " iterations took " + total_time + "ms, " +
+                    iter_time + "ms per iteration");
+            // Shut-off event interception
+            rfb.get_mouse().ungrab();
+            rfb.get_keyboard().ungrab();
+            $D('startButton').disabled = false;
+            $D('startButton').value = "Start";
+
+        }
+
+        window.onload = function() {
+            iterations = WebUtil.getQueryVar('iterations', 3);
+            $D('iterations').value = iterations;
+            mode = WebUtil.getQueryVar('mode', 3);
+            if (mode === 'realtime') {
+                $D('mode2').checked = true;
+            } else {
+                $D('mode1').checked = true;
+            }
+            if (fname) {
+                message("VNC_frame_data.length: " + VNC_frame_data.length);
+                rfb = new RFB({'target': $D('VNC_canvas'),
+                               'updateState': updateState});
+            }
+        }
+    </script>
+</html>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/utils/Makefile
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/utils/Makefile b/patches/systemvm/debian/config/root/lswcp/utils/Makefile
new file mode 100644
index 0000000..7dc1bc4
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/utils/Makefile
@@ -0,0 +1,11 @@
+TARGETS=rebind.so
+CFLAGS += -fPIC
+
+all: $(TARGETS)
+
+rebind.so: rebind.o
+	$(CC) $(LDFLAGS) $^ -shared -fPIC -ldl -o $@
+
+clean:
+	rm -f rebind.o rebind.so
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/utils/README.md
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/utils/README.md b/patches/systemvm/debian/config/root/lswcp/utils/README.md
new file mode 100644
index 0000000..0abbd0d
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/utils/README.md
@@ -0,0 +1,11 @@
+## WebSockets Proxy
+
+wsproxy has become [websockify](https://github.com/kanaka/websockify).
+A copy of the python version of websockify (named wsproxy.py) is kept
+here for ease of use. The other versions of websockify (C, Node.js)
+and the associated test programs have been moved to
+[websockify](https://github.com/kanaka/websockify).
+
+For more detailed description and usage information please refer to
+the [websockify README](https://github.com/kanaka/websockify/blob/master/README.md).
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/utils/img2js.py
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/utils/img2js.py b/patches/systemvm/debian/config/root/lswcp/utils/img2js.py
new file mode 100644
index 0000000..3ba4598
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/utils/img2js.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+
+#
+# Convert image to Javascript compatible base64 Data URI
+# Copyright 2011 Joel Martin
+# Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3)
+#
+
+import sys, base64
+
+try:
+    from PIL import Image
+except:
+    print "python PIL module required (python-imaging package)"
+    sys.exit(1)
+
+
+if len(sys.argv) < 3:
+    print "Usage: %s IMAGE JS_VARIABLE" % sys.argv[0]
+    sys.exit(1)
+
+fname = sys.argv[1]
+var   = sys.argv[2]
+
+ext = fname.lower().split('.')[-1]
+if   ext == "png":            mime = "image/png"
+elif ext in ["jpg", "jpeg"]:  mime = "image/jpeg"
+elif ext == "gif":            mime = "image/gif"
+else:
+    print "Only PNG, JPEG and GIF images are supported"
+    sys.exit(1)
+uri = "data:%s;base64," % mime
+
+im = Image.open(fname)
+w, h = im.size
+
+raw = open(fname).read()
+
+print '%s = {"width": %s, "height": %s, "data": "%s%s"};' % (
+        var, w, h, uri, base64.b64encode(raw))

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/utils/json2graph.py
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/utils/json2graph.py b/patches/systemvm/debian/config/root/lswcp/utils/json2graph.py
new file mode 100644
index 0000000..0f6a7ad
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/utils/json2graph.py
@@ -0,0 +1,206 @@
+#!/usr/bin/env python
+
+'''
+Use matplotlib to generate performance charts
+Copyright 2011 Joel Martin
+Licensed under GPL version 3 (see docs/LICENSE.GPL-3)
+'''
+
+# a bar plot with errorbars
+import sys, json, pprint
+import numpy as np
+import matplotlib.pyplot as plt
+from matplotlib.font_manager import FontProperties
+
+def usage():
+    print "%s json_file level1 level2 level3 [legend_height]\n\n" % sys.argv[0]
+    print "Description:\n"
+    print "level1, level2, and level3 are one each of the following:\n";
+    print "  select=ITEM - select only ITEM at this level";
+    print "  bar         - each item on this level becomes a graph bar";
+    print "  group       - items on this level become groups of bars";
+    print "\n";
+    print "json_file is a file containing json data in the following format:\n"
+    print '  {';
+    print '    "conf": {';
+    print '      "order_l1": [';
+    print '        "level1_label1",';
+    print '        "level1_label2",';
+    print '        ...';
+    print '      ],';
+    print '      "order_l2": [';
+    print '        "level2_label1",';
+    print '        "level2_label2",';
+    print '        ...';
+    print '      ],';
+    print '      "order_l3": [';
+    print '        "level3_label1",';
+    print '        "level3_label2",';
+    print '        ...';
+    print '      ]';
+    print '    },';
+    print '    "stats": {';
+    print '      "level1_label1": {';
+    print '        "level2_label1": {';
+    print '          "level3_label1": [val1, val2, val3],';
+    print '          "level3_label2": [val1, val2, val3],';
+    print '          ...';
+    print '        },';
+    print '        "level2_label2": {';
+    print '        ...';
+    print '        },';
+    print '      },';
+    print '      "level1_label2": {';
+    print '        ...';
+    print '      },';
+    print '      ...';
+    print '    },';
+    print '  }';
+    sys.exit(2)
+
+def error(msg):
+    print msg
+    sys.exit(1)
+
+
+#colors = ['#ff0000', '#0863e9', '#00f200', '#ffa100',
+#          '#800000', '#805100', '#013075', '#007900']
+colors = ['#ff0000', '#00ff00', '#0000ff',
+          '#dddd00', '#dd00dd', '#00dddd',
+          '#dd6622', '#dd2266', '#66dd22',
+          '#8844dd', '#44dd88', '#4488dd']
+
+if len(sys.argv) < 5:
+    usage()
+
+filename = sys.argv[1]
+L1 = sys.argv[2]
+L2 = sys.argv[3]
+L3 = sys.argv[4]
+if len(sys.argv) > 5:
+    legendHeight = float(sys.argv[5])
+else:
+    legendHeight = 0.75
+
+# Load the JSON data from the file
+data = json.loads(file(filename).read())
+conf = data['conf']
+stats = data['stats']
+
+# Sanity check data hierarchy
+if len(conf['order_l1']) != len(stats.keys()):
+    error("conf.order_l1 does not match stats level 1")
+for l1 in stats.keys():
+    if len(conf['order_l2']) != len(stats[l1].keys()):
+        error("conf.order_l2 does not match stats level 2 for %s" % l1)
+    if conf['order_l1'].count(l1) < 1:
+        error("%s not found in conf.order_l1" % l1)
+    for l2 in stats[l1].keys():
+        if len(conf['order_l3']) != len(stats[l1][l2].keys()):
+            error("conf.order_l3 does not match stats level 3")
+        if conf['order_l2'].count(l2) < 1:
+            error("%s not found in conf.order_l2" % l2)
+        for l3 in stats[l1][l2].keys():
+            if conf['order_l3'].count(l3) < 1:
+                error("%s not found in conf.order_l3" % l3)
+
+#
+# Generate the data based on the level specifications
+#
+bar_labels = None
+group_labels = None
+bar_vals = []
+bar_sdvs = []
+if L3.startswith("select="):
+    select_label = l3 = L3.split("=")[1]
+    bar_labels = conf['order_l1']
+    group_labels = conf['order_l2']
+    bar_vals = [[0]*len(group_labels) for i in bar_labels]
+    bar_sdvs = [[0]*len(group_labels) for i in bar_labels]
+    for b in range(len(bar_labels)):
+        l1 = bar_labels[b]
+        for g in range(len(group_labels)):
+            l2 = group_labels[g]
+            bar_vals[b][g] = np.mean(stats[l1][l2][l3])
+            bar_sdvs[b][g] = np.std(stats[l1][l2][l3])
+elif L2.startswith("select="):
+    select_label = l2 = L2.split("=")[1]
+    bar_labels = conf['order_l1']
+    group_labels = conf['order_l3']
+    bar_vals = [[0]*len(group_labels) for i in bar_labels]
+    bar_sdvs = [[0]*len(group_labels) for i in bar_labels]
+    for b in range(len(bar_labels)):
+        l1 = bar_labels[b]
+        for g in range(len(group_labels)):
+            l3 = group_labels[g]
+            bar_vals[b][g] = np.mean(stats[l1][l2][l3])
+            bar_sdvs[b][g] = np.std(stats[l1][l2][l3])
+elif L1.startswith("select="):
+    select_label = l1 = L1.split("=")[1]
+    bar_labels = conf['order_l2']
+    group_labels = conf['order_l3']
+    bar_vals = [[0]*len(group_labels) for i in bar_labels]
+    bar_sdvs = [[0]*len(group_labels) for i in bar_labels]
+    for b in range(len(bar_labels)):
+        l2 = bar_labels[b]
+        for g in range(len(group_labels)):
+            l3 = group_labels[g]
+            bar_vals[b][g] = np.mean(stats[l1][l2][l3])
+            bar_sdvs[b][g] = np.std(stats[l1][l2][l3])
+else:
+    usage()
+
+# If group is before bar then flip (zip) the data
+if [L1, L2, L3].index("group") < [L1, L2, L3].index("bar"):
+    bar_labels, group_labels = group_labels, bar_labels
+    bar_vals = zip(*bar_vals)
+    bar_sdvs = zip(*bar_sdvs)
+
+print "bar_vals:", bar_vals
+
+#
+# Now render the bar graph
+#
+ind = np.arange(len(group_labels))  # the x locations for the groups
+width = 0.8 * (1.0/len(bar_labels)) # the width of the bars
+
+fig = plt.figure(figsize=(10,6), dpi=80)
+plot = fig.add_subplot(1, 1, 1)
+
+rects = []
+for i in range(len(bar_vals)):
+    rects.append(plot.bar(ind+width*i, bar_vals[i], width, color=colors[i],
+                          yerr=bar_sdvs[i], align='center'))
+
+# add some
+plot.set_ylabel('Milliseconds (less is better)')
+plot.set_title("Javascript array test: %s" % select_label)
+plot.set_xticks(ind+width)
+plot.set_xticklabels( group_labels )
+
+fontP = FontProperties()
+fontP.set_size('small')
+plot.legend( [r[0] for r in rects], bar_labels, prop=fontP,
+            loc = 'center right', bbox_to_anchor = (1.0, legendHeight))
+
+def autolabel(rects):
+    # attach some text labels
+    for rect in rects:
+        height = rect.get_height()
+        if np.isnan(height):
+            height = 0.0
+        plot.text(rect.get_x()+rect.get_width()/2., height+20, '%d'%int(height),
+                ha='center', va='bottom', size='7')
+
+for rect in rects:
+    autolabel(rect)
+
+# Adjust axis sizes
+axis = list(plot.axis())
+axis[0] = -width          # Make sure left side has enough for bar
+#axis[1] = axis[1] * 1.20  # Add 20% to the right to make sure it fits
+axis[2] = 0               # Make y-axis start at 0
+axis[3] = axis[3] * 1.10  # Add 10% to the top
+plot.axis(axis)
+
+plt.show()

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/utils/launch.sh
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/utils/launch.sh b/patches/systemvm/debian/config/root/lswcp/utils/launch.sh
new file mode 100644
index 0000000..8afd6e4
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/utils/launch.sh
@@ -0,0 +1,108 @@
+#!/usr/bin/env bash
+
+usage() {
+    if [ "$*" ]; then
+        echo "$*"
+        echo
+    fi
+    echo "Usage: ${NAME} [--listen PORT] [--vnc VNC_HOST:PORT] [--cert CERT]"
+    echo
+    echo "Starts the WebSockets proxy and a mini-webserver and "
+    echo "provides a cut-and-paste URL to go to."
+    echo 
+    echo "    --listen PORT         Port for proxy/webserver to listen on"
+    echo "                          Default: 6080"
+    echo "    --vnc VNC_HOST:PORT   VNC server host:port proxy target"
+    echo "                          Default: localhost:5900"
+    echo "    --cert CERT           Path to combined cert/key file"
+    echo "                          Default: self.pem"
+    exit 2
+}
+
+NAME="$(basename $0)"
+HERE="$(cd "$(dirname "$0")" && pwd)"
+PORT="6080"
+VNC_DEST="localhost:5900"
+CERT=""
+proxy_pid=""
+
+die() {
+    echo "$*"
+    exit 1
+}
+
+cleanup() {
+    trap - TERM QUIT INT EXIT
+    trap "true" CHLD   # Ignore cleanup messages
+    echo
+    if [ -n "${proxy_pid}" ]; then
+        echo "Terminating WebSockets proxy (${proxy_pid})"
+        kill ${proxy_pid}
+    fi
+}
+
+# Process Arguments
+
+# Arguments that only apply to chrooter itself
+while [ "$*" ]; do
+    param=$1; shift; OPTARG=$1
+    case $param in
+    --listen)  PORT="${OPTARG}"; shift            ;;
+    --vnc)     VNC_DEST="${OPTARG}"; shift        ;;
+    --cert)    CERT="${OPTARG}"; shift            ;;
+    -h|--help) usage                              ;;
+    -*) usage "Unknown chrooter option: ${param}" ;;
+    *) break                                      ;;
+    esac
+done
+
+# Sanity checks
+which netstat >/dev/null 2>&1 \
+    || die "Must have netstat installed"
+
+netstat -ltn | grep -qs "${PORT}.*LISTEN" \
+    && die "Port ${PORT} in use. Try --listen PORT"
+
+trap "cleanup" TERM QUIT INT EXIT
+
+# Find vnc.html
+if [ -e "$(pwd)/vnc.html" ]; then
+    WEB=$(pwd)
+elif [ -e "${HERE}/../vnc.html" ]; then
+    WEB=${HERE}/../
+elif [ -e "${HERE}/vnc.html" ]; then
+    WEB=${HERE}
+else
+    die "Could not find vnc.html"
+fi
+
+# Find self.pem
+if [ -n "${CERT}" ]; then
+    if [ ! -e "${CERT}" ]; then
+        die "Could not find ${CERT}"
+    fi
+elif [ -e "$(pwd)/self.pem" ]; then
+    CERT="$(pwd)/self.pem"
+elif [ -e "${HERE}/../self.pem" ]; then
+    CERT="${HERE}/../self.pem"
+elif [ -e "${HERE}/self.pem" ]; then
+    CERT="${HERE}/self.pem"
+else
+    echo "Warning: could not find self.pem"
+fi
+
+echo "Starting webserver and WebSockets proxy on port ${PORT}"
+${HERE}/wsproxy.py --web ${WEB} ${CERT:+--cert ${CERT}} ${PORT} ${VNC_DEST} &
+proxy_pid="$!"
+sleep 1
+if ! ps -p ${proxy_pid} >/dev/null; then
+    proxy_pid=
+    echo "Failed to start WebSockets proxy"
+    exit 1
+fi
+
+echo -e "\n\nNavigate to this URL:\n"
+echo -e "    http://$(hostname):${PORT}/vnc.html?host=$(hostname)&port=${PORT}\n"
+echo -e "Press Ctrl-C to exit\n\n"
+
+wait ${proxy_pid}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/utils/rebind
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/utils/rebind b/patches/systemvm/debian/config/root/lswcp/utils/rebind
new file mode 100644
index 0000000..2289aaa
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/utils/rebind
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+
+usage() {
+    echo "Usage: $(basename $0) OLD_PORT NEW_PORT COMMAND_LINE"
+    echo
+    echo "Launch COMMAND_LINE, but intercept system calls to bind"
+    echo "to OLD_PORT and instead bind them to localhost:NEW_PORT"
+    exit 2
+}
+
+# Parameter defaults
+mydir=$(readlink -f $(dirname ${0}))
+
+export REBIND_PORT_OLD="${1}"; shift
+export REBIND_PORT_NEW="${1}"; shift
+
+LD_PRELOAD=${mydir}/rebind.so "${@}"
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/utils/rebind.c
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/utils/rebind.c b/patches/systemvm/debian/config/root/lswcp/utils/rebind.c
new file mode 100644
index 0000000..c7e83de
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/utils/rebind.c
@@ -0,0 +1,94 @@
+/*
+ * rebind: Intercept bind calls and bind to a different port
+ * Copyright 2010 Joel Martin
+ * Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3)
+ *
+ * Overload (LD_PRELOAD) bind system call. If REBIND_PORT_OLD and
+ * REBIND_PORT_NEW environment variables are set then bind on the new
+ * port (of localhost) instead of the old port. 
+ *
+ * This allows a proxy (such as wsproxy) to run on the old port and translate
+ * traffic to/from the new port.
+ *
+ * Usage:
+ *     LD_PRELOAD=./rebind.so \
+ *     REBIND_PORT_OLD=23 \
+ *     REBIND_PORT_NEW=2023 \
+ *     program
+ */
+
+//#define DO_DEBUG 1
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define __USE_GNU 1  // Pull in RTLD_NEXT
+#include <dlfcn.h>
+
+#include <string.h>
+#include <netinet/in.h>
+
+
+#if defined(DO_DEBUG)
+#define DEBUG(...) \
+    fprintf(stderr, "wswrapper: "); \
+    fprintf(stderr, __VA_ARGS__);
+#else
+#define DEBUG(...)
+#endif
+
+
+int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
+{
+    static void * (*func)();
+    int do_move = 0;
+    struct sockaddr_in * addr_in = (struct sockaddr_in *)addr;
+    struct sockaddr_in addr_tmp;
+    socklen_t addrlen_tmp;
+    char * PORT_OLD, * PORT_NEW, * end1, * end2;
+    int ret, oldport, newport, askport = htons(addr_in->sin_port);
+    uint32_t askaddr = htons(addr_in->sin_addr.s_addr);
+    if (!func) func = (void *(*)()) dlsym(RTLD_NEXT, "bind");
+
+    DEBUG(">> bind(%d, _, %d), askaddr %d, askport %d\n",
+          sockfd, addrlen, askaddr, askport);
+
+    /* Determine if we should move this socket */
+    if (addr_in->sin_family == AF_INET) {
+        // TODO: support IPv6
+        PORT_OLD = getenv("REBIND_OLD_PORT");
+        PORT_NEW = getenv("REBIND_NEW_PORT");
+        if (PORT_OLD && (*PORT_OLD != '\0') &&
+            PORT_NEW && (*PORT_NEW != '\0')) {
+            oldport = strtol(PORT_OLD, &end1, 10);
+            newport = strtol(PORT_NEW, &end2, 10);
+            if (oldport && (*end1 == '\0') &&
+                newport && (*end2 == '\0') &&
+                (oldport == askport)) {
+                do_move = 1;
+            }
+        }
+    }
+
+    if (! do_move) {
+        /* Just pass everything right through to the real bind */
+        ret = (int) func(sockfd, addr, addrlen);
+        DEBUG("<< bind(%d, _, %d) ret %d\n", sockfd, addrlen, ret);
+        return ret;
+    }
+
+    DEBUG("binding fd %d on localhost:%d instead of 0x%x:%d\n",
+        sockfd, newport, ntohl(addr_in->sin_addr.s_addr), oldport);
+
+    /* Use a temporary location for the new address information */
+    addrlen_tmp = sizeof(addr_tmp);
+    memcpy(&addr_tmp, addr, addrlen_tmp);
+
+    /* Bind to other port on the loopback instead */
+    addr_tmp.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+    addr_tmp.sin_port = htons(newport);
+    ret = (int) func(sockfd, &addr_tmp, addrlen_tmp);
+
+    DEBUG("<< bind(%d, _, %d) ret %d\n", sockfd, addrlen, ret);
+    return ret;
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/utils/rijndael.py
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/utils/rijndael.py b/patches/systemvm/debian/config/root/lswcp/utils/rijndael.py
new file mode 100644
index 0000000..7954d3e
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/utils/rijndael.py
@@ -0,0 +1,376 @@
+"""
+A pure python (slow) implementation of rijndael with a decent interface
+
+To include -
+
+from rijndael import rijndael
+
+To do a key setup -
+
+r = rijndael(key, block_size = 16)
+
+key must be a string of length 16, 24, or 32
+blocksize must be 16, 24, or 32. Default is 16
+
+To use -
+
+ciphertext = r.encrypt(plaintext)
+plaintext = r.decrypt(ciphertext)
+
+If any strings are of the wrong length a ValueError is thrown
+"""
+
+# ported from the Java reference code by Bram Cohen, April 2001
+# this code is public domain, unless someone makes 
+# an intellectual property claim against the reference 
+# code, in which case it can be made public domain by 
+# deleting all the comments and renaming all the variables
+
+import copy
+import string
+
+shifts = [[[0, 0], [1, 3], [2, 2], [3, 1]],
+          [[0, 0], [1, 5], [2, 4], [3, 3]],
+          [[0, 0], [1, 7], [3, 5], [4, 4]]]
+
+# [keysize][block_size]
+num_rounds = {16: {16: 10, 24: 12, 32: 14}, 24: {16: 12, 24: 12, 32: 14}, 32: {16: 14, 24: 14, 32: 14}}
+
+A = [[1, 1, 1, 1, 1, 0, 0, 0],
+     [0, 1, 1, 1, 1, 1, 0, 0],
+     [0, 0, 1, 1, 1, 1, 1, 0],
+     [0, 0, 0, 1, 1, 1, 1, 1],
+     [1, 0, 0, 0, 1, 1, 1, 1],
+     [1, 1, 0, 0, 0, 1, 1, 1],
+     [1, 1, 1, 0, 0, 0, 1, 1],
+     [1, 1, 1, 1, 0, 0, 0, 1]]
+
+# produce log and alog tables, needed for multiplying in the
+# field GF(2^m) (generator = 3)
+alog = [1]
+for i in range(255):
+    j = (alog[-1] << 1) ^ alog[-1]
+    if j & 0x100 != 0:
+        j ^= 0x11B
+    alog.append(j)
+
+log = [0] * 256
+for i in range(1, 255):
+    log[alog[i]] = i
+
+# multiply two elements of GF(2^m)
+def mul(a, b):
+    if a == 0 or b == 0:
+        return 0
+    return alog[(log[a & 0xFF] + log[b & 0xFF]) % 255]
+
+# substitution box based on F^{-1}(x)
+box = [[0] * 8 for i in range(256)]
+box[1][7] = 1
+for i in range(2, 256):
+    j = alog[255 - log[i]]
+    for t in range(8):
+        box[i][t] = (j >> (7 - t)) & 0x01
+
+B = [0, 1, 1, 0, 0, 0, 1, 1]
+
+# affine transform:  box[i] <- B + A*box[i]
+cox = [[0] * 8 for i in range(256)]
+for i in range(256):
+    for t in range(8):
+        cox[i][t] = B[t]
+        for j in range(8):
+            cox[i][t] ^= A[t][j] * box[i][j]
+
+# S-boxes and inverse S-boxes
+S =  [0] * 256
+Si = [0] * 256
+for i in range(256):
+    S[i] = cox[i][0] << 7
+    for t in range(1, 8):
+        S[i] ^= cox[i][t] << (7-t)
+    Si[S[i] & 0xFF] = i
+
+# T-boxes
+G = [[2, 1, 1, 3],
+    [3, 2, 1, 1],
+    [1, 3, 2, 1],
+    [1, 1, 3, 2]]
+
+AA = [[0] * 8 for i in range(4)]
+
+for i in range(4):
+    for j in range(4):
+        AA[i][j] = G[i][j]
+        AA[i][i+4] = 1
+
+for i in range(4):
+    pivot = AA[i][i]
+    if pivot == 0:
+        t = i + 1
+        while AA[t][i] == 0 and t < 4:
+            t += 1
+            assert t != 4, 'G matrix must be invertible'
+            for j in range(8):
+                AA[i][j], AA[t][j] = AA[t][j], AA[i][j]
+            pivot = AA[i][i]
+    for j in range(8):
+        if AA[i][j] != 0:
+            AA[i][j] = alog[(255 + log[AA[i][j] & 0xFF] - log[pivot & 0xFF]) % 255]
+    for t in range(4):
+        if i != t:
+            for j in range(i+1, 8):
+                AA[t][j] ^= mul(AA[i][j], AA[t][i])
+            AA[t][i] = 0
+
+iG = [[0] * 4 for i in range(4)]
+
+for i in range(4):
+    for j in range(4):
+        iG[i][j] = AA[i][j + 4]
+
+def mul4(a, bs):
+    if a == 0:
+        return 0
+    r = 0
+    for b in bs:
+        r <<= 8
+        if b != 0:
+            r = r | mul(a, b)
+    return r
+
+T1 = []
+T2 = []
+T3 = []
+T4 = []
+T5 = []
+T6 = []
+T7 = []
+T8 = []
+U1 = []
+U2 = []
+U3 = []
+U4 = []
+
+for t in range(256):
+    s = S[t]
+    T1.append(mul4(s, G[0]))
+    T2.append(mul4(s, G[1]))
+    T3.append(mul4(s, G[2]))
+    T4.append(mul4(s, G[3]))
+
+    s = Si[t]
+    T5.append(mul4(s, iG[0]))
+    T6.append(mul4(s, iG[1]))
+    T7.append(mul4(s, iG[2]))
+    T8.append(mul4(s, iG[3]))
+
+    U1.append(mul4(t, iG[0]))
+    U2.append(mul4(t, iG[1]))
+    U3.append(mul4(t, iG[2]))
+    U4.append(mul4(t, iG[3]))
+
+# round constants
+rcon = [1]
+r = 1
+for t in range(1, 30):
+    r = mul(2, r)
+    rcon.append(r)
+
+del A
+del AA
+del pivot
+del B
+del G
+del box
+del log
+del alog
+del i
+del j
+del r
+del s
+del t
+del mul
+del mul4
+del cox
+del iG
+
+class rijndael:
+    def __init__(self, key, block_size = 16):
+        if block_size != 16 and block_size != 24 and block_size != 32:
+            raise ValueError('Invalid block size: ' + str(block_size))
+        if len(key) != 16 and len(key) != 24 and len(key) != 32:
+            raise ValueError('Invalid key size: ' + str(len(key)))
+        self.block_size = block_size
+
+        ROUNDS = num_rounds[len(key)][block_size]
+        BC = block_size // 4
+        # encryption round keys
+        Ke = [[0] * BC for i in range(ROUNDS + 1)]
+        # decryption round keys
+        Kd = [[0] * BC for i in range(ROUNDS + 1)]
+        ROUND_KEY_COUNT = (ROUNDS + 1) * BC
+        KC = len(key) // 4
+
+        # copy user material bytes into temporary ints
+        tk = []
+        for i in range(0, KC):
+            tk.append((ord(key[i * 4]) << 24) | (ord(key[i * 4 + 1]) << 16) |
+                (ord(key[i * 4 + 2]) << 8) | ord(key[i * 4 + 3]))
+
+        # copy values into round key arrays
+        t = 0
+        j = 0
+        while j < KC and t < ROUND_KEY_COUNT:
+            Ke[t // BC][t % BC] = tk[j]
+            Kd[ROUNDS - (t // BC)][t % BC] = tk[j]
+            j += 1
+            t += 1
+        tt = 0
+        rconpointer = 0
+        while t < ROUND_KEY_COUNT:
+            # extrapolate using phi (the round key evolution function)
+            tt = tk[KC - 1]
+            tk[0] ^= (S[(tt >> 16) & 0xFF] & 0xFF) << 24 ^  \
+                     (S[(tt >>  8) & 0xFF] & 0xFF) << 16 ^  \
+                     (S[ tt        & 0xFF] & 0xFF) <<  8 ^  \
+                     (S[(tt >> 24) & 0xFF] & 0xFF)       ^  \
+                     (rcon[rconpointer]    & 0xFF) << 24
+            rconpointer += 1
+            if KC != 8:
+                for i in range(1, KC):
+                    tk[i] ^= tk[i-1]
+            else:
+                for i in range(1, KC // 2):
+                    tk[i] ^= tk[i-1]
+                tt = tk[KC // 2 - 1]
+                tk[KC // 2] ^= (S[ tt        & 0xFF] & 0xFF)       ^ \
+                               (S[(tt >>  8) & 0xFF] & 0xFF) <<  8 ^ \
+                               (S[(tt >> 16) & 0xFF] & 0xFF) << 16 ^ \
+                               (S[(tt >> 24) & 0xFF] & 0xFF) << 24
+                for i in range(KC // 2 + 1, KC):
+                    tk[i] ^= tk[i-1]
+            # copy values into round key arrays
+            j = 0
+            while j < KC and t < ROUND_KEY_COUNT:
+                Ke[t // BC][t % BC] = tk[j]
+                Kd[ROUNDS - (t // BC)][t % BC] = tk[j]
+                j += 1
+                t += 1
+        # inverse MixColumn where needed
+        for r in range(1, ROUNDS):
+            for j in range(BC):
+                tt = Kd[r][j]
+                Kd[r][j] = U1[(tt >> 24) & 0xFF] ^ \
+                           U2[(tt >> 16) & 0xFF] ^ \
+                           U3[(tt >>  8) & 0xFF] ^ \
+                           U4[ tt        & 0xFF]
+        self.Ke = Ke
+        self.Kd = Kd
+
+    def encrypt(self, plaintext):
+        if len(plaintext) != self.block_size:
+            raise ValueError('wrong block length, expected ' + str(self.block_size) + ' got ' + str(len(plaintext)))
+        Ke = self.Ke
+
+        BC = self.block_size // 4
+        ROUNDS = len(Ke) - 1
+        if BC == 4:
+            SC = 0
+        elif BC == 6:
+            SC = 1
+        else:
+            SC = 2
+        s1 = shifts[SC][1][0]
+        s2 = shifts[SC][2][0]
+        s3 = shifts[SC][3][0]
+        a = [0] * BC
+        # temporary work array
+        t = []
+        # plaintext to ints + key
+        for i in range(BC):
+            t.append((ord(plaintext[i * 4    ]) << 24 |
+                      ord(plaintext[i * 4 + 1]) << 16 |
+                      ord(plaintext[i * 4 + 2]) <<  8 |
+                      ord(plaintext[i * 4 + 3])        ) ^ Ke[0][i])
+        # apply round transforms
+        for r in range(1, ROUNDS):
+            for i in range(BC):
+                a[i] = (T1[(t[ i           ] >> 24) & 0xFF] ^
+                        T2[(t[(i + s1) % BC] >> 16) & 0xFF] ^
+                        T3[(t[(i + s2) % BC] >>  8) & 0xFF] ^
+                        T4[ t[(i + s3) % BC]        & 0xFF]  ) ^ Ke[r][i]
+            t = copy.copy(a)
+        # last round is special
+        result = []
+        for i in range(BC):
+            tt = Ke[ROUNDS][i]
+            result.append((S[(t[ i           ] >> 24) & 0xFF] ^ (tt >> 24)) & 0xFF)
+            result.append((S[(t[(i + s1) % BC] >> 16) & 0xFF] ^ (tt >> 16)) & 0xFF)
+            result.append((S[(t[(i + s2) % BC] >>  8) & 0xFF] ^ (tt >>  8)) & 0xFF)
+            result.append((S[ t[(i + s3) % BC]        & 0xFF] ^  tt       ) & 0xFF)
+        return ''.join(map(chr, result))
+
+    def decrypt(self, ciphertext):
+        if len(ciphertext) != self.block_size:
+            raise ValueError('wrong block length, expected ' + str(self.block_size) + ' got ' + str(len(ciphertext)))
+        Kd = self.Kd
+
+        BC = self.block_size // 4
+        ROUNDS = len(Kd) - 1
+        if BC == 4:
+            SC = 0
+        elif BC == 6:
+            SC = 1
+        else:
+            SC = 2
+        s1 = shifts[SC][1][1]
+        s2 = shifts[SC][2][1]
+        s3 = shifts[SC][3][1]
+        a = [0] * BC
+        # temporary work array
+        t = [0] * BC
+        # ciphertext to ints + key
+        for i in range(BC):
+            t[i] = (ord(ciphertext[i * 4    ]) << 24 |
+                    ord(ciphertext[i * 4 + 1]) << 16 |
+                    ord(ciphertext[i * 4 + 2]) <<  8 |
+                    ord(ciphertext[i * 4 + 3])        ) ^ Kd[0][i]
+        # apply round transforms
+        for r in range(1, ROUNDS):
+            for i in range(BC):
+                a[i] = (T5[(t[ i           ] >> 24) & 0xFF] ^
+                        T6[(t[(i + s1) % BC] >> 16) & 0xFF] ^
+                        T7[(t[(i + s2) % BC] >>  8) & 0xFF] ^
+                        T8[ t[(i + s3) % BC]        & 0xFF]  ) ^ Kd[r][i]
+            t = copy.copy(a)
+        # last round is special
+        result = []
+        for i in range(BC):
+            tt = Kd[ROUNDS][i]
+            result.append((Si[(t[ i           ] >> 24) & 0xFF] ^ (tt >> 24)) & 0xFF)
+            result.append((Si[(t[(i + s1) % BC] >> 16) & 0xFF] ^ (tt >> 16)) & 0xFF)
+            result.append((Si[(t[(i + s2) % BC] >>  8) & 0xFF] ^ (tt >>  8)) & 0xFF)
+            result.append((Si[ t[(i + s3) % BC]        & 0xFF] ^  tt       ) & 0xFF)
+        return ''.join(map(chr, result))
+
+def encrypt(key, block):
+    return rijndael(key, len(block)).encrypt(block)
+
+def decrypt(key, block):
+    return rijndael(key, len(block)).decrypt(block)
+
+def test():
+    def t(kl, bl):
+        b = 'b' * bl
+        r = rijndael('a' * kl, bl)
+        assert r.decrypt(r.encrypt(b)) == b
+    t(16, 16)
+    t(16, 24)
+    t(16, 32)
+    t(24, 16)
+    t(24, 24)
+    t(24, 32)
+    t(32, 16)
+    t(32, 24)
+    t(32, 32)

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/utils/rijndael_lsw.py
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/utils/rijndael_lsw.py b/patches/systemvm/debian/config/root/lswcp/utils/rijndael_lsw.py
new file mode 100644
index 0000000..f39da1f
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/utils/rijndael_lsw.py
@@ -0,0 +1,41 @@
+import rijndael
+import base64
+
+KEY_SIZE = 16
+BLOCK_SIZE = 32
+
+def encrypt(key, plaintext):
+    padded_key = key.ljust(KEY_SIZE, '\0')
+    padded_text = plaintext + (BLOCK_SIZE - len(plaintext) % BLOCK_SIZE) * '\0'
+
+    # could also be one of
+    #if len(plaintext) % BLOCK_SIZE != 0:
+    #    padded_text = plaintext.ljust((len(plaintext) / BLOCK_SIZE) + 1 * BLOCKSIZE), '\0')
+    # -OR-
+    #padded_text = plaintext.ljust((len(plaintext) + (BLOCK_SIZE - len(plaintext) % BLOCK_SIZE)), '\0')
+
+    r = rijndael.rijndael(padded_key, BLOCK_SIZE)
+
+    ciphertext = ''
+    for start in range(0, len(padded_text), BLOCK_SIZE):
+        ciphertext += r.encrypt(padded_text[start:start+BLOCK_SIZE])
+
+    encoded = ciphertext.encode('hex_codec')
+
+    return encoded
+
+
+def decrypt(key, encoded):
+    padded_key = key.ljust(KEY_SIZE, '\0')
+
+    ciphertext = encoded.decode('hex_codec')
+
+    r = rijndael.rijndael(padded_key, BLOCK_SIZE)
+
+    padded_text = ''
+    for start in range(0, len(ciphertext), BLOCK_SIZE):
+        padded_text += r.decrypt(ciphertext[start:start+BLOCK_SIZE])
+
+    plaintext = padded_text.split('\x00', 1)[0]
+
+    return plaintext

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/utils/self.pem
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/utils/self.pem b/patches/systemvm/debian/config/root/lswcp/utils/self.pem
new file mode 100644
index 0000000..fec81bc
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/utils/self.pem
@@ -0,0 +1,33 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXwIBAAKBgQDUUSXEFWjVJIqzIe8sP0i1gwBeoy5S0DfUZ9Nlawa/ETTOUwXR
+F9HPbyFqm6+5v9GupdrdsyYV3cTB1bWUksgl664ukm6VZ/VCtiT5oAGz8viQSAdy
+wG9RdI1wmodlBS4CyLQJbqm6qxUuUDcT2a/wTCddiGPBoxZmHZkfWoE2CwIDAQAB
+AoGBANB8BpuvckuqIFCah+NpGRqz0s8baceEEu6OLXUvTWadnL7lo5aYzzvkImov
+CrVZeKsIzgxZeJKMPEMiebW1FLbtQotk249pjPHBLCZ9sVh9gdXC6ryfpGBwFNRc
+9sPjCI88dN3eVizObVZNgfJIWqMSWjRvV9NkbPb2obJYnM9xAkEA9udtDBmrEMtl
+3hU6+vdLFdnQNxzdf4oijH+upiZKGkkL8SGx3tvezHM4XN9gCIO/hXBS0Z+CXmOg
+F7vM0+vnBQJBANwjhze2+NDjiNH90DAzGIlhylWTF8EP9E8J/iBpR9BkJc1hLj/a
+q+J5jquiXL7Yp6aXcgpLp7zM84A/u+72Fc8CQQDV8mG+y3s9WVLTJ0htcd4heBWB
+vER/IN6hKn7XQHST5Foxv4XW3GVqeikL6Q/ZMPjDkzpgpLyeN+vgxP5PYKpVAkEA
+oO0j+xm6GNJNAd2+5I1lwYCIbjhiZBMqsOEIMl9kTTX44IPLUIiloKDmKBhAHo+5
+NzJ8/oPB8mYNF9L/qregxwJBALyClZBR7p1EggexzBYym0AtBEBdC7TvDPBG00St
+QziMZA7DmWIozExgLxK2r/AaqYYLaAr67znhKLzsnRL5F1s=
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIC+zCCAmSgAwIBAgIJAKSuRhf9HaRNMA0GCSqGSIb3DQEBBQUAMF0xCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQxFjAUBgNVBAMTDTk1LjIxMS41MS4yMjUwHhcNMTIwMzE5
+MjIyNjIzWhcNMTMwMzE5MjIyNjIzWjBdMQswCQYDVQQGEwJBVTETMBEGA1UECBMK
+U29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRYw
+FAYDVQQDEw05NS4yMTEuNTEuMjI1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
+gQDUUSXEFWjVJIqzIe8sP0i1gwBeoy5S0DfUZ9Nlawa/ETTOUwXRF9HPbyFqm6+5
+v9GupdrdsyYV3cTB1bWUksgl664ukm6VZ/VCtiT5oAGz8viQSAdywG9RdI1wmodl
+BS4CyLQJbqm6qxUuUDcT2a/wTCddiGPBoxZmHZkfWoE2CwIDAQABo4HCMIG/MB0G
+A1UdDgQWBBS9xuncC+iZJ+s5jQPiJS+AIx7iFDCBjwYDVR0jBIGHMIGEgBS9xunc
+C+iZJ+s5jQPiJS+AIx7iFKFhpF8wXTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNv
+bWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEWMBQG
+A1UEAxMNOTUuMjExLjUxLjIyNYIJAKSuRhf9HaRNMAwGA1UdEwQFMAMBAf8wDQYJ
+KoZIhvcNAQEFBQADgYEAqqYane3pVxRfECvtHYd5efVbAmSY0Oko4/40MugQOrx0
+qwddA9AejqKJRCy41pW5nqfq23YFpHt3FPPa2TG/jhW5udqIBxKWnhFE5foesZbo
+/C8U32pomyGkE3JylnZ+T556SBJjwd+o1tpyUdVrxGdebZASPrS+H68Xb5jPN5I=
+-----END CERTIFICATE-----

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/utils/u2x11
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/utils/u2x11 b/patches/systemvm/debian/config/root/lswcp/utils/u2x11
new file mode 100644
index 0000000..fd3e4ba
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/utils/u2x11
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+#
+# Convert "U+..." commented entries in /usr/include/X11/keysymdef.h
+# into JavaScript for use by noVNC.  Note this is likely to produce
+# a few duplicate properties with clashing values, that will need
+# resolving manually.
+#
+# Colin Dean <co...@xvpsource.org>
+#
+
+regex="^#define[ \t]+XK_[A-Za-z0-9_]+[ \t]+0x([0-9a-fA-F]+)[ \t]+\/\*[ \t]+U\+([0-9a-fA-F]+)[ \t]+[^*]+.[ \t]+\*\/[ \t]*$"
+echo "unicodeTable = {"
+while read line; do
+    if echo "${line}" | egrep -qs "${regex}"; then
+
+        x11=$(echo "${line}" | sed -r "s/${regex}/\1/")
+        vnc=$(echo "${line}" | sed -r "s/${regex}/\2/")
+	
+	if echo "${vnc}" | egrep -qs "^00[2-9A-F][0-9A-F]$"; then
+	    : # skip ISO Latin-1 (U+0020 to U+00FF) as 1-to-1 mapping
+	else
+	    # note 1-to-1 is possible (e.g. for Euro symbol, U+20AC)
+	    echo "    0x${vnc} : 0x${x11},"
+	fi
+    fi
+done < /usr/include/X11/keysymdef.h | uniq
+echo "};"
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/utils/web.py
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/utils/web.py b/patches/systemvm/debian/config/root/lswcp/utils/web.py
new file mode 100644
index 0000000..23afca0
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/utils/web.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+'''
+A super simple HTTP/HTTPS webserver for python. Automatically detect
+
+You can make a cert/key with openssl using:
+openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem
+as taken from http://docs.python.org/dev/library/ssl.html#certificates
+
+'''
+
+import traceback, sys
+import socket
+import ssl
+#import http.server as server      # python 3.X
+import SimpleHTTPServer as server  # python 2.X
+
+def do_request(connstream, from_addr):
+    x = object()
+    server.SimpleHTTPRequestHandler(connstream, from_addr, x)
+    connstream.close()
+
+def serve():
+    bindsocket = socket.socket()
+    bindsocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+    #bindsocket.bind(('localhost', PORT))
+    bindsocket.bind(('', PORT))
+    bindsocket.listen(5)
+
+    print("serving on port", PORT)
+
+    while True:
+        try:
+            newsocket, from_addr = bindsocket.accept()
+            peek = newsocket.recv(1024, socket.MSG_PEEK)
+            if peek.startswith("\x16"):
+                connstream = ssl.wrap_socket(
+                        newsocket,
+                        server_side=True,
+                        certfile='self.pem',
+                        ssl_version=ssl.PROTOCOL_TLSv1)
+            else:
+                connstream = newsocket
+
+            do_request(connstream, from_addr)
+
+        except Exception:
+            traceback.print_exc()
+
+try:
+    PORT = int(sys.argv[1])
+except:
+    print "%s port" % sys.argv[0]
+    sys.exit(2)
+
+serve()